3

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

4

4 回答 4

8

我同意 Hans 的观点,您应该使用标准且经过良好测试的库来执行此操作。但是,如果您正在编写一个服务器来了解 HTTP,这里有一些关于做您想做的事情的信息。

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

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

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

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

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

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

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

于 2009-12-02T04:58:11.737 回答
2

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

于 2009-10-16T19:07:34.167 回答
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();
    }
}
于 2010-01-23T18:34:05.410 回答
0

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

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

字符 [] 缓冲区 = 新字符 [内容长度]; 请求.读取(缓冲区);

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

注意: BufferedReader.read 返回读取的字符的 int 值,因此您可以在那里检查是否与 Content-Length 标头不一致。

于 2015-06-02T16:42:46.253 回答