Statistics
| Branch: | Revision:

root / asi-http-request-with-pithos / Classes / ASIHTTPRequest.h @ cc176feb

History | View | Annotate | Download (44 kB)

1
//
2
//  ASIHTTPRequest.h
3
//
4
//  Created by Ben Copsey on 04/10/2007.
5
//  Copyright 2007-2011 All-Seeing Interactive. All rights reserved.
6
//
7
//  A guide to the main features is available at:
8
//  http://allseeing-i.com/ASIHTTPRequest
9
//
10
//  Portions are based on the ImageClient example from Apple:
11
//  See: http://developer.apple.com/samplecode/ImageClient/listing37.html
12

    
13
#import <Foundation/Foundation.h>
14
#if TARGET_OS_IPHONE
15
        #import <CFNetwork/CFNetwork.h>
16
        #if __IPHONE_OS_VERSION_MAX_ALLOWED >= __IPHONE_4_0
17
        #import <UIKit/UIKit.h> // Necessary for background task support
18
        #endif
19
#endif
20

    
21
#import <stdio.h>
22
#import "ASIHTTPRequestConfig.h"
23
#import "ASIHTTPRequestDelegate.h"
24
#import "ASIProgressDelegate.h"
25
#import "ASICacheDelegate.h"
26

    
27
@class ASIDataDecompressor;
28

    
29
extern NSString *ASIHTTPRequestVersion;
30

    
31
// Make targeting different platforms more reliable
32
// See: http://www.blumtnwerx.com/blog/2009/06/cross-sdk-code-hygiene-in-xcode/
33
#ifndef __IPHONE_3_2
34
        #define __IPHONE_3_2 30200
35
#endif
36
#ifndef __IPHONE_4_0
37
        #define __IPHONE_4_0 40000
38
#endif
39
#ifndef __MAC_10_5
40
        #define __MAC_10_5 1050
41
#endif
42
#ifndef __MAC_10_6
43
        #define __MAC_10_6 1060
44
#endif
45

    
46
typedef enum _ASIAuthenticationState {
47
        ASINoAuthenticationNeededYet = 0,
48
        ASIHTTPAuthenticationNeeded = 1,
49
        ASIProxyAuthenticationNeeded = 2
50
} ASIAuthenticationState;
51

    
52
typedef enum _ASINetworkErrorType {
53
    ASIConnectionFailureErrorType = 1,
54
    ASIRequestTimedOutErrorType = 2,
55
    ASIAuthenticationErrorType = 3,
56
    ASIRequestCancelledErrorType = 4,
57
    ASIUnableToCreateRequestErrorType = 5,
58
    ASIInternalErrorWhileBuildingRequestType  = 6,
59
    ASIInternalErrorWhileApplyingCredentialsType  = 7,
60
        ASIFileManagementError = 8,
61
        ASITooMuchRedirectionErrorType = 9,
62
        ASIUnhandledExceptionError = 10,
63
        ASICompressionError = 11
64
        
65
} ASINetworkErrorType;
66

    
67

    
68
// The error domain that all errors generated by ASIHTTPRequest use
69
extern NSString* const NetworkRequestErrorDomain;
70

    
71
// You can use this number to throttle upload and download bandwidth in iPhone OS apps send or receive a large amount of data
72
// This may help apps that might otherwise be rejected for inclusion into the app store for using excessive bandwidth
73
// This number is not official, as far as I know there is no officially documented bandwidth limit
74
extern unsigned long const ASIWWANBandwidthThrottleAmount;
75

    
76
#if NS_BLOCKS_AVAILABLE
77
typedef void (^ASIBasicBlock)(void);
78
typedef void (^ASIHeadersBlock)(NSDictionary *responseHeaders);
79
typedef void (^ASISizeBlock)(long long size);
80
typedef void (^ASIProgressBlock)(unsigned long long size, unsigned long long total);
81
typedef void (^ASIDataBlock)(NSData *data);
82
#endif
83

    
84
@interface ASIHTTPRequest : NSOperation <NSCopying> {
85
        
86
        // The url for this operation, should include GET params in the query string where appropriate
87
        NSURL *url; 
88
        
89
        // Will always contain the original url used for making the request (the value of url can change when a request is redirected)
90
        NSURL *originalURL;
91
        
92
        // Temporarily stores the url we are about to redirect to. Will be nil again when we do redirect
93
        NSURL *redirectURL;
94

    
95
        // The delegate - will be notified of various changes in state via the ASIHTTPRequestDelegate protocol
96
        id <ASIHTTPRequestDelegate> delegate;
97
        
98
        // Another delegate that is also notified of request status changes and progress updates
99
        // Generally, you won't use this directly, but ASINetworkQueue sets itself as the queue so it can proxy updates to its own delegates
100
        // NOTE: WILL BE RETAINED BY THE REQUEST
101
        id <ASIHTTPRequestDelegate, ASIProgressDelegate> queue;
102
        
103
        // HTTP method to use (eg: GET / POST / PUT / DELETE / HEAD etc). Defaults to GET
104
        NSString *requestMethod;
105
        
106
        // Request body - only used when the whole body is stored in memory (shouldStreamPostDataFromDisk is false)
107
        NSMutableData *postBody;
108
        
109
        // gzipped request body used when shouldCompressRequestBody is YES
110
        NSData *compressedPostBody;
111
        
112
        // When true, post body will be streamed from a file on disk, rather than loaded into memory at once (useful for large uploads)
113
        // Automatically set to true in ASIFormDataRequests when using setFile:forKey:
114
        BOOL shouldStreamPostDataFromDisk;
115
        
116
        // Path to file used to store post body (when shouldStreamPostDataFromDisk is true)
117
        // You can set this yourself - useful if you want to PUT a file from local disk 
118
        NSString *postBodyFilePath;
119
        
120
        // Path to a temporary file used to store a deflated post body (when shouldCompressPostBody is YES)
121
        NSString *compressedPostBodyFilePath;
122
        
123
        // Set to true when ASIHTTPRequest automatically created a temporary file containing the request body (when true, the file at postBodyFilePath will be deleted at the end of the request)
124
        BOOL didCreateTemporaryPostDataFile;
125
        
126
        // Used when writing to the post body when shouldStreamPostDataFromDisk is true (via appendPostData: or appendPostDataFromFile:)
127
        NSOutputStream *postBodyWriteStream;
128
        
129
        // Used for reading from the post body when sending the request
130
        NSInputStream *postBodyReadStream;
131
        
132
        // Dictionary for custom HTTP request headers
133
        NSMutableDictionary *requestHeaders;
134
        
135
        // Set to YES when the request header dictionary has been populated, used to prevent this happening more than once
136
        BOOL haveBuiltRequestHeaders;
137
        
138
        // Will be populated with HTTP response headers from the server
139
        NSDictionary *responseHeaders;
140
        
141
        // Can be used to manually insert cookie headers to a request, but it's more likely that sessionCookies will do this for you
142
        NSMutableArray *requestCookies;
143
        
144
        // Will be populated with cookies
145
        NSArray *responseCookies;
146
        
147
        // If use useCookiePersistence is true, network requests will present valid cookies from previous requests
148
        BOOL useCookiePersistence;
149
        
150
        // If useKeychainPersistence is true, network requests will attempt to read credentials from the keychain, and will save them in the keychain when they are successfully presented
151
        BOOL useKeychainPersistence;
152
        
153
        // If useSessionPersistence is true, network requests will save credentials and reuse for the duration of the session (until clearSession is called)
154
        BOOL useSessionPersistence;
155
        
156
        // If allowCompressedResponse is true, requests will inform the server they can accept compressed data, and will automatically decompress gzipped responses. Default is true.
157
        BOOL allowCompressedResponse;
158
        
159
        // If shouldCompressRequestBody is true, the request body will be gzipped. Default is false.
160
        // You will probably need to enable this feature on your webserver to make this work. Tested with apache only.
161
        BOOL shouldCompressRequestBody;
162
        
163
        // When downloadDestinationPath is set, the result of this request will be downloaded to the file at this location
164
        // If downloadDestinationPath is not set, download data will be stored in memory
165
        NSString *downloadDestinationPath;
166
        
167
        // The location that files will be downloaded to. Once a download is complete, files will be decompressed (if necessary) and moved to downloadDestinationPath
168
        NSString *temporaryFileDownloadPath;
169
        
170
        // If the response is gzipped and shouldWaitToInflateCompressedResponses is NO, a file will be created at this path containing the inflated response as it comes in
171
        NSString *temporaryUncompressedDataDownloadPath;
172
        
173
        // Used for writing data to a file when downloadDestinationPath is set
174
        NSOutputStream *fileDownloadOutputStream;
175
        
176
        NSOutputStream *inflatedFileDownloadOutputStream;
177
        
178
        // When the request fails or completes successfully, complete will be true
179
        BOOL complete;
180
        
181
    // external "finished" indicator, subject of KVO notifications; updates after 'complete'
182
    BOOL finished;
183
    
184
    // True if our 'cancel' selector has been called
185
    BOOL cancelled;
186
    
187
        // If an error occurs, error will contain an NSError
188
        // If error code is = ASIConnectionFailureErrorType (1, Connection failure occurred) - inspect [[error userInfo] objectForKey:NSUnderlyingErrorKey] for more information
189
        NSError *error;
190
        
191
        // Username and password used for authentication
192
        NSString *username;
193
        NSString *password;
194
        
195
        // User-Agent for this request
196
        NSString *userAgentString;
197
        
198
        // Domain used for NTLM authentication
199
        NSString *domain;
200
        
201
        // Username and password used for proxy authentication
202
        NSString *proxyUsername;
203
        NSString *proxyPassword;
204
        
205
        // Domain used for NTLM proxy authentication
206
        NSString *proxyDomain;
207
        
208
        // Delegate for displaying upload progress (usually an NSProgressIndicator, but you can supply a different object and handle this yourself)
209
        id <ASIProgressDelegate> uploadProgressDelegate;
210
        
211
        // Delegate for displaying download progress (usually an NSProgressIndicator, but you can supply a different object and handle this yourself)
212
        id <ASIProgressDelegate> downloadProgressDelegate;
213
        
214
        // Whether we've seen the headers of the response yet
215
    BOOL haveExaminedHeaders;
216
        
217
        // Data we receive will be stored here. Data may be compressed unless allowCompressedResponse is false - you should use [request responseData] instead in most cases
218
        NSMutableData *rawResponseData;
219
        
220
        // Used for sending and receiving data
221
    CFHTTPMessageRef request;        
222
        NSInputStream *readStream;
223
        
224
        // Used for authentication
225
    CFHTTPAuthenticationRef requestAuthentication; 
226
        NSDictionary *requestCredentials;
227
        
228
        // Used during NTLM authentication
229
        int authenticationRetryCount;
230
        
231
        // Authentication scheme (Basic, Digest, NTLM)
232
        // If you are using Basic authentication and want to force ASIHTTPRequest to send an authorization header without waiting for a 401, you must set this to (NSString *)kCFHTTPAuthenticationSchemeBasic
233
        NSString *authenticationScheme;
234
        
235
        // Realm for authentication when credentials are required
236
        NSString *authenticationRealm;
237
        
238
        // When YES, ASIHTTPRequest will present a dialog allowing users to enter credentials when no-matching credentials were found for a server that requires authentication
239
        // The dialog will not be shown if your delegate responds to authenticationNeededForRequest:
240
        // Default is NO.
241
        BOOL shouldPresentAuthenticationDialog;
242
        
243
        // When YES, ASIHTTPRequest will present a dialog allowing users to enter credentials when no-matching credentials were found for a proxy server that requires authentication
244
        // The dialog will not be shown if your delegate responds to proxyAuthenticationNeededForRequest:
245
        // Default is YES (basically, because most people won't want the hassle of adding support for authenticating proxies to their apps)
246
        BOOL shouldPresentProxyAuthenticationDialog;        
247
        
248
        // Used for proxy authentication
249
    CFHTTPAuthenticationRef proxyAuthentication; 
250
        NSDictionary *proxyCredentials;
251
        
252
        // Used during authentication with an NTLM proxy
253
        int proxyAuthenticationRetryCount;
254
        
255
        // Authentication scheme for the proxy (Basic, Digest, NTLM)
256
        NSString *proxyAuthenticationScheme;        
257
        
258
        // Realm for proxy authentication when credentials are required
259
        NSString *proxyAuthenticationRealm;
260
        
261
        // HTTP status code, eg: 200 = OK, 404 = Not found etc
262
        int responseStatusCode;
263
        
264
        // Description of the HTTP status code
265
        NSString *responseStatusMessage;
266
        
267
        // Size of the response
268
        unsigned long long contentLength;
269
        
270
        // Size of the partially downloaded content
271
        unsigned long long partialDownloadSize;
272
        
273
        // Size of the POST payload
274
        unsigned long long postLength;        
275
        
276
        // The total amount of downloaded data
277
        unsigned long long totalBytesRead;
278
        
279
        // The total amount of uploaded data
280
        unsigned long long totalBytesSent;
281
        
282
        // Last amount of data read (used for incrementing progress)
283
        unsigned long long lastBytesRead;
284
        
285
        // Last amount of data sent (used for incrementing progress)
286
        unsigned long long lastBytesSent;
287
        
288
        // This lock prevents the operation from being cancelled at an inopportune moment
289
        NSRecursiveLock *cancelledLock;
290
        
291
        // Called on the delegate (if implemented) when the request starts. Default is requestStarted:
292
        SEL didStartSelector;
293
        
294
        // Called on the delegate (if implemented) when the request receives response headers. Default is request:didReceiveResponseHeaders:
295
        SEL didReceiveResponseHeadersSelector;
296

    
297
        // Called on the delegate (if implemented) when the request receives a Location header and shouldRedirect is YES
298
        // The delegate can then change the url if needed, and can restart the request by calling [request redirectToURL:], or simply cancel it
299
        SEL willRedirectSelector;
300

    
301
        // Called on the delegate (if implemented) when the request completes successfully. Default is requestFinished:
302
        SEL didFinishSelector;
303
        
304
        // Called on the delegate (if implemented) when the request fails. Default is requestFailed:
305
        SEL didFailSelector;
306
        
307
        // Called on the delegate (if implemented) when the request receives data. Default is request:didReceiveData:
308
        // If you set this and implement the method in your delegate, you must handle the data yourself - ASIHTTPRequest will not populate responseData or write the data to downloadDestinationPath
309
        SEL didReceiveDataSelector;
310
        
311
        // Used for recording when something last happened during the request, we will compare this value with the current date to time out requests when appropriate
312
        NSDate *lastActivityTime;
313
        
314
        // Number of seconds to wait before timing out - default is 10
315
        NSTimeInterval timeOutSeconds;
316
        
317
        // Will be YES when a HEAD request will handle the content-length before this request starts
318
        BOOL shouldResetUploadProgress;
319
        BOOL shouldResetDownloadProgress;
320
        
321
        // Used by HEAD requests when showAccurateProgress is YES to preset the content-length for this request
322
        ASIHTTPRequest *mainRequest;
323
        
324
        // When NO, this request will only update the progress indicator when it completes
325
        // When YES, this request will update the progress indicator according to how much data it has received so far
326
        // The default for requests is YES
327
        // Also see the comments in ASINetworkQueue.h
328
        BOOL showAccurateProgress;
329
        
330
        // Used to ensure the progress indicator is only incremented once when showAccurateProgress = NO
331
        BOOL updatedProgress;
332
        
333
        // Prevents the body of the post being built more than once (largely for subclasses)
334
        BOOL haveBuiltPostBody;
335
        
336
        // Used internally, may reflect the size of the internal buffer used by CFNetwork
337
        // POST / PUT operations with body sizes greater than uploadBufferSize will not timeout unless more than uploadBufferSize bytes have been sent
338
        // Likely to be 32KB on iPhone 3.0, 128KB on Mac OS X Leopard and iPhone 2.2.x
339
        unsigned long long uploadBufferSize;
340
        
341
        // Text encoding for responses that do not send a Content-Type with a charset value. Defaults to NSISOLatin1StringEncoding
342
        NSStringEncoding defaultResponseEncoding;
343
        
344
        // The text encoding of the response, will be defaultResponseEncoding if the server didn't specify. Can't be set.
345
        NSStringEncoding responseEncoding;
346
        
347
        // Tells ASIHTTPRequest not to delete partial downloads, and allows it to use an existing file to resume a download. Defaults to NO.
348
        BOOL allowResumeForFileDownloads;
349
        
350
        // Custom user information associated with the request (not sent to the server)
351
        NSDictionary *userInfo;
352
        NSInteger tag;
353
        
354
        // Use HTTP 1.0 rather than 1.1 (defaults to false)
355
        BOOL useHTTPVersionOne;
356
        
357
        // When YES, requests will automatically redirect when they get a HTTP 30x header (defaults to YES)
358
        BOOL shouldRedirect;
359
        
360
        // Used internally to tell the main loop we need to stop and retry with a new url
361
        BOOL needsRedirect;
362
        
363
        // Incremented every time this request redirects. When it reaches 5, we give up
364
        int redirectCount;
365
        
366
        // When NO, requests will not check the secure certificate is valid (use for self-signed certificates during development, DO NOT USE IN PRODUCTION) Default is YES
367
        BOOL validatesSecureCertificate;
368
    
369
    // If not nil and the URL scheme is https, CFNetwork configured to supply a client certificate
370
    SecIdentityRef clientCertificateIdentity;
371
        NSArray *clientCertificates;
372
        
373
        // Details on the proxy to use - you could set these yourself, but it's probably best to let ASIHTTPRequest detect the system proxy settings
374
        NSString *proxyHost;
375
        int proxyPort;
376
        
377
        // ASIHTTPRequest will assume kCFProxyTypeHTTP if the proxy type could not be automatically determined
378
        // Set to kCFProxyTypeSOCKS if you are manually configuring a SOCKS proxy
379
        NSString *proxyType;
380

    
381
        // URL for a PAC (Proxy Auto Configuration) file. If you want to set this yourself, it's probably best if you use a local file
382
        NSURL *PACurl;
383
        
384
        // See ASIAuthenticationState values above. 0 == default == No authentication needed yet
385
        ASIAuthenticationState authenticationNeeded;
386
        
387
        // When YES, ASIHTTPRequests will present credentials from the session store for requests to the same server before being asked for them
388
        // This avoids an extra round trip for requests after authentication has succeeded, which is much for efficient for authenticated requests with large bodies, or on slower connections
389
        // Set to NO to only present credentials when explicitly asked for them
390
        // This only affects credentials stored in the session cache when useSessionPersistence is YES. Credentials from the keychain are never presented unless the server asks for them
391
        // Default is YES
392
        // For requests using Basic authentication, set authenticationScheme to (NSString *)kCFHTTPAuthenticationSchemeBasic, and credentials can be sent on the very first request when shouldPresentCredentialsBeforeChallenge is YES
393
        BOOL shouldPresentCredentialsBeforeChallenge;
394
        
395
        // YES when the request hasn't finished yet. Will still be YES even if the request isn't doing anything (eg it's waiting for delegate authentication). READ-ONLY
396
        BOOL inProgress;
397
        
398
        // Used internally to track whether the stream is scheduled on the run loop or not
399
        // Bandwidth throttling can unschedule the stream to slow things down while a request is in progress
400
        BOOL readStreamIsScheduled;
401
        
402
        // Set to allow a request to automatically retry itself on timeout
403
        // Default is zero - timeout will stop the request
404
        int numberOfTimesToRetryOnTimeout;
405

    
406
        // The number of times this request has retried (when numberOfTimesToRetryOnTimeout > 0)
407
        int retryCount;
408

    
409
        // Temporarily set to YES when a closed connection forces a retry (internally, this stops ASIHTTPRequest cleaning up a temporary post body)
410
        BOOL willRetryRequest;
411

    
412
        // When YES, requests will keep the connection to the server alive for a while to allow subsequent requests to re-use it for a substantial speed-boost
413
        // Persistent connections will not be used if the server explicitly closes the connection
414
        // Default is YES
415
        BOOL shouldAttemptPersistentConnection;
416

    
417
        // Number of seconds to keep an inactive persistent connection open on the client side
418
        // Default is 60
419
        // If we get a keep-alive header, this is this value is replaced with how long the server told us to keep the connection around
420
        // A future date is created from this and used for expiring the connection, this is stored in connectionInfo's expires value
421
        NSTimeInterval persistentConnectionTimeoutSeconds;
422
        
423
        // Set to yes when an appropriate keep-alive header is found
424
        BOOL connectionCanBeReused;
425
        
426
        // Stores information about the persistent connection that is currently in use.
427
        // It may contain:
428
        // * The id we set for a particular connection, incremented every time we want to specify that we need a new connection
429
        // * The date that connection should expire
430
        // * A host, port and scheme for the connection. These are used to determine whether that connection can be reused by a subsequent request (all must match the new request)
431
        // * An id for the request that is currently using the connection. This is used for determining if a connection is available or not (we store a number rather than a reference to the request so we don't need to hang onto a request until the connection expires)
432
        // * A reference to the stream that is currently using the connection. This is necessary because we need to keep the old stream open until we've opened a new one.
433
        //   The stream will be closed + released either when another request comes to use the connection, or when the timer fires to tell the connection to expire
434
        NSMutableDictionary *connectionInfo;
435
        
436
        // When set to YES, 301 and 302 automatic redirects will use the original method and and body, according to the HTTP 1.1 standard
437
        // Default is NO (to follow the behaviour of most browsers)
438
        BOOL shouldUseRFC2616RedirectBehaviour;
439
        
440
        // Used internally to record when a request has finished downloading data
441
        BOOL downloadComplete;
442
        
443
        // An ID that uniquely identifies this request - primarily used for debugging persistent connections
444
        NSNumber *requestID;
445
        
446
        // Will be ASIHTTPRequestRunLoopMode for synchronous requests, NSDefaultRunLoopMode for all other requests
447
        NSString *runLoopMode;
448
        
449
        // This timer checks up on the request every 0.25 seconds, and updates progress
450
        NSTimer *statusTimer;
451
        
452
        // The download cache that will be used for this request (use [ASIHTTPRequest setDefaultCache:cache] to configure a default cache
453
        id <ASICacheDelegate> downloadCache;
454
        
455
        // The cache policy that will be used for this request - See ASICacheDelegate.h for possible values
456
        ASICachePolicy cachePolicy;
457
        
458
        // The cache storage policy that will be used for this request - See ASICacheDelegate.h for possible values
459
        ASICacheStoragePolicy cacheStoragePolicy;
460
        
461
        // Will be true when the response was pulled from the cache rather than downloaded
462
        BOOL didUseCachedResponse;
463

    
464
        // Set secondsToCache to use a custom time interval for expiring the response when it is stored in a cache
465
        NSTimeInterval secondsToCache;
466

    
467
        #if TARGET_OS_IPHONE && __IPHONE_OS_VERSION_MAX_ALLOWED >= __IPHONE_4_0
468
        BOOL shouldContinueWhenAppEntersBackground;
469
        UIBackgroundTaskIdentifier backgroundTask;
470
        #endif
471
        
472
        // When downloading a gzipped response, the request will use this helper object to inflate the response
473
        ASIDataDecompressor *dataDecompressor;
474
        
475
        // Controls how responses with a gzipped encoding are inflated (decompressed)
476
        // When set to YES (This is the default):
477
        // * gzipped responses for requests without a downloadDestinationPath will be inflated only when [request responseData] / [request responseString] is called
478
        // * gzipped responses for requests with a downloadDestinationPath set will be inflated only when the request completes
479
        //
480
        // When set to NO
481
        // All requests will inflate the response as it comes in
482
        // * If the request has no downloadDestinationPath set, the raw (compressed) response is discarded and rawResponseData will contain the decompressed response
483
        // * If the request has a downloadDestinationPath, the raw response will be stored in temporaryFileDownloadPath as normal, the inflated response will be stored in temporaryUncompressedDataDownloadPath
484
        //   Once the request completes successfully, the contents of temporaryUncompressedDataDownloadPath are moved into downloadDestinationPath
485
        //
486
        // Setting this to NO may be especially useful for users using ASIHTTPRequest in conjunction with a streaming parser, as it will allow partial gzipped responses to be inflated and passed on to the parser while the request is still running
487
        BOOL shouldWaitToInflateCompressedResponses;
488

    
489
        // Will be YES if this is a request created behind the scenes to download a PAC file - these requests do not attempt to configure their own proxies
490
        BOOL isPACFileRequest;
491

    
492
        // Used for downloading PAC files from http / https webservers
493
        ASIHTTPRequest *PACFileRequest;
494

    
495
        // Used for asynchronously reading PAC files from file:// URLs
496
        NSInputStream *PACFileReadStream;
497

    
498
        // Used for storing PAC data from file URLs as it is downloaded
499
        NSMutableData *PACFileData;
500

    
501
        // Set to YES in startSynchronous. Currently used by proxy detection to download PAC files synchronously when appropriate
502
        BOOL isSynchronous;
503

    
504
        #if NS_BLOCKS_AVAILABLE
505
        //block to execute when request starts
506
        ASIBasicBlock startedBlock;
507

    
508
        //block to execute when headers are received
509
        ASIHeadersBlock headersReceivedBlock;
510

    
511
        //block to execute when request completes successfully
512
        ASIBasicBlock completionBlock;
513

    
514
        //block to execute when request fails
515
        ASIBasicBlock failureBlock;
516

    
517
        //block for when bytes are received
518
        ASIProgressBlock bytesReceivedBlock;
519

    
520
        //block for when bytes are sent
521
        ASIProgressBlock bytesSentBlock;
522

    
523
        //block for when download size is incremented
524
        ASISizeBlock downloadSizeIncrementedBlock;
525

    
526
        //block for when upload size is incremented
527
        ASISizeBlock uploadSizeIncrementedBlock;
528

    
529
        //block for handling raw bytes received
530
        ASIDataBlock dataReceivedBlock;
531

    
532
        //block for handling authentication
533
        ASIBasicBlock authenticationNeededBlock;
534

    
535
        //block for handling proxy authentication
536
        ASIBasicBlock proxyAuthenticationNeededBlock;
537
        
538
    //block for handling redirections, if you want to
539
    ASIBasicBlock requestRedirectedBlock;
540
        #endif
541
}
542

    
543
#pragma mark init / dealloc
544

    
545
// Should be an HTTP or HTTPS url, may include username and password if appropriate
546
- (id)initWithURL:(NSURL *)newURL;
547

    
548
// Convenience constructor
549
+ (id)requestWithURL:(NSURL *)newURL;
550

    
551
+ (id)requestWithURL:(NSURL *)newURL usingCache:(id <ASICacheDelegate>)cache;
552
+ (id)requestWithURL:(NSURL *)newURL usingCache:(id <ASICacheDelegate>)cache andCachePolicy:(ASICachePolicy)policy;
553

    
554
#if NS_BLOCKS_AVAILABLE
555
- (void)setStartedBlock:(ASIBasicBlock)aStartedBlock;
556
- (void)setHeadersReceivedBlock:(ASIHeadersBlock)aReceivedBlock;
557
- (void)setCompletionBlock:(ASIBasicBlock)aCompletionBlock;
558
- (void)setFailedBlock:(ASIBasicBlock)aFailedBlock;
559
- (void)setBytesReceivedBlock:(ASIProgressBlock)aBytesReceivedBlock;
560
- (void)setBytesSentBlock:(ASIProgressBlock)aBytesSentBlock;
561
- (void)setDownloadSizeIncrementedBlock:(ASISizeBlock) aDownloadSizeIncrementedBlock;
562
- (void)setUploadSizeIncrementedBlock:(ASISizeBlock) anUploadSizeIncrementedBlock;
563
- (void)setDataReceivedBlock:(ASIDataBlock)aReceivedBlock;
564
- (void)setAuthenticationNeededBlock:(ASIBasicBlock)anAuthenticationBlock;
565
- (void)setProxyAuthenticationNeededBlock:(ASIBasicBlock)aProxyAuthenticationBlock;
566
- (void)setRequestRedirectedBlock:(ASIBasicBlock)aRedirectBlock;
567
#endif
568

    
569
#pragma mark setup request
570

    
571
// Add a custom header to the request
572
- (void)addRequestHeader:(NSString *)header value:(NSString *)value;
573

    
574
// Called during buildRequestHeaders and after a redirect to create a cookie header from request cookies and the global store
575
- (void)applyCookieHeader;
576

    
577
// Populate the request headers dictionary. Called before a request is started, or by a HEAD request that needs to borrow them
578
- (void)buildRequestHeaders;
579

    
580
// Used to apply authorization header to a request before it is sent (when shouldPresentCredentialsBeforeChallenge is YES)
581
- (void)applyAuthorizationHeader;
582

    
583

    
584
// Create the post body
585
- (void)buildPostBody;
586

    
587
// Called to add data to the post body. Will append to postBody when shouldStreamPostDataFromDisk is false, or write to postBodyWriteStream when true
588
- (void)appendPostData:(NSData *)data;
589
- (void)appendPostDataFromFile:(NSString *)file;
590

    
591
#pragma mark get information about this request
592

    
593
// Returns the contents of the result as an NSString (not appropriate for binary data - used responseData instead)
594
- (NSString *)responseString;
595

    
596
// Response data, automatically uncompressed where appropriate
597
- (NSData *)responseData;
598

    
599
// Returns true if the response was gzip compressed
600
- (BOOL)isResponseCompressed;
601

    
602
#pragma mark running a request
603

    
604

    
605
// Run a request synchronously, and return control when the request completes or fails
606
- (void)startSynchronous;
607

    
608
// Run request in the background
609
- (void)startAsynchronous;
610

    
611
// Clears all delegates and blocks, then cancels the request
612
- (void)clearDelegatesAndCancel;
613

    
614
#pragma mark HEAD request
615

    
616
// Used by ASINetworkQueue to create a HEAD request appropriate for this request with the same headers (though you can use it yourself)
617
- (ASIHTTPRequest *)HEADRequest;
618

    
619
#pragma mark upload/download progress
620

    
621
// Called approximately every 0.25 seconds to update the progress delegates
622
- (void)updateProgressIndicators;
623

    
624
// Updates upload progress (notifies the queue and/or uploadProgressDelegate of this request)
625
- (void)updateUploadProgress;
626

    
627
// Updates download progress (notifies the queue and/or uploadProgressDelegate of this request)
628
- (void)updateDownloadProgress;
629

    
630
// Called when authorisation is needed, as we only find out we don't have permission to something when the upload is complete
631
- (void)removeUploadProgressSoFar;
632

    
633
// Called when we get a content-length header and shouldResetDownloadProgress is true
634
- (void)incrementDownloadSizeBy:(long long)length;
635

    
636
// Called when a request starts and shouldResetUploadProgress is true
637
// Also called (with a negative length) to remove the size of the underlying buffer used for uploading
638
- (void)incrementUploadSizeBy:(long long)length;
639

    
640
// Helper method for interacting with progress indicators to abstract the details of different APIS (NSProgressIndicator and UIProgressView)
641
+ (void)updateProgressIndicator:(id *)indicator withProgress:(unsigned long long)progress ofTotal:(unsigned long long)total;
642

    
643
// Helper method used for performing invocations on the main thread (used for progress)
644
+ (void)performSelector:(SEL)selector onTarget:(id *)target withObject:(id)object amount:(void *)amount callerToRetain:(id)caller;
645

    
646
#pragma mark talking to delegates
647

    
648
// Called when a request starts, lets the delegate know via didStartSelector
649
- (void)requestStarted;
650

    
651
// Called when a request receives response headers, lets the delegate know via didReceiveResponseHeadersSelector
652
- (void)requestReceivedResponseHeaders:(NSDictionary *)newHeaders;
653

    
654
// Called when a request completes successfully, lets the delegate know via didFinishSelector
655
- (void)requestFinished;
656

    
657
// Called when a request fails, and lets the delegate know via didFailSelector
658
- (void)failWithError:(NSError *)theError;
659

    
660
// Called to retry our request when our persistent connection is closed
661
// Returns YES if we haven't already retried, and connection will be restarted
662
// Otherwise, returns NO, and nothing will happen
663
- (BOOL)retryUsingNewConnection;
664

    
665
// Can be called by delegates from inside their willRedirectSelector implementations to restart the request with a new url
666
- (void)redirectToURL:(NSURL *)newURL;
667

    
668
#pragma mark parsing HTTP response headers
669

    
670
// Reads the response headers to find the content length, encoding, cookies for the session 
671
// Also initiates request redirection when shouldRedirect is true
672
// And works out if HTTP auth is required
673
- (void)readResponseHeaders;
674

    
675
// Attempts to set the correct encoding by looking at the Content-Type header, if this is one
676
- (void)parseStringEncodingFromHeaders;
677

    
678
+ (void)parseMimeType:(NSString **)mimeType andResponseEncoding:(NSStringEncoding *)stringEncoding fromContentType:(NSString *)contentType;
679

    
680
#pragma mark http authentication stuff
681

    
682
// Apply credentials to this request
683
- (BOOL)applyCredentials:(NSDictionary *)newCredentials;
684
- (BOOL)applyProxyCredentials:(NSDictionary *)newCredentials;
685

    
686
// Attempt to obtain credentials for this request from the URL, username and password or keychain
687
- (NSMutableDictionary *)findCredentials;
688
- (NSMutableDictionary *)findProxyCredentials;
689

    
690
// Unlock (unpause) the request thread so it can resume the request
691
// Should be called by delegates when they have populated the authentication information after an authentication challenge
692
- (void)retryUsingSuppliedCredentials;
693

    
694
// Should be called by delegates when they wish to cancel authentication and stop
695
- (void)cancelAuthentication;
696

    
697
// Apply authentication information and resume the request after an authentication challenge
698
- (void)attemptToApplyCredentialsAndResume;
699
- (void)attemptToApplyProxyCredentialsAndResume;
700

    
701
// Attempt to show the built-in authentication dialog, returns YES if credentials were supplied, NO if user cancelled dialog / dialog is disabled / running on main thread
702
// Currently only used on iPhone OS
703
- (BOOL)showProxyAuthenticationDialog;
704
- (BOOL)showAuthenticationDialog;
705

    
706
// Construct a basic authentication header from the username and password supplied, and add it to the request headers
707
// Used when shouldPresentCredentialsBeforeChallenge is YES
708
- (void)addBasicAuthenticationHeaderWithUsername:(NSString *)theUsername andPassword:(NSString *)thePassword;
709

    
710
#pragma mark stream status handlers
711

    
712
// CFnetwork event handlers
713
- (void)handleNetworkEvent:(CFStreamEventType)type;
714
- (void)handleBytesAvailable;
715
- (void)handleStreamComplete;
716
- (void)handleStreamError;
717

    
718
#pragma mark cleanup
719

    
720
// Cleans up and lets the queue know this operation is finished.
721
// Appears in this header for subclassing only, do not call this method from outside your request!
722
- (void)markAsFinished;
723

    
724
// Cleans up temporary files. There's normally no reason to call these yourself, they are called automatically when a request completes or fails
725

    
726
// Clean up the temporary file used to store the downloaded data when it comes in (if downloadDestinationPath is set)
727
- (BOOL)removeTemporaryDownloadFile;
728

    
729
// Clean up the temporary file used to store data that is inflated (decompressed) as it comes in
730
- (BOOL)removeTemporaryUncompressedDownloadFile;
731

    
732
// Clean up the temporary file used to store the request body (when shouldStreamPostDataFromDisk is YES)
733
- (BOOL)removeTemporaryUploadFile;
734

    
735
// Clean up the temporary file used to store a deflated (compressed) request body when shouldStreamPostDataFromDisk is YES
736
- (BOOL)removeTemporaryCompressedUploadFile;
737

    
738
// Remove a file on disk, returning NO and populating the passed error pointer if it fails
739
+ (BOOL)removeFileAtPath:(NSString *)path error:(NSError **)err;
740

    
741
#pragma mark persistent connections
742

    
743
// Get the ID of the connection this request used (only really useful in tests and debugging)
744
- (NSNumber *)connectionID;
745

    
746
// Called automatically when a request is started to clean up any persistent connections that have expired
747
+ (void)expirePersistentConnections;
748

    
749
#pragma mark default time out
750

    
751
+ (NSTimeInterval)defaultTimeOutSeconds;
752
+ (void)setDefaultTimeOutSeconds:(NSTimeInterval)newTimeOutSeconds;
753

    
754
#pragma mark client certificate
755

    
756
- (void)setClientCertificateIdentity:(SecIdentityRef)anIdentity;
757

    
758
#pragma mark session credentials
759

    
760
+ (NSMutableArray *)sessionProxyCredentialsStore;
761
+ (NSMutableArray *)sessionCredentialsStore;
762

    
763
+ (void)storeProxyAuthenticationCredentialsInSessionStore:(NSDictionary *)credentials;
764
+ (void)storeAuthenticationCredentialsInSessionStore:(NSDictionary *)credentials;
765

    
766
+ (void)removeProxyAuthenticationCredentialsFromSessionStore:(NSDictionary *)credentials;
767
+ (void)removeAuthenticationCredentialsFromSessionStore:(NSDictionary *)credentials;
768

    
769
- (NSDictionary *)findSessionProxyAuthenticationCredentials;
770
- (NSDictionary *)findSessionAuthenticationCredentials;
771

    
772
#pragma mark keychain storage
773

    
774
// Save credentials for this request to the keychain
775
- (void)saveCredentialsToKeychain:(NSDictionary *)newCredentials;
776

    
777
// Save credentials to the keychain
778
+ (void)saveCredentials:(NSURLCredential *)credentials forHost:(NSString *)host port:(int)port protocol:(NSString *)protocol realm:(NSString *)realm;
779
+ (void)saveCredentials:(NSURLCredential *)credentials forProxy:(NSString *)host port:(int)port realm:(NSString *)realm;
780

    
781
// Return credentials from the keychain
782
+ (NSURLCredential *)savedCredentialsForHost:(NSString *)host port:(int)port protocol:(NSString *)protocol realm:(NSString *)realm;
783
+ (NSURLCredential *)savedCredentialsForProxy:(NSString *)host port:(int)port protocol:(NSString *)protocol realm:(NSString *)realm;
784

    
785
// Remove credentials from the keychain
786
+ (void)removeCredentialsForHost:(NSString *)host port:(int)port protocol:(NSString *)protocol realm:(NSString *)realm;
787
+ (void)removeCredentialsForProxy:(NSString *)host port:(int)port realm:(NSString *)realm;
788

    
789
// We keep track of any cookies we accept, so that we can remove them from the persistent store later
790
+ (void)setSessionCookies:(NSMutableArray *)newSessionCookies;
791
+ (NSMutableArray *)sessionCookies;
792

    
793
// Adds a cookie to our list of cookies we've accepted, checking first for an old version of the same cookie and removing that
794
+ (void)addSessionCookie:(NSHTTPCookie *)newCookie;
795

    
796
// Dump all session data (authentication and cookies)
797
+ (void)clearSession;
798

    
799
#pragma mark get user agent
800

    
801
// Will be used as a user agent if requests do not specify a custom user agent
802
// Is only used when you have specified a Bundle Display Name (CFDisplayBundleName) or Bundle Name (CFBundleName) in your plist
803
+ (NSString *)defaultUserAgentString;
804
+ (void)setDefaultUserAgentString:(NSString *)agent;
805

    
806
#pragma mark mime-type detection
807

    
808
// Return the mime type for a file
809
+ (NSString *)mimeTypeForFileAtPath:(NSString *)path;
810

    
811
#pragma mark bandwidth measurement / throttling
812

    
813
// The maximum number of bytes ALL requests can send / receive in a second
814
// This is a rough figure. The actual amount used will be slightly more, this does not include HTTP headers
815
+ (unsigned long)maxBandwidthPerSecond;
816
+ (void)setMaxBandwidthPerSecond:(unsigned long)bytes;
817

    
818
// Get a rough average (for the last 5 seconds) of how much bandwidth is being used, in bytes
819
+ (unsigned long)averageBandwidthUsedPerSecond;
820

    
821
- (void)performThrottling;
822

    
823
// Will return YES is bandwidth throttling is currently in use
824
+ (BOOL)isBandwidthThrottled;
825

    
826
// Used internally to record bandwidth use, and by ASIInputStreams when uploading. It's probably best if you don't mess with this.
827
+ (void)incrementBandwidthUsedInLastSecond:(unsigned long)bytes;
828

    
829
// On iPhone, ASIHTTPRequest can automatically turn throttling on and off as the connection type changes between WWAN and WiFi
830

    
831
#if TARGET_OS_IPHONE
832
// Set to YES to automatically turn on throttling when WWAN is connected, and automatically turn it off when it isn't
833
+ (void)setShouldThrottleBandwidthForWWAN:(BOOL)throttle;
834

    
835
// Turns on throttling automatically when WWAN is connected using a custom limit, and turns it off automatically when it isn't
836
+ (void)throttleBandwidthForWWANUsingLimit:(unsigned long)limit;
837

    
838
#pragma mark reachability
839

    
840
// Returns YES when an iPhone OS device is connected via WWAN, false when connected via WIFI or not connected
841
+ (BOOL)isNetworkReachableViaWWAN;
842

    
843
#endif
844

    
845
#pragma mark queue
846

    
847
// Returns the shared queue
848
+ (NSOperationQueue *)sharedQueue;
849

    
850
#pragma mark cache
851

    
852
+ (void)setDefaultCache:(id <ASICacheDelegate>)cache;
853
+ (id <ASICacheDelegate>)defaultCache;
854

    
855
// Returns the maximum amount of data we can read as part of the current measurement period, and sleeps this thread if our allowance is used up
856
+ (unsigned long)maxUploadReadLength;
857

    
858
#pragma mark network activity
859

    
860
+ (BOOL)isNetworkInUse;
861

    
862
+ (void)setShouldUpdateNetworkActivityIndicator:(BOOL)shouldUpdate;
863

    
864
// Shows the network activity spinner thing on iOS. You may wish to override this to do something else in Mac projects
865
+ (void)showNetworkActivityIndicator;
866

    
867
// Hides the network activity spinner thing on iOS
868
+ (void)hideNetworkActivityIndicator;
869

    
870
#pragma mark miscellany
871

    
872
// Used for generating Authorization header when using basic authentication when shouldPresentCredentialsBeforeChallenge is true
873
// And also by ASIS3Request
874
+ (NSString *)base64forData:(NSData *)theData;
875

    
876
// Returns the expiration date for the request.
877
// Calculated from the Expires response header property, unless maxAge is non-zero or
878
// there exists a non-zero max-age property in the Cache-Control response header.
879
+ (NSDate *)expiryDateForRequest:(ASIHTTPRequest *)request maxAge:(NSTimeInterval)maxAge;
880

    
881
// Returns a date from a string in RFC1123 format
882
+ (NSDate *)dateFromRFC1123String:(NSString *)string;
883

    
884

    
885
// Used for detecting multitasking support at runtime (for backgrounding requests)
886
#if TARGET_OS_IPHONE
887
+ (BOOL)isMultitaskingSupported;
888
#endif
889

    
890
#pragma mark threading behaviour
891

    
892
// In the default implementation, all requests run in a single background thread
893
// Advanced users only: Override this method in a subclass for a different threading behaviour
894
// Eg: return [NSThread mainThread] to run all requests in the main thread
895
// Alternatively, you can create a thread on demand, or manage a pool of threads
896
// Threads returned by this method will need to run the runloop in default mode (eg CFRunLoopRun())
897
// Requests will stop the runloop when they complete
898
// If you have multiple requests sharing the thread you'll need to restart the runloop when this happens
899
+ (NSThread *)threadForRequest:(ASIHTTPRequest *)request;
900

    
901

    
902
#pragma mark ===
903

    
904
@property (retain) NSString *username;
905
@property (retain) NSString *password;
906
@property (retain) NSString *userAgentString;
907
@property (retain) NSString *domain;
908

    
909
@property (retain) NSString *proxyUsername;
910
@property (retain) NSString *proxyPassword;
911
@property (retain) NSString *proxyDomain;
912

    
913
@property (retain) NSString *proxyHost;
914
@property (assign) int proxyPort;
915
@property (retain) NSString *proxyType;
916

    
917
@property (retain,setter=setURL:, nonatomic) NSURL *url;
918
@property (retain) NSURL *originalURL;
919
@property (assign, nonatomic) id delegate;
920
@property (retain, nonatomic) id queue;
921
@property (assign, nonatomic) id uploadProgressDelegate;
922
@property (assign, nonatomic) id downloadProgressDelegate;
923
@property (assign) BOOL useKeychainPersistence;
924
@property (assign) BOOL useSessionPersistence;
925
@property (retain) NSString *downloadDestinationPath;
926
@property (retain) NSString *temporaryFileDownloadPath;
927
@property (retain) NSString *temporaryUncompressedDataDownloadPath;
928
@property (assign) SEL didStartSelector;
929
@property (assign) SEL didReceiveResponseHeadersSelector;
930
@property (assign) SEL willRedirectSelector;
931
@property (assign) SEL didFinishSelector;
932
@property (assign) SEL didFailSelector;
933
@property (assign) SEL didReceiveDataSelector;
934
@property (retain,readonly) NSString *authenticationRealm;
935
@property (retain,readonly) NSString *proxyAuthenticationRealm;
936
@property (retain) NSError *error;
937
@property (assign,readonly) BOOL complete;
938
@property (retain) NSDictionary *responseHeaders;
939
@property (retain) NSMutableDictionary *requestHeaders;
940
@property (retain) NSMutableArray *requestCookies;
941
@property (retain,readonly) NSArray *responseCookies;
942
@property (assign) BOOL useCookiePersistence;
943
@property (retain) NSDictionary *requestCredentials;
944
@property (retain) NSDictionary *proxyCredentials;
945
@property (assign,readonly) int responseStatusCode;
946
@property (retain,readonly) NSString *responseStatusMessage;
947
@property (retain) NSMutableData *rawResponseData;
948
@property (assign) NSTimeInterval timeOutSeconds;
949
@property (retain, nonatomic) NSString *requestMethod;
950
@property (retain) NSMutableData *postBody;
951
@property (assign) unsigned long long contentLength;
952
@property (assign) unsigned long long postLength;
953
@property (assign) BOOL shouldResetDownloadProgress;
954
@property (assign) BOOL shouldResetUploadProgress;
955
@property (assign) ASIHTTPRequest *mainRequest;
956
@property (assign) BOOL showAccurateProgress;
957
@property (assign) unsigned long long totalBytesRead;
958
@property (assign) unsigned long long totalBytesSent;
959
@property (assign) NSStringEncoding defaultResponseEncoding;
960
@property (assign) NSStringEncoding responseEncoding;
961
@property (assign) BOOL allowCompressedResponse;
962
@property (assign) BOOL allowResumeForFileDownloads;
963
@property (retain) NSDictionary *userInfo;
964
@property (assign) NSInteger tag;
965
@property (retain) NSString *postBodyFilePath;
966
@property (assign) BOOL shouldStreamPostDataFromDisk;
967
@property (assign) BOOL didCreateTemporaryPostDataFile;
968
@property (assign) BOOL useHTTPVersionOne;
969
@property (assign, readonly) unsigned long long partialDownloadSize;
970
@property (assign) BOOL shouldRedirect;
971
@property (assign) BOOL validatesSecureCertificate;
972
@property (assign) BOOL shouldCompressRequestBody;
973
@property (retain) NSURL *PACurl;
974
@property (retain) NSString *authenticationScheme;
975
@property (retain) NSString *proxyAuthenticationScheme;
976
@property (assign) BOOL shouldPresentAuthenticationDialog;
977
@property (assign) BOOL shouldPresentProxyAuthenticationDialog;
978
@property (assign, readonly) ASIAuthenticationState authenticationNeeded;
979
@property (assign) BOOL shouldPresentCredentialsBeforeChallenge;
980
@property (assign, readonly) int authenticationRetryCount;
981
@property (assign, readonly) int proxyAuthenticationRetryCount;
982
@property (assign) BOOL haveBuiltRequestHeaders;
983
@property (assign, nonatomic) BOOL haveBuiltPostBody;
984
@property (assign, readonly) BOOL inProgress;
985
@property (assign) int numberOfTimesToRetryOnTimeout;
986
@property (assign, readonly) int retryCount;
987
@property (assign) BOOL shouldAttemptPersistentConnection;
988
@property (assign) NSTimeInterval persistentConnectionTimeoutSeconds;
989
@property (assign) BOOL shouldUseRFC2616RedirectBehaviour;
990
@property (assign, readonly) BOOL connectionCanBeReused;
991
@property (retain, readonly) NSNumber *requestID;
992
@property (assign) id <ASICacheDelegate> downloadCache;
993
@property (assign) ASICachePolicy cachePolicy;
994
@property (assign) ASICacheStoragePolicy cacheStoragePolicy;
995
@property (assign, readonly) BOOL didUseCachedResponse;
996
@property (assign) NSTimeInterval secondsToCache;
997
@property (retain) NSArray *clientCertificates;
998
#if TARGET_OS_IPHONE && __IPHONE_OS_VERSION_MAX_ALLOWED >= __IPHONE_4_0
999
@property (assign) BOOL shouldContinueWhenAppEntersBackground;
1000
#endif
1001
@property (retain) ASIDataDecompressor *dataDecompressor;
1002
@property (assign) BOOL shouldWaitToInflateCompressedResponses;
1003

    
1004
@end