about summary refs log tree commit diff stats
path: root/src/loader/headers.nim
diff options
context:
space:
mode:
authorbptato <nincsnevem662@gmail.com>2024-08-13 22:48:12 +0200
committerbptato <nincsnevem662@gmail.com>2024-08-13 23:03:41 +0200
commit885a3493b6cad4b4247a200928fe61e41883aaba (patch)
tree2b823ef18043c775f21b8ad723c826ffdc6b2663 /src/loader/headers.nim
parent968de41082280dde47bac7c2bb59522284b4c672 (diff)
downloadchawan-885a3493b6cad4b4247a200928fe61e41883aaba.tar.gz
xhr: progress
* fix header case sensitivity issues
	-> probably still wrong as it discards the original
	  casing. better than nothing, anyway
* fix fulfill on generic promises
* support standard open() async parameter weirdness
* refactor loader response body reading (so bodyRead is no longer
  mandatory)
* actually read response body

still missing: response body getters
Diffstat (limited to 'src/loader/headers.nim')
-rw-r--r--src/loader/headers.nim28
1 files changed, 17 insertions, 11 deletions
diff --git a/src/loader/headers.nim b/src/loader/headers.nim
index 6b598cc2..e09d2267 100644
--- a/src/loader/headers.nim
+++ b/src/loader/headers.nim
@@ -5,6 +5,7 @@ import monoucha/fromjs
 import monoucha/javascript
 import monoucha/jserror
 import monoucha/quickjs
+import monoucha/tojs
 import types/opt
 import utils/twtstr
 
@@ -99,7 +100,8 @@ func isForbiddenRequestHeader*(name, value: string): bool =
   return false
 
 func isForbiddenResponseHeaderName*(name: string): bool =
-  return name in ["Set-Cookie", "Set-Cookie2"]
+  return name.equalsIgnoreCase("Set-Cookie") or
+    name.equalsIgnoreCase("Set-Cookie2")
 
 proc validate(this: Headers; name, value: string): JSResult[bool] =
   if not name.isValidHeaderName() or not value.isValidHeaderValue():
@@ -118,7 +120,6 @@ func isNoCorsSafelistedName(name: string): bool =
     name.equalsIgnoreCase("Content-Language") or
     name.equalsIgnoreCase("Content-Type")
 
-
 const CorsUnsafeRequestByte = {
   char(0x00)..char(0x08), char(0x10)..char(0x1F), '"', '(', ')', ':', '<', '>',
   '?', '@', '[', '\\', ']', '{', '}', '\e'
@@ -145,12 +146,14 @@ func isNoCorsSafelisted(name, value: string): bool =
 func get0(this: Headers; name: string): string =
   return this.table[name].join(", ")
 
-proc get(this: Headers; name: string): JSResult[Option[string]] {.jsfunc.} =
+proc get*(ctx: JSContext; this: Headers; name: string): JSValue {.jsfunc.} =
   if not name.isValidHeaderName():
-    return errTypeError("Invalid header name")
+    JS_ThrowTypeError(ctx, "Invalid header name")
+    return JS_EXCEPTION
+  let name = name.toHeaderCase()
   if name notin this.table:
-    return ok(none(string))
-  return ok(some(this.get0(name)))
+    return JS_NULL
+  return ctx.toJS(this.get0(name))
 
 proc removeRange(this: Headers) =
   if this.guard == hgRequestNoCors:
@@ -162,18 +165,21 @@ proc append(this: Headers; name, value: string): JSResult[void] {.jsfunc.} =
   let value = value.strip(chars = HTTPWhitespace)
   if not ?this.validate(name, value):
     return ok()
+  let name = name.toHeaderCase()
   if this.guard == hgRequestNoCors:
     if name in this.table:
       let tmp = this.get0(name) & ", " & value
       if not name.isNoCorsSafelisted(tmp):
         return ok()
-      this.table[name].add(value)
-    else:
-      this.table[name] = @[value]
+  if name in this.table:
+    this.table[name].add(value)
+  else:
+    this.table[name] = @[value]
   this.removeRange()
   ok()
 
 proc delete(this: Headers; name: string): JSResult[void] {.jsfunc.} =
+  let name = name.toHeaderCase()
   if not ?this.validate(name, "") or name notin this.table:
     return ok()
   if not name.isNoCorsSafelistedName() and not name.equalsIgnoreCase("Range"):
@@ -185,6 +191,7 @@ proc delete(this: Headers; name: string): JSResult[void] {.jsfunc.} =
 proc has(this: Headers; name: string): JSResult[bool] {.jsfunc.} =
   if not name.isValidHeaderName():
     return errTypeError("Invalid header name")
+  let name = name.toHeaderCase()
   return ok(name in this.table)
 
 proc set(this: Headers; name, value: string): JSResult[void] {.jsfunc.} =
@@ -193,8 +200,7 @@ proc set(this: Headers; name, value: string): JSResult[void] {.jsfunc.} =
     return
   if this.guard == hgRequestNoCors and not name.isNoCorsSafelisted(value):
     return
-  #TODO do this case insensitively
-  this.table[name] = @[value]
+  this.table[name.toHeaderCase()] = @[value]
   this.removeRange()
 
 proc fill(headers: Headers; s: seq[(string, string)]): JSResult[void] =