zf

zenflows testing
git clone https://s.sonu.ch/~srfsh/zf.git
Log | Files | Refs | Submodules | README | LICENSE

cow_ws.erl (31521B)


      1 %% Copyright (c) 2015-2018, Loïc Hoguin <essen@ninenines.eu>
      2 %%
      3 %% Permission to use, copy, modify, and/or distribute this software for any
      4 %% purpose with or without fee is hereby granted, provided that the above
      5 %% copyright notice and this permission notice appear in all copies.
      6 %%
      7 %% THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
      8 %% WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
      9 %% MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
     10 %% ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
     11 %% WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
     12 %% ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
     13 %% OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
     14 
     15 -module(cow_ws).
     16 
     17 -export([key/0]).
     18 -export([encode_key/1]).
     19 
     20 -export([negotiate_permessage_deflate/3]).
     21 -export([negotiate_x_webkit_deflate_frame/3]).
     22 
     23 -export([validate_permessage_deflate/3]).
     24 
     25 -export([parse_header/3]).
     26 -export([parse_payload/9]).
     27 -export([make_frame/4]).
     28 
     29 -export([frame/2]).
     30 -export([masked_frame/2]).
     31 
     32 -type close_code() :: 1000..1003 | 1006..1011 | 3000..4999.
     33 -export_type([close_code/0]).
     34 
     35 -type extensions() :: map().
     36 -export_type([extensions/0]).
     37 
     38 -type deflate_opts() :: #{
     39 	%% Compression parameters.
     40 	level => zlib:zlevel(),
     41 	mem_level => zlib:zmemlevel(),
     42 	strategy => zlib:zstrategy(),
     43 
     44 	%% Whether the compression context will carry over between frames.
     45 	server_context_takeover => takeover | no_takeover,
     46 	client_context_takeover => takeover | no_takeover,
     47 
     48 	%% LZ77 sliding window size limits.
     49 	server_max_window_bits => 8..15,
     50 	client_max_window_bits => 8..15
     51 }.
     52 -export_type([deflate_opts/0]).
     53 
     54 -type frag_state() :: undefined | {fin | nofin, text | binary, rsv()}.
     55 -export_type([frag_state/0]).
     56 
     57 -type frame() :: close | ping | pong
     58 	| {text | binary | close | ping | pong, iodata()}
     59 	| {close, close_code(), iodata()}
     60 	| {fragment, fin | nofin, text | binary | continuation, iodata()}.
     61 -export_type([frame/0]).
     62 
     63 -type frame_type() :: fragment | text | binary | close | ping | pong.
     64 -export_type([frame_type/0]).
     65 
     66 -type mask_key() :: undefined | 0..16#ffffffff.
     67 -export_type([mask_key/0]).
     68 
     69 -type rsv() :: <<_:3>>.
     70 -export_type([rsv/0]).
     71 
     72 -type utf8_state() :: 0..8 | undefined.
     73 -export_type([utf8_state/0]).
     74 
     75 %% @doc Generate a key for the Websocket handshake request.
     76 
     77 -spec key() -> binary().
     78 key() ->
     79 	base64:encode(crypto:strong_rand_bytes(16)).
     80 
     81 %% @doc Encode the key into the accept value for the Websocket handshake response.
     82 
     83 -spec encode_key(binary()) -> binary().
     84 encode_key(Key) ->
     85 	base64:encode(crypto:hash(sha, [Key, "258EAFA5-E914-47DA-95CA-C5AB0DC85B11"])).
     86 
     87 %% @doc Negotiate the permessage-deflate extension.
     88 
     89 -spec negotiate_permessage_deflate(
     90 	[binary() | {binary(), binary()}], Exts, deflate_opts())
     91 	-> ignore | {ok, iolist(), Exts} when Exts::extensions().
     92 %% Ignore if deflate already negotiated.
     93 negotiate_permessage_deflate(_, #{deflate := _}, _) ->
     94 	ignore;
     95 negotiate_permessage_deflate(Params, Extensions, Opts) ->
     96 	case lists:usort(Params) of
     97 		%% Ignore if multiple parameters with the same name.
     98 		Params2 when length(Params) =/= length(Params2) ->
     99 			ignore;
    100 		Params2 ->
    101 			negotiate_permessage_deflate1(Params2, Extensions, Opts)
    102 	end.
    103 
    104 negotiate_permessage_deflate1(Params, Extensions, Opts) ->
    105 	%% We are allowed to send back no_takeover even if the client
    106 	%% accepts takeover. Therefore we use no_takeover if any of
    107 	%% the inputs have it.
    108 	ServerTakeover = maps:get(server_context_takeover, Opts, takeover),
    109 	ClientTakeover = maps:get(client_context_takeover, Opts, takeover),
    110 	%% We can send back window bits smaller than or equal to what
    111 	%% the client sends us.
    112 	ServerMaxWindowBits = maps:get(server_max_window_bits, Opts, 15),
    113 	ClientMaxWindowBits = maps:get(client_max_window_bits, Opts, 15),
    114 	%% We may need to send back no_context_takeover depending on configuration.
    115 	RespParams0 = case ServerTakeover of
    116 		takeover -> [];
    117 		no_takeover -> [<<"; server_no_context_takeover">>]
    118 	end,
    119 	RespParams1 = case ClientTakeover of
    120 		takeover -> RespParams0;
    121 		no_takeover -> [<<"; client_no_context_takeover">>|RespParams0]
    122 	end,
    123 	Negotiated0 = #{
    124 		server_context_takeover => ServerTakeover,
    125 		client_context_takeover => ClientTakeover,
    126 		server_max_window_bits => ServerMaxWindowBits,
    127 		client_max_window_bits => ClientMaxWindowBits
    128 	},
    129 	case negotiate_params(Params, Negotiated0, RespParams1) of
    130 		ignore ->
    131 			ignore;
    132 		{#{server_max_window_bits := SB}, _} when SB > ServerMaxWindowBits ->
    133 			ignore;
    134 		{#{client_max_window_bits := CB}, _} when CB > ClientMaxWindowBits ->
    135 			ignore;
    136 		{Negotiated, RespParams2} ->
    137 			%% We add the configured max window bits if necessary.
    138 			RespParams = case Negotiated of
    139 				#{server_max_window_bits_set := true} -> RespParams2;
    140 				_ when ServerMaxWindowBits =:= 15 -> RespParams2;
    141 				_ -> [<<"; server_max_window_bits=">>,
    142 					integer_to_binary(ServerMaxWindowBits)|RespParams2]
    143 			end,
    144 			{Inflate, Deflate} = init_permessage_deflate(
    145 				maps:get(client_max_window_bits, Negotiated),
    146 				maps:get(server_max_window_bits, Negotiated), Opts),
    147 			{ok, [<<"permessage-deflate">>, RespParams], Extensions#{
    148 				deflate => Deflate,
    149 				deflate_takeover => maps:get(server_context_takeover, Negotiated),
    150 				inflate => Inflate,
    151 				inflate_takeover => maps:get(client_context_takeover, Negotiated)}}
    152 	end.
    153 
    154 negotiate_params([], Negotiated, RespParams) ->
    155 	{Negotiated, RespParams};
    156 %% We must only send the client_max_window_bits parameter if the
    157 %% request explicitly indicated the client supports it.
    158 negotiate_params([<<"client_max_window_bits">>|Tail], Negotiated, RespParams) ->
    159 	CB = maps:get(client_max_window_bits, Negotiated),
    160 	negotiate_params(Tail, Negotiated#{client_max_window_bits_set => true},
    161 		[<<"; client_max_window_bits=">>, integer_to_binary(CB)|RespParams]);
    162 negotiate_params([{<<"client_max_window_bits">>, Max}|Tail], Negotiated, RespParams) ->
    163 	CB0 = maps:get(client_max_window_bits, Negotiated, undefined),
    164 	case parse_max_window_bits(Max) of
    165 		error ->
    166 			ignore;
    167 		CB when CB =< CB0 ->
    168 			negotiate_params(Tail, Negotiated#{client_max_window_bits => CB},
    169 				[<<"; client_max_window_bits=">>, Max|RespParams]);
    170 		%% When the client sends window bits larger than the server wants
    171 		%% to use, we use what the server defined.
    172 		_ ->
    173 			negotiate_params(Tail, Negotiated,
    174 				[<<"; client_max_window_bits=">>, integer_to_binary(CB0)|RespParams])
    175 	end;
    176 negotiate_params([{<<"server_max_window_bits">>, Max}|Tail], Negotiated, RespParams) ->
    177 	SB0 = maps:get(server_max_window_bits, Negotiated, undefined),
    178 	case parse_max_window_bits(Max) of
    179 		error ->
    180 			ignore;
    181 		SB when SB =< SB0 ->
    182 			negotiate_params(Tail, Negotiated#{
    183 				server_max_window_bits => SB,
    184 				server_max_window_bits_set => true},
    185 				[<<"; server_max_window_bits=">>, Max|RespParams]);
    186 		%% When the client sends window bits larger than the server wants
    187 		%% to use, we use what the server defined. The parameter will be
    188 		%% set only when this function returns.
    189 		_ ->
    190 			negotiate_params(Tail, Negotiated, RespParams)
    191 	end;
    192 %% We only need to send the no_context_takeover parameter back
    193 %% here if we didn't already define it via configuration.
    194 negotiate_params([<<"client_no_context_takeover">>|Tail], Negotiated, RespParams) ->
    195 	case maps:get(client_context_takeover, Negotiated) of
    196 		no_takeover ->
    197 			negotiate_params(Tail, Negotiated, RespParams);
    198 		takeover ->
    199 			negotiate_params(Tail, Negotiated#{client_context_takeover => no_takeover},
    200 				[<<"; client_no_context_takeover">>|RespParams])
    201 	end;
    202 negotiate_params([<<"server_no_context_takeover">>|Tail], Negotiated, RespParams) ->
    203 	case maps:get(server_context_takeover, Negotiated) of
    204 		no_takeover ->
    205 			negotiate_params(Tail, Negotiated, RespParams);
    206 		takeover ->
    207 			negotiate_params(Tail, Negotiated#{server_context_takeover => no_takeover},
    208 				[<<"; server_no_context_takeover">>|RespParams])
    209 	end;
    210 %% Ignore if unknown parameter; ignore if parameter with invalid or missing value.
    211 negotiate_params(_, _, _) ->
    212 	ignore.
    213 
    214 parse_max_window_bits(<<"8">>) -> 8;
    215 parse_max_window_bits(<<"9">>) -> 9;
    216 parse_max_window_bits(<<"10">>) -> 10;
    217 parse_max_window_bits(<<"11">>) -> 11;
    218 parse_max_window_bits(<<"12">>) -> 12;
    219 parse_max_window_bits(<<"13">>) -> 13;
    220 parse_max_window_bits(<<"14">>) -> 14;
    221 parse_max_window_bits(<<"15">>) -> 15;
    222 parse_max_window_bits(_) -> error.
    223 
    224 %% A negative WindowBits value indicates that zlib headers are not used.
    225 init_permessage_deflate(InflateWindowBits, DeflateWindowBits, Opts) ->
    226 	Inflate = zlib:open(),
    227 	ok = zlib:inflateInit(Inflate, -InflateWindowBits),
    228 	Deflate = zlib:open(),
    229 	%% zlib 1.2.11+ now rejects -8. It used to transform it to -9.
    230 	%% We need to use 9 when 8 is requested for interoperability.
    231 	DeflateWindowBits2 = case DeflateWindowBits of
    232 		8 -> 9;
    233 		_ -> DeflateWindowBits
    234 	end,
    235 	ok = zlib:deflateInit(Deflate,
    236 		maps:get(level, Opts, best_compression),
    237 		deflated,
    238 		-DeflateWindowBits2,
    239 		maps:get(mem_level, Opts, 8),
    240 		maps:get(strategy, Opts, default)),
    241 	%% Set the owner pid of the zlib contexts if requested.
    242 	case Opts of
    243 		#{owner := Pid} -> set_owner(Pid, Inflate, Deflate);
    244 		_ -> ok
    245 	end,
    246 	{Inflate, Deflate}.
    247 
    248 -ifdef(OTP_RELEASE).
    249 %% Using is_port/1 on a zlib context results in a Dialyzer warning in OTP 21.
    250 %% This function helps silence that warning while staying compatible
    251 %% with all supported versions.
    252 
    253 set_owner(Pid, Inflate, Deflate) ->
    254 	zlib:set_controlling_process(Inflate, Pid),
    255 	zlib:set_controlling_process(Deflate, Pid).
    256 -else.
    257 %% The zlib port became a reference in OTP 20.1+. There
    258 %% was however no way to change the controlling process
    259 %% until the OTP 20.1.3 patch version. Since we can't
    260 %% enable compression for 20.1, 20.1.1 and 20.1.2 we
    261 %% explicitly crash. The caller should ignore this extension.
    262 
    263 set_owner(Pid, Inflate, Deflate) when is_port(Inflate) ->
    264 	true = erlang:port_connect(Inflate, Pid),
    265 	true = unlink(Inflate),
    266 	true = erlang:port_connect(Deflate, Pid),
    267 	true = unlink(Deflate),
    268 	ok;
    269 set_owner(Pid, Inflate, Deflate) ->
    270 	case erlang:function_exported(zlib, set_controlling_process, 2) of
    271 		true ->
    272 			zlib:set_controlling_process(Inflate, Pid),
    273 			zlib:set_controlling_process(Deflate, Pid);
    274 		false ->
    275 			exit({error, incompatible_zlib_version,
    276 				'OTP 20.1, 20.1.1 and 20.1.2 are missing required functionality.'})
    277 	end.
    278 -endif.
    279 
    280 %% @doc Negotiate the x-webkit-deflate-frame extension.
    281 %%
    282 %% The implementation is very basic and none of the parameters
    283 %% are currently supported.
    284 
    285 -spec negotiate_x_webkit_deflate_frame(
    286 	[binary() | {binary(), binary()}], Exts, deflate_opts())
    287 	-> ignore | {ok, binary(), Exts} when Exts::extensions().
    288 negotiate_x_webkit_deflate_frame(_, #{deflate := _}, _) ->
    289 	ignore;
    290 negotiate_x_webkit_deflate_frame(_Params, Extensions, Opts) ->
    291 	% Since we are negotiating an unconstrained deflate-frame
    292 	% then we must be willing to accept frames using the
    293 	% maximum window size which is 2^15.
    294 	{Inflate, Deflate} = init_permessage_deflate(15, 15, Opts),
    295 	{ok, <<"x-webkit-deflate-frame">>,
    296 		Extensions#{
    297 			deflate => Deflate,
    298 			deflate_takeover => takeover,
    299 			inflate => Inflate,
    300 			inflate_takeover => takeover}}.
    301 
    302 %% @doc Validate the negotiated permessage-deflate extension.
    303 
    304 %% Error when more than one deflate extension was negotiated.
    305 validate_permessage_deflate(_, #{deflate := _}, _) ->
    306 	error;
    307 validate_permessage_deflate(Params, Extensions, Opts) ->
    308 	case lists:usort(Params) of
    309 		%% Error if multiple parameters with the same name.
    310 		Params2 when length(Params) =/= length(Params2) ->
    311 			error;
    312 		Params2 ->
    313 			case parse_response_permessage_deflate_params(Params2, 15, takeover, 15, takeover) of
    314 				error ->
    315 					error;
    316 				{ClientWindowBits, ClientTakeOver, ServerWindowBits, ServerTakeOver} ->
    317 					{Inflate, Deflate} = init_permessage_deflate(ServerWindowBits, ClientWindowBits, Opts),
    318 					{ok, Extensions#{
    319 						deflate => Deflate,
    320 						deflate_takeover => ClientTakeOver,
    321 						inflate => Inflate,
    322 						inflate_takeover => ServerTakeOver}}
    323 			end
    324 	end.
    325 
    326 parse_response_permessage_deflate_params([], CB, CTO, SB, STO) ->
    327 	{CB, CTO, SB, STO};
    328 parse_response_permessage_deflate_params([{<<"client_max_window_bits">>, Max}|Tail], _, CTO, SB, STO) ->
    329 	case parse_max_window_bits(Max) of
    330 		error -> error;
    331 		CB -> parse_response_permessage_deflate_params(Tail, CB, CTO, SB, STO)
    332 	end;
    333 parse_response_permessage_deflate_params([<<"client_no_context_takeover">>|Tail], CB, _, SB, STO) ->
    334 	parse_response_permessage_deflate_params(Tail, CB, no_takeover, SB, STO);
    335 parse_response_permessage_deflate_params([{<<"server_max_window_bits">>, Max}|Tail], CB, CTO, _, STO) ->
    336 	case parse_max_window_bits(Max) of
    337 		error -> error;
    338 		SB -> parse_response_permessage_deflate_params(Tail, CB, CTO, SB, STO)
    339 	end;
    340 parse_response_permessage_deflate_params([<<"server_no_context_takeover">>|Tail], CB, CTO, SB, _) ->
    341 	parse_response_permessage_deflate_params(Tail, CB, CTO, SB, no_takeover);
    342 %% Error if unknown parameter; error if parameter with invalid or missing value.
    343 parse_response_permessage_deflate_params(_, _, _, _, _) ->
    344 	error.
    345 
    346 %% @doc Parse and validate the Websocket frame header.
    347 %%
    348 %% This function also updates the fragmentation state according to
    349 %% information found in the frame's header.
    350 
    351 -spec parse_header(binary(), extensions(), frag_state())
    352 	-> error | more | {frame_type(), frag_state(), rsv(), non_neg_integer(), mask_key(), binary()}.
    353 %% RSV bits MUST be 0 unless an extension is negotiated
    354 %% that defines meanings for non-zero values.
    355 parse_header(<< _:1, Rsv:3, _/bits >>, Extensions, _) when Extensions =:= #{}, Rsv =/= 0 -> error;
    356 %% Last 2 RSV bits MUST be 0 if deflate-frame extension is used.
    357 parse_header(<< _:2, 1:1, _/bits >>, #{deflate := _}, _) -> error;
    358 parse_header(<< _:3, 1:1, _/bits >>, #{deflate := _}, _) -> error;
    359 %% Invalid opcode. Note that these opcodes may be used by extensions.
    360 parse_header(<< _:4, 3:4, _/bits >>, _, _) -> error;
    361 parse_header(<< _:4, 4:4, _/bits >>, _, _) -> error;
    362 parse_header(<< _:4, 5:4, _/bits >>, _, _) -> error;
    363 parse_header(<< _:4, 6:4, _/bits >>, _, _) -> error;
    364 parse_header(<< _:4, 7:4, _/bits >>, _, _) -> error;
    365 parse_header(<< _:4, 11:4, _/bits >>, _, _) -> error;
    366 parse_header(<< _:4, 12:4, _/bits >>, _, _) -> error;
    367 parse_header(<< _:4, 13:4, _/bits >>, _, _) -> error;
    368 parse_header(<< _:4, 14:4, _/bits >>, _, _) -> error;
    369 parse_header(<< _:4, 15:4, _/bits >>, _, _) -> error;
    370 %% Control frames MUST NOT be fragmented.
    371 parse_header(<< 0:1, _:3, Opcode:4, _/bits >>, _, _) when Opcode >= 8 -> error;
    372 %% A frame MUST NOT use the zero opcode unless fragmentation was initiated.
    373 parse_header(<< _:4, 0:4, _/bits >>, _, undefined) -> error;
    374 %% Non-control opcode when expecting control message or next fragment.
    375 parse_header(<< _:4, 1:4, _/bits >>, _, {_, _, _}) -> error;
    376 parse_header(<< _:4, 2:4, _/bits >>, _, {_, _, _}) -> error;
    377 parse_header(<< _:4, 3:4, _/bits >>, _, {_, _, _}) -> error;
    378 parse_header(<< _:4, 4:4, _/bits >>, _, {_, _, _}) -> error;
    379 parse_header(<< _:4, 5:4, _/bits >>, _, {_, _, _}) -> error;
    380 parse_header(<< _:4, 6:4, _/bits >>, _, {_, _, _}) -> error;
    381 parse_header(<< _:4, 7:4, _/bits >>, _, {_, _, _}) -> error;
    382 %% Close control frame length MUST be 0 or >= 2.
    383 parse_header(<< _:4, 8:4, _:1, 1:7, _/bits >>, _, _) -> error;
    384 %% Close control frame with incomplete close code. Need more data.
    385 parse_header(Data = << _:4, 8:4, 0:1, Len:7, _/bits >>, _, _) when Len > 1, byte_size(Data) < 4 -> more;
    386 parse_header(Data = << _:4, 8:4, 1:1, Len:7, _/bits >>, _, _) when Len > 1, byte_size(Data) < 8 -> more;
    387 %% 7 bits payload length.
    388 parse_header(<< Fin:1, Rsv:3/bits, Opcode:4, 0:1, Len:7, Rest/bits >>, _, FragState) when Len < 126 ->
    389 	parse_header(Opcode, Fin, FragState, Rsv, Len, undefined, Rest);
    390 parse_header(<< Fin:1, Rsv:3/bits, Opcode:4, 1:1, Len:7, MaskKey:32, Rest/bits >>, _, FragState) when Len < 126 ->
    391 	parse_header(Opcode, Fin, FragState, Rsv, Len, MaskKey, Rest);
    392 %% 16 bits payload length.
    393 parse_header(<< Fin:1, Rsv:3/bits, Opcode:4, 0:1, 126:7, Len:16, Rest/bits >>, _, FragState) when Len > 125, Opcode < 8 ->
    394 	parse_header(Opcode, Fin, FragState, Rsv, Len, undefined, Rest);
    395 parse_header(<< Fin:1, Rsv:3/bits, Opcode:4, 1:1, 126:7, Len:16, MaskKey:32, Rest/bits >>, _, FragState) when Len > 125, Opcode < 8 ->
    396 	parse_header(Opcode, Fin, FragState, Rsv, Len, MaskKey, Rest);
    397 %% 63 bits payload length.
    398 parse_header(<< Fin:1, Rsv:3/bits, Opcode:4, 0:1, 127:7, 0:1, Len:63, Rest/bits >>, _, FragState) when Len > 16#ffff, Opcode < 8 ->
    399 	parse_header(Opcode, Fin, FragState, Rsv, Len, undefined, Rest);
    400 parse_header(<< Fin:1, Rsv:3/bits, Opcode:4, 1:1, 127:7, 0:1, Len:63, MaskKey:32, Rest/bits >>, _, FragState) when Len > 16#ffff, Opcode < 8 ->
    401 	parse_header(Opcode, Fin, FragState, Rsv, Len, MaskKey, Rest);
    402 %% When payload length is over 63 bits, the most significant bit MUST be 0.
    403 parse_header(<< _:9, 127:7, 1:1, _/bits >>, _, _) -> error;
    404 %% For the next two clauses, it can be one of the following:
    405 %%
    406 %% * The minimal number of bytes MUST be used to encode the length
    407 %% * All control frames MUST have a payload length of 125 bytes or less
    408 parse_header(<< _:8, 0:1, 126:7, _:16, _/bits >>, _, _) -> error;
    409 parse_header(<< _:8, 1:1, 126:7, _:48, _/bits >>, _, _) -> error;
    410 parse_header(<< _:8, 0:1, 127:7, _:64, _/bits >>, _, _) -> error;
    411 parse_header(<< _:8, 1:1, 127:7, _:96, _/bits >>, _, _) -> error;
    412 %% Need more data.
    413 parse_header(_, _, _) -> more.
    414 
    415 parse_header(Opcode, Fin, FragState, Rsv, Len, MaskKey, Rest) ->
    416 	Type = opcode_to_frame_type(Opcode),
    417 	Type2 = case Fin of
    418 		0 -> fragment;
    419 		1 -> Type
    420 	end,
    421 	{Type2, frag_state(Type, Fin, Rsv, FragState), Rsv, Len, MaskKey, Rest}.
    422 
    423 opcode_to_frame_type(0) -> fragment;
    424 opcode_to_frame_type(1) -> text;
    425 opcode_to_frame_type(2) -> binary;
    426 opcode_to_frame_type(8) -> close;
    427 opcode_to_frame_type(9) -> ping;
    428 opcode_to_frame_type(10) -> pong.
    429 
    430 frag_state(Type, 0, Rsv, undefined) -> {nofin, Type, Rsv};
    431 frag_state(fragment, 0, _, FragState = {nofin, _, _}) -> FragState;
    432 frag_state(fragment, 1, _, {nofin, Type, Rsv}) -> {fin, Type, Rsv};
    433 frag_state(_, 1, _, FragState) -> FragState.
    434 
    435 %% @doc Parse and validate the frame's payload.
    436 %%
    437 %% Validation is only required for text and close frames which feature
    438 %% a UTF-8 payload.
    439 
    440 -spec parse_payload(binary(), mask_key(), utf8_state(), non_neg_integer(),
    441 		frame_type(), non_neg_integer(), frag_state(), extensions(), rsv())
    442 	-> {ok, binary(), utf8_state(), binary()}
    443 	| {ok, close_code(), binary(), utf8_state(), binary()}
    444 	| {more, binary(), utf8_state()}
    445 	| {more, close_code(), binary(), utf8_state()}
    446 	| {error, badframe | badencoding}.
    447 %% Empty last frame of compressed message.
    448 parse_payload(Data, _, Utf8State, _, _, 0, {fin, _, << 1:1, 0:2 >>},
    449 		#{inflate := Inflate, inflate_takeover := TakeOver}, _) ->
    450 	_ = zlib:inflate(Inflate, << 0, 0, 255, 255 >>),
    451 	case TakeOver of
    452 		no_takeover -> zlib:inflateReset(Inflate);
    453 		takeover -> ok
    454 	end,
    455 	{ok, <<>>, Utf8State, Data};
    456 %% Compressed fragmented frame.
    457 parse_payload(Data, MaskKey, Utf8State, ParsedLen, Type, Len, FragState = {_, _, << 1:1, 0:2 >>},
    458 		#{inflate := Inflate, inflate_takeover := TakeOver}, _) ->
    459 	{Data2, Rest, Eof} = split_payload(Data, Len),
    460 	Payload = inflate_frame(unmask(Data2, MaskKey, ParsedLen), Inflate, TakeOver, FragState, Eof),
    461 	validate_payload(Payload, Rest, Utf8State, ParsedLen, Type, FragState, Eof);
    462 %% Compressed frame.
    463 parse_payload(Data, MaskKey, Utf8State, ParsedLen, Type, Len, FragState,
    464 		#{inflate := Inflate, inflate_takeover := TakeOver}, << 1:1, 0:2 >>) when Type =:= text; Type =:= binary ->
    465 	{Data2, Rest, Eof} = split_payload(Data, Len),
    466 	Payload = inflate_frame(unmask(Data2, MaskKey, ParsedLen), Inflate, TakeOver, FragState, Eof),
    467 	validate_payload(Payload, Rest, Utf8State, ParsedLen, Type, FragState, Eof);
    468 %% Empty frame.
    469 parse_payload(Data, _, Utf8State, 0, _, 0, _, _, _)
    470 		when Utf8State =:= 0; Utf8State =:= undefined ->
    471 	{ok, <<>>, Utf8State, Data};
    472 %% Start of close frame.
    473 parse_payload(Data, MaskKey, Utf8State, 0, Type = close, Len, FragState, _, << 0:3 >>) ->
    474 	{<< MaskedCode:2/binary, Data2/bits >>, Rest, Eof} = split_payload(Data, Len),
    475 	<< CloseCode:16 >> = unmask(MaskedCode, MaskKey, 0),
    476 	case validate_close_code(CloseCode) of
    477 		ok ->
    478 			Payload = unmask(Data2, MaskKey, 2),
    479 			case validate_payload(Payload, Rest, Utf8State, 2, Type, FragState, Eof) of
    480 				{ok, _, Utf8State2, _} -> {ok, CloseCode, Payload, Utf8State2, Rest};
    481 				{more, _, Utf8State2} -> {more, CloseCode, Payload, Utf8State2};
    482 				Error -> Error
    483 			end;
    484 		error ->
    485 			{error, badframe}
    486 	end;
    487 %% Normal frame.
    488 parse_payload(Data, MaskKey, Utf8State, ParsedLen, Type, Len, FragState, _, << 0:3 >>) ->
    489 	{Data2, Rest, Eof} = split_payload(Data, Len),
    490 	Payload = unmask(Data2, MaskKey, ParsedLen),
    491 	validate_payload(Payload, Rest, Utf8State, ParsedLen, Type, FragState, Eof).
    492 
    493 split_payload(Data, Len) ->
    494 	case byte_size(Data) of
    495 		Len ->
    496 			{Data, <<>>, true};
    497 		DataLen when DataLen < Len ->
    498 			{Data, <<>>, false};
    499 		_ ->
    500 			<< Data2:Len/binary, Rest/bits >> = Data,
    501 			{Data2, Rest, true}
    502 	end.
    503 
    504 validate_close_code(Code) ->
    505 	if
    506 		Code < 1000 -> error;
    507 		Code =:= 1004 -> error;
    508 		Code =:= 1005 -> error;
    509 		Code =:= 1006 -> error;
    510 		Code > 1011, Code < 3000 -> error;
    511 		Code > 4999 -> error;
    512 		true -> ok
    513 	end.
    514 
    515 unmask(Data, undefined, _) ->
    516 	Data;
    517 unmask(Data, MaskKey, 0) ->
    518 	mask(Data, MaskKey, <<>>);
    519 %% We unmask on the fly so we need to continue from the right mask byte.
    520 unmask(Data, MaskKey, UnmaskedLen) ->
    521 	Left = UnmaskedLen rem 4,
    522 	Right = 4 - Left,
    523 	MaskKey2 = (MaskKey bsl (Left * 8)) + (MaskKey bsr (Right * 8)),
    524 	mask(Data, MaskKey2, <<>>).
    525 
    526 mask(<<>>, _, Unmasked) ->
    527 	Unmasked;
    528 mask(<< O:32, Rest/bits >>, MaskKey, Acc) ->
    529 	T = O bxor MaskKey,
    530 	mask(Rest, MaskKey, << Acc/binary, T:32 >>);
    531 mask(<< O:24 >>, MaskKey, Acc) ->
    532 	<< MaskKey2:24, _:8 >> = << MaskKey:32 >>,
    533 	T = O bxor MaskKey2,
    534 	<< Acc/binary, T:24 >>;
    535 mask(<< O:16 >>, MaskKey, Acc) ->
    536 	<< MaskKey2:16, _:16 >> = << MaskKey:32 >>,
    537 	T = O bxor MaskKey2,
    538 	<< Acc/binary, T:16 >>;
    539 mask(<< O:8 >>, MaskKey, Acc) ->
    540 	<< MaskKey2:8, _:24 >> = << MaskKey:32 >>,
    541 	T = O bxor MaskKey2,
    542 	<< Acc/binary, T:8 >>.
    543 
    544 inflate_frame(Data, Inflate, TakeOver, FragState, true)
    545 		when FragState =:= undefined; element(1, FragState) =:= fin ->
    546 	Data2 = zlib:inflate(Inflate, << Data/binary, 0, 0, 255, 255 >>),
    547 	case TakeOver of
    548 		no_takeover -> zlib:inflateReset(Inflate);
    549 		takeover -> ok
    550 	end,
    551 	iolist_to_binary(Data2);
    552 inflate_frame(Data, Inflate, _T, _F, _E) ->
    553 	iolist_to_binary(zlib:inflate(Inflate, Data)).
    554 
    555 %% The Utf8State variable can be set to 'undefined' to disable the validation.
    556 validate_payload(Payload, _, undefined, _, _, _, false) ->
    557 	{more, Payload, undefined};
    558 validate_payload(Payload, Rest, undefined, _, _, _, true) ->
    559 	{ok, Payload, undefined, Rest};
    560 %% Text frames and close control frames MUST have a payload that is valid UTF-8.
    561 validate_payload(Payload, Rest, Utf8State, _, Type, _, Eof) when Type =:= text; Type =:= close ->
    562 	case validate_utf8(Payload, Utf8State) of
    563 		1 -> {error, badencoding};
    564 		Utf8State2 when not Eof -> {more, Payload, Utf8State2};
    565 		0 when Eof -> {ok, Payload, 0, Rest};
    566 		_ -> {error, badencoding}
    567 	end;
    568 validate_payload(Payload, Rest, Utf8State, _, fragment, {Fin, text, _}, Eof) ->
    569 	case validate_utf8(Payload, Utf8State) of
    570 		1 -> {error, badencoding};
    571 		0 when Eof -> {ok, Payload, 0, Rest};
    572 		Utf8State2 when Eof, Fin =:= nofin -> {ok, Payload, Utf8State2, Rest};
    573 		Utf8State2 when not Eof -> {more, Payload, Utf8State2};
    574 		_ -> {error, badencoding}
    575 	end;
    576 validate_payload(Payload, _, Utf8State, _, _, _, false) ->
    577 	{more, Payload, Utf8State};
    578 validate_payload(Payload, Rest, Utf8State, _, _, _, true) ->
    579 	{ok, Payload, Utf8State, Rest}.
    580 
    581 %% Based on the Flexible and Economical UTF-8 Decoder algorithm by
    582 %% Bjoern Hoehrmann <bjoern@hoehrmann.de> (http://bjoern.hoehrmann.de/utf-8/decoder/dfa/).
    583 %%
    584 %% The original algorithm has been unrolled into all combinations of values for C and State
    585 %% each with a clause. The common clauses were then grouped together.
    586 %%
    587 %% This function returns 0 on success, 1 on error, and 2..8 on incomplete data.
    588 validate_utf8(<<>>, State) -> State;
    589 validate_utf8(<< C, Rest/bits >>, 0) when C < 128 -> validate_utf8(Rest, 0);
    590 validate_utf8(<< C, Rest/bits >>, 2) when C >= 128, C < 144 -> validate_utf8(Rest, 0);
    591 validate_utf8(<< C, Rest/bits >>, 3) when C >= 128, C < 144 -> validate_utf8(Rest, 2);
    592 validate_utf8(<< C, Rest/bits >>, 5) when C >= 128, C < 144 -> validate_utf8(Rest, 2);
    593 validate_utf8(<< C, Rest/bits >>, 7) when C >= 128, C < 144 -> validate_utf8(Rest, 3);
    594 validate_utf8(<< C, Rest/bits >>, 8) when C >= 128, C < 144 -> validate_utf8(Rest, 3);
    595 validate_utf8(<< C, Rest/bits >>, 2) when C >= 144, C < 160 -> validate_utf8(Rest, 0);
    596 validate_utf8(<< C, Rest/bits >>, 3) when C >= 144, C < 160 -> validate_utf8(Rest, 2);
    597 validate_utf8(<< C, Rest/bits >>, 5) when C >= 144, C < 160 -> validate_utf8(Rest, 2);
    598 validate_utf8(<< C, Rest/bits >>, 6) when C >= 144, C < 160 -> validate_utf8(Rest, 3);
    599 validate_utf8(<< C, Rest/bits >>, 7) when C >= 144, C < 160 -> validate_utf8(Rest, 3);
    600 validate_utf8(<< C, Rest/bits >>, 2) when C >= 160, C < 192 -> validate_utf8(Rest, 0);
    601 validate_utf8(<< C, Rest/bits >>, 3) when C >= 160, C < 192 -> validate_utf8(Rest, 2);
    602 validate_utf8(<< C, Rest/bits >>, 4) when C >= 160, C < 192 -> validate_utf8(Rest, 2);
    603 validate_utf8(<< C, Rest/bits >>, 6) when C >= 160, C < 192 -> validate_utf8(Rest, 3);
    604 validate_utf8(<< C, Rest/bits >>, 7) when C >= 160, C < 192 -> validate_utf8(Rest, 3);
    605 validate_utf8(<< C, Rest/bits >>, 0) when C >= 194, C < 224 -> validate_utf8(Rest, 2);
    606 validate_utf8(<< 224, Rest/bits >>, 0) -> validate_utf8(Rest, 4);
    607 validate_utf8(<< C, Rest/bits >>, 0) when C >= 225, C < 237 -> validate_utf8(Rest, 3);
    608 validate_utf8(<< 237, Rest/bits >>, 0) -> validate_utf8(Rest, 5);
    609 validate_utf8(<< C, Rest/bits >>, 0) when C =:= 238; C =:= 239 -> validate_utf8(Rest, 3);
    610 validate_utf8(<< 240, Rest/bits >>, 0) -> validate_utf8(Rest, 6);
    611 validate_utf8(<< C, Rest/bits >>, 0) when C =:= 241; C =:= 242; C =:= 243 -> validate_utf8(Rest, 7);
    612 validate_utf8(<< 244, Rest/bits >>, 0) -> validate_utf8(Rest, 8);
    613 validate_utf8(_, _) -> 1.
    614 
    615 %% @doc Return a frame tuple from parsed state and data.
    616 
    617 -spec make_frame(frame_type(), binary(), close_code(), frag_state()) -> frame().
    618 %% Fragmented frame.
    619 make_frame(fragment, Payload, _, {Fin, Type, _}) -> {fragment, Fin, Type, Payload};
    620 make_frame(text, Payload, _, _) -> {text, Payload};
    621 make_frame(binary, Payload, _, _) -> {binary, Payload};
    622 make_frame(close, <<>>, undefined, _) -> close;
    623 make_frame(close, Payload, CloseCode, _) -> {close, CloseCode, Payload};
    624 make_frame(ping, <<>>, _, _) -> ping;
    625 make_frame(ping, Payload, _, _) -> {ping, Payload};
    626 make_frame(pong, <<>>, _, _) -> pong;
    627 make_frame(pong, Payload, _, _) -> {pong, Payload}.
    628 
    629 %% @doc Construct an unmasked Websocket frame.
    630 
    631 -spec frame(frame(), extensions()) -> iodata().
    632 %% Control frames. Control packets must not be > 125 in length.
    633 frame(close, _) ->
    634 	<< 1:1, 0:3, 8:4, 0:8 >>;
    635 frame(ping, _) ->
    636 	<< 1:1, 0:3, 9:4, 0:8 >>;
    637 frame(pong, _) ->
    638 	<< 1:1, 0:3, 10:4, 0:8 >>;
    639 frame({close, Payload}, Extensions) ->
    640 	frame({close, 1000, Payload}, Extensions);
    641 frame({close, StatusCode, Payload}, _) ->
    642 	Len = 2 + iolist_size(Payload),
    643 	true = Len =< 125,
    644 	[<< 1:1, 0:3, 8:4, 0:1, Len:7, StatusCode:16 >>, Payload];
    645 frame({ping, Payload}, _) ->
    646 	Len = iolist_size(Payload),
    647 	true = Len =< 125,
    648 	[<< 1:1, 0:3, 9:4, 0:1, Len:7 >>, Payload];
    649 frame({pong, Payload}, _) ->
    650 	Len = iolist_size(Payload),
    651 	true = Len =< 125,
    652 	[<< 1:1, 0:3, 10:4, 0:1, Len:7 >>, Payload];
    653 %% Data frames, deflate-frame extension.
    654 frame({text, Payload}, #{deflate := Deflate, deflate_takeover := TakeOver})
    655 		when Deflate =/= false ->
    656 	Payload2 = deflate_frame(Payload, Deflate, TakeOver),
    657 	Len = payload_length(Payload2),
    658 	[<< 1:1, 1:1, 0:2, 1:4, 0:1, Len/bits >>, Payload2];
    659 frame({binary, Payload}, #{deflate := Deflate, deflate_takeover := TakeOver})
    660 		when Deflate =/= false ->
    661 	Payload2 = deflate_frame(Payload, Deflate, TakeOver),
    662 	Len = payload_length(Payload2),
    663 	[<< 1:1, 1:1, 0:2, 2:4, 0:1, Len/bits >>, Payload2];
    664 %% Data frames.
    665 frame({text, Payload}, _) ->
    666 	Len = payload_length(Payload),
    667 	[<< 1:1, 0:3, 1:4, 0:1, Len/bits >>, Payload];
    668 frame({binary, Payload}, _) ->
    669 	Len = payload_length(Payload),
    670 	[<< 1:1, 0:3, 2:4, 0:1, Len/bits >>, Payload].
    671 
    672 %% @doc Construct a masked Websocket frame.
    673 %%
    674 %% We use a mask key of 0 if there is no payload for close, ping and pong frames.
    675 
    676 -spec masked_frame(frame(), extensions()) -> iodata().
    677 %% Control frames. Control packets must not be > 125 in length.
    678 masked_frame(close, _) ->
    679 	<< 1:1, 0:3, 8:4, 1:1, 0:39 >>;
    680 masked_frame(ping, _) ->
    681 	<< 1:1, 0:3, 9:4, 1:1, 0:39 >>;
    682 masked_frame(pong, _) ->
    683 	<< 1:1, 0:3, 10:4, 1:1, 0:39 >>;
    684 masked_frame({close, Payload}, Extensions) ->
    685 	frame({close, 1000, Payload}, Extensions);
    686 masked_frame({close, StatusCode, Payload}, _) ->
    687 	Len = 2 + iolist_size(Payload),
    688 	true = Len =< 125,
    689 	MaskKeyBin = << MaskKey:32 >> = crypto:strong_rand_bytes(4),
    690 	[<< 1:1, 0:3, 8:4, 1:1, Len:7 >>, MaskKeyBin, mask(iolist_to_binary([<< StatusCode:16 >>, Payload]), MaskKey, <<>>)];
    691 masked_frame({ping, Payload}, _) ->
    692 	Len = iolist_size(Payload),
    693 	true = Len =< 125,
    694 	MaskKeyBin = << MaskKey:32 >> = crypto:strong_rand_bytes(4),
    695 	[<< 1:1, 0:3, 9:4, 1:1, Len:7 >>, MaskKeyBin, mask(iolist_to_binary(Payload), MaskKey, <<>>)];
    696 masked_frame({pong, Payload}, _) ->
    697 	Len = iolist_size(Payload),
    698 	true = Len =< 125,
    699 	MaskKeyBin = << MaskKey:32 >> = crypto:strong_rand_bytes(4),
    700 	[<< 1:1, 0:3, 10:4, 1:1, Len:7 >>, MaskKeyBin, mask(iolist_to_binary(Payload), MaskKey, <<>>)];
    701 %% Data frames, deflate-frame extension.
    702 masked_frame({text, Payload}, #{deflate := Deflate, deflate_takeover := TakeOver})
    703 		when Deflate =/= false ->
    704 	MaskKeyBin = << MaskKey:32 >> = crypto:strong_rand_bytes(4),
    705 	Payload2 = mask(deflate_frame(Payload, Deflate, TakeOver), MaskKey, <<>>),
    706 	Len = payload_length(Payload2),
    707 	[<< 1:1, 1:1, 0:2, 1:4, 1:1, Len/bits >>, MaskKeyBin, Payload2];
    708 masked_frame({binary, Payload}, #{deflate := Deflate, deflate_takeover := TakeOver})
    709 		when Deflate =/= false ->
    710 	MaskKeyBin = << MaskKey:32 >> = crypto:strong_rand_bytes(4),
    711 	Payload2 = mask(deflate_frame(Payload, Deflate, TakeOver), MaskKey, <<>>),
    712 	Len = payload_length(Payload2),
    713 	[<< 1:1, 1:1, 0:2, 2:4, 1:1, Len/bits >>, MaskKeyBin, Payload2];
    714 %% Data frames.
    715 masked_frame({text, Payload}, _) ->
    716 	MaskKeyBin = << MaskKey:32 >> = crypto:strong_rand_bytes(4),
    717 	Len = payload_length(Payload),
    718 	[<< 1:1, 0:3, 1:4, 1:1, Len/bits >>, MaskKeyBin, mask(iolist_to_binary(Payload), MaskKey, <<>>)];
    719 masked_frame({binary, Payload}, _) ->
    720 	MaskKeyBin = << MaskKey:32 >> = crypto:strong_rand_bytes(4),
    721 	Len = payload_length(Payload),
    722 	[<< 1:1, 0:3, 2:4, 1:1, Len/bits >>, MaskKeyBin, mask(iolist_to_binary(Payload), MaskKey, <<>>)].
    723 
    724 payload_length(Payload) ->
    725 	case iolist_size(Payload) of
    726 		N when N =< 125 -> << N:7 >>;
    727 		N when N =< 16#ffff -> << 126:7, N:16 >>;
    728 		N when N =< 16#7fffffffffffffff -> << 127:7, N:64 >>
    729 	end.
    730 
    731 deflate_frame(Payload, Deflate, TakeOver) ->
    732 	Deflated = iolist_to_binary(zlib:deflate(Deflate, Payload, sync)),
    733 	case TakeOver of
    734 		no_takeover -> zlib:deflateReset(Deflate);
    735 		takeover -> ok
    736 	end,
    737 	Len = byte_size(Deflated) - 4,
    738 	case Deflated of
    739 		<< Body:Len/binary, 0:8, 0:8, 255:8, 255:8 >> -> Body;
    740 		_ -> Deflated
    741 	end.