Software /
code /
prosody
Comparison
net/http.lua @ 13319:6d6291dfe735
net.http: Add simple connection pooling
This should speed up repeated requests to the same site by keeping their
connections around and sending more requests on them.
Sending multiple requests at the same time is not supported, instead a
request started while another to the same authority is in progress would
open a new one and the first one to complete would go back in the pool.
This could be investigated in the future.
Some http servers limit the number of requests per connection and this
is not tested and could cause one request to fail, but hopefully it will
close the connection and prevent it from being reused.
author | Kim Alvefur <zash@zash.se> |
---|---|
date | Sat, 11 Nov 2023 23:08:34 +0100 |
parent | 12974:ba409c67353b |
child | 13320:23f95714c386 |
comparison
equal
deleted
inserted
replaced
13318:4a437dd62cc9 | 13319:6d6291dfe735 |
---|---|
49 end | 49 end |
50 end | 50 end |
51 return ...; | 51 return ...; |
52 end | 52 end |
53 | 53 |
54 local function destroy_request(request) | 54 local function destroy_request(request, force) |
55 local conn = request.conn; | 55 local conn = request.conn; |
56 if conn then | 56 if conn then |
57 request.conn = nil; | 57 request.conn = nil; |
58 local pool = request.http.pool; | |
59 if pool and not force then | |
60 local pool_id = request.scheme .. "://" .. request.authority; | |
61 if not pool[pool_id] then | |
62 pool[conn] = pool_id; | |
63 pool[pool_id] = conn; | |
64 return; | |
65 end | |
66 end | |
58 conn:close() | 67 conn:close() |
59 end | 68 end |
60 end | 69 end |
61 | 70 |
62 local function cancel_request(request, reason) | 71 local function cancel_request(request, reason) |
191 function listener.ondisconnect(conn, err) | 200 function listener.ondisconnect(conn, err) |
192 local request = requests[conn]; | 201 local request = requests[conn]; |
193 if request and request.conn then | 202 if request and request.conn then |
194 request:reader(nil, err or "closed"); | 203 request:reader(nil, err or "closed"); |
195 end | 204 end |
205 if request and request.http.pool then | |
206 local pool = request.http.pool; | |
207 local pool_id = pool[conn]; | |
208 if pool_id then | |
209 pool[pool_id], pool[conn] = nil, nil; | |
210 end | |
211 end | |
196 requests[conn] = nil; | 212 requests[conn] = nil; |
197 end | 213 end |
198 | 214 |
199 function listener.onattach(conn, req) | 215 function listener.onattach(conn, req) |
200 requests[conn] = req; | 216 requests[conn] = req; |
291 local sslctx = false; | 307 local sslctx = false; |
292 if using_https then | 308 if using_https then |
293 sslctx = ex and ex.sslctx or self.options and self.options.sslctx; | 309 sslctx = ex and ex.sslctx or self.options and self.options.sslctx; |
294 if ex and ex.use_dane ~= nil then | 310 if ex and ex.use_dane ~= nil then |
295 use_dane = ex.use_dane; | 311 use_dane = ex.use_dane; |
312 end | |
313 end | |
314 | |
315 if self.pool then | |
316 local pool_id = req.scheme .. "://" .. req.authority; | |
317 local conn = self.pool[pool_id]; | |
318 if conn then | |
319 log("debug", "Re-using connection to %s from pool", req.host); | |
320 self.pool[pool_id] = nil; | |
321 self.pool[conn] = nil; | |
322 req.conn = conn; | |
323 requests[conn] = req; | |
324 self.events.fire_event("request", { http = self, request = req, url = u }); | |
325 listener.onconnect(conn); | |
326 return req; | |
327 else | |
328 log("debug", "Opening a new connection for this request"); | |
296 end | 329 end |
297 end | 330 end |
298 | 331 |
299 local http_service = basic_resolver.new(host, port_number, "tcp", { servername = req.host; use_dane = use_dane }); | 332 local http_service = basic_resolver.new(host, port_number, "tcp", { servername = req.host; use_dane = use_dane }); |
300 connect(http_service, listener, { sslctx = sslctx }, req); | 333 connect(http_service, listener, { sslctx = sslctx }, req); |
330 end | 363 end |
331 return new(final_options); | 364 return new(final_options); |
332 end or new; | 365 end or new; |
333 events = events.new(); | 366 events = events.new(); |
334 }; | 367 }; |
368 if options and options.connection_pooling then | |
369 -- util.cache in the future? | |
370 http.pool = {}; | |
371 end | |
335 return http; | 372 return http; |
336 end | 373 end |
337 | 374 |
338 local default_http = new({ | 375 local default_http = new({ |
339 sslctx = { mode = "client", protocol = "sslv23", options = { "no_sslv2", "no_sslv3" }, alpn = "http/1.1", verify = "peer" }; | 376 sslctx = { mode = "client", protocol = "sslv23", options = { "no_sslv2", "no_sslv3" }, alpn = "http/1.1", verify = "peer" }; |