HTTP headers became lowercased 2 - java

I need to send UPPERcased headers via http post. The first part of story was described here . Now its sockets time. :)
Socket s = new Socket(InetAddress.getByName("localhost"), 8080);
PrintWriter pw = new PrintWriter(s.getOutputStream());
// PrintStream pw = System.out;
pw.println("POST /test-servlet/TestServlet HTTP/1.0");
String params = "key1=value1&key2=value2";
pw.println("accept = text/xml");
pw.println("accept-language: ru");
pw.println("SOAPAction: requestCreditBureau");
pw.println("eif: 3");
pw.println("host: localhost");
pw.println("content-length: " + params.getBytes().length);
pw.println();
pw.println(params);
pw.println();
pw.flush();
BufferedReader br = new BufferedReader(new InputStreamReader(s.getInputStream()));
String t;
while((t = br.readLine()) != null) System.out.println(t);
br.close();
There are two problems here.
It doesn't work. :) The server's servlet recive:
workflow = TSM \
soapaction = requestCreditBureau
eif = 3
There is no params in HttpServletRequest on server, only headers.

The println() method will use the systems line separator to send newlines.
HTTP defines the strict usage of \r\n as the line separator.
So you should hardcode the line breaks:
pw.print("SOAPAction: requestCreditBureau\r\n");
pw.print("eif: 3\r\n");
pw.print("host: localhost\r\n");
pw.print("content-length: " + params.getBytes().length + "\r\n");
pw.print("\r\n");
Consider using java.net.HttpURLConnection instead of implementing the HTTP protocol yourself.

Thanks! The problem was that i used tomcat7. There is no such problem using jetty.

Related

Cannot read line break/carriage return from socket response

I am sending setup commands to a TP-LINK wireless router through a telnet connection:
Trying 1.2.3.4...
Connected to 1.2.3.4.
Escape character is '^]'.
*HELLO*$$$
CMD
factory RESET
factory RESET
Set Factory Defaults
<4.00> set sys autoconn 0
set sys autoconn 0
AOK
<4.00>
...
I have a PHP code that performs the sending of commands and gets the response using sockets:
socket_write($socket, "factory RESET\r"); // send command
$response = socket_read($socket, 256); // get response
PHP works fine. The $response variable contains:
factory RESET
Set Factory Defaults
But using the Java I have problems. Using a BufferedReader object to read response, I can get the first line content. but I can not get the following lines:
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));
BufferedReader br = new BufferedReader(new InputStreamReader(socket.getInputStream()));
// ...
bw.write("factory RESET");
bw.newLine();
bw.flush();
// ...
StringBuilder sb = new StringBuilder();
String s;
while ((s = br.readLine()) != null) {
sb.append(s);
}
I can get the first line content, but the second reading don't proceed and don't raise exception...
If I use the read function, only the first row is returned:
char[] buffer = new char[256];
br.read(buffer, 0, 256);
String response = new String(buffer); // response is "factory RESET"
What is the problem?
Your PHP code execute two reads. Your Java code attempts to read until end of stream, which only happens when the peer closes the connection. Do a single read.
The line separator in the Telnet protocol is defined as \r\n, unless you're using binary mode, which you aren't. Not as\r or whatever BufferedWriter may do on your platform.

Sending and receiving HTTP post data - Java

I'm trying to send a request through Google's Safe Browsing API, but I'm not getting any output and I'm not sure why. I've searched this online but each solution either only refers to only how to send or receive a POST request (but not both), or the input of data is done differently.
According to the Google Safe Browsing documentation:
Specify the queried URLs in the POST request body using the following format:
POST_REQ_BODY = NUM LF URL (LF URL)*
NUM = (DIGIT)+
URL = URL string following the RFC 1738
-
Response body:
POST_RESP_BODY = VERDICT (LF VERDICT)*
VERDICT = “phishing” | “malware” | "unwanted" | “phishing,malware” >| "phishing,unwanted" | "malware,unwanted" | "phishing, malware, unwanted" >| “ok”
and sent to:
https://sb-ssl.google.com/safebrowsing/api/lookup?client=CLIENT&key=APIKEY
I found another topic that shows how you send this request, but I'm not sure how to get/print out the response. Here is what I tried:
String baseURL="https://sb-ssl.google.com/safebrowsing/api/lookup";
String arguments = "";
arguments +=URLEncoder.encode("client", "UTF-8") + "=" + URLEncoder.encode("myapp", "UTF-8") + "&";
arguments +=URLEncoder.encode("apikey", "UTF-8") + "=" + URLEncoder.encode("12345", "UTF-8") + "&";
arguments +=URLEncoder.encode("appver", "UTF-8") + "=" + URLEncoder.encode("1.5.2", "UTF-8") + "&";
arguments +=URLEncoder.encode("pver", "UTF-8") + "=" + URLEncoder.encode("3.0", "UTF-8");
// Construct the url object representing cgi script
URL url = new URL(baseURL + "?" + arguments);
// Get a URLConnection object, to write to POST method
URLConnection connect = url.openConnection();
// Specify connection settings
connect.setDoInput(true);
connect.setDoOutput(true);
InputStream input = connect.getInputStream();
BufferedReader reader = new BufferedReader(new InputStreamReader(input));
StringBuilder result = new StringBuilder();
String line;
// Get an output stream for writing
OutputStream output = connect.getOutputStream();
PrintStream pout = new PrintStream (output);
pout.print("2");
pout.println();
pout.print("http://www.google.com");
pout.println();
pout.print("http://www.facebook.com");
pout.close();
while((line = reader.readLine()) != null) {
result.append(line);
}
System.out.println(result.toString());
Where is the error?
Move these lines:
InputStream input = connect.getInputStream();
BufferedReader reader = new BufferedReader(new InputStreamReader(input));
After pout.close();, the getInputStream method actually send the HTTP request to the server, in that example you are sending the request before you fill the body.
It looks like there will be other things to fix after this.

Multiple HTTP requests over socket connection

I want to HTTP GET the server ,read the data and then again do HTTP GET or POST over same socket connection.
However I am unable to get a response for second request.What can be wrong with following code :
Socket s = new Socket(InetAddress.getByName("xyz.abc.asd"), 80);
InputStream is=s.getInputStream();
OutputStream os=s.getOutputStream();
PrintWriter pwGET = new PrintWriter(os);
pwGET.println("GET /login/ HTTP/1.1");
pwGET.println("Host: xyz.abc.asd");
pwGET.println("Connection: keep-alive");
pwGET.println("");
pwGET.flush();
BufferedReader brGET = new BufferedReader(new InputStreamReader(is));
String t=null;
while((t = brGET.readLine()) != null) {
System.out.println(t);
}
pwGET.println("GET /login/ HTTP/1.1");
pwGET.println("Host: xyz.abc.asd");
pwGET.println("Connection: keep-alive");
pwGET.println("");
pwGET.flush();
BufferedReader br = new BufferedReader(new InputStreamReader(is));
t=null;
while((t = br.readLine()) != null) {
System.out.println(t);
}
The main error is, that you don't parse the response correctly.
The response consists of an HTTP header followed by the body (maybe). To get the body you must parse and understand the response header, especially the code (some codes don't have a body), Transfer-Encoding and Content-length. Then you should also have a look at the Connection header.
Only then you know the length of the body and if further requests are accepted on this connection.
Apart from that lines should be delimited by \r\n, not just \n as you do with println.
In summary: if you really want to implement HTTP on your own study the necessary documentation (RFC2616 or the newer RFC7230..RFC7235). If you don't like this use existing HTTP libraries.

Read Special Characters in Socket Server

I am creating Client/Server using Java Networking API. My client will send special unicode characters to Server before and after message. Before message it will send \uc001B and after message \uc00C. After message has been send successfully again client will send \r to server. Server can identify by receiving of this that the message sending is done. But my problem here is how can I check in the server whether the message from client has \r.
DataOutputStream outToServer = new DataOutputStream( clientSocket.getOutputStream());
BufferedReader inFromServer = new BufferedReader(new InputStreamReader(
clientSocket.getInputStream()));
outToServer.writeBytes("\uc001B");
outToServer.flush();
outToServer.writeBytes(message.toString());
outToServer.writeBytes("\uc001C");
outToServer.flush();
outToServer.writeBytes("\r");
outToServer.flush();
And here is my server Code to read messages from the client
in = new BufferedReader(new InputStreamReader(m_clientSocket.getInputStream()));
out = new PrintWriter(new OutputStreamWriter( m_clientSocket.getOutputStream()));
String receivingMessage = "";
while (m_bRunThread) {
String clientCommand = in.readLine().toString();
receivingMessage += clientCommand;
System.out.println("Client Says :" + clientCommand);
if (in.equals("\r")) {
System.out.print("Message Receiving from Client Done : "+ m_clientID);
m_bRunThread = false;
}
}
Thanks
You are using readLine(). It removes the newline, whatever it was: it understands all of them. Ergo you cannot possibly tell what the newline character was. Also you cannot possibly care. Every line you read was terminated by a newline character. But you are on fairly dangerous ground using STX and ETX in association with a Reader. You seem to have a protocol definition problem: you are sending STX/ETX and also expecting newlines. Why?

Java constructing an http request message

I asked a similar question in another thread but I think I'm just having trouble getting the syntax right at this point. I basically want to open a socket in Java, send a HTTP request message to get the header fields of a specific web page. My program looks like this so far:
String server = "www.w3.org";
int port = 80;
String uri = "/Protocols/rfc2616/rfc2616-sec5.html#sec5.1"
Socket socket = new Socket(server, port);
PrintStream output = new PrintStream(socket.getOutputStream());
BufferedReader socketInput = new BufferedReader(new InputStreamReader(socket.getInputStream()));
output.println("HEAD " + uri + " HTTP/1.1");
//String response = "";
String line = "";
while((line = socketInput.readLine()) != null){
System.out.println(line);
}
socketInput.close();
socket.close();
It doesn't really work. Or it doesn't work for all websites. If someone could just tell me the immediate problems with what I'm doing, that would be great. Thank you!
Change
output.println("HEAD " + uri + " HTTP/1.1");
to
output.println("HEAD " + uri + " HTTP/1.1");
output.println("Host: " + server);
output.println();
You have to send the Host header because usually there are more than one virtual host on one IP address. If you use HTTP/1.0 it works without the Host header.
I would use some higher-level component, like HttpURLConnection (see here) or apache http components.

Categories