about summary refs log tree commit diff stats
path: root/adapter
diff options
context:
space:
mode:
authorbptato <nincsnevem662@gmail.com>2023-12-13 15:00:34 +0100
committerbptato <nincsnevem662@gmail.com>2023-12-13 15:00:34 +0100
commit53bc47531543fe55997f4c6875fa03745a17e754 (patch)
treea7d3b3de2f68580a79415818bad84bf607e58c14 /adapter
parent4818cb28debf4601213707f6c1b9b22348b51fbc (diff)
downloadchawan-53bc47531543fe55997f4c6875fa03745a17e754.tar.gz
Various fixes
* Makefile: fix parallel build, add new binaries to install target
* twtstr: split out libunicode-related stuff to luwrap
* config: quote default gopher2html URL env var for unquote
* adapter/: get rid of types/url dependency, use CURL url in all cases
Diffstat (limited to 'adapter')
-rw-r--r--adapter/protocol/curlwrap.nim7
-rw-r--r--adapter/protocol/file.nim9
-rw-r--r--adapter/protocol/ftp.nim28
-rw-r--r--adapter/protocol/gopher.nim51
-rw-r--r--adapter/protocol/http.nim4
5 files changed, 62 insertions, 37 deletions
diff --git a/adapter/protocol/curlwrap.nim b/adapter/protocol/curlwrap.nim
index d5014b26..41ef5355 100644
--- a/adapter/protocol/curlwrap.nim
+++ b/adapter/protocol/curlwrap.nim
@@ -11,3 +11,10 @@ template getinfo*(curl: CURL, info: CURLINFO, arg: typed) =
 
 template set*(url: CURLU, part: CURLUPart, content: string, flags: cuint) =
   discard curl_url_set(url, part, cstring(content), flags)
+
+template get*(url: CURLU, part: CURLUPart, flags: cuint): cstring =
+  var outs: cstring
+  if curl_url_get(url, part, addr outs, flags) == CURLUE_OK:
+    outs
+  else:
+    nil
diff --git a/adapter/protocol/file.nim b/adapter/protocol/file.nim
index 168be58b..d05d558c 100644
--- a/adapter/protocol/file.nim
+++ b/adapter/protocol/file.nim
@@ -9,11 +9,11 @@ import dirlist
 import loader/connecterror
 import utils/twtstr
 
-proc loadDir(path: string) =
+proc loadDir(path, opath: string) =
   var path = path
   if path[^1] != '/': #TODO dos/windows
     path &= '/'
-  var base = getEnv("QUERY_STRING")
+  var base = "file://" & opath
   if base[^1] != '/': #TODO dos/windows
     base &= '/'
   stdout.write("Content-Type: text/html\n\n")
@@ -96,11 +96,12 @@ proc loadFile(istream: Stream) =
         break
 
 proc main() =
-  let path = percentDecode(getEnv("MAPPED_URI_PATH"))
+  let opath = getEnv("MAPPED_URI_PATH")
+  let path = percentDecode(opath)
   let istream = newFileStream(path, fmRead)
   if istream == nil:
     if dirExists(path):
-      loadDir(path)
+      loadDir(path, opath)
     elif symlinkExists(path):
       loadSymlink(path)
     else:
diff --git a/adapter/protocol/ftp.nim b/adapter/protocol/ftp.nim
index 7d072471..1a406743 100644
--- a/adapter/protocol/ftp.nim
+++ b/adapter/protocol/ftp.nim
@@ -9,7 +9,6 @@ import dirlist
 import bindings/curl
 import loader/connecterror
 import types/opt
-import types/url
 import utils/twtstr
 
 type FtpHandle = ref object
@@ -153,17 +152,27 @@ proc finish(op: FtpHandle) =
 proc main() =
   let curl = curl_easy_init()
   doAssert curl != nil
-  let surl = getEnv("QUERY_STRING")
   let opath = getEnv("MAPPED_URI_PATH")
   let path = percentDecode(opath)
+  let url = curl_url()
+  const flags = cuint(CURLU_PATH_AS_IS)
+  url.set(CURLUPART_SCHEME, getEnv("MAPPED_URI_SCHEME"), flags)
+  let username = getEnv("MAPPED_URI_USERNAME")
+  if username != "":
+    url.set(CURLUPART_USER, username, flags)
+  let password = getEnv("MAPPED_URI_PASSWORD")
+  if password != "":
+    url.set(CURLUPART_PASSWORD, password, flags)
+  url.set(CURLUPART_HOST, getEnv("MAPPED_URI_HOST"), flags)
+  let port = getEnv("MAPPED_URI_PORT")
+  if port != "":
+    url.set(CURLUPART_PORT, port, flags)
   # By default, cURL CWD's into relative paths, and an extra slash is
   # necessary to specify absolute paths.
   # This is incredibly confusing, and probably not what the user wanted.
   # So we work around it by adding the extra slash ourselves.
-  let hackurl = newURL(surl).get
-  hackurl.setPathname('/' & opath)
-  let csurl = hackurl.serialize()
-  curl.setopt(CURLOPT_URL, csurl)
+  url.set(CURLUPART_PATH, '/' & opath, flags)
+  curl.setopt(CURLOPT_CURLU, url)
   let dirmode = path.len > 0 and path[^1] == '/'
   let op = FtpHandle(
     curl: curl,
@@ -175,7 +184,12 @@ proc main() =
   curl.setopt(CURLOPT_WRITEFUNCTION, curlWriteBody)
   curl.setopt(CURLOPT_FTP_FILEMETHOD, CURLFTPMETHOD_SINGLECWD)
   if dirmode:
-    op.base = surl
+    const flags = cuint(CURLU_PUNY2IDN)
+    let surl = url.get(CURLUPART_URL, flags)
+    if surl == nil:
+      stdout.write("Cha-Control: ConnectionError " & $int(ERROR_INVALID_URL))
+      return
+    op.base = $surl
     op.path = path
   let purl = getEnv("ALL_PROXY")
   if purl != "":
diff --git a/adapter/protocol/gopher.nim b/adapter/protocol/gopher.nim
index 91875a1e..7ee7b625 100644
--- a/adapter/protocol/gopher.nim
+++ b/adapter/protocol/gopher.nim
@@ -1,5 +1,4 @@
 import std/envvars
-import std/options
 
 import curlwrap
 import curlerrors
@@ -8,8 +7,6 @@ import ../gophertypes
 
 import bindings/curl
 import loader/connecterror
-import types/opt
-import types/url
 import utils/twtstr
 
 type GopherHandle = ref object
@@ -63,35 +60,43 @@ proc main() =
   if getEnv("REQUEST_METHOD") != "GET":
     stdout.write("Cha-Control: ConnectionError " & $int(ERROR_INVALID_METHOD))
     return
-  var url = newURL(getEnv("QUERY_STRING")).get
-  var path = url.pathname
+  var path = getEnv("MAPPED_URI_PATH")
   if path.len < 1:
     path &= '/'
   if path.len < 2:
     path &= '1'
-    url = newURL(url)
-    url.setPathname(path)
+  let url = curl_url()
+  const flags = cuint(CURLU_PATH_AS_IS)
+  url.set(CURLUPART_SCHEME, getEnv("MAPPED_URI_SCHEME"), flags)
+  url.set(CURLUPART_HOST, getEnv("MAPPED_URI_HOST"), flags)
+  let port = getEnv("MAPPED_URI_PORT")
+  if port != "":
+    url.set(CURLUPART_PORT, port, flags)
+  url.set(CURLUPART_PATH, path, flags)
+  let query = getEnv("MAPPED_URI_QUERY")
+  if query != "":
+    url.set(CURLUPART_QUERY, query.after('='), flags)
   let op = GopherHandle(
     curl: curl,
     t: gopherType(path[1])
   )
-  if op.t == SEARCH:
-    if url.query.isNone:
-      op.loadSearch(url.serialize())
-      return
+  if op.t == SEARCH and query == "":
+    const flags = cuint(CURLU_PUNY2IDN)
+    let surl = url.get(CURLUPART_URL, flags)
+    if surl == nil:
+      stdout.write("Cha-Control: ConnectionError " & $int(ERROR_INVALID_URL))
     else:
-      url.query = some(url.query.get.after('='))
-  let surl = url.serialize()
-  #TODO avoid re-parsing
-  curl.setopt(CURLOPT_URL, surl)
-  curl.setopt(CURLOPT_WRITEDATA, op)
-  curl.setopt(CURLOPT_WRITEFUNCTION, curlWriteBody)
-  let proxy = getEnv("ALL_PROXY")
-  if proxy != "":
-    curl.setopt(CURLOPT_PROXY, proxy)
-  let res = curl_easy_perform(curl)
-  if res != CURLE_OK and not op.statusline:
-    stdout.write(getCurlConnectionError(res))
+      op.loadSearch($surl)
+  else:
+    curl.setopt(CURLOPT_CURLU, url)
+    curl.setopt(CURLOPT_WRITEDATA, op)
+    curl.setopt(CURLOPT_WRITEFUNCTION, curlWriteBody)
+    let proxy = getEnv("ALL_PROXY")
+    if proxy != "":
+      curl.setopt(CURLOPT_PROXY, proxy)
+    let res = curl_easy_perform(curl)
+    if res != CURLE_OK and not op.statusline:
+      stdout.write(getCurlConnectionError(res))
   curl_easy_cleanup(curl)
 
 main()
diff --git a/adapter/protocol/http.nim b/adapter/protocol/http.nim
index e59cac0a..45a78c46 100644
--- a/adapter/protocol/http.nim
+++ b/adapter/protocol/http.nim
@@ -1,12 +1,10 @@
 import std/envvars
-import std/options
 import std/strutils
 
 import curlerrors
 import curlwrap
 
 import bindings/curl
-import types/opt
 import utils/twtstr
 
 type
@@ -111,7 +109,7 @@ proc main() =
     curl.setopt(CURLOPT_HTTPGET, 1)
   of "POST":
     curl.setopt(CURLOPT_POST, 1)
-    let len = parseInt64(getEnv("CONTENT_LENGTH")).get
+    let len = parseInt(getEnv("CONTENT_LENGTH"))
     # > For any given platform/compiler curl_off_t must be typedef'ed to
     # a 64-bit
     # > wide signed integral data type. The width of this data type must remain