about summary refs log tree commit diff stats
path: root/src/io/loaderhandle.nim
diff options
context:
space:
mode:
authorbptato <nincsnevem662@gmail.com>2023-08-13 17:42:34 +0200
committerbptato <nincsnevem662@gmail.com>2023-08-13 17:54:05 +0200
commitd526deb99e44f2a8d1a9c3eea60676703dd64302 (patch)
treef63689ff7654d14ad9bca182a837b3155b2471a0 /src/io/loaderhandle.nim
parentf92e30232252deb194596e7c298cc7fcf56517cb (diff)
downloadchawan-d526deb99e44f2a8d1a9c3eea60676703dd64302.tar.gz
Add mailcap, mime.types & misc refactorings
* add mailcap: works with copiousoutput, needsterminal, etc.
* add mime.types (only works with mailcap)
* refactor pipeBuffer
* remove "dispatcher"
* fix bug in directory display where baseurl would not be used
Diffstat (limited to 'src/io/loaderhandle.nim')
-rw-r--r--src/io/loaderhandle.nim73
1 files changed, 73 insertions, 0 deletions
diff --git a/src/io/loaderhandle.nim b/src/io/loaderhandle.nim
new file mode 100644
index 00000000..077b1a2a
--- /dev/null
+++ b/src/io/loaderhandle.nim
@@ -0,0 +1,73 @@
+import net
+import streams
+
+import io/posixstream
+import io/headers
+import ips/serialize
+import ips/socketstream
+
+type LoaderHandle* = ref object
+  ostream: Stream
+  # Only the first handle can be redirected, because a) mailcap can only
+  # redirect the first handle and b) async redirects would result in race
+  # conditions that would be difficult to untangle.
+  canredir: bool
+  sostream: Stream # saved ostream when redirected
+
+# Create a new loader handle, with the output stream ostream.
+proc newLoaderHandle*(ostream: Stream, canredir: bool): LoaderHandle =
+  return LoaderHandle(ostream: ostream, canredir: canredir)
+
+proc getFd*(handle: LoaderHandle): int =
+  return int(SocketStream(handle.ostream).source.getFd())
+
+proc sendResult*(handle: LoaderHandle, res: int): bool =
+  try:
+    handle.ostream.swrite(res)
+    return true
+  except IOError: # broken pipe
+    return false
+
+proc sendStatus*(handle: LoaderHandle, status: int): bool =
+  try:
+    handle.ostream.swrite(status)
+    return true
+  except IOError: # broken pipe
+    return false
+
+proc sendHeaders*(handle: LoaderHandle, headers: Headers): bool =
+  try:
+    handle.ostream.swrite(headers)
+    if handle.canredir:
+      var redir: bool
+      handle.ostream.sread(redir)
+      if redir:
+        let fd = SocketStream(handle.ostream).recvFileHandle()
+        handle.sostream = handle.ostream
+        let stream = newPosixStream(fd)
+        handle.ostream = stream
+    return true
+  except IOError: # broken pipe
+    return false
+
+proc sendData*(handle: LoaderHandle, p: pointer, nmemb: int): bool =
+  try:
+    handle.ostream.writeData(p, nmemb)
+    return true
+  except IOError: # broken pipe
+    return false
+
+proc sendData*(handle: LoaderHandle, s: string): bool =
+  if s.len > 0:
+    return handle.sendData(unsafeAddr s[0], s.len)
+  return true
+
+proc close*(handle: LoaderHandle) =
+  if handle.sostream != nil:
+    try:
+      handle.sostream.swrite(true)
+    except IOError:
+      # ignore error, that just means the buffer has already closed the stream
+      discard
+    handle.sostream.close()
+  handle.ostream.close()