@@ -7,6 +7,23 @@ module Transport
77 class PooledNetRequester
88 extend DockerEngineRuby ::Internal ::Util ::SorbetRuntimeSupport
99
10+ class UnixSocketHTTP < Net ::HTTP
11+ # Net::HTTP.new forwards multiple args to #initialize.
12+ # We only care about socket_path and ignore the rest.
13+ def initialize ( socket_path , *_rest )
14+ super ( "localhost" , Net ::HTTP . http_default_port )
15+ @socket_path = socket_path
16+ end
17+
18+ private def connect
19+ raise ArgumentError . new ( "TLS over unix sockets is not supported" ) if use_ssl?
20+
21+ @socket = Net ::BufferedIO . new ( UNIXSocket . new ( @socket_path ) )
22+ @last_communicated = nil
23+ on_connect
24+ end
25+ end
26+
1027 # from the golang stdlib
1128 # https://github.com/golang/go/blob/c8eced8580028328fde7c03cbfcb720ce15b2358/src/net/http/transport.go#L49
1229 KEEP_ALIVE_TIMEOUT = 30
@@ -19,10 +36,17 @@ class << self
1936 # @param cert_store [OpenSSL::X509::Store]
2037 # @param tls_cert [OpenSSL::X509::Certificate, nil]
2138 # @param tls_key [OpenSSL::PKey::PKey, nil]
39+ # @param unix_socket_path [String, nil]
2240 # @param url [URI::Generic]
2341 #
2442 # @return [Net::HTTP]
25- def connect ( cert_store :, tls_cert :, tls_key :, url :)
43+ def connect ( cert_store :, tls_cert :, tls_key :, unix_socket_path :, url :)
44+ if unix_socket_path
45+ return UnixSocketHTTP . new ( unix_socket_path ) . tap do
46+ _1 . use_ssl = false
47+ _1 . max_retries = 0
48+ end
49+ end
2650 port =
2751 case [ url . port , url . scheme ]
2852 in [ Integer , _ ]
@@ -100,18 +124,25 @@ def build_request(request, &blk)
100124 # @api private
101125 #
102126 # @param url [URI::Generic]
127+ # @param unix_socket_path [String, nil]
103128 # @param deadline [Float]
104129 # @param blk [Proc]
105130 #
106131 # @raise [Timeout::Error]
107132 # @yieldparam [Net::HTTP]
108- private def with_pool ( url , deadline :, &blk )
109- origin = DockerEngineRuby ::Internal ::Util . uri_origin ( url )
133+ private def with_pool ( url , unix_socket_path : , deadline :, &blk )
134+ origin = unix_socket_path || DockerEngineRuby ::Internal ::Util . uri_origin ( url )
110135 timeout = deadline - DockerEngineRuby ::Internal ::Util . monotonic_secs
111136 pool =
112137 @mutex . synchronize do
113138 @pools [ origin ] ||= ConnectionPool . new ( size : @size ) do
114- self . class . connect ( cert_store : @cert_store , tls_cert : @tls_cert , tls_key : @tls_key , url : url )
139+ self . class . connect (
140+ cert_store : @cert_store ,
141+ tls_cert : @tls_cert ,
142+ tls_key : @tls_key ,
143+ unix_socket_path : unix_socket_path ,
144+ url : url
145+ )
115146 end
116147 end
117148
@@ -135,6 +166,7 @@ def build_request(request, &blk)
135166 # @return [Array(Integer, Net::HTTPResponse, Enumerable<String>)]
136167 def execute ( request )
137168 url , deadline = request . fetch_values ( :url , :deadline )
169+ unix_socket_path = request . fetch ( :unix_socket_path , @default_unix_socket_path )
138170
139171 req = nil
140172 finished = false
@@ -143,7 +175,7 @@ def execute(request)
143175 enum = Enumerator . new do |y |
144176 next if finished
145177
146- with_pool ( url , deadline : deadline ) do |conn |
178+ with_pool ( url , unix_socket_path : unix_socket_path , deadline : deadline ) do |conn |
147179 eof = false
148180 closing = nil
149181 ::Thread . handle_interrupt ( Object => :never ) do
@@ -203,14 +235,17 @@ def execute(request)
203235 # @param tls_ca_cert_path [String, nil]
204236 # @param tls_client_cert_path [String, nil]
205237 # @param tls_client_key_path [String, nil]
238+ # @param unix_socket_path [String, nil]
206239 def initialize (
207240 size : self . class ::DEFAULT_MAX_CONNECTIONS ,
241+ unix_socket_path : nil ,
208242 tls_ca_cert_path : nil ,
209243 tls_client_cert_path : nil ,
210244 tls_client_key_path : nil
211245 )
212246 @mutex = Mutex . new
213247 @size = size
248+ @default_unix_socket_path = unix_socket_path
214249 @cert_store = OpenSSL ::X509 ::Store . new . tap ( &:set_default_paths )
215250 @cert_store . add_file ( tls_ca_cert_path ) if tls_ca_cert_path
216251
@@ -230,7 +265,16 @@ def initialize(
230265 end
231266
232267 define_sorbet_constant! ( :Request ) do
233- T . type_alias { { method : Symbol , url : URI ::Generic , headers : T ::Hash [ String , String ] , body : T . anything , deadline : Float } }
268+ T . type_alias do
269+ {
270+ method : Symbol ,
271+ url : URI ::Generic ,
272+ unix_socket_path : T . nilable ( String ) ,
273+ headers : T ::Hash [ String , String ] ,
274+ body : T . anything ,
275+ deadline : Float
276+ }
277+ end
234278 end
235279 end
236280 end
0 commit comments