user1850254
user1850254

Reputation: 2471

My response seems to hang in response class while working with sockets

I am currently implementing a web proxy but i have run into a problem.I can parse my request from the browser and make a new request quite alright but i seem to have a problem with response.It keeps hanging inside my response loop

    serveroutput.write(request.getFullRequest());
            //  serveroutput.newLine();
                serveroutput.flush();
                //serveroutput.
                 //serveroutput.close();
            } catch (IOException e) {
                System.out.println("Writting tothe server was unsuccesful");
                e.printStackTrace();
            }
            System.out.println("Write was succesful...");
             System.out.println("flushed.");

             try {
                 System.out.println("Getting a response...");
                 response= new    HttpResponse(serversocket.getInputStream());
        } catch (IOException e) {
                System.out.println("tried to read response from server but failed");
                e.printStackTrace();
            }

              System.out.println("Response was succesfull");



      //response code

        public HttpResponse(InputStream input) {
    busy=true;

      reader = new BufferedReader(new InputStreamReader(input));
      try {
          while (!reader.ready());//wait for initialization.

          String line;
          while ((line = reader.readLine()) != null) {
              fullResponse += "\r\n" + line;


          }

          reader.close();
          fullResponse = "\r\n" + fullResponse.trim() + "\r\n\r\n";
      } catch (IOException`` e) {

          e.printStackTrace();
      } 
      busy = false;
  }

Upvotes: 0

Views: 127

Answers (3)

Brian Roach
Brian Roach

Reputation: 76898

You're doing a blocking, synchronous read on a socket. Web servers don't close their connections after sending you a page (if HTTP/1.1 is specified) so it's going to sit there and block until the webserver times out the connection. To do this properly you would need to be looking for the Content-Length header and reading the appropriate amount of data when it gets to the body.

You really shouldn't be trying to re-invent the wheel and instead be using either the core Java provided HttpURLConnection or the Appache HttpClient to make your requests.

Upvotes: 2

user207421
user207421

Reputation: 310883

You are making numerous mistakes here.

  • Using a spin loop calling ready() instead of just blocking in the subsequent read.
  • Using a Reader when you don't know that the data is text.
  • Not implementing the HTTP 1.1 protocol even slightly.

Instead of reviewing your code I suggest you review the HTTP 1.1 RFC. All you need to do to implement a naive proxy for HTTP 1.1 is the following:

  1. Read one line from the client. This should be a CONNECT command naming the host you are to connect to. Read this with a DataInputStream, not a BufferedReader, and yes I know it's deprecated.

  2. Connect to the target. If that succeeded, send an HTTP 200 back to the client. If it didn't, send whatever HTTP status is appropriate and close the client.

  3. If you succeeded at (2), start two threads, one to copy all the data from the client to the target, as bytes, and the other to do the opposite.

  4. When you get EOS reading one of those sockes, call shutdownOutput() on the other one.

  5. If shutdownOutput() hasn't already been called on the input socket of this thread, just exit the thread.

  6. If it has been called already, close both sockets and exit the thread.

Note that you don't have to parse anything except the CONNECT command; you don't have to worry about Content-length; you just have to transfer bytes and then EOS correctly.

Upvotes: 1

kufudo
kufudo

Reputation: 2833

while (!reader.ready());

This line goes into an infinite loop, thrashing the CPU until the stream is available for read. Generally not a good idea.

Upvotes: 1

Related Questions