From f3d6b05b863fe177a34a8a6ba48c5f263ef8cf82 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lo=C3=AFc=20Hoguin?= Date: Sun, 29 Oct 2017 19:52:27 +0000 Subject: Add cowboy_req:inform/2,3 User code can now send as many 1xx responses as necessary. --- src/cowboy_http2.erl | 7 +++++++ src/cowboy_req.erl | 16 +++++++++++++++- src/cowboy_stream_h.erl | 2 ++ 3 files changed, 24 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/cowboy_http2.erl b/src/cowboy_http2.erl index d863d1a..663d33a 100644 --- a/src/cowboy_http2.erl +++ b/src/cowboy_http2.erl @@ -495,6 +495,13 @@ commands(State, Stream=#stream{local=idle}, [{error_response, StatusCode, Header commands(State, Stream, [{response, StatusCode, Headers, Body}|Tail]); commands(State, Stream, [{error_response, _, _, _}|Tail]) -> commands(State, Stream, Tail); +%% Send an informational response. +commands(State=#state{socket=Socket, transport=Transport, encode_state=EncodeState0}, + Stream=#stream{id=StreamID, local=idle}, [{inform, StatusCode, Headers0}|Tail]) -> + Headers = Headers0#{<<":status">> => status(StatusCode)}, + {HeaderBlock, EncodeState} = headers_encode(Headers, EncodeState0), + Transport:send(Socket, cow_http2:headers(StreamID, fin, HeaderBlock)), + commands(State#state{encode_state=EncodeState}, Stream, Tail); %% Send response headers. %% %% @todo Kill the stream if it sent a response when one has already been sent. diff --git a/src/cowboy_req.erl b/src/cowboy_req.erl index 1615c07..253564d 100644 --- a/src/cowboy_req.erl +++ b/src/cowboy_req.erl @@ -71,6 +71,8 @@ -export([set_resp_body/2]). %% @todo set_resp_body/3 with a ContentType or even Headers argument, to set content headers. -export([has_resp_body/1]). +-export([inform/2]). +-export([inform/3]). -export([reply/2]). -export([reply/3]). -export([reply/4]). @@ -685,6 +687,18 @@ has_resp_body(_) -> delete_resp_header(Name, Req=#{resp_headers := RespHeaders}) -> Req#{resp_headers => maps:remove(Name, RespHeaders)}. +-spec inform(cowboy:http_status(), req()) -> ok. +inform(Status, Req) -> + inform(Status, #{}, Req). + +-spec inform(cowboy:http_status(), cowboy:http_headers(), req()) -> ok. +inform(_, _, #{has_sent_resp := _}) -> + error(function_clause); %% @todo Better error message. +inform(Status, Headers, #{pid := Pid, streamid := StreamID}) + when is_integer(Status); is_binary(Status) -> + Pid ! {{Pid, StreamID}, {inform, Status, Headers}}, + ok. + -spec reply(cowboy:http_status(), Req) -> Req when Req::req(). reply(Status, Req) -> reply(Status, #{}, Req). @@ -699,7 +713,7 @@ reply(Status, Headers, Req) -> -spec reply(cowboy:http_status(), cowboy:http_headers(), resp_body(), Req) -> Req when Req::req(). reply(_, _, _, #{has_sent_resp := _}) -> - error(function_clause); + error(function_clause); %% @todo Better error message. reply(Status, Headers, {sendfile, _, 0, _}, Req) when is_integer(Status); is_binary(Status) -> do_reply(Status, Headers#{ diff --git a/src/cowboy_stream_h.erl b/src/cowboy_stream_h.erl index 5c674dd..c631c87 100644 --- a/src/cowboy_stream_h.erl +++ b/src/cowboy_stream_h.erl @@ -119,6 +119,8 @@ info(_StreamID, {read_body_timeout, Ref}, State=#state{pid=Pid, read_body_ref=Re info(_StreamID, {read_body_timeout, _}, State) -> {[], State}; %% Response. +info(_StreamID, Inform = {inform, _, _}, State) -> + {[Inform], State}; info(_StreamID, Response = {response, _, _, _}, State) -> {[Response], State}; info(_StreamID, Headers = {headers, _, _}, State) -> -- cgit v1.2.3