HelloWebServer.java 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131
  1. package hello;
  2. import com.fasterxml.jackson.databind.ObjectMapper;
  3. import org.microhttp.EventLoop;
  4. import org.microhttp.Header;
  5. import org.microhttp.LogEntry;
  6. import org.microhttp.Logger;
  7. import org.microhttp.Options;
  8. import org.microhttp.Request;
  9. import org.microhttp.Response;
  10. import java.io.IOException;
  11. import java.nio.charset.StandardCharsets;
  12. import java.time.Duration;
  13. import java.time.Instant;
  14. import java.time.ZoneOffset;
  15. import java.time.format.DateTimeFormatter;
  16. import java.util.List;
  17. import java.util.function.Consumer;
  18. public class HelloWebServer {
  19. static final String MESSAGE = "Hello, World!";
  20. static final byte[] TEXT_BYTES = MESSAGE.getBytes(StandardCharsets.UTF_8);
  21. static final String SERVER = "microhttp";
  22. static final DateTimeFormatter DATE_FORMATTER = DateTimeFormatter.RFC_1123_DATE_TIME.withZone(ZoneOffset.UTC);
  23. static final ObjectMapper OBJECT_MAPPER = new ObjectMapper();
  24. final int port;
  25. volatile String date = DATE_FORMATTER.format(Instant.now());
  26. record JsonMessage(String message) {
  27. }
  28. HelloWebServer(int port) {
  29. this.port = port;
  30. }
  31. void start() throws IOException, InterruptedException {
  32. startUpdater();
  33. Options options = new Options()
  34. .withHost(null) // wildcard any-address binding
  35. .withPort(port)
  36. .withReuseAddr(true)
  37. .withReusePort(true)
  38. .withAcceptLength(8_192)
  39. .withMaxRequestSize(1_024 * 1_024)
  40. .withReadBufferSize(1_024 * 64)
  41. .withResolution(Duration.ofMillis(1_000))
  42. .withRequestTimeout(Duration.ofSeconds(90));
  43. EventLoop eventLoop = new EventLoop(options, new DisabledLogger(), this::handle);
  44. eventLoop.start();
  45. eventLoop.join();
  46. }
  47. void startUpdater() {
  48. Thread thread = new Thread(this::runDateUpdater);
  49. thread.setDaemon(true);
  50. thread.setPriority(Thread.MIN_PRIORITY);
  51. thread.start();
  52. }
  53. void runDateUpdater() {
  54. while (true) {
  55. try {
  56. Thread.sleep(1_000);
  57. } catch (InterruptedException e) {
  58. return;
  59. }
  60. date = DATE_FORMATTER.format(Instant.now());
  61. }
  62. }
  63. void handle(Request request, Consumer<Response> callback) {
  64. if (request.uri().equals("/plaintext")) {
  65. List<Header> headers = List.of(
  66. new Header("Content-Type", "text/plain"),
  67. new Header("Date", date),
  68. new Header("Server", SERVER));
  69. callback.accept(new Response(200, "OK", headers, TEXT_BYTES));
  70. } else if (request.uri().equals("/json")) {
  71. List<Header> headers = List.of(
  72. new Header("Content-Type", "application/json"),
  73. new Header("Date", date),
  74. new Header("Server", SERVER));
  75. callback.accept(new Response(200, "OK", headers, jsonBody()));
  76. } else {
  77. List<Header> headers = List.of(
  78. new Header("Date", date),
  79. new Header("Server", SERVER));
  80. callback.accept(new Response(404, "Not Found", headers, new byte[0]));
  81. }
  82. }
  83. static byte[] jsonBody() {
  84. try {
  85. return OBJECT_MAPPER.writeValueAsBytes(new JsonMessage(MESSAGE));
  86. } catch (IOException e) {
  87. throw new RuntimeException(e);
  88. }
  89. }
  90. public static void main(String[] args) throws IOException, InterruptedException {
  91. int port = args.length > 0
  92. ? Integer.parseInt(args[0])
  93. : 8080;
  94. new HelloWebServer(port).start();
  95. }
  96. static class DisabledLogger implements Logger {
  97. @Override
  98. public boolean enabled() {
  99. return false;
  100. }
  101. @Override
  102. public void log(LogEntry... logEntries) {
  103. }
  104. @Override
  105. public void log(Exception e, LogEntry... logEntries) {
  106. }
  107. }
  108. }