1

The webviews in my apps have been getting these errors from the new iOS 9 NSAppTransportSecurity standards:

NSURLSession/NSURLConnection HTTP load failed (kCFStreamErrorDomainSSL, -9802)

I don't know where this error is being generated but essentially I want to find out how to know which URL was attempted?

After that I can configure the plist appropriately.

So far I have set a breakpoint in - (void)webView:(UIWebView *)webView didFailLoadWithError:(NSError *)error but this code is not called when getting the error.

kraftydevil
  • 5,144
  • 6
  • 43
  • 65

1 Answers1

2

If you're just debugging, set the CFNETWORK_DIAGNOSTICS environment variable to 3, e.g.

setenv("CFNETWORK_DIAGNOSTICS", "3", 1);

at the beginning of your app, before you call anything that would potentially cause the CFNetwork framework code to load (i.e. at the beginning of main). You should get the URLs in the console.

If you need to do this in a shipping app in a way that would let you debug it remotely, register an NSURLProtocol object globally, and in the canInitWithRequest: method, print the value and return NO. That should happen early enough in the process that it works even with strict transport security enabled.

Example:

@interface MyProtocol: NSURLProtocol
@end

@implementation MyProtocol
+ (BOOL)canInitWithRequest:(NSURLRequest *)request
{
    NSLog(@"Request: %@\n", request); // Log it in whatever way you need.
    return NO;
}
@end

...

// Somewhere else, e.g. in applicationDidFinishLaunching:, do this:
[NSURLProtocol registerClass:[MyProtocol class]];

Ordering isn't guaranteed, but the failed URL is likely to be printed roughly right before the failure.

dgatwood
  • 10,129
  • 1
  • 28
  • 49
  • It sounds viable but I'm looking for a more low-level answer with some kind of example. Of course it doesn't have to be the full solution - just some code to get me on the right track. Also, I'm curious if this approach will catch failed image urls embedded in the urls displayed by the webviews? – kraftydevil Oct 28 '15 at 11:54
  • An NSURLProtocol should catch any URL request by any part of the operating system, so long as it goes through NSURLConnection or NSURLSession. – dgatwood Oct 28 '15 at 16:55
  • Added an example of the protocol, and also added a bit about CFNETWORK_DIAGNOSTICS environment variable, which I probably should have suggested first.... :-) – dgatwood Oct 28 '15 at 17:04
  • I've had some minor success so I added more specific troubleshooting steps to your first option. It's currently waiting for peer review so I will accept when approved. – kraftydevil Oct 29 '15 at 16:00
  • Regarding the second option, how can I use this to say "this is the domain of the url that is failing". The code you provided appears to only handle printing information when initializing the object and I don't understand how this prints domain failure information. – kraftydevil Oct 29 '15 at 16:02
  • It is an approximation intended to show you the most recent URLs (one of which was likely the failing URL) for log analysis of in-the-field failures. If you want to know with 100% certainty which URL failued using that approach, you have to go a bit further and actually create a full protocol handler that takes the request, tweaks it in some detectable way (such as adding a header), re-issues it, refuses it when it sees the modified request (so that the normal protocol handles it), and serves as the connection/task's delegate so that it can detect the connection failure. – dgatwood Oct 29 '15 at 17:47
  • The extended version of that approach also requires your protocol to send challenges for authentication, etc. It is much more complex than the code required for getting a quick approximation, which is why I didn't attempt it here. :-) – dgatwood Oct 29 '15 at 17:49
  • I understand. Does `canInitWithRequest` get called as long as I register it in `applicationDidFinishLaunching`? – kraftydevil Oct 29 '15 at 19:38
  • For NSURLConnection, yes, and by extension, for web views. For NSURLSession, I'm not certain whether the globally registered protocols are used or not; you might have to register it as part of creating the session configuration. – dgatwood Oct 30 '15 at 00:29
  • Just to clarify, "...and by extension, for UIWebView views". – dgatwood Sep 07 '17 at 02:40