about summary refs log tree commit diff stats
path: root/src/types/blob.nim
diff options
context:
space:
mode:
authorbptato <nincsnevem662@gmail.com>2024-05-11 19:56:25 +0200
committerbptato <nincsnevem662@gmail.com>2024-05-11 20:06:10 +0200
commitb8345d19efdecb27139e011e92f89efbb7618c08 (patch)
tree5d0f3de089ef40f1f653ee386771e326f9847cd6 /src/types/blob.nim
parent2c1d1899e424c5e055214d3647979f7f0ba4dcfe (diff)
downloadchawan-b8345d19efdecb27139e011e92f89efbb7618c08.tar.gz
buffer: fix multipart forms
* fix enctype not getting picked up
* fix form data constructor requiring open() syscall (which gets blocked
  by our seccomp filter)
* add closing boundary to multipart end
* pass fds instead of path names through WebFile/Blob and send those
  through bufwriter/bufreader
Diffstat (limited to 'src/types/blob.nim')
-rw-r--r--src/types/blob.nim44
1 files changed, 17 insertions, 27 deletions
diff --git a/src/types/blob.nim b/src/types/blob.nim
index ebf5aedf..dd812c02 100644
--- a/src/types/blob.nim
+++ b/src/types/blob.nim
@@ -1,27 +1,25 @@
 import std/options
-import std/os
+import std/posix
 import std/strutils
 
 import js/fromjs
 import js/javascript
 import js/jstypes
 import utils/mimeguess
-import utils/twtstr
 
 type
   DeallocFun = proc() {.closure, raises: [].}
 
   Blob* = ref object of RootObj
-    isfile*: bool
     size* {.jsget.}: uint64
     ctype* {.jsget: "type".}: string
     buffer*: pointer
     deallocFun*: DeallocFun
+    fd*: Option[FileHandle]
 
   WebFile* = ref object of Blob
     webkitRelativePath {.jsget.}: string
-    path*: string
-    file: File #TODO maybe use fd?
+    name* {.jsget.}: string
 
 jsDestructor(Blob)
 jsDestructor(WebFile)
@@ -36,25 +34,20 @@ proc newBlob*(buffer: pointer; size: int; ctype: string;
   )
 
 proc finalize(blob: Blob) {.jsfin.} =
+  if blob.fd.isSome:
+    discard close(blob.fd.get)
   if blob.deallocFun != nil and blob.buffer != nil:
     blob.deallocFun()
     blob.buffer = nil
 
 proc finalize(file: WebFile) {.jsfin.} =
-  if file.deallocFun != nil and file.buffer != nil:
-    file.deallocFun()
-    file.buffer = nil
-
-proc newWebFile*(path: string; webkitRelativePath = ""): WebFile =
-  var file: File
-  if not open(file, path, fmRead):
-    raise newException(IOError, "Failed to open file")
+  Blob(file).finalize()
+
+proc newWebFile*(name: string; fd: FileHandle): WebFile =
   return WebFile(
-    isfile: true,
-    path: path,
-    file: file,
-    ctype: DefaultGuess.guessContentType(path),
-    webkitRelativePath: webkitRelativePath
+    name: name,
+    fd: some(fd),
+    ctype: DefaultGuess.guessContentType(name)
   )
 
 type
@@ -68,8 +61,7 @@ type
 proc newWebFile(ctx: JSContext; fileBits: seq[string]; fileName: string;
     options = FilePropertyBag()): WebFile {.jsctor.} =
   let file = WebFile(
-    isfile: false,
-    path: fileName,
+    name: fileName
   )
   var len = 0
   for blobPart in fileBits:
@@ -94,18 +86,16 @@ proc newWebFile(ctx: JSContext; fileBits: seq[string]; fileName: string;
 #TODO File, Blob constructors
 
 proc getSize*(this: Blob): uint64 =
-  if this.isfile:
-    return uint64(WebFile(this).path.getFileSize())
+  if this.fd.isSome:
+    var statbuf: Stat
+    if fstat(this.fd.get, statbuf) < 0:
+      return 0
+    return uint64(statbuf.st_size)
   return this.size
 
 proc size*(this: WebFile): uint64 {.jsfget.} =
   return this.getSize()
 
-func name*(this: WebFile): string {.jsfget.} =
-  if this.path.len > 0 and this.path[^1] != '/':
-    return this.path.afterLast('/')
-  return this.path.afterLast('/', 2)
-
 #TODO lastModified
 
 proc addBlobModule*(ctx: JSContext) =