diff 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
line wrap: on
line diff
--- a/net/http.lua	Thu Nov 05 22:27:17 2020 +0100
+++ b/net/http.lua	Thu Nov 05 22:31:25 2020 +0100
@@ -12,6 +12,8 @@
 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 basic_resolver = require "net.resolvers.basic";
 local connect = require "net.connect".connect;
@@ -40,7 +42,7 @@
 local function handleerr(err) log("error", "Traceback[http]: %s", traceback(tostring(err), 2)); return err; end
 local function log_if_failed(req, ret, ...)
 	if not ret then
-		log("error", "Request '%s': error in callback: %s", req.id, tostring((...)));
+		log("error", "Request '%s': error in callback: %s", req.id, (...));
 		if not req.suppress_errors then
 			error(...);
 		end
@@ -81,7 +83,24 @@
 			return;
 		end
 
+		local finalize_sink;
 		local function success_cb(r)
+			if r.partial then
+				-- Request should be streamed
+				log("debug", "Request '%s': partial response (%s%s)",
+					request.id,
+					r.chunked and "chunked, " or "",
+					r.body_length and ("%d bytes"):format(r.body_length) or "unknown length"
+				);
+				if request.streaming_handler then
+					log("debug", "Request '%s': Streaming via handler");
+					r.body_sink, finalize_sink = request.streaming_handler(r);
+				end
+				return;
+			elseif finalize_sink then
+				log("debug", "Request '%s': Finalizing response stream");
+				finalize_sink(r);
+			end
 			if request.callback then
 				request.callback(r.body, r.code, r, request);
 				request.callback = nil;
@@ -161,7 +180,7 @@
 	local request = requests[conn];
 
 	if not request then
-		log("warn", "Received response from connection %s with no request attached!", tostring(conn));
+		log("warn", "Received response from connection %s with no request attached!", conn);
 		return;
 	end
 
@@ -254,6 +273,7 @@
 		end
 		req.insecure = ex.insecure;
 		req.suppress_errors = ex.suppress_errors;
+		req.streaming_handler = ex.streaming_handler;
 	end
 
 	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);
@@ -282,7 +302,22 @@
 local function new(options)
 	local http = {
 		options = options;
-		request = request;
+		request = function (self, u, ex, callback)
+			if callback ~= nil then
+				return request(self, u, ex, callback);
+			else
+				return promise.new(function (resolve, reject)
+					request(self, u, ex, function (body, code, a, b)
+						if code == 0 then
+							reject(http_errors.new(body, { request = a }));
+						else
+							a.request = b;
+							resolve(a);
+						end
+					end);
+				end);
+			end
+		end;
 		new = options and function (new_options)
 			local final_options = {};
 			for k, v in pairs(options) do final_options[k] = v; end
@@ -297,7 +332,7 @@
 end
 
 local default_http = new({
-	sslctx = { mode = "client", protocol = "sslv23", options = { "no_sslv2", "no_sslv3" } };
+	sslctx = { mode = "client", protocol = "sslv23", options = { "no_sslv2", "no_sslv3" }, alpn = "http/1.1" };
 	suppress_errors = true;
 });