Setting content length of an HTTP POST request

14.7k Views Asked by At

I am trying to make a Http POST request using apache HTTP client. I am trying to copy contents of an HTTP POST request (received at my application) to another HTTP POST request (initiated from my application to another URL). Code is shown below:

httpPost = new HttpPost(inputURL);
// copy headers
for (Enumeration<String> e = request.getHeaderNames(); e.hasMoreElements();) {
      String headerName = e.nextElement().toString(); 
      httpPost.setHeader(headerName, request.getHeader(headerName));
}

BufferedInputStream clientToProxyBuf = new BufferedInputStream(request.getInputStream());
BasicHttpEntity basicHttpEntity = new BasicHttpEntity();
basicHttpEntity.setContent(clientToProxyBuf);
basicHttpEntity.setContentLength(clientToProxyBuf.available());

httpPost.setEntity(basicHttpEntity);

HttpResponse responseFromWeb = httpclient.execute(httpPost);

Basically, I am trying to implement a proxy application which will get a url as parameter, froward the request to the URL and then serve pages etc in custom look and feel.

Here request is HttpServletRequest. I am facing problem in setting content length. Through debugging I found out that clientToProxyBuf.available() is not giving me correct length of input stream and I am getting Http error 400 IE and Error 354 (net::ERR_CONTENT_LENGTH_MISMATCH): The server unexpectedly closed the connection in chrome.

Am I doing it wrong? Is there any other way to achieve it?

2

There are 2 best solutions below

1
On BEST ANSWER

It was rather simple and very obvious. I just needed to get content length from header as:

basicHttpEntity.setContentLength(Integer.parseInt(request.getHeader("Content-Length")));
3
On

The available() function doesn't provide the actual length of the content of the stream, rather

Returns the number of bytes that can be read from this input stream without blocking. (From javadoc)

I would suggest you to first read the whole content from the stream, and then set that to the content, rather than passing the stream object. That way, you will also have the actual length of the content.