Workaround getting the wrong content-length header from apache when issuing a HE…
…AD request for dynamic content and accepting gzip More work on progress tests
Showing
4 changed files
with
99 additions
and
57 deletions
| @@ -982,7 +982,7 @@ static BOOL isiPhoneOS2; | @@ -982,7 +982,7 @@ static BOOL isiPhoneOS2; | ||
| 982 | { | 982 | { |
| 983 | 983 | ||
| 984 | //Only update progress if this isn't a HEAD request used to preset the content-length | 984 | //Only update progress if this isn't a HEAD request used to preset the content-length |
| 985 | - if (!mainRequest) { | 985 | + if (![self mainRequest]) { |
| 986 | if ([self showAccurateProgress] || ([self complete] && ![self updatedProgress])) { | 986 | if ([self showAccurateProgress] || ([self complete] && ![self updatedProgress])) { |
| 987 | [self updateUploadProgress]; | 987 | [self updateUploadProgress]; |
| 988 | [self updateDownloadProgress]; | 988 | [self updateDownloadProgress]; |
| @@ -1352,15 +1352,27 @@ static BOOL isiPhoneOS2; | @@ -1352,15 +1352,27 @@ static BOOL isiPhoneOS2; | ||
| 1352 | // See if we got a Content-length header | 1352 | // See if we got a Content-length header |
| 1353 | NSString *cLength = [responseHeaders valueForKey:@"Content-Length"]; | 1353 | NSString *cLength = [responseHeaders valueForKey:@"Content-Length"]; |
| 1354 | if (cLength) { | 1354 | if (cLength) { |
| 1355 | - [self setContentLength:CFStringGetIntValue((CFStringRef)cLength)]; | 1355 | + SInt32 length = CFStringGetIntValue((CFStringRef)cLength); |
| 1356 | - if ([self mainRequest]) { | 1356 | + |
| 1357 | - [[self mainRequest] setContentLength:contentLength]; | 1357 | + // Workaround for Apache HEAD requests for dynamically generated content returning the wrong Content-Length when using gzip |
| 1358 | - } | 1358 | + if ([self mainRequest] && [self allowCompressedResponse] && length == 20 && [self showAccurateProgress] && [self shouldResetProgressIndicators]) { |
| 1359 | - if ([self showAccurateProgress] && [self shouldResetProgressIndicators]) { | 1359 | + [[self mainRequest] setShowAccurateProgress:NO]; |
| 1360 | - [self resetDownloadProgress:[self contentLength]+[self partialDownloadSize]]; | 1360 | + [self resetDownloadProgress:1]; |
| 1361 | + | ||
| 1362 | + } else { | ||
| 1363 | + [self setContentLength:length]; | ||
| 1364 | + if ([self mainRequest]) { | ||
| 1365 | + [[self mainRequest] setContentLength:length]; | ||
| 1366 | + } | ||
| 1367 | + | ||
| 1368 | + if ([self showAccurateProgress] && [self shouldResetProgressIndicators]) { | ||
| 1369 | + [self resetDownloadProgress:[self contentLength]+[self partialDownloadSize]]; | ||
| 1370 | + } | ||
| 1361 | } | 1371 | } |
| 1372 | + | ||
| 1362 | } else if ([self showAccurateProgress] && [self shouldResetProgressIndicators]) { | 1373 | } else if ([self showAccurateProgress] && [self shouldResetProgressIndicators]) { |
| 1363 | - [self resetDownloadProgress:1]; | 1374 | + [[self mainRequest] setShowAccurateProgress:NO]; |
| 1375 | + [self resetDownloadProgress:1]; | ||
| 1364 | } | 1376 | } |
| 1365 | 1377 | ||
| 1366 | // Handle response text encoding | 1378 | // Handle response text encoding |
| @@ -150,7 +150,9 @@ | @@ -150,7 +150,9 @@ | ||
| 150 | if ([self showAccurateProgress]) { | 150 | if ([self showAccurateProgress]) { |
| 151 | 151 | ||
| 152 | // If this is a GET request and we want accurate progress, perform a HEAD request first to get the content-length | 152 | // If this is a GET request and we want accurate progress, perform a HEAD request first to get the content-length |
| 153 | - if ([[request requestMethod] isEqualToString:@"GET"]) { | 153 | + // We'll only do this before the queue is started |
| 154 | + // If requests are added after the queue is started they will probably move the progress backwards anyway, so there's no value performing the HEAD requests first | ||
| 155 | + if ([[request requestMethod] isEqualToString:@"GET"] && [self isSuspended]) { | ||
| 154 | ASIHTTPRequest *HEADRequest = [request HEADRequest]; | 156 | ASIHTTPRequest *HEADRequest = [request HEADRequest]; |
| 155 | [self addHEADOperation:HEADRequest]; | 157 | [self addHEADOperation:HEADRequest]; |
| 156 | 158 |
| @@ -64,74 +64,101 @@ IMPORTANT | @@ -64,74 +64,101 @@ IMPORTANT | ||
| 64 | [networkQueue setDelegate:self]; | 64 | [networkQueue setDelegate:self]; |
| 65 | [networkQueue setShowAccurateProgress:NO]; | 65 | [networkQueue setShowAccurateProgress:NO]; |
| 66 | [networkQueue setQueueDidFinishSelector:@selector(queueFinished:)]; | 66 | [networkQueue setQueueDidFinishSelector:@selector(queueFinished:)]; |
| 67 | + | ||
| 68 | + int i; | ||
| 69 | + for (i=0; i<5; i++) { | ||
| 70 | + NSURL *url = [[[NSURL alloc] initWithString:@"http://allseeing-i.com/i/logo.png"] autorelease]; | ||
| 71 | + ASIHTTPRequest *request = [[[ASIHTTPRequest alloc] initWithURL:url] autorelease]; | ||
| 72 | + [networkQueue addOperation:request]; | ||
| 73 | + } | ||
| 74 | + [networkQueue go]; | ||
| 75 | + | ||
| 76 | + while (!complete) { | ||
| 77 | + [[NSRunLoop currentRunLoop] runUntilDate:[NSDate dateWithTimeIntervalSinceNow:0.25]]; | ||
| 78 | + } | ||
| 67 | 79 | ||
| 68 | - NSURL *url; | 80 | + [[NSRunLoop currentRunLoop] runUntilDate:[NSDate dateWithTimeIntervalSinceNow:1]]; |
| 69 | -// url = [[[NSURL alloc] initWithString:@"http://allseeing-i.com"] autorelease]; | 81 | + BOOL success = (progress == 1.0); |
| 70 | -// ASIHTTPRequest *request1 = [[[ASIHTTPRequest alloc] initWithURL:url] autorelease]; | 82 | + GHAssertTrue(success,@"Failed to increment progress properly"); |
| 71 | -// [networkQueue addOperation:request1]; | ||
| 72 | -// | ||
| 73 | -// url = [[[NSURL alloc] initWithString:@"http://allseeing-i.com"] autorelease]; | ||
| 74 | -// ASIHTTPRequest *request2 = [[[ASIHTTPRequest alloc] initWithURL:url] autorelease]; | ||
| 75 | -// [networkQueue addOperation:request2]; | ||
| 76 | -// | ||
| 77 | -// url = [[[NSURL alloc] initWithString:@"http://allseeing-i.com"] autorelease]; | ||
| 78 | -// ASIHTTPRequest *request3 = [[[ASIHTTPRequest alloc] initWithURL:url] autorelease]; | ||
| 79 | -// [networkQueue addOperation:request3]; | ||
| 80 | -// | ||
| 81 | -// url = [[[NSURL alloc] initWithString:@"http://allseeing-i.com"] autorelease]; | ||
| 82 | -// ASIHTTPRequest *request4 = [[[ASIHTTPRequest alloc] initWithURL:url] autorelease]; | ||
| 83 | -// [networkQueue addOperation:request4]; | ||
| 84 | -// | ||
| 85 | -// [networkQueue go]; | ||
| 86 | -// | ||
| 87 | -// while (!complete) { | ||
| 88 | -// [[NSRunLoop currentRunLoop] runUntilDate:[NSDate dateWithTimeIntervalSinceNow:0.25]]; | ||
| 89 | -// } | ||
| 90 | -// | ||
| 91 | -// [[NSRunLoop currentRunLoop] runUntilDate:[NSDate dateWithTimeIntervalSinceNow:1]]; | ||
| 92 | - BOOL success = (progress > 0.95); | ||
| 93 | -// GHAssertTrue(success,@"Failed to increment progress properly"); | ||
| 94 | -// | ||
| 95 | - | ||
| 96 | 83 | ||
| 84 | + | ||
| 97 | //Now test again with accurate progress | 85 | //Now test again with accurate progress |
| 98 | complete = NO; | 86 | complete = NO; |
| 99 | progress = 0; | 87 | progress = 0; |
| 100 | [networkQueue cancelAllOperations]; | 88 | [networkQueue cancelAllOperations]; |
| 101 | [networkQueue setShowAccurateProgress:YES]; | 89 | [networkQueue setShowAccurateProgress:YES]; |
| 102 | - | ||
| 103 | - url = [[[NSURL alloc] initWithString:@"http://allseeing-i.com"] autorelease]; | ||
| 104 | - ASIHTTPRequest *request1 = [[[ASIHTTPRequest alloc] initWithURL:url] autorelease]; | ||
| 105 | - [request1 setAllowCompressedResponse:NO]; | ||
| 106 | - [networkQueue addOperation:request1]; | ||
| 107 | 90 | ||
| 108 | - url = [[[NSURL alloc] initWithString:@"http://allseeing-i.com"] autorelease]; | 91 | + for (i=0; i<5; i++) { |
| 109 | - ASIHTTPRequest *request2 = [[[ASIHTTPRequest alloc] initWithURL:url] autorelease]; | 92 | + NSURL *url = [[[NSURL alloc] initWithString:@"http://allseeing-i.com/i/logo.png"] autorelease]; |
| 110 | - [request2 setAllowCompressedResponse:NO]; | 93 | + ASIHTTPRequest *request = [[[ASIHTTPRequest alloc] initWithURL:url] autorelease]; |
| 111 | - [networkQueue addOperation:request2]; | 94 | + [networkQueue addOperation:request]; |
| 95 | + } | ||
| 96 | + [networkQueue go]; | ||
| 112 | 97 | ||
| 113 | - url = [[[NSURL alloc] initWithString:@"http://allseeing-i.com"] autorelease]; | 98 | + while (!complete) { |
| 114 | - ASIHTTPRequest *request3 = [[[ASIHTTPRequest alloc] initWithURL:url] autorelease]; | 99 | + [[NSRunLoop currentRunLoop] runUntilDate:[NSDate dateWithTimeIntervalSinceNow:0.25]]; |
| 115 | - [request3 setAllowCompressedResponse:NO]; | 100 | + } |
| 116 | - [networkQueue addOperation:request3]; | 101 | + |
| 102 | + success = (progress == 1.0); | ||
| 103 | + GHAssertTrue(success,@"Failed to increment progress properly"); | ||
| 104 | + | ||
| 105 | +} | ||
| 106 | + | ||
| 107 | +- (void)testAccurateProgressFallsBackToSimpleProgress | ||
| 108 | +{ | ||
| 117 | 109 | ||
| 118 | - url = [[[NSURL alloc] initWithString:@"http://allseeing-i.com"] autorelease]; | 110 | + ASINetworkQueue *networkQueue = [ASINetworkQueue queue]; |
| 119 | - ASIHTTPRequest *request4 = [[[ASIHTTPRequest alloc] initWithURL:url] autorelease]; | 111 | + [networkQueue setDownloadProgressDelegate:self]; |
| 120 | - [request4 setAllowCompressedResponse:NO]; | 112 | + [networkQueue setDelegate:self]; |
| 121 | - [networkQueue addOperation:request4]; | 113 | + [networkQueue setShowAccurateProgress:NO]; |
| 114 | + [networkQueue setQueueDidFinishSelector:@selector(queueFinished:)]; | ||
| 115 | + | ||
| 116 | + // Test accurate progress falls back to simpler progress when responses have no content-length header | ||
| 117 | + complete = NO; | ||
| 118 | + progress = 0; | ||
| 119 | + [networkQueue setShowAccurateProgress:YES]; | ||
| 122 | 120 | ||
| 121 | + int i; | ||
| 122 | + for (i=0; i<5; i++) { | ||
| 123 | + NSURL *url = [[[NSURL alloc] initWithString:@"http://allseeing-i.com"] autorelease]; | ||
| 124 | + ASIHTTPRequest *request = [[[ASIHTTPRequest alloc] initWithURL:url] autorelease]; | ||
| 125 | + [request setAllowCompressedResponse:NO]; // A bit hacky - my server will send a chunked response (without content length) when we don't specify that we accept gzip | ||
| 126 | + [networkQueue addOperation:request]; | ||
| 127 | + } | ||
| 123 | [networkQueue go]; | 128 | [networkQueue go]; |
| 124 | 129 | ||
| 125 | while (!complete) { | 130 | while (!complete) { |
| 126 | [[NSRunLoop currentRunLoop] runUntilDate:[NSDate dateWithTimeIntervalSinceNow:0.25]]; | 131 | [[NSRunLoop currentRunLoop] runUntilDate:[NSDate dateWithTimeIntervalSinceNow:0.25]]; |
| 127 | } | 132 | } |
| 128 | 133 | ||
| 129 | - // Progress maths are inexact for queues | 134 | + BOOL success = (progress == 1.0); |
| 130 | - success = (progress > 0.95); | ||
| 131 | GHAssertTrue(success,@"Failed to increment progress properly"); | 135 | GHAssertTrue(success,@"Failed to increment progress properly"); |
| 132 | 136 | ||
| 137 | + // This test will request gzipped content, but the content-length header we get on the HEAD request will be wrong, ASIHTTPRequest should fall back to simple progress | ||
| 138 | + // This is to workaround an issue Apache has with HEAD requests for dynamically generated content when accepting gzip - it returns the content-length of a gzipped empty body | ||
| 139 | + complete = NO; | ||
| 140 | + progress = 0; | ||
| 141 | + [networkQueue cancelAllOperations]; | ||
| 142 | + [networkQueue setShowAccurateProgress:YES]; | ||
| 143 | + | ||
| 144 | + for (i=0; i<5; i++) { | ||
| 145 | + NSURL *url = [[[NSURL alloc] initWithString:@"http://allseeing-i.com"] autorelease]; | ||
| 146 | + ASIHTTPRequest *request = [[[ASIHTTPRequest alloc] initWithURL:url] autorelease]; | ||
| 147 | + [networkQueue addOperation:request]; | ||
| 148 | + } | ||
| 149 | + [networkQueue go]; | ||
| 150 | + | ||
| 151 | + while (!complete) { | ||
| 152 | + [[NSRunLoop currentRunLoop] runUntilDate:[NSDate dateWithTimeIntervalSinceNow:0.25]]; | ||
| 153 | + } | ||
| 154 | + | ||
| 155 | + success = (progress == 1.0); | ||
| 156 | + GHAssertTrue(success,@"Failed to increment progress properly"); | ||
| 133 | } | 157 | } |
| 134 | 158 | ||
| 159 | + | ||
| 160 | + | ||
| 161 | + | ||
| 135 | - (void)uploadFailed:(ASIHTTPRequest *)request | 162 | - (void)uploadFailed:(ASIHTTPRequest *)request |
| 136 | { | 163 | { |
| 137 | GHFail(@"Failed to upload some data, cannot continue with this test"); | 164 | GHFail(@"Failed to upload some data, cannot continue with this test"); |
| @@ -202,10 +229,11 @@ IMPORTANT | @@ -202,10 +229,11 @@ IMPORTANT | ||
| 202 | 229 | ||
| 203 | - (void)setProgress:(float)newProgress | 230 | - (void)setProgress:(float)newProgress |
| 204 | { | 231 | { |
| 232 | + NSLog(@"%f",newProgress); | ||
| 205 | if (newProgress < progress) { | 233 | if (newProgress < progress) { |
| 206 | GHFail(@"Progress went backwards!"); | 234 | GHFail(@"Progress went backwards!"); |
| 207 | } | 235 | } |
| 208 | - NSLog(@"%f",newProgress); | 236 | + |
| 209 | 237 | ||
| 210 | progress = newProgress; | 238 | progress = newProgress; |
| 211 | } | 239 | } |
This diff was suppressed by a .gitattributes entry.
-
Please register or login to post a comment