Apache HttpClient не показывает заголовки ответа Content-Length и Content-Encoding ответа - PullRequest
0 голосов
/ 03 апреля 2020

Я установил Apache httpcomponents-client-5.0.x , и, просматривая заголовки ответа http, я был шокирован, что в нем не отображаются заголовки Content-Length и Content-Encoding, это это код, который я использовал для тестирования

import org.apache.hc.client5.http.impl.classic.CloseableHttpClient;
import org.apache.hc.client5.http.impl.classic.CloseableHttpResponse;
import org.apache.hc.client5.http.impl.classic.HttpClients;
import com.sun.net.httpserver.Headers;

CloseableHttpClient httpclient = HttpClients.createDefault();
HttpGet request = new HttpGet(new URI("https://www.example.com"));
CloseableHttpResponse response = httpclient.execute(request);
Header[] responseHeaders = response.getHeaders();
for(Header header: responseHeaders) {               
    System.out.println(header.getName());
}
// this prints all the headers except 
// status code header
// Content-Length
// Content-Encoding

Независимо от того, что я пытаюсь, я получаю тот же результат, как этот

Iterator<Header> headersItr = response.headerIterator();
while(headersItr.hasNext()) {
    Header header = headersItr.next();
    System.out.println(header.getName());
}

Или это

HttpEntity entity = response.getEntity();
System.out.println(entity.getContentEncoding()); // NULL
System.out.println(entity.getContentLength());   // -1

Согласно на этот вопрос , который задавался 6 лет go, кажется старым даже с более старыми версиями Apache HttpClient.

Конечно, сервер действительно возвращается эти заголовки подтверждены Wireshark, и Apache HttpClient регистрирует себя

2020-04-03 07:59:09,106 DEBUG [org.apache.hc.client5.http.headers] http-outgoing-0 << HTTP/1.1 200 OK
2020-04-03 07:59:09,106 DEBUG [org.apache.hc.client5.http.headers] http-outgoing-0 << Content-Encoding: gzip
2020-04-03 07:59:09,106 DEBUG [org.apache.hc.client5.http.headers] http-outgoing-0 << Accept-Ranges: bytes
2020-04-03 07:59:09,107 DEBUG [org.apache.hc.client5.http.headers] http-outgoing-0 << Age: 451956
2020-04-03 07:59:09,107 DEBUG [org.apache.hc.client5.http.headers] http-outgoing-0 << Cache-Control: max-age=604800
2020-04-03 07:59:09,107 DEBUG [org.apache.hc.client5.http.headers] http-outgoing-0 << Content-Type: text/html; charset=UTF-8
2020-04-03 07:59:09,107 DEBUG [org.apache.hc.client5.http.headers] http-outgoing-0 << Date: Fri, 03 Apr 2020 05:59:09 GMT
2020-04-03 07:59:09,108 DEBUG [org.apache.hc.client5.http.headers] http-outgoing-0 << Etag: "3147526947+gzip"
2020-04-03 07:59:09,108 DEBUG [org.apache.hc.client5.http.headers] http-outgoing-0 << Expires: Fri, 10 Apr 2020 05:59:09 GMT
2020-04-03 07:59:09,108 DEBUG [org.apache.hc.client5.http.headers] http-outgoing-0 << Last-Modified: Thu, 17 Oct 2019 07:18:26 GMT
2020-04-03 07:59:09,108 DEBUG [org.apache.hc.client5.http.headers] http-outgoing-0 << Server: ECS (dcb/7EEB)
2020-04-03 07:59:09,108 DEBUG [org.apache.hc.client5.http.headers] http-outgoing-0 << Vary: Accept-Encoding
2020-04-03 07:59:09,109 DEBUG [org.apache.hc.client5.http.headers] http-outgoing-0 << X-Cache: HIT
2020-04-03 07:59:09,109 DEBUG [org.apache.hc.client5.http.headers] http-outgoing-0 << Content-Length: 648

BTW, java.net.http библиотека, известная как JDK HttpClient, прекрасно работает и показывает все заголовки.

Что-то не так я сделал, или я должен сообщить об ошибке, которая существовала годами?

Ответы [ 2 ]

3 голосов
/ 03 апреля 2020

Коммиттер HttpComponents здесь ...

Вы не обратили пристального внимания на то, что сказал Дэйв Дж. По умолчанию HttpClientBuilder включит прозрачную декомпрессию, и причина, по которой вы больше не видите некоторые заголовки, заключается в здесь :

if (decoderFactory != null) {
  response.setEntity(new DecompressingEntity(response.getEntity(), decoderFactory));
  response.removeHeaders(HttpHeaders.CONTENT_LENGTH);
  response.removeHeaders(HttpHeaders.CONTENT_ENCODING);
  response.removeHeaders(HttpHeaders.CONTENT_MD5);
} ...

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

коммиттер скручивания здесь ...

У меня тоже возник вопрос .

2 голосов
/ 03 апреля 2020

Длина содержимого в этом случае может быть потенциально проигнорирована.

HttpGet request = new HttpGet(new URI("https://www.example.com"));
request.setHeader("Accept-Encoding", "identity");
CloseableHttpResponse response = httpclient.execute(request);

Я вижу следующее

HttpEntity entity = response.getEntity();
System.out.println(entity.getContentLength());
System.out.println(entity.getContentEncoding());

Вывод

...
2020-04-03 03:04:17.760 DEBUG 34196 --- [           main] org.apache.hc.client5.http.headers       : http-outgoing-0 << Content-Length: 1256
...
1256
null

I ' Я хотел бы обратить ваше внимание на отправку этого заголовка:

http-outgoing-0 >> Accept-Encoding: gzip, x-gzip, deflate

Он сообщает серверу, что этот клиент может принимать в ответ gzip, x-gzip и дефлировать контент. В ответе говорится, что он закодирован в «gzip».

http-outgoing-0 << Content-Encoding: gzip

Я считаю, что HttpClient прозрачно обрабатывает это внутренне и делает содержимое доступным.

Как указано в другой статье, на которую вы ссылались, В одном из ответов указывалось, что для получения длины контента можно применить метод EntityUtils.toByteArray(httpResponse.getEntity()).length.

...