Skip to content

Commit

Permalink
Give TTURLResponse objects the ability to process invalid HTTP respon…
Browse files Browse the repository at this point in the history
…ses.

This fully backward-compatible patch give TTURLResponse objects the ability to optionally process error HTTP responses if they implement the request:processErrorResponse:data: method. If a TTURLResponse object does not respond to the request:processErrorResponse:data: method call or if calling it does return an NSError object, create a default NSError object instead.
  • Loading branch information
buddydvd committed Jul 10, 2011
1 parent 06e0189 commit 2377007
Show file tree
Hide file tree
Showing 2 changed files with 33 additions and 17 deletions.
13 changes: 13 additions & 0 deletions src/Three20Network/Headers/TTURLResponse.h
Expand Up @@ -45,4 +45,17 @@
- (NSError*)request:(TTURLRequest*)request processResponse:(NSHTTPURLResponse*)response
data:(id)data;

@optional
/**
* Processes the data from a unsuccessful request to construct a custom NSError object.
*
* @param request The request this response is bound to.
* @param response The response object, useful for getting the status code.
* @param data The data received from the TTURLRequest.
* @return NSError to construct for this response.
*
* @optional
*/
- (NSError*)request:(TTURLRequest*)request processErrorResponse:(NSHTTPURLResponse*)response
data:(id)data;
@end
37 changes: 20 additions & 17 deletions src/Three20Network/Sources/TTRequestLoader.m
Expand Up @@ -240,7 +240,24 @@ - (BOOL)cancel:(TTURLRequest*)request {
///////////////////////////////////////////////////////////////////////////////////////////////////
- (NSError*)processResponse:(NSHTTPURLResponse*)response data:(id)data {
for (TTURLRequest* request in _requests) {
NSError* error = [request.response request:request processResponse:response data:data];
NSError* error = nil;
// We need to accept valid HTTP status codes, not only 200.
if (!response
|| (response.statusCode >= 200 && response.statusCode < 300)
|| response.statusCode == 304) {
error = [request.response request:request processResponse:response data:data];
} else {
if ([request.response respondsToSelector:@selector(request:processErrorResponse:data:)]) {
error = [request.response request:request processErrorResponse:response data:data];
}
// Supply an NSError object if request.response's
// request:processErrorResponse:data: does not return one.
if (!error) {
TTDCONDITIONLOG(TTDFLAG_URLREQUEST, @" FAILED LOADING (%d) %@", _response.statusCode, _urlPath);
NSDictionary* userInfo = [NSDictionary dictionaryWithObject:data forKey:kTTErrorResponseDataKey];
error = [NSError errorWithDomain:NSURLErrorDomain code:_response.statusCode userInfo:userInfo];
}
}
if (error) {
return error;
}
Expand Down Expand Up @@ -366,24 +383,10 @@ - (void)connectionDidFinishLoading:(NSURLConnection *)connection {

TTDCONDITIONLOG(TTDFLAG_ETAGS, @"Response status code: %d", _response.statusCode);

// We need to accept valid HTTP status codes, not only 200.
if (_response.statusCode >= 200 && _response.statusCode < 300) {
[_queue loader:self didLoadResponse:_response data:_responseData];

} else if (_response.statusCode == 304) {
if (_response.statusCode == 304) {
[_queue loader:self didLoadUnmodifiedResponse:_response];

} else {
TTDCONDITIONLOG(TTDFLAG_URLREQUEST, @" FAILED LOADING (%d) %@",
_response.statusCode, _urlPath);
NSDictionary* userInfo = [NSDictionary dictionaryWithObject:_responseData forKey:kTTErrorResponseDataKey];
NSError* error = [NSError errorWithDomain:NSURLErrorDomain code:_response.statusCode
userInfo:userInfo];
/*
NSError* error = [NSError errorWithDomain:NSURLErrorDomain code:_response.statusCode
userInfo:nil];
*/
[_queue loader:self didFailLoadWithError:error];
[_queue loader:self didLoadResponse:_response data:_responseData];
}

TT_RELEASE_SAFELY(_responseData);
Expand Down

0 comments on commit 2377007

Please sign in to comment.