HttpClient: отключение кускового кодирования - PullRequest
2 голосов
/ 11 октября 2011

Я использую Apache Commons HttpClient вместе с Restlet для вызова полноценного веб-сервиса.К сожалению, моему серверу (основанному на Ruby on Rails) не нравится Transfer-Encoding: chunked, который HttpClient использует по умолчанию.

Есть ли способ отключить использование чанкованного кодирования для POST-файлов с клиента?*

Ответы [ 3 ]

5 голосов
/ 11 октября 2011

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

Документация клиента Apache, кажется, подтверждает это: AbstractHttpEntity.setChunked() состояния

Обратите внимание, что параметр chunked является только подсказкой.При использовании HTTP / 1.0 разбиение на части никогда не выполняется.В противном случае, даже если chunked имеет значение false, HttpClient должен использовать кодирование чанка, если длина содержимого сущности неизвестна (-1).

2 голосов
/ 02 апреля 2015

Самый надежный способ, как намекнул @Slartibartfast в своем ответе, - явно переключить HttpPost на протокол HTTP 1.0.

  1. Установить запрос Apache HttpPost для протокола HTTP 1.0 (то же самое для HttpGet, если вам нужно это ...):

    HttpPost httpPost = новый HttpPost (someUrl); httpPost.setProtocolVersion (HttpVersion.HTTP_1_0); // Начиная с v.4.3 Apache HttpClient

  2. При создании многочастного пост-запроса в качестве входных данных для вложения указывайте не InputStream (как для HTTP 1.1, который вызывает чанкованное кодирование), а массив байтов, который вы должны заранее создать из того же потока. Вот почему длина контента известна. См. Org.apache.http.entity.mime.MultipartEntityBuilder.addBinaryBody (String, byte [], ContentType, String)

Я проверил это для разработки под Android, для которой требовалось немного другое имя класса ... (см. https://github.com/andstatus/andstatus/issues/249)

2 голосов
/ 11 октября 2011

Как сказано в списке рассылки Restlet, в версии 2.1 Restlet вы можете установить для свойства ClientResource # entityBuffering значение true, чтобы кэшировать содержимое в памяти и предотвращать фрагментированное кодирование.

...