diff options
-rw-r--r-- | src/config/mailcap.nim | 7 | ||||
-rw-r--r-- | src/io/posixstream.nim | 71 | ||||
-rw-r--r-- | src/io/socketstream.nim | 91 | ||||
-rw-r--r-- | src/loader/loader.nim | 12 | ||||
-rw-r--r-- | src/loader/request.nim | 62 | ||||
-rw-r--r-- | src/local/client.nim | 45 | ||||
-rw-r--r-- | src/local/container.nim | 1 | ||||
-rw-r--r-- | src/local/pager.nim | 2 | ||||
-rw-r--r-- | src/render/rendertext.nim | 11 | ||||
-rw-r--r-- | src/server/buffer.nim | 46 | ||||
-rw-r--r-- | src/server/forkserver.nim | 6 | ||||
-rw-r--r-- | src/types/buffersource.nim | 11 | ||||
-rw-r--r-- | src/types/formdata.nim | 5 |
13 files changed, 127 insertions, 243 deletions
diff --git a/src/config/mailcap.nim b/src/config/mailcap.nim index fc75086d..0caf7f17 100644 --- a/src/config/mailcap.nim +++ b/src/config/mailcap.nim @@ -216,11 +216,10 @@ proc quoteFile(file: string, qs: QuoteState): string = elif qs == QS_NORMAL: s &= '\\' # double-quoted: append normally - of '_', '.', ':', '/': + of AsciiAlphaNumeric, '_', '.', ':', '/': discard # no need to quote - else: - if c notin AsciiAlpha and qs == QS_NORMAL: - s &= '\\' + elif qs == QS_NORMAL: + s &= '\\' s &= c return s diff --git a/src/io/posixstream.nim b/src/io/posixstream.nim index 3aa14191..683d72b8 100644 --- a/src/io/posixstream.nim +++ b/src/io/posixstream.nim @@ -6,6 +6,7 @@ type PosixStream* = ref object of Stream fd*: cint isend*: bool + blocking*: bool ErrorAgain* = object of IOError ErrorBadFD* = object of IOError @@ -33,32 +34,6 @@ proc raisePosixIOError*() = else: raise newException(IOError, $strerror(errno)) -proc psClose(s: Stream) = - let s = cast[PosixStream](s) - discard close(s.fd) - -proc psReadData(s: Stream, buffer: pointer, len: int): int = - assert len != 0 - let s = cast[PosixStream](s) - let wasend = s.isend - let buffer = cast[ptr UncheckedArray[uint8]](buffer) - while result < len: - let n = read(s.fd, addr buffer[result], len - result) - if n < 0: - if result == 0: - result = n - break - elif n == 0: - s.isend = true - break - result += n - if result == 0: - if wasend: - raise newException(EOFError, "eof") - s.isend = true - if result == -1: - raisePosixIOError() - method recvData*(s: PosixStream, buffer: pointer, len: int): int {.base.} = let n = read(s.fd, buffer, len) if n < 0: @@ -69,6 +44,12 @@ method recvData*(s: PosixStream, buffer: pointer, len: int): int {.base.} = s.isend = true return n +proc recvData*(s: PosixStream, buffer: var openArray[uint8]): int {.inline.} = + return s.recvData(addr buffer[0], buffer.len) + +proc recvData*(s: PosixStream, buffer: var openArray[char]): int {.inline.} = + return s.recvData(addr buffer[0], buffer.len) + method sendData*(s: PosixStream, buffer: pointer, len: int): int {.base.} = #TODO use sendData instead let n = write(s.fd, buffer, len) @@ -77,30 +58,42 @@ method sendData*(s: PosixStream, buffer: pointer, len: int): int {.base.} = return n method setBlocking*(s: PosixStream, blocking: bool) {.base.} = + s.blocking = blocking let ofl = fcntl(s.fd, F_GETFL, 0) if blocking: discard fcntl(s.fd, F_SETFL, ofl and not O_NONBLOCK) else: discard fcntl(s.fd, F_SETFL, ofl or O_NONBLOCK) +method sclose*(s: PosixStream) {.base.} = + discard close(s.fd) + +proc psClose(s: Stream) = + PosixStream(s).sclose() + +proc psReadData(s: Stream, buffer: pointer, len: int): int = + let s = PosixStream(s) + assert len != 0 and s.blocking + return s.recvData(buffer, len) + proc psWriteData(s: Stream, buffer: pointer, len: int) = - #TODO use sendData instead - let s = cast[PosixStream](s) - let res = write(s.fd, buffer, len) - if res == -1: - raisePosixIOError() + let s = PosixStream(s) + assert len != 0 and s.blocking + discard s.sendData(buffer, len) proc psAtEnd(s: Stream): bool = - return cast[PosixStream](s).isend + return PosixStream(s).isend + +proc addStreamIface*(ps: PosixStream) = + ps.closeImpl = cast[typeof(ps.closeImpl)](psClose) + ps.readDataImpl = cast[typeof(ps.readDataImpl)](psReadData) + ps.writeDataImpl = cast[typeof(ps.writeDataImpl)](psWriteData) + ps.atEndImpl = psAtEnd proc newPosixStream*(fd: FileHandle): PosixStream = - return PosixStream( - fd: fd, - closeImpl: psClose, - readDataImpl: psReadData, - writeDataImpl: psWriteData, - atEndImpl: psAtEnd - ) + let ps = PosixStream(fd: fd, blocking: true) + ps.addStreamIface() + return ps proc newPosixStream*(path: string, flags, mode: cint): PosixStream = let fd = open(cstring(path), flags, mode) diff --git a/src/io/socketstream.nim b/src/io/socketstream.nim index dd391f21..99f7c2c9 100644 --- a/src/io/socketstream.nim +++ b/src/io/socketstream.nim @@ -1,7 +1,6 @@ import std/nativesockets import std/net import std/os -import std/streams when defined(posix): import std/posix @@ -11,43 +10,6 @@ import io/serversocket type SocketStream* = ref object of PosixStream source*: Socket - blk*: bool - -proc sockReadData(s: Stream, buffer: pointer, len: int): int = - assert len != 0 - let s = SocketStream(s) - let wasend = s.isend - let buffer = cast[ptr UncheckedArray[uint8]](buffer) - if s.blk: - while result < len: - let n = s.source.recv(addr buffer[result], len - result) - if n < 0: - if result == 0: - result = n - break - elif n == 0: - s.isend = true - break - result += n - else: - result = s.source.recv(buffer, len) - if result == 0: - if wasend: - raise newException(EOFError, "eof") - s.isend = true - if result < 0: - raisePosixIOError() - elif result == 0: - s.isend = true - -proc sockWriteData(s: Stream, buffer: pointer, len: int) = - var i = 0 - let buffer = cast[ptr UncheckedArray[uint8]](buffer) - while i < len: - let n = SocketStream(s).source.send(addr buffer[i], len - i) - if n < 0: - raisePosixIOError() - i += n method recvData*(s: SocketStream, buffer: pointer, len: int): int = let n = s.source.recv(buffer, len) @@ -65,49 +27,34 @@ method sendData*(s: SocketStream, buffer: pointer, len: int): int = raisePosixIOError() return n -proc sockAtEnd(s: Stream): bool = - SocketStream(s).isend - -proc sockClose(s: Stream) = {.cast(tags: []).}: #...sigh - let s = SocketStream(s) - s.source.close() - {.compile: "sendfd.c".} -proc sendfd(sock: SocketHandle, fd: cint): int {.importc.} +proc sendfd(sock, fd: cint): int {.importc.} -# See https://stackoverflow.com/a/4491203 proc sendFileHandle*(s: SocketStream, fd: FileHandle) = assert not s.source.hasDataBuffered - let n = sendfd(s.source.getFd(), cint(fd)) + let n = sendfd(s.fd, cint(fd)) if n < 0: raisePosixIOError() assert n == 1 # we send a single nul byte as buf {.compile: "recvfd.c".} -proc recvfd(sock: SocketHandle, fdout: ptr cint): int {.importc.} +proc recvfd(sock: cint, fdout: ptr cint): int {.importc.} proc recvFileHandle*(s: SocketStream): FileHandle = assert not s.source.hasDataBuffered var fd: cint - let n = recvfd(s.source.getFd(), addr fd) + let n = recvfd(s.fd, addr fd) if n < 0: raisePosixIOError() return FileHandle(fd) -func newSocketStream*(): SocketStream = - return SocketStream( - readDataImpl: cast[proc (s: Stream, buffer: pointer, bufLen: int): int - {.nimcall, raises: [Defect, IOError, OSError], tags: [ReadIOEffect], - gcsafe.} - ](sockReadData), # ... ??? - writeDataImpl: sockWriteData, - atEndImpl: sockAtEnd, - closeImpl: sockClose - ) - method setBlocking*(s: SocketStream, blocking: bool) = + s.blocking = blocking s.source.getFd().setBlocking(blocking) +method sclose*(s: SocketStream) = + s.source.close() + # see serversocket.nim for an explanation {.compile: "connect_unix.c".} proc connect_unix_from_c(fd: cint, path: cstring, pathlen: cint): cint @@ -115,8 +62,6 @@ proc connect_unix_from_c(fd: cint, path: cstring, pathlen: cint): cint proc connectSocketStream*(path: string, buffered = true, blocking = true): SocketStream = - result = newSocketStream() - result.blk = blocking let sock = newSocket(Domain.AF_UNIX, SockType.SOCK_STREAM, Protocol.IPPROTO_IP, buffered) if not blocking: @@ -124,22 +69,28 @@ proc connectSocketStream*(path: string, buffered = true, blocking = true): if connect_unix_from_c(cint(sock.getFd()), cstring(path), cint(path.len)) != 0: raiseOSError(osLastError()) - result.source = sock - result.fd = cint(sock.getFd()) + result = SocketStream( + source: sock, + fd: cint(sock.getFd()), + blocking: blocking + ) + result.addStreamIface() proc connectSocketStream*(pid: Pid, buffered = true, blocking = true): SocketStream = try: - connectSocketStream(getSocketPath(pid), buffered, blocking) + return connectSocketStream(getSocketPath(pid), buffered, blocking) except OSError: return nil proc acceptSocketStream*(ssock: ServerSocket, blocking = true): SocketStream = - result = newSocketStream() - result.blk = blocking var sock: Socket ssock.sock.accept(sock, inheritable = true) - result.source = sock if not blocking: sock.getFd().setBlocking(false) - result.fd = cint(sock.getFd()) + result = SocketStream( + blocking: blocking, + source: sock, + fd: cint(sock.getFd()) + ) + result.addStreamIface() diff --git a/src/loader/loader.nim b/src/loader/loader.nim index 11ddefcc..f2d38d61 100644 --- a/src/loader/loader.nim +++ b/src/loader/loader.nim @@ -608,7 +608,7 @@ proc fetch*(loader: FileLoader, input: Request): FetchPromise = stream.swrite(LOAD) stream.swrite(input) stream.flush() - let fd = int(stream.source.getFd()) + let fd = int(stream.fd) loader.registerFun(fd) let promise = FetchPromise() loader.connecting[fd] = ConnectData( @@ -624,7 +624,7 @@ proc reconnect*(loader: FileLoader, data: ConnectData) = stream.swrite(LOAD) stream.swrite(data.request) stream.flush() - let fd = int(stream.source.getFd()) + let fd = int(stream.fd) loader.registerFun(fd) loader.connecting[fd] = ConnectData( promise: data.promise, @@ -638,7 +638,7 @@ proc switchStream*(data: var ConnectData, stream: SocketStream) = proc switchStream*(loader: FileLoader, data: var OngoingData, stream: SocketStream) = data.response.body = stream - let fd = int(stream.source.getFd()) + let fd = int(stream.fd) let realCloseImpl = stream.closeImpl stream.closeImpl = nil data.response.unregisterFun = proc() = @@ -704,7 +704,7 @@ proc onConnected*(loader: FileLoader, fd: int) = response: response, bodyRead: response.bodyRead ) - stream.source.getFd().setBlocking(false) + stream.setBlocking(false) promise.resolve(JSResult[Response].ok(response)) else: var msg: string @@ -724,7 +724,7 @@ proc onRead*(loader: FileLoader, fd: int) = let olen = buffer[].buf.len try: buffer[].buf.setLen(olen + BufferSize) - let n = response.body.readData(addr buffer[].buf[olen], BufferSize) + let n = response.body.recvData(addr buffer[].buf[olen], BufferSize) buffer[].buf.setLen(olen + n) if n == 0: break @@ -743,7 +743,7 @@ proc onError*(loader: FileLoader, fd: int) = when defined(debug): var lbuf {.noinit.}: array[BufferSize, char] if not response.body.atEnd(): - let n = response.body.readData(addr lbuf[0], lbuf.len) + let n = response.body.recvData(addr lbuf[0], lbuf.len) assert n == 0 assert response.body.atEnd() buffer[].bodyRead.resolve(buffer[].buf) diff --git a/src/loader/request.nim b/src/loader/request.nim index fcad1681..1d0e31cd 100644 --- a/src/loader/request.nim +++ b/src/loader/request.nim @@ -1,5 +1,4 @@ import std/options -import std/streams import std/strutils import std/tables @@ -84,11 +83,6 @@ type fromcache*: bool clientId*: StreamId - ReadableStream* = ref object of Stream - isource*: Stream - buf: string - isend: bool - jsDestructor(Request) proc js_url(this: Request): string {.jsfget: "url".} = @@ -105,62 +99,6 @@ iterator pairs*(headers: Headers): (string, string) = for v in vs: yield (k, v) -proc rsReadData(s: Stream, buffer: pointer, bufLen: int): int = - var s = ReadableStream(s) - if s.atEnd: - return 0 - while s.buf.len < bufLen: - var len: int - s.isource.read(len) - if len == 0: - result = s.buf.len - copyMem(buffer, addr(s.buf[0]), result) - s.buf = s.buf.substr(result) - s.isend = true - return - var nbuf: string - s.isource.readStr(len, nbuf) - s.buf &= nbuf - assert s.buf.len >= bufLen - result = bufLen - copyMem(buffer, addr(s.buf[0]), result) - s.buf = s.buf.substr(result) - if s.buf.len == 0: - var len: int - s.isource.read(len) - if len == 0: - s.isend = true - else: - s.isource.readStr(len, s.buf) - -proc rsAtEnd(s: Stream): bool = - ReadableStream(s).isend - -proc rsClose(s: Stream) = {.cast(tags: [WriteIOEffect]).}: #TODO TODO TODO ew. - var s = ReadableStream(s) - if s.isend: return - s.buf = "" - while true: - var len: int - s.isource.read(len) - if len == 0: - s.isend = true - break - s.isource.setPosition(s.isource.getPosition() + len) - -proc newReadableStream*(isource: Stream): ReadableStream = - var len: int - isource.read(len) - result = ReadableStream( - isource: isource, - readDataImpl: rsReadData, - atEndImpl: rsAtEnd, - closeImpl: rsClose, - isend: len == 0 - ) - if len != 0: - isource.readStr(len, result.buf) - func newRequest*(url: URL, httpMethod = HTTP_GET, headers = newHeaders(), body = opt(string), multipart = opt(FormData), mode = RequestMode.NO_CORS, credentialsMode = CredentialsMode.SAME_ORIGIN, diff --git a/src/local/client.nim b/src/local/client.nim index 20e1a6ef..2912b7ef 100644 --- a/src/local/client.nim +++ b/src/local/client.nim @@ -314,10 +314,10 @@ proc consoleBuffer(client: Client): Container {.jsfget.} = proc acceptBuffers(client: Client) = while client.pager.unreg.len > 0: let (pid, stream) = client.pager.unreg.pop() - let fd = stream.source.getFd() - if int(fd) in client.fdmap: + let fd = int(stream.fd) + if fd in client.fdmap: client.selector.unregister(fd) - client.fdmap.del(int(fd)) + client.fdmap.del(fd) else: client.pager.procmap.del(pid) stream.close() @@ -328,8 +328,8 @@ proc acceptBuffers(client: Client) = client.pager.alert("Error: failed to set up buffer") continue container.setStream(stream) - let fd = stream.source.getFd() - client.fdmap[int(fd)] = container + let fd = int(stream.fd) + client.fdmap[fd] = container client.selector.registerHandle(fd, {Read}, 0) client.pager.handleEvents(container) accepted.add(pid) @@ -344,22 +344,33 @@ proc handleRead(client: Client, fd: int) = client.handlePagerEvents() ) elif fd == client.forkserver.estream.fd: - var nl = false + const BufferSize = 4096 const prefix = "STDERR: " - var s = prefix + var buffer {.noinit.}: array[BufferSize, char] + let estream = client.forkserver.estream + var hadlf = true while true: try: - let c = client.forkserver.estream.readChar() - if nl and s.len > prefix.len: - client.console.err.write(s) - s = prefix - nl = false - s &= c - nl = c == '\n' - except IOError: + let n = estream.recvData(addr buffer[0], BufferSize) + var i = 0 + while i < n: + var j = n + var found = false + for k in i ..< n: + if buffer[k] == '\n': + j = k + 1 + found = true + break + if hadlf: + client.console.err.write(prefix) + if j - i > 0: + client.console.err.writeData(addr buffer[i], j - i) + i = j + hadlf = found + except ErrorAgain: break - if s.len > prefix.len: - client.console.err.write(s) + if not hadlf: + client.console.err.write('\n') client.console.err.flush() elif fd in client.loader.connecting: client.loader.onConnected(fd) diff --git a/src/local/container.nim b/src/local/container.nim index 9ad69cc4..d6db15c0 100644 --- a/src/local/container.nim +++ b/src/local/container.nim @@ -20,7 +20,6 @@ import loader/request import local/select import server/buffer import server/forkserver -import types/buffersource import types/cell import types/color import types/cookie diff --git a/src/local/pager.nim b/src/local/pager.nim index 3cdd0226..a6c6c9ad 100644 --- a/src/local/pager.nim +++ b/src/local/pager.nim @@ -31,8 +31,8 @@ import loader/loader import loader/request import local/container import local/select +import server/buffer import server/forkserver -import types/buffersource import types/cell import types/color import types/cookie diff --git a/src/render/rendertext.nim b/src/render/rendertext.nim index 54f2378a..56a0b2ba 100644 --- a/src/render/rendertext.nim +++ b/src/render/rendertext.nim @@ -23,7 +23,7 @@ type StreamRenderer* = object #TODO pass bool for whether we can rewind proc newStreamRenderer*(stream: Stream, charsets0: openArray[Charset]): - StreamRenderer = + ref StreamRenderer = var charsets = newSeq[Charset](charsets0.len) for i in 0 ..< charsets.len: charsets[i] = charsets0[charsets.high - i] @@ -37,7 +37,7 @@ proc newStreamRenderer*(stream: Stream, charsets0: openArray[Charset]): let decoder = newDecoderStream(stream, cs, errormode = em) decoder.setInhibitCheckEnd(true) let encoder = newEncoderStream(decoder) - return StreamRenderer( + return (ref StreamRenderer)( stream: stream, decoder: decoder, encoder: encoder, @@ -169,3 +169,10 @@ proc renderStream*(grid: var FlexibleGrid, renderer: var StreamRenderer): bool = grid.addLine() grid.renderChunk(renderer, buf) return true + +proc finishRender*(grid: var FlexibleGrid, renderer: var StreamRenderer) = + renderer.decoder.setInhibitCheckEnd(false) + let buf = renderer.decoder.readAll() + if grid.len == 0: + grid.addLine() + grid.renderChunk(renderer, buf) diff --git a/src/server/buffer.nim b/src/server/buffer.nim index cb66e9ef..3c6dfa21 100644 --- a/src/server/buffer.nim +++ b/src/server/buffer.nim @@ -40,7 +40,6 @@ import loader/headers import loader/loader import render/renderdocument import render/rendertext -import types/buffersource import types/cell import types/color import types/cookie @@ -57,8 +56,10 @@ import chakasu/charset import chame/tags type - LoadInfo* = enum - CONNECT, DOWNLOAD, RENDER, DONE + BufferSource* = object + contentType*: Option[string] # override + charset*: Charset # fallback + request*: Request BufferCommand* = enum LOAD, RENDER, WINDOW_CHANGE, FIND_ANCHOR, READ_SUCCESS, READ_CANCELED, @@ -71,7 +72,7 @@ type # LOADING_PAGE: istream open # LOADING_RESOURCES: istream closed, resources open # LOADED: istream closed, resources closed - BufferState* = enum + BufferState = enum LOADING_PAGE, LOADING_RESOURCES, LOADED HoverType* = enum @@ -88,12 +89,14 @@ type rfd: int # file descriptor of command pipe fd: int # file descriptor of buffer source url: URL # URL before readFromFd + pstream: SocketStream # control stream alive: bool + connected: bool + savetask: bool + ishtml: bool + firstBufferRead: bool lines: FlexibleGrid - rendered: bool source: BufferSource - width: int - height: int attrs: WindowAttributes window: Window document: Document @@ -102,25 +105,20 @@ type istream: SocketStream sstream: StringStream available: int - pstream: SocketStream # pipe stream - srenderer: StreamRenderer - connected: bool state: BufferState prevnode: StyledNode loader: FileLoader config: BufferConfig - userstyle: CSSStylesheet tasks: array[BufferCommand, int] #TODO this should have arguments - savetask: bool hovertext: array[HoverType, string] estream: Stream # error stream - ishtml: bool ssock: ServerSocket factory: CAtomFactory uastyle: CSSStylesheet quirkstyle: CSSStylesheet + userstyle: CSSStylesheet htmlParser: HTML5ParserWrapper - firstBufferRead: bool + srenderer: ref StreamRenderer InterfaceOpaque = ref object stream: Stream @@ -637,12 +635,10 @@ proc processData(buffer: Buffer): bool = buffer.document = buffer.htmlParser.builder.document return res else: - return buffer.lines.renderStream(buffer.srenderer) + return buffer.lines.renderStream(buffer.srenderer[]) proc windowChange*(buffer: Buffer, attrs: WindowAttributes) {.proxy.} = buffer.attrs = attrs - buffer.width = buffer.attrs.width - buffer.height = buffer.attrs.height - 1 buffer.prevstyled = nil if buffer.window != nil: buffer.window.attrs = attrs @@ -905,10 +901,9 @@ proc clone*(buffer: Buffer, newurl: URL): Pid {.proxy.} = let stream = buffer.loader.tee((parentPid, fd)) var success: bool stream.sread(success) - let sfd = int(stream.source.getFd()) if success: switchStream(buffer.loader.connecting[fd], stream) - buffer.loader.connecting[sfd] = buffer.loader.connecting[fd] + buffer.loader.connecting[stream.fd] = buffer.loader.connecting[fd] else: # Unlikely, but theoretically possible: our SUSPEND connection # finished before the connection could have been completed. @@ -923,10 +918,9 @@ proc clone*(buffer: Buffer, newurl: URL): Pid {.proxy.} = let stream = buffer.loader.tee((parentPid, fd)) var success: bool stream.sread(success) - let sfd = int(stream.source.getFd()) if success: buffer.loader.switchStream(buffer.loader.ongoing[fd], stream) - buffer.loader.ongoing[sfd] = buffer.loader.ongoing[fd] + buffer.loader.ongoing[stream.fd] = buffer.loader.ongoing[fd] else: # Already finished. #TODO what to do? @@ -945,7 +939,7 @@ proc clone*(buffer: Buffer, newurl: URL): Pid {.proxy.} = it = 0 let socks = ssock.acceptSocketStream() buffer.pstream = socks - buffer.rfd = int(socks.source.getFd()) + buffer.rfd = socks.fd buffer.selector.registerHandle(buffer.rfd, {Read}, 0) return 0 else: # parent @@ -1094,7 +1088,7 @@ proc onload(buffer: Buffer) = var n = 0 if not reprocess: buffer.sstream.data.prepareMutation() - n = buffer.istream.readData(addr buffer.sstream.data[0], BufferSize) + n = buffer.istream.recvData(addr buffer.sstream.data[0], BufferSize) if n != buffer.sstream.data.len: buffer.sstream.data.setLen(n) if n != 0 or reprocess: @@ -1120,6 +1114,8 @@ proc onload(buffer: Buffer) = buffer.state = LOADED if buffer.document != nil: # may be nil if not buffer.ishtml buffer.document.readyState = READY_STATE_COMPLETE + if not buffer.ishtml: + buffer.lines.finishRender(buffer.srenderer[]) buffer.dispatchLoadEvent() buffer.resolveTask(LOAD, res) ) @@ -1765,12 +1761,10 @@ proc launchBuffer*(config: BufferConfig, source: BufferSource, loader: loader, source: source, sstream: newStringStream(), - width: attrs.width, - height: attrs.height - 1, selector: newSelector[int](), estream: newFileStream(stderr), pstream: socks, - rfd: int(socks.source.getFd()), + rfd: socks.fd, ssock: ssock ) gbuffer = buffer diff --git a/src/server/forkserver.nim b/src/server/forkserver.nim index f788aa24..6fa95ab6 100644 --- a/src/server/forkserver.nim +++ b/src/server/forkserver.nim @@ -13,7 +13,6 @@ import io/urlfilter import loader/headers import loader/loader import server/buffer -import types/buffersource import types/cookie import types/urimethodmap import types/url @@ -288,9 +287,10 @@ proc newForkServer*(): ForkServer = raise newException(Defect, "Failed to open output handle") if not open(readf, pipefd_out[0], fmRead): raise newException(Defect, "Failed to open input handle") - discard fcntl(pipefd_err[0], F_SETFL, fcntl(pipefd_err[0], F_GETFL, 0) or O_NONBLOCK) + let estream = newPosixStream(pipefd_err[0]) + estream.setBlocking(false) return ForkServer( ostream: newFileStream(writef), istream: newFileStream(readf), - estream: newPosixStream(pipefd_err[0]) + estream: estream ) diff --git a/src/types/buffersource.nim b/src/types/buffersource.nim deleted file mode 100644 index 60fd7137..00000000 --- a/src/types/buffersource.nim +++ /dev/null @@ -1,11 +0,0 @@ -import std/options - -import loader/request - -import chakasu/charset - -type - BufferSource* = object - contentType*: Option[string] # override - charset*: Charset # fallback - request*: Request diff --git a/src/types/formdata.nim b/src/types/formdata.nim index 02a08d15..29817e54 100644 --- a/src/types/formdata.nim +++ b/src/types/formdata.nim @@ -79,8 +79,11 @@ proc writeEntry*(stream: Stream, entry: FormDataEntry, boundary: string) = var buf {.noinit.}: array[4096, uint8] while true: let n = fs.readData(addr buf[0], 4096) + if n == 0: + break stream.writeData(addr buf[0], n) - if n != 4096: break + if n < buf.len: + break else: stream.writeData(blob.buffer, int(blob.size)) stream.write("\r\n") |