aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLoïc Hoguin <[email protected]>2017-01-02 16:31:59 +0100
committerLoïc Hoguin <[email protected]>2017-01-02 16:31:59 +0100
commitbc733a2ca5f7d07f997ad6edf184f775b23434aa (patch)
treea72c4de950adc26402fc847f601eb5bd7c0a71cb
parent6fcb19616b09b59f8fab68b30c08606f9260a5b3 (diff)
downloadgun-1.0.0-pre.2.tar.gz
gun-1.0.0-pre.2.tar.bz2
gun-1.0.0-pre.2.zip
Fix sending of data > 16384 with HTTP/21.0.0-pre.2
-rw-r--r--src/gun_http2.erl28
1 files changed, 21 insertions, 7 deletions
diff --git a/src/gun_http2.erl b/src/gun_http2.erl
index e58db74..c0983b6 100644
--- a/src/gun_http2.erl
+++ b/src/gun_http2.erl
@@ -249,10 +249,11 @@ request(State=#http2_state{socket=Socket, transport=Transport, encode_state=Enco
Headers = lists:keystore(<<"content-length">>, 1, Headers0,
{<<"content-length">>, integer_to_binary(iolist_size(Body))}),
{HeaderBlock, EncodeState} = prepare_headers(EncodeState0, Transport, Method, Host, Port, Path, Headers),
- Transport:send(Socket, [
- cow_http2:headers(StreamID, nofin, HeaderBlock),
- cow_http2:data(StreamID, fin, Body)
- ]),
+ Transport:send(Socket, cow_http2:headers(StreamID, nofin, HeaderBlock)),
+ %% @todo 16384 is the default SETTINGS_MAX_FRAME_SIZE.
+ %% Use the length set by the server instead, if any.
+ %% @todo Would be better if we didn't have to convert to binary.
+ send_data(Socket, Transport, StreamID, fin, iolist_to_binary(Body), 16384),
new_stream(StreamID, StreamRef, nofin, fin,
State#http2_state{stream_id=StreamID + 2, encode_state=EncodeState}).
@@ -276,18 +277,31 @@ prepare_headers(EncodeState, Transport, Method, Host, Port, Path, Headers0) ->
|Headers1],
cow_hpack:encode(Headers, EncodeState).
-data(State=#http2_state{socket=Socket, transport=Transport},
- StreamRef, IsFin, Data) ->
+data(State=#http2_state{socket=Socket, transport=Transport}, StreamRef, IsFin, Data) ->
case get_stream_by_ref(StreamRef, State) of
#stream{local=fin} ->
error_stream_closed(State, StreamRef);
S = #stream{} ->
- Transport:send(Socket, cow_http2:data(S#stream.id, IsFin, Data)),
+ %% @todo 16384 is the default SETTINGS_MAX_FRAME_SIZE.
+ %% Use the length set by the server instead, if any.
+ %% @todo Would be better if we didn't have to convert to binary.
+ send_data(Socket, Transport, S#stream.id, IsFin, iolist_to_binary(Data), 16384),
local_fin(S, State, IsFin);
false ->
error_stream_not_found(State, StreamRef)
end.
+%% This same function is found in cowboy_http2.
+send_data(Socket, Transport, StreamID, IsFin, Data, Length) ->
+ if
+ Length < byte_size(Data) ->
+ << Payload:Length/binary, Rest/bits >> = Data,
+ Transport:send(Socket, cow_http2:data(StreamID, nofin, Payload)),
+ send_data(Socket, Transport, StreamID, IsFin, Rest, Length);
+ true ->
+ Transport:send(Socket, cow_http2:data(StreamID, IsFin, Data))
+ end.
+
cancel(State=#http2_state{socket=Socket, transport=Transport},
StreamRef) ->
case get_stream_by_ref(StreamRef, State) of