Подтвердить что ты не робот

Как отменить постоянное соединение с помощью NSURLConnection?

Возможно ли уничтожить постоянное соединение, которое было создано с помощью NSURLConnection? Мне нужно иметь возможность уничтожить постоянное соединение и выполнить другое квитирование SSL.

Как и сейчас, вызов [conn cancel] оставляет постоянное соединение за тем, которое используется с последующим запросом на соединение с этим хостом, чего я не хочу.

4b9b3361

Ответ 1

Как оказалось, я считаю, что кэш сеанса Secure Transport TLS виноват.

Я также задал вопрос на форумах разработчиков Apple и получил ответ от человека Apple. Он указал мне на этот образец кода образца Apple, в котором говорится:

В нижней части стека TLS на iOS и Mac OS X есть компонент, известный как Secure Transport. Secure Transport поддерживает кеш сеанса TLS для каждого процесса. Когда вы подключаетесь через TLS, кэш хранит информацию о согласовании TLS, чтобы последующие соединения могли подключаться быстрее. Механизм на проводе описан по ссылке ниже.

http://en.wikipedia.org/wiki/Transport_Layer_Security#Resumed_TLS_handshake

Здесь представлены некоторые интересные ошибки, особенно при отладке. Например, рассмотрим следующую последовательность:

  • Вы используете вкладку "Отладка", чтобы отключить проверку сервера TLS.

  • Вы подключаетесь к сайту с самозаверяющим идентификатором. Соединение выполняется успешно, поскольку вы отключили проверку доверия TLS-сервера. Это добавляет запись в кеш сеанса Secure Transport TLS.

  • Вы используете вкладку "Отладка", чтобы установить проверку сервера TLS по умолчанию.

  • Вы сразу же подключаетесь к тому же сайту, что и на шаге 2. Это должно завершиться неудачно из-за изменения политики проверки доверия сервера, но оно преуспевает, потому что вы никогда не получаете запрос NSURLAuthenticationMethodServerTrust. Под обложками Secure Transport возобновил сеанс TLS, что означает, что вызов никогда не пузырится до вашего уровня.

  • С другой стороны, если вы задерживаетесь на 11 минут между шагами 3 и 4, все работает так, как ожидалось (ну, как ожидалось:-). Это связано с тем, что кеш сеанса Secure Transport TLS имеет время ожидания 10 минут.

В реальном мире это не огромная проблема, но во время отладки это может быть очень запутанным. Там нет программного способа очистки кэша сеанса Secure Transport TLS, но, поскольку кеш-процесс является процессом, вы можете избежать этой проблемы во время отладки, просто прекратив работу и перезапустив приложение. Помните, что, начиная с iOS 4, нажатие кнопки "Домой" не обязательно покидает ваше приложение. Вместо этого вы должны выйти из приложения из списка последних приложений.

Итак, на основании этого пользователю придется либо убить приложение, либо перезагрузить его, либо подождать более 10 минут, прежде чем отправлять другой запрос.

Я сделал еще один поиск Google с этой новой информацией и нашел эту техническую статью и техническую статью Apple, которая точно соответствует этой проблеме. Рядом со дном в нем упоминается добавление конечного "." . для доменных имен (и, надеюсь, IP-адресов) для запросов, чтобы заставить пропустить кеш сеанса TLS (если вы не можете каким-либо образом изменить сервер, чего я не могу), поэтому я собираюсь попробовать это и, надеюсь, это будет работать. Я опубликую свои результаты после того, как проведу это.

### EDIT ###

Я тестировал добавление '.' до конца IP-адреса, и запрос был успешно завершен.

Но я думал о проблеме в целом, и нет причин для принудительного установления SSL-связи. В моем случае решение этой проблемы - сохранить копию последнего известного SecCertificateRef, который был возвращен с сервера. При выполнении другого запроса на сервер, если используется кешированный сеанс TLS (connection:didReceiveAuthenticationChallenge: не был вызван), мы знаем, что сохраненный SecCertificateRef по-прежнему действителен. Если вызывается connection:didReceiveAuthenticationChallenge:, мы можем получить новый SecCertificateRef в это время.

Ответ 2

Начиная с OS X 10.9, NSURLSession является решением.

Ответ 3

Во-первых, вы должны использовать   [self.conn cancel] и, во-вторых, это делает то, что он говорит. Он отменяет себя. Если вы больше не хотите использовать NSURLConnection, он ничего не сделает, и если вы снова будете использовать его, вы можете просто установить другой запрос, который будет подключаться к данному серверу.

Надеюсь, что это поможет.