blob: 2c99981380ac9e81f941099f2c0ca92e21ff13d9 (
plain) (
tree)
|
|
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()
|