about summary refs log tree commit diff stats
path: root/src/loader
diff options
context:
space:
mode:
Diffstat (limited to 'src/loader')
-rw-r--r--src/loader/cgi.nim6
-rw-r--r--src/loader/file.nim6
-rw-r--r--src/loader/loader.nim24
3 files changed, 29 insertions, 7 deletions
diff --git a/src/loader/cgi.nim b/src/loader/cgi.nim
index d94a2243..b0341a59 100644
--- a/src/loader/cgi.nim
+++ b/src/loader/cgi.nim
@@ -54,7 +54,11 @@ proc loadCGI*(handle: LoaderHandle, request: Request, cgiDir: seq[string]) =
   if cgiDir.len == 0:
     discard handle.sendResult(ERROR_NO_CGI_DIR)
     return
-  let path = percentDecode(request.url.pathname)
+  var path = percentDecode(request.url.pathname)
+  if path.startsWith("/cgi-bin/"):
+    path.delete(0 .. "/cgi-bin/".high)
+  elif path.startsWith("/$LIB/"):
+    path.delete(0 .. "/$LIB/".high)
   if path == "" or request.url.hostname != "":
     discard handle.sendResult(ERROR_INVALID_CGI_PATH)
     return
diff --git a/src/loader/file.nim b/src/loader/file.nim
index 5d552e40..cdb7afc2 100644
--- a/src/loader/file.nim
+++ b/src/loader/file.nim
@@ -108,11 +108,7 @@ proc loadFile(handle: LoaderHandle, istream: Stream) =
       if n < bufferSize:
         break
 
-proc loadFilePath*(handle: LoaderHandle, url: URL) =
-  when defined(windows) or defined(OS2) or defined(DOS):
-    let path = url.path.serialize_unicode_dos()
-  else:
-    let path = url.path.serialize_unicode()
+proc loadFilePath*(handle: LoaderHandle, url: URL, path: string) =
   let istream = newFileStream(path, fmRead)
   if istream == nil:
     if dirExists(path):
diff --git a/src/loader/loader.nim b/src/loader/loader.nim
index a148b77b..1f313a64 100644
--- a/src/loader/loader.nim
+++ b/src/loader/loader.nim
@@ -103,6 +103,7 @@ type
     acceptProxy*: bool
     cgiDir*: seq[string]
     uriMethodMap*: URIMethodMap
+    w3mCGICompat*: bool
 
   FetchPromise* = Promise[JSResult[Response]]
 
@@ -114,6 +115,16 @@ proc addFd(ctx: LoaderContext, fd: int, flags: int) =
 
 const MaxRewrites = 2 # should be enough? TODO find out what w3m thinks
 
+func canRewriteForCGICompat(ctx: LoaderContext, path: string): bool =
+  if not ctx.config.w3mCGICompat:
+    return false
+  if path.startsWith("/cgi-bin/") or path.startsWith("/$LIB/"):
+    return true
+  for dir in ctx.config.cgiDir:
+    if path.startsWith(dir):
+      return true
+  return false
+
 proc loadResource(ctx: LoaderContext, request: Request, handle: LoaderHandle) =
   var redo = true
   var tries = 0
@@ -121,7 +132,15 @@ proc loadResource(ctx: LoaderContext, request: Request, handle: LoaderHandle) =
     redo = false
     case request.url.scheme
     of "file":
-      handle.loadFilePath(request.url)
+      let path = request.url.path.serialize_unicode()
+      if ctx.canRewriteForCGICompat(path):
+        let newURL = newURL("cgi-bin:" & path & request.url.search)
+        if newURL.isSome:
+          request.url = newURL.get
+          inc tries
+          redo = true
+          continue
+      handle.loadFilePath(request.url, path)
       handle.close()
     of "http", "https":
       let handleData = handle.loadHttp(ctx.curlm, request)
@@ -280,6 +299,9 @@ proc initLoaderContext(fd: cint, config: LoaderConfig): LoaderContext =
     discard sig
     gctx.exitLoader()
   ctx.addFd(int(ctx.ssock.sock.getFd()), CURL_WAIT_POLLIN)
+  for dir in ctx.config.cgiDir.mitems:
+    if dir.len > 0 and dir[^1] != '/':
+      dir &= '/'
   return ctx
 
 proc runFileLoader*(fd: cint, config: LoaderConfig) =