summary refs log tree commit diff stats
path: root/lib
diff options
context:
space:
mode:
authorDominik Picheta <dominikpicheta@gmail.com>2017-10-13 21:14:06 +0100
committerDominik Picheta <dominikpicheta@gmail.com>2017-10-13 21:14:06 +0100
commitac67f5eda57a91e97d16b31dcdea65fb39de9fc5 (patch)
treea1055d8c30922b02a2c9b8dbf2da1ed7fc42eb94 /lib
parent1dc6caea6b449a0d4e9334ff19aa7d6484c3528f (diff)
downloadNim-ac67f5eda57a91e97d16b31dcdea65fb39de9fc5.tar.gz
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.
Diffstat (limited to 'lib')
-rw-r--r--lib/pure/httpclient.nim22
1 files changed, 18 insertions, 4 deletions
diff --git a/lib/pure/httpclient.nim b/lib/pure/httpclient.nim
index cb4f4f664..de1d332a3 100644
--- a/lib/pure/httpclient.nim
+++ b/lib/pure/httpclient.nim
@@ -883,7 +883,9 @@ proc recvFull(client: HttpClient | AsyncHttpClient, size: int, timeout: int,
       let data = client.socket.recv(sizeToRecv, timeout)
     else:
       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)
     if keep:
@@ -950,6 +952,7 @@ proc parseBody(client: HttpClient | AsyncHttpClient,
       if length > 0:
         let recvLen = await client.recvFull(length, client.timeout, true)
         if recvLen == 0:
+          client.close()
           httpError("Got disconnected while trying to read body.")
         if recvLen != length:
           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":
         while true:
           let recvLen = await client.recvFull(4000, client.timeout, true)
-          if recvLen == 0: break
+          if recvLen == 0:
+            client.close()
+            break
 
   when client is AsyncHttpClient:
     client.bodyStream.complete()
   else:
     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,
                    getBody: bool): Future[Response | AsyncResponse]
                    {.multisync.} =
@@ -984,7 +994,10 @@ proc parseResponse(client: HttpClient | AsyncHttpClient,
       line = await client.socket.recvLine(client.timeout)
     else:
       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":
       fullyRead = true
       break
@@ -1033,7 +1046,8 @@ proc newConnection(client: HttpClient | AsyncHttpClient,
                    url: Uri) {.multisync.} =
   if client.currentURL.hostname != url.hostname 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"
 
     if isSsl and not defined(ssl):