Skip to content

Commit

Permalink
Passing test for MAX_FRAME_SIZE
Browse files Browse the repository at this point in the history
  • Loading branch information
joedevivo committed Jun 7, 2015
1 parent b2c7aee commit 80e798f
Show file tree
Hide file tree
Showing 7 changed files with 82 additions and 25 deletions.
6 changes: 5 additions & 1 deletion common_test/http2_frame_size_SUITE.erl
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,12 @@ frame_too_big(Config) ->
%% How do I get the response? Should be GOAWAY with FRAME_SIZE_ERROR
timer:sleep(10000),

Resp = http2c:get_frames(Client, 3),
Resp = http2c:get_frames(Client, 0),
ct:pal("Resp: ~p", [Resp]),

?assertEqual(1, length(Resp)),

[{_GoAwayH, GoAway}] = Resp,
?FRAME_SIZE_ERROR = GoAway#goaway.error_code,

ok.
2 changes: 1 addition & 1 deletion include/http2.hrl
Original file line number Diff line number Diff line change
Expand Up @@ -137,7 +137,7 @@
-record(goaway, {
last_stream_id :: stream_id(),
error_code :: error_code(),
additional_debug_data :: binary()
additional_debug_data = <<>> :: binary()
}).
-type goaway() :: #goaway{}.

Expand Down
8 changes: 7 additions & 1 deletion src/chatterbox.app.src
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,13 @@
{mod, { chatterbox_app, []}},
{env, [
{port, 80},
{concurrent_acceptors, 20}
{concurrent_acceptors, 20},
{header_table_size, 4096},
{enable_push, 1},
{max_concurrent_streams, unlimited},
{initial_window_size, 65535},
{max_frame_size, 16384},
{max_header_list_size, unlimited}
]}
]}.
%% vim: set filetype=erlang tabstop=2
22 changes: 19 additions & 3 deletions src/chatterbox.erl
Original file line number Diff line number Diff line change
@@ -1,6 +1,22 @@
-module(chatterbox).

-export([hello/0]).
-include("http2.hrl").

hello() ->
howdy.
-export([settings/0]).

settings() ->
{ok, HTS} = application:get_env(?MODULE, header_table_size),
{ok, EP} = application:get_env(?MODULE, enable_push),
{ok, MCS} = application:get_env(?MODULE, max_concurrent_streams),
{ok, IWS} = application:get_env(?MODULE, initial_window_size),
{ok, MFS} = application:get_env(?MODULE, max_frame_size),
{ok, MHLS} = application:get_env(?MODULE, max_header_list_size),

#settings{
header_table_size=HTS,
enable_push=EP,
max_concurrent_streams=MCS,
initial_window_size=IWS,
max_frame_size=MFS,
max_header_list_size=MHLS
}.
24 changes: 22 additions & 2 deletions src/chatterbox_fsm.erl
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
frame_backlog = [],
settings_backlog = [],
client_settings = undefined,
server_settings = #settings{},
server_settings = chatterbox:settings() ::settings(),
next_available_stream_id = 2 :: stream_id(),
streams = [] :: [proplists:property()],
decode_context = hpack:new_decode_context() :: hpack:decode_context(),
Expand All @@ -30,7 +30,9 @@

-export([accept/2,
settings_handshake/2,
connected/2]).
connected/2,
closing/2
]).

start_link(Socket) ->
gen_fsm:start_link(?MODULE, Socket, []).
Expand Down Expand Up @@ -157,11 +159,29 @@ connected(start_frame, S = #chatterbox_fsm_state{socket=Socket}) ->
gen_fsm:send_event(self(), start_frame),
Response.

closing(StateName, State) ->
lager:debug("[closing] ~p", [StateName]),
{next_state, StateName, State}.
%% Maybe use something like this for readability later
%% -define(SOCKET_PM, #chatterbox_fsm_state{socket=Socket}).

-spec route_frame(frame(), #chatterbox_fsm_state{}) ->
{next_state, connected, #chatterbox_fsm_state{}}.
route_frame({#frame_header{length=L}, _},
S = #chatterbox_fsm_state{socket={T,Socket},
server_settings=#settings{max_frame_size=MFS},
next_available_stream_id=NAS})
when L > MFS ->
GoAway = #goaway{
last_stream_id=NAS,
error_code=?FRAME_SIZE_ERROR
},
GoAwayBin = http2_frame:to_binary({#frame_header{
stream_id=0
}, GoAway}),
T:send(Socket, GoAwayBin),
{next_state, closing, S};

route_frame({H=#frame_header{stream_id=StreamId}, _Payload}, S = #chatterbox_fsm_state{socket=_Socket})
when H#frame_header.type == ?DATA ->
lager:debug("Received DATA Frame for Stream ~p", [StreamId]),
Expand Down
43 changes: 27 additions & 16 deletions src/http2_frame.erl
Original file line number Diff line number Diff line change
Expand Up @@ -33,10 +33,9 @@
-spec read(socket()) -> {frame_header(), payload()}.
read(Socket) ->
{H, <<>>} = read_header(Socket),
lager:debug("HeaderBytes: ~p", [H]),
%%lager:debug("HeaderBytes: ~p", [H]),
{ok, Payload, <<>>} = read_payload(Socket, H),
lager:debug("PayloadBytes: ~p", [Payload]),

%%lager:debug("PayloadBytes: ~p", [Payload]),
lager:debug(format({H, Payload})),
{H, Payload}.

Expand Down Expand Up @@ -136,9 +135,13 @@ format(<<>>) -> "".

-spec to_binary(frame()) -> iodata().
to_binary({Header, Payload}) ->
HeaderBin = header_to_binary(Header),
{Type, PayloadBin} = payload_to_binary(Payload),
NewHeader = Header#frame_header{
length = iodata_size(PayloadBin),
type = Type
},
HeaderBin = header_to_binary(NewHeader),
lager:debug("HeaderBin: ~p", [HeaderBin]),
PayloadBin = payload_to_binary(Payload),
lager:debug("PayloadBin: ~p", [PayloadBin]),
[HeaderBin, PayloadBin].

Expand All @@ -149,16 +152,24 @@ header_to_binary(#frame_header{
flags=F,
stream_id=StreamId
}) ->
lager:debug("H: ~p", [L]),
<<L:24,T:8,F:8,0:1,StreamId:31>>.

-spec payload_to_binary(payload()) -> iodata().
payload_to_binary(P=#data{}) -> http2_frame_data:to_binary(P);
payload_to_binary(P=#headers{}) -> http2_frame_headers:to_binary(P);
payload_to_binary(P=#priority{}) -> http2_frame_priority:to_binary(P);
payload_to_binary(P=#rst_stream{}) -> http2_frame_rst_stream:to_binary(P);
payload_to_binary(P=#settings{}) -> http2_frame_settings:to_binary(P);
payload_to_binary(P=#push_promise{}) -> http2_frame_push_promise:to_binary(P);
payload_to_binary(P=#ping{}) -> http2_frame_ping:to_binary(P);
payload_to_binary(P=#goaway{}) -> http2_frame_goaway:to_binary(P);
payload_to_binary(P=#window_update{}) -> http2_frame_window_update:to_binary(P);
payload_to_binary(P=#continuation{}) -> http2_frame_continuation:to_binary(P).
-spec payload_to_binary(payload()) -> {frame_type(), iodata()}.
payload_to_binary(P=#data{}) -> {?DATA, http2_frame_data:to_binary(P)};
payload_to_binary(P=#headers{}) -> {?HEADERS, http2_frame_headers:to_binary(P)};
payload_to_binary(P=#priority{}) -> {?PRIORITY, http2_frame_priority:to_binary(P)};
payload_to_binary(P=#rst_stream{}) -> {?RST_STREAM, http2_frame_rst_stream:to_binary(P)};
payload_to_binary(P=#settings{}) -> {?SETTINGS, http2_frame_settings:to_binary(P)};
payload_to_binary(P=#push_promise{}) -> {?PUSH_PROMISE, http2_frame_push_promise:to_binary(P)};
payload_to_binary(P=#ping{}) -> {?PING, http2_frame_ping:to_binary(P)};
payload_to_binary(P=#goaway{}) -> {?GOAWAY, http2_frame_goaway:to_binary(P)};
payload_to_binary(P=#window_update{}) -> {?WINDOW_UPDATE, http2_frame_window_update:to_binary(P)};
payload_to_binary(P=#continuation{}) -> {?CONTINUATION, http2_frame_continuation:to_binary(P)}.

iodata_size(L) when is_list(L) ->
lists:foldl(fun(X, Acc) ->
Acc + iodata_size(X)
end, 0, L);
iodata_size(B) when is_binary(B) ->
byte_size(B).
2 changes: 1 addition & 1 deletion src/http2_frame_goaway.erl
Original file line number Diff line number Diff line change
Expand Up @@ -32,4 +32,4 @@ to_binary(#goaway{
error_code=EC,
additional_debug_data=ADD
}) ->
<<0:1,LSID:31,EC:32,ADD>>.
[<<0:1,LSID:31,EC:32>>,ADD].

0 comments on commit 80e798f

Please sign in to comment.