diff options
author | Andreas Rumpf <rumpf_a@web.de> | 2017-11-07 22:14:55 +0100 |
---|---|---|
committer | Andreas Rumpf <rumpf_a@web.de> | 2017-11-07 22:14:55 +0100 |
commit | d4cdd92bc90c20250b312fb11b8cb014a6204ce5 (patch) | |
tree | a5d3a160467052d800dc43bee9806a6807bc0d7d /lib/pure | |
parent | 157d48bc3208720af98ac5ed60a08494ddc5e328 (diff) | |
parent | f221c192b3779a50b51d7ba22431e0d06ab0edc1 (diff) | |
download | Nim-d4cdd92bc90c20250b312fb11b8cb014a6204ce5.tar.gz |
Merge branch 'devel' of github.com:nim-lang/Nim into devel
Diffstat (limited to 'lib/pure')
-rw-r--r-- | lib/pure/httpclient.nim | 74 | ||||
-rw-r--r-- | lib/pure/net.nim | 2 | ||||
-rw-r--r-- | lib/pure/strutils.nim | 10 |
3 files changed, 49 insertions, 37 deletions
diff --git a/lib/pure/httpclient.nim b/lib/pure/httpclient.nim index de1d332a3..54a8498fa 100644 --- a/lib/pure/httpclient.nim +++ b/lib/pure/httpclient.nim @@ -469,7 +469,7 @@ proc request*(url: string, httpMethod: string, extraHeaders = "", ## **Deprecated since version 0.15.0**: use ``HttpClient.request`` instead. var r = if proxy == nil: parseUri(url) else: proxy.url var hostUrl = if proxy == nil: r else: parseUri(url) - var headers = httpMethod.toUpper() + var headers = httpMethod.toUpperAscii() # TODO: Use generateHeaders further down once it supports proxies. var s = newSocket() @@ -713,10 +713,10 @@ proc downloadFile*(url: string, outputFilename: string, proc generateHeaders(requestUrl: Uri, httpMethod: string, headers: HttpHeaders, body: string, proxy: Proxy): string = # GET - result = httpMethod.toUpper() + result = httpMethod.toUpperAscii() result.add ' ' - if proxy.isNil: + if proxy.isNil or (not proxy.isNil and requestUrl.scheme == "https"): # /path?query if requestUrl.path[0] != '/': result.add '/' result.add(requestUrl.path) @@ -1048,7 +1048,11 @@ proc newConnection(client: HttpClient | AsyncHttpClient, client.currentURL.scheme != url.scheme or client.currentURL.port != url.port or (not client.connected): - let isSsl = url.scheme.toLowerAscii() == "https" + # Connect to proxy if specified + let connectionUrl = + if client.proxy.isNil: url else: client.proxy.url + + let isSsl = connectionUrl.scheme.toLowerAscii() == "https" if isSsl and not defined(ssl): raise newException(HttpRequestError, @@ -1056,31 +1060,55 @@ proc newConnection(client: HttpClient | AsyncHttpClient, if client.connected: client.close() + client.connected = false # TODO: I should be able to write 'net.Port' here... let port = - if url.port == "": + if connectionUrl.port == "": if isSsl: nativesockets.Port(443) else: nativesockets.Port(80) - else: nativesockets.Port(url.port.parseInt) + else: nativesockets.Port(connectionUrl.port.parseInt) when client is HttpClient: - client.socket = await net.dial(url.hostname, port) + client.socket = await net.dial(connectionUrl.hostname, port) elif client is AsyncHttpClient: - client.socket = await asyncnet.dial(url.hostname, port) + client.socket = await asyncnet.dial(connectionUrl.hostname, port) else: {.fatal: "Unsupported client type".} when defined(ssl): if isSsl: try: client.sslContext.wrapConnectedSocket( - client.socket, handshakeAsClient, url.hostname) + client.socket, handshakeAsClient, connectionUrl.hostname) except: client.socket.close() raise getCurrentException() + # If need to CONNECT through proxy + if url.scheme == "https" and not client.proxy.isNil: + when defined(ssl): + # Pass only host:port for CONNECT + var connectUrl = initUri() + connectUrl.hostname = url.hostname + connectUrl.port = if url.port != "": url.port else: "443" + + let proxyHeaderString = generateHeaders(connectUrl, $HttpConnect, newHttpHeaders(), "", client.proxy) + await client.socket.send(proxyHeaderString) + let proxyResp = await parseResponse(client, false) + + if not proxyResp.status.startsWith("200"): + raise newException(HttpRequestError, + "The proxy server rejected a CONNECT request, " & + "so a secure connection could not be established.") + client.sslContext.wrapConnectedSocket( + client.socket, handshakeAsClient, url.hostname) + else: + raise newException(HttpRequestError, + "SSL support is not available. Cannot connect over SSL.") + + # May be connected through proxy but remember actual URL being accessed client.currentURL = url client.connected = true @@ -1100,32 +1128,9 @@ proc requestAux(client: HttpClient | AsyncHttpClient, url: string, headers: HttpHeaders = nil): Future[Response | AsyncResponse] {.multisync.} = # 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) - let savedProxy = client.proxy # client's proxy may be overwritten. - - if requestUrl.scheme == "https" and not client.proxy.isNil: - when defined(ssl): - client.proxy.url = connectionUrl - var connectUrl = requestUrl - connectUrl.scheme = "http" - connectUrl.port = "443" - let proxyResp = await requestAux(client, $connectUrl, $HttpConnect) - - if not proxyResp.status.startsWith("200"): - raise newException(HttpRequestError, - "The proxy server rejected a CONNECT request, " & - "so a secure connection could not be established.") - client.sslContext.wrapConnectedSocket( - client.socket, handshakeAsClient, requestUrl.hostname) - client.proxy = nil - else: - raise newException(HttpRequestError, - "SSL support not available. Cannot connect to https site over proxy.") - else: - await newConnection(client, connectionUrl) + await newConnection(client, requestUrl) let effectiveHeaders = client.headers.override(headers) @@ -1143,9 +1148,6 @@ proc requestAux(client: HttpClient | AsyncHttpClient, url: string, client.getBody result = await parseResponse(client, getBody) - # 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 | AsyncResponse] diff --git a/lib/pure/net.nim b/lib/pure/net.nim index a405ce1bd..b8d05642b 100644 --- a/lib/pure/net.nim +++ b/lib/pure/net.nim @@ -58,7 +58,7 @@ ## You can then begin accepting connections using the ``accept`` procedure. ## ## .. code-block:: Nim -## var client = newSocket() +## var client = new Socket ## var address = "" ## while true: ## socket.acceptAddr(client, address) diff --git a/lib/pure/strutils.nim b/lib/pure/strutils.nim index 0b55e6b1d..5c07757cb 100644 --- a/lib/pure/strutils.nim +++ b/lib/pure/strutils.nim @@ -2007,6 +2007,16 @@ proc formatFloat*(f: float, format: FloatFormatMode = ffDefault, ## after the decimal point for Nim's ``float`` type. ## ## If ``precision == 0``, it tries to format it nicely. + ## + ## Examples: + ## + ## .. code-block:: nim + ## + ## let x = 123.456 + ## echo x.formatFloat() # 123.4560000000000 + ## echo x.formatFloat(ffDecimal, 4) # 123.4560 + ## echo x.formatFloat(ffScientific, 2) # 1.23e+02 + ## result = formatBiggestFloat(f, format, precision, decimalSep) proc trimZeros*(x: var string) {.noSideEffect.} = |