NSURLProtocol - handle https request

2019-08-01 11:38发布

This is canInitWithRequest in NSURLProtocol:

+ (BOOL)canInitWithRequest:(NSURLRequest *)request
{
  // only handle http requests we haven't marked with our header.
  if ([[[request URL] scheme] isEqualToString:@"http"] &&
      ([request valueForHTTPHeaderField:RNCachingURLHeader] == nil)) {
    return YES;
  }
  return NO;
}  

But I want NSURLProtocol to allow https requests as well.
I tried this but all requests fail when called :

+ (BOOL)canInitWithRequest:(NSURLRequest *)request
{
  // only handle http requests we haven't marked with our header.
  if (([[[request URL] scheme] isEqualToString:@"http"] || [[[request URL] scheme] isEqualToString:@"https"]) &&
      ([request valueForHTTPHeaderField:RNCachingURLHeader] == nil)) {
    return YES;
  }
  return NO;

}

One example is of a login request which has https scheme. In the above function, YES is returned but when the login request is called, I get this error in log :

Error Domain=NSURLErrorDomain Code=-1004 "Could not connect to the server."

However if I remove check of https in canInitWithRequest, I get no error.
I am using RNCachingURLProtocol to cache the requests.
How may I achieve this.

2条回答
迷人小祖宗
2楼-- · 2019-08-01 12:17

"Could not connect to the server" means that you're offline, but the URL you requested was not found in the cache.

Look in startLoading. Check the absolute string of the URL. Make sure that the one you cached is precisely the same as the one you're now requesting. If you put any changeable data in your URL, then it won't match.

I just noticed that a lot of little problems I thought I'd fixed in this code were actually pending pull requests. So I've merged most of those now. In particular, my way of hashing URLs was very prone to collisions. That's fixed. And the updated code adds support for non-http. (But your error still suggests an URL mismatch.)

查看更多
你好瞎i
3楼-- · 2019-08-01 12:20

Just for testing and comprehension refactor your code:

+ (BOOL)canInitWithRequest:(NSURLRequest *)request
{
    NSString *scheme = [[[request URL] scheme] lowercaseString];
    BOOL supportedScheme = [scheme isEqualToString:@"http"] || [scheme isEqualToString:@"https"];

    NSString *header = [request valueForHTTPHeaderField:RNCachingURLHeader];
    BOOL validHeader = header == nil;

    BOOL canInit = supportedScheme && validHeader;

    return canInit;
}

Note the lowercaseString, that is defensive coding.

查看更多
登录 后发表回答