Add a RKRequest attribute to control redirect handling

The default behavior is the same as before, to follow redirects. If RKRequest.followRedirect is set to NO, then a redirect (301, 302, 307) response will not be followed, and the request processing will proceed using the current request only.
This commit is contained in:
Marcus Brito
2012-04-04 09:20:00 -03:00
committed by Blake Watters
parent e0b248da46
commit ea100b6aac
7 changed files with 64 additions and 1 deletions

View File

@@ -190,7 +190,8 @@ typedef void(^RKRequestDidFailLoadWithErrorBlock)(NSError *error);
NSSet *_additionalRootCertificates;
BOOL _disableCertificateValidation;
BOOL _followRedirect;
#if TARGET_OS_IPHONE
RKRequestBackgroundPolicy _backgroundPolicy;
UIBackgroundTaskIdentifier _backgroundTaskIdentifier;
@@ -373,6 +374,12 @@ typedef void(^RKRequestDidFailLoadWithErrorBlock)(NSError *error);
*/
@property (nonatomic, copy) RKRequestDidFailLoadWithErrorBlock onDidFailLoadWithError;
/**
Whether this request should follow server redirects or not.
@default YES
*/
@property (nonatomic, assign) BOOL followRedirect;
#if TARGET_OS_IPHONE
///-----------------------------------------------------------------------------

View File

@@ -117,6 +117,7 @@ RKRequestMethod RKRequestMethodTypeFromName(NSString *methodName) {
@synthesize additionalRootCertificates = _additionalRootCertificates;
@synthesize disableCertificateValidation = _disableCertificateValidation;
@synthesize cancelled = _cancelled;
@synthesize followRedirect = _followRedirect;
#if TARGET_OS_IPHONE
@synthesize backgroundPolicy = _backgroundPolicy, backgroundTaskIdentifier = _backgroundTaskIdentifier;
@@ -136,6 +137,7 @@ RKRequestMethod RKRequestMethodTypeFromName(NSString *methodName) {
_cacheTimeoutInterval = 0;
_timeoutInterval = 120.0;
_defaultHTTPEncoding = NSUTF8StringEncoding;
_followRedirect = YES;
}
return self;
}

View File

@@ -181,6 +181,16 @@ return __VA_ARGS__;
return hasCredentials;
}
- (NSURLRequest *)connection:(NSURLConnection *)connection willSendRequest:(NSURLRequest *)request redirectResponse:(NSURLResponse *)response {
if (nil == response || _request.followRedirect) {
RKLogDebug(@"Proceeding with request to %@", request);
return request;
} else {
RKLogDebug(@"Not following redirect to %@", request);
return nil;
}
}
- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data {
RKResponseIgnoreDelegateIfCancelled();
[_body appendData:data];

View File

@@ -1163,6 +1163,7 @@
25EC1B3814F84B5C00C3CF3F /* UIImage+RKAdditions.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "UIImage+RKAdditions.m"; sourceTree = "<group>"; };
25FABED414E37A2B00E609E7 /* RKTestResponseLoader.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = RKTestResponseLoader.h; path = Testing/RKTestResponseLoader.h; sourceTree = "<group>"; };
25FABED514E37A2B00E609E7 /* RKTestResponseLoader.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = RKTestResponseLoader.m; path = Testing/RKTestResponseLoader.m; sourceTree = "<group>"; };
41A4EBF715374D1800740BC8 /* redirection.rb */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.ruby; path = redirection.rb; sourceTree = "<group>"; };
49A66B0814CEFB0400A6F062 /* LICENCE */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; name = LICENCE; path = XMLReader/LICENCE; sourceTree = "<group>"; };
49A66B0914CEFB0400A6F062 /* XMLReader.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = XMLReader.h; path = XMLReader/XMLReader.h; sourceTree = "<group>"; };
49A66B0A14CEFB0400A6F062 /* XMLReader.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = XMLReader.m; path = XMLReader/XMLReader.m; sourceTree = "<group>"; };
@@ -1887,6 +1888,7 @@
2516104A1456F2330060A5C5 /* network */ = {
isa = PBXGroup;
children = (
41A4EBF715374D1800740BC8 /* redirection.rb */,
2516104B1456F2330060A5C5 /* authentication.rb */,
2516104C1456F2330060A5C5 /* etags.rb */,
2516104D1456F2330060A5C5 /* oauth2.rb */,

View File

@@ -268,4 +268,31 @@
assertThatInteger([loader.response bodyEncoding], is(equalToInteger(NSASCIIStringEncoding)));
}
- (void)testFollowRedirect {
RKClient* client = [RKTestFactory client];
RKTestResponseLoader* loader = [RKTestResponseLoader responseLoader];
[client get:@"/redirection" delegate:loader];
[loader waitForResponse];
assertThatInteger(loader.response.statusCode, is(equalToInteger(200)));
id body = [loader.response parsedBody:NULL];
assertThat([body objectForKey:@"redirected"], is(equalTo([NSNumber numberWithBool:YES])));
}
- (void)testNoFollowRedirect {
RKClient* client = [RKTestFactory client];
RKTestResponseLoader* loader = [RKTestResponseLoader responseLoader];
RKRequest* request = [client requestWithResourcePath:@"/redirection"];
request.method = RKRequestMethodGET;
request.followRedirect = NO;
request.delegate = loader;
[request send];
[loader waitForResponse];
assertThatInteger(loader.response.statusCode, is(equalToInteger(302)));
assertThat([loader.response.allHeaderFields objectForKey:@"Location"], is(equalTo(@"/redirection/target")));
}
@end

View File

@@ -0,0 +1,13 @@
module RestKit
module Network
class Redirection < Sinatra::Base
get '/redirection' do
[302, {"Location" => '/redirection/target'}, ""]
end
get '/redirection/target' do
[200, {"Content-Type" => "application/json"}, {"redirected" => true}.to_json]
end
end
end
end

View File

@@ -18,6 +18,7 @@ require 'restkit/network/authentication'
require 'restkit/network/etags'
require 'restkit/network/timeout'
require 'restkit/network/oauth2'
require 'restkit/network/redirection'
class Person < Struct.new(:name, :age)
def to_json(*args)
@@ -38,6 +39,7 @@ class RestKitTestServer < Sinatra::Base
use RestKit::Network::ETags
use RestKit::Network::Timeout
use RestKit::Network::OAuth2
use RestKit::Network::Redirection
def render_fixture(path, options = {})
send_file File.join(settings.public_folder, path), options