diff options
-rw-r--r-- | Makefile | 7 | ||||
-rw-r--r-- | context.d | 62 | ||||
-rw-r--r-- | serverutils.d | 17 |
3 files changed, 56 insertions, 30 deletions
@@ -1,5 +1,5 @@ TARGET=servd -PREQS=server.o serverutils.o context.o +PREQS=server.o context.o all: ${TARGET} @@ -8,3 +8,8 @@ ${TARGET}: ${PREQS} %.o: %.d dmd -c $< + +.PHONY: clean + +clean: + rm *.o servd @@ -3,26 +3,46 @@ import std.file, std.string, std.format, - std.stdio; -import - serverutils; + std.path; enum ClientState { START, REQUEST_LINE, - HEADER_LINES, + END_REQUEST, DONE, ERROR }; +enum ResponseCode { + OKAY = 200, + NOTFOUND = 404, + NOTIMPLEMENTED = 501 +}; + class Request { string method; string path; string vers; - char[][] header_lines; + string[] header_lines; auto this(char[] line) { line = strip(line); - formattedRead(line, "%s %s %s", &method, &path, &vers); + string tpath; + formattedRead(line, "%s %s %s", &method, &tpath, &vers); + if (tpath[0] == '/') + path = buildNormalizedPath(getcwd() ~ tpath); + else + path = buildNormalizedPath(getcwd() ~ "/" ~ tpath); + } + ResponseCode check() { + try { + bool isfile = path.isFile(); + if (!isfile) + return ResponseCode.NOTFOUND; + } + catch (FileException e) { + return ResponseCode.NOTFOUND; + } + return ResponseCode.OKAY; } } @@ -45,13 +65,31 @@ class ClientContext { state = ClientState.REQUEST_LINE; break; case ClientState.REQUEST_LINE: - state + char[255] line; + auto len = pair.receive(line); + if (len < 3) //FIXME: A better test needed for newline + state = ClientState.END_REQUEST; + else { + auto header_line = line[0 .. len]; + header_line = strip(line); + request.header_lines ~= cast(string) header_line; + } break; - case ClientState.HEADER_LINES: - if (inRoot(request.path)) - pair.send(readText(request.path)); - else - pair.send("ERROR: Client left root!\n"); + case ClientState.END_REQUEST: + switch (request.check()) { + case ResponseCode.OKAY: + pair.send(readText(request.path)); + break; + case ResponseCode.NOTFOUND: + pair.send("404 File Not Found"); + break; + case ResponseCode.NOTIMPLEMENTED: + pair.send("501 Method Not Implemented"); + break; + default: + pair.send("500 Internal Server Error"); + break; + } state = ClientState.DONE; break; case ClientState.DONE: diff --git a/serverutils.d b/serverutils.d deleted file mode 100644 index 43063ef..0000000 --- a/serverutils.d +++ /dev/null @@ -1,17 +0,0 @@ -bool inRoot(string path) { - auto level = 0; - if (path[0] == '/') return false; - while (path.length > 0) { - if (path[0] == '/') { - level++; - path = path[1..$]; - } else if (path[0] == '.' && path[1] == '.' && path[2] == '/') { - level--; - path = path[3..$]; - } else { - path = path[1..$]; - } - if (level < 0) return false; - } - return true; -} |