summary refs log tree commit diff stats
path: root/lib
diff options
context:
space:
mode:
authorDominik Picheta <dominikpicheta@googlemail.com>2017-01-21 11:48:50 +0100
committerGitHub <noreply@github.com>2017-01-21 11:48:50 +0100
commit9e723166fe0d9bd2e608143036db17b7efc3ab68 (patch)
tree856aafda1e98261937c6295fd7059ac10a3253cb /lib
parente634ee858cf09e87e1fb5cbe09fcd79e59700049 (diff)
parent0d735aa73c835cf8d2a9eed91c5e1cac38fbbcc4 (diff)
downloadNim-9e723166fe0d9bd2e608143036db17b7efc3ab68.tar.gz
Merge pull request #5250 from yglukhov/http-redirect
Redirects support in request proc
Diffstat (limited to 'lib')
-rw-r--r--lib/pure/httpclient.nim48
1 files changed, 30 insertions, 18 deletions
diff --git a/lib/pure/httpclient.nim b/lib/pure/httpclient.nim
index ba967b14f..760e97049 100644
--- a/lib/pure/httpclient.nim
+++ b/lib/pure/httpclient.nim
@@ -540,6 +540,8 @@ proc getNewLocation(lastURL: string, headers: HttpHeaders): string =
   if r.hostname == "" and r.path != "":
     var parsed = parseUri(lastURL)
     parsed.path = r.path
+    parsed.query = r.query
+    parsed.anchor = r.anchor
     result = $parsed
 
 proc get*(url: string, extraHeaders = "", maxRedirects = 5,
@@ -1000,15 +1002,10 @@ proc override(fallback, override: HttpHeaders): HttpHeaders =
   for k, vs in override.table:
     result[k] = vs
 
-proc request*(client: HttpClient | AsyncHttpClient, url: string,
+proc requestAux(client: HttpClient | AsyncHttpClient, url: string,
               httpMethod: string, body = "",
               headers: 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``.
-  ##
-  ## Connection will kept alive. Further requests on the same ``client`` to
-  ## the same hostname will not require a new connection to be made. The
-  ## connection can be closed by using the ``close`` procedure.
+  # Helper that actually makes the request. Does not handle redirects.
   let connectionUrl =
     if client.proxy.isNil: parseUri(url) else: client.proxy.url
   let requestUrl = parseUri(url)
@@ -1021,7 +1018,7 @@ proc request*(client: HttpClient | AsyncHttpClient, url: string,
       var connectUrl = requestUrl
       connectUrl.scheme = "http"
       connectUrl.port = "443"
-      let proxyResp = await request(client, $connectUrl, $HttpConnect)
+      let proxyResp = await requestAux(client, $connectUrl, $HttpConnect)
 
       if not proxyResp.status.startsWith("200"):
         raise newException(HttpRequestError,
@@ -1053,6 +1050,29 @@ proc request*(client: HttpClient | AsyncHttpClient, url: string,
   # Restore the clients proxy in case it was overwritten.
   client.proxy = savedProxy
 
+
+proc request*(client: HttpClient | AsyncHttpClient, url: string,
+              httpMethod: string, body = "",
+              headers: 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``.
+  ##
+  ## Connection will kept alive. Further requests on the same ``client`` to
+  ## the same hostname will not require a new connection to be made. The
+  ## connection can be closed by using the ``close`` procedure.
+  ##
+  ## This procedure will follow redirects up to a maximum number of redirects
+  ## specified in ``client.maxRedirects``.
+  result = await client.requestAux(url, httpMethod, body, headers)
+
+  var lastURL = url
+  for i in 1..client.maxRedirects:
+    if result.status.redirection():
+      let redirectTo = getNewLocation(lastURL, result.headers)
+      result = await client.request(redirectTo, httpMethod, body, headers)
+      lastURL = redirectTo
+
+
 proc request*(client: HttpClient | AsyncHttpClient, url: string,
               httpMethod = HttpGET, body = "",
               headers: HttpHeaders = nil): Future[Response] {.multisync.} =
@@ -1076,14 +1096,6 @@ proc get*(client: HttpClient | AsyncHttpClient,
   ## specified in ``client.maxRedirects``.
   result = await client.request(url, HttpGET)
 
-  # Handle redirects.
-  var lastURL = url
-  for i in 1..client.maxRedirects:
-    if result.status.redirection():
-      let redirectTo = getNewLocation(lastURL, result.headers)
-      result = await client.request(redirectTo, HttpGET)
-      lastURL = redirectTo
-
 proc getContent*(client: HttpClient | AsyncHttpClient,
                  url: string): Future[string] {.multisync.} =
   ## Connects to the hostname specified by the URL and performs a GET request.
@@ -1119,7 +1131,7 @@ proc post*(client: HttpClient | AsyncHttpClient, url: string, body = "",
     headers["Content-Type"] = mpHeader.split(": ")[1]
   headers["Content-Length"] = $len(xb)
 
-  result = await client.request(url, HttpPOST, xb,
+  result = await client.requestAux(url, $HttpPOST, xb,
                                 headers = headers)
   # Handle redirects.
   var lastURL = url
@@ -1127,7 +1139,7 @@ proc post*(client: HttpClient | AsyncHttpClient, url: string, body = "",
     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.requestAux(redirectTo, $meth, xb,
                                     headers = headers)
       lastURL = redirectTo