0

I am doing some work for the university, in which I am asked to create a TCP socket that makes an HTTP request with OPTIONS as a header and return the whole page in a variable.

The code I have made is the following:

public String SendReq(String url, int port) throws Exception {

        String resposta = null;
        // Instantiate a new socket
        Socket s = new Socket(url, port);

        // Instantiates a new PrintWriter passing in the sockets output stream
        PrintWriter wtr = new PrintWriter(s.getOutputStream());

        // Prints the request string to the output stream
        wtr.println("OPTIONS / HTTP/1.1");
        wtr.println("Host: " + url);
        wtr.println("");
        wtr.flush();
        // Creates a BufferedReader that contains the server response
        BufferedReader bufRead = new BufferedReader(new InputStreamReader(s.getInputStream()));
        String outStr;
 
        
        while ((outStr = bufRead.readLine()) != null) {

            resposta = resposta + outStr;
            
            if (!outStr.trim().isEmpty()) {
                resposta += "\r\n";
            }
        }

        LSimLogger.log(Level.INFO, "response http : " + resposta);

        s.close();
        bufRead.close();
        wtr.close();
        return resposta ;
    }

And actually works.

As you can see, I run this code with example.org as url and 80 as port. In the logs, I see:

10-04-2021 21:35:49:514 tcp_client [INFO] : inici client http
10-04-2021 21:35:49:517 tcp_client [INFO] : inici HTTPclient.get 
10-04-2021 21:35:49:517 tcp_client [INFO] : HTTP server_address: example.org
10-04-2021 21:35:49:517 tcp_client [INFO] : HTTP server_port: 80
10-04-2021 21:35:49:517 tcp_client [INFO] : example.org
10-04-2021 21:38:00:636 tcp_client [INFO] : response http : nullHTTP/1.1 200 OK
Allow: OPTIONS, GET, HEAD, POST
Cache-Control: max-age=604800
Content-Type: text/html; charset=UTF-8
Date: Sat, 10 Apr 2021 19:35:49 GMT
Expires: Sat, 17 Apr 2021 19:35:49 GMT
Server: EOS (vny/0452)
Content-Length: 0

As you can see, it takes more than 3 minutes to get the response, but the date of the response is the same as the request.

What can I do to make the response faster?

Remy Lebeau
  • 555,201
  • 31
  • 458
  • 770
F. Iván
  • 167
  • 1
  • 1
  • 12

1 Answers1

4
    wtr.println("OPTIONS / HTTP/1.1");
    wtr.println("Host: " + url);
    wtr.println("");

You are doing a HTTP/1.1 request which implicitly enables HTTP keep-alive. This means that the server might wait for another request on the same TCP connection.

Only your code expects the server to close the connection immediately after the response. But the server does not do this and instead is waiting for more requests for some time and only stops waiting after several minutes.

To fix the problem you either need to properly read the HTTP response and detect when the response is finished by following the HTTP standard. Or make sure that HTTP keep-alive is off by adding a Connection: close header to the request.

Steffen Ullrich
  • 114,247
  • 10
  • 131
  • 172
  • Thats it, its working now properly adding wtr.println("Connection: close "); Thank you so much – F. Iván Apr 10 '21 at 20:20
  • @F.Iván What you have shown is not a valid way to read HTTP responses. You really need to parse the responses properly. See [this answer](https://stackoverflow.com/a/16247097/65863). But, why are you not using Java's [built-in HTTP client](https://docs.oracle.com/en/java/javase/11/docs/api/java.net.http/java/net/http/HttpClient.html) instead? Also see [5 ways to make HTTP requests in Java](https://www.twilio.com/blog/5-ways-to-make-http-requests-in-java). – Remy Lebeau Apr 10 '21 at 20:57