После некоторой отладки это кажется недостатком в библиотеках классов JRE, особенно в sun.net.www.protocol.http.HttpURLConnection
.
Изучение запросов и ответов HTTP в случаях конечных точек HTTP и HTTPS показало, что в успешном случае HTTP запросы имели заголовок Proxy-Connection=keep-alive
, который отсутствовал в случае сбоя HTTPS. Если читать в более общем плане, то возникает некоторая путаница относительно того, следует ли использовать «Proxy-Connection» или просто «Connection» тоже ...
В любом случае, примечательно, что в случае HTTP код проходит через HttpURLConnection.writeRequests()
, который содержит следующий фрагмент кода
/*
* For HTTP/1.1 the default behavior is to keep connections alive.
* However, we may be talking to a 1.0 server so we should set
* keep-alive just in case, except if we have encountered an error
* or if keep alive is disabled via a system property
*/
// Try keep-alive only on first attempt
if (!failedOnce && http.getHttpKeepAliveSet()) {
if (http.usingProxy) {
requests.setIfNotSet("Proxy-Connection", "keep-alive");
} else {
requests.setIfNotSet("Connection", "keep-alive");
}
Нет такого кода при создании туннеля через прокси для HTTPS, что приводит к тому, что Squid расстраивается во время диалога аутентификации NTLM.
Чтобы обойти это, в HttpURLConnection.sendCONNECTRequest()
я добавил
if (http.getHttpKeepAliveSet()) {
if (http.usingProxy) {
requests.setIfNotSet("Proxy-Connection", "keep-alive");
}
}
как раз перед
setPreemptiveProxyAuthentication(requests);
http.writeRequests(requests, null);
Я ввел свой модифицированный HttpURLConnection.class
в JRE, используя флаг "-Xbootclasspath / p", и теперь он работает! Не совсем элегантно, но мы здесь.