Skip to content

Commit 7d74057

Browse files
committed
move fragment logic back into frame module
originally this was removed because the guard is_control/1 was causing a compiler crash (some beam_ssa_opt or other)
1 parent d6d6f8d commit 7d74057

2 files changed

Lines changed: 45 additions & 52 deletions

File tree

lib/mint/web_socket/frame.ex

Lines changed: 45 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ defmodule Mint.WebSocket.Frame do
77
shared = [{:reserved, <<0::size(3)>>}, :mask, :data]
88

99
import Record
10-
alias Mint.WebSocket.{Utils, Frame.Fragment}
10+
alias Mint.WebSocket.Utils
1111

1212
defrecord :continuation, shared ++ [:fin?]
1313
defrecord :text, shared ++ [:fin?]
@@ -125,11 +125,11 @@ defmodule Mint.WebSocket.Frame do
125125
def decode(websocket, data) do
126126
case websocket.buffer |> Utils.maybe_concat(data) |> decode_raw(websocket, []) do
127127
{:ok, frames} ->
128-
{websocket, frames} = Fragment.resolve(websocket, frames)
128+
{websocket, frames} = resolve_fragments(websocket, frames)
129129
{:ok, put_in(websocket.buffer, <<>>), frames}
130130

131131
{:buffer, partial, frames} ->
132-
{websocket, frames} = Fragment.resolve(websocket, frames)
132+
{websocket, frames} = resolve_fragments(websocket, frames)
133133
{:ok, put_in(websocket.buffer, partial), frames}
134134
end
135135
catch
@@ -355,4 +355,46 @@ defmodule Mint.WebSocket.Frame do
355355
unquote(type)(frame, data: frame_data <> continuation_data, fin?: fin?)
356356
end
357357
end
358+
359+
@doc """
360+
Emits frames for any finalized fragments and stores any unfinalized fragments
361+
in the `:fragments` key in the websocket
362+
"""
363+
def resolve_fragments(websocket, frames, acc \\ [])
364+
365+
def resolve_fragments(websocket, [], acc) do
366+
{websocket, :lists.reverse(acc)}
367+
end
368+
369+
def resolve_fragments(websocket, [frame | rest], acc) when is_control(frame) do
370+
resolve_fragments(websocket, rest, [translate(frame) | acc])
371+
end
372+
373+
def resolve_fragments(websocket, [frame | rest], acc) when is_fin(frame) do
374+
frame = combine_frames([frame | websocket.fragments])
375+
376+
put_in(websocket.fragments, [])
377+
|> resolve_fragments(rest, [frame | acc])
378+
end
379+
380+
def resolve_fragments(websocket, [frame | rest], acc) do
381+
update_in(websocket.fragments, &[frame | &1])
382+
|> resolve_fragments(rest, acc)
383+
end
384+
385+
defp combine_frames([continuation()]) do
386+
throw({:mint, :uninitiated_continuation})
387+
end
388+
389+
defp combine_frames([full_frame]) do
390+
translate(full_frame)
391+
end
392+
393+
defp combine_frames([continuation() = continuation, prior_fragment | rest]) do
394+
combine_frames([combine(prior_fragment, continuation) | rest])
395+
end
396+
397+
defp combine_frames(_out_of_order_fragments) do
398+
throw({:mint, :out_of_order_fragments})
399+
end
358400
end

lib/mint/web_socket/frame/fragment.ex

Lines changed: 0 additions & 49 deletions
This file was deleted.

0 commit comments

Comments
 (0)