about summary refs log tree commit diff stats
diff options
context:
space:
mode:
-rw-r--r--src/html/dom.nim1
-rw-r--r--src/html/env.nim6
-rw-r--r--src/html/formdata.nim19
-rw-r--r--src/local/client.nim7
-rw-r--r--src/local/pager.nim10
-rw-r--r--src/main.nim5
-rw-r--r--src/server/buffer.nim14
-rw-r--r--src/server/forkserver.nim5
8 files changed, 36 insertions, 31 deletions
diff --git a/src/html/dom.nim b/src/html/dom.nim
index 274d401f..37c9f951 100644
--- a/src/html/dom.nim
+++ b/src/html/dom.nim
@@ -105,6 +105,7 @@ type
     imageId: int
     # list of streams that must be closed for canvas rendering on load
     pendingCanvasCtls*: seq[CanvasRenderingContext2D]
+    urandom*: PosixStream
 
   # Navigator stuff
   Navigator* = object
diff --git a/src/html/env.nim b/src/html/env.nim
index d0c77b46..f3292504 100644
--- a/src/html/env.nim
+++ b/src/html/env.nim
@@ -331,7 +331,8 @@ proc runJSJobs*(window: Window) =
     ctx.writeException(window.console.err)
 
 proc newWindow*(scripting, images, styling: bool; attrs: WindowAttributes;
-    factory: CAtomFactory; loader: FileLoader; url: URL): Window =
+    factory: CAtomFactory; loader: FileLoader; url: URL; urandom: PosixStream):
+    Window =
   let err = newDynFileStream(stderr)
   let window = Window(
     attrs: attrs,
@@ -344,7 +345,8 @@ proc newWindow*(scripting, images, styling: bool; attrs: WindowAttributes;
       scripting: scripting,
       origin: url.origin
     ),
-    factory: factory
+    factory: factory,
+    urandom: urandom
   )
   window.location = window.newLocation()
   if scripting:
diff --git a/src/html/formdata.nim b/src/html/formdata.nim
index f6a7451b..808609d4 100644
--- a/src/html/formdata.nim
+++ b/src/html/formdata.nim
@@ -15,23 +15,20 @@ import utils/twtstr
 proc constructEntryList*(form: HTMLFormElement; submitter: Element = nil;
     encoding = "UTF-8"): seq[FormDataEntry]
 
-var urandom* {.global.}: PosixStream
-
-proc generateBoundary(): string =
+proc generateBoundary(urandom: PosixStream): string =
   var s: array[33, uint8]
   urandom.recvDataLoop(s)
   # 33 * 4 / 3 = 44 + prefix string is 22 bytes = 66 bytes
   return "----WebKitFormBoundary" & btoa(s)
 
-proc newFormData0*(): FormData =
-  return FormData(boundary: generateBoundary())
-
-proc newFormData0*(entries: seq[FormDataEntry]): FormData =
-  return FormData(boundary: generateBoundary(), entries: entries)
+proc newFormData0*(entries: seq[FormDataEntry]; urandom: PosixStream):
+    FormData =
+  return FormData(boundary: urandom.generateBoundary(), entries: entries)
 
-proc newFormData(form: HTMLFormElement = nil; submitter: HTMLElement = nil):
-    DOMResult[FormData] {.jsctor.} =
-  let this = newFormData0()
+proc newFormData(ctx: JSContext; form: HTMLFormElement = nil;
+    submitter: HTMLElement = nil): DOMResult[FormData] {.jsctor.} =
+  let urandom = ctx.getGlobal().urandom
+  let this = FormData(boundary: urandom.generateBoundary())
   if form != nil:
     if submitter != nil:
       if not submitter.isSubmitButton():
diff --git a/src/local/client.nim b/src/local/client.nim
index df5bd1ca..93c9f3cd 100644
--- a/src/local/client.nim
+++ b/src/local/client.nim
@@ -795,11 +795,11 @@ func getClient(client: Client): Client {.jsfget: "client".} =
   return client
 
 proc newClient*(config: Config; forkserver: ForkServer; loaderPid: int;
-    jsctx: JSContext; warnings: seq[string]): Client =
+    jsctx: JSContext; warnings: seq[string]; urandom: PosixStream): Client =
   setControlCHook(proc() {.noconv.} = quit(1))
   let jsrt = JS_GetRuntime(jsctx)
   JS_SetModuleLoaderFunc(jsrt, normalizeModuleName, clientLoadJSModule, nil)
-  let pager = newPager(config, forkserver, jsctx, warnings)
+  let pager = newPager(config, forkserver, jsctx, warnings, urandom)
   let loader = FileLoader(process: loaderPid, clientPid: getCurrentProcessId())
   loader.setSocketDir(config.external.sockdir)
   pager.setLoader(loader)
@@ -811,7 +811,8 @@ proc newClient*(config: Config; forkserver: ForkServer; loaderPid: int;
     exitCode: -1,
     alive: true,
     factory: newCAtomFactory(),
-    loader: loader
+    loader: loader,
+    urandom: urandom
   )
   JS_SetInterruptHandler(jsrt, interruptHandler, cast[pointer](client))
   let global = JS_GetGlobalObject(jsctx)
diff --git a/src/local/pager.nim b/src/local/pager.nim
index 53f9a84f..e20a4d05 100644
--- a/src/local/pager.nim
+++ b/src/local/pager.nim
@@ -128,7 +128,6 @@ type
     consoleWrapper*: ConsoleWrapper
     container*: Container
     cookiejars: Table[string, CookieJar]
-    devRandom: PosixStream
     display: Surface
     forkserver*: ForkServer
     hasload*: bool # has a page been successfully loaded since startup?
@@ -157,6 +156,7 @@ type
     term*: Terminal
     timeouts*: TimeoutState
     unreg*: seq[Container]
+    urandom: PosixStream
 
 jsDestructor(Pager)
 
@@ -340,19 +340,20 @@ proc quit*(pager: Pager) =
   pager.dumpAlerts()
 
 proc newPager*(config: Config; forkserver: ForkServer; ctx: JSContext;
-    alerts: seq[string]): Pager =
+    alerts: seq[string]; urandom: PosixStream): Pager =
   return Pager(
     config: config,
     forkserver: forkserver,
     term: newTerminal(stdout, config),
     alerts: alerts,
     jsctx: ctx,
-    luctx: LUContext()
+    luctx: LUContext(),
+    urandom: urandom
   )
 
 proc genClientKey(pager: Pager): ClientKey =
   var key: ClientKey
-  pager.devRandom.recvDataLoop(key)
+  pager.urandom.recvDataLoop(key)
   return key
 
 proc addLoaderClient*(pager: Pager; pid: int; config: LoaderClientConfig;
@@ -363,7 +364,6 @@ proc addLoaderClient*(pager: Pager; pid: int; config: LoaderClientConfig;
   return key
 
 proc setLoader*(pager: Pager; loader: FileLoader) =
-  pager.devRandom = newPosixStream("/dev/urandom", O_RDONLY, 0)
   pager.loader = loader
   let config = LoaderClientConfig(
     defaultHeaders: newHeaders(pager.config.network.default_headers),
diff --git a/src/main.nim b/src/main.nim
index 8ef2d50d..17d49870 100644
--- a/src/main.nim
+++ b/src/main.nim
@@ -8,6 +8,7 @@ import std/streams
 import chagashi/charset
 import config/chapath
 import config/config
+import io/dynstream
 import local/client
 import local/term
 import monoucha/javascript
@@ -229,6 +230,7 @@ proc main() =
   putEnv("CHA_BIN_DIR", getAppFileName().beforeLast('/'))
   putEnv("CHA_LIBEXEC_DIR", ChaPath(libexecPath).unquoteGet())
   let forkserver = newForkServer()
+  let urandom = newPosixStream("/dev/urandom", O_RDONLY, 0)
   var ctx = ParamParseContext(params: commandLineParams(), i: 0)
   ctx.parse()
   let jsrt = newJSRuntime()
@@ -253,7 +255,8 @@ proc main() =
   discard mkdir(cstring(config.external.tmpdir), 0o700)
   discard mkdir(cstring(config.external.sockdir), 0o700)
   let loaderPid = forkserver.loadConfig(config)
-  let client = newClient(config, forkserver, loaderPid, jsctx, warnings)
+  let client = newClient(config, forkserver, loaderPid, jsctx, warnings,
+    urandom)
   try:
     client.launchClient(ctx.pages, ctx.contentType, ctx.charset, ctx.dump)
   except CatchableError:
diff --git a/src/server/buffer.nim b/src/server/buffer.nim
index 66858bf6..a1218a62 100644
--- a/src/server/buffer.nim
+++ b/src/server/buffer.nim
@@ -1219,8 +1219,9 @@ proc cancel*(buffer: Buffer) {.proxy.} =
   discard buffer.maybeReshape()
 
 #https://html.spec.whatwg.org/multipage/form-control-infrastructure.html#multipart/form-data-encoding-algorithm
-proc serializeMultipart(entries: seq[FormDataEntry]): FormData =
-  let formData = newFormData0(entries)
+proc serializeMultipart(entries: seq[FormDataEntry]; urandom: PosixStream):
+    FormData =
+  let formData = newFormData0(entries, urandom)
   for entry in formData.entries.mitems:
     entry.name = makeCRLF(entry.name)
   return formData
@@ -1305,7 +1306,8 @@ proc makeFormRequest(buffer: Buffer; parsedAction: URL; httpMethod: HttpMethod;
       RequestBody(t: rbtString, s: serializeFormURLEncoded(kvlist))
     of fetMultipart:
       #TODO with charset
-      RequestBody(t: rbtMultipart, multipart: serializeMultipart(entryList))
+      let multipart = serializeMultipart(entryList, buffer.window.urandom)
+      RequestBody(t: rbtMultipart, multipart: multipart)
     of fetTextPlain:
       #TODO with charset
       let kvlist = entryList.toNameValuePairs()
@@ -1867,13 +1869,13 @@ proc runBuffer(buffer: Buffer) =
 
 proc cleanup(buffer: Buffer) =
   buffer.pstream.sclose()
-  urandom.sclose()
+  buffer.window.urandom.sclose()
   # no unlink access on Linux, so just hope that the pager could clean it up
   buffer.ssock.close(unlink = false)
 
 proc launchBuffer*(config: BufferConfig; url: URL; attrs: WindowAttributes;
     ishtml: bool; charsetStack: seq[Charset]; loader: FileLoader;
-    ssock: ServerSocket; pstream: SocketStream) =
+    ssock: ServerSocket; pstream: SocketStream; urandom: PosixStream) =
   let factory = newCAtomFactory()
   let confidence = if config.charsetOverride == CHARSET_UNKNOWN:
     ccTentative
@@ -1895,7 +1897,7 @@ proc launchBuffer*(config: BufferConfig; url: URL; attrs: WindowAttributes;
     outputId: -1,
     factory: factory,
     window: newWindow(config.scripting, config.images, config.styling, attrs,
-      factory, loader, url)
+      factory, loader, url, urandom)
   )
   if buffer.config.scripting:
     buffer.window.navigate = proc(url: URL) = buffer.navigate(url)
diff --git a/src/server/forkserver.nim b/src/server/forkserver.nim
index c6a77f99..8014b674 100644
--- a/src/server/forkserver.nim
+++ b/src/server/forkserver.nim
@@ -6,7 +6,6 @@ import std/tables
 import chagashi/charset
 import config/config
 import config/urimethodmap
-import html/formdata
 import io/bufreader
 import io/bufwriter
 import io/dynstream
@@ -153,7 +152,7 @@ proc forkBuffer(ctx: var ForkServerContext; r: var BufferedReader): int =
     let ps = newPosixStream(pipefd[1])
     ps.write(char(0))
     ps.sclose()
-    urandom = newPosixStream("/dev/urandom", O_RDONLY, 0)
+    let urandom = newPosixStream("/dev/urandom", O_RDONLY, 0)
     let pstream = ssock.acceptSocketStream()
     gssock = ssock
     gpstream = pstream
@@ -172,7 +171,7 @@ proc forkBuffer(ctx: var ForkServerContext; r: var BufferedReader): int =
     )
     try:
       launchBuffer(config, url, attrs, ishtml, charsetStack, loader,
-        ssock, pstream)
+        ssock, pstream, urandom)
     except CatchableError:
       let e = getCurrentException()
       # taken from system/excpt.nim