about summary refs log tree commit diff stats
path: root/src
diff options
context:
space:
mode:
authorbptato <nincsnevem662@gmail.com>2023-12-12 10:38:42 +0100
committerbptato <nincsnevem662@gmail.com>2023-12-12 19:37:14 +0100
commit4eb57c2b88325d3963c6671a6f27bd08fc07cb59 (patch)
tree06bec584dcaf017d94e570e6cffb394b75aca338 /src
parentf779f672e6aa28efe03733226465c73c1a7490ad (diff)
downloadchawan-4eb57c2b88325d3963c6671a6f27bd08fc07cb59.tar.gz
local CGI: add mapped URI env vars; move about: to adapters
* Add MAPPED_URI_* as environment variables when a request is coming
  from urimethodmap

It costs us compatibility with w3m, but it seems to be a massive
improvement over smuggling in the URL as a query string and then
writing an ad-hoc parser for every single urimethodmap script.

The variables are set for every urimethodmap request, to avoid
accidental leaking of global environment variables.

* Move about: to adapters (an obvious improvement over the previous
  solution)
Diffstat (limited to 'src')
-rw-r--r--src/config/config.nim1
-rw-r--r--src/loader/about.nim32
-rw-r--r--src/loader/cgi.nim19
-rw-r--r--src/loader/loader.nim11
4 files changed, 22 insertions, 41 deletions
diff --git a/src/config/config.nim b/src/config/config.nim
index 42ffafdd..db4af966 100644
--- a/src/config/config.nim
+++ b/src/config/config.nim
@@ -410,6 +410,7 @@ proc getMimeTypes*(config: Config): MimeTypes =
 const DefaultURIMethodMap = parseURIMethodMap("""
 finger:		cgi-bin:cha-finger?%s
 gemini:		cgi-bin:gmifetch?%s
+about:		cgi-bin:about
 """)
 
 proc getURIMethodMap*(config: Config): URIMethodMap =
diff --git a/src/loader/about.nim b/src/loader/about.nim
deleted file mode 100644
index 054cee89..00000000
--- a/src/loader/about.nim
+++ /dev/null
@@ -1,32 +0,0 @@
-import loader/connecterror
-import loader/headers
-import loader/loaderhandle
-import loader/request
-import types/url
-
-const chawan = staticRead"res/chawan.html"
-const license = staticRead"res/license.html"
-const HeaderTable = {
-  "Content-Type": "text/html"
-}
-
-proc loadAbout*(handle: LoaderHandle, request: Request) =
-  template t(body: untyped) =
-    if not body:
-      return
-  if request.url.pathname == "blank":
-    t handle.sendResult(0)
-    t handle.sendStatus(200) # ok
-    t handle.sendHeaders(newHeaders(HeaderTable))
-  elif request.url.pathname == "chawan":
-    t handle.sendResult(0)
-    t handle.sendStatus(200) # ok
-    t handle.sendHeaders(newHeaders(HeaderTable))
-    t handle.sendData(chawan)
-  elif request.url.pathname == "license":
-    t handle.sendResult(0)
-    t handle.sendStatus(200) # ok
-    t handle.sendHeaders(newHeaders(HeaderTable))
-    t handle.sendData(license)
-  else:
-    t handle.sendResult(ERROR_ABOUT_PAGE_NOT_FOUND)
diff --git a/src/loader/cgi.nim b/src/loader/cgi.nim
index b0341a59..592111c9 100644
--- a/src/loader/cgi.nim
+++ b/src/loader/cgi.nim
@@ -14,8 +14,17 @@ import types/opt
 import types/url
 import utils/twtstr
 
+proc putMappedURL(url: URL) =
+  putEnv("MAPPED_URI_SCHEME", url.scheme)
+  putEnv("MAPPED_URI_USERNAME", url.username)
+  putEnv("MAPPED_URI_PASSWORD", url.password)
+  putEnv("MAPPED_URI_HOST", url.hostname)
+  putEnv("MAPPED_URI_PORT", url.port)
+  putEnv("MAPPED_URI_PATH", url.path.serialize())
+  putEnv("MAPPED_URI_QUERY", url.query.get(""))
+
 proc setupEnv(cmd, scriptName, pathInfo, requestURI: string, request: Request,
-    contentLen: int) =
+    contentLen: int, prevURL: URL) =
   let url = request.url
   putEnv("SERVER_SOFTWARE", "Chawan")
   putEnv("SERVER_PROTOCOL", "HTTP/1.0")
@@ -28,6 +37,8 @@ proc setupEnv(cmd, scriptName, pathInfo, requestURI: string, request: Request,
   putEnv("SCRIPT_FILENAME", cmd)
   putEnv("REQUEST_URI", requestURI)
   putEnv("REQUEST_METHOD", $request.httpmethod)
+  if prevURL != nil:
+    putMappedURL(prevURL)
   if pathInfo != "":
     putEnv("PATH_INFO", pathInfo)
   if url.query.isSome:
@@ -47,7 +58,8 @@ proc setupEnv(cmd, scriptName, pathInfo, requestURI: string, request: Request,
       putEnv("HTTPS_proxy", s)
     putEnv("ALL_PROXY", s)
 
-proc loadCGI*(handle: LoaderHandle, request: Request, cgiDir: seq[string]) =
+proc loadCGI*(handle: LoaderHandle, request: Request, cgiDir: seq[string],
+    prevURL: URL) =
   template t(body: untyped) =
     if not body:
       return
@@ -127,7 +139,8 @@ proc loadCGI*(handle: LoaderHandle, request: Request, cgiDir: seq[string]) =
     else:
       closeStdin()
     # we leave stderr open, so it can be seen in the browser console
-    setupEnv(cmd, scriptName, pathInfo, requestURI, request, contentLen)
+    setupEnv(cmd, scriptName, pathInfo, requestURI, request, contentLen,
+      prevURL)
     discard execl(cstring(cmd), cstring(basename), nil)
     stdout.write("Content-Type: text/plain\r\n\r\nFailed to execute script.")
     quit(1)
diff --git a/src/loader/loader.nim b/src/loader/loader.nim
index 1f313a64..5fb49c07 100644
--- a/src/loader/loader.nim
+++ b/src/loader/loader.nim
@@ -28,7 +28,6 @@ import io/socketstream
 import io/urlfilter
 import js/error
 import js/javascript
-import loader/about
 import loader/cgi
 import loader/connecterror
 import loader/curlhandle
@@ -113,7 +112,8 @@ proc addFd(ctx: LoaderContext, fd: int, flags: int) =
     events: cast[cshort](flags)
   ))
 
-const MaxRewrites = 2 # should be enough? TODO find out what w3m thinks
+#TODO this may be too low if we want to use urimethodmap for everything
+const MaxRewrites = 4
 
 func canRewriteForCGICompat(ctx: LoaderContext, path: string): bool =
   if not ctx.config.w3mCGICompat:
@@ -128,6 +128,7 @@ func canRewriteForCGICompat(ctx: LoaderContext, path: string): bool =
 proc loadResource(ctx: LoaderContext, request: Request, handle: LoaderHandle) =
   var redo = true
   var tries = 0
+  var prevurl: URL = nil
   while redo and tries < MaxRewrites:
     redo = false
     case request.url.scheme
@@ -146,9 +147,6 @@ proc loadResource(ctx: LoaderContext, request: Request, handle: LoaderHandle) =
       let handleData = handle.loadHttp(ctx.curlm, request)
       if handleData != nil:
         ctx.handleList.add(handleData)
-    of "about":
-      handle.loadAbout(request)
-      handle.close()
     of "data":
       handle.loadData(request)
       handle.close()
@@ -161,9 +159,10 @@ proc loadResource(ctx: LoaderContext, request: Request, handle: LoaderHandle) =
       if handleData != nil:
         ctx.handleList.add(handleData)
     of "cgi-bin":
-      handle.loadCGI(request, ctx.config.cgiDir)
+      handle.loadCGI(request, ctx.config.cgiDir, prevurl)
       handle.close()
     else:
+      prevurl = request.url
       case ctx.config.urimethodmap.findAndRewrite(request.url)
       of URI_RESULT_SUCCESS:
         inc tries