Fixes req w/ both Content-Length & Connection: close headers.

Also closes the socket when connection is closed to ensure
that a new connection is made on any further requests.
This commit is contained in:
Dominik Picheta 2017-10-13 21:14:06 +01:00
commit ac67f5eda5

View file

@ -883,7 +883,9 @@ proc recvFull(client: HttpClient | AsyncHttpClient, size: int, timeout: int,
let data = client.socket.recv(sizeToRecv, timeout) let data = client.socket.recv(sizeToRecv, timeout)
else: else:
let data = await client.socket.recv(sizeToRecv) let data = await client.socket.recv(sizeToRecv)
if data == "": break # We've been disconnected. if data == "":
client.close()
break # We've been disconnected.
readLen.inc(data.len) readLen.inc(data.len)
if keep: if keep:
@ -950,6 +952,7 @@ proc parseBody(client: HttpClient | AsyncHttpClient,
if length > 0: if length > 0:
let recvLen = await client.recvFull(length, client.timeout, true) let recvLen = await client.recvFull(length, client.timeout, true)
if recvLen == 0: if recvLen == 0:
client.close()
httpError("Got disconnected while trying to read body.") httpError("Got disconnected while trying to read body.")
if recvLen != length: if recvLen != length:
httpError("Received length doesn't match expected length. Wanted " & httpError("Received length doesn't match expected length. Wanted " &
@ -962,13 +965,20 @@ proc parseBody(client: HttpClient | AsyncHttpClient,
if headers.getOrDefault"Connection" == "close" or httpVersion == "1.0": if headers.getOrDefault"Connection" == "close" or httpVersion == "1.0":
while true: while true:
let recvLen = await client.recvFull(4000, client.timeout, true) let recvLen = await client.recvFull(4000, client.timeout, true)
if recvLen == 0: break if recvLen == 0:
client.close()
break
when client is AsyncHttpClient: when client is AsyncHttpClient:
client.bodyStream.complete() client.bodyStream.complete()
else: else:
client.bodyStream.setPosition(0) client.bodyStream.setPosition(0)
# If the server will close our connection, then no matter the method of
# reading the body, we need to close our socket.
if headers.getOrDefault"Connection" == "close":
client.close()
proc parseResponse(client: HttpClient | AsyncHttpClient, proc parseResponse(client: HttpClient | AsyncHttpClient,
getBody: bool): Future[Response | AsyncResponse] getBody: bool): Future[Response | AsyncResponse]
{.multisync.} = {.multisync.} =
@ -984,7 +994,10 @@ proc parseResponse(client: HttpClient | AsyncHttpClient,
line = await client.socket.recvLine(client.timeout) line = await client.socket.recvLine(client.timeout)
else: else:
line = await client.socket.recvLine() line = await client.socket.recvLine()
if line == "": break # We've been disconnected. if line == "":
# We've been disconnected.
client.close()
break
if line == "\c\L": if line == "\c\L":
fullyRead = true fullyRead = true
break break
@ -1033,7 +1046,8 @@ proc newConnection(client: HttpClient | AsyncHttpClient,
url: Uri) {.multisync.} = url: Uri) {.multisync.} =
if client.currentURL.hostname != url.hostname or if client.currentURL.hostname != url.hostname or
client.currentURL.scheme != url.scheme or client.currentURL.scheme != url.scheme or
client.currentURL.port != url.port: client.currentURL.port != url.port or
(not client.connected):
let isSsl = url.scheme.toLowerAscii() == "https" let isSsl = url.scheme.toLowerAscii() == "https"
if isSsl and not defined(ssl): if isSsl and not defined(ssl):