mirror of
https://github.com/nim-lang/Nim.git
synced 2026-06-04 02:44:44 +00:00
Merge pull request #5250 from yglukhov/http-redirect
Redirects support in request proc
This commit is contained in:
@@ -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
|
||||
|
||||
|
||||
@@ -2,6 +2,9 @@
|
||||
News
|
||||
====
|
||||
|
||||
`2017-01-08 Nim Version 0.16.2 released <news/e031_version_0_16_2.html>`_
|
||||
===================================
|
||||
|
||||
`2017-01-08 Nim Version 0.16.0 released <news/e029_version_0_16_0.html>`_
|
||||
===================================
|
||||
|
||||
|
||||
27
web/news/e031_version_0_16_2.rst
Normal file
27
web/news/e031_version_0_16_2.rst
Normal file
@@ -0,0 +1,27 @@
|
||||
Version 0.16.2 released
|
||||
=======================
|
||||
|
||||
Changelog
|
||||
~~~~~~~~~
|
||||
|
||||
Changes affecting backwards compatibility
|
||||
-----------------------------------------
|
||||
|
||||
- ``httpclient.request`` now respects ``maxRedirects`` option. Previously
|
||||
redirects were handled only by ``get`` and ``post`` procs.
|
||||
|
||||
Library Additions
|
||||
-----------------
|
||||
|
||||
|
||||
Tool Additions
|
||||
--------------
|
||||
|
||||
|
||||
Compiler Additions
|
||||
------------------
|
||||
|
||||
|
||||
Language Additions
|
||||
------------------
|
||||
|
||||
Reference in New Issue
Block a user