Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP

Loading…

Patch to fix a problem when using didReceiveData: delegate or dataReceivedBlock callback #319

Open
wants to merge 7 commits into from

3 participants

@joewhaley

There is a problem when processing data using callbacks/delegates whereby the callback receives the body of a 401/407 response, and there is no way to tell from the callback whether the data is from the initial 40x response or from a subsequent response. This means if you are using a streaming parser with ASIHTTPRequest, you will get garbage before the actual data.

You cannot check the response status code, response headers, or any other part of the request inside the block because the values may have changed between the time the data was received and when the callback happens. The passOnReceivedData callback is enqueued on the main thread and execution is not blocked, so the callback can happen much later, after the request has successfully retried and looks like it was successful.

My patch simply disables the data callbacks when authentication is needed, so the 40x response is simply added to the rawResponseData buffer as it would be if there were no callbacks defined. Considering it is not possible with the current interface to figure out which request the data came from, the code as it stands is not useful anyway. With the patch, you can still get the 40x body through the standard interfaces if you need to access it.

I think this approach is better than changing the callback interface to include additional information like response status code, etc.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Commits on Apr 26, 2012
Commits on Jul 27, 2012
  1. @erikchen

    Rename userAgent -> userAgentString

    erikchen authored John Whaley committed
    Apparently Apple doesn't like it when asi-http synthesizes userAgent.
    
    pokeb#309
  2. @jaygraves

    Fix the userAgent test case.

    jaygraves authored John Whaley committed
Commits on Sep 6, 2012
  1. Add support for getting HTTP version from response.

    John Whaley authored
Commits on Sep 13, 2012
  1. Merge remote-tracking branch 'upstream/master'

    John Whaley authored
This page is out of date. Refresh to see the latest.
Showing with 15 additions and 3 deletions.
  1. +4 −0 Classes/ASIHTTPRequest.h
  2. +11 −3 Classes/ASIHTTPRequest.m
View
4 Classes/ASIHTTPRequest.h
@@ -264,6 +264,9 @@ typedef void (^ASIDataBlock)(NSData *data);
// Description of the HTTP status code
NSString *responseStatusMessage;
+ // HTTP version of the response
+ NSString *responseVersion;
+
// Size of the response
unsigned long long contentLength;
@@ -944,6 +947,7 @@ typedef void (^ASIDataBlock)(NSData *data);
@property (retain) NSDictionary *proxyCredentials;
@property (assign,readonly) int responseStatusCode;
@property (retain,readonly) NSString *responseStatusMessage;
+@property (retain,readonly) NSString *responseVersion;
@property (retain) NSMutableData *rawResponseData;
@property (assign) NSTimeInterval timeOutSeconds;
@property (retain, nonatomic) NSString *requestMethod;
View
14 Classes/ASIHTTPRequest.m
@@ -225,6 +225,7 @@ - (void)callBlock:(ASIBasicBlock)block;
@property (retain) NSString *authenticationRealm;
@property (retain) NSString *proxyAuthenticationRealm;
@property (retain) NSString *responseStatusMessage;
+@property (retain) NSString *responseVersion;
@property (assign) BOOL inProgress;
@property (assign) int retryCount;
@property (assign) BOOL willRetryRequest;
@@ -389,6 +390,7 @@ - (void)dealloc
[PACurl release];
[clientCertificates release];
[responseStatusMessage release];
+ [responseVersion release];
[connectionInfo release];
[requestID release];
[dataDecompressor release];
@@ -2155,6 +2157,7 @@ - (void)readResponseHeaders
[self setResponseHeaders:[NSMakeCollectable(CFHTTPMessageCopyAllHeaderFields(message)) autorelease]];
[self setResponseStatusCode:(int)CFHTTPMessageGetResponseStatusCode(message)];
[self setResponseStatusMessage:[NSMakeCollectable(CFHTTPMessageCopyResponseStatusLine(message)) autorelease]];
+ [self setResponseVersion:[NSMakeCollectable(CFHTTPMessageCopyVersion(message)) autorelease]];
if ([self downloadCache] && ([[self downloadCache] canUseCachedDataForRequest:self])) {
@@ -2258,10 +2261,8 @@ - (void)readResponseHeaders
NSString *connectionHeader = [[[self responseHeaders] objectForKey:@"Connection"] lowercaseString];
- NSString *httpVersion = [NSMakeCollectable(CFHTTPMessageCopyVersion(message)) autorelease];
-
// Don't re-use the connection if the server is HTTP 1.0 and didn't send Connection: Keep-Alive
- if (![httpVersion isEqualToString:(NSString *)kCFHTTPVersion1_0] || [connectionHeader isEqualToString:@"keep-alive"]) {
+ if (![self.responseVersion isEqualToString:(NSString *)kCFHTTPVersion1_0] || [connectionHeader isEqualToString:@"keep-alive"]) {
// See if server explicitly told us to close the connection
if (![connectionHeader isEqualToString:@"close"]) {
@@ -3331,6 +3332,12 @@ - (void)handleBytesAvailable
dataWillBeHandledExternally = YES;
}
#endif
+
+ if ([self authenticationNeeded]) {
+ // Don't pass the body of a 401/407 response to the callback.
+ dataWillBeHandledExternally = NO;
+ }
+
// Does the delegate want to handle the data manually?
if (dataWillBeHandledExternally) {
@@ -5086,6 +5093,7 @@ - (void)setRequestRedirectedBlock:(ASIBasicBlock)aRedirectBlock
@synthesize shouldPresentProxyAuthenticationDialog;
@synthesize authenticationNeeded;
@synthesize responseStatusMessage;
+@synthesize responseVersion;
@synthesize shouldPresentCredentialsBeforeChallenge;
@synthesize haveBuiltRequestHeaders;
@synthesize inProgress;
Something went wrong with that request. Please try again.