diff options
author | bptato <nincsnevem662@gmail.com> | 2022-11-22 14:43:52 +0100 |
---|---|---|
committer | bptato <nincsnevem662@gmail.com> | 2022-11-22 14:43:52 +0100 |
commit | 04fe0c11dd8e5b0a3f643cc4a054b2487198cdb3 (patch) | |
tree | d775b2d480a0c0db1751b679e7edea91629e3764 /src/ips | |
parent | bd8e806b04b024f916b274650185c3480d3cff36 (diff) | |
download | chawan-04fe0c11dd8e5b0a3f643cc4a054b2487198cdb3.tar.gz |
Move ips stuff to src/ips/
Diffstat (limited to 'src/ips')
-rw-r--r-- | src/ips/serialize.nim | 207 | ||||
-rw-r--r-- | src/ips/serversocket.nim | 26 | ||||
-rw-r--r-- | src/ips/socketstream.nim | 54 |
3 files changed, 287 insertions, 0 deletions
diff --git a/src/ips/serialize.nim b/src/ips/serialize.nim new file mode 100644 index 00000000..2dde0649 --- /dev/null +++ b/src/ips/serialize.nim @@ -0,0 +1,207 @@ +# Write data to streams. + +import options +import streams +import tables + +import buffer/cell +import io/request +import js/regex +import types/color +import types/url + +template swrite*[T](stream: Stream, o: T) = + stream.write(o) + +proc swrite*(stream: Stream, s: string) = + stream.swrite(s.len) + stream.write(s) + +proc swrite*(stream: Stream, b: bool) = + if b: + stream.swrite(1u8) + else: + stream.swrite(0u8) + +proc swrite*(stream: Stream, url: Url) = + stream.swrite(url.serialize()) + +proc swrite*(stream: Stream, headers: HeaderList) = + stream.swrite(headers.table.len) + for k, v in headers.table: + stream.swrite(k) + stream.swrite(v.len) + for s in v: + stream.swrite(s) + +proc swrite*(stream: Stream, part: MimePart) = + stream.swrite(part.isFile) + stream.swrite(part.name) + stream.swrite(part.content) + if part.isFile: + stream.swrite(part.filename) + stream.swrite(part.contentType) + stream.swrite(part.fileSize) + stream.swrite(part.isStream) + +proc swrite*[T](stream: Stream, s: seq[T]) = + stream.swrite(s.len) + for m in s: + stream.swrite(m) + +proc swrite*[T](stream: Stream, o: Option[T]) = + stream.swrite(o.issome) + if o.issome: + stream.swrite(o.get) + +proc swrite*(stream: Stream, request: Request) = + stream.swrite(request.httpmethod) + stream.swrite(request.url) + stream.swrite(request.headers) + stream.swrite(request.body) + stream.swrite(request.multipart) + +proc swrite*(stream: Stream, color: CellColor) = + stream.swrite(color.rgb) + if color.rgb: + stream.swrite(color.rgbcolor) + else: + stream.swrite(color.color) + +proc swrite*(stream: Stream, format: Format) = + stream.swrite(format.fgcolor) + stream.swrite(format.bgcolor) + stream.swrite(format.flags) + +proc swrite*(stream: Stream, cell: SimpleFormatCell) = + stream.swrite(cell.format) + stream.swrite(cell.pos) + +proc swrite*(stream: Stream, line: SimpleFlexibleLine) = + stream.swrite(line.str) + stream.swrite(line.formats) + +proc swrite*(stream: Stream, cell: FormatCell) = + stream.swrite(cell.format) + stream.swrite(cell.pos) + +proc swrite*(stream: Stream, line: FlexibleLine) = + stream.swrite(line.str) + stream.swrite(line.formats) + +proc swrite*(stream: Stream, regex: Regex) = + stream.swrite(regex.plen) + stream.writeData(regex.bytecode, regex.plen) + stream.swrite(regex.buf) + +template sread*[T](stream: Stream, o: T) = + stream.read(o) + +proc sread*(stream: Stream, s: var string) = + var len: int + stream.sread(len) + stream.readStr(len, s) + +proc sread*(stream: Stream, b: var bool) = + var n: uint8 + stream.sread(n) + if n == 1u8: + b = true + else: + assert n == 0u8 + b = false + +proc sread*(stream: Stream, url: var Url) = + var s: string + stream.sread(s) + url = parseUrl(s).get + +proc sread*(stream: Stream, headers: var HeaderList) = + new(headers) + var len: int + stream.sread(len) + for i in 0..<len: + var k: string + stream.sread(k) + var n: int + stream.sread(n) + for j in 0..<n: + var v: string + stream.sread(v) + headers.add(k, v) + +proc sread*(stream: Stream, part: var MimePart) = + var isFile: bool + stream.sread(isFile) + if isFile: + part = MimePart(isFile: true) + else: + part = MimePart(isFile: false) + stream.sread(part.name) + stream.sread(part.content) + if part.isFile: + stream.sread(part.filename) + stream.sread(part.contentType) + stream.sread(part.fileSize) + stream.sread(part.isStream) + +proc sread*[T](stream: Stream, s: var seq[T]) = + var len: int + stream.sread(len) + s.setLen(len) + for i in 0..<len: + stream.sread(s[i]) + +proc sread*[T](stream: Stream, o: var Option[T]) = + var x: bool + stream.sread(x) + if x: + var m: T + stream.sread(m) + o = some(m) + else: + o = none(T) + +proc sread*(stream: Stream, req: var RequestObj) = + stream.sread(req.httpmethod) + stream.sread(req.url) + stream.sread(req.headers) + stream.sread(req.body) + stream.sread(req.multipart) + +proc sread*(stream: Stream, color: var CellColor) = + var rgb: bool + stream.sread(rgb) + if rgb: + color = CellColor(rgb: true) + stream.sread(color.rgbcolor) + else: + color = CellColor(rgb: false) + stream.sread(color.color) + +proc sread*(stream: Stream, format: var Format) = + stream.sread(format.fgcolor) + stream.sread(format.bgcolor) + stream.sread(format.flags) + +proc sread*(stream: Stream, cell: var SimpleFormatCell) = + stream.sread(cell.format) + stream.sread(cell.pos) + +proc sread*(stream: Stream, line: var SimpleFlexibleLine) = + stream.sread(line.str) + stream.sread(line.formats) + +proc sread*(stream: Stream, regex: var Regex) = + assert regex.bytecode == nil + stream.sread(regex.plen) + regex.bytecode = cast[ptr uint8](alloc(regex.plen)) + regex.clone = true + let l = stream.readData(regex.bytecode, regex.plen) + stream.sread(regex.buf) + if l != regex.plen: + `=destroy`(regex) + +proc readRequest*(stream: Stream): Request = + new(result) + stream.sread(result[]) diff --git a/src/ips/serversocket.nim b/src/ips/serversocket.nim new file mode 100644 index 00000000..aa260907 --- /dev/null +++ b/src/ips/serversocket.nim @@ -0,0 +1,26 @@ +import net +import os +when defined(posix): + import posix + +type ServerSocket* = object + sock*: Socket + path*: string + +const SocketDirectory = "/tmp/cha/" +const SocketPathPrefix = SocketDirectory & "cha_sock_" +func getSocketPath*(pid: Pid): string = + SocketPathPrefix & $pid + +proc initServerSocket*(pid: Pid): ServerSocket = + createDir(SocketDirectory) + result.sock = newSocket(Domain.AF_UNIX, SockType.SOCK_STREAM, Protocol.IPPROTO_IP) + result.path = getSocketPath(getpid()) + discard unlink(cstring(result.path)) + bindUnix(result.sock, result.path) + listen(result.sock) + +proc close*(ssock: ServerSocket) = + close(ssock.sock) + discard unlink(cstring(ssock.path)) + diff --git a/src/ips/socketstream.nim b/src/ips/socketstream.nim new file mode 100644 index 00000000..f25f72c1 --- /dev/null +++ b/src/ips/socketstream.nim @@ -0,0 +1,54 @@ +import nativesockets +import net +import streams + +when defined(posix): + import posix + +import ips/serversocket + +type SocketStream* = ref object of Stream + source*: Socket + isend: bool + +proc sockReadData(s: Stream, buffer: pointer, len: int): int = + let s = SocketStream(s) + result = s.source.recv(buffer, len) + if result < 0: + raise newException(Defect, "Failed to read data") + elif result < len: + s.isend = true + +proc sockWriteData(s: Stream, buffer: pointer, len: int) = + discard SocketStream(s).source.send(buffer, len) + +proc sockAtEnd(s: Stream): bool = + SocketStream(s).isend + +proc sockClose(s: Stream) = {.cast(tags: []).}: #...sigh + let s = SocketStream(s) + s.source.close() + +func newSocketStream*(): SocketStream = + new(result) + result.readDataImpl = cast[proc (s: Stream, buffer: pointer, bufLen: int): int + {.nimcall, raises: [Defect, IOError, OSError], tags: [ReadIOEffect], gcsafe.} + ](sockReadData) # ... ??? + result.writeDataImpl = sockWriteData + result.atEndImpl = sockAtEnd + result.closeImpl = sockClose + +proc connectSocketStream*(path: string): SocketStream = + result = newSocketStream() + let sock = newSocket(Domain.AF_UNIX, SockType.SOCK_STREAM, Protocol.IPPROTO_IP) + connectUnix(sock, path) + result.source = sock + +proc connectSocketStream*(pid: Pid): SocketStream = + connectSocketStream(getSocketPath(pid)) + +proc acceptSocketStream*(ssock: ServerSocket): SocketStream = + result = newSocketStream() + var sock: Socket + ssock.sock.accept(sock) + result.source = sock |