1 module handy_httpd.handlers;
2 
3 import std.stdio;
4 
5 import handy_httpd.handler;
6 import handy_httpd.request;
7 import handy_httpd.response;
8 import handy_httpd.responses;
9 
10 /** 
11  * Request handler that resolves files within a given base path.
12  */
13 class FileResolvingHandler : HttpRequestHandler {
14     import std.file;
15     import std.algorithm.searching;
16     import std.string;
17     import std.uni;
18 
19     private string basePath;
20 
21     this(string basePath = ".") {
22         this.basePath = basePath;
23     }
24 
25     HttpResponse handle(HttpRequest request) {
26         if (request.url.canFind("/../")) { // Forbid the use of navigating to parent directories.
27             return notFound();
28         }
29         string path = "index.html";
30         if (request.url != "/") {
31             path = request.url[1..$];
32         }
33         path = this.basePath ~ "/" ~ path;
34         if (!exists(path)) return notFound();
35         return fileResponse(path, getMimeType(path));
36     }
37 
38     private string getMimeType(string filename) {
39         string[string] MIME_TYPES = [
40             ".html": "text/html",
41             ".js": "text/javascript",
42             ".css": "text/css",
43             ".json": "application/json",
44             ".png": "image/png",
45             ".jpg": "image/jpg",
46             ".gif": "image/gif",
47             ".wav": "audio/wav",
48             ".ogg": "audio/ogg",
49             ".mp3": "audio/mpeg",
50             ".mp4": "video/mp4",
51             ".woff": "application/font-woff",
52             ".ttf": "application/font-ttf",
53             ".eot": "application/vnd.ms-fontobject",
54             ".otf": "application/font-otf",
55             ".svg": "application/image/svg+xml",
56             ".wasm": "application/wasm"
57         ];
58         auto p = filename.lastIndexOf('.');
59         if (p == -1) return "text/html";
60         string extension = filename[p..$].toLower();
61         if (extension !in MIME_TYPES) {
62             writefln!"Warning: Unknown mime type for file extension %s"(extension);
63             return "text/plain";
64         }
65         return MIME_TYPES[extension];
66     }
67 }