1
1
module ConnectionRequest
2
2
3
3
using URIs, Sockets, Base64, LoggingExtras, ConcurrentUtilities, ExceptionUnwrapping
4
- using MbedTLS: SSLContext, SSLConfig
5
- using OpenSSL: SSLStream
4
+ import MbedTLS
5
+ import OpenSSL
6
6
using .. Messages, .. IOExtras, .. Connections, .. Streams, .. Exceptions
7
7
import .. SOCKET_TYPE_TLS
8
8
@@ -55,7 +55,7 @@ Close the connection if the request throws an exception.
55
55
Otherwise leave it open so that it can be reused.
56
56
"""
57
57
function connectionlayer (handler)
58
- return function connections (req; proxy= getproxy (req. url. scheme, req. url. host), socket_type:: Type = TCPSocket, socket_type_tls:: Type = SOCKET_TYPE_TLS[] , readtimeout:: Int = 0 , connect_timeout:: Int = 30 , logerrors:: Bool = false , logtag= nothing , kw... )
58
+ return function connections (req; proxy= getproxy (req. url. scheme, req. url. host), socket_type:: Type = TCPSocket, socket_type_tls:: Union{Nothing, Type} = nothing , readtimeout:: Int = 0 , connect_timeout:: Int = 30 , logerrors:: Bool = false , logtag= nothing , kw... )
59
59
local io, stream
60
60
if proxy != = nothing
61
61
target_url = req. url
@@ -74,7 +74,7 @@ function connectionlayer(handler)
74
74
end
75
75
76
76
connect_timeout = connect_timeout == 0 && readtimeout > 0 ? readtimeout : connect_timeout
77
- IOType = sockettype (url, socket_type, socket_type_tls)
77
+ IOType = sockettype (url, socket_type, socket_type_tls, get (kw, :sslconfig , nothing ) )
78
78
start_time = time ()
79
79
try
80
80
io = newconnection (IOType, url. host, url. port; readtimeout= readtimeout, connect_timeout= connect_timeout, kw... )
@@ -148,7 +148,62 @@ function connectionlayer(handler)
148
148
end
149
149
end
150
150
151
- sockettype (url:: URI , tcp, tls) = url. scheme in (" wss" , " https" ) ? tls : tcp
151
+ function sockettype (url:: URI , socket_type_tcp, socket_type_tls, sslconfig)
152
+ if url. scheme in (" wss" , " https" )
153
+ tls_socket_type (socket_type_tls, sslconfig)
154
+ else
155
+ socket_type_tcp
156
+ end
157
+ end
158
+
159
+ """
160
+ tls_socket_type(socket_type_tls, sslconfig)::Type
161
+
162
+ Find the best TLS socket type, given the values of these keyword arguments.
163
+
164
+ If both are `nothing` then we use the global default: `HTTP.SOCKET_TYPE_TLS[]`.
165
+ If both are not `nothing` then they must agree:
166
+ `sslconfig` must be of the right type to configure `socket_type_tls` or we throw an `ArgumentError`.
167
+ """
168
+ function tls_socket_type (socket_type_tls:: Union{Nothing, Type} ,
169
+ sslconfig:: Union{Nothing, MbedTLS.SSLConfig, OpenSSL.SSLContext}
170
+ ):: Type
171
+
172
+ socket_type_matching_sslconfig =
173
+ if sslconfig isa MbedTLS. SSLConfig
174
+ MbedTLS. SSLContext
175
+ elseif sslconfig isa OpenSSL. SSLContext
176
+ OpenSSL. SSLStream
177
+ else
178
+ nothing
179
+ end
180
+
181
+ if socket_type_tls === socket_type_matching_sslconfig
182
+ # Use the global default TLS socket if they're both nothing, or use
183
+ # what they both specify if they're not nothing.
184
+ isnothing (socket_type_tls) ? SOCKET_TYPE_TLS[] : socket_type_tls
185
+ # If either is nothing, use the other one.
186
+ elseif isnothing (socket_type_tls)
187
+ socket_type_matching_sslconfig
188
+ elseif isnothing (socket_type_matching_sslconfig)
189
+ socket_type_tls
190
+ else
191
+ # If they specify contradictory types, throw an error.
192
+ # Error thrown in noinline closure to avoid speed penalty in common case
193
+ @noinline function err (socket_type_tls, sslconfig)
194
+ msg = """
195
+ Incompatible values for keyword args `socket_type_tls` and `sslconfig`:
196
+ socket_type_tls=$socket_type_tls
197
+ typeof(sslconfig)=$(typeof (sslconfig))
198
+
199
+ Make them match or provide only one of them.
200
+ - the socket type MbedTLS.SSLContext is configured by MbedTLS.SSLConfig
201
+ - the socket type OpenSSL.SSLStream is configured by OpenSSL.SSLContext"""
202
+ throw (ArgumentError (msg))
203
+ end
204
+ err (socket_type_tls, sslconfig)
205
+ end
206
+ end
152
207
153
208
function connect_tunnel (io, target_url, req)
154
209
target = " $(URIs. hoststring (target_url. host)) :$(target_url. port) "
0 commit comments