about summary refs log tree commit diff stats
diff options
context:
space:
mode:
authorbptato <nincsnevem662@gmail.com>2023-06-05 13:37:10 +0200
committerbptato <nincsnevem662@gmail.com>2023-06-05 13:37:10 +0200
commit06c0dd1741af58eb55c27601b070010ad6c50dc8 (patch)
tree9fb914f21db934f05a0abde5c662c35ae2bc1a82
parent86c133f37ec41e4dce39c692696228e8151fe75c (diff)
downloadchawan-06c0dd1741af58eb55c27601b070010ad6c50dc8.tar.gz
Refactor Request constructor
-rw-r--r--src/io/request.nim55
-rw-r--r--src/js/javascript.nim14
2 files changed, 41 insertions, 28 deletions
diff --git a/src/io/request.nim b/src/io/request.nim
index 76fd9fc4..08947bd5 100644
--- a/src/io/request.nim
+++ b/src/io/request.nim
@@ -241,36 +241,47 @@ func createPotentialCORSRequest*(url: URL, destination: RequestDestination, cors
 #TODO resource as Request
 #TODO also, I'm not sure what to do with init. For now I've re-introduced
 # JSObject to make this work, but I really wish we had a better solution.
-func newRequest*(resource: string, init: JSObject): Request {.jserr, jsctor.} =
+func newRequest*(ctx: JSContext, resource: string,
+    init = none(JSValue)): Request {.jserr, jsctor.} =
   let x = parseURL(resource)
   if x.isNone:
     JS_ERR JS_TypeError, resource & " is not a valid URL."
   if x.get.username != "" or x.get.password != "":
     JS_ERR JS_TypeError, resource & " is not a valid URL."
   let url = x.get
-  let ctx = init.ctx
   let fallbackMode = some(RequestMode.CORS) #TODO none if resource is request
-  #TODO fallback mode, origin, window, request mode, ...
-  let httpMethod = fromJS[HttpMethod](ctx,
-    JS_GetPropertyStr(ctx, init.val, "method")).get(HTTP_GET)
-  let bodyProp = JS_GetPropertyStr(ctx, init.val, "body")
-  let multipart = fromJS[FormData](ctx, bodyProp)
-  var body: Option[string]
-  if multipart.isNone:
-    body = fromJS[string](ctx, bodyProp)
-  #TODO inputbody
-  if (multipart.isSome or body.isSome) and httpMethod in {HTTP_GET, HTTP_HEAD}:
-    JS_ERR JS_TypeError, "HEAD or GET Request cannot have a body."
-  let jheaders = JS_GetPropertyStr(ctx, init.val, "headers")
+  var httpMethod = HTTP_GET
+  var body = none(string)
+  var credentials = CredentialsMode.SAME_ORIGIN
+  var mode = fallbackMode.get(RequestMode.NO_CORS)
   let hl = newHeaders()
-  hl.fill(ctx, jheaders)
-  let credentials = fromJS[CredentialsMode](ctx, JS_GetPropertyStr(ctx, init.val, "credentials"))
-    .get(CredentialsMode.SAME_ORIGIN)
-  let mode = fromJS[RequestMode](ctx, JS_GetPropertyStr(ctx, init.val, "mode"))
-    .get(fallbackMode.get(RequestMode.NO_CORS))
-  #TODO find a standard compatible way to implement this
-  let proxyUrl = fromJS[URL](ctx, JS_GetPropertyStr(ctx, init.val, "proxyUrl"))
-  return newRequest(url, httpMethod, hl, body, multipart, mode, credentials, proxy = proxyUrl.get(nil))
+  var proxyUrl = none(URL)
+  var multipart = none(FormData)
+  #TODO fallback mode, origin, window, request mode, ...
+  if init.isSome:
+    let init = init.get
+    httpMethod = fromJS[HttpMethod](ctx,
+      JS_GetPropertyStr(ctx, init, "method")).get(HTTP_GET)
+    let bodyProp = JS_GetPropertyStr(ctx, init, "body")
+    if not JS_IsNull(bodyProp) and not JS_IsUndefined(bodyProp):
+      # ????
+      multipart = fromJS[FormData](ctx, bodyProp)
+      if multipart.isNone:
+        body = fromJS[string](ctx, bodyProp)
+    #TODO inputbody
+    if (multipart.isSome or body.isSome) and
+        httpMethod in {HTTP_GET, HTTP_HEAD}:
+      JS_ERR JS_TypeError, "HEAD or GET Request cannot have a body."
+    let jheaders = JS_GetPropertyStr(ctx, init, "headers")
+    hl.fill(ctx, jheaders)
+    credentials = fromJS[CredentialsMode](ctx, JS_GetPropertyStr(ctx, init,
+      "credentials")).get(credentials)
+    mode = fromJS[RequestMode](ctx, JS_GetPropertyStr(ctx, init, "mode"))
+      .get(mode)
+    #TODO find a standard compatible way to implement this
+    proxyUrl = fromJS[URL](ctx, JS_GetPropertyStr(ctx, init, "proxyUrl"))
+  return newRequest(url, httpMethod, hl, body, multipart, mode, credentials,
+    proxy = proxyUrl.get(nil))
 
 proc add*(headers: var Headers, k, v: string) =
   let k = k.toHeaderCase()
diff --git a/src/js/javascript.nim b/src/js/javascript.nim
index adf58ee4..5bffbdbd 100644
--- a/src/js/javascript.nim
+++ b/src/js/javascript.nim
@@ -229,8 +229,7 @@ func toString*(ctx: JSContext, val: JSValue): Option[string] =
   let outp = JS_ToCStringLen(ctx, addr plen, val) # cstring
   if outp != nil:
     var ret = newString(plen)
-    for i in 0..<plen:
-      ret[i] = outp[i]
+    copyMem(addr ret[0], outp, plen)
     result = some(ret)
     JS_FreeCString(ctx, outp)
 
@@ -335,7 +334,7 @@ func newJSClass*(ctx: JSContext, cdef: JSClassDefConst, tname: string,
   JS_SetConstructor(ctx, jctor, proto)
   ctxOpaque.ctors[result] = JS_DupValue(ctx, jctor)
   if not nointerface:
-    if namespace == JS_NULL:
+    if JS_IsNull(namespace):
       let global = JS_GetGlobalObject(ctx)
       ctx.defineProperty(global, $cdef.class_name, jctor)
       JS_FreeValue(ctx, global)
@@ -648,8 +647,11 @@ proc fromJS*[T](ctx: JSContext, val: JSValue): Option[T] =
   elif T is (proc):
     return fromJSFunction1[typeof(unpackReturnType(T)), typeof(unpackArg0(T))](ctx, val)
   elif typeof(result.unsafeGet) is Option: # unwrap
+    if JS_IsUndefined(val):
+      #TODO what about null?
+      return none(T)
     let res = fromJS[typeof(result.get.get)](ctx, val)
-    if res.isnone:
+    if res.isNone:
       return none(T)
     return some(res)
   elif T is seq:
@@ -1243,13 +1245,13 @@ proc newJSProcBody(gen: var JSFuncGenerator, isva: bool): NimNode =
     ma -= 1
   if gen.passCtx:
     ma -= 1
-  let pctx = gen.passCtx
   assert ma >= 0
   result = newStmtList()
   if isva:
     result.add(quote do: 
       if argc < `ma`:
-        return JS_ThrowTypeError(ctx, "At least %d arguments required, but only %d passed %d", `ma`, argc, `pctx`)
+        return JS_ThrowTypeError(ctx, "At least %d arguments required, " &
+          "but only %d passed", `ma`, argc)
     )
   if gen.thisname.isSome:
     let tn = ident(gen.thisname.get)