diff --git a/core/core.js b/core/core.js index c0e7fb38..b867f867 100644 --- a/core/core.js +++ b/core/core.js @@ -556,36 +556,6 @@ function startsWithBytes(data, bytes) { } } -async function staticDirectoryHandler(request, response, directory, uri) { - let filename = uri || 'index.html'; - if (filename.indexOf('..') != -1) { - response.writeHead(404, {"Content-Type": "text/plain; charset=utf-8", "Content-Length": "File not found".length}); - response.end("File not found"); - return; - } - - try { - let stat = await File.stat(directory + filename); - let id = `${stat.mtime}_${stat.size}`; - - if (request.headers['if-none-match'] === '"' + id + '"') { - response.writeHead(304, {'Content-Length': '0'}); - response.end(); - } else { - let data = await File.readFile(directory + filename); - response.writeHead(200, { - 'Content-Type': k_mime_types[filename.split('.').pop()] || 'text/plain', - 'Content-Length': data.byteLength, - 'etag': '"' + id + '"', - }); - response.end(data); - } - } catch { - response.writeHead(404, {"Content-Type": "text/plain; charset=utf-8", "Content-Length": "File not found".length}); - response.end("File not found"); - } -} - async function wellKnownHandler(request, response, path) { let data = await File.readFile("data/global/.well-known/" + path); if (data) { @@ -968,12 +938,6 @@ loadSettings().then(function() { return blobHandler(request, response, match[1], match[2]); } else if (match = /^\/([&\%][^\.]{44}(?:\.\w+)?)(\/?.*)/.exec(request.uri)) { return blobHandler(request, response, match[1], match[2]); - } else if (match = /^\/lit\/([\.\w-/]*)$/.exec(request.uri)) { - return staticDirectoryHandler(request, response, 'deps/lit/', match[1]); - } else if (match = /^\/codemirror\/([\.\w-/]*)$/.exec(request.uri)) { - return staticDirectoryHandler(request, response, 'deps/codemirror/', match[1]); - } else if (match = /^\/speedscope\/([\.\w-/]*)$/.exec(request.uri)) { - return staticDirectoryHandler(request, response, 'deps/speedscope/', match[1]); } else if (match = /^(.*)(\/(?:save|delete)?)$/.exec(request.uri)) { return blobHandler(request, response, match[1], match[2]); } else if ((match = /^\/.well-known\/(.*)/.exec(request.uri)) && request.uri.indexOf("..") == -1) { diff --git a/src/httpd.js.c b/src/httpd.js.c index a3c6ad9c..6e5b134e 100644 --- a/src/httpd.js.c +++ b/src/httpd.js.c @@ -517,7 +517,7 @@ static const char* _after(const char* text, const char* prefix) { return text + prefix_length; } - return text; + return NULL; } static double _time_spec_to_double(const uv_timespec_t* time_spec) @@ -628,28 +628,55 @@ static void _httpd_endpoint_static(tf_http_request_t* request) "w3.css", }; - tf_task_t* task = request->user_data; - const char* after = _after(request->path, "/static/"); - bool found = false; - for (int i = 0; i < tf_countof(k_static_files); i++) + const char* k_map[][2] = { - if (strcmp(after, k_static_files[i]) == 0) - { - found = true; - break; - } + { "/static/", "core/" }, + { "/lit/", "deps/lit/" }, + { "/codemirror/", "deps/codemirror/" }, + { "/speedscope/", "deps/speedscope/" }, + }; + + bool is_core = false; + const char* after = NULL; + const char* file_path = NULL; + for (int i = 0; i < tf_countof(k_map) && !after; i++) + { + after = _after(request->path, k_map[i][0]); + file_path = k_map[i][1]; + is_core = is_core || (after && i == 0); } - if (!found) + if (!after || strstr(after, "..")) { const char* k_payload = tf_http_status_text(404); tf_http_respond(request, 404, NULL, 0, k_payload, strlen(k_payload)); return; } - size_t size = strlen("core/") + strlen(after) + 1; + if (is_core) + { + bool found = false; + for (int i = 0; i < tf_countof(k_static_files); i++) + { + if (strcmp(after, k_static_files[i]) == 0) + { + found = true; + break; + } + } + + if (!found) + { + const char* k_payload = tf_http_status_text(404); + tf_http_respond(request, 404, NULL, 0, k_payload, strlen(k_payload)); + return; + } + } + + tf_task_t* task = request->user_data; + size_t size = strlen(file_path) + strlen(after) + 1; char* path = alloca(size); - snprintf(path, size, "core/%s", after); + snprintf(path, size, "%s%s", file_path, after); tf_http_request_ref(request); tf_file_stat(task, path, _httpd_endpoint_static_stat, request); } @@ -717,7 +744,11 @@ void tf_httpd_register(JSContext* context) tf_http_set_trace(http, tf_task_get_trace(task)); JS_SetOpaque(httpd, http); + tf_http_add_handler(http, "/codemirror/", _httpd_endpoint_static, NULL, task); + tf_http_add_handler(http, "/lit/", _httpd_endpoint_static, NULL, task); + tf_http_add_handler(http, "/speedscope/", _httpd_endpoint_static, NULL, task); tf_http_add_handler(http, "/static/", _httpd_endpoint_static, NULL, task); + tf_http_add_handler(http, "/robots.txt", _httpd_endpoint_robots_txt, NULL, NULL); tf_http_add_handler(http, "/debug", _httpd_endpoint_debug, NULL, task); tf_http_add_handler(http, "/disconnections", _httpd_endpoint_disconnections, NULL, task);