diff --git a/chronos/apps/http/httpclient.nim b/chronos/apps/http/httpclient.nim index 6e9ea0c..9c79889 100644 --- a/chronos/apps/http/httpclient.nim +++ b/chronos/apps/http/httpclient.nim @@ -523,7 +523,7 @@ proc connect(session: HttpSessionRef, ha: HttpAddress): Future[HttpClientConnectionRef] {.async.} = ## Establish new connection with remote server using ``url`` and ``flags``. ## On success returns ``HttpClientConnectionRef`` object. - + var lastError = "" # Here we trying to connect to every possible remote host address we got after # DNS resolution. for address in ha.addresses: @@ -547,9 +547,14 @@ proc connect(session: HttpSessionRef, except CancelledError as exc: await res.closeWait() raise exc - except AsyncStreamError: + except TLSStreamProtocolError as exc: await res.closeWait() res.state = HttpClientConnectionState.Error + lastError = $exc.msg + except AsyncStreamError as exc: + await res.closeWait() + res.state = HttpClientConnectionState.Error + lastError = $exc.msg of HttpClientScheme.Nonsecure: res.state = HttpClientConnectionState.Ready res @@ -557,7 +562,11 @@ proc connect(session: HttpSessionRef, return conn # If all attempts to connect to the remote host have failed. - raiseHttpConnectionError("Could not connect to remote host") + if len(lastError) > 0: + raiseHttpConnectionError("Could not connect to remote host, reason: " & + lastError) + else: + raiseHttpConnectionError("Could not connect to remote host") proc removeConnection(session: HttpSessionRef, conn: HttpClientConnectionRef) {.async.} = diff --git a/chronos/streams/tlsstream.nim b/chronos/streams/tlsstream.nim index ceacaff..2999f7a 100644 --- a/chronos/streams/tlsstream.nim +++ b/chronos/streams/tlsstream.nim @@ -95,6 +95,7 @@ type trustAnchors: TrustAnchorStore SomeTLSStreamType* = TLSStreamReader|TLSStreamWriter|TLSAsyncStream + SomeTrustAnchorType* = TrustAnchorStore | openArray[X509TrustAnchor] TLSStreamError* = object of AsyncStreamError TLSStreamHandshakeError* = object of TLSStreamError @@ -139,12 +140,14 @@ proc newTLSStreamProtocolError[T](message: T): ref TLSStreamProtocolError = proc raiseTLSStreamProtocolError[T](message: T) {.noreturn, noinline.} = raise newTLSStreamProtocolImpl(message) -proc new*(T: typedesc[TrustAnchorStore], anchors: openArray[X509TrustAnchor]): TrustAnchorStore = +proc new*(T: typedesc[TrustAnchorStore], + anchors: openArray[X509TrustAnchor]): TrustAnchorStore = var res: seq[X509TrustAnchor] for anchor in anchors: res.add(anchor) - doAssert(unsafeAddr(anchor) != unsafeAddr(res[^1]), "Anchors should be copied") - return TrustAnchorStore(anchors: res) + doAssert(unsafeAddr(anchor) != unsafeAddr(res[^1]), + "Anchors should be copied") + TrustAnchorStore(anchors: res) proc tlsWriteRec(engine: ptr SslEngineContext, writer: TLSStreamWriter): Future[TLSResult] {.async.} = @@ -453,15 +456,16 @@ proc getSignerAlgo(xc: X509Certificate): int = else: int(x509DecoderGetSignerKeyType(dc)) -proc newTLSClientAsyncStream*(rsource: AsyncStreamReader, - wsource: AsyncStreamWriter, - serverName: string, - bufferSize = SSL_BUFSIZE_BIDI, - minVersion = TLSVersion.TLS12, - maxVersion = TLSVersion.TLS12, - flags: set[TLSFlags] = {}, - trustAnchors: TrustAnchorStore | openArray[X509TrustAnchor] = MozillaTrustAnchors - ): TLSAsyncStream = +proc newTLSClientAsyncStream*( + rsource: AsyncStreamReader, + wsource: AsyncStreamWriter, + serverName: string, + bufferSize = SSL_BUFSIZE_BIDI, + minVersion = TLSVersion.TLS12, + maxVersion = TLSVersion.TLS12, + flags: set[TLSFlags] = {}, + trustAnchors: SomeTrustAnchorType = MozillaTrustAnchors + ): TLSAsyncStream = ## Create new TLS asynchronous stream for outbound (client) connections ## using reading stream ``rsource`` and writing stream ``wsource``. ## @@ -484,7 +488,8 @@ proc newTLSClientAsyncStream*(rsource: AsyncStreamReader, ## a ``TrustAnchorStore`` you should reuse the same instance for ## every call to avoid making a copy of the trust anchors per call. when trustAnchors is TrustAnchorStore: - doAssert(len(trustAnchors.anchors) > 0, "Empty trust anchor list is invalid") + doAssert(len(trustAnchors.anchors) > 0, + "Empty trust anchor list is invalid") else: doAssert(len(trustAnchors) > 0, "Empty trust anchor list is invalid") var res = TLSAsyncStream() @@ -524,7 +529,7 @@ proc newTLSClientAsyncStream*(rsource: AsyncStreamReader, uint16(maxVersion)) if TLSFlags.NoVerifyServerName in flags: - let err = sslClientReset(res.ccontext, "", 0) + let err = sslClientReset(res.ccontext, nil, 0) if err == 0: raise newException(TLSStreamInitError, "Could not initialize TLS layer") else: