HttpClient:禁用分块编码

发布于 2024-12-09 01:49:54 字数 192 浏览 0 评论 0 原文

我正在使用 Apache Commons HttpClient 和 Restlet 来调用 Restful Web 服务。不幸的是,我的服务器(基于 Ruby on Rails)不喜欢 HttpClient 默认使用的 Transfer-Encoding: chunked

有什么方法可以禁用客户端 POST 的分块编码吗?

I am using the Apache Commons HttpClient along with Restlet to call a restful web service. Unfortunately, my server (based on Ruby on Rails) does not like the Transfer-Encoding: chunked that HttpClient is using by default.

Is there any way to disable the usage of chunked encoding for POSTs from the client?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

滥情哥ㄟ 2024-12-16 01:49:54

作为一般规则,为了不分块请求,您需要指定帖子正文的确切大小,这对于动态生成的数据意味着您需要在内存中缓冲整个响应,查看其大小然后才发送它。

Apache客户端文档似乎证实了这一点: AbstractHttpEntity.setChunked() 状态

请注意,分块设置只是一个提示。如果使用 HTTP/1.0,则永远不会执行分块。否则,即使 chunked 为 false,如果实体内容长度未知 (-1),HttpClient 也必须使用块编码。

As a general rule, for request not to be chunked, you need to specify exact size of post body, which for dynamically generated data means you need to buffer entire response in memory, see its size and only then send it.

Apache client documentation seems to confirm this: AbstractHttpEntity.setChunked() states

Note that the chunked setting is a hint only. If using HTTP/1.0, chunking is never performed. Otherwise, even if chunked is false, HttpClient must use chunk coding if the entity content length is unknown (-1).

画离情绘悲伤 2024-12-16 01:49:54

正如 Restlet 邮件列表中所述,在 Restlet 2.1 版本中,您可以将 ClientResource#entityBuffering 属性设置为 true 以将内容缓存在内存中并防止分块编码。

As said in Restlet mailing list, in Restlet version 2.1, you can set ClientResource#entityBuffering property to true to cache content in memory and prevent chunked encoding.

感性 2024-12-16 01:49:54

正如 @Slartibartfast 在他的回答中暗示的那样,最可靠的方法是显式将 HttpPost 切换到 HTTP 1.0 协议。

  1. 将 apache HttpPost 请求设置为 HTTP 1.0 协议(与 HttpGet 相同,如果您需要这个...):

    HttpPost httpPost = new HttpPost(someUrl);
    httpPost.setProtocolVersion(HttpVersion.HTTP_1_0); // 自 Apache HttpClient v.4.3 起

  2. 创建 Multipart post 请求时,提供附件作为输入,而不是输入流(对于 HTTP 1.1,这会导致分块编码),而是一个字节数组,您必须创建该数组事先来自同一个流。这就是内容长度已知的原因。请参阅 org.apache.http.entity.mime.MultipartEntityBuilder.addBinaryBody(String, byte[], ContentType, String)

我对此进行了 Android 开发测试,需要稍微不同的类名...(请参阅 https://github.com/andstatus/andstatus/issues/249 )

The most reliable way, as @Slartibartfast hinted in his answer, is to explicitly switch HttpPost to HTTP 1.0 protocol.

  1. Set apache HttpPost request to HTTP 1.0 protocol (the same for HttpGet, if you need this...):

    HttpPost httpPost = new HttpPost(someUrl);
    httpPost.setProtocolVersion(HttpVersion.HTTP_1_0); // Since v.4.3 of Apache HttpClient

  2. When creating Multipart post request provide as an input for an attachment not an InputStream (as for HTTP 1.1, which causes chunked encoding), but an array of bytes, which you have to create from the same stream beforehand. This is why content length is known. See org.apache.http.entity.mime.MultipartEntityBuilder.addBinaryBody(String, byte[], ContentType, String)

I tested this for Android development, that required slightly different class names... (see https://github.com/andstatus/andstatus/issues/249 )

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文