缓冲读取器HTTP POST

时间:2009-10-16 19:03:52

标签: java http post hang bufferedreader

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

4 个答案:

答案 0 :(得分:7)

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

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

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

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

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

  •   
  • 当您的标题行为空时,您已完成标题。

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

  •   

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

答案 1 :(得分:2)

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

答案 2 :(得分:1)

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

这也适用于以“example = true& bad = false”等形式出现的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();
    }
}

答案 3 :(得分:0)

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

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

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

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

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