about summary refs log tree commit diff stats
path: root/src/io/loader.nim
diff options
context:
space:
mode:
authorbptato <nincsnevem662@gmail.com>2022-09-12 00:30:21 +0200
committerbptato <nincsnevem662@gmail.com>2022-09-12 00:30:21 +0200
commit51ea622d58bfca19212fac1800cfb033bb85ec39 (patch)
treeb75891690f67b190c60584751f2a30c96f342fdc /src/io/loader.nim
parente38402dfa1bbc33db6b9d9736517eb45533d595c (diff)
downloadchawan-51ea622d58bfca19212fac1800cfb033bb85ec39.tar.gz
Add JS binding generation
Diffstat (limited to 'src/io/loader.nim')
-rw-r--r--src/io/loader.nim83
1 files changed, 38 insertions, 45 deletions
diff --git a/src/io/loader.nim b/src/io/loader.nim
index 31b51930..7c68258e 100644
--- a/src/io/loader.nim
+++ b/src/io/loader.nim
@@ -15,15 +15,16 @@ import options
 import streams
 import tables
 import net
-import os
 when defined(posix):
   import posix
 
 import bindings/curl
 import io/http
+import io/process
 import io/request
 import io/serialize
 import io/socketstream
+import types/mime
 import types/url
 import utils/twtstr
 
@@ -75,88 +76,80 @@ proc loadResource(loader: FileLoader, request: Request, ostream: Stream) =
     ostream.swrite(-1) # error
     ostream.flush()
 
-const SocketDirectory = "/tmp/cha/"
-const SocketPathPrefix = SocketDirectory & "cha_sock_"
-func getSocketPath(pid: Pid): string =
-  SocketPathPrefix & $pid
-
-proc runFileLoader(loader: FileLoader) =
+proc runFileLoader(loader: FileLoader, loadcb: proc()) =
   if curl_global_init(CURL_GLOBAL_ALL) != CURLE_OK:
     raise newException(Defect, "Failed to initialize libcurl.")
-  let path = getSocketPath(getpid())
-  discard unlink(cstring(path))
-  createDir(SocketDirectory)
-  let sock = newSocket(Domain.AF_UNIX, SockType.SOCK_STREAM, Protocol.IPPROTO_IP)
-  bindUnix(sock, path)
-  listen(sock)
-  stdout.write(char(0u8))
-  stdout.flushFile()
+  let ssock = initServerSocket(getpid())
+  # The server has been initialized, so the main process can resume execution.
+  loadcb()
   while true:
-    var sock2: Socket
-    sock.accept(sock2)
-    let istream = newSocketStream(sock2, nil)
-    let ostream = newSocketStream(nil, sock2)
+    let stream = ssock.acceptSocketStream()
     try:
-      let request = istream.readRequest()
+      let request = stream.readRequest()
       for k, v in loader.defaultHeaders.table:
         if k notin request.headers.table:
           request.headers.table[k] = v
-      loader.loadResource(request, ostream)
+      loader.loadResource(request, stream)
     except IOError:
       # End-of-file, quit.
       # TODO this should be EOFError
       break
-    close(sock2)
+    stream.close()
   curl_global_cleanup()
-  close(sock)
-  discard unlink(cstring(path))
+  ssock.close()
   quit(0)
 
 proc doRequest*(loader: FileLoader, request: Request): Response =
-  let sock = newSocket(Domain.AF_UNIX, SockType.SOCK_STREAM, Protocol.IPPROTO_IP)
-  let path = getSocketPath(loader.process)
-  connectUnix(sock, path)
-  let istream = newSocketStream(nil, sock)
-  let ostream = newSocketStream(sock, nil)
-  istream.swrite(request)
-  istream.flush()
-  ostream.sread(result.res)
+  let stream = connectSocketStream(loader.process)
+  stream.swrite(request)
+  stream.flush()
+  stream.sread(result.res)
   if result.res == 0:
-    ostream.sread(result.status)
-    ostream.sread(result.headers)
+    stream.sread(result.status)
+    stream.sread(result.headers)
     if "Content-Type" in result.headers.table:
       result.contenttype = result.headers.table["Content-Type"][0].until(';')
+    else:
+      result.contenttype = guessContentType($request.url)
     if "Location" in result.headers.table:
       let location = result.headers.table["Location"][0]
       result.redirect = parseUrl(location, some(request.url))
     # Only a stream of the response body may arrive after this point.
-    result.body = ostream
+    result.body = stream
 
 proc newFileLoader*(defaultHeaders: HeaderList): FileLoader =
   new(result)
   result.defaultHeaders = defaultHeaders
   when defined(posix):
-    var pipefd_b: array[0..1, cint]
-    if pipe(pipefd_b) == -1:
+    var pipefd: array[0..1, cint]
+    if pipe(pipefd) == -1:
       raise newException(Defect, "Failed to open pipe.")
     let pid = fork()
     if pid == -1:
       raise newException(Defect, "Failed to fork network process")
     elif pid == 0:
       # child process
-      let writefd = pipefd_b[1] # get write b
-      discard close(pipefd_b[0]) # close read b
-      discard dup2(writefd, stdout.getFileHandle())
-      result.runFileLoader()
+      discard close(pipefd[0]) # close read
+      var writef: File
+      if not open(writef, FileHandle(pipefd[1]), fmWrite):
+        raise newException(Defect, "Failed to open input handle.")
+      result.runFileLoader((proc() =
+        writef.write(char(0u8))
+        writef.flushFile()
+        close(writef)
+        discard close(pipefd[1])
+      ))
     else:
       result.process = pid
-      let readfd = pipefd_b[0] # get read b
-      discard close(pipefd_b[1]) # close write b
+      let readfd = pipefd[0] # get read
+      discard close(pipefd[1]) # close write
       var readf: File
       if not open(readf, FileHandle(readfd), fmRead):
         raise newException(Defect, "Failed to open output handle.")
-      var n: uint8
-      assert newFileStream(readf).readUint8() == 0u8
+      assert readf.readChar() == char(0u8)
+      close(readf)
+      discard close(pipefd[0])
+      
 
 proc newFileLoader*(): FileLoader =
   newFileLoader(DefaultHeaders)