Закрытие постоянного соединения с прокси-сервером

Я реализую поддержку прокси для приложения OSX.

Я создал собственный NSURLProtocol, и он отлично работает для прокси без аутентификации. Пробовал и с CCProxy, и с FreeProxy на компьютере с Windows в локальной сети.

Однако, когда включена прокси-аутентификация, любой запрос в первые несколько секунд работает отлично, а затем соединение переходит из состояния ESTABLISHED в CLOSE_WAIT через 5 секунд. Прокси снова показывает 0 подключений и после этого в приложении любой HTTP-запрос получит 407, даже если заголовок proxy-auth предварительно установлен.

Мой код выглядит так:

// set the auth fields
CFStringRef usernameRef = (__bridge CFStringRef)appProxyPrefs.proxyUserName;
CFStringRef passwordRef = (__bridge CFStringRef)appProxyPrefs.proxyPassword;
CFHTTPMessageAddAuthentication(copyOfOriginal, nil, usernameRef, passwordRef, kCFHTTPAuthenticationSchemeBasic, YES);
...
// useless
CFHTTPMessageSetHeaderFieldValue(copyOfOriginal, (__bridge CFStringRef)@"Connection", (CFStringRef)(@"Keep-Alive"));
... 
// create stream, callback, schedule
// apply proxy settings to the stream
if (isNoProxyOverride)
    CFReadStreamSetProperty(myReadStream, kCFStreamPropertyHTTPProxy, (__bridge CFTypeRef)(noProxyDict));
else
    CFReadStreamSetProperty(myReadStream, kCFStreamPropertyHTTPProxy, (__bridge CFTypeRef)(manualProxyDict));
...
CFReadStreamSetProperty(myReadStream, kCFStreamPropertyHTTPAttemptPersistentConnection, kCFBooleanTrue);
if (!CFReadStreamOpen(myReadStream)) {  // error }      
    else
    {
        // check if there is a prev stream
        if (currentStream != nil)
        {
            [currentStream close];
            currentStream = nil;
        }
        currentStream = (__bridge NSInputStream *)(myReadStream);
    }

Как вы видите, я пытался сохранить предыдущее соединение в статическом потоке ввода и выпускать его только после открытия нового, но это кажется бесполезным.

Также попытался настроить базовый сокет на поддержание активности в kCFStreamEventOpenCompleted, как это предлагается в NSStream TCP Keep-alive iOS , все еще безуспешно.

Почему соединение закрывается? Как я могу отладить его или заставить его работать? Является ли ошибка соединения прокси-сервером?

Спасибо.

Редактировать 1: wireshark

Изменить 2: похоже, это связано с HTTPS... Если я изменю сервер на простой http вместо https, он будет работать отлично.


person Templar    schedule 09.03.2015    source источник
comment
Вы проверили с захватом трафика, какая сторона отправляет пакет FIN? Это сузило бы его до проблемы клиента и прокси.   -  person RomanK    schedule 09.03.2015
comment
@RomanK Установил wireshark на машину с Windows, и соединение кажется активным, а затем прокси? отправляет FIN, и соединение сохраняется. См. редактирование.   -  person Templar    schedule 10.03.2015
comment
Из перехвата трудно понять, является ли 192.168.1.141 прокси-сервером или клиентом, но давайте предположим, что это прокси-сервер. Существует также предыдущее предупреждение TLS, поэтому, как вы подозреваете, оно определенно связано с TLS. Стоит просмотреть детали пакета предупреждений и/или журналы прокси-сервера, так как они могут дать подсказку. Кроме того, как вы выполняете аутентификацию с помощью прокси - вы отправляете заголовок Proxy-Authorization: Basic при начальном ПОДКЛЮЧЕНИИ?   -  person RomanK    schedule 10.03.2015
comment
141 — это прокси на порту 5555. Третья строка добавляет заголовок proxy-auth. В настоящее время, когда я получаю 407, я просто повторно отправляю тот же запрос, и он будет аутентифицирован, я действительно не знаю, почему бы не работать с предварительно добавленными заголовками при использовании HTTPS...   -  person Templar    schedule 11.03.2015
comment
Итак, просто чтобы повторить мой вопрос - вы добавляете упреждающий Proxy-Authorization в CONNECT? Это трудно понять только по названиям пакетов.   -  person RomanK    schedule 11.03.2015
comment
@RomanK Да, каждый раз.   -  person Templar    schedule 12.03.2015