about summary refs log tree commit diff stats
path: root/src
diff options
context:
space:
mode:
authorbptato <nincsnevem662@gmail.com>2023-09-27 02:48:21 +0200
committerbptato <nincsnevem662@gmail.com>2023-09-27 02:51:41 +0200
commitac3e737867245ac65adfa2352ce6e7fdacc57b18 (patch)
treee747a5891176c7dce618bafaf79d750d5a40416f /src
parent285b6f32c28d1cda403ba33bfb2d22c34fab2a1e (diff)
downloadchawan-ac3e737867245ac65adfa2352ce6e7fdacc57b18.tar.gz
buffer: simplify contentType handling
* remove contentType member of Buffer object
* add ishtml to reduce string comparisons
* consistent spelling: contenttype -> contentType
Diffstat (limited to 'src')
-rw-r--r--src/io/serialize.nim6
-rw-r--r--src/loader/loader.nim4
-rw-r--r--src/loader/response.nim6
-rw-r--r--src/local/container.nim8
-rw-r--r--src/local/pager.nim21
-rw-r--r--src/server/buffer.nim44
-rw-r--r--src/types/buffersource.nim2
7 files changed, 44 insertions, 47 deletions
diff --git a/src/io/serialize.nim b/src/io/serialize.nim
index d2e83524..98f3a70a 100644
--- a/src/io/serialize.nim
+++ b/src/io/serialize.nim
@@ -391,7 +391,7 @@ proc swrite*(stream: Stream, source: BufferSource) =
   of LOAD_REQUEST: stream.swrite(source.request)
   of LOAD_PIPE: stream.swrite(source.fd)
   stream.swrite(source.location)
-  stream.swrite(source.contenttype)
+  stream.swrite(source.contentType)
   stream.swrite(source.charset)
 
 proc sread*(stream: Stream, source: var BufferSource) =
@@ -408,7 +408,7 @@ proc sread*(stream: Stream, source: var BufferSource) =
     source = BufferSource(t: LOAD_PIPE)
     stream.sread(source.fd)
   stream.sread(source.location)
-  stream.sread(source.contenttype)
+  stream.sread(source.contentType)
   stream.sread(source.charset)
 
 func slen*(source: BufferSource): int =
@@ -418,4 +418,4 @@ func slen*(source: BufferSource): int =
   of LOAD_REQUEST: result += slen(source.request)
   of LOAD_PIPE: result += slen(source.fd)
   result += slen(source.location)
-  result += slen(source.contenttype)
+  result += slen(source.contentType)
diff --git a/src/loader/loader.nim b/src/loader/loader.nim
index 6ab3ee9b..6cd17f44 100644
--- a/src/loader/loader.nim
+++ b/src/loader/loader.nim
@@ -312,10 +312,10 @@ proc applyHeaders(loader: FileLoader, request: Request, response: Response) =
     # it breaks mailcap named attributes other than charset.)
     # Ideally, contentType would be a separate object type.
     let header = response.headers.table["Content-Type"][0].toLowerAscii()
-    response.contenttype = header.until(';').strip().toLowerAscii()
+    response.contentType = header.until(';').strip().toLowerAscii()
     response.charset = getCharset(header.getAttribute("charset"))
   else:
-    response.contenttype = guessContentType($response.url.path,
+    response.contentType = guessContentType($response.url.path,
       "application/octet-stream", DefaultGuess)
   if "Location" in response.headers.table:
     if response.status in 301u16..303u16 or response.status in 307u16..308u16:
diff --git a/src/loader/response.nim b/src/loader/response.nim
index 1133a5e4..8ad98f84 100644
--- a/src/loader/response.nim
+++ b/src/loader/response.nim
@@ -17,7 +17,7 @@ type
     fd*: int
     body*: Stream
     bodyUsed* {.jsget.}: bool
-    contenttype*: string
+    contentType*: string
     status* {.jsget.}: uint16
     headers* {.jsget.}: Headers
     redirect*: Request
@@ -75,11 +75,11 @@ proc blob(response: Response): Promise[JSResult[Blob]] {.jsfunc.} =
   response.bodyRead = nil
   return bodyRead.then(proc(s: string): JSResult[Blob] =
     if s.len == 0:
-      return ok(newBlob(nil, 0, response.contenttype, nil))
+      return ok(newBlob(nil, 0, response.contentType, nil))
     GC_ref(s)
     let deallocFun = proc() =
       GC_unref(s)
-    let blob = newBlob(unsafeAddr s[0], s.len, response.contenttype, deallocFun)
+    let blob = newBlob(unsafeAddr s[0], s.len, response.contentType, deallocFun)
     ok(blob))
 
 proc json(ctx: JSContext, this: Response): Promise[JSResult[JSValue]]
diff --git a/src/local/container.nim b/src/local/container.nim
index fb48e89e..ad98419d 100644
--- a/src/local/container.nim
+++ b/src/local/container.nim
@@ -181,7 +181,7 @@ func charset*(container: Container): Charset =
   return container.source.charset
 
 func contentType*(container: Container): Option[string] {.jsfget.} =
-  return container.source.contenttype
+  return container.source.contentType
 
 func lineLoaded(container: Container, y: int): bool =
   return y - container.lineshift in 0..container.lines.high
@@ -836,9 +836,9 @@ proc load(container: Container) =
             "application/octet-stream", container.config.mimeTypes)
           if contentType != "application/octet-stream":
             container.iface.setContentType(contentType)
-          container.source.contenttype = some(contentType)
-        elif res.contentType != "":
-          container.source.contenttype = some(res.contentType)
+          container.source.contentType = some(contentType)
+        else:
+          container.source.contentType = some(res.contentType)
         container.triggerEvent(CHECK_MAILCAP)
       else:
         container.setLoadInfo("")
diff --git a/src/local/pager.nim b/src/local/pager.nim
index eb3f0ca0..b07d300e 100644
--- a/src/local/pager.nim
+++ b/src/local/pager.nim
@@ -422,7 +422,7 @@ proc dupeBuffer2(pager: Pager, container: Container, location: URL,
   let contentType = if contentType != "":
     some(contentType)
   else:
-    container.contenttype
+    container.contentType
   let location = if location != nil:
     location
   else:
@@ -430,7 +430,7 @@ proc dupeBuffer2(pager: Pager, container: Container, location: URL,
   let source = BufferSource(
     t: CLONE,
     location: location,
-    contenttype: contentType,
+    contentType: contentType,
     clonepid: container.process,
   )
   let pipeTo = pager.newBuffer(container.config, source, container.title)
@@ -575,11 +575,11 @@ proc toggleSource(pager: Pager) {.jsfunc.} =
   if pager.container.sourcepair != nil:
     pager.setContainer(pager.container.sourcepair)
   else:
-    let contenttype = if pager.container.contentType.get("") == "text/html":
+    let contentType = if pager.container.contentType.get("") == "text/html":
       "text/plain"
     else:
       "text/html"
-    let container = pager.dupeBuffer2(pager.container, nil, contenttype)
+    let container = pager.dupeBuffer2(pager.container, nil, contentType)
     container.sourcepair = pager.container
     pager.container.sourcepair = container
     pager.addContainer(container)
@@ -660,7 +660,7 @@ proc gotoURL(pager: Pager, request: Request, prevurl = none(URL),
     let source = BufferSource(
       t: LOAD_REQUEST,
       request: request,
-      contenttype: ctype,
+      contentType: ctype,
       charset: cs,
       location: request.url
     )
@@ -733,7 +733,7 @@ proc readPipe0*(pager: Pager, ctype: Option[string], cs: Charset,
   let source = BufferSource(
     t: LOAD_PIPE,
     fd: fd,
-    contenttype: some(ctype.get("text/plain")),
+    contentType: some(ctype.get("text/plain")),
     charset: cs,
     location: location
   )
@@ -850,7 +850,7 @@ proc load(pager: Pager, s = "") {.jsfunc.} =
 # Reload the page in a new buffer, then kill the previous buffer.
 proc reload(pager: Pager) {.jsfunc.} =
   pager.gotoURL(newRequest(pager.container.source.location), none(URL),
-    pager.container.contenttype, replace = pager.container)
+    pager.container.contentType, replace = pager.container)
 
 proc setEnvVars(pager: Pager) {.jsfunc.} =
   try:
@@ -1042,11 +1042,11 @@ proc runMailcapWriteFile(pager: Pager, container: Container,
 #TODO add support for edit/compose, better error handling (use Promise[bool]
 # instead of tuple[EmptyPromise, bool])
 proc checkMailcap(pager: Pager, container: Container): (EmptyPromise, bool) =
-  if container.contenttype.isNone:
+  if container.contentType.isNone:
     return (nil, true)
   if container.source.t == CLONE:
     return (nil, true) # clone cannot use mailcap
-  let contentType = container.contenttype.get
+  let contentType = container.contentType.get
   if contentType == "text/html":
     # We support HTML natively, so it would make little sense to execute
     # mailcap filters for it.
@@ -1089,7 +1089,8 @@ proc handleEvent0(pager: Pager, container: Container, event: ContainerEvent): bo
     dec pager.numload
     pager.deleteContainer(container)
     if container.retry.len > 0:
-      pager.gotoURL(newRequest(container.retry.pop()), ctype = container.contenttype)
+      pager.gotoURL(newRequest(container.retry.pop()),
+        ctype = container.contentType)
     else:
       let errorMessage = getLoaderErrorMessage(container.code)
       pager.alert("Can't load " & $container.source.location & " (" &
diff --git a/src/server/buffer.nim b/src/server/buffer.nim
index 3be0fdcf..b1c67f78 100644
--- a/src/server/buffer.nim
+++ b/src/server/buffer.nim
@@ -89,7 +89,6 @@ type
     fd: int # file descriptor of buffer source
     alive: bool
     readbufsize: int
-    contenttype: string #TODO already stored in source
     lines: FlexibleGrid
     rendered: bool
     source: BufferSource
@@ -116,6 +115,7 @@ type
     savetask: bool
     hovertext: array[HoverType, string]
     estream: Stream # error stream
+    ishtml: bool
 
   InterfaceOpaque = ref object
     stream: Stream
@@ -547,8 +547,7 @@ proc gotoAnchor*(buffer: Buffer): tuple[x, y: int] {.proxy.} =
   return (-1, -1)
 
 proc do_reshape(buffer: Buffer) =
-  case buffer.contenttype
-  of "text/html":
+  if buffer.ishtml:
     if buffer.viewport == nil:
       buffer.viewport = Viewport(window: buffer.attrs)
     let ret = renderDocument(buffer.document, buffer.userstyle,
@@ -624,7 +623,7 @@ proc loadResource(buffer: Buffer, elem: HTMLLinkElement): EmptyPromise =
           let res = res.get
           #TODO we should use ReadableStreams for this (which would allow us to
           # parse CSS asynchronously)
-          if res.contenttype == "text/css":
+          if res.contentType == "text/css":
             return res.text()
           res.unregisterFun()
       ).then(proc(s: JSResult[string]) =
@@ -649,7 +648,7 @@ proc loadResource(buffer: Buffer, elem: HTMLImageElement): EmptyPromise =
         if res.isErr:
           return
         let res = res.get
-        if res.contenttype == "image/png":
+        if res.contentType == "image/png":
           #TODO using text() for PNG is wrong
           return res.text()
       ).then(proc(pngData: JSResult[string]) =
@@ -696,9 +695,6 @@ proc connect*(buffer: Buffer): ConnectResult {.proxy.} =
   let source = buffer.source
   # Warning: source content type overrides received content types, but source
   # charset is just a fallback.
-  let setct = source.contenttype.isNone
-  if not setct:
-    buffer.contenttype = source.contenttype.get
   var charset = source.charset
   var needsAuth = false
   var redirect: Request
@@ -715,14 +711,14 @@ proc connect*(buffer: Buffer): ConnectResult {.proxy.} =
     buffer.fd = int(s.source.getFd())
     if buffer.istream == nil:
       return ConnectResult(code: ERROR_SOURCE_NOT_FOUND)
-    if setct:
-      buffer.contenttype = "text/plain"
+    if buffer.source.contentType.isNone:
+      buffer.source.contentType = some("text/plain")
   of LOAD_PIPE:
     discard fcntl(source.fd, F_SETFL, fcntl(source.fd, F_GETFL, 0) or O_NONBLOCK)
     buffer.istream = newPosixStream(source.fd)
     buffer.fd = source.fd
-    if setct:
-      buffer.contenttype = "text/plain"
+    if buffer.source.contentType.isNone:
+      buffer.source.contentType = some("text/plain")
   of LOAD_REQUEST:
     let request = source.request
     let response = buffer.loader.doRequest(request, blocking = true, canredir = true)
@@ -730,8 +726,8 @@ proc connect*(buffer: Buffer): ConnectResult {.proxy.} =
       return ConnectResult(code: response.res)
     if response.charset != CHARSET_UNKNOWN:
       charset = charset
-    if setct:
-      buffer.contenttype = response.contenttype
+    if buffer.source.contentType.isNone:
+      buffer.source.contentType = some(response.contentType)
     buffer.istream = response.body
     let fd = SocketStream(response.body).source.getFd()
     buffer.fd = int(fd)
@@ -745,12 +741,14 @@ proc connect*(buffer: Buffer): ConnectResult {.proxy.} =
     if "Referrer-Policy" in response.headers.table:
       referrerpolicy = getReferrerPolicy(response.headers.table["Referrer-Policy"][0])
   buffer.connected = true
+  let contentType = buffer.source.contentType.get("")
+  buffer.ishtml = contentType == "text/html"
   return ConnectResult(
     charset: charset,
     needsAuth: needsAuth,
     redirect: redirect,
     cookies: cookies,
-    contentType: if setct: buffer.contenttype else: ""
+    contentType: contentType
   )
 
 # After connect, pager will call one of the following:
@@ -806,10 +804,10 @@ proc readFromFd*(buffer: Buffer, fd: FileHandle, ishtml: bool) {.proxy.} =
     t: LOAD_PIPE,
     fd: fd,
     location: buffer.source.location,
-    contenttype: some(contentType),
+    contentType: some(contentType),
     charset: buffer.source.charset
   )
-  buffer.contenttype = contentType
+  buffer.ishtml = ishtml
   discard fcntl(fd, F_SETFL, fcntl(fd, F_GETFL, 0) or O_NONBLOCK)
   let ps = newPosixStream(fd)
   buffer.istream = newTeeStream(ps, buffer.sstream, closedest = false)
@@ -817,7 +815,8 @@ proc readFromFd*(buffer: Buffer, fd: FileHandle, ishtml: bool) {.proxy.} =
   buffer.selector.registerHandle(buffer.fd, {Read}, 0)
 
 proc setContentType*(buffer: Buffer, contentType: string) {.proxy.} =
-  buffer.source.contenttype = some(contentType)
+  buffer.source.contentType = some(contentType)
+  buffer.ishtml = contentType == "text/html"
 
 # Create an exact clone of the current buffer.
 # This clone will share the loader process with the previous buffer.
@@ -939,8 +938,7 @@ proc finishLoad(buffer: Buffer): EmptyPromise =
     p.resolve()
     return p
   var p: EmptyPromise
-  case buffer.contenttype
-  of "text/html":
+  if buffer.ishtml:
     buffer.sstream.setPosition(0)
     buffer.available = 0
     if buffer.window == nil:
@@ -1004,8 +1002,7 @@ proc onload(buffer: Buffer) =
       if buffer.readbufsize < BufferSize:
         buffer.readbufsize = min(BufferSize, buffer.readbufsize * 2)
       buffer.available += s.len
-      case buffer.contenttype
-      of "text/html":
+      if buffer.ishtml:
         res.bytes = buffer.available
       else:
         buffer.do_reshape()
@@ -1033,8 +1030,7 @@ proc cancel*(buffer: Buffer): int {.proxy.} =
   if buffer.state != LOADING_PAGE: return
   buffer.istream.close()
   buffer.state = LOADED
-  case buffer.contenttype
-  of "text/html":
+  if buffer.ishtml:
     buffer.sstream.setPosition(0)
     buffer.available = 0
     if buffer.window == nil:
diff --git a/src/types/buffersource.nim b/src/types/buffersource.nim
index 97126ed1..9b4e1814 100644
--- a/src/types/buffersource.nim
+++ b/src/types/buffersource.nim
@@ -14,7 +14,7 @@ type
 
   BufferSource* = object
     location*: URL
-    contenttype*: Option[string] # override
+    contentType*: Option[string] # override
     charset*: Charset # fallback
     case t*: BufferSourceType
     of CLONE: