1 module webcaret.application; 2 3 import router; 4 import heaploop.networking.http; 5 import heaploop.networking.tcp : TcpStream; 6 import std.string : format; 7 import std.stdio : writeln; 8 9 package: 10 11 class AppHttpServerConnection : HttpServerConnection { 12 13 public: 14 this(TcpStream stream) { 15 super(stream); 16 } 17 18 protected: 19 override HttpRequest createIncomingMessage() { 20 return new ApplicationHttpRequest(this); 21 } 22 } 23 24 class AppHttpListener : HttpListener { 25 26 protected: 27 override HttpServerConnection createConnection(TcpStream stream) { 28 return new AppHttpServerConnection(stream); 29 } 30 } 31 32 public: 33 34 class ApplicationHttpRequest : HttpRequest, IRoutedRequest { 35 36 private: 37 string[string] _params; 38 string[string] _form; 39 40 package: 41 42 void prepareRequest() { 43 switch(this.contentType) { 44 default: 45 return; 46 case "application/x-www-form-urlencoded": { 47 ubyte[] formData; 48 this.read ^= (chunk) { 49 formData ~= chunk.buffer; 50 }; 51 string formText = cast(string)formData; 52 this.form = parseURLEncodedForm(formText); 53 break; 54 } 55 case "multipart/form-data": { 56 assert(false, "multipart/form-data is not implemented yet, pull requests are welcome :)"); 57 } 58 } 59 } 60 61 62 public: 63 @property { 64 string[string] params() nothrow { 65 return _params; 66 } 67 void params(string[string] params) nothrow { 68 _params = params; 69 } 70 string[string] form() nothrow { 71 return _form; 72 } 73 void form(string[string] form) nothrow { 74 _form = form; 75 } 76 } 77 this(HttpServerConnection connection) { 78 super(connection); 79 } 80 } 81 82 class Application { 83 private: 84 Router!(ApplicationHttpRequest, HttpResponse) _router; 85 86 public: 87 this() { 88 _router = new Router!(ApplicationHttpRequest, HttpResponse); 89 } 90 91 @property { 92 Router!(ApplicationHttpRequest, HttpResponse) router() nothrow { 93 return _router; 94 } 95 } 96 97 void serve(string address, int port) { 98 auto server = new AppHttpListener; 99 server.bind4(address, port); 100 "Web^ Application serving http://%s:%d".format(address, port).writeln; 101 server.listen ^^= (connection) { 102 debug writeln("HTTP Agent just connected"); 103 connection.process ^^= (request, response) { 104 auto appRequest = cast(ApplicationHttpRequest)request; 105 appRequest.prepareRequest(); 106 _router.execute(request.method, request.uri.path, appRequest, response); 107 }; 108 }; 109 } 110 } 111