1

I'm trying to make a simple HTML server that will read a request from my browser, parse the requested file from the request, then serve the appropriate HTML back to the browser. I need to be able to handle multiple requests, so I currently have a Server class acting as a parent of another runnable class RequestHandler. Each time a connection is made on the server, a new instance of the runnable class RequestHandler is run.

package server;

import java.io.IOException;
import java.net.ServerSocket;

public class Server {

    public static void main(String[] args){
        try{
            ServerSocket serverSocket = new ServerSocket(8000);

            for(;;){
                Object block = new Object();
                RequestHandler handler = new RequestHandler(block, serverSocket);
                handler.start();

                try{
                    synchronized(block){
                        System.out.println("Server thread paused...");
                        block.wait();
                        System.out.println("Server thread creating new RequestHandler...");
                    }
                }catch(InterruptedException e){
                    System.out.println("Can't be interrupted!");
                    e.printStackTrace();
                }
            }

        }catch(IOException e){
            System.out.println("IOException!");
            e.printStackTrace();
        }
    }
}

package server;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;

public class RequestHandler extends Thread {

    Object block;
    ServerSocket serverSocket;
    BufferedReader socketReader;
    PrintWriter socketWriter;

    public RequestHandler(Object block, ServerSocket serverSocket){
        this.block = block;
        this.serverSocket = serverSocket;
    }

    @Override
    public void run() {
        try{
            System.out.println("Waiting for request...");
            Socket clientSocket = serverSocket.accept();
            System.out.println("Connection made.");

            synchronized(block){
                System.out.print("Notifying server thread...");
                block.notify();
                System.out.println("...done");
            }

            socketReader = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));            
            socketWriter = new PrintWriter(clientSocket.getOutputStream(), true);

            String input;
            while((input = socketReader.readLine()) != null){
                System.out.println(input);
            }
        }catch(IOException e){
            System.out.println("IOException!");
            e.printStackTrace();
        }
    }

}

The problem I'm running into is that I'm not sure how to combine all the lines of the request so that I can parse the requested file. If it's just constantly waiting on request input, I'll never get to a point where I can parse the entirety of the request. How can I solve this problem?

1
  • 1
    Take a look at HttpCore. It provides HTTP-related components, which would make building a server much easier. Commented Oct 19, 2011 at 20:59

2 Answers 2

3

your while loop will only break once the connection between the client and the server is closed. Since the client is waiting on the same connection for a response after sending the request the connection will remain open, so your readline() will block. In your while loop you have to check after every line whether you have reached the end of the request data. For GET requests, you have to look for a blank line following HTTP headers. For POST requests, you have to parse incoming headers looking for <Content-Length: N>. THen process the remaining headers looking for the blank line (just like in the GET case). Once you find the blank like, you have to read <N> bytes. At this point you know you've finished processing request data and should break out of the read loop.

Read the HTTP spec for details.

Sign up to request clarification or add additional context in comments.

Comments

1

The first line gives you the request method as well as the requested path, the following lines are the request headers, the header block ends with a blank line.

That said, you are reinventing the wheel: you could use com.sun.net.httpserver.HttpServer

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.