aboutsummaryrefslogtreecommitdiffhomepage
path: root/example/common/gtm-oauth2/HTTPFetcher/GTMHTTPFetcher.h
diff options
context:
space:
mode:
Diffstat (limited to 'example/common/gtm-oauth2/HTTPFetcher/GTMHTTPFetcher.h')
-rwxr-xr-xexample/common/gtm-oauth2/HTTPFetcher/GTMHTTPFetcher.h766
1 files changed, 766 insertions, 0 deletions
diff --git a/example/common/gtm-oauth2/HTTPFetcher/GTMHTTPFetcher.h b/example/common/gtm-oauth2/HTTPFetcher/GTMHTTPFetcher.h
new file mode 100755
index 00000000..cd9a9ff6
--- /dev/null
+++ b/example/common/gtm-oauth2/HTTPFetcher/GTMHTTPFetcher.h
@@ -0,0 +1,766 @@
+/* Copyright (c) 2011 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+//
+// GTMHTTPFetcher.h
+//
+
+// This is essentially a wrapper around NSURLConnection for POSTs and GETs.
+// If setPostData: is called, then POST is assumed.
+//
+// When would you use this instead of NSURLConnection?
+//
+// - When you just want the result from a GET, POST, or PUT
+// - When you want the "standard" behavior for connections (redirection handling
+// an so on)
+// - When you want automatic retry on failures
+// - When you want to avoid cookie collisions with Safari and other applications
+// - When you are fetching resources with ETags and want to avoid the overhead
+// of repeated fetches of unchanged data
+// - When you need to set a credential for the http operation
+//
+// This is assumed to be a one-shot fetch request; don't reuse the object
+// for a second fetch.
+//
+// The fetcher may be created auto-released, in which case it will release
+// itself after the fetch completion callback. The fetcher is implicitly
+// retained as long as a connection is pending.
+//
+// But if you may need to cancel the fetcher, retain it and have the delegate
+// release the fetcher in the callbacks.
+//
+// Sample usage:
+//
+// NSURLRequest *request = [NSURLRequest requestWithURL:myURL];
+// GTMHTTPFetcher* myFetcher = [GTMHTTPFetcher fetcherWithRequest:request];
+//
+// // optional upload body data
+// [myFetcher setPostData:[postString dataUsingEncoding:NSUTF8StringEncoding]];
+//
+// [myFetcher beginFetchWithDelegate:self
+// didFinishSelector:@selector(myFetcher:finishedWithData:error:)];
+//
+// Upon fetch completion, the callback selector is invoked; it should have
+// this signature (you can use any callback method name you want so long as
+// the signature matches this):
+//
+// - (void)myFetcher:(GTMHTTPFetcher *)fetcher finishedWithData:(NSData *)retrievedData error:(NSError *)error;
+//
+// The block callback version looks like:
+//
+// [myFetcher beginFetchWithCompletionHandler:^(NSData *retrievedData, NSError *error) {
+// if (error != nil) {
+// // status code or network error
+// } else {
+// // succeeded
+// }
+// }];
+
+//
+// NOTE: Fetches may retrieve data from the server even though the server
+// returned an error. The failure selector is called when the server
+// status is >= 300, with an NSError having domain
+// kGTMHTTPFetcherStatusDomain and code set to the server status.
+//
+// Status codes are at <http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html>
+//
+//
+// Threading and queue support:
+//
+// Callbacks require either that the thread used to start the fetcher have a run
+// loop spinning (typically the main thread), or that an NSOperationQueue be
+// provided upon which the delegate callbacks will be called. Starting with
+// iOS 6 and Mac OS X 10.7, clients may simply create an operation queue for
+// callbacks on a background thread:
+//
+// NSOperationQueue *queue = [[[NSOperationQueue alloc] init] autorelease];
+// [queue setMaxConcurrentOperationCount:1];
+// fetcher.delegateQueue = queue;
+//
+// or specify the main queue for callbacks on the main thread:
+//
+// fetcher.delegateQueue = [NSOperationQueue mainQueue];
+//
+// The client may also re-dispatch from the callbacks and notifications to
+// a known dispatch queue:
+//
+// [myFetcher beginFetchWithCompletionHandler:^(NSData *retrievedData, NSError *error) {
+// if (error == nil) {
+// dispatch_async(myDispatchQueue, ^{
+// ...
+// });
+// }
+// }];
+//
+//
+//
+// Downloading to disk:
+//
+// To have downloaded data saved directly to disk, specify either a path for the
+// downloadPath property, or a file handle for the downloadFileHandle property.
+// When downloading to disk, callbacks will be passed a nil for the NSData*
+// arguments.
+//
+//
+// HTTP methods and headers:
+//
+// Alternative HTTP methods, like PUT, and custom headers can be specified by
+// creating the fetcher with an appropriate NSMutableURLRequest
+//
+//
+// Proxies:
+//
+// Proxy handling is invisible so long as the system has a valid credential in
+// the keychain, which is normally true (else most NSURL-based apps would have
+// difficulty.) But when there is a proxy authetication error, the the fetcher
+// will call the failedWithError: method with the NSURLChallenge in the error's
+// userInfo. The error method can get the challenge info like this:
+//
+// NSURLAuthenticationChallenge *challenge
+// = [[error userInfo] objectForKey:kGTMHTTPFetcherErrorChallengeKey];
+// BOOL isProxyChallenge = [[challenge protectionSpace] isProxy];
+//
+// If a proxy error occurs, you can ask the user for the proxy username/password
+// and call fetcher's setProxyCredential: to provide those for the
+// next attempt to fetch.
+//
+//
+// Cookies:
+//
+// There are three supported mechanisms for remembering cookies between fetches.
+//
+// By default, GTMHTTPFetcher uses a mutable array held statically to track
+// cookies for all instantiated fetchers. This avoids server cookies being set
+// by servers for the application from interfering with Safari cookie settings,
+// and vice versa. The fetcher cookies are lost when the application quits.
+//
+// To rely instead on WebKit's global NSHTTPCookieStorage, call
+// setCookieStorageMethod: with kGTMHTTPFetcherCookieStorageMethodSystemDefault.
+//
+// If the fetcher is created from a GTMHTTPFetcherService object
+// then the cookie storage mechanism is set to use the cookie storage in the
+// service object rather than the static storage.
+//
+//
+// Fetching for periodic checks:
+//
+// The fetcher object tracks ETag headers from responses and
+// provide an "If-None-Match" header. This allows the server to save
+// bandwidth by providing a status message instead of repeated response
+// data.
+//
+// To get this behavior, create the fetcher from an GTMHTTPFetcherService object
+// and look for a fetch callback error with code 304
+// (kGTMHTTPFetcherStatusNotModified) like this:
+//
+// - (void)myFetcher:(GTMHTTPFetcher *)fetcher finishedWithData:(NSData *)data error:(NSError *)error {
+// if ([error code] == kGTMHTTPFetcherStatusNotModified) {
+// // |data| is empty; use the data from the previous finishedWithData: for this URL
+// } else {
+// // handle other server status code
+// }
+// }
+//
+//
+// Monitoring received data
+//
+// The optional received data selector can be set with setReceivedDataSelector:
+// and should have the signature
+//
+// - (void)myFetcher:(GTMHTTPFetcher *)fetcher receivedData:(NSData *)dataReceivedSoFar;
+//
+// The number bytes received so far is available as [fetcher downloadedLength].
+// This number may go down if a redirect causes the download to begin again from
+// a new server.
+//
+// If supplied by the server, the anticipated total download size is available
+// as [[myFetcher response] expectedContentLength] (and may be -1 for unknown
+// download sizes.)
+//
+//
+// Automatic retrying of fetches
+//
+// The fetcher can optionally create a timer and reattempt certain kinds of
+// fetch failures (status codes 408, request timeout; 503, service unavailable;
+// 504, gateway timeout; networking errors NSURLErrorTimedOut and
+// NSURLErrorNetworkConnectionLost.) The user may set a retry selector to
+// customize the type of errors which will be retried.
+//
+// Retries are done in an exponential-backoff fashion (that is, after 1 second,
+// 2, 4, 8, and so on.)
+//
+// Enabling automatic retries looks like this:
+// [myFetcher setRetryEnabled:YES];
+//
+// With retries enabled, the success or failure callbacks are called only
+// when no more retries will be attempted. Calling the fetcher's stopFetching
+// method will terminate the retry timer, without the finished or failure
+// selectors being invoked.
+//
+// Optionally, the client may set the maximum retry interval:
+// [myFetcher setMaxRetryInterval:60.0]; // in seconds; default is 60 seconds
+// // for downloads, 600 for uploads
+//
+// Also optionally, the client may provide a callback selector to determine
+// if a status code or other error should be retried.
+// [myFetcher setRetrySelector:@selector(myFetcher:willRetry:forError:)];
+//
+// If set, the retry selector should have the signature:
+// -(BOOL)fetcher:(GTMHTTPFetcher *)fetcher willRetry:(BOOL)suggestedWillRetry forError:(NSError *)error
+// and return YES to set the retry timer or NO to fail without additional
+// fetch attempts.
+//
+// The retry method may return the |suggestedWillRetry| argument to get the
+// default retry behavior. Server status codes are present in the
+// error argument, and have the domain kGTMHTTPFetcherStatusDomain. The
+// user's method may look something like this:
+//
+// -(BOOL)myFetcher:(GTMHTTPFetcher *)fetcher willRetry:(BOOL)suggestedWillRetry forError:(NSError *)error {
+//
+// // perhaps examine [error domain] and [error code], or [fetcher retryCount]
+// //
+// // return YES to start the retry timer, NO to proceed to the failure
+// // callback, or |suggestedWillRetry| to get default behavior for the
+// // current error domain and code values.
+// return suggestedWillRetry;
+// }
+
+
+
+#pragma once
+
+#import <Foundation/Foundation.h>
+
+#if defined(GTL_TARGET_NAMESPACE)
+ // we're using target namespace macros
+ #import "GTLDefines.h"
+#elif defined(GDATA_TARGET_NAMESPACE)
+ #import "GDataDefines.h"
+#else
+ #if TARGET_OS_IPHONE
+ #ifndef GTM_FOUNDATION_ONLY
+ #define GTM_FOUNDATION_ONLY 1
+ #endif
+ #ifndef GTM_IPHONE
+ #define GTM_IPHONE 1
+ #endif
+ #endif
+#endif
+
+#if TARGET_OS_IPHONE && (__IPHONE_OS_VERSION_MAX_ALLOWED >= 40000)
+ #define GTM_BACKGROUND_FETCHING 1
+#endif
+
+#undef _EXTERN
+#undef _INITIALIZE_AS
+#ifdef GTMHTTPFETCHER_DEFINE_GLOBALS
+ #define _EXTERN
+ #define _INITIALIZE_AS(x) =x
+#else
+ #if defined(__cplusplus)
+ #define _EXTERN extern "C"
+ #else
+ #define _EXTERN extern
+ #endif
+ #define _INITIALIZE_AS(x)
+#endif
+
+// notifications
+//
+// fetch started and stopped, and fetch retry delay started and stopped
+_EXTERN NSString* const kGTMHTTPFetcherStartedNotification _INITIALIZE_AS(@"kGTMHTTPFetcherStartedNotification");
+_EXTERN NSString* const kGTMHTTPFetcherStoppedNotification _INITIALIZE_AS(@"kGTMHTTPFetcherStoppedNotification");
+_EXTERN NSString* const kGTMHTTPFetcherRetryDelayStartedNotification _INITIALIZE_AS(@"kGTMHTTPFetcherRetryDelayStartedNotification");
+_EXTERN NSString* const kGTMHTTPFetcherRetryDelayStoppedNotification _INITIALIZE_AS(@"kGTMHTTPFetcherRetryDelayStoppedNotification");
+
+// callback constants
+_EXTERN NSString* const kGTMHTTPFetcherErrorDomain _INITIALIZE_AS(@"com.google.GTMHTTPFetcher");
+_EXTERN NSString* const kGTMHTTPFetcherStatusDomain _INITIALIZE_AS(@"com.google.HTTPStatus");
+_EXTERN NSString* const kGTMHTTPFetcherErrorChallengeKey _INITIALIZE_AS(@"challenge");
+_EXTERN NSString* const kGTMHTTPFetcherStatusDataKey _INITIALIZE_AS(@"data"); // data returned with a kGTMHTTPFetcherStatusDomain error
+
+enum {
+ kGTMHTTPFetcherErrorDownloadFailed = -1,
+ kGTMHTTPFetcherErrorAuthenticationChallengeFailed = -2,
+ kGTMHTTPFetcherErrorChunkUploadFailed = -3,
+ kGTMHTTPFetcherErrorFileHandleException = -4,
+ kGTMHTTPFetcherErrorBackgroundExpiration = -6,
+
+ // The code kGTMHTTPFetcherErrorAuthorizationFailed (-5) has been removed;
+ // look for status 401 instead.
+
+ kGTMHTTPFetcherStatusNotModified = 304,
+ kGTMHTTPFetcherStatusBadRequest = 400,
+ kGTMHTTPFetcherStatusUnauthorized = 401,
+ kGTMHTTPFetcherStatusForbidden = 403,
+ kGTMHTTPFetcherStatusPreconditionFailed = 412
+};
+
+// cookie storage methods
+enum {
+ kGTMHTTPFetcherCookieStorageMethodStatic = 0,
+ kGTMHTTPFetcherCookieStorageMethodFetchHistory = 1,
+ kGTMHTTPFetcherCookieStorageMethodSystemDefault = 2,
+ kGTMHTTPFetcherCookieStorageMethodNone = 3
+};
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void GTMAssertSelectorNilOrImplementedWithArgs(id obj, SEL sel, ...);
+
+// Utility functions for applications self-identifying to servers via a
+// user-agent header
+
+// Make a proper app name without whitespace from the given string, removing
+// whitespace and other characters that may be special parsed marks of
+// the full user-agent string.
+NSString *GTMCleanedUserAgentString(NSString *str);
+
+// Make an identifier like "MacOSX/10.7.1" or "iPod_Touch/4.1"
+NSString *GTMSystemVersionString(void);
+
+// Make a generic name and version for the current application, like
+// com.example.MyApp/1.2.3 relying on the bundle identifier and the
+// CFBundleShortVersionString or CFBundleVersion. If no bundle ID
+// is available, the process name preceded by "proc_" is used.
+NSString *GTMApplicationIdentifier(NSBundle *bundle);
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
+
+@class GTMHTTPFetcher;
+
+@protocol GTMCookieStorageProtocol <NSObject>
+// This protocol allows us to call into the service without requiring
+// GTMCookieStorage sources in this project
+//
+// The public interface for cookie handling is the GTMCookieStorage class,
+// accessible from a fetcher service object's fetchHistory or from the fetcher's
+// +staticCookieStorage method.
+- (NSArray *)cookiesForURL:(NSURL *)theURL;
+- (void)setCookies:(NSArray *)newCookies;
+@end
+
+@protocol GTMHTTPFetchHistoryProtocol <NSObject>
+// This protocol allows us to call the fetch history object without requiring
+// GTMHTTPFetchHistory sources in this project
+- (void)updateRequest:(NSMutableURLRequest *)request isHTTPGet:(BOOL)isHTTPGet;
+- (BOOL)shouldCacheETaggedData;
+- (NSData *)cachedDataForRequest:(NSURLRequest *)request;
+- (id <GTMCookieStorageProtocol>)cookieStorage;
+- (void)updateFetchHistoryWithRequest:(NSURLRequest *)request
+ response:(NSURLResponse *)response
+ downloadedData:(NSData *)downloadedData;
+- (void)removeCachedDataForRequest:(NSURLRequest *)request;
+@end
+
+@protocol GTMHTTPFetcherServiceProtocol <NSObject>
+// This protocol allows us to call into the service without requiring
+// GTMHTTPFetcherService sources in this project
+
+@property (retain) NSOperationQueue *delegateQueue;
+
+- (BOOL)fetcherShouldBeginFetching:(GTMHTTPFetcher *)fetcher;
+- (void)fetcherDidStop:(GTMHTTPFetcher *)fetcher;
+
+- (GTMHTTPFetcher *)fetcherWithRequest:(NSURLRequest *)request;
+- (BOOL)isDelayingFetcher:(GTMHTTPFetcher *)fetcher;
+@end
+
+@protocol GTMFetcherAuthorizationProtocol <NSObject>
+@required
+// This protocol allows us to call the authorizer without requiring its sources
+// in this project.
+- (void)authorizeRequest:(NSMutableURLRequest *)request
+ delegate:(id)delegate
+ didFinishSelector:(SEL)sel;
+
+- (void)stopAuthorization;
+
+- (void)stopAuthorizationForRequest:(NSURLRequest *)request;
+
+- (BOOL)isAuthorizingRequest:(NSURLRequest *)request;
+
+- (BOOL)isAuthorizedRequest:(NSURLRequest *)request;
+
+@property (retain, readonly) NSString *userEmail;
+
+@optional
+
+// Indicate if authorization may be attempted. Even if this succeeds,
+// authorization may fail if the user's permissions have been revoked.
+@property (readonly) BOOL canAuthorize;
+
+// For development only, allow authorization of non-SSL requests, allowing
+// transmission of the bearer token unencrypted.
+@property (assign) BOOL shouldAuthorizeAllRequests;
+
+#if NS_BLOCKS_AVAILABLE
+- (void)authorizeRequest:(NSMutableURLRequest *)request
+ completionHandler:(void (^)(NSError *error))handler;
+#endif
+
+@property (assign) id <GTMHTTPFetcherServiceProtocol> fetcherService; // WEAK
+
+- (BOOL)primeForRefresh;
+
+@end
+
+// GTMHTTPFetcher objects are used for async retrieval of an http get or post
+//
+// See additional comments at the beginning of this file
+@interface GTMHTTPFetcher : NSObject {
+ @protected
+ NSMutableURLRequest *request_;
+ NSURLConnection *connection_;
+ NSMutableData *downloadedData_;
+ NSString *downloadPath_;
+ NSString *temporaryDownloadPath_;
+ NSFileHandle *downloadFileHandle_;
+ unsigned long long downloadedLength_;
+ NSURLCredential *credential_; // username & password
+ NSURLCredential *proxyCredential_; // credential supplied to proxy servers
+ NSData *postData_;
+ NSInputStream *postStream_;
+ NSMutableData *loggedStreamData_;
+ NSURLResponse *response_; // set in connection:didReceiveResponse:
+ id delegate_;
+ SEL finishedSel_; // should by implemented by delegate
+ SEL sentDataSel_; // optional, set with setSentDataSelector
+ SEL receivedDataSel_; // optional, set with setReceivedDataSelector
+#if NS_BLOCKS_AVAILABLE
+ void (^completionBlock_)(NSData *, NSError *);
+ void (^receivedDataBlock_)(NSData *);
+ void (^sentDataBlock_)(NSInteger, NSInteger, NSInteger);
+ BOOL (^retryBlock_)(BOOL, NSError *);
+#elif !__LP64__
+ // placeholders: for 32-bit builds, keep the size of the object's ivar section
+ // the same with and without blocks
+ id completionPlaceholder_;
+ id receivedDataPlaceholder_;
+ id sentDataPlaceholder_;
+ id retryPlaceholder_;
+#endif
+ BOOL hasConnectionEnded_; // set if the connection need not be cancelled
+ BOOL isCancellingChallenge_; // set only when cancelling an auth challenge
+ BOOL isStopNotificationNeeded_; // set when start notification has been sent
+ BOOL shouldFetchInBackground_;
+#if GTM_BACKGROUND_FETCHING
+ NSUInteger backgroundTaskIdentifer_; // UIBackgroundTaskIdentifier
+#endif
+ id userData_; // retained, if set by caller
+ NSMutableDictionary *properties_; // more data retained for caller
+ NSArray *runLoopModes_; // optional
+ NSOperationQueue *delegateQueue_; // optional; available iOS 6/10.7 and later
+ id <GTMHTTPFetchHistoryProtocol> fetchHistory_; // if supplied by the caller, used for Last-Modified-Since checks and cookies
+ NSInteger cookieStorageMethod_; // constant from above
+ id <GTMCookieStorageProtocol> cookieStorage_;
+
+ id <GTMFetcherAuthorizationProtocol> authorizer_;
+
+ // the service object that created and monitors this fetcher, if any
+ id <GTMHTTPFetcherServiceProtocol> service_;
+ NSString *serviceHost_;
+ NSInteger servicePriority_;
+ NSThread *thread_;
+
+ BOOL isRetryEnabled_; // user wants auto-retry
+ SEL retrySel_; // optional; set with setRetrySelector
+ NSTimer *retryTimer_;
+ NSUInteger retryCount_;
+ NSTimeInterval maxRetryInterval_; // default 600 seconds
+ NSTimeInterval minRetryInterval_; // random between 1 and 2 seconds
+ NSTimeInterval retryFactor_; // default interval multiplier is 2
+ NSTimeInterval lastRetryInterval_;
+ BOOL hasAttemptedAuthRefresh_;
+
+ NSString *comment_; // comment for log
+ NSString *log_;
+#if !STRIP_GTM_FETCH_LOGGING
+ NSURL *redirectedFromURL_;
+ NSString *logRequestBody_;
+ NSString *logResponseBody_;
+ BOOL shouldDeferResponseBodyLogging_;
+#endif
+}
+
+// Create a fetcher
+//
+// fetcherWithRequest will return an autoreleased fetcher, but if
+// the connection is successfully created, the connection should retain the
+// fetcher for the life of the connection as well. So the caller doesn't have
+// to retain the fetcher explicitly unless they want to be able to cancel it.
++ (GTMHTTPFetcher *)fetcherWithRequest:(NSURLRequest *)request;
+
+// Convenience methods that make a request, like +fetcherWithRequest
++ (GTMHTTPFetcher *)fetcherWithURL:(NSURL *)requestURL;
++ (GTMHTTPFetcher *)fetcherWithURLString:(NSString *)requestURLString;
+
+// Designated initializer
+- (id)initWithRequest:(NSURLRequest *)request;
+
+// Fetcher request
+//
+// The underlying request is mutable and may be modified by the caller
+@property (retain) NSMutableURLRequest *mutableRequest;
+
+// Setting the credential is optional; it is used if the connection receives
+// an authentication challenge
+@property (retain) NSURLCredential *credential;
+
+// Setting the proxy credential is optional; it is used if the connection
+// receives an authentication challenge from a proxy
+@property (retain) NSURLCredential *proxyCredential;
+
+// If post data or stream is not set, then a GET retrieval method is assumed
+@property (retain) NSData *postData;
+@property (retain) NSInputStream *postStream;
+
+// The default cookie storage method is kGTMHTTPFetcherCookieStorageMethodStatic
+// without a fetch history set, and kGTMHTTPFetcherCookieStorageMethodFetchHistory
+// with a fetch history set
+//
+// Applications needing control of cookies across a sequence of fetches should
+// create fetchers from a GTMHTTPFetcherService object (which encapsulates
+// fetch history) for a well-defined cookie store
+@property (assign) NSInteger cookieStorageMethod;
+
++ (id <GTMCookieStorageProtocol>)staticCookieStorage;
+
+// Object to add authorization to the request, if needed
+@property (retain) id <GTMFetcherAuthorizationProtocol> authorizer;
+
+// The service object that created and monitors this fetcher, if any
+@property (retain) id <GTMHTTPFetcherServiceProtocol> service;
+
+// The host, if any, used to classify this fetcher in the fetcher service
+@property (copy) NSString *serviceHost;
+
+// The priority, if any, used for starting fetchers in the fetcher service
+//
+// Lower values are higher priority; the default is 0, and values may
+// be negative or positive. This priority affects only the start order of
+// fetchers that are being delayed by a fetcher service.
+@property (assign) NSInteger servicePriority;
+
+// The thread used to run this fetcher in the fetcher service when no operation
+// queue is provided.
+@property (retain) NSThread *thread;
+
+// The delegate is retained during the connection
+@property (retain) id delegate;
+
+// On iOS 4 and later, the fetch may optionally continue while the app is in the
+// background until finished or stopped by OS expiration
+//
+// The default value is NO
+//
+// For Mac OS X, background fetches are always supported, and this property
+// is ignored
+@property (assign) BOOL shouldFetchInBackground;
+
+// The delegate's optional sentData selector may be used to monitor upload
+// progress. It should have a signature like:
+// - (void)myFetcher:(GTMHTTPFetcher *)fetcher
+// didSendBytes:(NSInteger)bytesSent
+// totalBytesSent:(NSInteger)totalBytesSent
+// totalBytesExpectedToSend:(NSInteger)totalBytesExpectedToSend;
+//
+// +doesSupportSentDataCallback indicates if this delegate method is supported
++ (BOOL)doesSupportSentDataCallback;
+
+@property (assign) SEL sentDataSelector;
+
+// The delegate's optional receivedData selector may be used to monitor download
+// progress. It should have a signature like:
+// - (void)myFetcher:(GTMHTTPFetcher *)fetcher
+// receivedData:(NSData *)dataReceivedSoFar;
+//
+// The dataReceived argument will be nil when downloading to a path or to a
+// file handle.
+//
+// Applications should not use this method to accumulate the received data;
+// the callback method or block supplied to the beginFetch call will have
+// the complete NSData received.
+@property (assign) SEL receivedDataSelector;
+
+#if NS_BLOCKS_AVAILABLE
+// The full interface to the block is provided rather than just a typedef for
+// its parameter list in order to get more useful code completion in the Xcode
+// editor
+@property (copy) void (^sentDataBlock)(NSInteger bytesSent, NSInteger totalBytesSent, NSInteger bytesExpectedToSend);
+
+// The dataReceived argument will be nil when downloading to a path or to
+// a file handle
+@property (copy) void (^receivedDataBlock)(NSData *dataReceivedSoFar);
+#endif
+
+// retrying; see comments at the top of the file. Calling
+// setRetryEnabled(YES) resets the min and max retry intervals.
+@property (assign, getter=isRetryEnabled) BOOL retryEnabled;
+
+// Retry selector or block is optional for retries.
+//
+// If present, it should have the signature:
+// -(BOOL)fetcher:(GTMHTTPFetcher *)fetcher willRetry:(BOOL)suggestedWillRetry forError:(NSError *)error
+// and return YES to cause a retry. See comments at the top of this file.
+@property (assign) SEL retrySelector;
+
+#if NS_BLOCKS_AVAILABLE
+@property (copy) BOOL (^retryBlock)(BOOL suggestedWillRetry, NSError *error);
+#endif
+
+// Retry intervals must be strictly less than maxRetryInterval, else
+// they will be limited to maxRetryInterval and no further retries will
+// be attempted. Setting maxRetryInterval to 0.0 will reset it to the
+// default value, 600 seconds.
+
+@property (assign) NSTimeInterval maxRetryInterval;
+
+// Starting retry interval. Setting minRetryInterval to 0.0 will reset it
+// to a random value between 1.0 and 2.0 seconds. Clients should normally not
+// call this except for unit testing.
+@property (assign) NSTimeInterval minRetryInterval;
+
+// Multiplier used to increase the interval between retries, typically 2.0.
+// Clients should not need to call this.
+@property (assign) double retryFactor;
+
+// Number of retries attempted
+@property (readonly) NSUInteger retryCount;
+
+// interval delay to precede next retry
+@property (readonly) NSTimeInterval nextRetryInterval;
+
+// Begin fetching the request
+//
+// The delegate can optionally implement the finished selectors or pass NULL
+// for it.
+//
+// Returns YES if the fetch is initiated. The delegate is retained between
+// the beginFetch call until after the finish callback.
+//
+// An error is passed to the callback for server statuses 300 or
+// higher, with the status stored as the error object's code.
+//
+// finishedSEL has a signature like:
+// - (void)fetcher:(GTMHTTPFetcher *)fetcher finishedWithData:(NSData *)data error:(NSError *)error;
+//
+// If the application has specified a downloadPath or downloadFileHandle
+// for the fetcher, the data parameter passed to the callback will be nil.
+
+- (BOOL)beginFetchWithDelegate:(id)delegate
+ didFinishSelector:(SEL)finishedSEL;
+
+#if NS_BLOCKS_AVAILABLE
+- (BOOL)beginFetchWithCompletionHandler:(void (^)(NSData *data, NSError *error))handler;
+#endif
+
+
+// Returns YES if this is in the process of fetching a URL
+- (BOOL)isFetching;
+
+// Cancel the fetch of the request that's currently in progress
+- (void)stopFetching;
+
+// Return the status code from the server response
+@property (readonly) NSInteger statusCode;
+
+// Return the http headers from the response
+@property (retain, readonly) NSDictionary *responseHeaders;
+
+// The response, once it's been received
+@property (retain) NSURLResponse *response;
+
+// Bytes downloaded so far
+@property (readonly) unsigned long long downloadedLength;
+
+// Buffer of currently-downloaded data
+@property (readonly, retain) NSData *downloadedData;
+
+// Path in which to non-atomically create a file for storing the downloaded data
+//
+// The path must be set before fetching begins. The download file handle
+// will be created for the path, and can be used to monitor progress. If a file
+// already exists at the path, it will be overwritten.
+@property (copy) NSString *downloadPath;
+
+// If downloadFileHandle is set, data received is immediately appended to
+// the file handle rather than being accumulated in the downloadedData property
+//
+// The file handle supplied must allow writing and support seekToFileOffset:,
+// and must be set before fetching begins. Setting a download path will
+// override the file handle property.
+@property (retain) NSFileHandle *downloadFileHandle;
+
+// The optional fetchHistory object is used for a sequence of fetchers to
+// remember ETags, cache ETagged data, and store cookies. Typically, this
+// is set by a GTMFetcherService object when it creates a fetcher.
+//
+// Side effect: setting fetch history implicitly calls setCookieStorageMethod:
+@property (retain) id <GTMHTTPFetchHistoryProtocol> fetchHistory;
+
+// userData is retained for the convenience of the caller
+@property (retain) id userData;
+
+// Stored property values are retained for the convenience of the caller
+@property (copy) NSMutableDictionary *properties;
+
+- (void)setProperty:(id)obj forKey:(NSString *)key; // pass nil obj to remove property
+- (id)propertyForKey:(NSString *)key;
+
+- (void)addPropertiesFromDictionary:(NSDictionary *)dict;
+
+// Comments are useful for logging
+@property (copy) NSString *comment;
+
+- (void)setCommentWithFormat:(NSString *)format, ... NS_FORMAT_FUNCTION(1, 2);
+
+// Log of request and response, if logging is enabled
+@property (copy) NSString *log;
+
+// Callbacks can be invoked on an operation queue rather than via the run loop,
+// starting on 10.7 and iOS 6. If a delegate queue is supplied. the run loop
+// modes are ignored.
+@property (retain) NSOperationQueue *delegateQueue;
+
+// Using the fetcher while a modal dialog is displayed requires setting the
+// run-loop modes to include NSModalPanelRunLoopMode
+@property (retain) NSArray *runLoopModes;
+
+// Users who wish to replace GTMHTTPFetcher's use of NSURLConnection
+// can do so globally here. The replacement should be a subclass of
+// NSURLConnection.
++ (Class)connectionClass;
++ (void)setConnectionClass:(Class)theClass;
+
+// Spin the run loop, discarding events, until the fetch has completed
+//
+// This is only for use in testing or in tools without a user interface.
+//
+// Synchronous fetches should never be done by shipping apps; they are
+// sufficient reason for rejection from the app store.
+- (void)waitForCompletionWithTimeout:(NSTimeInterval)timeoutInSeconds;
+
+#if STRIP_GTM_FETCH_LOGGING
+// if logging is stripped, provide a stub for the main method
+// for controlling logging
++ (void)setLoggingEnabled:(BOOL)flag;
+#endif // STRIP_GTM_FETCH_LOGGING
+
+@end