diff options
-rwxr-xr-x | lib/pure/httpserver.nim | 34 | ||||
-rwxr-xr-x | lib/pure/sockets.nim | 30 | ||||
-rwxr-xr-x | web/news.txt | 3 |
3 files changed, 56 insertions, 11 deletions
diff --git a/lib/pure/httpserver.nim b/lib/pure/httpserver.nim index 57d5a8577..52d5decf2 100755 --- a/lib/pure/httpserver.nim +++ b/lib/pure/httpserver.nim @@ -208,6 +208,7 @@ type port: TPort client*: TSocket ## the socket to write the file data to path*, query*: string ## path and query the client requested + headers*: PStringTable ## headers with which the client made the request proc open*(s: var TServer, port = TPort(80)) = ## creates a new server at port `port`. If ``port == 0`` a free port is @@ -224,6 +225,7 @@ proc open*(s: var TServer, port = TPort(80)) = s.client = InvalidSocket s.path = "" s.query = "" + s.headers = {:}.newStringTable() proc port*(s: var TServer): TPort = ## get the port number the server has acquired. @@ -232,15 +234,39 @@ proc port*(s: var TServer): TPort = proc next*(s: var TServer) = ## proceed to the first/next request. s.client = accept(s.socket) - headers(s.client, "") - var data = recv(s.client).string - #discard recvLine(s.client, data) + s.headers = {:}.newStringTable() + #headers(s.client, "") + var data = "" + while not s.client.recvLine(data): nil + if data == "": + # Socket disconnected + s.client.close() + next(s) + return + var header = "" + while true: + if s.client.recvLine(header): + if header == "\c\L": break + if header != "": + var i = 0 + var key = "" + var value = "" + i = header.parseUntil(key, ':') + i += header.skipWhiteSpace(i) + i += header.parseUntil(value, whitespace, i) + s.headers[key] = value + else: + s.client.close() + next(s) + return var i = skipWhitespace(data) if skipIgnoreCase(data, "GET") > 0: inc(i, 3) elif skipIgnoreCase(data, "POST") > 0: inc(i, 4) - else: + else: unimplemented(s.client) + s.client.close() + next(s) return var L = skipWhitespace(data, i) diff --git a/lib/pure/sockets.nim b/lib/pure/sockets.nim index 31973c6ce..eeec62843 100755 --- a/lib/pure/sockets.nim +++ b/lib/pure/sockets.nim @@ -581,10 +581,19 @@ proc recv*(socket: TSocket, data: var string, size: int, timeout: int): int = result = read proc recvLine*(socket: TSocket, line: var TaintedString): bool = - ## returns false if no further data is available. `Line` must be initialized - ## and not nil! This does not throw an EOS exception. - ## If ``socket`` is disconnected, ``true`` will be returned and line will be - ## set to ``""``. + ## retrieves a line from ``socket``. If a full line is received ``\r\L`` is not + ## added to ``line``, however if solely ``\r\L`` is received then ``data`` + ## will be set to it. + ## + ## ``True`` is returned if data is available. ``False`` usually suggests an + ## error, EOS exceptions are not raised in favour of this. + ## + ## If the socket is disconnected, ``line`` will be set to ``""`` and ``True`` + ## will be returned. + template addNLIfEmpty(): stmt = + if line.len == 0: + line.add("\c\L") + setLen(line.string, 0) while true: var c: char @@ -596,13 +605,19 @@ proc recvLine*(socket: TSocket, line: var TaintedString): bool = if n > 0 and c == '\L': discard recv(cint(socket), addr(c), 1, 0'i32) elif n <= 0: return false + addNlIfEmpty() + return true + elif c == '\L': + addNlIfEmpty() return true - elif c == '\L': return true add(line.string, c) proc recvLine*(socket: TSocket, line: var TaintedString, timeout: int): bool = ## variant with a ``timeout`` parameter, the timeout parameter specifies ## how many miliseconds to wait for data. + template addNLIfEmpty(): stmt = + if line.len == 0: + line.add("\c\L") var waited = 0.0 # number of seconds already waited @@ -619,8 +634,11 @@ proc recvLine*(socket: TSocket, line: var TaintedString, timeout: int): bool = if n > 0 and c == '\L': discard recv(cint(socket), addr(c), 1, 0'i32) elif n <= 0: return false + addNlIfEmpty() + return true + elif c == '\L': + addNlIfEmpty() return true - elif c == '\L': return true add(line.string, c) proc recvLineAsync*(socket: TSocket, line: var TaintedString): TRecvLineResult = diff --git a/web/news.txt b/web/news.txt index 64d0ce928..578e2203c 100755 --- a/web/news.txt +++ b/web/news.txt @@ -15,7 +15,8 @@ Bugfixes - Fixed a bug concerning implicit type conversions in ``case`` statements. - Fixed a serious code generation bug that caused ``algorithm.sort`` to produce segmentation faults. - +- Fixed ambiguity in recvLine which meant that receiving ``\r\L`` was + indistinguishable from disconnections. Library Additions ----------------- |