Redirects support in request proc

This commit is contained in:
Yuriy Glukhov
2017-01-19 15:06:08 +02:00
parent b85898cd41
commit b2237678fb

View File

@@ -1000,15 +1000,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 +1016,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 +1048,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 +1094,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 +1129,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 +1137,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