Разбор HTTP-запроса от браузера на локальном сервере: Java - PullRequest
1 голос
/ 20 октября 2011

Я пытаюсь создать простой HTML-сервер, который будет читать запрос из моего браузера, анализировать запрошенный файл из запроса, а затем отправлять соответствующий HTML обратно в браузер. Мне нужно иметь возможность обрабатывать несколько запросов, поэтому в настоящее время у меня есть класс Server, выступающий в роли родителя другого исполняемого класса RequestHandler. Каждый раз, когда устанавливается соединение с сервером, запускается новый экземпляр исполняемого класса RequestHandler.

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();
        }
    }

}

Проблема, с которой я сталкиваюсь, заключается в том, что я не уверен, как объединить все строки запроса, чтобы я мог проанализировать запрошенный файл. Если он просто постоянно ожидает ввода запроса, я никогда не доберусь до точки, где я смогу проанализировать весь запрос. Как я могу решить эту проблему?

Ответы [ 2 ]

3 голосов
/ 20 октября 2011

ваш цикл while прервется только после закрытия соединения между клиентом и сервером.Поскольку клиент ожидает ответа в том же соединении после отправки запроса, соединение останется открытым, поэтому ваша readline () будет заблокирована.В вашем цикле while вы должны после каждой строки проверять, достигли ли вы конца данных запроса.Для запросов GET вы должны искать пустую строку после заголовков HTTP.Для запросов POST необходимо проанализировать входящие заголовки в поисках,Затем обработайте оставшиеся заголовки в поисках пустой строки (как в случае GET).Как только вы найдете пробел как, вы должны прочитать байт.На данный момент вы знаете, что завершили обработку данных запроса и должны выйти из цикла чтения.

Подробнее см. Спецификацию HTTP.

1 голос
/ 20 октября 2011

Первая строка дает вам метод запроса, а также запрошенный путь, следующие строки являются заголовками запроса, блок заголовка заканчивается пустой строкой.

При этом вы заново изобретаете колесо:Вы можете использовать com.sun.net.httpserver.HttpServer

...