Implement dial, support IPv6 in httpclient (#5763)
* Implement dial, support IPv6 in httpclient Added ``dial`` procedure to networking modules: ``net``, ``asyncdispatch``, ``asyncnet``. It merges socket creation, address resolution, and connection into single step. When using ``dial``, you don't have to worry about IPv4 vs IPv6 problem. Fixed addrInfo loop in connect to behave properly. Previously it would stop on first non-immediate failure, instead of continuing and trying the remaining addresses. Fixed newAsyncNativeSocket to raise proper error if socket creation fails. Fixes: #3811 * Check domain during connect() only on non-Windows This is how it was in the previous implementation of connect(). * Call 'osLastError' before 'close' in net.dial * Record osLastError before freeAddrInfo in net.dial * Add missing docs for 'dial' proc * Optimize dial to create one FD per domain, add tests And make async IPv6 servers work on Windows. * Add IPv6 test to uri module * Fix getAddrString error handling
This commit is contained in:
parent
6377b52d8e
commit
ecf278c467
13 changed files with 559 additions and 334 deletions
|
|
@ -1033,32 +1033,38 @@ proc newConnection(client: HttpClient | AsyncHttpClient,
|
|||
if client.currentURL.hostname != url.hostname or
|
||||
client.currentURL.scheme != url.scheme or
|
||||
client.currentURL.port != url.port:
|
||||
let isSsl = url.scheme.toLowerAscii() == "https"
|
||||
|
||||
if isSsl and not defined(ssl):
|
||||
raise newException(HttpRequestError,
|
||||
"SSL support is not available. Cannot connect over SSL.")
|
||||
|
||||
if client.connected:
|
||||
client.close()
|
||||
|
||||
when client is HttpClient:
|
||||
client.socket = newSocket()
|
||||
elif client is AsyncHttpClient:
|
||||
client.socket = newAsyncSocket()
|
||||
else: {.fatal: "Unsupported client type".}
|
||||
|
||||
# TODO: I should be able to write 'net.Port' here...
|
||||
let port =
|
||||
if url.port == "":
|
||||
if url.scheme.toLower() == "https":
|
||||
if isSsl:
|
||||
nativesockets.Port(443)
|
||||
else:
|
||||
nativesockets.Port(80)
|
||||
else: nativesockets.Port(url.port.parseInt)
|
||||
|
||||
if url.scheme.toLower() == "https":
|
||||
when defined(ssl):
|
||||
client.sslContext.wrapSocket(client.socket)
|
||||
else:
|
||||
raise newException(HttpRequestError,
|
||||
"SSL support is not available. Cannot connect over SSL.")
|
||||
when client is HttpClient:
|
||||
client.socket = await net.dial(url.hostname, port)
|
||||
elif client is AsyncHttpClient:
|
||||
client.socket = await asyncnet.dial(url.hostname, port)
|
||||
else: {.fatal: "Unsupported client type".}
|
||||
|
||||
when defined(ssl):
|
||||
if isSsl:
|
||||
try:
|
||||
client.sslContext.wrapConnectedSocket(client.socket, handshakeAsClient)
|
||||
except:
|
||||
client.socket.close()
|
||||
raise getCurrentException()
|
||||
|
||||
await client.socket.connect(url.hostname, port)
|
||||
client.currentURL = url
|
||||
client.connected = true
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue