about summary refs log blame commit diff stats
path: root/src/loader/loaderhandle.nim
blob: 2c99981380ac9e81f941099f2c0ca92e21ff13d9 (plain) (tree)
1
2
3
4
5
6
7



                     


                      

































































                                                                              
import net
import streams

import io/posixstream
import io/serialize
import io/socketstream
import loader/headers

type LoaderHandle* = ref object
  ostream: Stream
  # 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
  sostream: Stream # saved ostream when redirected

# Create a new loader handle, with the output stream ostream.
proc newLoaderHandle*(ostream: Stream, canredir: bool): LoaderHandle =
  return LoaderHandle(ostream: ostream, canredir: canredir)

proc getFd*(handle: LoaderHandle): int =
  return int(SocketStream(handle.ostream).source.getFd())

proc sendResult*(handle: LoaderHandle, res: int): bool =
  try:
    handle.ostream.swrite(res)
    return true
  except IOError: # broken pipe
    return false

proc sendStatus*(handle: LoaderHandle, status: int): bool =
  try:
    handle.ostream.swrite(status)
    return true
  except IOError: # broken pipe
    return false

proc sendHeaders*(handle: LoaderHandle, headers: Headers): bool =
  try:
    handle.ostream.swrite(headers)
    if handle.canredir:
      var redir: bool
      handle.ostream.sread(redir)
      if redir:
        let fd = SocketStream(handle.ostream).recvFileHandle()
        handle.sostream = handle.ostream
        let stream = newPosixStream(fd)
        handle.ostream = stream
    return true
  except IOError: # broken pipe
    return false

proc sendData*(handle: LoaderHandle, p: pointer, nmemb: int): bool =
  try:
    handle.ostream.writeData(p, nmemb)
    return true
  except IOError: # broken pipe
    return false

proc sendData*(handle: LoaderHandle, s: string): bool =
  if s.len > 0:
    return handle.sendData(unsafeAddr s[0], s.len)
  return true

proc close*(handle: LoaderHandle) =
  if handle.sostream != nil:
    try:
      handle.sostream.swrite(true)
    except IOError:
      # ignore error, that just means the buffer has already closed the stream
      discard
    handle.sostream.close()
  handle.ostream.close()