即使没有contentlength标题,也可以从HTTP请求获取内容 [英] Get content from HTTP request even if there is no contentlength header

查看:173
本文介绍了即使没有contentlength标题,也可以从HTTP请求获取内容的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在测试一个客户端,他发送的HTTP请求中没有内容长度标题,但有一个内容。

如何在没有内容长度帮助的情况下提取此内容头部?

解决方案

我保留完整性的原始答案,但我只是在 HTTP RFC(2616)第4.3节:


通过在请求的消息头中包含一个Content-Length或Transfer-Encoding标头字段来标记请求中消息体的存在。如果请求方法的规范(第5.1.1节)不允许在请求中发送实体主体,则消息主体不能包含在请求中。服务器应该根据任何请求读取和转发消息主体;如果请求方法不包含为entity-body定义的语义,那么在处理请求时应该忽略message-body。


所以如果你没有内容长度,你必须有一个Transfer-Encoding(如果你没有,你应该用400状态来表示一个错误的请求或411(需要的长度))。在这一点上,你可以执行Transfer-Encoding告诉你的一切:)

现在如果你正在处理一个servlet API(或类似的HTTP API)为你处理所有这些 - 在这一点上,你可以使用下面的技术来读取流,直到它不会产生更多的数据为止,因为API将处理它(即它赢得了'如果你可以给我们更多关于你的上下文的信息,这将有所帮助。










原始答案

如果没有内容长度,则意味着内容会继续直到数据结束(当套接字关闭时)。



继续读取输入流(例如,将其写入ByteArrayOutputStream以存储它或可能是文件)直到 InputStream.read 返回-1。例如:

  byte [] buffer = new byte [8192]; 
ByteArrayOutputStream output = new ByteArrayOutputStream();
int bytesRead; ((bytesRead = inputStream.read(buffer))!= -1)

{
output.write(buffer,0,bytesRead);
}
//现在使用输出中的数据

编辑:正如在评论中指出的那样,客户端可能正在使用分块编码。通常您使用的HTTP API应该为您处理,但如果您要处理原始套接字,则必须自己处理。



指出这是一个请求(因此客户端无法关闭连接)是一个有趣的事情 - 我认为客户端可以关闭发送部分,但我不明白目前映射到TCP中的任何内容。我的低级网络知识不是它可能的。



如果这个答案变成绝对无用,我会删除它...

p>

Am testing with a client who send me a HTTP request with no content length header but has a content.

How do I extract this content without the help of contentlength header?

解决方案

I've kept the original answer for completeness, but I've just been looking in the HTTP RFC (2616) section 4.3:

The presence of a message-body in a request is signaled by the inclusion of a Content-Length or Transfer-Encoding header field in the request's message-headers. A message-body MUST NOT be included in a request if the specification of the request method (section 5.1.1) does not allow sending an entity-body in requests. A server SHOULD read and forward a message-body on any request; if the request method does not include defined semantics for an entity-body, then the message-body SHOULD be ignored when handling the request.

So if you haven't got a content length, you must have a Transfer-Encoding (and if you haven't, you should respond with a 400 status to indicate a bad request or 411 ("length required")). At that point, you do what the Transfer-Encoding tells you :)

Now if you're dealing with a servlet API (or a similar HTTP API) it may well handle all this for you - at which point you may be able to use the techique below to read from the stream until it yields no more data, as the API will take care of it (i.e. it won't just be a raw socket stream).

If you could give us more information about your context, that would help.


Original answer

If there's no content length, that means the content continues until the end of the data (when the socket closes).

Keep reading from the input stream (e.g. writing it to a ByteArrayOutputStream to store it, or possibly a file) until InputStream.read returns -1. For example:

byte[] buffer = new byte[8192];
ByteArrayOutputStream output = new ByteArrayOutputStream();
int bytesRead;
while ((bytesRead = inputStream.read(buffer)) != -1)
{
    output.write(buffer, 0, bytesRead);
}
// Now use the data in "output"

EDIT: As has been pointed out in comments, the client could be using a chunked encoding. Normally the HTTP API you're using should deal with this for you, but if you're dealing with a raw socket you'd have to handle it yourself.

The point about this being a request (and therefore the client not being able to close the connection) is an interesting one - I thought the client could just shut down the sending part, but I don't see how that maps to anything in TCP at the moment. My low-level networking knowledge isn't what it might be.

If this answer turns out to be "definitely useless" I'll delete it...

这篇关于即使没有contentlength标题,也可以从HTTP请求获取内容的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆