Nocilla
Nocilla copied to clipboard
Crash in LSHTTPStubURLProtocol - EXC_BAD_ACCESS - Specific way to stub redirects?
I'm getting a crash on line 54 of LSHTTPStubURLProtocol
:
[redirectRequest setAllHTTPHeaderFields:[NSHTTPCookie requestHeaderFieldsWithCookies:[cookieStorage cookiesForURL:newURL]]];
Here is the stack trace:
#0 0x000000010fd4a1d1 in CFURLCopyAbsoluteURL ()
#1 0x000000011211e3eb in HTTPCookieStorage::copyCookiesForURL(__CFURL const*, unsigned char) ()
#2 0x0000000112240c3f in -[NSHTTPCookieStorage cookiesForURL:] ()
#3 0x0000000119d6fa45 in -[LSHTTPStubURLProtocol startLoading] at /Users/Jamie/Development/Experiments/SampleCedarAsync/Pods/Nocilla/Nocilla/Hooks/NSURLRequest/LSHTTPStubURLProtocol.m:54
#4 0x0000000112206560 in ___ZN19URLConnectionLoader27_private_ScheduleOriginLoadEPK12NSURLRequestPK20_CFCachedURLResponse_block_invoke_2 ()
#5 0x0000000112119a5b in ___ZNK19URLConnectionLoader25withExistingProtocolAsyncEU13block_pointerFvP11URLProtocolE_block_invoke ()
#6 0x0000000112119a26 in RunloopBlockContext::_invoke_block(void const*, void*) ()
#7 0x000000010fd7a354 in CFArrayApplyFunction ()
#8 0x00000001121198e7 in RunloopBlockContext::perform() ()
#9 0x0000000112119726 in MultiplexerSource::perform() ()
#10 0x000000011211953c in MultiplexerSource::_perform(void*) ()
#11 0x000000010fda7431 in __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE0_PERFORM_FUNCTION__ ()
#12 0x000000010fd9d2fd in __CFRunLoopDoSources0 ()
#13 0x000000010fd9c934 in __CFRunLoopRun ()
#14 0x000000010fd9c366 in CFRunLoopRunSpecific ()
#15 0x000000011219f24d in +[NSURLConnection(Loader) _resourceLoadLoop:] ()
#16 0x000000010f6c109d in __NSThread__main__ ()
#17 0x0000000111dd5268 in _pthread_body ()
#18 0x0000000111dd51e5 in _pthread_start ()
#19 0x0000000111dd341d in thread_start ()
My testing code is as follows:
#import <Cedar/Cedar.h>
#import "CedarAsync.h"
#import "NSClient.h"
#import "Nocilla.h"
using namespace Cedar::Matchers;
using namespace Cedar::Doubles;
SPEC_BEGIN(NetworkSpec)
describe(@"Network", ^{
__block NSClient *subject;
__block NSUInteger returnedStatusCode;
beforeEach(^{
[[LSNocilla sharedInstance] start];
subject = [NSClient clientWithScheme:@"http" andHost:@"google.ca"];
stubRequest(kHTTPMethodGet, subject.baseURL.absoluteString).andReturn(303);
[subject sendRequestWithEndpoint:nil
httpMethodType:NSHTTPMethodTypeGet
requestType:NSRequestTypeURL
dataObject:nil
requestMutationBlock:nil
andCallback:^(NSUInteger statusCode, id responseObject, NSError *error)
{
returnedStatusCode = statusCode;
}];
});
afterEach(^{
[[LSNocilla sharedInstance] clearStubs];
[[LSNocilla sharedInstance] stop];
});
it(@"should return a 303", ^{
in_time(returnedStatusCode) should equal(303);
});
});
SPEC_END
It seems that further documentation is needed for how to use Nocilla with redirects, as it's not clear that you must include the Location
header in the stub itself.
Just so we're on the same page, it's important to note that HTTP requires that you include a Location
header when responding with a 3XX code (https://tools.ietf.org/html/rfc2616#section-10.3).
Since this is all very standard stuff, I wouldn't really describe it as documentation needed for using Nocilla with redirects; I'd just say that it's generally what you need to do when responding with a redirect.
Now, the crash that you're seeing here is happening because Nocilla isn't doing appropriate checks for nil when it retrieves the Location
header. In my opinion, this is just a bug that happens to be fatal if you don't stub a well-formed redirect. I've documented this along with a few other redirect quirks in issue #124.