about summary refs log tree commit diff stats
diff options
context:
space:
mode:
authorbptato <nincsnevem662@gmail.com>2022-08-18 21:08:29 +0200
committerbptato <nincsnevem662@gmail.com>2022-08-18 21:08:29 +0200
commit6a990cef8eac9bf11d785d942873f9a5fa614585 (patch)
tree75315119c5787d89b1d0ee4512d445a19d18c068
parent7a4faea7e046a65b2feeea6b2e08254a15eaef4c (diff)
downloadchawan-6a990cef8eac9bf11d785d942873f9a5fa614585.tar.gz
Fix request error handling
-rw-r--r--src/client.nim51
-rw-r--r--src/io/buffer.nim5
-rw-r--r--src/io/http.nim17
-rw-r--r--src/io/loader.nim19
-rw-r--r--src/io/request.nim1
5 files changed, 47 insertions, 46 deletions
diff --git a/src/client.nim b/src/client.nim
index 202090ca..561e821c 100644
--- a/src/client.nim
+++ b/src/client.nim
@@ -175,33 +175,30 @@ var g_client: Client
 proc gotoUrl(client: Client, request: Request, prevurl = none(Url), force = false, ctype = "") =
   setControlCHook(proc() {.noconv.} =
     raise newException(InterruptError, "Interrupted"))
-  if force or prevurl.isnone or not prevurl.get.equals(request.url, true):
-    try:
-      let page = client.loader.getPage(request)
-      client.needsauth = page.status == 401 # Unauthorized
-      client.redirecturl = page.redirect
-      var buf: string
-      page.s.sread(buf)
-      if buf != "": #TODO what about pages with an empty body?
-        client.addBuffer()
-        g_client = client
-        setControlCHook(proc() {.noconv.} =
-          if g_client.buffer.prev != nil or g_client.buffer.next != nil:
-            g_client.discardBuffer()
-          interruptError())
-        client.buffer.contenttype = if ctype != "": ctype else: page.contenttype
-        client.buffer.istream = newStringStream()
-        while true:
-          client.buffer.istream.write(buf)
-          page.s.sread(buf)
-          if buf == "": break
-        client.buffer.istream.setPosition(0)
-        client.buffer.location = request.url
-        client.setupBuffer()
-      else:
-        loadError("Couldn't load " & $request.url)
-    except IOError, OSError:
-      loadError("Couldn't load " & $request.url)
+  if force or prevurl.isnone or not prevurl.get.equals(request.url, true) or
+      prevurl.get.equals(request.url) or request.httpmethod != HTTP_GET:
+    let page = client.loader.doRequest(request)
+    client.needsauth = page.status == 401 # Unauthorized
+    client.redirecturl = page.redirect
+    if page.s != nil:
+      client.addBuffer()
+      g_client = client
+      setControlCHook(proc() {.noconv.} =
+        if g_client.buffer.prev != nil or g_client.buffer.next != nil:
+          g_client.discardBuffer()
+        interruptError())
+      client.buffer.contenttype = if ctype != "": ctype else: page.contenttype
+      client.buffer.istream = newStringStream()
+      while true:
+        var buf: string
+        page.s.sread(buf)
+        if buf == "": break
+        client.buffer.istream.write(buf)
+      client.buffer.istream.setPosition(0)
+      client.buffer.location = request.url
+      client.setupBuffer()
+    else:
+      loadError("Couldn't load " & $request.url & " (" & $page.res & ")")
   elif client.buffer != nil and prevurl.issome and prevurl.get.equals(request.url, true):
     if client.buffer.hasAnchor(request.url.anchor):
       client.dupeBuffer(request.url.some)
diff --git a/src/io/buffer.nim b/src/io/buffer.nim
index 13add309..bcbaef2d 100644
--- a/src/io/buffer.nim
+++ b/src/io/buffer.nim
@@ -846,14 +846,15 @@ proc loadResources(buffer: Buffer, document: Document) =
         if url.issome:
           let url = url.get
           if url.scheme == buffer.location.scheme:
-            let fs = buffer.loader.getPage(newRequest(url))
+            let fs = buffer.loader.doRequest(newRequest(url))
             if fs.s != nil and fs.contenttype == "text/css":
               var res = newStringStream()
               while true:
                 var s: string
-                buffer.istream.sread(s)
+                fs.s.sread(s)
                 if s == "": break
                 res.write(s)
+              res.setPosition(0)
               let sheet = parseStylesheet(res)
               elem.sheet = sheet
 
diff --git a/src/io/http.nim b/src/io/http.nim
index 221648f3..cda70bf1 100644
--- a/src/io/http.nim
+++ b/src/io/http.nim
@@ -1,6 +1,7 @@
 import options
 import streams
 import strutils
+import tables
 
 import bindings/curl
 import io/request
@@ -33,6 +34,7 @@ proc curlWriteHeader(p: cstring, size: csize_t, nitems: csize_t, userdata: point
   let headers = cast[HeaderResult](userdata)
   if not headers.statusline:
     headers.statusline = true
+    headers.ostream.swrite(int(CURLE_OK))
     var status: int
     headers.curl.getinfo(CURLINFO_RESPONSE_CODE, addr status)
     headers.ostream.swrite(status)
@@ -45,8 +47,9 @@ proc curlWriteHeader(p: cstring, size: csize_t, nitems: csize_t, userdata: point
     headers.ostream.swrite(headers.headers.getOrDefault("Content-Type").until(';'))
     var urlp: cstring
     headers.curl.getinfo(CURLINFO_REDIRECT_URL, addr urlp)
-    if urlp != nil:
-      headers.ostream.swrite(parseUrl($urlp, some(headers.request.url)))
+    if "Location" in headers.headers.table:
+      let location = headers.headers.table["Location"][0]
+      headers.ostream.swrite(parseUrl(location, some(headers.request.url)))
     else:
       headers.ostream.swrite(none(Url))
     return nitems
@@ -117,10 +120,12 @@ proc loadHttp*(request: Request, ostream: Stream) =
     curl.setopt(CURLOPT_HTTPHEADER, slist)
 
   let res = curl_easy_perform(curl)
-  if res == CURLE_OK: # TODO handle errors
-    discard
-  ostream.swrite("")
-  ostream.flush()
+  if res == CURLE_OK:
+    ostream.swrite("")
+    ostream.flush()
+  else:
+    ostream.swrite(int(res))
+    ostream.flush()
 
   curl_easy_cleanup(curl)
   if mime != nil:
diff --git a/src/io/loader.nim b/src/io/loader.nim
index 1fb6e7b7..4adf64bc 100644
--- a/src/io/loader.nim
+++ b/src/io/loader.nim
@@ -41,12 +41,10 @@ proc loadFile(url: Url, ostream: Stream) =
     let path = url.path.serialize_unicode()
   let istream = newFileStream(path, fmRead)
   if istream == nil:
-    ostream.swrite(404) # file not found
-    ostream.swrite("")
-    ostream.swrite(none(Url))
-    ostream.swrite("")
+    ostream.swrite(1)
     ostream.flush()
   else:
+    ostream.swrite(0)
     ostream.swrite(200) # ok
     ostream.swrite(guessContentType(path))
     ostream.swrite(none(Url))
@@ -98,10 +96,12 @@ proc doRequest*(loader: FileLoader, request: Request): LoadResult =
   if loader.istream != nil:
     loader.istream.swrite(request)
     loader.istream.flush()
-    loader.ostream.sread(result.status)
-    loader.ostream.sread(result.contenttype)
-    loader.ostream.sread(result.redirect)
-    result.s = loader.ostream
+    loader.ostream.sread(result.res)
+    if result.res == 0:
+      loader.ostream.sread(result.status)
+      loader.ostream.sread(result.contenttype)
+      loader.ostream.sread(result.redirect)
+      result.s = loader.ostream
   else:
     eprint "Error: no loader process"
     quit(1)
@@ -147,6 +147,3 @@ proc newFileLoader*(defaultHeaders: HeaderList): FileLoader =
 
 proc newFileLoader*(): FileLoader =
   newFileLoader(DefaultHeaders)
-
-proc getPage*(loader: FileLoader, request: Request): LoadResult =
-  loader.doRequest(request)
diff --git a/src/io/request.nim b/src/io/request.nim
index 68706c49..5e62dbc4 100644
--- a/src/io/request.nim
+++ b/src/io/request.nim
@@ -26,6 +26,7 @@ type
 
   LoadResult* = object
     s*: Stream
+    res*: int
     contenttype*: string
     status*: int
     headers*: HeaderList