about summary refs log tree commit diff stats
path: root/src/loader/cgi.nim
diff options
context:
space:
mode:
authorbptato <nincsnevem662@gmail.com>2023-12-13 12:08:05 +0100
committerbptato <nincsnevem662@gmail.com>2023-12-13 12:56:28 +0100
commitab203acf554993d15e37604773f160c84b4d8252 (patch)
tree45428aa45bc751f788cc5c52c32b15bb8a2363f1 /src/loader/cgi.nim
parentbf761bcb6dcc5288a86aa5e8c2b67df3f0df056b (diff)
downloadchawan-ab203acf554993d15e37604773f160c84b4d8252.tar.gz
Move http out of main binary
Now it is (technically) no longer mandatory to link to libcurl.

Also, Chawan is at last completely protocol and network backend
agnostic :)

* Implement multipart requests in local CGI
* Implement simultaneous download of CGI data
* Add REQUEST_HEADERS env var with all headers
* cssparser: add a missing check in consumeEscape
Diffstat (limited to 'src/loader/cgi.nim')
-rw-r--r--src/loader/cgi.nim32
1 files changed, 15 insertions, 17 deletions
diff --git a/src/loader/cgi.nim b/src/loader/cgi.nim
index 89361a7c..8fe96274 100644
--- a/src/loader/cgi.nim
+++ b/src/loader/cgi.nim
@@ -10,6 +10,7 @@ import loader/connecterror
 import loader/headers
 import loader/loaderhandle
 import loader/request
+import types/formdata
 import types/opt
 import types/url
 import utils/twtstr
@@ -37,6 +38,10 @@ proc setupEnv(cmd, scriptName, pathInfo, requestURI: string, request: Request,
   putEnv("SCRIPT_FILENAME", cmd)
   putEnv("REQUEST_URI", requestURI)
   putEnv("REQUEST_METHOD", $request.httpmethod)
+  var headers = ""
+  for k, v in request.headers:
+    headers &= k & ": " & v & "\r\n"
+  putEnv("REQUEST_HEADERS", headers)
   if prevURL != nil:
     putMappedURL(prevURL)
   if pathInfo != "":
@@ -44,19 +49,17 @@ proc setupEnv(cmd, scriptName, pathInfo, requestURI: string, request: Request,
   if url.query.isSome:
     putEnv("QUERY_STRING", url.query.get)
   if request.httpmethod == HTTP_POST:
-    putEnv("CONTENT_TYPE", request.headers.getOrDefault("Content-Type", ""))
+    if request.multipart.isSome:
+      putEnv("CONTENT_TYPE", request.multipart.get.getContentType())
+    else:
+      putEnv("CONTENT_TYPE", request.headers.getOrDefault("Content-Type", ""))
     putEnv("CONTENT_LENGTH", $contentLen)
   if "Cookie" in request.headers:
     putEnv("HTTP_COOKIE", request.headers["Cookie"])
   if request.referer != nil:
     putEnv("HTTP_REFERER", $request.referer)
   if request.proxy != nil:
-    let s = $request.proxy
-    if request.proxy.scheme == "https" or request.proxy.scheme == "http":
-      putEnv("http_proxy", s)
-      putEnv("HTTP_PROXY", s)
-      putEnv("HTTPS_proxy", s)
-    putEnv("ALL_PROXY", s)
+    putEnv("ALL_PROXY", $request.proxy)
 
 type ControlResult = enum
   RESULT_CONTROL_DONE, RESULT_CONTROL_CONTINUE, RESULT_ERROR
@@ -184,9 +187,7 @@ proc loadCGI*(handle: LoaderHandle, request: Request, cgiDir: seq[string],
   if request.body.isSome:
     contentLen = request.body.get.len
   elif request.multipart.isSome:
-    #TODO multipart
-    # maybe use curl formdata? (the mime api has no serialization functions)
-    discard
+    contentLen = request.multipart.get.calcLength()
   let pid = fork()
   if pid == -1:
     t handle.sendResult(ERROR_FAIL_SETUP_CGI)
@@ -214,8 +215,9 @@ proc loadCGI*(handle: LoaderHandle, request: Request, cgiDir: seq[string],
       if request.body.isSome:
         ps.write(request.body.get)
       elif request.multipart.isSome:
-        #TODO
-        discard
+        let multipart = request.multipart.get
+        for entry in multipart.entries:
+          ps.writeEntry(entry, multipart.boundary)
       ps.close()
     let ps = newPosixStream(pipefd[0])
     let headers = newHeaders()
@@ -249,8 +251,4 @@ proc loadCGI*(handle: LoaderHandle, request: Request, cgiDir: seq[string],
           handle.handleLine(line, headers)
     t handle.sendStatus(status)
     t handle.sendHeaders(headers)
-    var buffer: array[4096, uint8]
-    while not ps.atEnd:
-      let n = ps.readData(addr buffer[0], buffer.len)
-      t handle.sendData(addr buffer[0], n)
-    ps.close()
+    handle.istream = ps