about summary refs log tree commit diff stats
diff options
context:
space:
mode:
authorbptato <nincsnevem662@gmail.com>2023-01-01 19:52:49 +0100
committerbptato <nincsnevem662@gmail.com>2023-01-01 20:02:22 +0100
commit5da4c6e629dd4a0647fd3fe06906445eea65b867 (patch)
treec116a41e32444512cd13e4c18327f65c8d868fad
parent1a24350ee44859f6b3370ac15e8875a79fa7ae9b (diff)
downloadchawan-5da4c6e629dd4a0647fd3fe06906445eea65b867.tar.gz
loader: proper redirect handling
-rw-r--r--src/buffer/buffer.nim2
-rw-r--r--src/buffer/container.nim8
-rw-r--r--src/display/pager.nim7
-rw-r--r--src/io/loader.nim17
-rw-r--r--src/io/request.nim2
5 files changed, 24 insertions, 12 deletions
diff --git a/src/buffer/buffer.nim b/src/buffer/buffer.nim
index 7b38b255..e07e9146 100644
--- a/src/buffer/buffer.nim
+++ b/src/buffer/buffer.nim
@@ -525,7 +525,7 @@ proc loadResources(buffer: Buffer, document: Document) =
 type ConnectResult* = object
   code*: int
   needsAuth*: bool
-  redirect*: Option[URL]
+  redirect*: Request
   contentType*: string
   cookies*: seq[Cookie]
   referrerpolicy*: Option[ReferrerPolicy]
diff --git a/src/buffer/container.nim b/src/buffer/container.nim
index 2d2ff73e..a42422e5 100644
--- a/src/buffer/container.nim
+++ b/src/buffer/container.nim
@@ -46,12 +46,10 @@ type
       password*: bool
     of READ_AREA:
       tvalue*: string
-    of OPEN:
+    of OPEN, REDIRECT:
       request*: Request
     of ANCHOR, NO_ANCHOR:
       anchor*: string
-    of REDIRECT:
-      location*: URL
     of ALERT:
       msg*: string
     of UPDATE:
@@ -685,8 +683,8 @@ proc load(container: Container) =
         container.setLoadInfo("Connected to " & $container.source.location & ". Downloading...")
         if res.needsAuth:
           container.triggerEvent(NEEDS_AUTH)
-        if res.redirect.isSome:
-          container.triggerEvent(ContainerEvent(t: REDIRECT, location: res.redirect.get))
+        if res.redirect != nil:
+          container.triggerEvent(ContainerEvent(t: REDIRECT, request: res.redirect))
         if res.contentType != "":
           container.contenttype = some(res.contentType)
         return container.iface.load()
diff --git a/src/display/pager.nim b/src/display/pager.nim
index bc9a33c1..3ba54032 100644
--- a/src/display/pager.nim
+++ b/src/display/pager.nim
@@ -768,9 +768,10 @@ proc handleEvent0(pager: Pager, container: Container, event: ContainerEvent): bo
       pager.authorize()
   of REDIRECT:
     if container.redirectdepth < pager.config.maxredirect:
-      let redirect = event.location
-      pager.alert("Redirecting to " & $redirect)
-      pager.gotoURL(newRequest(redirect), some(container.source.location), replace = container, redirectdepth = container.redirectdepth + 1, referrer = pager.container)
+      pager.alert("Redirecting to " & $event.request.url)
+      pager.gotoURL(event.request, some(container.source.location),
+        replace = container, redirectdepth = container.redirectdepth + 1,
+        referrer = pager.container)
     else:
       pager.alert("Error: maximum redirection depth reached")
       pager.deleteContainer(container)
diff --git a/src/io/loader.nim b/src/io/loader.nim
index 71cfd2ff..4931d40b 100644
--- a/src/io/loader.nim
+++ b/src/io/loader.nim
@@ -130,9 +130,22 @@ proc doRequest*(loader: FileLoader, request: Request, blocking = true): Response
     else:
       result.contenttype = guessContentType($request.url.path)
     if "Location" in result.headers.table:
-      if result.status in [201, 301, 302, 303, 307, 308]:
+      if result.status in 301..303 or result.status in 307..308:
         let location = result.headers.table["Location"][0]
-        result.redirect = parseUrl(location, some(request.url))
+        let url = parseUrl(location, some(request.url))
+        if url.isSome:
+          if (result.status == 303 and
+              request.httpmethod notin {HTTP_GET, HTTP_HEAD}) or
+              (result.status == 301 or result.status == 302 and
+              request.httpmethod == HTTP_POST):
+            result.redirect = newRequest(url.get, HTTP_GET,
+              mode = request.mode, credentialsMode = request.credentialsMode,
+              destination = request.destination)
+          else:
+            result.redirect = newRequest(url.get, request.httpmethod,
+              body = request.body, multipart = request.multipart,
+              mode = request.mode, credentialsMode = request.credentialsMode,
+              destination = request.destination)
     # Only a stream of the response body may arrive after this point.
     result.body = stream
     if not blocking:
diff --git a/src/io/request.nim b/src/io/request.nim
index 79ba7c0d..8837a1f9 100644
--- a/src/io/request.nim
+++ b/src/io/request.nim
@@ -51,7 +51,7 @@ type
     contenttype* {.jsget.}: string
     status* {.jsget.}: int
     headers* {.jsget.}: HeaderList
-    redirect* {.jsget.}: Option[Url]
+    redirect*: Request
  
   ReadableStream* = ref object of Stream
     isource*: Stream