-
Notifications
You must be signed in to change notification settings - Fork 1
/
GDataHTTPFetcher.h
executable file
·604 lines (527 loc) · 23.6 KB
/
GDataHTTPFetcher.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
/* Copyright (c) 2007 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.
*/
//
// GDataHTTPFetcher.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 or POST
// - When you want the "standard" behavior for connections (redirection handling
// an so on)
// - When you want to avoid cookie collisions with Safari and other applications
// - When you want to provide if-modified-since headers
// - When you need to set a credential for the http
// - When you want to avoid changing WebKit's cookies
//
// 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, allocate it with initWithRequest:
// and have the delegate release the fetcher in the callbacks.
//
// Sample usage:
//
// NSURLRequest *request = [NSURLRequest requestWithURL:myURL];
// GDataHTTPFetcher* myFetcher = [GDataHTTPFetcher httpFetcherWithRequest:request];
//
// // optional post data
// [myFetcher setPostData:[postString dataUsingEncoding:NSUTF8StringEncoding]];
//
// // optional fetch history, for persisting modified-dates and local cookie
// // storage
// [myFetcher setFetchHistory:myFetchHistory];
//
// [myFetcher beginFetchWithDelegate:self
// didFinishSelector:@selector(myFetcher:finishedWithData:)
// didFailSelector:@selector(myFetcher:failedWithError:)];
//
// Upon fetch completion, the callback selectors are invoked; they should have
// these signatures (you can use any callback method names you want so long as
// the signatures match these):
//
// - (void)myFetcher:(GDataHTTPFetcher *)fetcher finishedWithData:(NSData *)retrievedData;
// - (void)myFetcher:(GDataHTTPFetcher *)fetcher failedWithError:(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
// kGDataHTTPFetcherStatusDomain and code set to the server status.
//
// Status codes are at <http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html>
//
//
// 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:kGDataHTTPFetcherErrorChallengeKey];
// 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, GDataHTTPFetcher 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 kGDataHTTPFetcherCookieStorageMethodSystemDefault.
//
// If you provide a fetch history dictionary (such as for periodic checks,
// described below) then the cookie storage mechanism is set to use the fetch
// history rather than the static storage.
//
//
// Fetching for periodic checks:
//
// The fetcher object can track "Last-modified" dates on returned data and
// provide an "If-modified-since" header. This allows the server to save
// bandwidth by providing a "Nothing changed" status message instead of response
// data.
//
// To get this behavior, provide a persistent mutable dictionary to
// setFetchHistory:, and look for the failedWithStatus: callback with code 304
// (kGDataHTTPFetcherStatusNotModified) like this:
//
// - (void)myFetcher:(GDataHTTPFetcher *)fetcher failedWithStatus:(NSInteger)status data:(NSData *)data {
// if (status == kGDataHTTPFetcherStatusNotModified) {
// // |data| is empty; use the data from the previous finishedWithData: for this URL
// } else {
// // handle other server status code
// }
// }
//
// The fetchHistory mutable dictionary should be maintained by the client between
// fetches and given to each fetcher intended to have the If-modified-since header
// or the same cookie storage.
//
//
// Monitoring received data
//
// The optional received data selector can be set with setReceivedDataSelector:
// and should have the signature
//
// - (void)myFetcher:(GDataHTTPFetcher *)fetcher receivedData:(NSData *)dataReceivedSoFar;
//
// The bytes received so far are [dataReceivedSoFar length]. 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] (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 setIsRetryEnabled: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.]; // in seconds; default is 600 seconds
//
// 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:(GDataHTTPFetcher *)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 kGDataHTTPFetcherStatusDomain. The
// user's method may look something like this:
//
// -(BOOL)myFetcher:(GDataHTTPFetcher *)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 (MAC_OS_X_VERSION_MAX_ALLOWED <= MAC_OS_X_VERSION_10_4) || defined(GDATA_TARGET_NAMESPACE)
// we need NSInteger for the 10.4 SDK, or we're using target namespace macros
#import "GDataDefines.h"
#else
#if TARGET_OS_IPHONE
#ifndef GDATA_FOUNDATION_ONLY
#define GDATA_FOUNDATION_ONLY 1
#endif
#ifndef GDATA_IPHONE
#define GDATA_IPHONE 1
#endif
#endif
#endif
#undef _EXTERN
#undef _INITIALIZE_AS
#ifdef GDATAHTTPFETCHER_DEFINE_GLOBALS
#define _EXTERN
#define _INITIALIZE_AS(x) =x
#else
#define _EXTERN extern
#define _INITIALIZE_AS(x)
#endif
// notifications
//
// fetch started and stopped, and fetch retry delay started and stopped
_EXTERN NSString* const kGDataHTTPFetcherStartedNotification _INITIALIZE_AS(@"kGDataHTTPFetcherStartedNotification");
_EXTERN NSString* const kGDataHTTPFetcherStoppedNotification _INITIALIZE_AS(@"kGDataHTTPFetcherStoppedNotification");
_EXTERN NSString* const kGDataHTTPFetcherRetryDelayStartedNotification _INITIALIZE_AS(@"kGDataHTTPFetcherRetryDelayStartedNotification");
_EXTERN NSString* const kGDataHTTPFetcherRetryDelayStoppedNotification _INITIALIZE_AS(@"kGDataHTTPFetcherRetryDelayStoppedNotification");
// callback constants
_EXTERN NSString* const kGDataHTTPFetcherErrorDomain _INITIALIZE_AS(@"com.google.GDataHTTPFetcher");
_EXTERN NSString* const kGDataHTTPFetcherStatusDomain _INITIALIZE_AS(@"com.google.HTTPStatus");
_EXTERN NSString* const kGDataHTTPFetcherErrorChallengeKey _INITIALIZE_AS(@"challenge");
_EXTERN NSString* const kGDataHTTPFetcherStatusDataKey _INITIALIZE_AS(@"data"); // data returned with a kGDataHTTPFetcherStatusDomain error
enum {
kGDataHTTPFetcherErrorDownloadFailed = -1,
kGDataHTTPFetcherErrorAuthenticationChallengeFailed = -2,
kGDataHTTPFetcherErrorChunkUploadFailed = -3,
kGDataHTTPFetcherStatusNotModified = 304
};
// cookie storage methods
enum {
kGDataHTTPFetcherCookieStorageMethodStatic = 0,
kGDataHTTPFetcherCookieStorageMethodFetchHistory = 1,
kGDataHTTPFetcherCookieStorageMethodSystemDefault = 2,
kGDataHTTPFetcherCookieStorageMethodNone = 3
};
// default data cache size for when we're caching responses to handle "not
// modified" errors for the client
#if GDATA_IPHONE
// iPhone: up to 1MB memory
_EXTERN const NSUInteger kGDataDefaultDatedDataCacheMemoryCapacity _INITIALIZE_AS(1*1024*1024);
#else
// Mac OS X: up to 15MB memory
_EXTERN const NSUInteger kGDataDefaultDatedDataCacheMemoryCapacity _INITIALIZE_AS(15*1024*1024);
#endif
void AssertSelectorNilOrImplementedWithArguments(id obj, SEL sel, ...);
@class GDataURLCache;
@class GDataCookieStorage;
//
// Users of the GDataHTTPFetcher class may optionally create and set a fetch
// history object. The fetch history provides "memory" between subsequent
// fetches, including:
//
// - For fetch responses with "last-modified" headers, the fetch history
// remembers the response headers. Future fetcher requests to the same URL
// will be given an "If-modified-since" header, telling the server to return
// a 304 Not Modified status if the response is unchanged, reducing the
// server load and network traffic.
//
// - Optionally, the fetch history can cache the dated data that was returned
// in the responses that contained "Last-modified" headers. If a later fetch
// results in a 304 status, the fetcher will return the cached dated data
// to the client along with a 200 status, hiding the 304.
//
// - The fetch history can track cookies.
//
@interface GDataHTTPFetchHistory : NSObject {
GDataURLCache *datedDataCache_;
BOOL shouldCacheDatedData_; // if NO, then only headers are cached
GDataCookieStorage *cookieStorage_;
}
- (id)initWithMemoryCapacity:(NSUInteger)totalBytes
shouldCacheDatedData:(BOOL)shouldCacheDatedData;
- (void)clearDatedDataCache;
- (void)clearHistory;
- (BOOL)shouldCacheDatedData;
- (void)setShouldCacheDatedData:(BOOL)flag;
- (GDataCookieStorage *)cookieStorage;
- (void)setCookieStorage:(GDataCookieStorage *)obj;
// the default dated data cache capacity is kGDataDefaultDatedDataCacheMemoryCapacity
- (NSUInteger)memoryCapacity;
- (void)setMemoryCapacity:(NSUInteger)totalBytes;
@end
// async retrieval of an http get or post
@interface GDataHTTPFetcher : NSObject {
NSMutableURLRequest *request_;
NSURLConnection *connection_; // while connection_ is non-nil, delegate_ is retained
NSMutableData *downloadedData_;
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_; // WEAK (though retained during an open connection)
SEL finishedSEL_; // should by implemented by delegate
SEL statusFailedSEL_; // implemented by delegate if it needs separate network error callbacks
SEL networkFailedSEL_; // should be 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 retryPlaceholder_;
#endif
BOOL isCancellingChallenge_; // set only when cancelling an auth challenge
BOOL isStopNotificationNeeded_; // set when start notification has been sent
id userData_; // retained, if set by caller
NSMutableDictionary *properties_; // more data retained for caller
NSArray *runLoopModes_; // optional, for 10.5 and later
GDataHTTPFetchHistory *fetchHistory_; // if supplied by the caller, used for Last-Modified-Since checks and cookies
NSInteger cookieStorageMethod_; // constant from above
GDataCookieStorage *cookieStorage_;
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_;
}
// create a fetcher
//
// httpFetcherWithRequest 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.
+ (GDataHTTPFetcher *)httpFetcherWithRequest:(NSURLRequest *)request;
// designated initializer
- (id)initWithRequest:(NSURLRequest *)request;
- (NSMutableURLRequest *)request;
- (void)setRequest:(NSURLRequest *)theRequest;
// setting the credential is optional; it is used if the connection receives
// an authentication challenge
- (NSURLCredential *)credential;
- (void)setCredential:(NSURLCredential *)theCredential;
// setting the proxy credential is optional; it is used if the connection
// receives an authentication challenge from a proxy
- (NSURLCredential *)proxyCredential;
- (void)setProxyCredential:(NSURLCredential *)theCredential;
// if post data or stream is not set, then a GET retrieval method is assumed
- (NSData *)postData;
- (void)setPostData:(NSData *)theData;
// beware: In 10.4, NSInputStream fails to copy or retain
// the data it was initialized with, contrary to docs
- (NSInputStream *)postStream;
- (void)setPostStream:(NSInputStream *)theStream;
// the default cookie storage method is kGDataHTTPFetcherCookieStorageMethodStatic
// without a fetch history set, and kGDataHTTPFetcherCookieStorageMethodFetchHistory
// with a fetch history set
- (NSInteger)cookieStorageMethod;
- (void)setCookieStorageMethod:(NSInteger)method;
// the delegate is not retained except during the connection
- (id)delegate;
- (void)setDelegate:(id)theDelegate;
// the delegate's optional sentData selector has a signature like:
// - (void)myFetcher:(GDataHTTPFetcher *)fetcher
// didSendBytes:(NSInteger)bytesSent
// totalBytesSent:(NSInteger)totalBytesSent
// totalBytesExpectedToSend:(NSInteger)totalBytesExpectedToSend;
//
// +doesSupportSentDataCallback indicates if this delegate method is supported
+ (BOOL)doesSupportSentDataCallback;
- (SEL)sentDataSelector;
- (void)setSentDataSelector:(SEL)theSelector;
// the delegate's optional receivedData selector has a signature like:
// - (void)myFetcher:(GDataHTTPFetcher *)fetcher receivedData:(NSData *)dataReceivedSoFar;
- (SEL)receivedDataSelector;
- (void)setReceivedDataSelector:(SEL)theSelector;
#if NS_BLOCKS_AVAILABLE
- (void)setSentDataBlock:(void (^)(NSInteger bytesSent, NSInteger totalBytesSent, NSInteger bytesExpectedToSend))block;
- (void)setReceivedDataBlock:(void (^)(NSData *dataReceivedSoFar))block;
#endif
// retrying; see comments at the top of the file. Calling
// setIsRetryEnabled(YES) resets the min and max retry intervals.
- (BOOL)isRetryEnabled;
- (void)setIsRetryEnabled:(BOOL)flag;
// retry selector or block is optional for retries.
//
// If present, it should have the signature:
// -(BOOL)fetcher:(GDataHTTPFetcher *)fetcher willRetry:(BOOL)suggestedWillRetry forError:(NSError *)error
// and return YES to cause a retry. See comments at the top of this file.
- (SEL)retrySelector;
- (void)setRetrySelector:(SEL)theSel;
#if NS_BLOCKS_AVAILABLE
- (void)setRetryBlock:(BOOL (^)(BOOL suggestedWillRetry, NSError *error))block;
#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.
- (NSTimeInterval)maxRetryInterval;
- (void)setMaxRetryInterval:(NSTimeInterval)secs;
// 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.
- (NSTimeInterval)minRetryInterval;
- (void)setMinRetryInterval:(NSTimeInterval)secs;
// Multiplier used to increase the interval between retries, typically 2.0.
// Clients should not need to call this.
- (double)retryFactor;
- (void)setRetryFactor:(double)multiplier;
// number of retries attempted
- (NSUInteger)retryCount;
// interval delay to precede next retry
- (NSTimeInterval)nextRetryInterval;
// Begin fetching the request (simplified interface)
//
// The delegate can optionally implement the finished and failure selectors
// or pass nil for them.
//
// Returns YES if the fetch is initiated. The delegate is retained between
// the beginFetch call until after the finish/fail callbacks.
//
// The failure selector is called for server statuses 300 or higher, with the
// status stored as the error object's code.
//
// finishedSEL has a signature like:
// - (void)fetcher:(GDataHTTPFetcher *)fetcher finishedWithData:(NSData *)data
// failedSEL has a signature like:
// - (void)fetcher:(GDataHTTPFetcher *)fetcher failedWithError:(NSError *)error
//
- (BOOL)beginFetchWithDelegate:(id)delegate
didFinishSelector:(SEL)finishedSEL
didFailSelector:(SEL)failedSEL;
#if NS_BLOCKS_AVAILABLE
- (BOOL)beginFetchWithCompletionHandler:(void (^)(NSData *data, NSError *error))handler;
#endif
// Begin fetching the request (original interface)
//
// The delegate can optionally implement the finished, status failure, and
// network failure selectors, or pass nill for them.
//
// Returns YES if the fetch is initiated. The delegate is retained between
// the beginFetch call until after the finish/fail callbacks.
//
// The failure selector is called if the server returns status >= 300
//
// finishedSEL has a signature like:
// - (void)fetcher:(GDataHTTPFetcher *)fetcher finishedWithData:(NSData *)data
// statusFailedSEL has a signature like:
// - (void)fetcher:(GDataHTTPFetcher *)fetcher failedWithStatus:(NSInteger)status data:(NSData *)data
// failedSEL has a signature like:
// - (void)fetcher:(GDataHTTPFetcher *)fetcher failedWithError:(NSError *)error
//
- (BOOL)beginFetchWithDelegate:(id)delegate
didFinishSelector:(SEL)finishedSEL
didFailWithStatusSelector:(SEL)statusFailedSEL
didFailWithErrorSelector:(SEL)networkFailedSEL;
// 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
- (NSInteger)statusCode;
// return the http headers from the response
- (NSDictionary *)responseHeaders;
// the response, once it's been received
- (NSURLResponse *)response;
- (void)setResponse:(NSURLResponse *)response;
// buffer of currently-downloaded data
- (NSData *)downloadedData;
// if the caller supplies a mutable dictionary, it's used for Last-Modified-Since
// checks and for cookie storage
// side effect: setFetchHistory implicitly calls setCookieStorageMethod:
- (GDataHTTPFetchHistory *)fetchHistory;
- (void)setFetchHistory:(GDataHTTPFetchHistory *)fetchHistory;
// for fetched data with a last-modified date, cache the data
// in the fetch history and return cached data instead of a 304 error
// Set this to NO if you want to handle status 304 (Not changed) rather than be
// delivered cached data from previous fetches. Default is NO.
// When a cache result is returned, the didFinish selector is called
// with the data, but [fetcher status] still returns 304.
- (BOOL)shouldCacheDatedData;
- (void)setShouldCacheDatedData:(BOOL)flag;
// delete last-modified dates and cached data from the fetch history
- (void)clearDatedDataHistory;
// userData is retained for the convenience of the caller
- (id)userData;
- (void)setUserData:(id)theObj;
// properties are retained for the convenience of the caller
- (void)setProperties:(NSDictionary *)dict;
- (NSDictionary *)properties;
- (void)setProperty:(id)obj forKey:(NSString *)key; // pass nil obj to remove property
- (id)propertyForKey:(NSString *)key;
- (void)addPropertiesFromDictionary:(NSDictionary *)dict;
// using the fetcher while a modal dialog is displayed requires setting the
// run-loop modes to include NSModalPanelRunLoopMode
//
// setting run loop modes does nothing if they are not supported,
// such as on 10.4
- (NSArray *)runLoopModes;
- (void)setRunLoopModes:(NSArray *)modes;
+ (BOOL)doesSupportRunLoopModes;
+ (NSArray *)defaultRunLoopModes;
+ (void)setDefaultRunLoopModes:(NSArray *)modes;
// users who wish to replace GDataHTTPFetcher's use of NSURLConnection
// can do so globally here. The replacement should be a subclass of
// NSURLConnection.
+ (Class)connectionClass;
+ (void)setConnectionClass:(Class)theClass;
#if STRIP_GDATA_FETCH_LOGGING
// if logging is stripped, provide a stub for the main method
// for controlling logging
+ (void)setIsLoggingEnabled:(BOOL)flag;
#endif // STRIP_GDATA_FETCH_LOGGING
@end