缓冲读取器HTTP POST

寻求一些帮助,我目前编写了一个HTTP服务器。 它目前正在处理GET请求。 但是,在使用POST时,缓冲的阅读器似乎挂了。 当请求停止时,通过缓冲读取器读取其余输入流。 我在谷歌上发现了一些东西。 我已经尝试将CRLF和协议版本从1.1更改为1.0(浏览器自动发出请求为1.1)任何想法或帮助将不胜感激。 谢谢

我同意汉斯的意见,你应该使用一个经过良好测试的标准库来完成这项工作。 但是,如果您正在编写服务器以了解HTTP,请参阅以下有关执行您想要执行的操作的信息。

你真的不能使用BufferedReader,因为它缓冲了输入并可能从套接字读取太多字节。 这就是你的代码挂起的原因,BufferedReader试图读取比套接字上可用的字节更多的字节(因为POST数据没有行结束),并且它正在等待更多字节(永远不可用) 。

简单解析POST请求的过程是直接使用InputStream

  • 对于标题中的每一行,一次读取一个字节,直到得到’\ n’,然后是’\ n’

  • 查找以“Content-Length:”开头的行,提取该行末尾的数字。

  • 当你得到一个空标题行时,你就完成了标题。

  • 现在准确读取Content-Length标头中的#字节数。

现在你可以写下你的回复了。

不会写我自己的实现。 如果需要,请查看以下现有组件:

  • HTTP客户端: Apache HttpClient
  • HTTP服务器实现: Apache HttpComponents核心 (如Bombe所述)

这不安全! 但是展示了如何在初始HTTP标头之后的输入流期间获取POST数据。

这也仅适用于以“example = true&bad = false”等forms出现的POST数据。

private HashMap hashMap = new HashMap(); private StringBuffer buff = new StringBuffer(); private int c = 0; private String[] post; public PostInputStream(InputStream in) { try { //Initalizes avaliable buff if (in.available() != 0) { this.buff.appendCodePoint((this.c = in.read())); while (0 != in.available()) { //Console.output(buff.toString()); buff.appendCodePoint((this.c = in.read())); } this.post = buff.toString().split("&"); for (int i = 0; i < this.post.length; i++) { String[] n = this.post[i].split("="); if (n.length == 2) { hashMap.put(URLDecoder.decode(n[0], "UTF-8"), URLDecoder.decode(n[1], "UTF-8")); } else { Console.error("Malformed Post Request."); } } } else { Console.error("No POST Data"); } } catch (Exception e) { e.printStackTrace(); } } 

正如karoroberts所说,你必须检查POST中发送的内容的长度。 但是你仍然可以使用BufferedReader。

只需检查Content-Length标头的大小,读完所有标题后,您可以设置该大小的char数组并读取POST内容:

char [] buffer = new char [contentLength]; request.read(缓冲液);

其中request是BufferedReader。 如果需要字符串中的POST内容,可以使用:String.valueOf(buffer);

注意:BufferedReader.read返回已加入字符的int,因此您可以检查Content-Length标头是否存在不一致。