缓冲读取器 HTTP POST

3

需要一些帮助,我目前编写了一个HTTP服务器。它可以很好地处理GET请求。然而,在使用POST时,缓冲读取器似乎会挂起。当请求停止时,剩余的输入流通过缓冲读取器读取。我在谷歌上找到了一些东西。我尝试过更改CRLF和协议版本从1.1到1.0(浏览器自动将请求作为1.1),但没有效果。有什么建议或帮助将不胜感激。谢谢

4个回答

8
我同意Hans的建议,你应该使用一个标准且经过充分测试的库来完成这个任务。但是,如果你正在编写一个服务器用于学习HTTP协议,下面是关于如何实现你想要做的事情的一些信息。
你真的不能使用BufferedReader,因为它会缓冲输入并可能从套接字中读取太多字节。这就是为什么你的代码会挂起的原因,BufferedReader正在尝试读取比套接字中可用的字节数更多的字节(因为POST数据没有行结束符),而且它正在等待更多的字节(这些字节永远不会出现)。
解析POST请求的过程是直接使用InputStream:
- 对于头中的每一行,一个字节一个字节地读取,直到遇到'\r'和'\n'。 - 查找以"Content-Length:"开头的行,提取该行末尾的数字。 - 当你得到一个空的头行时,你已经处理完了头部。 - 现在读取正好等于Content-Length头部中指定的字节数。
现在你可以编写你的响应了。

2

如果我可以不觉得傻,多次写“seconded”,那就是要走的路线。 - Dean J
抱歉,我想说的是服务器而不是客户端。 - Hugh
仍然,Apache HttpComponents 是最好的选择。 - Bombe
是啊,为什么有人想要编写Java HTTP服务器我真的不理解(甚至比客户端更难)-- 只需要使用Jetty、Tomcat、Grizzly或其他n+1个替代方案就可以了。除非这是大学课程的作业之类的。 - StaxMan

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();
    }
}

0

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

只需检查Content-Length头文件的大小并在完成读取所有头文件后,您可以设置一个相同大小的char数组并进行POST内容的读取:

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

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

注意:BufferedReader.read返回读取的字符数int,因此您可以在那里检查与Content-Length头文件不一致的地方。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接