about summary refs log tree commit diff stats
diff options
context:
space:
mode:
authorbptato <nincsnevem662@gmail.com>2024-02-25 04:01:20 +0100
committerbptato <nincsnevem662@gmail.com>2024-02-25 04:01:20 +0100
commit929b85d06cfa97cf7b211b447fdd157384e028e3 (patch)
treed1f45cc6ed735e1015602b92e65b752ad908b99b
parent6e98894199442e2213dc89e0c5fe970029f05b65 (diff)
downloadchawan-929b85d06cfa97cf7b211b447fdd157384e028e3.tar.gz
buffer: fix rewind with mailcap entries
Cache mailcap entry output too, then delete it when the buffer can no
longer read from it.

(Maybe it would be useful to instead preserve it and allow viewSource
for HTML output too? Hmm.)
-rw-r--r--src/loader/loader.nim16
-rw-r--r--src/loader/loaderhandle.nim2
-rw-r--r--src/loader/request.nim17
-rw-r--r--src/server/buffer.nim16
4 files changed, 41 insertions, 10 deletions
diff --git a/src/loader/loader.nim b/src/loader/loader.nim
index 5a3a85bd..fee84782 100644
--- a/src/loader/loader.nim
+++ b/src/loader/loader.nim
@@ -85,6 +85,7 @@ type
     UNREF
     SET_REFERRER_POLICY
     PASS_FD
+    REMOVE_CACHED_URL
 
   LoaderContext = ref object
     refcount: int
@@ -201,6 +202,7 @@ proc addFd(ctx: LoaderContext, handle: LoaderHandle, originalUrl: URL) =
 proc loadStream(ctx: LoaderContext, handle: LoaderHandle, request: Request,
     originalUrl: URL) =
   ctx.passedFdMap.withValue(request.url.host, fdp):
+    handle.canredir = request.canredir
     handle.sendResult(0)
     handle.sendStatus(200)
     handle.sendHeaders(newHeaders())
@@ -430,6 +432,13 @@ proc acceptConnection(ctx: LoaderContext) =
       let fd = stream.recvFileHandle()
       ctx.passedFdMap[id] = fd
       stream.close()
+    of REMOVE_CACHED_URL:
+      var surl: string
+      stream.sread(surl)
+      ctx.cacheMap.withValue(surl, p):
+        discard unlink(cstring(p[]))
+        ctx.cacheMap.del(surl)
+      stream.close()
   except ErrorBrokenPipe:
     # receiving end died while reading the file; give up.
     stream.close()
@@ -837,3 +846,10 @@ proc passFd*(pid: Pid, id: string, fd: FileHandle) =
     stream.swrite(id)
     stream.sendFileHandle(fd)
     stream.close()
+
+proc removeCachedURL*(loader: FileLoader, surl: string) =
+  let stream = connectSocketStream(loader.process)
+  if stream != nil:
+    stream.swrite(REMOVE_CACHED_URL)
+    stream.swrite(surl)
+    stream.close()
diff --git a/src/loader/loaderhandle.nim b/src/loader/loaderhandle.nim
index 11a97bf4..eb6d61ba 100644
--- a/src/loader/loaderhandle.nim
+++ b/src/loader/loaderhandle.nim
@@ -38,7 +38,7 @@ type
     # Only the first handle can be redirected, because a) mailcap can only
     # redirect the first handle and b) async redirects would result in race
     # conditions that would be difficult to untangle.
-    canredir: bool
+    canredir*: bool
     outputs*: seq[OutputHandle]
     cached*: bool
     cacheUrl*: string
diff --git a/src/loader/request.nim b/src/loader/request.nim
index 1d0e31cd..a39cded2 100644
--- a/src/loader/request.nim
+++ b/src/loader/request.nim
@@ -122,15 +122,24 @@ func newRequest*(url: URL, httpMethod = HTTP_GET, headers = newHeaders(),
 func newRequest*(url: URL, httpMethod = HTTP_GET,
     headers: seq[(string, string)] = @[], body = opt(string),
     multipart = opt(FormData), mode = RequestMode.NO_CORS, proxy: URL = nil,
-    canredir = false):
-    Request =
+    canredir = false): Request =
   let hl = newHeaders()
   for pair in headers:
     let (k, v) = pair
     hl.table[k] = @[v]
-  return newRequest(url, httpMethod, hl, body, multipart, mode, proxy = proxy)
+  return newRequest(
+    url,
+    httpMethod,
+    hl,
+    body,
+    multipart,
+    mode,
+    proxy = proxy,
+    canredir = canredir
+  )
 
-func createPotentialCORSRequest*(url: URL, destination: RequestDestination, cors: CORSAttribute, fallbackFlag = false): Request =
+func createPotentialCORSRequest*(url: URL, destination: RequestDestination,
+    cors: CORSAttribute, fallbackFlag = false): Request =
   var mode = if cors == NO_CORS:
     RequestMode.NO_CORS
   else:
diff --git a/src/server/buffer.nim b/src/server/buffer.nim
index 783da17b..7e002a31 100644
--- a/src/server/buffer.nim
+++ b/src/server/buffer.nim
@@ -115,6 +115,7 @@ type
     validateBuf: seq[char]
     charsetStack: seq[Charset]
     charset: Charset
+    tmpCacheFlag: bool
 
   InterfaceOpaque = ref object
     stream: Stream
@@ -629,7 +630,7 @@ proc processData0(buffer: Buffer, data: openArray[char]): bool =
   else:
     var plaintext = buffer.document.findFirst(TAG_PLAINTEXT)
     if plaintext == nil:
-      const s = "<plaintext id='text'>"
+      const s = "<plaintext>"
       doAssert buffer.htmlParser.parseBuffer(s) != PRES_STOP
       plaintext = buffer.document.findFirst(TAG_PLAINTEXT)
     if data.len > 0:
@@ -640,6 +641,7 @@ proc processData0(buffer: Buffer, data: openArray[char]): bool =
         Text(lastChild).data &= text
       else:
         plaintext.insert(buffer.document.createTextNode(text), nil)
+      plaintext.invalid = true
   true
 
 func canSwitch(buffer: Buffer): bool {.inline.} =
@@ -801,7 +803,7 @@ type ConnectResult* = object
   charset*: Charset
 
 proc rewind(buffer: Buffer): bool =
-  let request = newRequest(buffer.url, fromcache = true)
+  let request = newRequest(buffer.request.url, fromcache = true)
   let response = buffer.loader.doRequest(request)
   if response.body == nil:
     return false
@@ -933,12 +935,15 @@ proc redirectToFd*(buffer: Buffer, fd: FileHandle, wait, cache: bool)
   buffer.istream.close()
 
 proc readFromFd*(buffer: Buffer, url: URL, ishtml: bool) {.proxy.} =
-  let request = newRequest(url)
+  let request = newRequest(url, canredir = true)
   buffer.request = request
   buffer.setHTML(ishtml)
   let response = buffer.loader.doRequest(request)
   buffer.istream = response.body
+  buffer.istream.swrite(false) # no redir
+  buffer.istream.swrite(true) # cache on
   buffer.istream.setBlocking(false)
+  buffer.tmpCacheFlag = true
   buffer.fd = response.body.fd
   buffer.selector.registerHandle(buffer.fd, {Read}, 0)
 
@@ -1131,6 +1136,8 @@ proc finishLoad(buffer: Buffer): EmptyPromise =
   buffer.loader.unregistered.add(buffer.fd)
   buffer.fd = -1
   buffer.istream.close()
+  if buffer.tmpCacheFlag:
+    buffer.loader.removeCachedURL($buffer.request.url)
   return buffer.loadResources()
 
 type LoadResult* = tuple[
@@ -1192,8 +1199,7 @@ proc onload(buffer: Buffer) =
           buffer.do_reshape()
           res.lines = buffer.lines.len
           buffer.state = bsLoaded
-          if buffer.document != nil: # may be nil if not buffer.ishtml
-            buffer.document.readyState = rsComplete
+          buffer.document.readyState = rsComplete
           buffer.dispatchLoadEvent()
           buffer.resolveTask(LOAD, res)
         )