diff options
| author | RblSb <msrblsb@gmail.com> | 2022-03-09 19:12:44 +0300 |
|---|---|---|
| committer | RblSb <msrblsb@gmail.com> | 2022-03-09 19:25:36 +0300 |
| commit | bb525795172fee119d8029addea4da173c3f9455 (patch) | |
| tree | 701dcda96a9383d02a7e1b617e61fb0e37007e95 | |
| parent | e48c2be14fb1474beb1993cd09e4f42aec51b1a8 (diff) | |
Improve url handling
| -rw-r--r-- | build/server.js | 35 | ||||
| -rw-r--r-- | src/server/HttpServer.hx | 36 | ||||
| -rw-r--r-- | test/tests/TestServer.hx | 11 |
3 files changed, 48 insertions, 34 deletions
diff --git a/build/server.js b/build/server.js index 15e5106..f1da10d 100644 --- a/build/server.js +++ b/build/server.js @@ -1,4 +1,3 @@ -// Generated by Haxe 4.2.2 (function ($global) { "use strict"; var $estr = function() { return js_Boot.__string_rec(this,''); },$hxEnums = $hxEnums || {},$_; function $extend(from, fields) { @@ -3690,18 +3689,21 @@ server_HttpServer.init = function(dir,customDir,allowLocalRequests) { server_HttpServer.allowLocalRequests = allowLocalRequests; }; server_HttpServer.serveFiles = function(req,res) { - var url = server_HttpServer.safeDecodeURI(req.url); - if(url == "/") { - url = "/index.html"; + var url; + try { + url = new js_node_url_URL(server_HttpServer.safeDecodeURI(req.url),"http://localhost"); + } catch( _g ) { + url = new js_node_url_URL("/","http://localhost"); } - var filePath = server_HttpServer.dir + url; + var filePath = server_HttpServer.getPath(server_HttpServer.dir,url); var ext = haxe_io_Path.extension(filePath).toLowerCase(); res.setHeader("Accept-Ranges","bytes"); res.setHeader("Content-Type",server_HttpServer.getMimeType(ext)); - if(server_HttpServer.allowLocalRequests && req.socket.remoteAddress == req.socket.localAddress || server_HttpServer.allowedLocalFiles.h[url]) { + if(server_HttpServer.allowLocalRequests && req.socket.remoteAddress == req.socket.localAddress || server_HttpServer.allowedLocalFiles.h[url.pathname]) { if(server_HttpServer.isMediaExtension(ext)) { - server_HttpServer.allowedLocalFiles.h[url] = true; - if(server_HttpServer.serveMedia(req,res,url)) { + server_HttpServer.allowedLocalFiles.h[url.pathname] = true; + var s = url.pathname; + if(server_HttpServer.serveMedia(req,res,decodeURIComponent(s.split("+").join(" ")))) { return; } } @@ -3712,19 +3714,16 @@ server_HttpServer.serveFiles = function(req,res) { res.end("Error getting the file: No access to " + rel + "."); return; } - if(StringTools.startsWith(url,"/proxy")) { + if(url.pathname == "/proxy") { if(!server_HttpServer.proxyUrl(req,res)) { res.end("Proxy error: " + req.url); } return; } if(server_HttpServer.hasCustomRes) { - var path = server_HttpServer.customDir + url; + var path = server_HttpServer.getPath(server_HttpServer.customDir,url); if(js_node_Fs.existsSync(path)) { filePath = path; - if(sys_FileSystem.isDirectory(filePath)) { - filePath = haxe_io_Path.addTrailingSlash(filePath) + "index.html"; - } } } if(server_HttpServer.isMediaExtension(ext)) { @@ -3743,6 +3742,14 @@ server_HttpServer.serveFiles = function(req,res) { res.end(data); }); }; +server_HttpServer.getPath = function(dir,url) { + var filePath = dir + url.pathname; + filePath = decodeURIComponent(filePath.split("+").join(" ")); + if(!sys_FileSystem.isDirectory(filePath)) { + return filePath; + } + return haxe_io_Path.addTrailingSlash(filePath) + "index.html"; +}; server_HttpServer.readFileError = function(err,res,filePath) { if(err.code == "ENOENT") { res.statusCode = 404; @@ -3753,7 +3760,6 @@ server_HttpServer.readFileError = function(err,res,filePath) { } }; server_HttpServer.serveMedia = function(req,res,filePath) { - filePath = decodeURIComponent(filePath.split("+").join(" ")); if(!js_node_Fs.existsSync(filePath)) { return false; } @@ -3863,6 +3869,7 @@ server_HttpServer.safeDecodeURI = function(data) { try { data = decodeURI(data); } catch( _g ) { + data = ""; } data = data.replace(server_HttpServer.ctrlCharacters.r,""); return data; diff --git a/src/server/HttpServer.hx b/src/server/HttpServer.hx index 7f257a4..2805770 100644 --- a/src/server/HttpServer.hx +++ b/src/server/HttpServer.hx @@ -50,19 +50,20 @@ class HttpServer { } public static function serveFiles(req:IncomingMessage, res:ServerResponse):Void { - var url = safeDecodeURI(req.url); - if (url == "/") url = "/index.html"; - var filePath = dir + url; + final url = try { + new URL(safeDecodeURI(req.url), "http://localhost"); + } catch (e) new URL("/", "http://localhost"); + var filePath = getPath(dir, url); final ext = Path.extension(filePath).toLowerCase(); res.setHeader("Accept-Ranges", "bytes"); res.setHeader("Content-Type", getMimeType(ext)); if (allowLocalRequests && req.socket.remoteAddress == req.socket.localAddress - || allowedLocalFiles[url]) { + || allowedLocalFiles[url.pathname]) { if (isMediaExtension(ext)) { - allowedLocalFiles[url] = true; - if (serveMedia(req, res, url)) return; + allowedLocalFiles[url.pathname] = true; + if (serveMedia(req, res, url.pathname.urlDecode())) return; } } @@ -73,19 +74,14 @@ class HttpServer { return; } - if (url.startsWith("/proxy")) { + if (url.pathname == "/proxy") { if (!proxyUrl(req, res)) res.end('Proxy error: ${req.url}'); return; } if (hasCustomRes) { - final path = customDir + url; - if (Fs.existsSync(path)) { - filePath = path; - if (FileSystem.isDirectory(filePath)) { - filePath = Path.addTrailingSlash(filePath) + "index.html"; - } - } + final path = getPath(customDir, url); + if (Fs.existsSync(path)) filePath = path; } if (isMediaExtension(ext)) { @@ -105,6 +101,13 @@ class HttpServer { }); } + static function getPath(dir:String, url:URL):String { + var filePath = dir + url.pathname; + filePath = filePath.urlDecode(); + if (!FileSystem.isDirectory(filePath)) return filePath; + return Path.addTrailingSlash(filePath) + "index.html"; + } + static function readFileError(err:Dynamic, res:ServerResponse, filePath:String):Void { if (err.code == "ENOENT") { res.statusCode = 404; @@ -117,7 +120,6 @@ class HttpServer { } static function serveMedia(req:IncomingMessage, res:ServerResponse, filePath:String):Bool { - filePath = filePath.urlDecode(); if (!Fs.existsSync(filePath)) return false; final videoSize = Fs.statSync(filePath).size; var range:String = req.headers["range"]; @@ -221,7 +223,9 @@ class HttpServer { static function safeDecodeURI(data:String):String { try { data = decodeURI(data); - } catch (err) {} + } catch (err) { + data = ""; + } data = ctrlCharacters.replace(data, ""); return data; } diff --git a/test/tests/TestServer.hx b/test/tests/TestServer.hx index 01d0c56..bbb1d9a 100644 --- a/test/tests/TestServer.hx +++ b/test/tests/TestServer.hx @@ -22,24 +22,27 @@ class TestServer extends Test { server.onServerInited = () -> { final url = 'http://${server.localIp}:${server.port}'; request('$url/你好,世界!@$^&*)_+-=', data -> { - Assert.equals("File 你好,世界!@$^&*)_+-= not found.", data); + Assert.equals("File 你好,世界!@$^&*)_ -= not found.", data); }); request('$url/Привет%00мир!', data -> { Assert.equals("File Приветмир! not found.", data); }); request('$url/Ы%ы%00ы!', data -> { - Assert.equals("File %D0%AB%%D1%8B%00%D1%8B! not found.", data); + Assert.equals("<!DOCTYPE html>", data.split("\n")[0]); }); request('$url/video/skins/default.php?dir_inc=/etc/passwd%00', data -> { - var line = "File video/skins/default.php?dir_inc=/etc/passwd not found."; + var line = "File video/skins/default.php not found."; if (Sys.systemName() == "Windows") line = line.replace("/", "\\"); Assert.equals(line, data); }); request('$url/%20', data -> { - Assert.equals("File not found.", data); + Assert.equals("<!DOCTYPE html>", data.split("\n")[0]); }); request('$url/build/../../server.js', data -> { Assert.equals("File server.js not found.", data); + }); + request('$url/?meh', data -> { + Assert.equals("<!DOCTYPE html>", data.split("\n")[0]); async.done(); }); } |
