about summary refs log tree commit diff stats
diff options
context:
space:
mode:
-rw-r--r--Makefile9
-rw-r--r--adapter/protocol/file.nim (renamed from src/loader/file.nim)68
-rw-r--r--src/config/config.nim3
-rw-r--r--src/loader/cgi.nim1
-rw-r--r--src/loader/loader.nim9
5 files changed, 39 insertions, 51 deletions
diff --git a/Makefile b/Makefile
index 87b117ed..55b91fb8 100644
--- a/Makefile
+++ b/Makefile
@@ -41,7 +41,7 @@ endif
 FLAGS += --nimcache:"$(OBJDIR)/$(TARGET)"
 
 .PHONY: all
-all: $(OUTDIR_BIN)/cha $(OUTDIR_LIBEXEC)/gopher2html $(OUTDIR_CGI_BIN)/gmifetch $(OUTDIR_LIBEXEC)/gmi2html $(OUTDIR_CGI_BIN)/cha-finger $(OUTDIR_CGI_BIN)/about $(OUTDIR_CGI_BIN)/data
+all: $(OUTDIR_BIN)/cha $(OUTDIR_LIBEXEC)/gopher2html $(OUTDIR_CGI_BIN)/gmifetch $(OUTDIR_LIBEXEC)/gmi2html $(OUTDIR_CGI_BIN)/cha-finger $(OUTDIR_CGI_BIN)/about $(OUTDIR_CGI_BIN)/data $(OUTDIR_CGI_BIN)/file
 
 $(OUTDIR_BIN)/cha: lib/libquickjs.a src/*.nim src/**/*.nim res/* res/**/*
 	@mkdir -p "$(OUTDIR)/$(TARGET)/bin"
@@ -49,7 +49,7 @@ $(OUTDIR_BIN)/cha: lib/libquickjs.a src/*.nim src/**/*.nim res/* res/**/*
 		$(FLAGS) -o:"$(OUTDIR_BIN)/cha" src/main.nim
 	ln -sf "$(OUTDIR)/$(TARGET)/bin/cha" cha
 
-$(OUTDIR_LIBEXEC)/gopher2html: adapter/format/gopher2html.nim
+$(OUTDIR_LIBEXEC)/gopher2html: adapter/format/gopher2html.nim src/utils/twtstr.nim
 	$(NIMC) $(FLAGS) -o:"$(OUTDIR_LIBEXEC)/gopher2html" \
 		adapter/format/gopher2html.nim
 
@@ -68,9 +68,12 @@ $(OUTDIR_CGI_BIN)/cha-finger: adapter/protocol/cha-finger
 $(OUTDIR_CGI_BIN)/about: adapter/protocol/about.nim
 	$(NIMC) $(FLAGS) -o:"$(OUTDIR_CGI_BIN)/about" adapter/protocol/about.nim
 
-$(OUTDIR_CGI_BIN)/data: adapter/protocol/data.nim
+$(OUTDIR_CGI_BIN)/data: adapter/protocol/data.nim src/utils/twtstr.nim
 	$(NIMC) $(FLAGS) -o:"$(OUTDIR_CGI_BIN)/data" adapter/protocol/data.nim
 
+$(OUTDIR_CGI_BIN)/file: adapter/protocol/file.nim src/loader/dirlist.nim src/utils/twtstr.nim
+	$(NIMC) $(FLAGS) -o:"$(OUTDIR_CGI_BIN)/file" adapter/protocol/file.nim
+
 CFLAGS = -g -Wall -O2 -DCONFIG_VERSION=\"$(shell cat lib/quickjs/VERSION)\"
 QJSOBJ = $(OBJDIR)/quickjs
 
diff --git a/src/loader/file.nim b/adapter/protocol/file.nim
index cdb7afc2..f3ffa93e 100644
--- a/src/loader/file.nim
+++ b/adapter/protocol/file.nim
@@ -1,28 +1,22 @@
-import algorithm
-import os
-import streams
-import times
+import std/algorithm
+import std/os
+import std/streams
+import std/times
+import std/envvars
 
 import loader/connecterror
 import loader/dirlist
-import loader/headers
-import loader/loaderhandle
-import types/url
+import utils/twtstr
 
-proc loadDir(handle: LoaderHandle, url: URL, path: string) =
-  template t(body: untyped) =
-    if not body:
-      return
+proc loadDir(path: string) =
   var path = path
   if path[^1] != '/': #TODO dos/windows
     path &= '/'
-  var base = $url
+  var base = getEnv("QUERY_STRING")
   if base[^1] != '/': #TODO dos/windows
     base &= '/'
-  t handle.sendResult(0)
-  t handle.sendStatus(200) # ok
-  t handle.sendHeaders(newHeaders({"Content-Type": "text/html"}))
-  t handle.sendData("""
+  stdout.write("Content-Type: text/html\n\n")
+  stdout.write("""
 <HTML>
 <HEAD>
 <BASE HREF="""" & base & """">
@@ -69,18 +63,13 @@ proc loadDir(handle: LoaderHandle, url: URL, path: string) =
         modified: modified,
         linkto: target
       ))
-  t handle.sendData(makeDirlist(items))
-  t handle.sendData("\n</PRE>\n</BODY>\n</HTML>\n")
+  stdout.write(makeDirlist(items))
+  stdout.write("\n</PRE>\n</BODY>\n</HTML>\n")
 
-proc loadSymlink(handle: LoaderHandle, path: string) =
-  template t(body: untyped) =
-    if not body:
-      return
-  t handle.sendResult(0)
-  t handle.sendStatus(200) # ok
-  t handle.sendHeaders(newHeaders({"Content-Type": "text/html"}))
+proc loadSymlink(path: string) =
+  stdout.write("Content-Type: text/html\n\n")
   let sl = expandSymlink(path)
-  t handle.sendData("""
+  stdout.write("""
 <HTML>
 <HEAD>
 <TITLE>Symlink view<TITLE>
@@ -90,13 +79,10 @@ Symbolic link to <A HREF="""" & sl & """">""" & sl & """</A></br>
 </BODY>
 </HTML>""")
 
-proc loadFile(handle: LoaderHandle, istream: Stream) =
-  template t(body: untyped) =
-    if not body:
-      return
-  t handle.sendResult(0)
-  t handle.sendStatus(200) # ok
-  t handle.sendHeaders(newHeaders())
+proc loadFile(istream: Stream) =
+  # No headers, we'll let the browser figure out the file type.
+  stdout.write("\n")
+  let outs = newFileStream(stdout)
   while not istream.atEnd:
     const bufferSize = 4096
     var buffer {.noinit.}: array[bufferSize, char]
@@ -104,18 +90,22 @@ proc loadFile(handle: LoaderHandle, istream: Stream) =
       let n = readData(istream, addr buffer[0], bufferSize)
       if n == 0:
         break
-      t handle.sendData(addr buffer[0], n)
+      outs.writeData(addr buffer[0], n)
       if n < bufferSize:
         break
 
-proc loadFilePath*(handle: LoaderHandle, url: URL, path: string) =
+proc main() =
+  let path = percentDecode(getEnv("MAPPED_URI_PATH"))
   let istream = newFileStream(path, fmRead)
   if istream == nil:
     if dirExists(path):
-      handle.loadDir(url, path)
+      loadDir(path)
     elif symlinkExists(path):
-      handle.loadSymlink(path)
+      loadSymlink(path)
     else:
-      discard handle.sendResult(ERROR_FILE_NOT_FOUND)
+      let code = int(ERROR_FILE_NOT_FOUND)
+      stdout.write("Cha-Control: ConnectionError " & $code)
   else:
-    handle.loadFile(istream)
+    loadFile(istream)
+
+main()
diff --git a/src/config/config.nim b/src/config/config.nim
index 3a14377f..269c37d5 100644
--- a/src/config/config.nim
+++ b/src/config/config.nim
@@ -408,10 +408,11 @@ proc getMimeTypes*(config: Config): MimeTypes =
   return mimeTypes
 
 const DefaultURIMethodMap = parseURIMethodMap("""
-finger:		cgi-bin:cha-finger?%s
+finger:		cgi-bin:cha-finger
 gemini:		cgi-bin:gmifetch?%s
 about:		cgi-bin:about
 data:		cgi-bin:data
+file:		cgi-bin:file?%s
 """)
 
 proc getURIMethodMap*(config: Config): URIMethodMap =
diff --git a/src/loader/cgi.nim b/src/loader/cgi.nim
index 659047da..dbdce99c 100644
--- a/src/loader/cgi.nim
+++ b/src/loader/cgi.nim
@@ -215,7 +215,6 @@ proc loadCGI*(handle: LoaderHandle, request: Request, cgiDir: seq[string],
         #TODO
         discard
       ps.close()
-    discard handle.sendResult(0) # success
     let ps = newPosixStream(pipefd[0])
     let headers = newHeaders()
     var status = 200
diff --git a/src/loader/loader.nim b/src/loader/loader.nim
index b6250098..28029160 100644
--- a/src/loader/loader.nim
+++ b/src/loader/loader.nim
@@ -31,7 +31,6 @@ import js/javascript
 import loader/cgi
 import loader/connecterror
 import loader/curlhandle
-import loader/file
 import loader/ftp
 import loader/gopher
 import loader/headers
@@ -115,8 +114,6 @@ proc addFd(ctx: LoaderContext, fd: int, flags: int) =
 const MaxRewrites = 4
 
 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:
@@ -130,8 +127,7 @@ proc loadResource(ctx: LoaderContext, request: Request, handle: LoaderHandle) =
   var prevurl: URL = nil
   while redo and tries < MaxRewrites:
     redo = false
-    case request.url.scheme
-    of "file":
+    if ctx.config.w3mCGICompat and request.url.scheme == "file":
       let path = request.url.path.serialize_unicode()
       if ctx.canRewriteForCGICompat(path):
         let newURL = newURL("cgi-bin:" & path & request.url.search)
@@ -140,8 +136,7 @@ proc loadResource(ctx: LoaderContext, request: Request, handle: LoaderHandle) =
           inc tries
           redo = true
           continue
-      handle.loadFilePath(request.url, path)
-      handle.close()
+    case request.url.scheme
     of "http", "https":
       let handleData = handle.loadHttp(ctx.curlm, request)
       if handleData != nil: