about summary refs log tree commit diff stats
path: root/src/loader
diff options
context:
space:
mode:
authorbptato <nincsnevem662@gmail.com>2024-09-01 01:03:50 +0200
committerbptato <nincsnevem662@gmail.com>2024-09-01 01:46:38 +0200
commit55cfd29e961488a8c1ed9eb7801d237d27bc86c7 (patch)
treec74569e15ca72d777eadcfd19a0203cbb76c3e3f /src/loader
parente9466c4c436f964b53034e28356aa3f5c957a068 (diff)
downloadchawan-55cfd29e961488a8c1ed9eb7801d237d27bc86c7.tar.gz
canvas: move to separate CGI script
* stream: and passFd is now client-based, and accessible for buffers
* Bitmap's width & height is now int, not uint64
* no more non-network Bitmap special case in the pager for canvas

I just shoehorned it into the static image model, so it still doesn't
render changes after page load. But at least now it doesn't crash the
browser.
Diffstat (limited to 'src/loader')
-rw-r--r--src/loader/loader.nim24
-rw-r--r--src/loader/response.nim42
2 files changed, 13 insertions, 53 deletions
diff --git a/src/loader/loader.nim b/src/loader/loader.nim
index c40c3cad..e3c36b01 100644
--- a/src/loader/loader.nim
+++ b/src/loader/loader.nim
@@ -108,7 +108,10 @@ type
   ClientData = ref object
     pid: int
     key: ClientKey
+    # List of cached resources.
     cacheMap: seq[CachedItem]
+    # List of file descriptors passed by the client.
+    passedFdMap: Table[string, FileHandle] # host -> fd
     config: LoaderClientConfig
 
   LoaderContext = ref object
@@ -119,8 +122,6 @@ type
     handleMap: Table[int, LoaderHandle]
     outputMap: Table[int, OutputHandle]
     selector: Selector[int]
-    # List of file descriptors passed by the pager.
-    passedFdMap: Table[string, FileHandle] # host -> fd
     # List of existing clients (buffer or pager) that may make requests.
     clientData: Table[int, ClientData] # pid -> data
     # ID of next output. TODO: find a better allocation scheme
@@ -356,8 +357,9 @@ proc loadStreamRegular(ctx: LoaderContext; handle, cachedHandle: LoaderHandle) =
   handle.outputs.setLen(0)
   handle.iclose()
 
-proc loadStream(ctx: LoaderContext; handle: LoaderHandle; request: Request) =
-  ctx.passedFdMap.withValue(request.url.pathname, fdp):
+proc loadStream(ctx: LoaderContext; client: ClientData; handle: LoaderHandle;
+    request: Request) =
+  client.passedFdMap.withValue(request.url.pathname, fdp):
     handle.sendResult(0)
     handle.sendStatus(200)
     handle.sendHeaders(newHeaders())
@@ -365,7 +367,7 @@ proc loadStream(ctx: LoaderContext; handle: LoaderHandle; request: Request) =
     var stats: Stat
     doAssert fstat(fdp[], stats) != -1
     handle.istream = ps
-    ctx.passedFdMap.del(request.url.pathname)
+    client.passedFdMap.del(request.url.pathname)
     if S_ISCHR(stats.st_mode) or S_ISREG(stats.st_mode):
       # regular file: e.g. cha <file
       # or character device: e.g. cha </dev/null
@@ -493,7 +495,7 @@ proc loadResource(ctx: LoaderContext; client: ClientData;
         assert ostream == nil
         handle.close()
     elif request.url.scheme == "stream":
-      ctx.loadStream(handle, request)
+      ctx.loadStream(client, handle, request)
       if handle.istream != nil:
         ctx.addFd(handle)
       else:
@@ -658,11 +660,12 @@ proc shareCachedItem(ctx: LoaderContext; stream: SocketStream;
   targetClient.cacheMap.add(item)
   stream.sclose()
 
-proc passFd(ctx: LoaderContext; stream: SocketStream; r: var BufferedReader) =
+proc passFd(ctx: LoaderContext; stream: SocketStream; client: ClientData;
+    r: var BufferedReader) =
   var id: string
   r.sread(id)
   let fd = stream.recvFileHandle()
-  ctx.passedFdMap[id] = fd
+  client.passedFdMap[id] = fd
   stream.sclose()
 
 proc removeCachedItem(ctx: LoaderContext; stream: SocketStream;
@@ -764,9 +767,6 @@ proc acceptConnection(ctx: LoaderContext) =
       of lcShareCachedItem:
         privileged_command
         ctx.shareCachedItem(stream, r)
-      of lcPassFd:
-        privileged_command
-        ctx.passFd(stream, r)
       of lcRedirectToFile:
         privileged_command
         ctx.redirectToFile(stream, r)
@@ -780,6 +780,8 @@ proc acceptConnection(ctx: LoaderContext) =
         ctx.addCacheFile(stream, client, r)
       of lcRemoveCachedItem:
         ctx.removeCachedItem(stream, client, r)
+      of lcPassFd:
+        ctx.passFd(stream, client, r)
       of lcLoad:
         ctx.load(stream, client, r)
       of lcTee:
diff --git a/src/loader/response.nim b/src/loader/response.nim
index d41f62eb..1d7307cd 100644
--- a/src/loader/response.nim
+++ b/src/loader/response.nim
@@ -3,7 +3,6 @@ import std/tables
 
 import chagashi/charset
 import chagashi/decoder
-import img/bitmap
 import io/dynstream
 import io/promise
 import loader/headers
@@ -13,7 +12,6 @@ import monoucha/jserror
 import monoucha/quickjs
 import monoucha/tojs
 import types/blob
-import types/color
 import types/opt
 import types/referrer
 import types/url
@@ -228,46 +226,6 @@ proc blob*(response: Response): Promise[JSResult[Blob]] {.jsfunc.} =
   response.resume()
   return opaque.bodyRead
 
-type BitmapOpaque = ref object of RootObj
-  bmp: Bitmap
-  idx: int
-  bodyRead: EmptyPromise
-
-proc onReadBitmap(response: Response) =
-  let opaque = BitmapOpaque(response.opaque)
-  let bmp = opaque.bmp
-  while true:
-    try:
-      let p = cast[ptr UncheckedArray[uint8]](addr bmp.px[0])
-      let L = bmp.px.len * 4 - opaque.idx
-      let n = response.body.recvData(addr p[opaque.idx], L)
-      opaque.idx += n
-      if n == 0:
-        break
-    except ErrorAgain:
-      break
-
-proc onFinishBitmap(response: Response; success: bool) =
-  let opaque = BitmapOpaque(response.opaque)
-  opaque.bodyRead.resolve()
-
-proc saveToBitmap*(response: Response; bmp: Bitmap): EmptyPromise =
-  assert not response.bodyUsed
-  let opaque = BitmapOpaque(bmp: bmp, idx: 0, bodyRead: EmptyPromise())
-  let size = bmp.width * bmp.height
-  bmp.px = cast[seq[RGBAColorBE]](newSeqUninitialized[uint32](size))
-  response.opaque = opaque
-  if size > 0:
-    response.onRead = onReadBitmap
-    response.onFinish = onFinishBitmap
-  else:
-    response.unregisterFun()
-    response.body.sclose()
-    opaque.bodyRead.resolve()
-  response.bodyUsed = true
-  response.resume()
-  return opaque.bodyRead
-
 proc json(ctx: JSContext; this: Response): Promise[JSValue] {.jsfunc.} =
   return this.text().then(proc(s: JSResult[string]): JSValue =
     if s.isNone: