about summary refs log tree commit diff stats
path: root/src/server
diff options
context:
space:
mode:
authorbptato <nincsnevem662@gmail.com>2024-02-13 12:29:05 +0100
committerbptato <nincsnevem662@gmail.com>2024-02-13 12:29:05 +0100
commit492a9e7cf80ae8e26b03602b5996f471c5edf4be (patch)
tree05c01438f4c8263648c66789b534e87391c51aca /src/server
parent955f5baca85203fbf21f9e734828d694a44777b1 (diff)
downloadchawan-492a9e7cf80ae8e26b03602b5996f471c5edf4be.tar.gz
buffer: more form fixes
Diffstat (limited to 'src/server')
-rw-r--r--src/server/buffer.nim42
1 files changed, 31 insertions, 11 deletions
diff --git a/src/server/buffer.nim b/src/server/buffer.nim
index d0a50284..ef7afc44 100644
--- a/src/server/buffer.nim
+++ b/src/server/buffer.nim
@@ -1,3 +1,5 @@
+from std/strutils import split
+
 import std/macros
 import std/nativesockets
 import std/net
@@ -1176,11 +1178,29 @@ proc serializePlainTextFormData(kvs: seq[(string, string)]): string =
     result &= value
     result &= "\r\n"
 
+func getOutputEncoding(charset: Charset): Charset =
+  if charset in {CHARSET_REPLACEMENT, CHARSET_UTF_16_BE, CHARSET_UTF_16_LE}:
+    return CHARSET_UTF_8
+  return charset
+
+func pickCharset(form: HTMLFormElement): Charset =
+  if form.attrb(atAcceptCharset):
+    let input = form.attr(atAcceptCharset)
+    for label in input.split(AsciiWhitespace):
+      let charset = label.getCharset()
+      if charset != CHARSET_UNKNOWN:
+        return charset.getOutputEncoding()
+    return CHARSET_UTF_8
+  return form.document.charset.getOutputEncoding()
+
 # https://html.spec.whatwg.org/multipage/form-control-infrastructure.html#form-submission-algorithm
 proc submitForm(form: HTMLFormElement, submitter: Element): Option[Request] =
-  if form.constructingentrylist:
-    return
-  let entrylist = form.constructEntryList(submitter).get(@[])
+  if form.constructingEntryList:
+    return none(Request)
+  #TODO submit()
+  let charset = form.pickCharset()
+  discard charset #TODO pass to constructEntryList
+  let entrylist = form.constructEntryList(submitter)
 
   let subAction = submitter.action()
   let action = if subAction != "":
@@ -1188,6 +1208,7 @@ proc submitForm(form: HTMLFormElement, submitter: Element): Option[Request] =
   else:
     $form.document.url
 
+  #TODO encoding-parse
   let url = submitter.document.parseURL(action)
   if url.isNone:
     return none(Request)
@@ -1213,6 +1234,7 @@ proc submitForm(form: HTMLFormElement, submitter: Element): Option[Request] =
 
   template mutateActionUrl() =
     let kvlist = entrylist.toNameValuePairs()
+    #TODO with charset
     let query = serializeApplicationXWWWFormUrlEncoded(kvlist)
     parsedaction.query = some(query)
     return some(newRequest(parsedaction, httpmethod))
@@ -1223,13 +1245,16 @@ proc submitForm(form: HTMLFormElement, submitter: Element): Option[Request] =
     var multipart: Opt[FormData]
     case enctype
     of FORM_ENCODING_TYPE_URLENCODED:
+      #TODO with charset
       let kvlist = entrylist.toNameValuePairs()
       body.ok(serializeApplicationXWWWFormUrlEncoded(kvlist))
       mimeType = $enctype
     of FORM_ENCODING_TYPE_MULTIPART:
+      #TODO with charset
       multipart.ok(serializeMultipartFormData(entrylist))
       mimetype = $enctype
     of FORM_ENCODING_TYPE_TEXT_PLAIN:
+      #TODO with charset
       let kvlist = entrylist.toNameValuePairs()
       body.ok(serializePlainTextFormData(kvlist))
       mimetype = $enctype
@@ -1242,6 +1267,7 @@ proc submitForm(form: HTMLFormElement, submitter: Element): Option[Request] =
 
   template mailWithHeaders() =
     let kvlist = entrylist.toNameValuePairs()
+    #TODO with charset
     let headers = serializeApplicationXWWWFormUrlEncoded(kvlist,
       spaceAsPlus = false)
     parsedaction.query = some(headers)
@@ -1253,6 +1279,7 @@ proc submitForm(form: HTMLFormElement, submitter: Element): Option[Request] =
       let text = serializePlainTextFormData(kvlist)
       percentEncode(text, PathPercentEncodeSet)
     else:
+      #TODO with charset
       serializeApplicationXWWWFormUrlEncoded(kvlist)
     if parsedaction.query.isNone:
       parsedaction.query = some("")
@@ -1262,14 +1289,6 @@ proc submitForm(form: HTMLFormElement, submitter: Element): Option[Request] =
     return some(newRequest(parsedaction, httpmethod))
 
   case scheme
-  of "http", "https", "gopher", "gophers", "cgi-bin":
-    # Note: only http & https are defined by the standard.
-    # We implement gopher, gophers & cgi-bin as HTTP-like protocols.
-    if formmethod == FORM_METHOD_GET:
-      mutateActionUrl
-    else:
-      assert formmethod == FORM_METHOD_POST
-      submitAsEntityBody
   of "ftp", "javascript":
     getActionUrl
   of "data":
@@ -1285,6 +1304,7 @@ proc submitForm(form: HTMLFormElement, submitter: Element): Option[Request] =
       assert formmethod == FORM_METHOD_POST
       mailAsBody
   else:
+    # Note: only http & https are defined by the standard.
     # Assume an HTTP-like protocol.
     if formmethod == FORM_METHOD_GET:
       mutateActionUrl