diff options
author | bptato <nincsnevem662@gmail.com> | 2024-03-12 19:51:03 +0100 |
---|---|---|
committer | bptato <nincsnevem662@gmail.com> | 2024-03-12 20:20:24 +0100 |
commit | 22480a38c618aea42285b20868231f247932f2ab (patch) | |
tree | ba9b562124c1c30782ed87cd94122e962b80f637 /src/local | |
parent | 232d861836993d81f7828a2917e8d242a23194e0 (diff) | |
download | chawan-22480a38c618aea42285b20868231f247932f2ab.tar.gz |
loader: remove applyHeaders
Better compute the values we need on-demand at the call sites; this way, we can pass through content type attributes to mailcap too. (Also, remove a bug where applyResponse was called twice.)
Diffstat (limited to 'src/local')
-rw-r--r-- | src/local/client.nim | 5 | ||||
-rw-r--r-- | src/local/container.nim | 19 | ||||
-rw-r--r-- | src/local/pager.nim | 37 |
3 files changed, 31 insertions, 30 deletions
diff --git a/src/local/client.nim b/src/local/client.nim index 0d1bf063..6b605311 100644 --- a/src/local/client.nim +++ b/src/local/client.nim @@ -518,8 +518,9 @@ proc handleRead(client: Client, fd: int) = let response = stream.readResponse(container.request) if response.body == nil: client.pager.fail(container, response.getErrorMessage()) - elif response.redirect != nil: - client.pager.redirect(container, response) + elif (let redirect = response.getRedirect(container.request); + redirect != nil): + client.pager.redirect(container, response, redirect) response.body.close() else: client.pager.connected(container, response) diff --git a/src/local/container.nim b/src/local/container.nim index 49d8885e..fc3384d9 100644 --- a/src/local/container.nim +++ b/src/local/container.nim @@ -1402,15 +1402,11 @@ proc applyResponse*(container: Container; response: Response) = container.setLoadInfo("Connected to " & $response.url & ". Downloading...") # setup content type; note that isSome means an override so we skip it if container.contentType.isNone: - if response.contentType == "application/octet-stream": - let contentType = guessContentType(container.url.pathname, - "application/octet-stream", container.config.mimeTypes) - if contentType != "application/octet-stream": - container.contentType = some(contentType) - else: - container.contentType = some(response.contentType) - else: - container.contentType = some(response.contentType) + var contentType = response.getContentType() + if contentType == "application/octet-stream": + contentType = container.config.mimeTypes + .guessContentType(container.url.pathname) + container.contentType = some(contentType) # setup charsets: # * override charset # * network charset @@ -1418,8 +1414,9 @@ proc applyResponse*(container: Container; response: Response) = # HTML may override the last two (but not the override charset). if container.config.charsetOverride != CHARSET_UNKNOWN: container.charsetStack = @[container.config.charsetOverride] - elif response.charset != CHARSET_UNKNOWN: - container.charsetStack = @[response.charset] + elif (let charset = response.getCharset(CHARSET_UNKNOWN); + charset != CHARSET_UNKNOWN): + container.charsetStack = @[charset] else: container.charsetStack = @[] for i in countdown(container.config.charsets.high, 0): diff --git a/src/local/pager.nim b/src/local/pager.nim index cba5a5d3..a0f63aca 100644 --- a/src/local/pager.nim +++ b/src/local/pager.nim @@ -1087,11 +1087,10 @@ type CheckMailcapResult = object ishtml: bool # Pipe output of an x-ansioutput mailcap command to the text/x-ansi handler. -proc ansiDecode(pager: Pager; url: URL; charset: Charset; ishtml: var bool; - fdin: cint): cint = - let entry = pager.mailcap.getMailcapEntry("text/x-ansi", "", url, charset) +proc ansiDecode(pager: Pager; url: URL; ishtml: var bool; fdin: cint): cint = + let entry = pager.mailcap.getMailcapEntry("text/x-ansi", "", url) var canpipe = true - let cmd = unquoteCommand(entry.cmd, "text/x-ansi", "", url, charset, canpipe) + let cmd = unquoteCommand(entry.cmd, "text/x-ansi", "", url, canpipe) if not canpipe: pager.alert("Error: could not pipe to text/x-ansi, decoding as text/plain") return -1 @@ -1283,35 +1282,34 @@ proc filterBuffer(pager: Pager; stream: SocketStream; cmd: string; # pager is suspended until the command exits. #TODO add support for edit/compose, better error handling proc checkMailcap(pager: Pager; container: Container; stream: SocketStream; - istreamOutputId: int): CheckMailcapResult = + istreamOutputId: int; contentType: string): CheckMailcapResult = if container.filter != nil: return pager.filterBuffer(stream, container.filter.cmd, container.ishtml) # contentType must exist, because we set it in applyResponse - let contentType = container.contentType.get - if contentType == "text/html": + let shortContentType = container.contentType.get + if shortContentType == "text/html": # We support text/html natively, so it would make little sense to execute # mailcap filters for it. return CheckMailcapResult(connect: true, fdout: stream.fd, ishtml: true) - if contentType == "text/plain": + if shortContentType == "text/plain": # text/plain could potentially be useful. Unfortunately, many mailcaps # include a text/plain entry with less by default, so it's probably better # to ignore this. return CheckMailcapResult(connect: true, fdout: stream.fd) #TODO callback for outpath or something let url = container.url - let cs = container.charset - let entry = pager.mailcap.getMailcapEntry(contentType, "", url, cs) + let entry = pager.mailcap.getMailcapEntry(contentType, "", url) if entry == nil: return CheckMailcapResult(connect: true, fdout: stream.fd) let tmpdir = pager.tmpdir let ext = url.pathname.afterLast('.') let tempfile = getTempFile(tmpdir, ext) let outpath = if entry.nametemplate != "": - unquoteCommand(entry.nametemplate, contentType, tempfile, url, cs) + unquoteCommand(entry.nametemplate, contentType, tempfile, url) else: tempfile var canpipe = true - let cmd = unquoteCommand(entry.cmd, contentType, outpath, url, cs, canpipe) + let cmd = unquoteCommand(entry.cmd, contentType, outpath, url, canpipe) var ishtml = HTMLOUTPUT in entry.flags let needsterminal = NEEDSTERMINAL in entry.flags putEnv("MAILCAP_URL", $url) @@ -1336,7 +1334,7 @@ proc checkMailcap(pager: Pager; container: Container; stream: SocketStream; pager.runMailcapReadFile(stream, cmd, outpath, pipefdOut) discard close(pipefdOut[1]) # close write let fdout = if not ishtml and ANSIOUTPUT in entry.flags: - pager.ansiDecode(url, cs, ishtml, pipefdOut[0]) + pager.ansiDecode(url, ishtml, pipefdOut[0]) else: pipefdOut[0] delEnv("MAILCAP_URL") @@ -1368,10 +1366,10 @@ proc fail*(pager: Pager; container: Container; errorMessage: string) = else: pager.alert("Can't load " & $container.url & " (" & errorMessage & ")") -proc redirect*(pager: Pager; container: Container; response: Response) = +proc redirect*(pager: Pager; container: Container; response: Response; + request: Request) = # still need to apply response, or we lose cookie jars. container.applyResponse(response) - let request = response.redirect if container.redirectdepth < pager.config.network.max_redirect: if container.url.scheme == request.url.scheme or container.url.scheme == "cgi-bin" or @@ -1395,10 +1393,15 @@ proc connected*(pager: Pager; container: Container; response: Response) = pager.authorize() istream.close() return - let mailcapRes = pager.checkMailcap(container, istream, response.outputId) + let realContentType = if "Content-Type" in response.headers: + response.headers["Content-Type"] + else: + # both contentType and charset must be set by applyResponse. + container.contentType.get & ";charset=" & $container.charset + let mailcapRes = pager.checkMailcap(container, istream, response.outputId, + realContentType) if mailcapRes.connect: container.ishtml = mailcapRes.ishtml - container.applyResponse(response) # buffer now actually exists; create a process for it container.process = pager.forkserver.forkBuffer( container.config, |