aboutsummaryrefslogtreecommitdiffstats
path: root/net/http.lua
diff options
context:
space:
mode:
Diffstat (limited to 'net/http.lua')
-rw-r--r--net/http.lua70
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