/core/externals/update-engine/externals/gdata-objectivec-client/Source/HTTPFetcher/GTMHTTPFetcher.h

http://macfuse.googlecode.com/ · C Header · 767 lines · 239 code · 106 blank · 422 comment · 1 complexity · 9f8ba41fffe2e8c94700c35468c04fb9 MD5 · raw file

  1. /* Copyright (c) 2011 Google Inc.
  2. *
  3. * Licensed under the Apache License, Version 2.0 (the "License");
  4. * you may not use this file except in compliance with the License.
  5. * You may obtain a copy of the License at
  6. *
  7. * http://www.apache.org/licenses/LICENSE-2.0
  8. *
  9. * Unless required by applicable law or agreed to in writing, software
  10. * distributed under the License is distributed on an "AS IS" BASIS,
  11. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. * See the License for the specific language governing permissions and
  13. * limitations under the License.
  14. */
  15. //
  16. // GTMHTTPFetcher.h
  17. //
  18. // This is essentially a wrapper around NSURLConnection for POSTs and GETs.
  19. // If setPostData: is called, then POST is assumed.
  20. //
  21. // When would you use this instead of NSURLConnection?
  22. //
  23. // - When you just want the result from a GET, POST, or PUT
  24. // - When you want the "standard" behavior for connections (redirection handling
  25. // an so on)
  26. // - When you want automatic retry on failures
  27. // - When you want to avoid cookie collisions with Safari and other applications
  28. // - When you are fetching resources with ETags and want to avoid the overhead
  29. // of repeated fetches of unchanged data
  30. // - When you need to set a credential for the http operation
  31. //
  32. // This is assumed to be a one-shot fetch request; don't reuse the object
  33. // for a second fetch.
  34. //
  35. // The fetcher may be created auto-released, in which case it will release
  36. // itself after the fetch completion callback. The fetcher is implicitly
  37. // retained as long as a connection is pending.
  38. //
  39. // But if you may need to cancel the fetcher, retain it and have the delegate
  40. // release the fetcher in the callbacks.
  41. //
  42. // Sample usage:
  43. //
  44. // NSURLRequest *request = [NSURLRequest requestWithURL:myURL];
  45. // GTMHTTPFetcher* myFetcher = [GTMHTTPFetcher fetcherWithRequest:request];
  46. //
  47. // // optional upload body data
  48. // [myFetcher setPostData:[postString dataUsingEncoding:NSUTF8StringEncoding]];
  49. //
  50. // [myFetcher beginFetchWithDelegate:self
  51. // didFinishSelector:@selector(myFetcher:finishedWithData:error:)];
  52. //
  53. // Upon fetch completion, the callback selector is invoked; it should have
  54. // this signature (you can use any callback method name you want so long as
  55. // the signature matches this):
  56. //
  57. // - (void)myFetcher:(GTMHTTPFetcher *)fetcher finishedWithData:(NSData *)retrievedData error:(NSError *)error;
  58. //
  59. // The block callback version looks like:
  60. //
  61. // [myFetcher beginFetchWithCompletionHandler:^(NSData *retrievedData, NSError *error) {
  62. // if (error != nil) {
  63. // // status code or network error
  64. // } else {
  65. // // succeeded
  66. // }
  67. // }];
  68. //
  69. // NOTE: Fetches may retrieve data from the server even though the server
  70. // returned an error. The failure selector is called when the server
  71. // status is >= 300, with an NSError having domain
  72. // kGTMHTTPFetcherStatusDomain and code set to the server status.
  73. //
  74. // Status codes are at <http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html>
  75. //
  76. //
  77. // Threading and queue support:
  78. //
  79. // Callbacks require either that the thread used to start the fetcher have a run
  80. // loop spinning (typically the main thread), or that an NSOperationQueue be
  81. // provided upon which the delegate callbacks will be called. Starting with
  82. // iOS 6 and Mac OS X 10.7, clients may simply create an operation queue for
  83. // callbacks on a background thread:
  84. //
  85. // NSOperationQueue *queue = [[[NSOperationQueue alloc] init] autorelease];
  86. // [queue setMaxConcurrentOperationCount:1];
  87. // fetcher.delegateQueue = queue;
  88. //
  89. // or specify the main queue for callbacks on the main thread:
  90. //
  91. // fetcher.delegateQueue = [NSOperationQueue mainQueue];
  92. //
  93. // The client may also re-dispatch from the callbacks and notifications to
  94. // a known dispatch queue:
  95. //
  96. // [myFetcher beginFetchWithCompletionHandler:^(NSData *retrievedData, NSError *error) {
  97. // if (error == nil) {
  98. // dispatch_async(myDispatchQueue, ^{
  99. // ...
  100. // });
  101. // }
  102. // }];
  103. //
  104. //
  105. //
  106. // Downloading to disk:
  107. //
  108. // To have downloaded data saved directly to disk, specify either a path for the
  109. // downloadPath property, or a file handle for the downloadFileHandle property.
  110. // When downloading to disk, callbacks will be passed a nil for the NSData*
  111. // arguments.
  112. //
  113. //
  114. // HTTP methods and headers:
  115. //
  116. // Alternative HTTP methods, like PUT, and custom headers can be specified by
  117. // creating the fetcher with an appropriate NSMutableURLRequest
  118. //
  119. //
  120. // Proxies:
  121. //
  122. // Proxy handling is invisible so long as the system has a valid credential in
  123. // the keychain, which is normally true (else most NSURL-based apps would have
  124. // difficulty.) But when there is a proxy authetication error, the the fetcher
  125. // will call the failedWithError: method with the NSURLChallenge in the error's
  126. // userInfo. The error method can get the challenge info like this:
  127. //
  128. // NSURLAuthenticationChallenge *challenge
  129. // = [[error userInfo] objectForKey:kGTMHTTPFetcherErrorChallengeKey];
  130. // BOOL isProxyChallenge = [[challenge protectionSpace] isProxy];
  131. //
  132. // If a proxy error occurs, you can ask the user for the proxy username/password
  133. // and call fetcher's setProxyCredential: to provide those for the
  134. // next attempt to fetch.
  135. //
  136. //
  137. // Cookies:
  138. //
  139. // There are three supported mechanisms for remembering cookies between fetches.
  140. //
  141. // By default, GTMHTTPFetcher uses a mutable array held statically to track
  142. // cookies for all instantiated fetchers. This avoids server cookies being set
  143. // by servers for the application from interfering with Safari cookie settings,
  144. // and vice versa. The fetcher cookies are lost when the application quits.
  145. //
  146. // To rely instead on WebKit's global NSHTTPCookieStorage, call
  147. // setCookieStorageMethod: with kGTMHTTPFetcherCookieStorageMethodSystemDefault.
  148. //
  149. // If the fetcher is created from a GTMHTTPFetcherService object
  150. // then the cookie storage mechanism is set to use the cookie storage in the
  151. // service object rather than the static storage.
  152. //
  153. //
  154. // Fetching for periodic checks:
  155. //
  156. // The fetcher object tracks ETag headers from responses and
  157. // provide an "If-None-Match" header. This allows the server to save
  158. // bandwidth by providing a status message instead of repeated response
  159. // data.
  160. //
  161. // To get this behavior, create the fetcher from an GTMHTTPFetcherService object
  162. // and look for a fetch callback error with code 304
  163. // (kGTMHTTPFetcherStatusNotModified) like this:
  164. //
  165. // - (void)myFetcher:(GTMHTTPFetcher *)fetcher finishedWithData:(NSData *)data error:(NSError *)error {
  166. // if ([error code] == kGTMHTTPFetcherStatusNotModified) {
  167. // // |data| is empty; use the data from the previous finishedWithData: for this URL
  168. // } else {
  169. // // handle other server status code
  170. // }
  171. // }
  172. //
  173. //
  174. // Monitoring received data
  175. //
  176. // The optional received data selector can be set with setReceivedDataSelector:
  177. // and should have the signature
  178. //
  179. // - (void)myFetcher:(GTMHTTPFetcher *)fetcher receivedData:(NSData *)dataReceivedSoFar;
  180. //
  181. // The number bytes received so far is available as [fetcher downloadedLength].
  182. // This number may go down if a redirect causes the download to begin again from
  183. // a new server.
  184. //
  185. // If supplied by the server, the anticipated total download size is available
  186. // as [[myFetcher response] expectedContentLength] (and may be -1 for unknown
  187. // download sizes.)
  188. //
  189. //
  190. // Automatic retrying of fetches
  191. //
  192. // The fetcher can optionally create a timer and reattempt certain kinds of
  193. // fetch failures (status codes 408, request timeout; 503, service unavailable;
  194. // 504, gateway timeout; networking errors NSURLErrorTimedOut and
  195. // NSURLErrorNetworkConnectionLost.) The user may set a retry selector to
  196. // customize the type of errors which will be retried.
  197. //
  198. // Retries are done in an exponential-backoff fashion (that is, after 1 second,
  199. // 2, 4, 8, and so on.)
  200. //
  201. // Enabling automatic retries looks like this:
  202. // [myFetcher setRetryEnabled:YES];
  203. //
  204. // With retries enabled, the success or failure callbacks are called only
  205. // when no more retries will be attempted. Calling the fetcher's stopFetching
  206. // method will terminate the retry timer, without the finished or failure
  207. // selectors being invoked.
  208. //
  209. // Optionally, the client may set the maximum retry interval:
  210. // [myFetcher setMaxRetryInterval:60.0]; // in seconds; default is 60 seconds
  211. // // for downloads, 600 for uploads
  212. //
  213. // Also optionally, the client may provide a callback selector to determine
  214. // if a status code or other error should be retried.
  215. // [myFetcher setRetrySelector:@selector(myFetcher:willRetry:forError:)];
  216. //
  217. // If set, the retry selector should have the signature:
  218. // -(BOOL)fetcher:(GTMHTTPFetcher *)fetcher willRetry:(BOOL)suggestedWillRetry forError:(NSError *)error
  219. // and return YES to set the retry timer or NO to fail without additional
  220. // fetch attempts.
  221. //
  222. // The retry method may return the |suggestedWillRetry| argument to get the
  223. // default retry behavior. Server status codes are present in the
  224. // error argument, and have the domain kGTMHTTPFetcherStatusDomain. The
  225. // user's method may look something like this:
  226. //
  227. // -(BOOL)myFetcher:(GTMHTTPFetcher *)fetcher willRetry:(BOOL)suggestedWillRetry forError:(NSError *)error {
  228. //
  229. // // perhaps examine [error domain] and [error code], or [fetcher retryCount]
  230. // //
  231. // // return YES to start the retry timer, NO to proceed to the failure
  232. // // callback, or |suggestedWillRetry| to get default behavior for the
  233. // // current error domain and code values.
  234. // return suggestedWillRetry;
  235. // }
  236. #pragma once
  237. #import <Foundation/Foundation.h>
  238. #if defined(GTL_TARGET_NAMESPACE)
  239. // we're using target namespace macros
  240. #import "GTLDefines.h"
  241. #elif defined(GDATA_TARGET_NAMESPACE)
  242. #import "GDataDefines.h"
  243. #else
  244. #if TARGET_OS_IPHONE
  245. #ifndef GTM_FOUNDATION_ONLY
  246. #define GTM_FOUNDATION_ONLY 1
  247. #endif
  248. #ifndef GTM_IPHONE
  249. #define GTM_IPHONE 1
  250. #endif
  251. #endif
  252. #endif
  253. #if TARGET_OS_IPHONE && (__IPHONE_OS_VERSION_MAX_ALLOWED >= 40000)
  254. #define GTM_BACKGROUND_FETCHING 1
  255. #endif
  256. #ifdef __cplusplus
  257. extern "C" {
  258. #endif
  259. // notifications
  260. //
  261. // fetch started and stopped, and fetch retry delay started and stopped
  262. extern NSString *const kGTMHTTPFetcherStartedNotification;
  263. extern NSString *const kGTMHTTPFetcherStoppedNotification;
  264. extern NSString *const kGTMHTTPFetcherRetryDelayStartedNotification;
  265. extern NSString *const kGTMHTTPFetcherRetryDelayStoppedNotification;
  266. // callback constants
  267. extern NSString *const kGTMHTTPFetcherErrorDomain;
  268. extern NSString *const kGTMHTTPFetcherStatusDomain;
  269. extern NSString *const kGTMHTTPFetcherErrorChallengeKey;
  270. extern NSString *const kGTMHTTPFetcherStatusDataKey; // data returned with a kGTMHTTPFetcherStatusDomain error
  271. #ifdef __cplusplus
  272. }
  273. #endif
  274. enum {
  275. kGTMHTTPFetcherErrorDownloadFailed = -1,
  276. kGTMHTTPFetcherErrorAuthenticationChallengeFailed = -2,
  277. kGTMHTTPFetcherErrorChunkUploadFailed = -3,
  278. kGTMHTTPFetcherErrorFileHandleException = -4,
  279. kGTMHTTPFetcherErrorBackgroundExpiration = -6,
  280. // The code kGTMHTTPFetcherErrorAuthorizationFailed (-5) has been removed;
  281. // look for status 401 instead.
  282. kGTMHTTPFetcherStatusNotModified = 304,
  283. kGTMHTTPFetcherStatusBadRequest = 400,
  284. kGTMHTTPFetcherStatusUnauthorized = 401,
  285. kGTMHTTPFetcherStatusForbidden = 403,
  286. kGTMHTTPFetcherStatusPreconditionFailed = 412
  287. };
  288. // cookie storage methods
  289. enum {
  290. kGTMHTTPFetcherCookieStorageMethodStatic = 0,
  291. kGTMHTTPFetcherCookieStorageMethodFetchHistory = 1,
  292. kGTMHTTPFetcherCookieStorageMethodSystemDefault = 2,
  293. kGTMHTTPFetcherCookieStorageMethodNone = 3
  294. };
  295. #ifdef __cplusplus
  296. extern "C" {
  297. #endif
  298. void GTMAssertSelectorNilOrImplementedWithArgs(id obj, SEL sel, ...);
  299. // Utility functions for applications self-identifying to servers via a
  300. // user-agent header
  301. // Make a proper app name without whitespace from the given string, removing
  302. // whitespace and other characters that may be special parsed marks of
  303. // the full user-agent string.
  304. NSString *GTMCleanedUserAgentString(NSString *str);
  305. // Make an identifier like "MacOSX/10.7.1" or "iPod_Touch/4.1"
  306. NSString *GTMSystemVersionString(void);
  307. // Make a generic name and version for the current application, like
  308. // com.example.MyApp/1.2.3 relying on the bundle identifier and the
  309. // CFBundleShortVersionString or CFBundleVersion.
  310. //
  311. // The bundle ID may be overridden as the base identifier string by
  312. // adding to the bundle's Info.plist a "GTMUserAgentID" key.
  313. //
  314. // If no bundle ID or override is available, the process name preceded
  315. // by "proc_" is used.
  316. NSString *GTMApplicationIdentifier(NSBundle *bundle);
  317. #ifdef __cplusplus
  318. } // extern "C"
  319. #endif
  320. @class GTMHTTPFetcher;
  321. @protocol GTMCookieStorageProtocol <NSObject>
  322. // This protocol allows us to call into the service without requiring
  323. // GTMCookieStorage sources in this project
  324. //
  325. // The public interface for cookie handling is the GTMCookieStorage class,
  326. // accessible from a fetcher service object's fetchHistory or from the fetcher's
  327. // +staticCookieStorage method.
  328. - (NSArray *)cookiesForURL:(NSURL *)theURL;
  329. - (void)setCookies:(NSArray *)newCookies;
  330. @end
  331. @protocol GTMHTTPFetchHistoryProtocol <NSObject>
  332. // This protocol allows us to call the fetch history object without requiring
  333. // GTMHTTPFetchHistory sources in this project
  334. - (void)updateRequest:(NSMutableURLRequest *)request isHTTPGet:(BOOL)isHTTPGet;
  335. - (BOOL)shouldCacheETaggedData;
  336. - (NSData *)cachedDataForRequest:(NSURLRequest *)request;
  337. - (id <GTMCookieStorageProtocol>)cookieStorage;
  338. - (void)updateFetchHistoryWithRequest:(NSURLRequest *)request
  339. response:(NSURLResponse *)response
  340. downloadedData:(NSData *)downloadedData;
  341. - (void)removeCachedDataForRequest:(NSURLRequest *)request;
  342. @end
  343. @protocol GTMHTTPFetcherServiceProtocol <NSObject>
  344. // This protocol allows us to call into the service without requiring
  345. // GTMHTTPFetcherService sources in this project
  346. @property (retain) NSOperationQueue *delegateQueue;
  347. - (BOOL)fetcherShouldBeginFetching:(GTMHTTPFetcher *)fetcher;
  348. - (void)fetcherDidStop:(GTMHTTPFetcher *)fetcher;
  349. - (GTMHTTPFetcher *)fetcherWithRequest:(NSURLRequest *)request;
  350. - (BOOL)isDelayingFetcher:(GTMHTTPFetcher *)fetcher;
  351. @end
  352. @protocol GTMFetcherAuthorizationProtocol <NSObject>
  353. @required
  354. // This protocol allows us to call the authorizer without requiring its sources
  355. // in this project.
  356. - (void)authorizeRequest:(NSMutableURLRequest *)request
  357. delegate:(id)delegate
  358. didFinishSelector:(SEL)sel;
  359. - (void)stopAuthorization;
  360. - (void)stopAuthorizationForRequest:(NSURLRequest *)request;
  361. - (BOOL)isAuthorizingRequest:(NSURLRequest *)request;
  362. - (BOOL)isAuthorizedRequest:(NSURLRequest *)request;
  363. @property (retain, readonly) NSString *userEmail;
  364. @optional
  365. // Indicate if authorization may be attempted. Even if this succeeds,
  366. // authorization may fail if the user's permissions have been revoked.
  367. @property (readonly) BOOL canAuthorize;
  368. // For development only, allow authorization of non-SSL requests, allowing
  369. // transmission of the bearer token unencrypted.
  370. @property (assign) BOOL shouldAuthorizeAllRequests;
  371. #if NS_BLOCKS_AVAILABLE
  372. - (void)authorizeRequest:(NSMutableURLRequest *)request
  373. completionHandler:(void (^)(NSError *error))handler;
  374. #endif
  375. @property (assign) id <GTMHTTPFetcherServiceProtocol> fetcherService; // WEAK
  376. - (BOOL)primeForRefresh;
  377. @end
  378. // GTMHTTPFetcher objects are used for async retrieval of an http get or post
  379. //
  380. // See additional comments at the beginning of this file
  381. @interface GTMHTTPFetcher : NSObject {
  382. @protected
  383. NSMutableURLRequest *request_;
  384. NSURLConnection *connection_;
  385. NSMutableData *downloadedData_;
  386. NSString *downloadPath_;
  387. NSString *temporaryDownloadPath_;
  388. NSFileHandle *downloadFileHandle_;
  389. unsigned long long downloadedLength_;
  390. NSURLCredential *credential_; // username & password
  391. NSURLCredential *proxyCredential_; // credential supplied to proxy servers
  392. NSData *postData_;
  393. NSInputStream *postStream_;
  394. NSMutableData *loggedStreamData_;
  395. NSURLResponse *response_; // set in connection:didReceiveResponse:
  396. id delegate_;
  397. SEL finishedSel_; // should by implemented by delegate
  398. SEL sentDataSel_; // optional, set with setSentDataSelector
  399. SEL receivedDataSel_; // optional, set with setReceivedDataSelector
  400. #if NS_BLOCKS_AVAILABLE
  401. void (^completionBlock_)(NSData *, NSError *);
  402. void (^receivedDataBlock_)(NSData *);
  403. void (^sentDataBlock_)(NSInteger, NSInteger, NSInteger);
  404. BOOL (^retryBlock_)(BOOL, NSError *);
  405. #elif !__LP64__
  406. // placeholders: for 32-bit builds, keep the size of the object's ivar section
  407. // the same with and without blocks
  408. id completionPlaceholder_;
  409. id receivedDataPlaceholder_;
  410. id sentDataPlaceholder_;
  411. id retryPlaceholder_;
  412. #endif
  413. BOOL hasConnectionEnded_; // set if the connection need not be cancelled
  414. BOOL isCancellingChallenge_; // set only when cancelling an auth challenge
  415. BOOL isStopNotificationNeeded_; // set when start notification has been sent
  416. BOOL shouldFetchInBackground_;
  417. #if GTM_BACKGROUND_FETCHING
  418. NSUInteger backgroundTaskIdentifer_; // UIBackgroundTaskIdentifier
  419. #endif
  420. id userData_; // retained, if set by caller
  421. NSMutableDictionary *properties_; // more data retained for caller
  422. NSArray *runLoopModes_; // optional
  423. NSOperationQueue *delegateQueue_; // optional; available iOS 6/10.7 and later
  424. id <GTMHTTPFetchHistoryProtocol> fetchHistory_; // if supplied by the caller, used for Last-Modified-Since checks and cookies
  425. NSInteger cookieStorageMethod_; // constant from above
  426. id <GTMCookieStorageProtocol> cookieStorage_;
  427. id <GTMFetcherAuthorizationProtocol> authorizer_;
  428. // the service object that created and monitors this fetcher, if any
  429. id <GTMHTTPFetcherServiceProtocol> service_;
  430. NSString *serviceHost_;
  431. NSInteger servicePriority_;
  432. NSThread *thread_;
  433. BOOL isRetryEnabled_; // user wants auto-retry
  434. SEL retrySel_; // optional; set with setRetrySelector
  435. NSTimer *retryTimer_;
  436. NSUInteger retryCount_;
  437. NSTimeInterval maxRetryInterval_; // default 600 seconds
  438. NSTimeInterval minRetryInterval_; // random between 1 and 2 seconds
  439. NSTimeInterval retryFactor_; // default interval multiplier is 2
  440. NSTimeInterval lastRetryInterval_;
  441. NSDate *initialRequestDate_;
  442. BOOL hasAttemptedAuthRefresh_;
  443. NSString *comment_; // comment for log
  444. NSString *log_;
  445. #if !STRIP_GTM_FETCH_LOGGING
  446. NSURL *redirectedFromURL_;
  447. NSString *logRequestBody_;
  448. NSString *logResponseBody_;
  449. BOOL hasLoggedError_;
  450. BOOL shouldDeferResponseBodyLogging_;
  451. #endif
  452. }
  453. // Create a fetcher
  454. //
  455. // fetcherWithRequest will return an autoreleased fetcher, but if
  456. // the connection is successfully created, the connection should retain the
  457. // fetcher for the life of the connection as well. So the caller doesn't have
  458. // to retain the fetcher explicitly unless they want to be able to cancel it.
  459. + (GTMHTTPFetcher *)fetcherWithRequest:(NSURLRequest *)request;
  460. // Convenience methods that make a request, like +fetcherWithRequest
  461. + (GTMHTTPFetcher *)fetcherWithURL:(NSURL *)requestURL;
  462. + (GTMHTTPFetcher *)fetcherWithURLString:(NSString *)requestURLString;
  463. // Designated initializer
  464. - (id)initWithRequest:(NSURLRequest *)request;
  465. // Fetcher request
  466. //
  467. // The underlying request is mutable and may be modified by the caller
  468. @property (retain) NSMutableURLRequest *mutableRequest;
  469. // Setting the credential is optional; it is used if the connection receives
  470. // an authentication challenge
  471. @property (retain) NSURLCredential *credential;
  472. // Setting the proxy credential is optional; it is used if the connection
  473. // receives an authentication challenge from a proxy
  474. @property (retain) NSURLCredential *proxyCredential;
  475. // If post data or stream is not set, then a GET retrieval method is assumed
  476. @property (retain) NSData *postData;
  477. @property (retain) NSInputStream *postStream;
  478. // The default cookie storage method is kGTMHTTPFetcherCookieStorageMethodStatic
  479. // without a fetch history set, and kGTMHTTPFetcherCookieStorageMethodFetchHistory
  480. // with a fetch history set
  481. //
  482. // Applications needing control of cookies across a sequence of fetches should
  483. // create fetchers from a GTMHTTPFetcherService object (which encapsulates
  484. // fetch history) for a well-defined cookie store
  485. @property (assign) NSInteger cookieStorageMethod;
  486. + (id <GTMCookieStorageProtocol>)staticCookieStorage;
  487. // Object to add authorization to the request, if needed
  488. @property (retain) id <GTMFetcherAuthorizationProtocol> authorizer;
  489. // The service object that created and monitors this fetcher, if any
  490. @property (retain) id <GTMHTTPFetcherServiceProtocol> service;
  491. // The host, if any, used to classify this fetcher in the fetcher service
  492. @property (copy) NSString *serviceHost;
  493. // The priority, if any, used for starting fetchers in the fetcher service
  494. //
  495. // Lower values are higher priority; the default is 0, and values may
  496. // be negative or positive. This priority affects only the start order of
  497. // fetchers that are being delayed by a fetcher service.
  498. @property (assign) NSInteger servicePriority;
  499. // The thread used to run this fetcher in the fetcher service when no operation
  500. // queue is provided.
  501. @property (retain) NSThread *thread;
  502. // The delegate is retained during the connection
  503. @property (retain) id delegate;
  504. // On iOS 4 and later, the fetch may optionally continue while the app is in the
  505. // background until finished or stopped by OS expiration
  506. //
  507. // The default value is NO
  508. //
  509. // For Mac OS X, background fetches are always supported, and this property
  510. // is ignored
  511. @property (assign) BOOL shouldFetchInBackground;
  512. // The delegate's optional sentData selector may be used to monitor upload
  513. // progress. It should have a signature like:
  514. // - (void)myFetcher:(GTMHTTPFetcher *)fetcher
  515. // didSendBytes:(NSInteger)bytesSent
  516. // totalBytesSent:(NSInteger)totalBytesSent
  517. // totalBytesExpectedToSend:(NSInteger)totalBytesExpectedToSend;
  518. //
  519. // +doesSupportSentDataCallback indicates if this delegate method is supported
  520. + (BOOL)doesSupportSentDataCallback;
  521. @property (assign) SEL sentDataSelector;
  522. // The delegate's optional receivedData selector may be used to monitor download
  523. // progress. It should have a signature like:
  524. // - (void)myFetcher:(GTMHTTPFetcher *)fetcher
  525. // receivedData:(NSData *)dataReceivedSoFar;
  526. //
  527. // The dataReceived argument will be nil when downloading to a path or to a
  528. // file handle.
  529. //
  530. // Applications should not use this method to accumulate the received data;
  531. // the callback method or block supplied to the beginFetch call will have
  532. // the complete NSData received.
  533. @property (assign) SEL receivedDataSelector;
  534. #if NS_BLOCKS_AVAILABLE
  535. // The full interface to the block is provided rather than just a typedef for
  536. // its parameter list in order to get more useful code completion in the Xcode
  537. // editor
  538. @property (copy) void (^sentDataBlock)(NSInteger bytesSent, NSInteger totalBytesSent, NSInteger bytesExpectedToSend);
  539. // The dataReceived argument will be nil when downloading to a path or to
  540. // a file handle
  541. @property (copy) void (^receivedDataBlock)(NSData *dataReceivedSoFar);
  542. #endif
  543. // retrying; see comments at the top of the file. Calling
  544. // setRetryEnabled(YES) resets the min and max retry intervals.
  545. @property (assign, getter=isRetryEnabled) BOOL retryEnabled;
  546. // Retry selector or block is optional for retries.
  547. //
  548. // If present, it should have the signature:
  549. // -(BOOL)fetcher:(GTMHTTPFetcher *)fetcher willRetry:(BOOL)suggestedWillRetry forError:(NSError *)error
  550. // and return YES to cause a retry. See comments at the top of this file.
  551. @property (assign) SEL retrySelector;
  552. #if NS_BLOCKS_AVAILABLE
  553. @property (copy) BOOL (^retryBlock)(BOOL suggestedWillRetry, NSError *error);
  554. #endif
  555. // Retry intervals must be strictly less than maxRetryInterval, else
  556. // they will be limited to maxRetryInterval and no further retries will
  557. // be attempted. Setting maxRetryInterval to 0.0 will reset it to the
  558. // default value, 600 seconds.
  559. @property (assign) NSTimeInterval maxRetryInterval;
  560. // Starting retry interval. Setting minRetryInterval to 0.0 will reset it
  561. // to a random value between 1.0 and 2.0 seconds. Clients should normally not
  562. // call this except for unit testing.
  563. @property (assign) NSTimeInterval minRetryInterval;
  564. // Multiplier used to increase the interval between retries, typically 2.0.
  565. // Clients should not need to call this.
  566. @property (assign) double retryFactor;
  567. // Number of retries attempted
  568. @property (readonly) NSUInteger retryCount;
  569. // interval delay to precede next retry
  570. @property (readonly) NSTimeInterval nextRetryInterval;
  571. // Begin fetching the request
  572. //
  573. // The delegate can optionally implement the finished selectors or pass NULL
  574. // for it.
  575. //
  576. // Returns YES if the fetch is initiated. The delegate is retained between
  577. // the beginFetch call until after the finish callback.
  578. //
  579. // An error is passed to the callback for server statuses 300 or
  580. // higher, with the status stored as the error object's code.
  581. //
  582. // finishedSEL has a signature like:
  583. // - (void)fetcher:(GTMHTTPFetcher *)fetcher finishedWithData:(NSData *)data error:(NSError *)error;
  584. //
  585. // If the application has specified a downloadPath or downloadFileHandle
  586. // for the fetcher, the data parameter passed to the callback will be nil.
  587. - (BOOL)beginFetchWithDelegate:(id)delegate
  588. didFinishSelector:(SEL)finishedSEL;
  589. #if NS_BLOCKS_AVAILABLE
  590. - (BOOL)beginFetchWithCompletionHandler:(void (^)(NSData *data, NSError *error))handler;
  591. #endif
  592. // Returns YES if this is in the process of fetching a URL
  593. - (BOOL)isFetching;
  594. // Cancel the fetch of the request that's currently in progress
  595. - (void)stopFetching;
  596. // Return the status code from the server response
  597. @property (readonly) NSInteger statusCode;
  598. // Return the http headers from the response
  599. @property (retain, readonly) NSDictionary *responseHeaders;
  600. // The response, once it's been received
  601. @property (retain) NSURLResponse *response;
  602. // Bytes downloaded so far
  603. @property (readonly) unsigned long long downloadedLength;
  604. // Buffer of currently-downloaded data
  605. @property (readonly, retain) NSData *downloadedData;
  606. // Path in which to non-atomically create a file for storing the downloaded data
  607. //
  608. // The path must be set before fetching begins. The download file handle
  609. // will be created for the path, and can be used to monitor progress. If a file
  610. // already exists at the path, it will be overwritten.
  611. @property (copy) NSString *downloadPath;
  612. // If downloadFileHandle is set, data received is immediately appended to
  613. // the file handle rather than being accumulated in the downloadedData property
  614. //
  615. // The file handle supplied must allow writing and support seekToFileOffset:,
  616. // and must be set before fetching begins. Setting a download path will
  617. // override the file handle property.
  618. @property (retain) NSFileHandle *downloadFileHandle;
  619. // The optional fetchHistory object is used for a sequence of fetchers to
  620. // remember ETags, cache ETagged data, and store cookies. Typically, this
  621. // is set by a GTMFetcherService object when it creates a fetcher.
  622. //
  623. // Side effect: setting fetch history implicitly calls setCookieStorageMethod:
  624. @property (retain) id <GTMHTTPFetchHistoryProtocol> fetchHistory;
  625. // userData is retained for the convenience of the caller
  626. @property (retain) id userData;
  627. // Stored property values are retained for the convenience of the caller
  628. @property (copy) NSMutableDictionary *properties;
  629. - (void)setProperty:(id)obj forKey:(NSString *)key; // pass nil obj to remove property
  630. - (id)propertyForKey:(NSString *)key;
  631. - (void)addPropertiesFromDictionary:(NSDictionary *)dict;
  632. // Comments are useful for logging
  633. @property (copy) NSString *comment;
  634. - (void)setCommentWithFormat:(NSString *)format, ... NS_FORMAT_FUNCTION(1, 2);
  635. // Log of request and response, if logging is enabled
  636. @property (copy) NSString *log;
  637. // Callbacks can be invoked on an operation queue rather than via the run loop,
  638. // starting on 10.7 and iOS 6. If a delegate queue is supplied. the run loop
  639. // modes are ignored.
  640. @property (retain) NSOperationQueue *delegateQueue;
  641. // Using the fetcher while a modal dialog is displayed requires setting the
  642. // run-loop modes to include NSModalPanelRunLoopMode
  643. @property (retain) NSArray *runLoopModes;
  644. // Users who wish to replace GTMHTTPFetcher's use of NSURLConnection
  645. // can do so globally here. The replacement should be a subclass of
  646. // NSURLConnection.
  647. + (Class)connectionClass;
  648. + (void)setConnectionClass:(Class)theClass;
  649. // Spin the run loop, discarding events, until the fetch has completed
  650. //
  651. // This is only for use in testing or in tools without a user interface.
  652. //
  653. // Synchronous fetches should never be done by shipping apps; they are
  654. // sufficient reason for rejection from the app store.
  655. - (void)waitForCompletionWithTimeout:(NSTimeInterval)timeoutInSeconds;
  656. #if STRIP_GTM_FETCH_LOGGING
  657. // if logging is stripped, provide a stub for the main method
  658. // for controlling logging
  659. + (void)setLoggingEnabled:(BOOL)flag;
  660. #endif // STRIP_GTM_FETCH_LOGGING
  661. @end