diff options
Diffstat (limited to 'net/http.lua')
-rw-r--r-- | net/http.lua | 70 |
1 files changed, 57 insertions, 13 deletions
diff --git a/net/http.lua b/net/http.lua index e81975fd..35a92d57 100644 --- a/net/http.lua +++ b/net/http.lua @@ -6,17 +6,17 @@ -- COPYING file in the source package for more information. -- -local b64 = require "util.encodings".base64.encode; +local b64 = require "prosody.util.encodings".base64.encode; local url = require "socket.url" -local httpstream_new = require "net.http.parser".new; -local util_http = require "util.http"; -local events = require "util.events"; -local verify_identity = require"util.x509".verify_identity; -local promise = require "util.promise"; -local http_errors = require "net.http.errors"; +local httpstream_new = require "prosody.net.http.parser".new; +local util_http = require "prosody.util.http"; +local events = require "prosody.util.events"; +local verify_identity = require"prosody.util.x509".verify_identity; +local promise = require "prosody.util.promise"; +local http_errors = require "prosody.net.http.errors"; -local basic_resolver = require "net.resolvers.basic"; -local connect = require "net.connect".connect; +local basic_resolver = require "prosody.net.resolvers.basic"; +local connect = require "prosody.net.connect".connect; local ssl_available = pcall(require, "ssl"); @@ -25,10 +25,10 @@ local pairs = pairs; local tonumber, tostring, traceback = tonumber, tostring, debug.traceback; local os_time = os.time; -local xpcall = require "util.xpcall".xpcall; +local xpcall = require "prosody.util.xpcall".xpcall; local error = error -local log = require "util.logger".init("http"); +local log = require "prosody.util.logger".init("http"); local _ENV = nil; -- luacheck: std none @@ -51,10 +51,19 @@ local function log_if_failed(req, ret, ...) return ...; end -local function destroy_request(request) +local function destroy_request(request, force) local conn = request.conn; if conn then request.conn = nil; + local pool = request.http.pool; + if pool and not force then + local pool_id = request.scheme .. "://" .. request.authority; + if not pool[pool_id] then + pool[conn] = pool_id; + pool[pool_id] = conn; + return; + end + end conn:close() end end @@ -106,7 +115,8 @@ local function request_reader(request, data, err) request.callback(r.body, r.code, r, request); request.callback = nil; end - destroy_request(request); + local persistent = (","..(r.headers.connection or "keep-alive")..","):find(",keep-alive,") + destroy_request(request, persistent); end local function options_cb() return request; @@ -193,6 +203,13 @@ function listener.ondisconnect(conn, err) if request and request.conn then request:reader(nil, err or "closed"); end + if request and request.http.pool then + local pool = request.http.pool; + local pool_id = pool[conn]; + if pool_id then + pool[pool_id], pool[conn] = nil, nil; + end + end requests[conn] = nil; end @@ -253,6 +270,12 @@ local function request(self, u, ex, callback) ["User-Agent"] = "Prosody XMPP Server"; }; + if self.pool then + headers["Connection"] = "keep-alive"; + else + headers["Connection"] = "close"; + end + if req.userinfo then headers["Authorization"] = "Basic "..b64(req.userinfo); end @@ -299,6 +322,23 @@ local function request(self, u, ex, callback) end end + if self.pool then + local pool_id = req.scheme .. "://" .. req.authority; + local conn = self.pool[pool_id]; + if conn then + log("debug", "Re-using connection to %s from pool", req.host); + self.pool[pool_id] = nil; + self.pool[conn] = nil; + req.conn = conn; + requests[conn] = req; + self.events.fire_event("request", { http = self, request = req, url = u }); + listener.onconnect(conn); + return req; + else + log("debug", "Opening a new connection for this request"); + end + end + local http_service = basic_resolver.new(host, port_number, "tcp", { servername = req.host; use_dane = use_dane }); connect(http_service, listener, { sslctx = sslctx }, req); @@ -335,6 +375,10 @@ local function new(options) end or new; events = events.new(); }; + if options and options.connection_pooling then + -- util.cache in the future? + http.pool = {}; + end return http; end |