NSURLProtocol — обработка https-запроса

Это canInitWithRequest в 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;
}  

Но я хочу, чтобы NSURLProtocol также разрешал запросы https.
Я пробовал это, но все запросы терпят неудачу при вызове:

+ (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;

}

Одним из примеров является запрос на вход со схемой https. В приведенной выше функции возвращается YES, но когда вызывается запрос на вход, я получаю эту ошибку в журнале:

Error Domain=NSURLErrorDomain Code=-1004 «Не удалось подключиться к серверу».

Однако, если я удалю проверку https в canInitWithRequest, я не получу ошибки.
Я использую RNCachingURLProtocol для кэширования запросов.
Как этого добиться.


person Nitish    schedule 13.02.2015    source источник
comment
Проверьте, какой из ваших тестов в if является ЛОЖНЫМ. Я попробовал ваш код, и он прошел оба теста isEqualToString:, но у меня нет значения RNCachingURLHeader для проверки.   -  person Larme    schedule 13.02.2015
comment
@Larne : RNCachingURLHeader = @X-RNCache   -  person Nitish    schedule 13.02.2015
comment
Я не могу воспроизвести вашу проблему. Я пытался, но https-запросы в вашем canInitWithRequest: ведут себя так же, как и http-запросы. В canInitWithRequest:: журналы [[request URL] scheme] и [request valueForHTTPHeaderField:RNCachingURLHeader]. Кроме того, проверьте, может ли быть проблема с учетом регистра (ваше сравнение с lowercase scheme).   -  person Larme    schedule 13.02.2015


Ответы (2)


Просто для тестирования и понимания рефакторинг вашего кода:

+ (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;
}

Обратите внимание на lowercaseString, это защитное кодирование.

person zaph    schedule 16.02.2015
comment
Это, кажется, не отвечает на вопрос. - person Jeffrey Bosboom; 16.02.2015
comment
@JeffreyBosboom Правильно и не претендует на это. Другого варианта, отображающего форматирование, нет. Обратите внимание на часть вопроса: However if I remove check of https in canInitWithRequest, I get no error и это указывает на то, что в этом есть ошибка или, как минимум, некоторая путаница. В вопросе ОП действительно нет способа проверить, что обеспечивают отдельные части и какая из них, если таковая имеется, способствует сбою. Этот стиль кодирования может помочь ОП найти свою проблему. - person zaph; 16.02.2015
comment
Так это должен быть комментарий? Не ответ? - person JumpingJezza; 17.02.2015

«Не удалось подключиться к серверу» означает, что вы не в сети, но запрошенный вами URL-адрес не найден в кеше.

Посмотрите в startLoading. Проверьте абсолютную строку URL. Убедитесь, что тот, который вы кэшировали, точно такой же, как тот, который вы сейчас запрашиваете. Если вы поместите какие-либо изменяемые данные в свой URL-адрес, он не будет совпадать.

Я только что заметил, что многие небольшие проблемы, которые, как мне казалось, я исправил в этом коде, на самом деле были ожидающими запросов на вытягивание. Поэтому сейчас я объединил большинство из них. В частности, мой способ хеширования URL-адресов был очень подвержен коллизиям . Это исправлено. И обновленный код добавляет поддержку не-http. (Но ваша ошибка по-прежнему предполагает несоответствие URL.)

person Rob Napier    schedule 16.02.2015
comment
Функция инициализации регистрируется только для http в обновленном коде на git. [сам setSupportedSchemes:[NSSet setWithObject:@http]]; - person Nitish; 19.02.2015
comment
Это просто по умолчанию. Вы можете установить свойство для включения https без взлома кода. - person Rob Napier; 19.02.2015
comment
Я попытался установить https для поддерживаемых схем: [self setSupportedSchemes:[NSSet setWithObjects:@http, @https, nil]]; в функции инициализации. Но все же запросы https не вызываются. Поэтому я даже не могу проверить, есть ли несоответствие URL, потому что startLoading не вызывается для https. - person Nitish; 10.03.2015