I'm trying to handle a simple POST Request in Java using a Socket. I can receive the request header and answer the request without any problem, but I certainly can not get the body of the request.
I read somewhere that I'd need to open a second InputStream to achive this, but this doesn't really makes sense to me. Do you have any tips on how to get the request body?
This is what I basically use to get the header:
BufferedReader in = new BufferedReader(new InputStreamReader(
clientSocket.getInputStream()));
char[] inputBuffer = new char[INPUT_BUFFER_LENGTH];
int inputMessageLength = in.read(inputBuffer, 0,
INPUT_BUFFER_LENGTH);
String inputMessage = new String(inputBuffer, 0, inputMessageLength);
So, the message I get is something like:
POST / HTTP/1.1
User-Agent: Java/1.8.0_45
Host: localhost:5555
Accept: text/html, image/gif, image/jpeg, *; q=.2, */*; q=.2
But I can't get the parameters of the POST request.
Edit:
So it turned out I just had INPUT_BUFFER_LENGTH up high enough (I know, shame on me). So as it worked I changed my ServerSocket to SSLServerSocket and tried again to send a request with a HttpsUrlConnection from Java, now I have the same problem again (already checked the buffer), getting something like this:
POST / HTTP/1.1
User-Agent: Java/1.8.0_45
Host: localhost:5555
Accept: text/html, image/gif, image/jpeg, *; q=.2, */*; q=.2
Connection: keep-alive
Content-type: application/x-www-form-urlencoded
Content-Length: 128
*Missing Body*
It turned out I only get this when sending requests with my Java-Client - Sending requests from Chrome, etc are working fine - so I assume I got something wrong in my code. This is what I use to send the request:
System.setProperty("javax.net.ssl.trustStore", ...);
System.setProperty("javax.net.ssl.trustStorePassword", ...);
SSLSocketFactory socketFactory = (SSLSocketFactory) SSLSocketFactory
.getDefault();
String url = "https://...";
URL obj = new URL(url);
HttpsURLConnection con = (HttpsURLConnection) obj.openConnection();
HttpsURLConnection.setDefaultSSLSocketFactory(socketFactory);
con.setRequestMethod("POST");
con.setDoOutput(true);
OutputStreamWriter writer = new OutputStreamWriter(con.getOutputStream());
writer.write(*Some String*);
writer.flush();
writer.close();
Any tips on what might be wrong with my code?
The code you have shown is not the correct way to read HTTP requests.
First off, Java has its own
HttpServer
andHttpsServer
classes. You should consider using them.Otherwise, you have to implement the HTTP protocol manually. You need to read the input line-by-line until you reach an empty line indicating the end of the request headers, then look at the headers you have read, in particular the
Transfer-Encoding
andContent-Length
headers, to know how to read the remaining bytes of the request, per RFC 2616 Section 4.4:Try something more like this (semi-pseudo code):