之前写Http Server 的时候,遇到这样一种情况:

当客户端POST一段JSON数据到服务器时,服务器要读取出所有的Http Request Body的内容。于是便直接用BufferedReader读取,直到EOF。但总是会出现SocketTimeoutException。很明显,是由于客户端发完数据之后,并没有关闭输出流,而是等待服务器段发送Connection:[keep-alive|closed]字段来判断是否复用连接。所以在服务器端等待EOF时,客户端也在等待服务器的Response,由此而引发超时。

那么该怎么判断EOF呢?很简单,在Http POST请求头中,会有Content-Length字段,表示Http Request Body的大小。故可以根据此大小来判断是否已经读完发来的数据。

private String parseRawBody() {
        long bytesRead = 0;
        long conLength = contentLength();

        ByteArrayOutputStream result = new ByteArrayOutputStream();
        byte[] buffer = new byte[512];
        int length;
        try {
            while (bytesRead < conLength && ((length = stream.read(buffer)) != -1)) {
                bytesRead += length;
                result.write(buffer, 0, length);
            }
        } catch (IOException e) {
            LOGGER.w(e.getMessage(), e);
        }

        return result.toString();
}