about summary refs log tree commit diff stats
path: root/src/loader
diff options
context:
space:
mode:
authorbptato <nincsnevem662@gmail.com>2024-07-18 18:22:15 +0200
committerbptato <nincsnevem662@gmail.com>2024-07-18 18:22:56 +0200
commitf94b84bde340739647ffe7dd92cfcefb6686eca2 (patch)
tree6e4af17196945d39ff8a1f9ab5e3516f9c0a2514 /src/loader
parent01cb95c89fb53a936172412e6dd69b943bf73b4b (diff)
downloadchawan-f94b84bde340739647ffe7dd92cfcefb6686eca2.tar.gz
html: event cleanup, XHR progress
Diffstat (limited to 'src/loader')
-rw-r--r--src/loader/headers.nim49
-rw-r--r--src/loader/response.nim25
2 files changed, 62 insertions, 12 deletions
diff --git a/src/loader/headers.nim b/src/loader/headers.nim
index ff7f9ed3..cd69251c 100644
--- a/src/loader/headers.nim
+++ b/src/loader/headers.nim
@@ -1,3 +1,4 @@
+import std/strutils
 import std/tables
 
 import monoucha/fromjs
@@ -98,7 +99,7 @@ proc `[]=`*(headers: Headers; k: static string, v: string) =
   const k = k.toHeaderCase()
   headers.table[k] = @[v]
 
-func `[]`*(headers: Headers; k: static string): string =
+func `[]`*(headers: Headers; k: static string): var string =
   const k = k.toHeaderCase()
   return headers.table[k][0]
 
@@ -113,5 +114,51 @@ func getOrDefault*(headers: Headers; k: static string; default = ""): string =
   do:
     return default
 
+const TokenChars = {
+  '!', '#', '$', '%', '&', '\'', '*', '+', '-', '.', '^', '_', '`', '|', '~'
+} + AsciiAlphaNumeric
+
+#TODO maybe assert these are valid on insertion?
+func isValidHeaderName*(s: string): bool =
+  return s.len > 0 and AllChars - TokenChars notin s
+
+func isValidHeaderValue*(s: string): bool =
+  return s.len == 0 or s[0] notin {' ', '\t'} and s[^1] notin {' ', '\t'} and
+    '\n' notin s
+
+func isForbiddenHeader*(name, value: string): bool =
+  const ForbiddenNames = [
+    "Accept-Charset",
+    "Accept-Encoding",
+    "Access-Control-Request-Headers",
+    "Access-Control-Request-Method",
+    "Connection",
+    "Content-Length",
+    "Cookie",
+    "Cookie2",
+    "Date",
+    "DNT",
+    "Expect",
+    "Host",
+    "Keep-Alive",
+    "Origin",
+    "Referer",
+    "Set-Cookie",
+    "TE",
+    "Trailer",
+    "Transfer-Encoding",
+    "Upgrade",
+    "Via",
+  ]
+  if name in ForbiddenNames:
+    return true
+  if name.startsWith("proxy-") or name.startsWith("sec-"):
+    return true
+  if name.equalsIgnoreCase("X-HTTP-Method") or
+      name.equalsIgnoreCase("X-HTTP-Method-Override") or
+      name.equalsIgnoreCase("X-Method-Override"):
+    return true # meh
+  return false
+
 proc addHeadersModule*(ctx: JSContext) =
   ctx.registerType(Headers)
diff --git a/src/loader/response.nim b/src/loader/response.nim
index b8d95e36..8b33621e 100644
--- a/src/loader/response.nim
+++ b/src/loader/response.nim
@@ -21,12 +21,12 @@ import utils/twtstr
 
 type
   ResponseType* = enum
-    TYPE_DEFAULT = "default"
-    TYPE_BASIC = "basic"
-    TYPE_CORS = "cors"
-    TYPE_ERROR = "error"
-    TYPE_OPAQUE = "opaque"
-    TYPE_OPAQUEREDIRECT = "opaqueredirect"
+    rtDefault = "default"
+    rtBasic = "basic"
+    rtCors = "cors"
+    rtError = "error"
+    rtOpaque = "opaque"
+    rtOpaquedirect = "opaqueredirect"
 
   #TODO fully implement headers guards
   HeadersGuard* = enum
@@ -36,6 +36,9 @@ type
     hgResponse = "response"
     hgNone = "none"
 
+  ResponseFlag* = enum
+    rfAborted
+
   Response* = ref object
     responseType* {.jsget: "type".}: ResponseType
     res*: int
@@ -52,6 +55,7 @@ type
     outputId*: int
     onRead*: proc(response: Response) {.nimcall.}
     opaque*: RootRef
+    flags*: set[ResponseFlag]
 
 jsDestructor(Response)
 
@@ -69,7 +73,7 @@ func makeNetworkError*(): Response {.jsstfunc: "Response.error".} =
   #TODO headers immutable
   return Response(
     res: 0,
-    responseType: TYPE_ERROR,
+    responseType: rtError,
     status: 0,
     headers: newHeaders(),
     headersGuard: hgImmutable,
@@ -79,8 +83,8 @@ func makeNetworkError*(): Response {.jsstfunc: "Response.error".} =
 func sok(response: Response): bool {.jsfget: "ok".} =
   return response.status in 200u16 .. 299u16
 
-func surl(response: Response): string {.jsfget: "url".} =
-  if response.responseType == TYPE_ERROR:
+func surl*(response: Response): string {.jsfget: "url".} =
+  if response.responseType == rtError or response.url == nil:
     return ""
   return $response.url
 
@@ -178,8 +182,7 @@ proc onReadBlob(response: Response) =
 proc blob*(response: Response): Promise[JSResult[Blob]] {.jsfunc.} =
   if response.bodyUsed:
     let p = newPromise[JSResult[Blob]]()
-    let err = JSResult[Blob]
-      .err(newTypeError("Body has already been consumed"))
+    let err = JSResult[Blob].err(newTypeError("Body has already been consumed"))
     p.resolve(err)
     return p
   let opaque = BlobOpaque()