Buffered Reader HTTP POST

时间秒杀一切 提交于 2019-11-30 18:49:48

问题


Looking for a bit of help, I have currently written a HTTP server. It currently handles GET requests fine. However, whilst using POST the buffered reader seems to hang. When the request is stopped the rest of the input stream is read via the buffered reader. I have found a few things on google. I have tried changing the CRLF and the protocol version from 1.1 to 1.0 (browsers automatically make requests as 1.1) Any ideas or help would be appreciated. Thanks


回答1:


I agree with Hans that you should use a standard and well-tested library to do this. However, if you are writing a server to learn about HTTP, here's some info on doing what you want to do.

You really can't use a BufferedReader because it buffers the input and might read too many bytes from the socket. That's why your code is hanging, the BufferedReader is trying to read more bytes than are available on the socket (since the POST data doesn't have an end of line), and it is waiting for more bytes (which will never be available).

The process to simply parse a POST request is to use the InputStream directly

  • For each line in the header read a byte at a time until you get a '\r' and then a '\n'

  • Look for a line that starts with "Content-Length: ", extract the number at the end of that line.

  • When you get a header line that is empty, you're done with headers.

  • Now read exactly the # of bytes that came from the Content-Length header.

Now you can write your response.




回答2:


Wouldn't write my own implementation. Look at the following existing components, if you want:

  • a HTTP client: Apache HttpClient
  • a HTTP server implementation: Apache HttpComponents core (as mentioned by Bombe)



回答3:


This is not safe! But shows how to get the POST data during an Input Stream after the initial HTTP Headers.

This also only works for POST data coming in as "example=true&bad=false" etc.

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



回答4:


As karoroberts said you have to check the length of the content sent in the POST. But you still can use BufferedReader.

Just have to check for the Content-Length header for the size of it and after finishing reading all the headers you can set a char array of that size and make the reading of the POST content:

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

Where request is the BufferedReader. If you need the POST content in a string, you can use: String.valueOf(buffer);

Note: BufferedReader.read returns an int of the characters readed, so you could check there for inconsistencies with the Content-Length header.



来源:https://stackoverflow.com/questions/1579823/buffered-reader-http-post

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!