From 38b7fb94ef539b7cfeb5299286805a6ec5687db3 Mon Sep 17 00:00:00 2001 From: Varriount Date: Thu, 22 Jan 2015 16:45:18 -0500 Subject: [PATCH 1/2] Fixes #1962 --- lib/pure/httpclient.nim | 63 +++++++++++++++++++++++------------------ 1 file changed, 36 insertions(+), 27 deletions(-) diff --git a/lib/pure/httpclient.nim b/lib/pure/httpclient.nim index d9f161d499..418e5f3da9 100644 --- a/lib/pure/httpclient.nim +++ b/lib/pure/httpclient.nim @@ -380,17 +380,11 @@ proc format(p: MultipartData): tuple[header, body: string] = result.body.add("--" & bound & "\c\L" & s) result.body.add("--" & bound & "--\c\L") -proc request*(url: string, httpMethod = httpGET, extraHeaders = "", - body = "", - sslContext: SSLContext = defaultSSLContext, - timeout = -1, userAgent = defUserAgent, - proxy: Proxy = nil): Response = - ## | Requests ``url`` with the specified ``httpMethod``. - ## | Extra headers can be specified and must be seperated by ``\c\L`` - ## | An optional timeout can be specified in miliseconds, if reading from the - ## server takes longer than specified an ETimeout exception will be raised. +proc request*(url: string, httpMethod: string, extraHeaders = "", + body = "", sslContext = defaultSSLContext, timeout = -1, + userAgent = defUserAgent, proxy: Proxy = nil): Response = var r = if proxy == nil: parseUri(url) else: proxy.url - var headers = substr($httpMethod, len("http")) + var headers = substr(httpMethod, len("http")) if proxy == nil: headers.add(" " & r.path) if r.query.len > 0: @@ -430,9 +424,19 @@ proc request*(url: string, httpMethod = httpGET, extraHeaders = "", if body != "": s.send(body) - result = parseResponse(s, httpMethod != httpHEAD, timeout) + result = parseResponse(s, httpMethod != "httpHEAD", timeout) s.close() +proc request*(url: string, httpMethod = httpGET, extraHeaders = "", + body = "", sslContext = defaultSSLContext, timeout = -1, + userAgent = defUserAgent, proxy: Proxy = nil): Response = + ## | Requests ``url`` with the specified ``httpMethod``. + ## | Extra headers can be specified and must be seperated by ``\c\L`` + ## | An optional timeout can be specified in miliseconds, if reading from the + ## server takes longer than specified an ETimeout exception will be raised. + result = request(url, $httpMethod, extraHeaders, body, sslContext, timeout, + userAgent, proxy) + proc redirection(status: string): bool = const redirectionNRs = ["301", "302", "303", "307"] for i in items(redirectionNRs): @@ -556,9 +560,9 @@ proc downloadFile*(url: string, outputFilename: string, else: fileError("Unable to open file") -proc generateHeaders(r: Uri, httpMethod: HttpMethod, +proc generateHeaders(r: Uri, httpMethod: string, headers: StringTableRef): string = - result = substr($httpMethod, len("http")) + result = substr(httpMethod, len("http")) # TODO: Proxies result.add(" " & r.path) if r.query.len > 0: @@ -755,8 +759,25 @@ proc newConnection(client: AsyncHttpClient, url: Uri) {.async.} = client.currentURL = url client.connected = true -proc request*(client: AsyncHttpClient, url: string, httpMethod = httpGET, +proc request*(client: AsyncHttpClient, url: string, httpMethod: string, body = ""): Future[Response] {.async.} = + let r = parseUri(url) + await newConnection(client, r) + + if not client.headers.hasKey("user-agent") and client.userAgent != "": + client.headers["User-Agent"] = client.userAgent + + var headers = generateHeaders(r, $httpMethod, client.headers) + + await client.socket.send(headers) + if body != "": + await client.socket.send(body) + + result = await parseResponse(client, httpMethod != "httpHEAD") + +proc request*(client: AsyncHttpClient, url: string, httpMethod = httpGET, + body = ""): Future[Response] = + ## Connects to the hostname specified by the URL and performs a request ## using the method specified. ## @@ -765,19 +786,7 @@ proc request*(client: AsyncHttpClient, url: string, httpMethod = httpGET, ## connection can be closed by using the ``close`` procedure. ## ## The returned future will complete once the request is completed. - let r = parseUri(url) - await newConnection(client, r) - - if not client.headers.hasKey("user-agent") and client.userAgent != "": - client.headers["User-Agent"] = client.userAgent - - var headers = generateHeaders(r, httpMethod, client.headers) - - await client.socket.send(headers) - if body != "": - await client.socket.send(body) - - result = await parseResponse(client, httpMethod != httpHEAD) + result = request(client, url, $httpMethod, body) proc get*(client: AsyncHttpClient, url: string): Future[Response] {.async.} = ## Connects to the hostname specified by the URL and performs a GET request. From 0e65df4bbf11bc579ea12886711335fdfe321a1a Mon Sep 17 00:00:00 2001 From: Varriount Date: Fri, 23 Jan 2015 22:06:57 -0500 Subject: [PATCH 2/2] Added documentation for the new http request procedures. --- lib/pure/httpclient.nim | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/lib/pure/httpclient.nim b/lib/pure/httpclient.nim index 418e5f3da9..3c14018870 100644 --- a/lib/pure/httpclient.nim +++ b/lib/pure/httpclient.nim @@ -383,6 +383,11 @@ proc format(p: MultipartData): tuple[header, body: string] = proc request*(url: string, httpMethod: string, extraHeaders = "", body = "", sslContext = defaultSSLContext, timeout = -1, userAgent = defUserAgent, proxy: Proxy = nil): Response = + ## | Requests ``url`` with the custom method string specified by the + ## | ``httpMethod`` parameter. + ## | Extra headers can be specified and must be seperated by ``\c\L`` + ## | An optional timeout can be specified in miliseconds, if reading from the + ## server takes longer than specified an ETimeout exception will be raised. var r = if proxy == nil: parseUri(url) else: proxy.url var headers = substr(httpMethod, len("http")) if proxy == nil: @@ -761,6 +766,14 @@ proc newConnection(client: AsyncHttpClient, url: Uri) {.async.} = proc request*(client: AsyncHttpClient, url: string, httpMethod: string, body = ""): Future[Response] {.async.} = + ## 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. + ## + ## The returned future will complete once the request is completed. let r = parseUri(url) await newConnection(client, r) @@ -777,7 +790,6 @@ proc request*(client: AsyncHttpClient, url: string, httpMethod: string, proc request*(client: AsyncHttpClient, url: string, httpMethod = httpGET, body = ""): Future[Response] = - ## Connects to the hostname specified by the URL and performs a request ## using the method specified. ##