Android HttpPost 消息不会通过网络发送其有效负载
我正在尝试发送一个简单的字符串作为 HttpPost 消息的内容。
问题是,HttpPost 消息的正文永远不会到达线路。 (Wireshark 捕获说)。标头看起来不错(包括正确计算的内容长度)。
代码如下所示:
String url = "http://1.2.3.4/resource";
HttpClient client = new DefaultHttpClient();
String cmd = "AT+AVLPOS\r\n";
StringEntity se = new StringEntity(cmd);
se.setContentType("text/plain");
HttpPost request = new HttpPost(url);
request.setHeader("Content-Type","text/plain");
request.setEntity(se);
HttpResponse response = client.execute(request);
[...]
字符串应该是 ASCII 编码的,但这只是此时的细节。
这就是 WireShark 中显示的内容: ->请注意,标有 + 的行是发送的内容,标有 - 的行是接收的内容。
+POST /resource HTTP/1.1
+Content-Type: text/plain
+Content-Length: 11
+Host: 1.2.3.4
+Connection: Keep-Alive
+User-Agent: Apache-HttpClient/UNAVAILABLE (java 1.4)
+Expect: 100-Continue
-HTTP/1.1 200 OK
-Content-Type: text/plain
-Transfer-Encoding: chunked
-4
-OK
这就是应该显示的内容(用 C# 编写了一个非常简单的控制台应用程序来执行此操作,它就可以工作):
+POST /resource HTTP/1.1
+Content-Type: text/plain
+Host: 1.2.3.4
+Content-Length: 11
+Expect: 100-continue
+Connection: Keep-Alive
+
-HTTP/1.1 200 OK
-Content-Type: text/plain
-Transfer-Encoding: chunked
-
+AT+AVLPOS
+
-4
-OK
-
-48
-$AVTMR,99999999,204810,A,1234.2218,N,0123.1051,E,0,20,150811,0,REQ*69
-
-0
-
有什么建议吗?
I'm trying to send a simple string as the contents of a HttpPost message.
The problem is, the body of the HttpPost message never makes it to the wire. (Says the Wireshark capture). The header looks just fine though (including the correctly calculated Content-Length.
Here's what the code looks like:
String url = "http://1.2.3.4/resource";
HttpClient client = new DefaultHttpClient();
String cmd = "AT+AVLPOS\r\n";
StringEntity se = new StringEntity(cmd);
se.setContentType("text/plain");
HttpPost request = new HttpPost(url);
request.setHeader("Content-Type","text/plain");
request.setEntity(se);
HttpResponse response = client.execute(request);
[...]
The string should be ASCII-encoded, but that's a detail at this point.
This is what shows up in WireShark:
-> note that lines marked with + are what's sent, and - is what's received.
+POST /resource HTTP/1.1
+Content-Type: text/plain
+Content-Length: 11
+Host: 1.2.3.4
+Connection: Keep-Alive
+User-Agent: Apache-HttpClient/UNAVAILABLE (java 1.4)
+Expect: 100-Continue
-HTTP/1.1 200 OK
-Content-Type: text/plain
-Transfer-Encoding: chunked
-4
-OK
This is what should show up (wrote a very simple console app in C# to do this, it just works):
+POST /resource HTTP/1.1
+Content-Type: text/plain
+Host: 1.2.3.4
+Content-Length: 11
+Expect: 100-continue
+Connection: Keep-Alive
+
-HTTP/1.1 200 OK
-Content-Type: text/plain
-Transfer-Encoding: chunked
-
+AT+AVLPOS
+
-4
-OK
-
-48
-$AVTMR,99999999,204810,A,1234.2218,N,0123.1051,E,0,20,150811,0,REQ*69
-
-0
-
Any suggestions?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
我已经弄清楚了,今天我学到了一些东西。
长话短说:禁用 HttpClient 的
HTTP Post Expect-Continue
握手,通过 设置其参数之一,这将在一个块中发送整个请求消息。现在这就是我到达那里的方法,也许有一天这会对某人有所帮助。
首先,我从
HttpEntityWrapper< /code>
并使用它作为我的请求实体来查看何时调用什么,并发现
Entity
的writeTo(OutputStream)
方法从未被调用过根本没有打电话。然后我开始研究为什么在“正确”行为的情况下,POST 请求不是一次全部发送,而是发送请求标头,然后接收响应标头,然后请求正文是发送。
这一切都与
HTTP Post Expect-Continue
握手有关。阅读更多相关信息 被黑客攻击。如果在请求中发送了 Expect-Continue 标头,则 Http 服务器应该回复一个
100Continue
消息,表示“好的,我会接受你的消息”,或者返回一个错误,停止可能很长的 POST消息在其轨道上。不幸的是,我运行的 Web 服务器是在芯片上运行的简单实现,它发送了错误的回复(
200 OK
而不是100 Continue
)。.NET Http 客户端的默认实现在这里似乎更加宽容:它将
200
消息视为100 Continue
,耸耸肩,并获取正在发送请求正文。Android 的 Http 客户端实现(API 级别 7)并非如此。
接下来我尝试的是完全禁用
expect-continue
握手,以使 HttpClient 发送整个请求。令我惊讶和高兴的是,网络服务器处理得很好,它回复了我想要的信息。耶!I've figured it out, AND I've learned something today.
Long story short: disable the HttpClient's
HTTP Post expect-continue
handshake, by setting one of its parameters, this will send the whole request message in one chunk.Now here's how I got there, maybe this will help someone someday.
First I derived from a
HttpEntityWrapper
and used that as my request entity to see what gets called when, and found out that theEntity
'swriteTo(OutputStream)
method was never called at all.Then I started to look at why, in the case of the "correct" behaviour, the POST request wasn't sent all at once, and instead, the request headers were sent, then the response header is received, THEN the request body is sent.
IT's all got to do with the
HTTP Post expect-continue
handshake. Read more about it on Haacked.If the expect-continue header is sent in a request, the Http server SHOULD reply with a
100 Continue
message signifying "OK, I will accept your message", or with an error, stopping the possibly long POST message in its tracks.Unfortunately, the web server I run against is a bare bones implementation that runs on a chip, and it sends the wrong reply (
200 OK
instead of100 Continue
).The default implementation of the .NET Http Client seems to be more forgiving here: it treats the
200
message as100 Continue
, shrugs, and gets on its way to send the request body.Not so with the Http client implementation of Android (API level 7).
Next thing I tried was to disable the
expect-continue
handshake completely, in order to make the HttpClient send the whole request. To my surprise and joy, this was handled fine by the web server, which replied with the information I wanted. Yay!