adds function to responseFilePath (streaming into a file, if set)

adds total/offsetContentLength. We really need those in case we pause/resume.
This commit is contained in:
Peter Steinberger 2012-04-09 17:45:41 -07:00
parent 24564772df
commit 61eda7c4e0
2 changed files with 52 additions and 4 deletions

View file

@ -50,9 +50,28 @@ extern NSString * AFCreateIncompleteDownloadDirectoryPath(void);
@property (readonly, nonatomic, retain) NSHTTPURLResponse *response;
/**
Set a target file for the response, will stream directly into this destination.
Defaults to nil, which will use a memory stream. Will create a new outputStream on change.
Note: Changing this while the request is not in ready state will be ignored.
*/
@property (readonly, nonatomic, copy) NSString *responseFilePath;
@property (nonatomic, copy) NSString *responseFilePath;
/**
Expected total length. This is different than expectedContentLength if the file is resumed.
On regular requests, this is equal to self.response.expectedContentLength unless we resume a request.
Note: this can also be -1 if the file size is not sent (*)
*/
@property (assign, readonly) long long totalContentLength;
/**
Indicator for the file offset on partial/resumed downloads.
This is greater than zero if the file download is resumed.
*/
@property (assign, readonly) long long offsetContentLength;
///----------------------------------------------------------
/// @name Managing And Checking For Acceptable HTTP Responses

View file

@ -114,7 +114,8 @@ NSString * AFCreateIncompleteDownloadDirectoryPath(void) {
@property (readwrite, nonatomic, retain) NSURLRequest *request;
@property (readwrite, nonatomic, retain) NSHTTPURLResponse *response;
@property (readwrite, nonatomic, retain) NSError *HTTPError;
@property (readwrite, nonatomic, copy) NSString *responseFilePath;
@property (assign) long long totalContentLength;
@property (assign) long long offsetContentLength;
@end
@implementation AFHTTPRequestOperation
@ -122,6 +123,8 @@ NSString * AFCreateIncompleteDownloadDirectoryPath(void) {
@synthesize responseFilePath = _responseFilePath;
@synthesize successCallbackQueue = _successCallbackQueue;
@synthesize failureCallbackQueue = _failureCallbackQueue;
@synthesize totalContentLength = _totalContentLength;
@synthesize offsetContentLength = _offsetContentLength;
@dynamic request;
@dynamic response;
@ -241,6 +244,19 @@ NSString * AFCreateIncompleteDownloadDirectoryPath(void) {
};
}
- (void)setResponseFilePath:(NSString *)responseFilePath {
if ([self isReady] && responseFilePath != _responseFilePath) {
[_responseFilePath release];
_responseFilePath = [responseFilePath retain];
if (responseFilePath) {
self.outputStream = [NSOutputStream outputStreamToFileAtPath:responseFilePath append:NO];
}else {
self.outputStream = [NSOutputStream outputStreamToMemory];
}
}
}
#pragma mark - AFHTTPClientOperation
+ (NSIndexSet *)acceptableStatusCodes {
@ -283,6 +299,8 @@ didReceiveResponse:(NSURLResponse *)response
self.response = (NSHTTPURLResponse *)response;
// 206 = Partial Content.
long long totalContentLength = self.response.expectedContentLength;
long long fileOffset = 0;
if ([self.response statusCode] != 206) {
if ([self.outputStream propertyForKey:NSStreamFileCurrentOffsetKey]) {
[self.outputStream setProperty:[NSNumber numberWithInteger:0] forKey:NSStreamFileCurrentOffsetKey];
@ -291,8 +309,19 @@ didReceiveResponse:(NSURLResponse *)response
self.outputStream = [NSOutputStream outputStreamToMemory];
}
}
}else {
NSString *contentRange = [self.response.allHeaderFields valueForKey:@"Content-Range"];
if ([contentRange hasPrefix:@"bytes"]) {
NSArray *bytes = [contentRange componentsSeparatedByCharactersInSet:[NSCharacterSet characterSetWithCharactersInString:@" -/"]];
if ([bytes count] == 4) {
fileOffset = [[bytes objectAtIndex:1] longLongValue];
totalContentLength = [[bytes objectAtIndex:2] longLongValue] ?: -1; // if this is *, it's converted to 0, but -1 is default.
}
}
}
self.offsetContentLength = MAX(fileOffset, 0);
self.totalContentLength = totalContentLength;
[self.outputStream open];
}