I'm trying to use telnet to request a new identity for tor. From my understanding, you're supposed to send
authenticate ""
and then if the response is "250 OK" send
signal newnym
Using this code, I get a response of "null." I have also used several telnet client libraries and get the same kind of results.
try {
Socket socket = new Socket("localhost", 9050);
PrintWriter out = new PrintWriter(socket.getOutputStream(), true);
BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
out.println("authenticate \"\"");
System.out.println(in.readLine()); //should be 250 but is null
out.close();
in.close();
socket.close();
} catch (Exception e) {
e.printStackTrace();
}
The documentation says that all commands are case sensitive. So you should be sending them in UPPER case (as per documentation).
I also found that a valid new identity request looks like
AUTHENTICATE
250 OK
SIGNAL NEWNYM
250 OK
Hope that helps!
Related
I have a client application which send POST request(json) to a custom server. The server must send a response(json) to the incoming message, but i haven't detected any response on the client side.
The problem is not on the client's side, because if it sends a request to another server, then after a few seconds it receives a response and I see it in the logs.
SERVER CODE
try{
server = new ServerSocket(4321);
client = server.accept();
PrintWriter out = new PrintWriter(client.getOutputStream(), true);
System.out.println("Connection received from " + client.getInetAddress());
BufferedReader in = new BufferedReader(new InputStreamReader(client.getInputStream()));
String s = "SERVER: Started.";
Gson gson = new Gson();
String json = gson.toJson(jsonObject.toString());
while ((s = in.readLine()) != null) {
System.out.println("RECV: "+s);
ss = s.split("PUSH\\s");
out.println("HTTP/1.1 200 OK");
out.println("application/json;charset=UTF-8");
out.println("application/json;charset=UTF-8");
out.println("Jersey/2.27 (HttpUrlConnection 1.8.0_291)");
out.println("no-cache");
out.println("no-cache");
out.println("hostname:4321");
out.println("keep-alive");
out.println("392");
out.println("\n");
out.println(json);
} catch(Exception e) {e.printStackTrace();}
I think the root of my issue is out.println(). I don't know exactly what the server should send back to client.
Response must contain json!
Also, i don't have the client code.
Could you help?
While I definitively wouldn't recommend writing an HTTP server this way there are at least two problems in your code:
You are missing header names, e.g. application/json;charset=UTF-8 should read Content-Type: application/json;charset=UTF-8
out.println() uses the line separator string as defined by the system property line.separator (e.g. \n for Linux). HTTP on the other hand needs \r\n, so better write it like this: out.print("HTTP/1.1 200 OK\r\n");
Try this:
out.print("HTTP/1.1 200 OK" + "\r\n");
out.print("Content-Type: application/json" + "\r\n");
// you shouldn't need the other headers…
out.print("\r\n");
out.print(json);
Hello I'm making an HTTP client. I'm trying to fetch google.com's html code. I have a problem the the BufferedReader.readLine() function is blocking endlessly because the remote server apparently doesn't send a blank line? Or could it be that my request is wrong?
Appreciate any help!
public static void main(String[] args) {
String uri = "www.google.com";
int port = 80;
Socket socket = new Socket(uri, port);
PrintWriter toServer = new PrintWriter(socket.getOutputStream(), true);
InputStream inputStream = socket.getInputStream();
get(uri, port, language, socket, toServer, inputStream);
}
public static void get(String uri, int port, String language, Socket socket, PrintWriter toServer, InputStream inputStream) {
try {
toServer.println("GET / HTTP/1.1");
toServer.println("Host: " + uri + ":" + port);
toServer.println();
// Parse header
StringBuilder stringBuilder = new StringBuilder();
BufferedReader fromServer = new BufferedReader(new InputStreamReader(inputStream));
String line;
while ((line = fromServer.readLine()) != null) {
stringBuilder.append(line);
}
System.out.println("done");
} catch (IOException e) {
e.printStackTrace();
}
}
You are sending a HTTP/1.1 request which by default enables HTTP keep-alive. This means that the server might keep the TCP connection open after the response was sent in order to accept more requests from the client. Your code instead assumes that the server will close the connection after the response was finished by explicitly expecting readline to return null. But since the server will not close the connection (or only after some long timeout) the readline will just block.
To fix this either use HTTP/1.0 (which has keep-alive off by default) instead of HTTP/1.1 or explicitly tell the server that no more requests will be send by adding a Connection: close header.
Please note that in general HTTP is way more complex than you might think if you've just seen a few examples. The problem you face in your question is only a glimpse into more problems which you will face when continuing this path. If you really want to implement your own HTTP handling instead of using established libraries please study the actual standard instead of just assuming a specific behavior.
I am trying to read the data from an HttpPost, but when I read the data from BufferedReader I only get the header info. Please see the code below.
Here is the server
try {
ServerSocket server = new ServerSocket(8332);
System.out.println("Listening for connection on port 8332 ....");
while (true) {
try (Socket socket = server.accept()) {
BufferedReader buffer = new BufferedReader(new InputStreamReader(socket.getInputStream()));
String request = "";
String line;
while ((line = buffer.readLine()) != null) {
System.out.println(line);
request += line;
}
System.out.print("port 8332 reading: " + request);
} catch (IOException e) {
System.out.print(e.getMessage());
}
}
} catch (IOException e){
System.out.print(e.getMessage());
}
Here is the Client
HttpClient client = HttpClientBuilder.create().build();
HttpPost post = new HttpPost("http://localhost:8332");
try {
StringEntity params =new StringEntity("details={\"name\":\"myname\",\"age\":\"20\"} ");
post.addHeader("content-type", "application/x-www-form-urlencoded");
post.setEntity(params);
client.execute(post);
} catch (IOException e){
System.out.println(e);
}
When I run this program I just get the following output
Listening for connection on port 8332 ....
POST / HTTP/1.1
content-type: application/x-www-form-urlencoded
Content-Length: 37
Host: localhost:8332
Connection: Keep-Alive
User-Agent: Apache-HttpClient/4.5.6 (Java/1.8.0_131)
Accept-Encoding: gzip,deflate
Upon debugging it seems like the program is not exiting this while loop
while ((line = buffer.readLine()) != null) {
System.out.println(line);
request += line;
}
But I can't figure out why. Please help I have been stuck all day.
Thanks in advance
But I can't figure out why.
The only way that your server will get a null from buffer.readLine() is if the client closes its socket output stream.
The problem is that the client side is trying to keep the connection alive ... which means that it won't close its socket output stream. That means that the server needs to respect the "content-length" header; i.e. count the number of bytes read rather than looking for an end-of-stream.
Fundamentally, your server side is not implementing the HTTP 1.1 specification correctly.
What to do?
Well my advice is to not try to implement HTTP starting from sockets. Use and existing framework ... or the Apache HttpComponents library.
But if you insist on doing it this way1, read the HTTP specification thoroughly before you start trying to implement it. And consult the spec whenever you run into problems with your implementation to check that you are doing the right thing.
1 - Definition: Masochism - the enjoyment of an activity that appears to be painful or tedious.
Use !=0 instead of !=null in your while loop:
while((line = buffer.readLine()).length() !=0) {
output:
port 8332 reading: POST / HTTP/1.1content-type:
application/x-www-form-urlencodedContent-Length: 18Host:
localhost:8332Connection: Keep-AliveUser-Agent:
Apache-HttpClient/4.5.3 (Java/1.8.0_171)Accept-Encoding:
gzip,deflateorg.apache.http.NoHttpResponseException: localhost:8332
failed to respond
I already read some threads here on stackoverflow, also some tutorials, but I don't find a solution to my problem.
I have Java client which connects to a server, then sends exactly one line to the server, and I get 2 or 3 lines as a response.
Here is my code:
public static void main(String[] args) {
String message;
String response;
try {
BufferedReader inFromUser = new BufferedReader( new InputStreamReader(System.in));
Socket clientSocket = new Socket(hostname, port);
DataOutputStream outToServer = new DataOutputStream(clientSocket.getOutputStream());
BufferedReader inFromServer = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
message = inFromUser.readLine();
outToServer.writeBytes(message + '\n');
// here my program "freezes"
while ((response = inFromServer.readLine()) != null) {
System.out.println("response: " + response);
}
clientSocket.close();
} catch (UnknownHostException e) {
System.out.println("Unknown Host");
} catch (IOException e) {
System.out.println("IO Exception");
}
}
My problem is, I can read every line of the response, but my program won't exit. The line clientSocket.close(); gets never called. What am I doing wrong?
Presumably your server isn't closing the connection - therefore the underlying stream for the reader isn't closed... at any point the server could send more information. readLine() only returns null when the stream has been closed, i.e. there will definitely not be any more data.
Now we don't know anything about the protocol here, but if the expected behaviour is that the client won't send any more information, and the server will close the connection, then the bug is in the server. If the protocol states that the server will keep the connection open, then the bug is in your client code and you need to work out how to detect the end of data (or send some sort of ack that will cause the server to close the connection, or whatever).
I am trying to mark DSCP values using setTrafficClass. I have server and client set up on two different machines and I am able to print value of DSCP but I can not see it in WireShark.
I have gone through some posts online but nothing helped. I am using Windows 7 professional.
Any help would be appreciated. Thank you!
I am more testing to see how this can be done.
Here is the client code:
try {
Socket socket = new Socket(addr, 2345);
socket.setTrafficClass(10);
PrintWriter out = new PrintWriter( socket.getOutputStream(), true);
out.println("Current DSCP value: " + socket.getTrafficClass());
out.close();
socket.close();
}
catch (Exception e) {
e.printStackTrace();
}
}
Server:
try {
ServerSocket serverSocket = new ServerSocket(1234);
Socket clientSocket = serverSocket.accept();
BufferedReader in = new BufferedReader(new InputStreamReader(
clientSocket.getInputStream()));
String fromClient = in.readLine();
System.out.println(fromClient);
in.close();
clientSocket.close();
serverSocket.close();
} catch (Exception e) {
e.printStackTrace();
}
}
In console on server side:
Current DSCP value: 10
My server code and client are on separate machines.
In wireshark I see:
Differentiated Services Field: 0x00 (DSCP 0x00: Default; ECN: 0x00: Not-ECT (Not ECN-Capable Transport))
I expect to see changes in wireshark and I only see default value zero.
Last time I worked with DSCP values in Java one had to set the java.net.preferIPv4Stack system property to true due to a bug in the JVM. Othwerwise DSCP values would not be set on the underlying socket despite appearing to work in the java.net.Socket API.
Also you may have to call setTrafficClass before connecting the socket, it may not work after connection on some platforms.
java -Djava.net.preferIPv4Stack=true ...