SHARE
TWEET

govno

a guest Sep 17th, 2019 99 Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. import java.io.*;
  2. import java.net.ServerSocket;
  3. import java.net.Socket;
  4. import java.net.URLDecoder;
  5. import java.nio.charset.StandardCharsets;
  6. import java.util.Collections;
  7. import java.util.HashMap;
  8. import java.util.Map;
  9.  
  10. class HttpServer {
  11.     private final File root;
  12.  
  13.     private HttpServer(File root, int port) throws IOException {
  14.         this.root = root;
  15.  
  16.         ServerSocket serverSocket = new ServerSocket(port);
  17.         while (serverSocket.isBound()) {
  18.             try {
  19.                 Socket socket = serverSocket.accept();
  20.                 process(socket);
  21.                 socket.close();
  22.             } catch (IOException ignored) {
  23.                 // No operations.
  24.             }
  25.         }
  26.     }
  27.  
  28.     private void process(Socket socket) throws IOException {
  29.         Request request = readRequest(socket);
  30.  
  31.         Response response = new Response();
  32.         response.setHeader("Connection", "close");
  33.  
  34.         try {
  35.             process(request, response);
  36.         } catch (Exception ignored) {
  37.             response.setStatusCode(502);
  38.         }
  39.  
  40.         try {
  41.             writeResponse(socket, response);
  42.         } catch (Exception e) {
  43.             e.printStackTrace();
  44.         }
  45.     }
  46.  
  47.     private void writeResponse(Socket socket, Response response) throws IOException {
  48.         try {
  49.             ByteArrayOutputStream result = new ByteArrayOutputStream();
  50.             result.write(("HTTP/1.1 " + response.getStatusCode() + " NA\r\n").getBytes());
  51.             for (Map.Entry<String, String> entry : response.getHeaders().entrySet()) {
  52.                 result.write((entry.getKey() + ": " + entry.getValue() + "\r\n").getBytes());
  53.             }
  54.             result.write("\r\n".getBytes());
  55.             if (response.getBody() != null) {
  56.                 result.write(response.getBody());
  57.             }
  58.  
  59.             OutputStream outputStream = socket.getOutputStream();
  60.             outputStream.write(result.toByteArray());
  61.             outputStream.close();
  62.         } finally {
  63.             socket.close();
  64.         }
  65.     }
  66.  
  67.     private void process(Request request, Response response) throws IOException {
  68.         if (!"GET".equals(request.getMethod())) {
  69.             response.setStatusCode(405);
  70.             return;
  71.         }
  72.  
  73.         boolean rootPath = false;
  74.         File file;
  75.         String uri = URLDecoder.decode(request.getUri(), StandardCharsets.UTF_8.name()).trim();
  76.  
  77.         if (uri.equals("/") || uri.isEmpty()) {
  78.             rootPath = true;
  79.             file = new File(root, "index.html");
  80.         } else if (uri.equals("/images") || uri.equals("/images/")) {
  81.             rootPath = true;
  82.             file = new File(root, "/images/index.html");
  83.         } else {
  84.             file = new File(root, uri);
  85.         }
  86.  
  87.         if (file.isFile()) {
  88.             if (!rootPath && request.getHeader("If-None-Match") != null &&
  89.                     request.getHeader("If-None-Match").equals(String.valueOf(file.length() * 228))) {
  90.                 response.setStatusCode(304);
  91.                 response.setHeader("ETag", String.valueOf(file.length() * 228));
  92.                 return;
  93.             }
  94.  
  95.             byte[] body = readFile(file);
  96.             response.setStatusCode(200);
  97.             response.setBody(body);
  98.             response.setHeader("Content-Length", Integer.toString(body.length));
  99.             response.setHeader("Content-Type", getContentType(file));
  100.             response.setHeader("ETag", String.valueOf(file.length() * 228));
  101.         } else {
  102.             response.setStatusCode(404);
  103.         }
  104.     }
  105.  
  106.     private String getContentType(File file) {
  107.         String path = file.getAbsolutePath();
  108.         if (path.endsWith(".html") || path.endsWith(".htm")) {
  109.             return "text/html";
  110.         } else if (path.endsWith(".png")) {
  111.             return "image/png";
  112.         }
  113.         throw new IllegalArgumentException();
  114.     }
  115.  
  116.     private void silentClose(Closeable closeable) {
  117.         try {
  118.             closeable.close();
  119.         } catch (Exception ignored) {
  120.             // No operations.
  121.         }
  122.     }
  123.  
  124.     private byte[] readInputStream(InputStream inputStream, boolean breakOnCrLf) throws IOException {
  125.         ByteArrayOutputStream bytes = new ByteArrayOutputStream();
  126.  
  127.         byte[] lastTwoBytes = new byte[2];
  128.         int lastTwoBytesSize = 0;
  129.  
  130.         try {
  131.             byte[] buffer = new byte[1024];
  132.             while (true) {
  133.                 if (breakOnCrLf && lastTwoBytes[0] == 13 && lastTwoBytes[1] == 10) {
  134.                     break;
  135.                 }
  136.  
  137.                 int read = inputStream.read(buffer);
  138.                 if (breakOnCrLf) {
  139.                     if (read == 1) {
  140.                         if (lastTwoBytesSize > 1) {
  141.                             lastTwoBytes[0] = lastTwoBytes[1];
  142.                         }
  143.                         lastTwoBytesSize = Math.max(0, lastTwoBytesSize - 1);
  144.                         lastTwoBytes[lastTwoBytesSize++] = buffer[read - 1];
  145.                     } else if (read >= 2) {
  146.                         lastTwoBytesSize = 2;
  147.                         lastTwoBytes[0] = buffer[read - 2];
  148.                         lastTwoBytes[1] = buffer[read - 1];
  149.                     }
  150.                 }
  151.  
  152.                 if (read >= 0) {
  153.                     bytes.write(buffer, 0, read);
  154.                 } else {
  155.                     break;
  156.                 }
  157.             }
  158.         } finally {
  159.             silentClose(bytes);
  160.         }
  161.  
  162.         return bytes.toByteArray();
  163.     }
  164.  
  165.     private byte[] readFile(File file) throws IOException {
  166.         InputStream inputStream = new FileInputStream(file);
  167.         try {
  168.             return readInputStream(inputStream, false);
  169.         } finally {
  170.             silentClose(inputStream);
  171.         }
  172.     }
  173.  
  174.     private Request readRequest(Socket socket) throws IOException {
  175.         InputStream inputStream = socket.getInputStream();
  176.         return new Request(new String(readInputStream(inputStream, true)));
  177.     }
  178.  
  179.     private static final class Request {
  180.         private final String method;
  181.         private final String uri;
  182.         private final Map<String, String> headers;
  183.  
  184.         private Request(String request) {
  185.             String[] lines = request.split("[\r\n]+");
  186.             if (lines.length < 1) {
  187.                 throw new IllegalArgumentException();
  188.             }
  189.  
  190.             String[] firstLineTokens = lines[0].split("\\s+");
  191.             method = firstLineTokens[0];
  192.             uri = firstLineTokens[1];
  193.             headers = new HashMap<>();
  194.  
  195.             for (int i = 1; i < lines.length; i++) {
  196.                 String line = lines[i];
  197.                 if (line.contains(":")) {
  198.                     int sep = line.indexOf(':');
  199.                     headers.put(line.substring(0, sep), line.substring(sep + 1).trim());
  200.                 }
  201.             }
  202.         }
  203.  
  204.         private String getMethod() {
  205.             return method;
  206.         }
  207.  
  208.         private String getUri() {
  209.             return uri;
  210.         }
  211.  
  212.         @SuppressWarnings({"SameParameterValue", "unused"})
  213.         private String getHeader(String name) {
  214.             return headers.get(name);
  215.         }
  216.     }
  217.  
  218.     private static final class Response {
  219.         private int statusCode;
  220.         private final Map<String, String> headers = new HashMap<>();
  221.         private byte[] body;
  222.  
  223.         private void setHeader(String name, String value) {
  224.             headers.put(name, value);
  225.         }
  226.  
  227.         private int getStatusCode() {
  228.             return statusCode;
  229.         }
  230.  
  231.         private void setStatusCode(int statusCode) {
  232.             this.statusCode = statusCode;
  233.             this.body = ("Error " + statusCode).getBytes();
  234.         }
  235.  
  236.         private byte[] getBody() {
  237.             return body;
  238.         }
  239.  
  240.         private void setBody(byte[] body) {
  241.             this.body = body;
  242.         }
  243.  
  244.         private Map<String, String> getHeaders() {
  245.             return Collections.unmodifiableMap(headers);
  246.         }
  247.     }
  248.  
  249.     public static void main(String[] args) throws IOException {
  250.         new HttpServer(new File("static"), 8088);
  251.     }
  252. }
RAW Paste Data
We use cookies for various purposes including analytics. By continuing to use Pastebin, you agree to our use of cookies as described in the Cookies Policy. OK, I Understand
 
Top