about summary refs log tree commit diff stats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/client.nim16
-rw-r--r--src/io/buffer.nim13
-rw-r--r--src/io/loader.nim5
-rw-r--r--src/io/request.nim60
-rw-r--r--src/utils/eprint.nim2
5 files changed, 70 insertions, 26 deletions
diff --git a/src/client.nim b/src/client.nim
index de8bd9c9..eb48a30a 100644
--- a/src/client.nim
+++ b/src/client.nim
@@ -11,7 +11,6 @@ import io/cell
 import io/lineedit
 import io/loader
 import io/request
-import io/serialize
 import io/term
 import js/javascript
 import js/regex
@@ -181,7 +180,7 @@ proc gotoUrl(client: Client, request: Request, prevurl = none(Url), force = fals
     let page = client.loader.doRequest(request)
     client.needsauth = page.status == 401 # Unauthorized
     client.redirecturl = page.redirect
-    if page.s != nil:
+    if page.body != nil:
       client.addBuffer()
       g_client = client
       setControlCHook(proc() {.noconv.} =
@@ -189,13 +188,7 @@ proc gotoUrl(client: Client, request: Request, prevurl = none(Url), force = fals
           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.istream = page.body
       client.buffer.location = request.url
       client.setupBuffer()
     else:
@@ -515,7 +508,10 @@ proc checkAuth(client: Client) =
 
 proc followRedirect(client: Client) =
   while client.redirecturl.issome:
-    client.buffer.refreshBuffer()
+    client.statusMode()
+    print("Redirecting to ", $client.redirecturl.get)
+    stdout.flushFile()
+    client.buffer.refreshBuffer(true)
     var buf = client.buffer
     let redirecturl = client.redirecturl.get
     client.redirecturl = none(Url)
diff --git a/src/io/buffer.nim b/src/io/buffer.nim
index bcbaef2d..52a55819 100644
--- a/src/io/buffer.nim
+++ b/src/io/buffer.nim
@@ -15,7 +15,6 @@ import io/cell
 import io/lineedit
 import io/loader
 import io/request
-import io/serialize
 import io/term
 import js/regex
 import layout/box
@@ -847,16 +846,8 @@ proc loadResources(buffer: Buffer, document: Document) =
           let url = url.get
           if url.scheme == buffer.location.scheme:
             let fs = buffer.loader.doRequest(newRequest(url))
-            if fs.s != nil and fs.contenttype == "text/css":
-              var res = newStringStream()
-              while true:
-                var s: string
-                fs.s.sread(s)
-                if s == "": break
-                res.write(s)
-              res.setPosition(0)
-              let sheet = parseStylesheet(res)
-              elem.sheet = sheet
+            if fs.body != nil and fs.contenttype == "text/css":
+              elem.sheet = parseStylesheet(fs.body)
 
     for child in elem.children_rev:
       stack.add(child)
diff --git a/src/io/loader.nim b/src/io/loader.nim
index 50a5c1c7..4a1e35e7 100644
--- a/src/io/loader.nim
+++ b/src/io/loader.nim
@@ -93,10 +93,9 @@ proc doRequest*(loader: FileLoader, request: Request): LoadResult =
       loader.ostream.sread(result.status)
       loader.ostream.sread(result.contenttype)
       loader.ostream.sread(result.redirect)
-      result.s = loader.ostream
+      result.body = newReadableStream(loader.ostream)
   else:
-    eprint "Error: no loader process"
-    quit(1)
+    raise newException(Defect, "Error: no loader process")
 
 proc newFileLoader*(defaultHeaders: HeaderList): FileLoader =
   new(result)
diff --git a/src/io/request.nim b/src/io/request.nim
index 86bfe834..789f92aa 100644
--- a/src/io/request.nim
+++ b/src/io/request.nim
@@ -19,13 +19,18 @@ type
     multipart*: Option[MimeData]
 
   LoadResult* = object
-    s*: Stream
+    body*: ReadableStream
     res*: int
     contenttype*: string
     status*: int
     headers*: HeaderList
     redirect*: Option[Url]
 
+  ReadableStream* = ref object of Stream
+    isource*: Stream
+    buf: string
+    isend: bool
+
   HeaderList* = object
     table*: Table[string, seq[string]]
 
@@ -47,6 +52,59 @@ iterator pairs*(headers: HeaderList): (string, string) =
     for v in vs:
       yield (k, v)
 
+proc newReadableStream*(isource: Stream): ReadableStream =
+  new(result)
+  result.isource = isource
+  result.readDataImpl = (proc(s: Stream, buffer: pointer, bufLen: int): int =
+    var s = ReadableStream(s)
+    if s.atEnd:
+      return 0
+    while s.buf.len < bufLen:
+      var len: int
+      s.isource.read(len)
+      if len == 0:
+        result = s.buf.len
+        copyMem(buffer, addr(s.buf[0]), result)
+        s.buf = s.buf.substr(result)
+        s.isend = true
+        return
+      var nbuf: string
+      s.isource.readStr(len, nbuf)
+      s.buf &= nbuf
+    assert s.buf.len >= bufLen
+    result = bufLen
+    copyMem(buffer, addr(s.buf[0]), result)
+    s.buf = s.buf.substr(result)
+    if s.buf.len == 0:
+      var len: int
+      s.isource.read(len)
+      if len == 0:
+        s.isend = true
+      else:
+        s.isource.readStr(len, s.buf)
+  )
+  result.atEndImpl = (proc(s: Stream): bool =
+    return ReadableStream(s).isend
+  )
+  result.closeImpl = (proc(s: Stream) = {.cast(tags: [WriteIOEffect]).}: #TODO TODO TODO ew.
+    var s = ReadableStream(s)
+    if s.isend: return
+    s.buf = ""
+    while true:
+      var len: int
+      s.isource.read(len)
+      if len == 0:
+        s.isend = true
+        break
+      s.isource.setPosition(s.isource.getPosition() + len)
+  )
+  var len: int
+  result.isource.read(len)
+  if len == 0:
+    result.isend = true
+  else:
+    result.isource.readStr(len, result.buf)
+
 func newHeaderList*(): HeaderList =
   discard
 
diff --git a/src/utils/eprint.nim b/src/utils/eprint.nim
index ac4963fb..6a76d250 100644
--- a/src/utils/eprint.nim
+++ b/src/utils/eprint.nim
@@ -1,6 +1,6 @@
 {.used.}
 
-template eprint*(s: varargs[string, `$`]) = {.cast(noSideEffect).}:
+template eprint*(s: varargs[string, `$`]) = {.cast(noSideEffect), cast(tags: []), cast(raises: []).}:
   var a = false
   when nimVm:
     var o = ""