Ben Copsey

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
@@ -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.