diff options
author | bptato <nincsnevem662@gmail.com> | 2024-02-25 04:01:20 +0100 |
---|---|---|
committer | bptato <nincsnevem662@gmail.com> | 2024-02-25 04:01:20 +0100 |
commit | 929b85d06cfa97cf7b211b447fdd157384e028e3 (patch) | |
tree | d1f45cc6ed735e1015602b92e65b752ad908b99b | |
parent | 6e98894199442e2213dc89e0c5fe970029f05b65 (diff) | |
download | chawan-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.nim | 16 | ||||
-rw-r--r-- | src/loader/loaderhandle.nim | 2 | ||||
-rw-r--r-- | src/loader/request.nim | 17 | ||||
-rw-r--r-- | src/server/buffer.nim | 16 |
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) ) |