From 4fb244adc677ce2321f7863d5b166f718cff8aa2 Mon Sep 17 00:00:00 2001 From: nishi Date: Fri, 19 Apr 2024 14:09:20 +0000 Subject: [PATCH] http server works git-svn-id: file:///raid/svn-main/nishi-mandshurica/trunk@41 f982e544-4a7d-3444-ad1a-fde59a2a69f1 --- Mandshurica/file.c | 61 ++++++++++- Mandshurica/ms_util.h | 1 + Mandshurica/util.c | 59 +++++++++++ Module/http.c | 133 ++++++++++++++---------- Webroot/{index.html => index.html.tmpl} | 4 +- 5 files changed, 203 insertions(+), 55 deletions(-) rename Webroot/{index.html => index.html.tmpl} (78%) diff --git a/Mandshurica/file.c b/Mandshurica/file.c index 839f835..9a21d1f 100644 --- a/Mandshurica/file.c +++ b/Mandshurica/file.c @@ -30,6 +30,65 @@ #include "ms_file.h" +#include "ms_template.h" +#include "ms_util.h" + +#include +#include #include +#include +#include +#include + +char* get_mime(const char* _path) { + char* path = mandshurica_strdup(_path); + if(strlen(path) > 4 && memcmp(path + strlen(path) - 5, ".tmpl", 5) == 0) { + path[strlen(path) - 5] = 0; + } + int i; + for(i = strlen(path) - 1; i >= 0; i--) { + if(path[i] == '.') { + char* ext = path + i + 1; + char* typ = mandshurica_strdup("application/octet-stream"); + if(strcmp(ext, "gif") == 0) { + free(typ); + typ = mandshurica_strdup("image/gif"); + } else if(strcmp(ext, "html") == 0) { + free(typ); + typ = mandshurica_strdup("text/html"); + } + free(path); + return typ; + break; + } + } + free(path); + return mandshurica_strdup("application/octet-stream"); +} -char* mandshurica_load(const char* path, char** type, uint64_t* len) { return NULL; } +char* mandshurica_load(const char* path, char** type, uint64_t* len) { + bool tmpl = false; + if(strlen(path) > 4 && memcmp(path + strlen(path) - 5, ".tmpl", 5) == 0) { + tmpl = true; + } + FILE* f = fopen(path, "rb"); + if(f != NULL) { + struct stat s; + if(stat(path, &s) == 0) { + char* fdata = malloc(s.st_size + 1); + fread(fdata, s.st_size, 1, f); + fdata[s.st_size] = 0; + *type = get_mime(path); + if(tmpl) { + char* data = mandshurica_parse_template(fdata); + *len = strlen(data); + fclose(f); + return data; + } + *len = s.st_size; + return fdata; + } + fclose(f); + } + return NULL; +} diff --git a/Mandshurica/ms_util.h b/Mandshurica/ms_util.h index 808efeb..d06c737 100644 --- a/Mandshurica/ms_util.h +++ b/Mandshurica/ms_util.h @@ -36,6 +36,7 @@ char* mandshurica_strcat(const char* str1, const char* str2); char* mandshurica_strcat3(const char* str1, const char* str2, const char* str3); char* mandshurica_strdup(const char* str); +char* mandshurica_path(const char* path); bool mandshurica_strequ(const char* str1, const char* str2); bool mandshurica_strcaseequ(const char* str1, const char* str2); diff --git a/Mandshurica/util.c b/Mandshurica/util.c index 63321fb..36213bb 100644 --- a/Mandshurica/util.c +++ b/Mandshurica/util.c @@ -57,6 +57,65 @@ char* mandshurica_strdup(const char* str) { return r; } +char* mandshurica_path(const char* path) { + char* r = malloc(1); + r[0] = 0; + int i; + char cbuf[2]; + cbuf[1] = 0; + char* pbuf = malloc(1); + pbuf[0] = 0; + for(i = 0;; i++) { + cbuf[0] = path[i]; + if(path[i] == '/' || path[i] == 0) { + if(strcmp(pbuf, "..") == 0) { + int j; + int count = 1; + if(r[strlen(r) - 1] == '/') count = 2; + for(j = strlen(r) - 1; j >= 0; j--) { + if(r[j] == '/') { + r[j] = 0; + count--; + if(count == 0) break; + } + } + if(strlen(r) == 0) { + free(r); + r = mandshurica_strdup("/"); + } + } else { + char* tmp = r; + r = mandshurica_strcat(tmp, pbuf); + free(tmp); + } + + free(pbuf); + pbuf = malloc(1); + pbuf[0] = 0; + + if(path[i] == '/') { + for(; path[i] != 0 && path[i] == '/'; i++) + ; + + i--; + + char* tmp = r; + r = mandshurica_strcat(tmp, cbuf); + free(tmp); + } + + if(path[i] == 0) break; + } else { + char* tmp = pbuf; + pbuf = mandshurica_strcat(tmp, cbuf); + free(tmp); + } + } + free(pbuf); + if(r[strlen(r) - 1] == '/') r[strlen(r) - 1] = 0; + return r; +} + bool mandshurica_strequ(const char* str1, const char* str2) { if(strlen(str1) != strlen(str2)) return false; int i; diff --git a/Module/http.c b/Module/http.c index 8da4d83..e85eed2 100644 --- a/Module/http.c +++ b/Module/http.c @@ -41,6 +41,7 @@ #include #include #include +#include #include #include @@ -185,67 +186,93 @@ void http_handler(int sock) { if(count == 2) { if(strcmp(method, "GET") == 0) { char* chpath = mandshurica_strcat(webroot, path); - chdir(chpath); - free(chpath); - - char pth[PATH_MAX + 1]; - getcwd(pth, PATH_MAX); - - bool under = false; - if(pth[strlen(pth) - 1] != '/') { - pth[strlen(pth) + 1] = 0; - pth[strlen(pth)] = '/'; - } - if(strcmp(pth, webroot) == 0) { - under = true; - } else if(strlen(pth) >= strlen(webroot)) { - int j; - under = true; - for(j = 0; webroot[j] != 0; j++) { - if(webroot[j] != pth[j]) { - under = false; - break; + struct stat st2; + if(stat(chpath, &st2) != 0) { + send(sock, "HTTP/1.1 404 Not Found\r\n", 15 + 9, 0); + send(sock, "Connection: keep-alive\r\n", 24, 0); + send(sock, "Content-Length: 0\r\n", 19, 0); + send(sock, "\r\n", 2, 0); + } else { + char* pth = mandshurica_path(chpath); + free(chpath); + + bool under = false; + char* pth2 = mandshurica_strcat(pth, "/"); + if(strcmp(pth, webroot) == 0) { + under = true; + } else if(strcmp(pth2, webroot) == 0) { + under = true; + } else if(strlen(pth) >= strlen(webroot)) { + int j; + under = true; + for(j = 0; webroot[j] != 0; j++) { + if(webroot[j] != pth[j]) { + under = false; + break; + } } } - } - - if(under) { - char* s = mandshurica_strcat(pth, "/index.html"); - - char* type; - uint64_t len; - char* data = config->mandshurica_load(s, &type, &len); - if(data != NULL) { - send(sock, "HTTP/1.1 200 OK\r\n", 8 + 9, 0); - send(sock, "Connection: keep-alive\r\n", 24, 0); - send(sock, "\r\n", 2, 0); - send(sock, "Content-Type: ", 14, 0); - send(sock, type, strlen(type), 0); - send(sock, "\r\n", 2, 0); - send(sock, "Content-Length: ", 16, 0); - - char* lenstr = malloc(513); - sprintf(lenstr, "%llu", len); - send(sock, lenstr, strlen(lenstr), 0); - free(lenstr); + free(pth2); + + if(under) { + char* type; + uint64_t len; + char* data = NULL; + char* s; + + struct stat st; + if(stat(pth, &st) == 0) { + if(S_ISDIR(st.st_mode)) { + if(data == NULL) { + s = mandshurica_strcat(pth, "/index.html.tmpl"); + data = config->mandshurica_load(s, &type, &len); + free(s); + } + if(data == NULL) { + s = mandshurica_strcat(pth, "/index.html"); + data = config->mandshurica_load(s, &type, &len); + free(s); + } + } else { + data = config->mandshurica_load(pth, &type, &len); + } - send(sock, "\r\n", 2, 0); - send(sock, "\r\n", 2, 0); - send(sock, data, len, 0); - free(type); + if(data != NULL) { + send(sock, "HTTP/1.1 200 OK\r\n", 8 + 9, 0); + send(sock, "Connection: keep-alive\r\n", 24, 0); + send(sock, "Content-Type: ", 14, 0); + send(sock, type, strlen(type), 0); + send(sock, "\r\n", 2, 0); + send(sock, "Content-Length: ", 16, 0); + + char* lenstr = malloc(513); + sprintf(lenstr, "%llu", len); + send(sock, lenstr, strlen(lenstr), 0); + free(lenstr); + + send(sock, "\r\n", 2, 0); + send(sock, "\r\n", 2, 0); + send(sock, data, len, 0); + free(type); + } else { + send(sock, "HTTP/1.1 404 Not Found\r\n", 15 + 9, 0); + send(sock, "Connection: keep-alive\r\n", 24, 0); + send(sock, "Content-Length: 0\r\n", 19, 0); + send(sock, "\r\n", 2, 0); + } + } else { + send(sock, "HTTP/1.1 500 Internal Server Error\r\n", 15 + 9 + 12, 0); + send(sock, "Connection: keep-alive\r\n", 24, 0); + send(sock, "Content-Length: 0\r\n", 19, 0); + send(sock, "\r\n", 2, 0); + } } else { - send(sock, "HTTP/1.1 404 Not Found\r\n", 15 + 9, 0); + send(sock, "HTTP/1.1 400 Bad Request\r\n", 17 + 9, 0); send(sock, "Connection: keep-alive\r\n", 24, 0); send(sock, "Content-Length: 0\r\n", 19, 0); send(sock, "\r\n", 2, 0); } - - free(s); - } else { - send(sock, "HTTP/1.1 400 Bad Request\r\n", 17 + 9, 0); - send(sock, "Connection: keep-alive\r\n", 24, 0); - send(sock, "Content-Length: 0\r\n", 19, 0); - send(sock, "\r\n", 2, 0); + free(pth); } goto reset; diff --git a/Webroot/index.html b/Webroot/index.html.tmpl similarity index 78% rename from Webroot/index.html rename to Webroot/index.html.tmpl index cd4c8c8..cc83226 100644 --- a/Webroot/index.html +++ b/Webroot/index.html.tmpl @@ -1,5 +1,7 @@ -* TMPL * + -- 2.43.0