1 /*
2 * Geario - A cross-platform abstraction library with asynchronous I/O.
3 *
4 * Copyright (C) 2021-2022 Kerisy.com
5 *
6 * Website: https://www.kerisy.com
7 *
8 * Licensed under the Apache-2.0 License.
9 *
10 */
11
12 module http.HttpServer;
13
14 import geario.buffer.Bytes;
15
16 import geario.event;
17 import geario.logging;
18
19 import geario.net.TcpListener;
20 import geario.net.TcpStream;
21
22 import geario.codec.Framed;
23
24 import http.codec.HttpCodec;
25
26 import http.HttpRequest;
27 import http.HttpResponse;
28
29 class HttpServer
30 {
31 private
32 {
33 TcpListener _listener;
34 EventLoop _loop;
35 }
36
37 this()
38 {
39 _loop = new EventLoop();
40 _listener = new TcpListener(_loop);
41 }
42
43 void Listen(ushort port)
44 {
45 _listener.Bind(port);
46 _listener.Accepted((TcpListener sender, TcpStream connection) {
47 log.info("new connection from: %s", connection.RemoteAddress.toString());
48
49 auto codec = new HttpCodec();
50 auto framed = codec.CreateFramed(connection);
51
52 framed.OnFrame((HttpRequest request)
53 {
54 log.trace("content: %s", request.content);
55 HttpResponse response = new HttpResponse();
56 string path = request.uri;
57 if(path == "/plaintext")
58 {
59 response.headers["Content-Type"] = ["text/plain"];
60 response.content = cast(ubyte[])"Hello, World!".dup;
61 }
62
63 framed.Send(response);
64 });
65
66 connection.Disconnected(() {
67 log.info("client disconnected: %s", connection.RemoteAddress.toString());
68 }).Closed(() {
69 log.info("connection closed, local: %s, remote: %s",
70 connection.LocalAddress.toString(), connection.RemoteAddress.toString());
71 }).Error((IoError error) {
72 log.error("Error occurred: %d %s", error.errorCode, error.errorMsg);
73 });
74 });
75 }
76
77 void Start()
78 {
79 log.trace("Listening on: %s", _listener.BindingAddress.toString());
80
81 _listener.Start();
82 _loop.Run();
83 }
84 }