summary refs log tree commit diff stats
path: root/lib
diff options
context:
space:
mode:
authorDmitry Polienko <dmitry@eldis.ru>2016-10-31 09:46:50 +0700
committerDmitry Polienko <dmitry@eldis.ru>2016-10-31 09:46:50 +0700
commit52f4590e98832b536282fd2c90ca36246cc95b80 (patch)
treec139c2d191fd66a1800cbe9c5bdaa6d258dc47c9 /lib
parent860264a382a2e8cb44ea358fbbfcd1e763964097 (diff)
downloadNim-52f4590e98832b536282fd2c90ca36246cc95b80.tar.gz
Don't persist generated headers between requests
Diffstat (limited to 'lib')
-rw-r--r--lib/pure/httpclient.nim43
1 files changed, 32 insertions, 11 deletions
diff --git a/lib/pure/httpclient.nim b/lib/pure/httpclient.nim
index c56d13b57..080229756 100644
--- a/lib/pure/httpclient.nim
+++ b/lib/pure/httpclient.nim
@@ -117,7 +117,7 @@
 ## only basic authentication is supported at the moment.
 
 import net, strutils, uri, parseutils, strtabs, base64, os, mimetypes,
-  math, random, httpcore, times
+  math, random, httpcore, times, tables
 import asyncnet, asyncdispatch
 import nativesockets
 
@@ -989,8 +989,17 @@ proc newConnection(client: HttpClient | AsyncHttpClient,
     client.currentURL = url
     client.connected = true
 
+proc withFallback(override, fallback: HttpHeaders): HttpHeaders =
+  # Left-biased map union for `HttpHeaders`
+  result = newHttpHeaders()
+  # Copy by value
+  result.table[] = fallback.table[]
+  for k, vs in override.table:
+    result[k] = vs
+
 proc request*(client: HttpClient | AsyncHttpClient, url: string,
-              httpMethod: string, body = ""): Future[Response] {.multisync.} =
+              httpMethod: string, body = "",
+              overrideHeaders: HttpHeaders = nil): Future[Response] {.multisync.} =
   ## Connects to the hostname specified by the URL and performs a request
   ## using the custom method string specified by ``httpMethod``.
   ##
@@ -1023,11 +1032,17 @@ proc request*(client: HttpClient | AsyncHttpClient, url: string,
   else:
     await newConnection(client, connectionUrl)
 
-  if not client.headers.hasKey("user-agent") and client.userAgent != "":
-    client.headers["User-Agent"] = client.userAgent
+  var effectiveHeaders: HttpHeaders
+  if overrideHeaders != nil:
+    effectiveHeaders = overrideHeaders.withFallback(client.headers)
+  else:
+    effectiveHeaders = client.headers
+
+  if not effectiveHeaders.hasKey("user-agent") and client.userAgent != "":
+    effectiveHeaders["User-Agent"] = client.userAgent
 
   var headers = generateHeaders(requestUrl, httpMethod,
-                                client.headers, body, client.proxy)
+                                effectiveHeaders, body, client.proxy)
 
   await client.socket.send(headers)
   if body != "":
@@ -1040,7 +1055,8 @@ proc request*(client: HttpClient | AsyncHttpClient, url: string,
   client.proxy = savedProxy
 
 proc request*(client: HttpClient | AsyncHttpClient, url: string,
-              httpMethod = HttpGET, body = ""): Future[Response] {.multisync.} =
+              httpMethod = HttpGET, body = "",
+              overrideHeaders: HttpHeaders = nil): Future[Response] {.multisync.} =
   ## Connects to the hostname specified by the URL and performs a request
   ## using the method specified.
   ##
@@ -1050,7 +1066,8 @@ proc request*(client: HttpClient | AsyncHttpClient, url: string,
   ##
   ## When a request is made to a different hostname, the current connection will
   ## be closed.
-  result = await request(client, url, $httpMethod, body)
+  result = await request(client, url, $httpMethod, body,
+                         overrideHeaders = overrideHeaders)
 
 proc get*(client: HttpClient | AsyncHttpClient,
           url: string): Future[Response] {.multisync.} =
@@ -1097,18 +1114,22 @@ proc post*(client: HttpClient | AsyncHttpClient, url: string, body = "",
     else:
       x
   var xb = mpBody.withNewLine() & body
+
+  var overrideHeaders = newHttpHeaders()
   if multipart != nil:
-    client.headers["Content-Type"] = mpHeader.split(": ")[1]
-  client.headers["Content-Length"] = $len(xb)
+    overrideHeaders["Content-Type"] = mpHeader.split(": ")[1]
+  overrideHeaders["Content-Length"] = $len(xb)
 
-  result = await client.request(url, HttpPOST, xb)
+  result = await client.request(url, HttpPOST, xb,
+                                overrideHeaders = overrideHeaders)
   # Handle redirects.
   var lastURL = url
   for i in 1..client.maxRedirects:
     if result.status.redirection():
       let redirectTo = getNewLocation(lastURL, result.headers)
       var meth = if result.status != "307": HttpGet else: HttpPost
-      result = await client.request(redirectTo, meth, xb)
+      result = await client.request(redirectTo, meth, xb,
+                                    overrideHeaders = overrideHeaders)
       lastURL = redirectTo
 
 proc postContent*(client: HttpClient | AsyncHttpClient, url: string,