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(). 78key() -> 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(). 84encode_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. 93negotiate_permessage_deflate(_, #{deflate := _}, _) -> 94 ignore; 95negotiate_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 104negotiate_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 154negotiate_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. 158negotiate_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]); 162negotiate_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; 176negotiate_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. 194negotiate_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; 202negotiate_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. 211negotiate_params(_, _, _) -> 212 ignore. 213 214parse_max_window_bits(<<"8">>) -> 8; 215parse_max_window_bits(<<"9">>) -> 9; 216parse_max_window_bits(<<"10">>) -> 10; 217parse_max_window_bits(<<"11">>) -> 11; 218parse_max_window_bits(<<"12">>) -> 12; 219parse_max_window_bits(<<"13">>) -> 13; 220parse_max_window_bits(<<"14">>) -> 14; 221parse_max_window_bits(<<"15">>) -> 15; 222parse_max_window_bits(_) -> error. 223 224%% A negative WindowBits value indicates that zlib headers are not used. 225init_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 253set_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 263set_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; 269set_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(). 288negotiate_x_webkit_deflate_frame(_, #{deflate := _}, _) -> 289 ignore; 290negotiate_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. 305validate_permessage_deflate(_, #{deflate := _}, _) -> 306 error; 307validate_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 326parse_response_permessage_deflate_params([], CB, CTO, SB, STO) -> 327 {CB, CTO, SB, STO}; 328parse_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; 333parse_response_permessage_deflate_params([<<"client_no_context_takeover">>|Tail], CB, _, SB, STO) -> 334 parse_response_permessage_deflate_params(Tail, CB, no_takeover, SB, STO); 335parse_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; 340parse_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. 343parse_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. 355parse_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. 357parse_header(<< _:2, 1:1, _/bits >>, #{deflate := _}, _) -> error; 358parse_header(<< _:3, 1:1, _/bits >>, #{deflate := _}, _) -> error; 359%% Invalid opcode. Note that these opcodes may be used by extensions. 360parse_header(<< _:4, 3:4, _/bits >>, _, _) -> error; 361parse_header(<< _:4, 4:4, _/bits >>, _, _) -> error; 362parse_header(<< _:4, 5:4, _/bits >>, _, _) -> error; 363parse_header(<< _:4, 6:4, _/bits >>, _, _) -> error; 364parse_header(<< _:4, 7:4, _/bits >>, _, _) -> error; 365parse_header(<< _:4, 11:4, _/bits >>, _, _) -> error; 366parse_header(<< _:4, 12:4, _/bits >>, _, _) -> error; 367parse_header(<< _:4, 13:4, _/bits >>, _, _) -> error; 368parse_header(<< _:4, 14:4, _/bits >>, _, _) -> error; 369parse_header(<< _:4, 15:4, _/bits >>, _, _) -> error; 370%% Control frames MUST NOT be fragmented. 371parse_header(<< 0:1, _:3, Opcode:4, _/bits >>, _, _) when Opcode >= 8 -> error; 372%% A frame MUST NOT use the zero opcode unless fragmentation was initiated. 373parse_header(<< _:4, 0:4, _/bits >>, _, undefined) -> error; 374%% Non-control opcode when expecting control message or next fragment. 375parse_header(<< _:4, 1:4, _/bits >>, _, {_, _, _}) -> error; 376parse_header(<< _:4, 2:4, _/bits >>, _, {_, _, _}) -> error; 377parse_header(<< _:4, 3:4, _/bits >>, _, {_, _, _}) -> error; 378parse_header(<< _:4, 4:4, _/bits >>, _, {_, _, _}) -> error; 379parse_header(<< _:4, 5:4, _/bits >>, _, {_, _, _}) -> error; 380parse_header(<< _:4, 6:4, _/bits >>, _, {_, _, _}) -> error; 381parse_header(<< _:4, 7:4, _/bits >>, _, {_, _, _}) -> error; 382%% Close control frame length MUST be 0 or >= 2. 383parse_header(<< _:4, 8:4, _:1, 1:7, _/bits >>, _, _) -> error; 384%% Close control frame with incomplete close code. Need more data. 385parse_header(Data = << _:4, 8:4, 0:1, Len:7, _/bits >>, _, _) when Len > 1, byte_size(Data) < 4 -> more; 386parse_header(Data = << _:4, 8:4, 1:1, Len:7, _/bits >>, _, _) when Len > 1, byte_size(Data) < 8 -> more; 387%% 7 bits payload length. 388parse_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); 390parse_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. 393parse_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); 395parse_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. 398parse_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); 400parse_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. 403parse_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 408parse_header(<< _:8, 0:1, 126:7, _:16, _/bits >>, _, _) -> error; 409parse_header(<< _:8, 1:1, 126:7, _:48, _/bits >>, _, _) -> error; 410parse_header(<< _:8, 0:1, 127:7, _:64, _/bits >>, _, _) -> error; 411parse_header(<< _:8, 1:1, 127:7, _:96, _/bits >>, _, _) -> error; 412%% Need more data. 413parse_header(_, _, _) -> more. 414 415parse_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 423opcode_to_frame_type(0) -> fragment; 424opcode_to_frame_type(1) -> text; 425opcode_to_frame_type(2) -> binary; 426opcode_to_frame_type(8) -> close; 427opcode_to_frame_type(9) -> ping; 428opcode_to_frame_type(10) -> pong. 429 430frag_state(Type, 0, Rsv, undefined) -> {nofin, Type, Rsv}; 431frag_state(fragment, 0, _, FragState = {nofin, _, _}) -> FragState; 432frag_state(fragment, 1, _, {nofin, Type, Rsv}) -> {fin, Type, Rsv}; 433frag_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. 448parse_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. 457parse_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. 463parse_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. 469parse_payload(Data, _, Utf8State, 0, _, 0, _, _, _) 470 when Utf8State =:= 0; Utf8State =:= undefined -> 471 {ok, <<>>, Utf8State, Data}; 472%% Start of close frame. 473parse_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. 488parse_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 493split_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 504validate_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 515unmask(Data, undefined, _) -> 516 Data; 517unmask(Data, MaskKey, 0) -> 518 mask(Data, MaskKey, <<>>); 519%% We unmask on the fly so we need to continue from the right mask byte. 520unmask(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 526mask(<<>>, _, Unmasked) -> 527 Unmasked; 528mask(<< O:32, Rest/bits >>, MaskKey, Acc) -> 529 T = O bxor MaskKey, 530 mask(Rest, MaskKey, << Acc/binary, T:32 >>); 531mask(<< O:24 >>, MaskKey, Acc) -> 532 << MaskKey2:24, _:8 >> = << MaskKey:32 >>, 533 T = O bxor MaskKey2, 534 << Acc/binary, T:24 >>; 535mask(<< O:16 >>, MaskKey, Acc) -> 536 << MaskKey2:16, _:16 >> = << MaskKey:32 >>, 537 T = O bxor MaskKey2, 538 << Acc/binary, T:16 >>; 539mask(<< O:8 >>, MaskKey, Acc) -> 540 << MaskKey2:8, _:24 >> = << MaskKey:32 >>, 541 T = O bxor MaskKey2, 542 << Acc/binary, T:8 >>. 543 544inflate_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); 552inflate_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. 556validate_payload(Payload, _, undefined, _, _, _, false) -> 557 {more, Payload, undefined}; 558validate_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. 561validate_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; 568validate_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; 576validate_payload(Payload, _, Utf8State, _, _, _, false) -> 577 {more, Payload, Utf8State}; 578validate_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. 588validate_utf8(<<>>, State) -> State; 589validate_utf8(<< C, Rest/bits >>, 0) when C < 128 -> validate_utf8(Rest, 0); 590validate_utf8(<< C, Rest/bits >>, 2) when C >= 128, C < 144 -> validate_utf8(Rest, 0); 591validate_utf8(<< C, Rest/bits >>, 3) when C >= 128, C < 144 -> validate_utf8(Rest, 2); 592validate_utf8(<< C, Rest/bits >>, 5) when C >= 128, C < 144 -> validate_utf8(Rest, 2); 593validate_utf8(<< C, Rest/bits >>, 7) when C >= 128, C < 144 -> validate_utf8(Rest, 3); 594validate_utf8(<< C, Rest/bits >>, 8) when C >= 128, C < 144 -> validate_utf8(Rest, 3); 595validate_utf8(<< C, Rest/bits >>, 2) when C >= 144, C < 160 -> validate_utf8(Rest, 0); 596validate_utf8(<< C, Rest/bits >>, 3) when C >= 144, C < 160 -> validate_utf8(Rest, 2); 597validate_utf8(<< C, Rest/bits >>, 5) when C >= 144, C < 160 -> validate_utf8(Rest, 2); 598validate_utf8(<< C, Rest/bits >>, 6) when C >= 144, C < 160 -> validate_utf8(Rest, 3); 599validate_utf8(<< C, Rest/bits >>, 7) when C >= 144, C < 160 -> validate_utf8(Rest, 3); 600validate_utf8(<< C, Rest/bits >>, 2) when C >= 160, C < 192 -> validate_utf8(Rest, 0); 601validate_utf8(<< C, Rest/bits >>, 3) when C >= 160, C < 192 -> validate_utf8(Rest, 2); 602validate_utf8(<< C, Rest/bits >>, 4) when C >= 160, C < 192 -> validate_utf8(Rest, 2); 603validate_utf8(<< C, Rest/bits >>, 6) when C >= 160, C < 192 -> validate_utf8(Rest, 3); 604validate_utf8(<< C, Rest/bits >>, 7) when C >= 160, C < 192 -> validate_utf8(Rest, 3); 605validate_utf8(<< C, Rest/bits >>, 0) when C >= 194, C < 224 -> validate_utf8(Rest, 2); 606validate_utf8(<< 224, Rest/bits >>, 0) -> validate_utf8(Rest, 4); 607validate_utf8(<< C, Rest/bits >>, 0) when C >= 225, C < 237 -> validate_utf8(Rest, 3); 608validate_utf8(<< 237, Rest/bits >>, 0) -> validate_utf8(Rest, 5); 609validate_utf8(<< C, Rest/bits >>, 0) when C =:= 238; C =:= 239 -> validate_utf8(Rest, 3); 610validate_utf8(<< 240, Rest/bits >>, 0) -> validate_utf8(Rest, 6); 611validate_utf8(<< C, Rest/bits >>, 0) when C =:= 241; C =:= 242; C =:= 243 -> validate_utf8(Rest, 7); 612validate_utf8(<< 244, Rest/bits >>, 0) -> validate_utf8(Rest, 8); 613validate_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. 619make_frame(fragment, Payload, _, {Fin, Type, _}) -> {fragment, Fin, Type, Payload}; 620make_frame(text, Payload, _, _) -> {text, Payload}; 621make_frame(binary, Payload, _, _) -> {binary, Payload}; 622make_frame(close, <<>>, undefined, _) -> close; 623make_frame(close, Payload, CloseCode, _) -> {close, CloseCode, Payload}; 624make_frame(ping, <<>>, _, _) -> ping; 625make_frame(ping, Payload, _, _) -> {ping, Payload}; 626make_frame(pong, <<>>, _, _) -> pong; 627make_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. 633frame(close, _) -> 634 << 1:1, 0:3, 8:4, 0:8 >>; 635frame(ping, _) -> 636 << 1:1, 0:3, 9:4, 0:8 >>; 637frame(pong, _) -> 638 << 1:1, 0:3, 10:4, 0:8 >>; 639frame({close, Payload}, Extensions) -> 640 frame({close, 1000, Payload}, Extensions); 641frame({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]; 645frame({ping, Payload}, _) -> 646 Len = iolist_size(Payload), 647 true = Len =< 125, 648 [<< 1:1, 0:3, 9:4, 0:1, Len:7 >>, Payload]; 649frame({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. 654frame({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]; 659frame({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. 665frame({text, Payload}, _) -> 666 Len = payload_length(Payload), 667 [<< 1:1, 0:3, 1:4, 0:1, Len/bits >>, Payload]; 668frame({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. 678masked_frame(close, _) -> 679 << 1:1, 0:3, 8:4, 1:1, 0:39 >>; 680masked_frame(ping, _) -> 681 << 1:1, 0:3, 9:4, 1:1, 0:39 >>; 682masked_frame(pong, _) -> 683 << 1:1, 0:3, 10:4, 1:1, 0:39 >>; 684masked_frame({close, Payload}, Extensions) -> 685 frame({close, 1000, Payload}, Extensions); 686masked_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, <<>>)]; 691masked_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, <<>>)]; 696masked_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. 702masked_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]; 708masked_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. 715masked_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, <<>>)]; 719masked_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 724payload_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 731deflate_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. 742