JAVA міні сервер

Простенький web-сервер на java, який демонструє принцип роботи HTTP протоколу. Цілком може виступати в ролі заглушки.


import java.net.ServerSocket;
import java.net.Socket;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.InputStreamReader;
import java.io.BufferedReader;
 
public class HttpServer {
 
    public static void main(String[] args) throws Throwable {
        ServerSocket ss = new ServerSocket(80);
        while (true) {
            Socket s = ss.accept();
            System.err.println("Client accepted");
            new Thread(new SocketProcessor(s)).start();
        }
    }
 
    private static class SocketProcessor implements Runnable {
 
        private Socket s;
        private InputStream is;
        private OutputStream os;
 
        private SocketProcessor(Socket s) throws Throwable {
            this.s = s;
            this.is = s.getInputStream();
            this.os = s.getOutputStream();
        }
 
        public void run() {
            try {
                readInputHeaders();
                writeResponse("<html><body><h1>Hello from java!</h1></body></html>");
            } catch (Throwable t) {
                /*do nothing*/
            } finally {
                try {
                    s.close();
                } catch (Throwable t) {
                    /*do nothing*/
                }
            }
            System.err.println("Client processing finished");
        }
 
        private void writeResponse(String s) throws Throwable {
            String response = "HTTP/1.1 200 OK\r\n" +
                    "Server: MiniServer/2014-04-25\r\n" +
                    "Content-Type: text/html\r\n" +
                    "Content-Length: " + s.length() + "\r\n" +
                    "Connection: close\r\n\r\n";
            String result = response + s;
            os.write(result.getBytes());
            os.flush();
        }
 
        private void readInputHeaders() throws Throwable {
            BufferedReader br = new BufferedReader(new InputStreamReader(is));
            while(true) {
                String s = br.readLine();
                if(s == null || s.trim().length() == 0) {
                    break;
                }
            }
        }
    }
}

В даному випадку йому буде байдуже до вмісту запиту, він віддаватиме прошиту в нього відповідь:

writeResponse("<html><body><h1>Hello from java!</h1></body></html>");

Принцип роботи дуже простий. Він “вішається” на порт 80 (стандартний http порт, не вказується в url, в інакшому випадку потрібно буде вказувати його таким чином: 127.0.0.1:1234).

ServerSocket ss = new ServerSocket(80);

Потім у вічному циклі очікує вхідного запиту:

Socket s = ss.accept();

І створює новий потік, щоб відгалузити обробку цього запиту і надати можливість паралельно слухати інші запити.

new Thread(new SocketProcessor(s)).start();

Найголовніша річ: щоб браузер сприйняв відповідь, потрібно відповідь почати у деякому форматі. Це ті знамениті заголовки HTTP (Headers). Інакше браузер повідомить про помилку, оскільки відповідь прийшла не згідно протоколу http.

private void writeResponse(String s) throws Throwable {
        String response = "HTTP/1.1 200 OK\r\n" +
            "Server: MiniServer/2014-04-25\r\n" +
            "Content-Type: text/html\r\n" +
            "Content-Length: " + s.length() + "\r\n" +
            "Connection: close\r\n\r\n";
        String result = response + s;
        os.write(result.getBytes());
        os.flush();
    }

Звісно, бойовим його не назвеш, проте, якщо вдосконалити, можна зробити свій веб-сервер.

Що це?

Це не блог, це більше записки від себе для себе.

Тематика: IT, дичь, що це?