Context
I'm trying to build a simple HTTP web proxy using Java. Right now all I have is something that listens on port 5041 for HTTP requests. Right now I have 2 classes. The Proxy class opens a ServerSocket on the port, I call this socket the welcomeSocket. After this port is opened Proxy starts a new Connection thread everytime welcomeSocket accepts a new socket. The Connection class has some simple logic to read the HTTP request header information. Later this class will be extended for further functionality. Thanks for any help.
Problems
When I run my proxy and configure my browser to point to the proxy I'm getting SocketException errors saying that my socket is closed. I'm not sure how these are coming about. Also it appears that Connection threads are being created but don't necessarily output HTTP header info. This is apparent because output shows repetetive NEW connection thread created prints but no header info after the print.
Proxy Class
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
public class Proxy {
// Port is 5000 + 41
private final int PORT;
private ServerSocket welcomeSocket = null;
private boolean listening = true;
public Proxy(int port) {
PORT = port;
try {
welcomeSocket = new ServerSocket(PORT);
listenForConnectionRequests();
} catch (IOException e) {
System.err.println("There was a problem while creating the welcome socket");
e.printStackTrace();
System.exit(-1);
}
}
public void listenForConnectionRequests() {
System.out.println("Listening for connection requests at " + PORT + "\n");
while (listening) {
try {
new Connection(welcomeSocket.accept()).start();
} catch (IOException e) {
System.err.println("I/O error occured while waiting for a connection.");
e.printStackTrace();
}
}
}
}
Connection Class
public class Connection extends Thread {
private Socket connectionSocket = null;
private ArrayList<String> requestHeaders = new ArrayList<String>();
private boolean running = true;
private OutputStream os;
private InputStream is;
public Connection(Socket connectionSocket) {
super("Proxy");
System.out.println("NEW connection thread created");
this.connectionSocket = connectionSocket;
}
public void run() {
while (running) {
readHttpHeader();
}
}
private void stopRunning() {
running = false;
System.err.println("Stopping thread.");
closeEverything();
}
private void readHttpHeader() {
try {
os = connectionSocket.getOutputStream();
} catch (IOException e) {
System.err.println("Problem getting output stream from connection socket.");
e.printStackTrace();
stopRunning();
}
try {
is = connectionSocket.getInputStream();
} catch (IOException e) {
System.err.println("Problem getting input stream from connection socket.");
e.printStackTrace();
stopRunning();
}
String input;
BufferedReader in = null;
DataOutputStream out = null;
try {
in = new BufferedReader(new InputStreamReader(connectionSocket.getInputStream()));
out = new DataOutputStream(connectionSocket.getOutputStream());
while ((input = in.readLine()) != null) {
requestHeaders.add(input);
System.out.println(input);
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} finally {
try {
if (in != null)
in.close();
if (out != null)
out.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
private void closeEverything() {
try {
connectionSocket.close();
is.close();
os.close();
} catch (IOException e) {
System.err.println("Problem closing connection or streams");
e.printStackTrace();
stopRunning();
}
}
}
Output after testing some webpages
Listening for connection requests at 5041
NEW connection thread created
GET http://127.0.0.1:63342/browserConnection/buildInfo HTTP/1.1
Host: 127.0.0.1:63342
Proxy-Connection: keep-alive
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/48.0.2564.116 Safari/537.36
Accept: */*
DNT: 1
Accept-Encoding: gzip, deflate, sdch
Accept-Language: en-US,en;q=0.8
NEW connection thread created
NEW connection thread created
GET http://google.com/ HTTP/1.1
Host: google.com
Proxy-Connection: keep-alive
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/48.0.2564.116 Safari/537.36
X-Client-Data: CKK2yQEIwbbJAQj9lcoB
DNT: 1
Accept-Encoding: gzip, deflate, sdch
Accept-Language: en-US,en;q=0.8
Cookie: OGP=-5061574:; SID=DQAAAMoCAACmU0EuiAZrQAuo8mgssp5cukiLvNn13ryGL2GeGswaF8Cmv2NIxyW_nnC7ihLpQRaY0gdlYg4K91TStT2aPHo3PWFhExCr5zD0yywqgMwsXuWgQedtdi8Lc6tsL0Nz2WSt8j1Is6Dw53SYpWw-Ukis9d386YATJRYdsDUhVsb3h-pe-QrKNBL3deaxIlMIb5itaAWVTSVkRUVcocns6S-mAopRFT-k8YMKXKVeouztBQhblI1YQUKAtMCqv55ZllmFyfZSQcqmbcsJx19ofBLnl6u2KByIwBLwMMa1DrK1YketAgvgxUzlrfanvTm94VQ7Lie9rppG-up1cNlDsu4XbXrIOkG2bdbD7J2SdjwmI_Hf9IrLl3IelDvdCfQol3CT8rdAMk1p7zBMQq5L_JfiiCLmjNd9VA0CiadcB-6dIBWnGGThNYEOkrU11i2qeiEPtvJqDx_7kyuphkFuQh8b5GI7f5xg-uVmLfjaO4Q7q5EiV7BTt5jacajRibvPsqK77lEw9_UTnPvXOkW1jmfJOKx85rAztVpV2vymO_dGMiG_ehiD4R6CO6ifCnHjij5TKUeWeSEzQdtdDsKGL3MAMSg1bZVKcmc3Veq77AwWZa996gUkyEdD1dJ5c4eTodTEjTx8KiUDEufPGxQtjyOEuT8rnY_MWvDTFUx0os-aMZfcYsLrTmJ6mWpYzKa5wnCvFHKnjBL24UddbBmhhaklLcOghJEH8kcVEVWvNuKC145OIzxwZA2CmTCfEDzymOd6pTGlwl9P7VInl2ro_SkoNmEn6VqUWLRC0zH1jEWZhpkNf9kbpLmWBS-xLWMBpvgPu7ysVBf7qR8_YlzyVprCdRDAR4mrciRaOaswHvWCWgU8EJk_gF8PgiP_D2WEtw8uJR6b4IL_ggxpmckGdHM7yUvkel9jWeFQxrazmF1f1c6SHBooSO6t-tCW7-Hw44A; HSID=A_KCc1Le4o6JlU760; APISID=hE0OzriLy98RcM4M/ALgi7Gky2rmmyyiDE; NID=77=dmymZT8yk5KfHAaIyzxhzvKfG_fvBjPwDpg-yTfz_5cBDKAsqL9n010br6xg1dSRrSKhS--_RYLoCuDodOzAHiaWS11pBB-4Npc9eQbqwkLnaf-nzeqNC_fwNSDElB7qfUmmvnZSHX1mowllXfpIM8cLm-ewYD0tGdHbpfvbAxkfH_jIwQKj-pS0f6ZkcodJ2CEEeoDhMUbZDAOfBKUUhM5qvLxE3curLhef6pftojQo0QpTumhoky2_pWR1lWP-5W0lPN29lMDSdeYrW5Umz_3jNHPRyMiGFwzNMIV9r9RUoyO50JreK057mDnzNygESvk_fBHlt49b2U6tesQ5NAtaAmL4VaWsAuj3jKEvjWTxSgSVrUeWwPC84hjn3liuGlBulWg; OGPC=5061900-22:5061918-27:5061934-15:5061921-40:5061937-46:5061933-25:5061941-6:5061574-1:5061940-57:5061952-26:5061975-14:5061983-7:
Problem getting output stream from connection socket.
java.net.SocketException: Socket is closed
at java.net.Socket.getOutputStream(Socket.java:916)
at Connection.readHttpHeader(Connection.java:46)
at Connection.run(Connection.java:34)
Stopping thread.
Problem getting input stream from connection socket.
java.net.SocketException: Socket is closed
at java.net.Socket.getInputStream(Socket.java:876)
at Connection.readHttpHeader(Connection.java:54)
at Connection.run(Connection.java:34)
Stopping thread.
java.net.SocketException: Socket is closed
at java.net.Socket.getInputStream(Socket.java:876)
at Connection.readHttpHeader(Connection.java:65)
at Connection.run(Connection.java:34)
Problem getting output stream from connection socket.
java.net.SocketException: Socket is closed
at java.net.Socket.getOutputStream(Socket.java:916)
at Connection.readHttpHeader(Connection.java:46)
at Connection.run(Connection.java:34)
Stopping thread.
Problem getting input stream from connection socket.
java.net.SocketException: Socket is closed
at java.net.Socket.getInputStream(Socket.java:876)
at Connection.readHttpHeader(Connection.java:54)
at Connection.run(Connection.java:34)
Stopping thread.
java.net.SocketException: Socket is closed
at java.net.Socket.getInputStream(Socket.java:876)
at Connection.readHttpHeader(Connection.java:65)
at Connection.run(Connection.java:34)
NEW connection thread created
NEW connection thread created
NEW connection thread created
NEW connection thread created
NEW connection thread created
NEW connection thread created
NEW connection thread created
NEW connection thread created
NEW connection thread created
NEW connection thread created
NEW connection thread created
NEW connection thread created
NEW connection thread created
NEW connection thread created
NEW connection thread created
NEW connection thread created
NEW connection thread created
NEW connection thread created
NEW connection thread created
NEW connection thread created
NEW connection thread created
NEW connection thread created
NEW connection thread created
NEW connection thread created
NEW connection thread created
GET http://www.yelp.com/ HTTP/1.1
Host: www.yelp.com
Proxy-Connection: keep-alive
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/48.0.2564.116 Safari/537.36
DNT: 1
Accept-Encoding: gzip, deflate, sdch
Accept-Language: en-US,en;q=0.8
Cookie: __cfduid=dd3ccfb39916d84ca8053ba95c0ca89fe1457229239; yuv=pOdmTZnrxWdr1NhFcLyF8cCB7Pj5l2tN3CSqNp0fiz0yKun0fbD0MHFrIo4K432S0pKC_-Sl9QijvKAX5u1iUJMmwZ2EnL4p; hl=en_US; fd=0; D_SID=172.250.60.189:SscPaGXtn/I/Skx3ISxQZOtF5qtsm+TmywEwnqXsiuo; qntcst=D%2CT%2C43606%2C43604%2C43602%2C43597%2C43596%2C43595%2C43583%2C43582%2C43581%2C37336%2C34588%2C34585%2C27425%2C27424%2C20052%2C20047%2C20040%2C20021%2C20020%2C20015%2C19991%2C19989%2C19958%2C19948%2C19947%2C19945%2C19944%2C19942%2C19941%2C19939%2C19936%2C19934%2C19932; __qca=P0-1476739725-1457229248633; fbm_97534753161=base_domain=.yelp.com; location=%7B%22city%22%3A+%22Seattle%22%2C+%22zip%22%3A+%22%22%2C+%22country%22%3A+%22US%22%2C+%22address2%22%3A+%22%22%2C+%22address3%22%3A+%22%22%2C+%22state%22%3A+%22WA%22%2C+%22address1%22%3A+%22%22%2C+%22unformatted%22%3A+%22seattle%22%7D; bse=b955bbc7020253479a51b278e343d766; __utma=165223479.439363298.1457229244.1457383227.1457394139.4; __utmc=165223479; __utmz=165223479.1457383227.3.3.utmcsr=google|utmccn=(organic)|utmcmd=organic|utmctr=(not%20provided); __utmv=165223479.|4=account%20level=anon=1; _ga=GA1.2.C1BEB9B4D17FEEDD; D_PID=469F0452-18FF-3E05-8072-566D9785BE96; D_IID=EC337894-ADD2-36A6-848D-AA87DA4B1407; D_UID=6E67A9C8-F999-33A6-8838-4EBFBC9B943E; D_HID=qXtXeOzvXZDnGT33GPaUewyWk7KgXdgunNy1mqdkX7g
Problem getting output stream from connection socket.
Problem getting output stream from connection socket.
Problem getting output stream from connection socket.
Problem getting output stream from connection socket.
You are closing the socket, and then trying to read from it.
The following code will call readHttpHeader twice ...
while (running) {
readHttpHeader();
}
The first time it is successful:
try {
in = new BufferedReader(new InputStreamReader(connectionSocket.getInputStream()));
while ((input = in.readLine()) != null) {
requestHeaders.add(input);
System.out.println(input);
}
And then you close the input stream ...
} finally {
try {
if (in != null)
in.close();
Which closes the stream it wraps (the InputStreamReader) which in turn closes the socket's input stream.
And then you loop around for the second call to readHttpHeader(), which finds the stream closed. Several try-catch blocks catch some errors, report them to stderr, and then muddle on, arriving at the read loop (failing), and finally the stream closing. Finally, since running is false, the readHttpHeader() is not called a third time.
Related
I have written a simple class extends Thread, used to receive user request, send it to HTTP-proxy server, runs on my Android device, get response and send it back to user:
public class ProxyThread extends Thread {
private Socket clientSocket = null;
public ProxyThread(Socket socket) {
super("ProxyThread");
this.clientSocket = socket;
}
public void run() {
try {
// Read request
InputStream incomingIS = clientSocket.getInputStream();
byte[] b = new byte[8196];
int len = incomingIS.read(b);
if (len > 0) {
System.out.println("REQUEST"
+ System.getProperty("line.separator") + "-------");
System.out.println(new String(b, 0, len));
// Write Request
Socket socket = new Socket("192.168.136.96", 8080);
OutputStream outgoingOS = socket.getOutputStream();
outgoingOS.write(b, 0, len);
// Send back
OutputStream incomingOS = clientSocket.getOutputStream();
InputStream outgoingIS = socket.getInputStream();
for (int length; (length = outgoingIS.read(b)) != -1; ) {
incomingOS.write(b, 0, length);
System.out.println("Answer"
+ System.getProperty("line.separator") + "-------");
System.out.println(new String(b, 0, len));
}
incomingOS.close();
outgoingIS.close();
outgoingOS.close();
incomingIS.close();
socket.close();
}
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
clientSocket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
System.out.println("closed");
}
I used FireFox to connect to the server (localhost:80). So it works fine with sites using HTTP (example http://info.cern.ch/), but it is not for sites using HTTPS.
For example i try to connect https://facebook.com.
FireFox sends a request:
CONNECT www.facebook.com:443 HTTP/1.1
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:91.0) Gecko/20100101 Firefox/91.0
Proxy-Connection: keep-alive
Connection: keep-alive
Host: www.facebook.com:443
Proxy sends back a response:
HTTP/1.1 200 Connection Established
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:91.0) Gecko/20100101 Firefox/91.0
Proxy-Connection: keep-alive
Connection: keep-alive
Host: www.facebook.com:443
I don't know why FireFox does show nothing, but maybe it just can't recive an response from my server (localhost:80) and i don't know why.
I am trying to send a message to the server. My problem is that the client keeps waiting for input and never sends it to the server until the last message that tells it to terminate (which is "bye"). After client terminates, the server will receive the message. But I want the server to receive the message everytime the client hit's the enter key.
I am not sure, but I think that the problem is with the Bufferedwriter in the client, because if I connect to the server using the browser, the server receives all the browser information. An example is shown below:
Connect to this server name: localhost and port: 121
Connection from client: Socket[addr=/0:0:0:0:0:0:0:1,port=61942,localport=121]
From client > GET / HTTP/1.1
From client > Host: localhost:121
From client > Connection: keep-alive
From client > Cache-Control: max-age=0
From client > Upgrade-Insecure-Requests: 1
From client > User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.111 Safari/537.36
...
Relevant server code:
try {
sers = new ServerSocket(port);
client = sers.accept();
reader = new BufferedReader(new InputStreamReader(client.getInputStream()));
writer = new BufferedWriter(new OutputStreamWriter(client.getOutputStream()));
boolean clientIsOnline = true;
while (clientIsOnline) {
print("Connection from client: " + client);
while((msg = reader.readLine()) != null) {
print("From client > " + msg);
if(msg.toLowerCase().equals("bye"))
print("Client left, server closed");
clientIsOnline=false;
}
ss.close();
reader.close();
writer.close();
}
} catch(Exception e) {
print("Error starting server: ");
e.printStackTrace();
}
Relevant client code:
public Client(String adr, int port) {
this.adr=adr;
this.port=port;
try {
c=new Socket(adr, port);
r = new BufferedReader(new InputStreamReader(c.getInputStream()));
w = new PrintWriter(new OutputStreamWriter(c.getOutputStream()));
} catch (IOException e) {
e.printStackTrace();
}
}
Client method for sending the message
private void msgToServer(String msg) {
try {
w.write(msg);
w.flush();
} catch (Exception e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
if(msg.toLowerCase().equals("bye")) {
print("I am out, bye");
try {
c.close();
r.close();
w.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
Client main method:
public static void main(String[] args) {
int port=121;
String msg =null;
Scanner sc = new Scanner(System.in);
Client c = new Client("localhost", port);
System.out.println("Write something to server");
while(true) {
c.msgToServer(sc.next());
}
}
I also tried using the PrintWriter instead of BufferedWriter, and also tried adding the true keyword as parameter, like
new PrintWriter(new OutputStreamWriter(c.getOutputStream()), true);
Just to give an example of what it looks like using my client.
I type hello hit enter (I expect it to send this, but it doesn't). Then I type my name is john hit enter again. Finally I type bye
I excpect:
From client > hello
From client > my name is john
From client > bye
What I get: From client > hellomynameisjohnbye
I believe the newline is being consumed when the client reads the input, so it needs to be added when sent to the server. In the client method:
private void msgToServer(String msg) {
try {
// re-introduce newline:
w.println(msg);
[SNIP]
I have server and client applications running on my local machine.
Client takes file, changes it and sends to server, then server responds if the file is correct. Client does it multiple times, sending one file at a time.
I send two files from client and on the second file I get Connection reset
Server snippet:
private void initServer() throws IOException {
while (true) {
ServerSocket server = new ServerSocket(55555);
Socket fromclient = server.accept();
InputStream sin = fromclient.getInputStream();
OutputStream sout = fromclient.getOutputStream();
DataInputStream in = new DataInputStream(sin);
DataOutputStream out = new DataOutputStream(sout);
String line = in.readUTF();
if (line.equals("new file")) {
long fileSize = in.readLong();
tempSavedFile = new File("/home/evgeniy/Files/Downloads/temp");
tempSavedFile.createNewFile();
try (FileOutputStream fos = new FileOutputStream(tempSavedFile)) {
int t;
for (int i = 0; i < fileSize; i++) {
t = sin.read();
fos.write(t);
}
}
if (checkPadding(tempSavedFile)) {
out.writeInt(PADDING_OK_RESPONSE);
} else {
out.writeInt(PADDING_ERROR_RESPONSE);
}
out.flush();
}
out.close();
in.close();
sout.close();
sin.close();
fromclient.close();
server.close();
}
}
Client class that calls new thread in for loop
for (byte i = 0; i < 2; i++) {
Callable callable = new FileSender(tempFile);
FutureTask<Integer> ftask = new FutureTask<>(callable);
Thread thread = new Thread(ftask);
thread.start();
int response = 3244;
try {
response = ftask.get();
} catch (InterruptedException | ExecutionException ex) {
Logger.getLogger(FXMLController.class.getName()).log(Level.SEVERE, null, ex);
}
putMessage(String.valueOf(response));
Client Callable thread:
public Integer call() throws Exception {
Socket socket = new Socket(address, serverPort);
InputStream sin = socket.getInputStream();
OutputStream sout = socket.getOutputStream();
DataInputStream in = new DataInputStream(sin);
DataOutputStream out = new DataOutputStream(sout);
out.writeUTF("new file");
out.flush();
out.writeLong(file.length);
out.flush();
sout.write(file);
sout.flush();
System.out.println(socket.isConnected());
int response = in.readInt();
System.out.println("--------RESP="+response);
out.close();
in.close();
sin.close();
sout.close();
socket.close();
return response;
}
As you can see I send two files, and get this console output on client app:
true
--------RESP=200
true
ноя 20, 2018 5:16:36 PM com.evgeniy_mh.paddingoracle.FXMLController SendFileToServer
SEVERE: null
java.util.concurrent.ExecutionException: java.net.SocketException: Connection reset
Also, I don't understand why socket is ok, but
int response = in.readInt();
raising Connection reset exception.
Your code creates a new ServerSocket and later closes the created server socket for every single request that it processes. The code does not use the same ServerSocket instance to serve multiple requests.
The connection reset failure appears to be because of this, as when the second request is creating a socket connection with the server, the existing ServerSocket is closed and recreated on the same port leading to the connection being reset. For a start try taking out the ServerSocket creation outside the while loop.
private void initServer() {
try (ServerSocket server = new ServerSocket(5555)) {
while (true) {
Socket fromclient = server.accept();
... // remaining code
fromclient.close();
}
} catch (IOException ioe) {
// handle failures
}
}
The try-with-resources handles the .close() call on the AutoCloseable server socket.
Also, note that the requests would be processed serially on a single thread in your code. Usually the Socket obtained for a connection from the ServerSocket#accept() (or the streams derived from it) is passed to a separate thread for processing unlike your code that processes the requests serially.
I've got strange issue with my http communication. I wrote following very simple http server and client.
Http server:
public class SimpleHttpServer {
public void run() throws IOException {
final ServerSocket serverSocket = new ServerSocket(8080);
while(true)
{
final Socket connectionSocket = serverSocket.accept();
new Thread(new Runnable() {
#Override
public void run() {
try {
try(BufferedReader in = new BufferedReader(new InputStreamReader(connectionSocket.getInputStream()));
DataOutputStream out = new DataOutputStream(connectionSocket.getOutputStream())){
System.out.println(in.readLine());
String line = null;
while((line = in.readLine()) != null && !line.trim().isEmpty()){
System.out.println(line);
}
byte[] message = loadFile(); //load some gzipped jpg image from disk
out.write(ascii("HTTP/1.1 200 OK\n"));
out.write(ascii("Content-Type: image/jpg\n"));
out.write(ascii(String.format("Content-Length: %s\n", message.length)));
out.write(ascii("content-encoding: gzip\n"));
out.write(ascii("\n"));
out.write(message);
}
}catch(Exception e){
e.printStackTrace();
}
}
}).start();
}
}
}
Http client:
public class SimpleHttpClient {
public void run() throws IOException {
String host = "localhost";
int port = 8080;
Socket socket = new Socket(host, port);
try (OutputStream out = socket.getOutputStream()) {
out.write(ascii("GET / HTTP/1.1\n"));
out.write(ascii("User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/53.0.2785.143 Safari/537.36\n"));
out.write(ascii("Accept-Encoding: gzip, deflate, sdch\n"));
out.write(ascii("Accept-Language: pl-PL,pl;q=0.8,en-US;q=0.6,en;q=0.4\n"));
out.write(ascii("\n"));
try (BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream()))) {
String line = null;
while ((line = in.readLine()) != null && !line.trim().isEmpty()) {
System.out.println(line);
}
}
}
}
}
So, when I remove line with user agent header, I get result as I expect:
HTTP/1.1 200 OK
Content-Type: image/jpg
Content-Length: 378632
content-encoding: gzip
And this is clear and obvious.
But when this header will appear, the answer is different:
HTTP/1.1 200 OK
Content-Type: image/jpg
Transfer-Encoding: chunked
I didn't change anything on server side. On every request I send the same response. The user agent was copied from chrome browser.
Both implementations are in plain java socket, not on third party libriares.
So my question is: how it happend? Something was cached? But where?
Please don't look at code quality. This is just an example. I don't want to use it on production :)
EDIT 1:
private byte[] ascii(String value) throws UnsupportedEncodingException {
return value.getBytes(StandardCharsets.US_ASCII);
}
EDIT 2:
I've done some research. It happens when user agent contains "AppleWebKit", protocol name is HTTP and port is 80 or 8080.
Moreover it happens on Windows 10 (I checked on two different computers). On Linux (Ubuntu 16.04 and Debian 8) everything is fine.
Maybe I should change the title of question? But how can I explain the problem in one short sentence?
I was wrote fowling code then set HTTP proxy on 127.0.0.1:9090 and try to reach google.com but it print following output and nothing happend.
Output:
Waiting for clients on port 9090
Got connection from /127.0.0.1:11827
Active Connections = 1
Waiting for clients on port 9090
connect started
connect finished
***Got connection from /74.125.232.131:80
writed
GET http://google.com/ HTTP/1.1
Host: google.com
User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:19.0) Gecko/20100101 Firefox/19.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
Cookie: ****
Connection: keep-alive
null
read line startes
Code:
import java.net.*;
import java.io.*;
import java.util.*;
public class SocketGoogler
{
public static void main(String[] args)
{
int port = 9090;
try {
ServerSocket server = new ServerSocket(port);
//System.out.println(google());
while(true) {
System.out.println("Waiting for clients on port " + port);
Socket client = server.accept();
ConnectionHandler handler = new ConnectionHandler(client);
handler.start();
}
} catch(Exception ex) {
System.out.println("Connection error: "+ex);
}
}
}
class ConnectionHandler extends Thread {
private Socket client;
BufferedReader reader;
PrintWriter writer;
static int count;
public ConnectionHandler(Socket client) {
this.client = client;
System.out.println("Got connection from "+client.getInetAddress()
+":"+client.getPort());
count++;
System.out.println("Active Connections = " + count);
}
public void run() {
String message;
String totalMessage;
try {
reader = new BufferedReader(new
InputStreamReader(client.getInputStream()));
writer = new PrintWriter(client.getOutputStream());
writer.flush();
message = reader.readLine();
totalMessage=message+"\n";
while (message != null) {
message = reader.readLine();
totalMessage+=message+"\n";
}
client.close();
//System.out.println(totalMessage);
google(totalMessage);
count--;
System.out.println("Active Connections = " + count);
} catch (Exception ex) {
count--;
System.out.println("Active Connections = " + count);
}
}
public String google(String w) throws IOException
{
String message , totalMessage;
int port = 80;
//ServerSocket server = new ServerSocket(port,10,InetAddress.getByName("google.com"));
//Socket googler=server.accept();
Socket googler=new Socket();
InetSocketAddress endpoint=new InetSocketAddress(InetAddress.getByName("google.com").getHostAddress(), port);
System.out.println("connect started");
googler.connect(endpoint);
System.out.println("connect finished");
System.out.println("***Got connection from "+googler.getInetAddress()+":"+googler.getPort());
BufferedReader reader = new BufferedReader(new
InputStreamReader(googler.getInputStream()));
PrintWriter writer=new PrintWriter(googler.getOutputStream());
//String w="GET http://google.com/ HTTP/1.1\nHost: google.com\nUser-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:19.0) Gecko/20100101 Firefox/19.0\nAccept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8\nAccept-Language: en-US,en;q=0.5\nAccept-Encoding: gzip, deflate\nConnection: keep-alive"+null;
writer.print(w);
System.out.println("writed\n"+w);
System.out.println("read line startes");
message = reader.readLine();
System.out.println("read line finished");
totalMessage=message+"\n";
while (message != null) {
message = reader.readLine();
System.out.println("*");
totalMessage+=message+"\n";
}
googler.close();
System.out.println("close");
return totalMessage;
}
}
Why this problems happens?I already connected too google.com and send request but nothing respond from this host.
Use writer.flush(); It will send your request.
:)