diff options
author | bptato <nincsnevem662@gmail.com> | 2024-05-30 00:19:48 +0200 |
---|---|---|
committer | bptato <nincsnevem662@gmail.com> | 2024-06-20 17:50:22 +0200 |
commit | 60dc37269cd2dc8cdf23d9f77680f6af9490032f (patch) | |
tree | 9a72ba24daffa546f92704e7e06cf84fded2d89d /src/io | |
parent | a146a22b11cea39bc691417d9d9a1292b7177552 (diff) | |
download | chawan-60dc37269cd2dc8cdf23d9f77680f6af9490032f.tar.gz |
img, loader: separate out png codec into cgi, misc improvements
* multi-processed and sandboxed PNG decoding & encoding (through local CGI) * improved request body passing (including support for output id as response body) * simplified & faster blob()/text() - now every request starts suspended, and OngoingData.buf has been replaced with loader's buffering capability * image caching: we no longer pull bitmaps from the container after every single getLines call Next steps: replace our bespoke PNG decoder with something more usable, add other decoders, and make them stream.
Diffstat (limited to 'src/io')
-rw-r--r-- | src/io/bufreader.nim | 41 | ||||
-rw-r--r-- | src/io/bufwriter.nim | 26 | ||||
-rw-r--r-- | src/io/promise.nim | 10 | ||||
-rw-r--r-- | src/io/urlfilter.nim | 2 |
4 files changed, 74 insertions, 5 deletions
diff --git a/src/io/bufreader.nim b/src/io/bufreader.nim index 90940424..bd2486be 100644 --- a/src/io/bufreader.nim +++ b/src/io/bufreader.nim @@ -2,8 +2,10 @@ import std/options import std/sets import std/tables +import img/bitmap import io/dynstream import io/socketstream +import loader/request import types/blob import types/color import types/formdata @@ -32,6 +34,8 @@ proc sread*(reader: var BufferedReader; blob: var Blob) proc sread*[T](reader: var BufferedReader; o: var Option[T]) proc sread*[T, E](reader: var BufferedReader; o: var Result[T, E]) proc sread*(reader: var BufferedReader; c: var ARGBColor) {.inline.} +proc sread*(reader: var BufferedReader; o: var RequestBody) +proc sread*(reader: var BufferedReader; bmp: var Bitmap) proc initReader*(stream: DynStream; len, auxLen: int): BufferedReader = assert len != 0 @@ -169,7 +173,7 @@ proc sread*(reader: var BufferedReader; blob: var Blob) = let buffer = alloc(blob.size) reader.readData(blob.buffer, int(blob.size)) blob.buffer = buffer - blob.deallocFun = proc() = dealloc(buffer) + blob.deallocFun = deallocBlob proc sread*[T](reader: var BufferedReader; o: var Option[T]) = var x: bool @@ -201,3 +205,38 @@ proc sread*[T, E](reader: var BufferedReader; o: var Result[T, E]) = proc sread*(reader: var BufferedReader; c: var ARGBColor) = reader.sread(uint32(c)) + +proc sread*(reader: var BufferedReader; o: var RequestBody) = + var t: RequestBodyType + reader.sread(t) + o = RequestBody(t: t) + case t + of rbtNone: discard + of rbtString: reader.sread(o.s) + of rbtMultipart: reader.sread(o.multipart) + of rbtOutput: reader.sread(o.outputId) + +proc sread*(reader: var BufferedReader; bmp: var Bitmap) = + var isImageBitmap: bool + var width: uint64 + var height: uint64 + reader.sread(isImageBitmap) + reader.sread(width) + reader.sread(height) + if isImageBitmap: + bmp = ImageBitmap( + width: width, + height: height + ) + reader.sread(bmp.px) + else: + var outputId: int + var imageId: int + reader.sread(outputId) + reader.sread(imageId) + bmp = NetworkBitmap( + width: width, + height: height, + outputId: outputId, + imageId: imageId + ) diff --git a/src/io/bufwriter.nim b/src/io/bufwriter.nim index fd3c12a8..56e30f5b 100644 --- a/src/io/bufwriter.nim +++ b/src/io/bufwriter.nim @@ -5,8 +5,10 @@ import std/options import std/sets import std/tables +import img/bitmap import io/dynstream import io/socketstream +import loader/request import types/blob import types/color import types/formdata @@ -34,7 +36,7 @@ proc swrite*(writer: var BufferedWriter; b: bool) proc swrite*(writer: var BufferedWriter; url: URL) proc swrite*(writer: var BufferedWriter; tup: tuple) proc swrite*[I, T](writer: var BufferedWriter; a: array[I, T]) -proc swrite*(writer: var BufferedWriter; s: seq) +proc swrite*[T](writer: var BufferedWriter; s: openArray[T]) proc swrite*[U, V](writer: var BufferedWriter; t: Table[U, V]) proc swrite*(writer: var BufferedWriter; obj: object) proc swrite*(writer: var BufferedWriter; obj: ref object) @@ -43,6 +45,8 @@ proc swrite*(writer: var BufferedWriter; blob: Blob) proc swrite*[T](writer: var BufferedWriter; o: Option[T]) proc swrite*[T, E](writer: var BufferedWriter; o: Result[T, E]) proc swrite*(writer: var BufferedWriter; c: ARGBColor) {.inline.} +proc swrite*(writer: var BufferedWriter; o: RequestBody) +proc swrite*(writer: var BufferedWriter; bmp: Bitmap) const InitLen = sizeof(int) * 2 const SizeInit = max(64, InitLen) @@ -130,7 +134,7 @@ proc swrite*[I, T](writer: var BufferedWriter; a: array[I, T]) = for x in a: writer.swrite(x) -proc swrite*(writer: var BufferedWriter; s: seq) = +proc swrite*[T](writer: var BufferedWriter; s: openArray[T]) = writer.swrite(s.len) for x in s: writer.swrite(x) @@ -188,3 +192,21 @@ proc swrite*[T, E](writer: var BufferedWriter; o: Result[T, E]) = proc swrite*(writer: var BufferedWriter; c: ARGBColor) = writer.swrite(uint32(c)) + +proc swrite*(writer: var BufferedWriter; o: RequestBody) = + writer.swrite(o.t) + case o.t + of rbtNone: discard + of rbtString: writer.swrite(o.s) + of rbtMultipart: writer.swrite(o.multipart) + of rbtOutput: writer.swrite(o.outputId) + +proc swrite*(writer: var BufferedWriter; bmp: Bitmap) = + writer.swrite(bmp of ImageBitmap) + writer.swrite(bmp.width) + writer.swrite(bmp.height) + if bmp of ImageBitmap: + writer.swrite(bmp.px) + else: + writer.swrite(NetworkBitmap(bmp).outputId) + writer.swrite(NetworkBitmap(bmp).imageId) diff --git a/src/io/promise.nim b/src/io/promise.nim index 183091cb..a1a5cfc9 100644 --- a/src/io/promise.nim +++ b/src/io/promise.nim @@ -132,6 +132,14 @@ proc then*[T](promise: Promise[T]; cb: (proc(x: T): EmptyPromise)): EmptyPromise next.resolve()) return next +proc then*[T](promise: EmptyPromise; cb: (proc(): T)): Promise[T] + {.discardable.} = + let next = Promise[T]() + promise.then(proc() = + next.res = cb() + next.resolve()) + return next + proc then*[T, U](promise: Promise[T]; cb: (proc(x: T): U)): Promise[U] {.discardable.} = let next = Promise[U]() @@ -195,7 +203,7 @@ proc promiseThenCallback(ctx: JSContext; this_val: JSValue; argc: cint; proc fromJSEmptyPromise*(ctx: JSContext; val: JSValue): JSResult[EmptyPromise] = if not JS_IsObject(val): - return err(newTypeError("Value is not an object")) + return errTypeError("Value is not an object") var p = EmptyPromise() GC_ref(p) let tmp = JS_NewObject(ctx) diff --git a/src/io/urlfilter.nim b/src/io/urlfilter.nim index e86e0e6b..20983498 100644 --- a/src/io/urlfilter.nim +++ b/src/io/urlfilter.nim @@ -6,7 +6,7 @@ import types/url #TODO add denyhost/s for blocklists type URLFilter* = object scheme: Option[string] - allowschemes: seq[string] + allowschemes*: seq[string] allowhost*: Option[string] allowhosts: seq[Regex] default: bool |