From dee468d502a2d2e0aa6ae2f8365c098f72acc0c9 Mon Sep 17 00:00:00 2001 From: bptato Date: Sat, 8 Jun 2024 21:30:32 +0200 Subject: pager, buffer: improve forms, protocol config * refactor form submission * add options to specify form handling per protocol * block cross-protocol POST requests --- src/local/container.nim | 8 ++++---- src/local/pager.nim | 32 +++++++++++++++++++------------- 2 files changed, 23 insertions(+), 17 deletions(-) (limited to 'src/local') diff --git a/src/local/container.nim b/src/local/container.nim index 8439b32a..90e00ebb 100644 --- a/src/local/container.nim +++ b/src/local/container.nim @@ -1489,8 +1489,8 @@ proc readSuccess*(container: Container; s: string; fd = -1) = p.then(proc(res: ReadSuccessResult) = if res.repaint: container.needslines = true - if res.open.isSome: - container.triggerEvent(ContainerEvent(t: cetOpen, request: res.open.get)) + if res.open != nil: + container.triggerEvent(ContainerEvent(t: cetOpen, request: res.open)) ) proc reshape(container: Container): EmptyPromise {.jsfunc.} = @@ -1513,10 +1513,10 @@ proc displaySelect(container: Container; selectResult: SelectResult) = proc onclick(container: Container; res: ClickResult; save: bool) = if res.repaint: container.needslines = true - if res.open.isSome: + if res.open != nil: container.triggerEvent(ContainerEvent( t: cetOpen, - request: res.open.get, + request: res.open, save: save )) if res.select.isSome and not save: diff --git a/src/local/pager.nim b/src/local/pager.nim index 8eb42b65..48856837 100644 --- a/src/local/pager.nim +++ b/src/local/pager.nim @@ -98,7 +98,6 @@ type LineDataAuth = ref object of LineData url: URL - username: string NavDirection = enum ndPrev = "prev" @@ -124,6 +123,7 @@ type devRandom: PosixStream display: FixedGrid forkserver*: ForkServer + formRequestMap*: Table[string, FormRequestType] hasload*: bool # has a page been successfully loaded since startup? inputBuffer*: string # currently uninterpreted characters iregex: Result[Regex, string] @@ -1026,6 +1026,7 @@ proc applySiteconf(pager: Pager; url: var URL; charsetOverride: Charset; images: images, isdump: pager.config.start.headless, charsetOverride: charsetOverride, + protocol: pager.config.protocol ) # Load request in a new buffer. @@ -1231,18 +1232,13 @@ proc updateReadLine*(pager: Pager) = case pager.linemode of lmLocation: pager.loadURL(lineedit.news) of lmUsername: - LineDataAuth(pager.lineData).username = lineedit.news + LineDataAuth(pager.lineData).url.username = lineedit.news pager.setLineEdit(lmPassword, hide = true) of lmPassword: - let data = LineDataAuth(pager.lineData) - let url = newURL(data.url) - url.username = data.username + let url = LineDataAuth(pager.lineData).url url.password = lineedit.news - pager.gotoURL( - newRequest(url), some(pager.container.url), - replace = pager.container, - referrer = pager.container - ) + pager.gotoURL(newRequest(url), some(pager.container.url), + replace = pager.container, referrer = pager.container) pager.lineData = nil of lmCommand: pager.scommand = lineedit.news @@ -1676,6 +1672,9 @@ proc redirect(pager: Pager; container: Container; response: Response; container.url.scheme == "http" and request.url.scheme == "https" or container.url.scheme == "https" and request.url.scheme == "http": pager.redirectTo(container, request) + #TODO perhaps make following behavior configurable? + elif request.url.scheme == "cgi-bin": + pager.alert("Blocked redirection attempt to " & $request.url) else: let url = request.url pager.ask("Warning: switch protocols? " & $url).then(proc(x: bool) = @@ -1708,7 +1707,7 @@ proc connected(pager: Pager; container: Container; response: Response) = container.applyResponse(response, pager.config.external.mime_types) if response.status == 401: # unauthorized pager.setLineEdit(lmUsername) - pager.lineData = LineDataAuth(url: container.url) + pager.lineData = LineDataAuth(url: newURL(container.url)) istream.sclose() return # This forces client to ask for confirmation before quitting. @@ -1863,8 +1862,15 @@ proc handleEvent0(pager: Pager; container: Container; event: ContainerEvent): pager.setLineEdit(lmBufferFile, "") of cetOpen: let url = event.request.url - if not event.save and (pager.container != container or - not container.isHoverURL(url)): + let sameScheme = container.url.scheme == url.scheme + if event.request.httpMethod != hmGet and (not sameScheme or + container.url.scheme in ["http", "https"] and + url.scheme in ["http", "https"]): + pager.alert("Blocked cross-scheme POST: " & $url) + return + #TODO this is horrible UX, async actions shouldn't block input + if pager.container != container or + not event.save and not container.isHoverURL(url): pager.ask("Open pop-up? " & $url).then(proc(x: bool) = if x: pager.gotoURL(event.request, some(container.url), -- cgit 1.4.1-2-gfad0