websockets I think are done

This commit is contained in:
Peter Harpending 2025-10-21 12:28:45 -07:00
parent 1865f03085
commit b44292a790

View File

@ -11,9 +11,8 @@
-export([ -export([
handshake/1, handshake/1,
recv/2, recv/2, recv/3,
send/2, send/2
pong/1, pong/2
]). ]).
-include("http.hrl"). -include("http.hrl").
@ -692,35 +691,43 @@ recv_frame_await(Frame, Sock, Received) ->
-spec send(Socket, Payload) -> Result -spec send(Socket, Message) -> Result
when Socket :: gen_tcp:socket(), when Socket :: gen_tcp:socket(),
Payload :: iodata(), Message :: ws_msg(),
Result :: ok Result :: ok
| {error, Reason}, | {error, Reason},
Reason :: closed | {timeout, RestData} | inet:posix(), Reason :: any().
RestData :: binary() | erlang:iovec().
% @doc % @doc
% FIXME: this should be sending a message, not an arbitrary payload % send message to client over Socket. handles frame nonsense
%
% send binary data over Socket. handles frame nonsense
%
% types the payload as bytes
% %
% max payload size is 2^63 - 1 bytes % max payload size is 2^63 - 1 bytes
% @end % @end
send(Socket, Payload) -> send(Socket, {Type, Payload}) ->
BPayload = unicode:characters_to_binary(Payload), BPayload = payload_to_binary(Payload),
Frame = payload_to_frame(BPayload), Frame = message_to_frame(Type, BPayload),
send_frame(Socket, Frame). send_frame(Socket, Frame).
payload_to_binary(Bin) when is_binary(Bin) -> Bin;
payload_to_binary(X) -> unicode:characters_to_binary(X).
payload_to_frame(Payload) when byte_size(Payload) < ?MAX_PAYLOAD_SIZE ->
% data messages
message_to_frame(Data, Payload)
when ((Data =:= text) orelse (Data =:= binary)),
is_binary(Payload),
(byte_size(Payload) < ?MAX_PAYLOAD_SIZE) ->
#frame{fin = true, #frame{fin = true,
opcode = binary, opcode = Data,
mask = false, payload_length = byte_size(Payload),
payload = Payload};
message_to_frame(Control, Payload)
when ((Control =:= close) orelse (Control =:= ping) orelse (Control =:= pong)),
is_binary(Payload),
(byte_size(Payload) =< 125) ->
#frame{fin = true,
opcode = Control,
payload_length = byte_size(Payload), payload_length = byte_size(Payload),
masking_key = none,
payload = Payload}. payload = Payload}.
@ -749,6 +756,8 @@ send_frame(Sock, Frame) ->
% %
% TODO: this doesn't check/do masking % TODO: this doesn't check/do masking
% %
% also RSV is always <<0:3>> in rendered frame
%
% This is a non-issue as long as this is only used for rendering messages sent % This is a non-issue as long as this is only used for rendering messages sent
% from server to client (unmasked per protocol). However, for debugging % from server to client (unmasked per protocol). However, for debugging
% purposes, a user of this library might want to test how frames render with % purposes, a user of this library might want to test how frames render with
@ -810,32 +819,3 @@ render_payload_length(Len) when 126 =< Len, Len =< 2#1111_1111_1111_1111 ->
<<126:7, Len:16>>; <<126:7, Len:16>>;
render_payload_length(Len) when (1 bsl 16) =< Len, Len < ?MAX_PAYLOAD_SIZE -> render_payload_length(Len) when (1 bsl 16) =< Len, Len < ?MAX_PAYLOAD_SIZE ->
<<127:7, Len:64>>. <<127:7, Len:64>>.
-spec pong(Socket) -> Result
when Socket :: gen_tcp:socket(),
Result :: ok
| {error, Reason},
Reason :: closed | {timeout, RestData} | inet:posix(),
RestData :: binary() | erlang:iovec().
pong(Sock) ->
pong(Sock, <<>>).
-spec pong(Socket, Payload) -> Result
when Socket :: gen_tcp:socket(),
Payload :: binary(),
Result :: ok
| {error, Reason},
Reason :: closed | {timeout, RestData} | inet:posix(),
RestData :: binary() | erlang:iovec().
pong(Sock, Payload) when is_binary(Payload), byte_size(Payload) < ?MAX_PAYLOAD_SIZE ->
Frame = #frame{fin = true,
opcode = pong,
payload_length = byte_size(Payload),
payload = Payload},
send_frame(Sock, Frame).