comparison net/http.lua @ 11200:bf8f2da84007

Merge 0.11->trunk
author Kim Alvefur <zash@zash.se>
date Thu, 05 Nov 2020 22:31:25 +0100
parents 409ce7686c11
children 9b25eecde9e6
comparison
equal deleted inserted replaced
11199:6c7c50a4de32 11200:bf8f2da84007
10 local url = require "socket.url" 10 local url = require "socket.url"
11 local httpstream_new = require "net.http.parser".new; 11 local httpstream_new = require "net.http.parser".new;
12 local util_http = require "util.http"; 12 local util_http = require "util.http";
13 local events = require "util.events"; 13 local events = require "util.events";
14 local verify_identity = require"util.x509".verify_identity; 14 local verify_identity = require"util.x509".verify_identity;
15 local promise = require "util.promise";
16 local http_errors = require "net.http.errors";
15 17
16 local basic_resolver = require "net.resolvers.basic"; 18 local basic_resolver = require "net.resolvers.basic";
17 local connect = require "net.connect".connect; 19 local connect = require "net.connect".connect;
18 20
19 local ssl_available = pcall(require, "ssl"); 21 local ssl_available = pcall(require, "ssl");
38 40
39 -- Request-related helper functions 41 -- Request-related helper functions
40 local function handleerr(err) log("error", "Traceback[http]: %s", traceback(tostring(err), 2)); return err; end 42 local function handleerr(err) log("error", "Traceback[http]: %s", traceback(tostring(err), 2)); return err; end
41 local function log_if_failed(req, ret, ...) 43 local function log_if_failed(req, ret, ...)
42 if not ret then 44 if not ret then
43 log("error", "Request '%s': error in callback: %s", req.id, tostring((...))); 45 log("error", "Request '%s': error in callback: %s", req.id, (...));
44 if not req.suppress_errors then 46 if not req.suppress_errors then
45 error(...); 47 error(...);
46 end 48 end
47 end 49 end
48 return ...; 50 return ...;
79 if not data then 81 if not data then
80 error_cb(err); 82 error_cb(err);
81 return; 83 return;
82 end 84 end
83 85
86 local finalize_sink;
84 local function success_cb(r) 87 local function success_cb(r)
88 if r.partial then
89 -- Request should be streamed
90 log("debug", "Request '%s': partial response (%s%s)",
91 request.id,
92 r.chunked and "chunked, " or "",
93 r.body_length and ("%d bytes"):format(r.body_length) or "unknown length"
94 );
95 if request.streaming_handler then
96 log("debug", "Request '%s': Streaming via handler");
97 r.body_sink, finalize_sink = request.streaming_handler(r);
98 end
99 return;
100 elseif finalize_sink then
101 log("debug", "Request '%s': Finalizing response stream");
102 finalize_sink(r);
103 end
85 if request.callback then 104 if request.callback then
86 request.callback(r.body, r.code, r, request); 105 request.callback(r.body, r.code, r, request);
87 request.callback = nil; 106 request.callback = nil;
88 end 107 end
89 destroy_request(request); 108 destroy_request(request);
159 178
160 function listener.onincoming(conn, data) 179 function listener.onincoming(conn, data)
161 local request = requests[conn]; 180 local request = requests[conn];
162 181
163 if not request then 182 if not request then
164 log("warn", "Received response from connection %s with no request attached!", tostring(conn)); 183 log("warn", "Received response from connection %s with no request attached!", conn);
165 return; 184 return;
166 end 185 end
167 186
168 if data and request.reader then 187 if data and request.reader then
169 request:reader(data); 188 request:reader(data);
252 headers[k] = v; 271 headers[k] = v;
253 end 272 end
254 end 273 end
255 req.insecure = ex.insecure; 274 req.insecure = ex.insecure;
256 req.suppress_errors = ex.suppress_errors; 275 req.suppress_errors = ex.suppress_errors;
276 req.streaming_handler = ex.streaming_handler;
257 end 277 end
258 278
259 log("debug", "Making %s %s request '%s' to %s", req.scheme:upper(), method or "GET", req.id, (ex and ex.suppress_url and host_header) or u); 279 log("debug", "Making %s %s request '%s' to %s", req.scheme:upper(), method or "GET", req.id, (ex and ex.suppress_url and host_header) or u);
260 280
261 -- Attach to request object 281 -- Attach to request object
280 end 300 end
281 301
282 local function new(options) 302 local function new(options)
283 local http = { 303 local http = {
284 options = options; 304 options = options;
285 request = request; 305 request = function (self, u, ex, callback)
306 if callback ~= nil then
307 return request(self, u, ex, callback);
308 else
309 return promise.new(function (resolve, reject)
310 request(self, u, ex, function (body, code, a, b)
311 if code == 0 then
312 reject(http_errors.new(body, { request = a }));
313 else
314 a.request = b;
315 resolve(a);
316 end
317 end);
318 end);
319 end
320 end;
286 new = options and function (new_options) 321 new = options and function (new_options)
287 local final_options = {}; 322 local final_options = {};
288 for k, v in pairs(options) do final_options[k] = v; end 323 for k, v in pairs(options) do final_options[k] = v; end
289 if new_options then 324 if new_options then
290 for k, v in pairs(new_options) do final_options[k] = v; end 325 for k, v in pairs(new_options) do final_options[k] = v; end
295 }; 330 };
296 return http; 331 return http;
297 end 332 end
298 333
299 local default_http = new({ 334 local default_http = new({
300 sslctx = { mode = "client", protocol = "sslv23", options = { "no_sslv2", "no_sslv3" } }; 335 sslctx = { mode = "client", protocol = "sslv23", options = { "no_sslv2", "no_sslv3" }, alpn = "http/1.1" };
301 suppress_errors = true; 336 suppress_errors = true;
302 }); 337 });
303 338
304 return { 339 return {
305 request = function (u, ex, callback) 340 request = function (u, ex, callback)