Current section
Files
Jump to
Current section
Files
src/ws_close.erl
%% Copyright 2026 Benoit Chesneau
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
%% You may obtain a copy of the License at
%%
%% http://www.apache.org/licenses/LICENSE-2.0
%%
%% Unless required by applicable law or agreed to in writing, software
%% distributed under the License is distributed on an "AS IS" BASIS,
%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%% See the License for the specific language governing permissions and
%% limitations under the License.
%% @doc Close-code classification and validation (RFC 6455 §7.4).
%%
%% 1000..1003, 1007..1011 are defined.
%% 1004 is reserved; 1005, 1006, 1015 MUST NOT appear on the wire.
%% 3000..3999 are reserved for registration.
%% 4000..4999 are free for application use.
-module(ws_close).
-export([valid_on_wire/1]).
-export([reason_name/1]).
-include("../include/ws.hrl").
-type code() :: 1000..4999.
-export_type([code/0]).
%% @doc True if Code is allowed to appear in a close frame on the wire.
-spec valid_on_wire(integer()) -> boolean().
valid_on_wire(Code) when is_integer(Code) ->
if
Code < 1000 -> false;
Code =:= 1004 -> false;
Code =:= 1005 -> false;
Code =:= 1006 -> false;
Code =:= 1015 -> false;
Code =< 1011 -> true;
Code < 3000 -> false;
Code =< 4999 -> true;
true -> false
end;
valid_on_wire(_) ->
false.
%% @doc Human-readable label for a standard close code. Returns `undefined'
%% for application-range codes the library does not know about.
-spec reason_name(integer()) -> atom().
reason_name(?WS_CLOSE_NORMAL) -> normal;
reason_name(?WS_CLOSE_GOING_AWAY) -> going_away;
reason_name(?WS_CLOSE_PROTOCOL_ERROR) -> protocol_error;
reason_name(?WS_CLOSE_UNSUPPORTED) -> unsupported_data;
reason_name(?WS_CLOSE_NO_STATUS) -> no_status;
reason_name(?WS_CLOSE_ABNORMAL) -> abnormal;
reason_name(?WS_CLOSE_INVALID_UTF8) -> invalid_utf8;
reason_name(?WS_CLOSE_POLICY) -> policy_violation;
reason_name(?WS_CLOSE_TOO_BIG) -> message_too_big;
reason_name(?WS_CLOSE_EXT_NEGOTIATION) -> extension_required;
reason_name(?WS_CLOSE_INTERNAL_ERROR) -> internal_error;
reason_name(?WS_CLOSE_TLS_HANDSHAKE) -> tls_handshake;
reason_name(_) -> undefined.