diff options
author | Dominik Picheta <dominikpicheta@googlemail.com> | 2014-08-31 12:54:43 +0100 |
---|---|---|
committer | Dominik Picheta <dominikpicheta@googlemail.com> | 2014-08-31 12:55:04 +0100 |
commit | bb1e87ce4d3e3e81e65609354667e5ed860f02c8 (patch) | |
tree | 7a457d72e48c330d33672690772d157d041f866d /lib/pure/httpclient.nim | |
parent | d26d42b88e2abacb74cd3bfedf7b9a0d8d0a7eee (diff) | |
download | Nim-bb1e87ce4d3e3e81e65609354667e5ed860f02c8.tar.gz |
Async SSL support.
Diffstat (limited to 'lib/pure/httpclient.nim')
-rw-r--r-- | lib/pure/httpclient.nim | 57 |
1 files changed, 37 insertions, 20 deletions
diff --git a/lib/pure/httpclient.nim b/lib/pure/httpclient.nim index c5e657bab..8b19c58f8 100644 --- a/lib/pure/httpclient.nim +++ b/lib/pure/httpclient.nim @@ -78,6 +78,7 @@ import sockets, strutils, parseurl, parseutils, strtabs, base64, os import asyncnet, asyncdispatch import rawsockets +from net import nil type Response* = tuple[ @@ -164,16 +165,17 @@ proc parseBody(s: TSocket, headers: PStringTable, timeout: int): string = var contentLengthHeader = headers["Content-Length"] if contentLengthHeader != "": var length = contentLengthHeader.parseint() - result = newString(length) - var received = 0 - while true: - if received >= length: break - let r = s.recv(addr(result[received]), length-received, timeout) - if r == 0: break - received += r - if received != length: - httpError("Got invalid content length. Expected: " & $length & - " got: " & $received) + if length > 0: + result = newString(length) + var received = 0 + while true: + if received >= length: break + let r = s.recv(addr(result[received]), length-received, timeout) + if r == 0: break + received += r + if received != length: + httpError("Got invalid content length. Expected: " & $length & + " got: " & $received) else: # (http://tools.ietf.org/html/rfc2616#section-4.4) NR.4 TODO @@ -444,11 +446,13 @@ type headers: StringTableRef maxRedirects: int userAgent: string + when defined(ssl): + sslContext: net.SslContext {.deprecated: [PAsyncHttpClient: AsyncHttpClient].} proc newAsyncHttpClient*(userAgent = defUserAgent, - maxRedirects = 5): AsyncHttpClient = + maxRedirects = 5, sslContext = defaultSslContext): AsyncHttpClient = ## Creates a new PAsyncHttpClient instance. ## ## ``userAgent`` specifies the user agent that will be used when making @@ -456,10 +460,13 @@ proc newAsyncHttpClient*(userAgent = defUserAgent, ## ## ``maxRedirects`` specifies the maximum amount of redirects to follow, ## default is 5. + ## + ## ``sslContext`` specifies the SSL context to use for HTTPS requests. new result result.headers = newStringTable(modeCaseInsensitive) result.userAgent = defUserAgent result.maxRedirects = maxRedirects + result.sslContext = net.SslContext(sslContext) proc close*(client: AsyncHttpClient) = ## Closes any connections held by the HTTP client. @@ -519,12 +526,13 @@ proc parseBody(client: PAsyncHttpClient, var contentLengthHeader = headers["Content-Length"] if contentLengthHeader != "": var length = contentLengthHeader.parseint() - result = await client.socket.recvFull(length) - if result == "": - httpError("Got disconnected while trying to read body.") - if result.len != length: - httpError("Received length doesn't match expected length. Wanted " & - $length & " got " & $result.len) + if length > 0: + result = await client.socket.recvFull(length) + if result == "": + httpError("Got disconnected while trying to read body.") + if result.len != length: + httpError("Received length doesn't match expected length. Wanted " & + $length & " got " & $result.len) else: # (http://tools.ietf.org/html/rfc2616#section-4.4) NR.4 TODO @@ -590,14 +598,23 @@ proc newConnection(client: PAsyncHttpClient, url: TURL) {.async.} = client.currentURL.scheme != url.scheme: if client.connected: client.close() client.socket = newAsyncSocket() - if url.scheme == "https": - assert false, "TODO SSL" # TODO: I should be able to write 'net.TPort' here... let port = - if url.port == "": rawsockets.TPort(80) + if url.port == "": + if url.scheme.toLower() == "https": + rawsockets.TPort(443) + else: + rawsockets.TPort(80) else: rawsockets.TPort(url.port.parseInt) + if url.scheme.toLower() == "https": + when defined(ssl): + client.sslContext.wrapSocket(client.socket) + else: + raise newException(EHttpRequestErr, + "SSL support is not available. Cannot connect over SSL.") + await client.socket.connect(url.hostname, port) client.currentURL = url client.connected = true |