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;
{
//Only update progress if this isn't a HEAD request used to preset the content-length
if (!mainRequest) {
if (![self mainRequest]) {
if ([self showAccurateProgress] || ([self complete] && ![self updatedProgress])) {
[self updateUploadProgress];
[self updateDownloadProgress];
... ... @@ -1352,14 +1352,26 @@ static BOOL isiPhoneOS2;
// See if we got a Content-length header
NSString *cLength = [responseHeaders valueForKey:@"Content-Length"];
if (cLength) {
[self setContentLength:CFStringGetIntValue((CFStringRef)cLength)];
SInt32 length = CFStringGetIntValue((CFStringRef)cLength);
// Workaround for Apache HEAD requests for dynamically generated content returning the wrong Content-Length when using gzip
if ([self mainRequest] && [self allowCompressedResponse] && length == 20 && [self showAccurateProgress] && [self shouldResetProgressIndicators]) {
[[self mainRequest] setShowAccurateProgress:NO];
[self resetDownloadProgress:1];
} else {
[self setContentLength:length];
if ([self mainRequest]) {
[[self mainRequest] setContentLength:contentLength];
[[self mainRequest] setContentLength:length];
}
if ([self showAccurateProgress] && [self shouldResetProgressIndicators]) {
[self resetDownloadProgress:[self contentLength]+[self partialDownloadSize]];
}
}
} else if ([self showAccurateProgress] && [self shouldResetProgressIndicators]) {
[[self mainRequest] setShowAccurateProgress:NO];
[self resetDownloadProgress:1];
}
... ...
... ... @@ -150,7 +150,9 @@
if ([self showAccurateProgress]) {
// If this is a GET request and we want accurate progress, perform a HEAD request first to get the content-length
if ([[request requestMethod] isEqualToString:@"GET"]) {
// We'll only do this before the queue is started
// 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
if ([[request requestMethod] isEqualToString:@"GET"] && [self isSuspended]) {
ASIHTTPRequest *HEADRequest = [request HEADRequest];
[self addHEADOperation:HEADRequest];
... ...
... ... @@ -65,33 +65,21 @@ IMPORTANT
[networkQueue setShowAccurateProgress:NO];
[networkQueue setQueueDidFinishSelector:@selector(queueFinished:)];
NSURL *url;
// url = [[[NSURL alloc] initWithString:@"http://allseeing-i.com"] autorelease];
// ASIHTTPRequest *request1 = [[[ASIHTTPRequest alloc] initWithURL:url] autorelease];
// [networkQueue addOperation:request1];
//
// url = [[[NSURL alloc] initWithString:@"http://allseeing-i.com"] autorelease];
// ASIHTTPRequest *request2 = [[[ASIHTTPRequest alloc] initWithURL:url] autorelease];
// [networkQueue addOperation:request2];
//
// url = [[[NSURL alloc] initWithString:@"http://allseeing-i.com"] autorelease];
// ASIHTTPRequest *request3 = [[[ASIHTTPRequest alloc] initWithURL:url] autorelease];
// [networkQueue addOperation:request3];
//
// url = [[[NSURL alloc] initWithString:@"http://allseeing-i.com"] autorelease];
// ASIHTTPRequest *request4 = [[[ASIHTTPRequest alloc] initWithURL:url] autorelease];
// [networkQueue addOperation:request4];
//
// [networkQueue go];
//
// while (!complete) {
// [[NSRunLoop currentRunLoop] runUntilDate:[NSDate dateWithTimeIntervalSinceNow:0.25]];
// }
//
// [[NSRunLoop currentRunLoop] runUntilDate:[NSDate dateWithTimeIntervalSinceNow:1]];
BOOL success = (progress > 0.95);
// GHAssertTrue(success,@"Failed to increment progress properly");
//
int i;
for (i=0; i<5; i++) {
NSURL *url = [[[NSURL alloc] initWithString:@"http://allseeing-i.com/i/logo.png"] autorelease];
ASIHTTPRequest *request = [[[ASIHTTPRequest alloc] initWithURL:url] autorelease];
[networkQueue addOperation:request];
}
[networkQueue go];
while (!complete) {
[[NSRunLoop currentRunLoop] runUntilDate:[NSDate dateWithTimeIntervalSinceNow:0.25]];
}
[[NSRunLoop currentRunLoop] runUntilDate:[NSDate dateWithTimeIntervalSinceNow:1]];
BOOL success = (progress == 1.0);
GHAssertTrue(success,@"Failed to increment progress properly");
//Now test again with accurate progress
... ... @@ -100,38 +88,77 @@ IMPORTANT
[networkQueue cancelAllOperations];
[networkQueue setShowAccurateProgress:YES];
url = [[[NSURL alloc] initWithString:@"http://allseeing-i.com"] autorelease];
ASIHTTPRequest *request1 = [[[ASIHTTPRequest alloc] initWithURL:url] autorelease];
[request1 setAllowCompressedResponse:NO];
[networkQueue addOperation:request1];
for (i=0; i<5; i++) {
NSURL *url = [[[NSURL alloc] initWithString:@"http://allseeing-i.com/i/logo.png"] autorelease];
ASIHTTPRequest *request = [[[ASIHTTPRequest alloc] initWithURL:url] autorelease];
[networkQueue addOperation:request];
}
[networkQueue go];
url = [[[NSURL alloc] initWithString:@"http://allseeing-i.com"] autorelease];
ASIHTTPRequest *request2 = [[[ASIHTTPRequest alloc] initWithURL:url] autorelease];
[request2 setAllowCompressedResponse:NO];
[networkQueue addOperation:request2];
while (!complete) {
[[NSRunLoop currentRunLoop] runUntilDate:[NSDate dateWithTimeIntervalSinceNow:0.25]];
}
url = [[[NSURL alloc] initWithString:@"http://allseeing-i.com"] autorelease];
ASIHTTPRequest *request3 = [[[ASIHTTPRequest alloc] initWithURL:url] autorelease];
[request3 setAllowCompressedResponse:NO];
[networkQueue addOperation:request3];
success = (progress == 1.0);
GHAssertTrue(success,@"Failed to increment progress properly");
}
url = [[[NSURL alloc] initWithString:@"http://allseeing-i.com"] autorelease];
ASIHTTPRequest *request4 = [[[ASIHTTPRequest alloc] initWithURL:url] autorelease];
[request4 setAllowCompressedResponse:NO];
[networkQueue addOperation:request4];
- (void)testAccurateProgressFallsBackToSimpleProgress
{
ASINetworkQueue *networkQueue = [ASINetworkQueue queue];
[networkQueue setDownloadProgressDelegate:self];
[networkQueue setDelegate:self];
[networkQueue setShowAccurateProgress:NO];
[networkQueue setQueueDidFinishSelector:@selector(queueFinished:)];
// Test accurate progress falls back to simpler progress when responses have no content-length header
complete = NO;
progress = 0;
[networkQueue setShowAccurateProgress:YES];
int i;
for (i=0; i<5; i++) {
NSURL *url = [[[NSURL alloc] initWithString:@"http://allseeing-i.com"] autorelease];
ASIHTTPRequest *request = [[[ASIHTTPRequest alloc] initWithURL:url] autorelease];
[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
[networkQueue addOperation:request];
}
[networkQueue go];
while (!complete) {
[[NSRunLoop currentRunLoop] runUntilDate:[NSDate dateWithTimeIntervalSinceNow:0.25]];
}
// Progress maths are inexact for queues
success = (progress > 0.95);
BOOL success = (progress == 1.0);
GHAssertTrue(success,@"Failed to increment progress properly");
// 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
// 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
complete = NO;
progress = 0;
[networkQueue cancelAllOperations];
[networkQueue setShowAccurateProgress:YES];
for (i=0; i<5; i++) {
NSURL *url = [[[NSURL alloc] initWithString:@"http://allseeing-i.com"] autorelease];
ASIHTTPRequest *request = [[[ASIHTTPRequest alloc] initWithURL:url] autorelease];
[networkQueue addOperation:request];
}
[networkQueue go];
while (!complete) {
[[NSRunLoop currentRunLoop] runUntilDate:[NSDate dateWithTimeIntervalSinceNow:0.25]];
}
success = (progress == 1.0);
GHAssertTrue(success,@"Failed to increment progress properly");
}
- (void)uploadFailed:(ASIHTTPRequest *)request
{
GHFail(@"Failed to upload some data, cannot continue with this test");
... ... @@ -202,10 +229,11 @@ IMPORTANT
- (void)setProgress:(float)newProgress
{
NSLog(@"%f",newProgress);
if (newProgress < progress) {
GHFail(@"Progress went backwards!");
}
NSLog(@"%f",newProgress);
progress = newProgress;
}
... ...
This diff was suppressed by a .gitattributes entry.