diff --git a/_build/dev/lib/bandit/.mix/compile.elixir b/_build/dev/lib/bandit/.mix/compile.elixir deleted file mode 100644 index 4dc021f..0000000 Binary files a/_build/dev/lib/bandit/.mix/compile.elixir and /dev/null differ diff --git a/_build/dev/lib/bandit/.mix/compile.elixir_scm b/_build/dev/lib/bandit/.mix/compile.elixir_scm deleted file mode 100644 index 4066741..0000000 Binary files a/_build/dev/lib/bandit/.mix/compile.elixir_scm and /dev/null differ diff --git a/_build/dev/lib/bandit/ebin/Elixir.Bandit.Adapter.beam b/_build/dev/lib/bandit/ebin/Elixir.Bandit.Adapter.beam deleted file mode 100644 index 9dba560..0000000 Binary files a/_build/dev/lib/bandit/ebin/Elixir.Bandit.Adapter.beam and /dev/null differ diff --git a/_build/dev/lib/bandit/ebin/Elixir.Bandit.Application.beam b/_build/dev/lib/bandit/ebin/Elixir.Bandit.Application.beam deleted file mode 100644 index 8082cf4..0000000 Binary files a/_build/dev/lib/bandit/ebin/Elixir.Bandit.Application.beam and /dev/null differ diff --git a/_build/dev/lib/bandit/ebin/Elixir.Bandit.Clock.beam b/_build/dev/lib/bandit/ebin/Elixir.Bandit.Clock.beam deleted file mode 100644 index e38796e..0000000 Binary files a/_build/dev/lib/bandit/ebin/Elixir.Bandit.Clock.beam and /dev/null differ diff --git a/_build/dev/lib/bandit/ebin/Elixir.Bandit.Compression.beam b/_build/dev/lib/bandit/ebin/Elixir.Bandit.Compression.beam deleted file mode 100644 index b393a2e..0000000 Binary files a/_build/dev/lib/bandit/ebin/Elixir.Bandit.Compression.beam and /dev/null differ diff --git a/_build/dev/lib/bandit/ebin/Elixir.Bandit.DelegatingHandler.beam b/_build/dev/lib/bandit/ebin/Elixir.Bandit.DelegatingHandler.beam deleted file mode 100644 index f6f35eb..0000000 Binary files a/_build/dev/lib/bandit/ebin/Elixir.Bandit.DelegatingHandler.beam and /dev/null differ diff --git a/_build/dev/lib/bandit/ebin/Elixir.Bandit.Extractor.beam b/_build/dev/lib/bandit/ebin/Elixir.Bandit.Extractor.beam deleted file mode 100644 index df4718f..0000000 Binary files a/_build/dev/lib/bandit/ebin/Elixir.Bandit.Extractor.beam and /dev/null differ diff --git a/_build/dev/lib/bandit/ebin/Elixir.Bandit.HTTP1.Handler.beam b/_build/dev/lib/bandit/ebin/Elixir.Bandit.HTTP1.Handler.beam deleted file mode 100644 index 69a4dc8..0000000 Binary files a/_build/dev/lib/bandit/ebin/Elixir.Bandit.HTTP1.Handler.beam and /dev/null differ diff --git a/_build/dev/lib/bandit/ebin/Elixir.Bandit.HTTP1.Socket.beam b/_build/dev/lib/bandit/ebin/Elixir.Bandit.HTTP1.Socket.beam deleted file mode 100644 index 7d80651..0000000 Binary files a/_build/dev/lib/bandit/ebin/Elixir.Bandit.HTTP1.Socket.beam and /dev/null differ diff --git a/_build/dev/lib/bandit/ebin/Elixir.Bandit.HTTP2.Connection.beam b/_build/dev/lib/bandit/ebin/Elixir.Bandit.HTTP2.Connection.beam deleted file mode 100644 index a6df251..0000000 Binary files a/_build/dev/lib/bandit/ebin/Elixir.Bandit.HTTP2.Connection.beam and /dev/null differ diff --git a/_build/dev/lib/bandit/ebin/Elixir.Bandit.HTTP2.Errors.ConnectionError.beam b/_build/dev/lib/bandit/ebin/Elixir.Bandit.HTTP2.Errors.ConnectionError.beam deleted file mode 100644 index 7d48f4f..0000000 Binary files a/_build/dev/lib/bandit/ebin/Elixir.Bandit.HTTP2.Errors.ConnectionError.beam and /dev/null differ diff --git a/_build/dev/lib/bandit/ebin/Elixir.Bandit.HTTP2.Errors.StreamError.beam b/_build/dev/lib/bandit/ebin/Elixir.Bandit.HTTP2.Errors.StreamError.beam deleted file mode 100644 index 4720588..0000000 Binary files a/_build/dev/lib/bandit/ebin/Elixir.Bandit.HTTP2.Errors.StreamError.beam and /dev/null differ diff --git a/_build/dev/lib/bandit/ebin/Elixir.Bandit.HTTP2.Errors.beam b/_build/dev/lib/bandit/ebin/Elixir.Bandit.HTTP2.Errors.beam deleted file mode 100644 index f42593c..0000000 Binary files a/_build/dev/lib/bandit/ebin/Elixir.Bandit.HTTP2.Errors.beam and /dev/null differ diff --git a/_build/dev/lib/bandit/ebin/Elixir.Bandit.HTTP2.FlowControl.beam b/_build/dev/lib/bandit/ebin/Elixir.Bandit.HTTP2.FlowControl.beam deleted file mode 100644 index b9ce4f6..0000000 Binary files a/_build/dev/lib/bandit/ebin/Elixir.Bandit.HTTP2.FlowControl.beam and /dev/null differ diff --git a/_build/dev/lib/bandit/ebin/Elixir.Bandit.HTTP2.Frame.Continuation.beam b/_build/dev/lib/bandit/ebin/Elixir.Bandit.HTTP2.Frame.Continuation.beam deleted file mode 100644 index 2fd182d..0000000 Binary files a/_build/dev/lib/bandit/ebin/Elixir.Bandit.HTTP2.Frame.Continuation.beam and /dev/null differ diff --git a/_build/dev/lib/bandit/ebin/Elixir.Bandit.HTTP2.Frame.Data.beam b/_build/dev/lib/bandit/ebin/Elixir.Bandit.HTTP2.Frame.Data.beam deleted file mode 100644 index 20d1861..0000000 Binary files a/_build/dev/lib/bandit/ebin/Elixir.Bandit.HTTP2.Frame.Data.beam and /dev/null differ diff --git a/_build/dev/lib/bandit/ebin/Elixir.Bandit.HTTP2.Frame.Flags.beam b/_build/dev/lib/bandit/ebin/Elixir.Bandit.HTTP2.Frame.Flags.beam deleted file mode 100644 index df5ebb5..0000000 Binary files a/_build/dev/lib/bandit/ebin/Elixir.Bandit.HTTP2.Frame.Flags.beam and /dev/null differ diff --git a/_build/dev/lib/bandit/ebin/Elixir.Bandit.HTTP2.Frame.Goaway.beam b/_build/dev/lib/bandit/ebin/Elixir.Bandit.HTTP2.Frame.Goaway.beam deleted file mode 100644 index 270ba36..0000000 Binary files a/_build/dev/lib/bandit/ebin/Elixir.Bandit.HTTP2.Frame.Goaway.beam and /dev/null differ diff --git a/_build/dev/lib/bandit/ebin/Elixir.Bandit.HTTP2.Frame.Headers.beam b/_build/dev/lib/bandit/ebin/Elixir.Bandit.HTTP2.Frame.Headers.beam deleted file mode 100644 index 3ba1938..0000000 Binary files a/_build/dev/lib/bandit/ebin/Elixir.Bandit.HTTP2.Frame.Headers.beam and /dev/null differ diff --git a/_build/dev/lib/bandit/ebin/Elixir.Bandit.HTTP2.Frame.Ping.beam b/_build/dev/lib/bandit/ebin/Elixir.Bandit.HTTP2.Frame.Ping.beam deleted file mode 100644 index 4a6b576..0000000 Binary files a/_build/dev/lib/bandit/ebin/Elixir.Bandit.HTTP2.Frame.Ping.beam and /dev/null differ diff --git a/_build/dev/lib/bandit/ebin/Elixir.Bandit.HTTP2.Frame.Priority.beam b/_build/dev/lib/bandit/ebin/Elixir.Bandit.HTTP2.Frame.Priority.beam deleted file mode 100644 index 1343366..0000000 Binary files a/_build/dev/lib/bandit/ebin/Elixir.Bandit.HTTP2.Frame.Priority.beam and /dev/null differ diff --git a/_build/dev/lib/bandit/ebin/Elixir.Bandit.HTTP2.Frame.PushPromise.beam b/_build/dev/lib/bandit/ebin/Elixir.Bandit.HTTP2.Frame.PushPromise.beam deleted file mode 100644 index afacfb5..0000000 Binary files a/_build/dev/lib/bandit/ebin/Elixir.Bandit.HTTP2.Frame.PushPromise.beam and /dev/null differ diff --git a/_build/dev/lib/bandit/ebin/Elixir.Bandit.HTTP2.Frame.RstStream.beam b/_build/dev/lib/bandit/ebin/Elixir.Bandit.HTTP2.Frame.RstStream.beam deleted file mode 100644 index 772723b..0000000 Binary files a/_build/dev/lib/bandit/ebin/Elixir.Bandit.HTTP2.Frame.RstStream.beam and /dev/null differ diff --git a/_build/dev/lib/bandit/ebin/Elixir.Bandit.HTTP2.Frame.Serializable.Bandit.HTTP2.Frame.Continuation.beam b/_build/dev/lib/bandit/ebin/Elixir.Bandit.HTTP2.Frame.Serializable.Bandit.HTTP2.Frame.Continuation.beam deleted file mode 100644 index 796ebe1..0000000 Binary files a/_build/dev/lib/bandit/ebin/Elixir.Bandit.HTTP2.Frame.Serializable.Bandit.HTTP2.Frame.Continuation.beam and /dev/null differ diff --git a/_build/dev/lib/bandit/ebin/Elixir.Bandit.HTTP2.Frame.Serializable.Bandit.HTTP2.Frame.Data.beam b/_build/dev/lib/bandit/ebin/Elixir.Bandit.HTTP2.Frame.Serializable.Bandit.HTTP2.Frame.Data.beam deleted file mode 100644 index 25d4ee2..0000000 Binary files a/_build/dev/lib/bandit/ebin/Elixir.Bandit.HTTP2.Frame.Serializable.Bandit.HTTP2.Frame.Data.beam and /dev/null differ diff --git a/_build/dev/lib/bandit/ebin/Elixir.Bandit.HTTP2.Frame.Serializable.Bandit.HTTP2.Frame.Goaway.beam b/_build/dev/lib/bandit/ebin/Elixir.Bandit.HTTP2.Frame.Serializable.Bandit.HTTP2.Frame.Goaway.beam deleted file mode 100644 index 3dcaa50..0000000 Binary files a/_build/dev/lib/bandit/ebin/Elixir.Bandit.HTTP2.Frame.Serializable.Bandit.HTTP2.Frame.Goaway.beam and /dev/null differ diff --git a/_build/dev/lib/bandit/ebin/Elixir.Bandit.HTTP2.Frame.Serializable.Bandit.HTTP2.Frame.Headers.beam b/_build/dev/lib/bandit/ebin/Elixir.Bandit.HTTP2.Frame.Serializable.Bandit.HTTP2.Frame.Headers.beam deleted file mode 100644 index c47b41e..0000000 Binary files a/_build/dev/lib/bandit/ebin/Elixir.Bandit.HTTP2.Frame.Serializable.Bandit.HTTP2.Frame.Headers.beam and /dev/null differ diff --git a/_build/dev/lib/bandit/ebin/Elixir.Bandit.HTTP2.Frame.Serializable.Bandit.HTTP2.Frame.Ping.beam b/_build/dev/lib/bandit/ebin/Elixir.Bandit.HTTP2.Frame.Serializable.Bandit.HTTP2.Frame.Ping.beam deleted file mode 100644 index dcdc37d..0000000 Binary files a/_build/dev/lib/bandit/ebin/Elixir.Bandit.HTTP2.Frame.Serializable.Bandit.HTTP2.Frame.Ping.beam and /dev/null differ diff --git a/_build/dev/lib/bandit/ebin/Elixir.Bandit.HTTP2.Frame.Serializable.Bandit.HTTP2.Frame.Priority.beam b/_build/dev/lib/bandit/ebin/Elixir.Bandit.HTTP2.Frame.Serializable.Bandit.HTTP2.Frame.Priority.beam deleted file mode 100644 index 3fafc8a..0000000 Binary files a/_build/dev/lib/bandit/ebin/Elixir.Bandit.HTTP2.Frame.Serializable.Bandit.HTTP2.Frame.Priority.beam and /dev/null differ diff --git a/_build/dev/lib/bandit/ebin/Elixir.Bandit.HTTP2.Frame.Serializable.Bandit.HTTP2.Frame.RstStream.beam b/_build/dev/lib/bandit/ebin/Elixir.Bandit.HTTP2.Frame.Serializable.Bandit.HTTP2.Frame.RstStream.beam deleted file mode 100644 index f7e36ca..0000000 Binary files a/_build/dev/lib/bandit/ebin/Elixir.Bandit.HTTP2.Frame.Serializable.Bandit.HTTP2.Frame.RstStream.beam and /dev/null differ diff --git a/_build/dev/lib/bandit/ebin/Elixir.Bandit.HTTP2.Frame.Serializable.Bandit.HTTP2.Frame.Settings.beam b/_build/dev/lib/bandit/ebin/Elixir.Bandit.HTTP2.Frame.Serializable.Bandit.HTTP2.Frame.Settings.beam deleted file mode 100644 index dc2b3cd..0000000 Binary files a/_build/dev/lib/bandit/ebin/Elixir.Bandit.HTTP2.Frame.Serializable.Bandit.HTTP2.Frame.Settings.beam and /dev/null differ diff --git a/_build/dev/lib/bandit/ebin/Elixir.Bandit.HTTP2.Frame.Serializable.Bandit.HTTP2.Frame.WindowUpdate.beam b/_build/dev/lib/bandit/ebin/Elixir.Bandit.HTTP2.Frame.Serializable.Bandit.HTTP2.Frame.WindowUpdate.beam deleted file mode 100644 index d74297c..0000000 Binary files a/_build/dev/lib/bandit/ebin/Elixir.Bandit.HTTP2.Frame.Serializable.Bandit.HTTP2.Frame.WindowUpdate.beam and /dev/null differ diff --git a/_build/dev/lib/bandit/ebin/Elixir.Bandit.HTTP2.Frame.Serializable.beam b/_build/dev/lib/bandit/ebin/Elixir.Bandit.HTTP2.Frame.Serializable.beam deleted file mode 100644 index b5b4301..0000000 Binary files a/_build/dev/lib/bandit/ebin/Elixir.Bandit.HTTP2.Frame.Serializable.beam and /dev/null differ diff --git a/_build/dev/lib/bandit/ebin/Elixir.Bandit.HTTP2.Frame.Settings.beam b/_build/dev/lib/bandit/ebin/Elixir.Bandit.HTTP2.Frame.Settings.beam deleted file mode 100644 index a48a24b..0000000 Binary files a/_build/dev/lib/bandit/ebin/Elixir.Bandit.HTTP2.Frame.Settings.beam and /dev/null differ diff --git a/_build/dev/lib/bandit/ebin/Elixir.Bandit.HTTP2.Frame.Unknown.beam b/_build/dev/lib/bandit/ebin/Elixir.Bandit.HTTP2.Frame.Unknown.beam deleted file mode 100644 index a118760..0000000 Binary files a/_build/dev/lib/bandit/ebin/Elixir.Bandit.HTTP2.Frame.Unknown.beam and /dev/null differ diff --git a/_build/dev/lib/bandit/ebin/Elixir.Bandit.HTTP2.Frame.WindowUpdate.beam b/_build/dev/lib/bandit/ebin/Elixir.Bandit.HTTP2.Frame.WindowUpdate.beam deleted file mode 100644 index 22ae2f3..0000000 Binary files a/_build/dev/lib/bandit/ebin/Elixir.Bandit.HTTP2.Frame.WindowUpdate.beam and /dev/null differ diff --git a/_build/dev/lib/bandit/ebin/Elixir.Bandit.HTTP2.Frame.beam b/_build/dev/lib/bandit/ebin/Elixir.Bandit.HTTP2.Frame.beam deleted file mode 100644 index ff22d55..0000000 Binary files a/_build/dev/lib/bandit/ebin/Elixir.Bandit.HTTP2.Frame.beam and /dev/null differ diff --git a/_build/dev/lib/bandit/ebin/Elixir.Bandit.HTTP2.Handler.beam b/_build/dev/lib/bandit/ebin/Elixir.Bandit.HTTP2.Handler.beam deleted file mode 100644 index f42f160..0000000 Binary files a/_build/dev/lib/bandit/ebin/Elixir.Bandit.HTTP2.Handler.beam and /dev/null differ diff --git a/_build/dev/lib/bandit/ebin/Elixir.Bandit.HTTP2.Settings.beam b/_build/dev/lib/bandit/ebin/Elixir.Bandit.HTTP2.Settings.beam deleted file mode 100644 index 63623c4..0000000 Binary files a/_build/dev/lib/bandit/ebin/Elixir.Bandit.HTTP2.Settings.beam and /dev/null differ diff --git a/_build/dev/lib/bandit/ebin/Elixir.Bandit.HTTP2.Stream.beam b/_build/dev/lib/bandit/ebin/Elixir.Bandit.HTTP2.Stream.beam deleted file mode 100644 index fc39f03..0000000 Binary files a/_build/dev/lib/bandit/ebin/Elixir.Bandit.HTTP2.Stream.beam and /dev/null differ diff --git a/_build/dev/lib/bandit/ebin/Elixir.Bandit.HTTP2.StreamCollection.beam b/_build/dev/lib/bandit/ebin/Elixir.Bandit.HTTP2.StreamCollection.beam deleted file mode 100644 index 32fe830..0000000 Binary files a/_build/dev/lib/bandit/ebin/Elixir.Bandit.HTTP2.StreamCollection.beam and /dev/null differ diff --git a/_build/dev/lib/bandit/ebin/Elixir.Bandit.HTTP2.StreamProcess.beam b/_build/dev/lib/bandit/ebin/Elixir.Bandit.HTTP2.StreamProcess.beam deleted file mode 100644 index 8207fe1..0000000 Binary files a/_build/dev/lib/bandit/ebin/Elixir.Bandit.HTTP2.StreamProcess.beam and /dev/null differ diff --git a/_build/dev/lib/bandit/ebin/Elixir.Bandit.HTTPError.beam b/_build/dev/lib/bandit/ebin/Elixir.Bandit.HTTPError.beam deleted file mode 100644 index 772d948..0000000 Binary files a/_build/dev/lib/bandit/ebin/Elixir.Bandit.HTTPError.beam and /dev/null differ diff --git a/_build/dev/lib/bandit/ebin/Elixir.Bandit.HTTPTransport.Bandit.HTTP1.Socket.beam b/_build/dev/lib/bandit/ebin/Elixir.Bandit.HTTPTransport.Bandit.HTTP1.Socket.beam deleted file mode 100644 index f0c50ec..0000000 Binary files a/_build/dev/lib/bandit/ebin/Elixir.Bandit.HTTPTransport.Bandit.HTTP1.Socket.beam and /dev/null differ diff --git a/_build/dev/lib/bandit/ebin/Elixir.Bandit.HTTPTransport.Bandit.HTTP2.Stream.beam b/_build/dev/lib/bandit/ebin/Elixir.Bandit.HTTPTransport.Bandit.HTTP2.Stream.beam deleted file mode 100644 index 46ebb3b..0000000 Binary files a/_build/dev/lib/bandit/ebin/Elixir.Bandit.HTTPTransport.Bandit.HTTP2.Stream.beam and /dev/null differ diff --git a/_build/dev/lib/bandit/ebin/Elixir.Bandit.HTTPTransport.beam b/_build/dev/lib/bandit/ebin/Elixir.Bandit.HTTPTransport.beam deleted file mode 100644 index f1929ba..0000000 Binary files a/_build/dev/lib/bandit/ebin/Elixir.Bandit.HTTPTransport.beam and /dev/null differ diff --git a/_build/dev/lib/bandit/ebin/Elixir.Bandit.Headers.beam b/_build/dev/lib/bandit/ebin/Elixir.Bandit.Headers.beam deleted file mode 100644 index 09bac73..0000000 Binary files a/_build/dev/lib/bandit/ebin/Elixir.Bandit.Headers.beam and /dev/null differ diff --git a/_build/dev/lib/bandit/ebin/Elixir.Bandit.InitialHandler.beam b/_build/dev/lib/bandit/ebin/Elixir.Bandit.InitialHandler.beam deleted file mode 100644 index 94bd216..0000000 Binary files a/_build/dev/lib/bandit/ebin/Elixir.Bandit.InitialHandler.beam and /dev/null differ diff --git a/_build/dev/lib/bandit/ebin/Elixir.Bandit.Logger.beam b/_build/dev/lib/bandit/ebin/Elixir.Bandit.Logger.beam deleted file mode 100644 index 7e70a01..0000000 Binary files a/_build/dev/lib/bandit/ebin/Elixir.Bandit.Logger.beam and /dev/null differ diff --git a/_build/dev/lib/bandit/ebin/Elixir.Bandit.PhoenixAdapter.beam b/_build/dev/lib/bandit/ebin/Elixir.Bandit.PhoenixAdapter.beam deleted file mode 100644 index 02c8f02..0000000 Binary files a/_build/dev/lib/bandit/ebin/Elixir.Bandit.PhoenixAdapter.beam and /dev/null differ diff --git a/_build/dev/lib/bandit/ebin/Elixir.Bandit.Pipeline.beam b/_build/dev/lib/bandit/ebin/Elixir.Bandit.Pipeline.beam deleted file mode 100644 index dc973b5..0000000 Binary files a/_build/dev/lib/bandit/ebin/Elixir.Bandit.Pipeline.beam and /dev/null differ diff --git a/_build/dev/lib/bandit/ebin/Elixir.Bandit.PrimitiveOps.WebSocket.beam b/_build/dev/lib/bandit/ebin/Elixir.Bandit.PrimitiveOps.WebSocket.beam deleted file mode 100644 index 033222f..0000000 Binary files a/_build/dev/lib/bandit/ebin/Elixir.Bandit.PrimitiveOps.WebSocket.beam and /dev/null differ diff --git a/_build/dev/lib/bandit/ebin/Elixir.Bandit.SocketHelpers.beam b/_build/dev/lib/bandit/ebin/Elixir.Bandit.SocketHelpers.beam deleted file mode 100644 index 76a2405..0000000 Binary files a/_build/dev/lib/bandit/ebin/Elixir.Bandit.SocketHelpers.beam and /dev/null differ diff --git a/_build/dev/lib/bandit/ebin/Elixir.Bandit.Telemetry.beam b/_build/dev/lib/bandit/ebin/Elixir.Bandit.Telemetry.beam deleted file mode 100644 index 2190d40..0000000 Binary files a/_build/dev/lib/bandit/ebin/Elixir.Bandit.Telemetry.beam and /dev/null differ diff --git a/_build/dev/lib/bandit/ebin/Elixir.Bandit.Trace.beam b/_build/dev/lib/bandit/ebin/Elixir.Bandit.Trace.beam deleted file mode 100644 index 2cbb111..0000000 Binary files a/_build/dev/lib/bandit/ebin/Elixir.Bandit.Trace.beam and /dev/null differ diff --git a/_build/dev/lib/bandit/ebin/Elixir.Bandit.TransportError.beam b/_build/dev/lib/bandit/ebin/Elixir.Bandit.TransportError.beam deleted file mode 100644 index 8e9b5bc..0000000 Binary files a/_build/dev/lib/bandit/ebin/Elixir.Bandit.TransportError.beam and /dev/null differ diff --git a/_build/dev/lib/bandit/ebin/Elixir.Bandit.WebSocket.Connection.beam b/_build/dev/lib/bandit/ebin/Elixir.Bandit.WebSocket.Connection.beam deleted file mode 100644 index 7a57a23..0000000 Binary files a/_build/dev/lib/bandit/ebin/Elixir.Bandit.WebSocket.Connection.beam and /dev/null differ diff --git a/_build/dev/lib/bandit/ebin/Elixir.Bandit.WebSocket.Frame.Binary.beam b/_build/dev/lib/bandit/ebin/Elixir.Bandit.WebSocket.Frame.Binary.beam deleted file mode 100644 index ff23ad3..0000000 Binary files a/_build/dev/lib/bandit/ebin/Elixir.Bandit.WebSocket.Frame.Binary.beam and /dev/null differ diff --git a/_build/dev/lib/bandit/ebin/Elixir.Bandit.WebSocket.Frame.ConnectionClose.beam b/_build/dev/lib/bandit/ebin/Elixir.Bandit.WebSocket.Frame.ConnectionClose.beam deleted file mode 100644 index 1a70f9e..0000000 Binary files a/_build/dev/lib/bandit/ebin/Elixir.Bandit.WebSocket.Frame.ConnectionClose.beam and /dev/null differ diff --git a/_build/dev/lib/bandit/ebin/Elixir.Bandit.WebSocket.Frame.Continuation.beam b/_build/dev/lib/bandit/ebin/Elixir.Bandit.WebSocket.Frame.Continuation.beam deleted file mode 100644 index 7823a49..0000000 Binary files a/_build/dev/lib/bandit/ebin/Elixir.Bandit.WebSocket.Frame.Continuation.beam and /dev/null differ diff --git a/_build/dev/lib/bandit/ebin/Elixir.Bandit.WebSocket.Frame.Ping.beam b/_build/dev/lib/bandit/ebin/Elixir.Bandit.WebSocket.Frame.Ping.beam deleted file mode 100644 index c94504d..0000000 Binary files a/_build/dev/lib/bandit/ebin/Elixir.Bandit.WebSocket.Frame.Ping.beam and /dev/null differ diff --git a/_build/dev/lib/bandit/ebin/Elixir.Bandit.WebSocket.Frame.Pong.beam b/_build/dev/lib/bandit/ebin/Elixir.Bandit.WebSocket.Frame.Pong.beam deleted file mode 100644 index 39bfb45..0000000 Binary files a/_build/dev/lib/bandit/ebin/Elixir.Bandit.WebSocket.Frame.Pong.beam and /dev/null differ diff --git a/_build/dev/lib/bandit/ebin/Elixir.Bandit.WebSocket.Frame.Serializable.Bandit.WebSocket.Frame.Binary.beam b/_build/dev/lib/bandit/ebin/Elixir.Bandit.WebSocket.Frame.Serializable.Bandit.WebSocket.Frame.Binary.beam deleted file mode 100644 index 90b70da..0000000 Binary files a/_build/dev/lib/bandit/ebin/Elixir.Bandit.WebSocket.Frame.Serializable.Bandit.WebSocket.Frame.Binary.beam and /dev/null differ diff --git a/_build/dev/lib/bandit/ebin/Elixir.Bandit.WebSocket.Frame.Serializable.Bandit.WebSocket.Frame.ConnectionClose.beam b/_build/dev/lib/bandit/ebin/Elixir.Bandit.WebSocket.Frame.Serializable.Bandit.WebSocket.Frame.ConnectionClose.beam deleted file mode 100644 index 0de4a89..0000000 Binary files a/_build/dev/lib/bandit/ebin/Elixir.Bandit.WebSocket.Frame.Serializable.Bandit.WebSocket.Frame.ConnectionClose.beam and /dev/null differ diff --git a/_build/dev/lib/bandit/ebin/Elixir.Bandit.WebSocket.Frame.Serializable.Bandit.WebSocket.Frame.Continuation.beam b/_build/dev/lib/bandit/ebin/Elixir.Bandit.WebSocket.Frame.Serializable.Bandit.WebSocket.Frame.Continuation.beam deleted file mode 100644 index 866767d..0000000 Binary files a/_build/dev/lib/bandit/ebin/Elixir.Bandit.WebSocket.Frame.Serializable.Bandit.WebSocket.Frame.Continuation.beam and /dev/null differ diff --git a/_build/dev/lib/bandit/ebin/Elixir.Bandit.WebSocket.Frame.Serializable.Bandit.WebSocket.Frame.Ping.beam b/_build/dev/lib/bandit/ebin/Elixir.Bandit.WebSocket.Frame.Serializable.Bandit.WebSocket.Frame.Ping.beam deleted file mode 100644 index a9041f2..0000000 Binary files a/_build/dev/lib/bandit/ebin/Elixir.Bandit.WebSocket.Frame.Serializable.Bandit.WebSocket.Frame.Ping.beam and /dev/null differ diff --git a/_build/dev/lib/bandit/ebin/Elixir.Bandit.WebSocket.Frame.Serializable.Bandit.WebSocket.Frame.Pong.beam b/_build/dev/lib/bandit/ebin/Elixir.Bandit.WebSocket.Frame.Serializable.Bandit.WebSocket.Frame.Pong.beam deleted file mode 100644 index 83a58c2..0000000 Binary files a/_build/dev/lib/bandit/ebin/Elixir.Bandit.WebSocket.Frame.Serializable.Bandit.WebSocket.Frame.Pong.beam and /dev/null differ diff --git a/_build/dev/lib/bandit/ebin/Elixir.Bandit.WebSocket.Frame.Serializable.Bandit.WebSocket.Frame.Text.beam b/_build/dev/lib/bandit/ebin/Elixir.Bandit.WebSocket.Frame.Serializable.Bandit.WebSocket.Frame.Text.beam deleted file mode 100644 index 8409645..0000000 Binary files a/_build/dev/lib/bandit/ebin/Elixir.Bandit.WebSocket.Frame.Serializable.Bandit.WebSocket.Frame.Text.beam and /dev/null differ diff --git a/_build/dev/lib/bandit/ebin/Elixir.Bandit.WebSocket.Frame.Serializable.beam b/_build/dev/lib/bandit/ebin/Elixir.Bandit.WebSocket.Frame.Serializable.beam deleted file mode 100644 index 351d03d..0000000 Binary files a/_build/dev/lib/bandit/ebin/Elixir.Bandit.WebSocket.Frame.Serializable.beam and /dev/null differ diff --git a/_build/dev/lib/bandit/ebin/Elixir.Bandit.WebSocket.Frame.Text.beam b/_build/dev/lib/bandit/ebin/Elixir.Bandit.WebSocket.Frame.Text.beam deleted file mode 100644 index dbc31c2..0000000 Binary files a/_build/dev/lib/bandit/ebin/Elixir.Bandit.WebSocket.Frame.Text.beam and /dev/null differ diff --git a/_build/dev/lib/bandit/ebin/Elixir.Bandit.WebSocket.Frame.beam b/_build/dev/lib/bandit/ebin/Elixir.Bandit.WebSocket.Frame.beam deleted file mode 100644 index 555219c..0000000 Binary files a/_build/dev/lib/bandit/ebin/Elixir.Bandit.WebSocket.Frame.beam and /dev/null differ diff --git a/_build/dev/lib/bandit/ebin/Elixir.Bandit.WebSocket.Handler.beam b/_build/dev/lib/bandit/ebin/Elixir.Bandit.WebSocket.Handler.beam deleted file mode 100644 index 56fb548..0000000 Binary files a/_build/dev/lib/bandit/ebin/Elixir.Bandit.WebSocket.Handler.beam and /dev/null differ diff --git a/_build/dev/lib/bandit/ebin/Elixir.Bandit.WebSocket.Handshake.beam b/_build/dev/lib/bandit/ebin/Elixir.Bandit.WebSocket.Handshake.beam deleted file mode 100644 index 5d0c748..0000000 Binary files a/_build/dev/lib/bandit/ebin/Elixir.Bandit.WebSocket.Handshake.beam and /dev/null differ diff --git a/_build/dev/lib/bandit/ebin/Elixir.Bandit.WebSocket.PerMessageDeflate.beam b/_build/dev/lib/bandit/ebin/Elixir.Bandit.WebSocket.PerMessageDeflate.beam deleted file mode 100644 index 95a46b5..0000000 Binary files a/_build/dev/lib/bandit/ebin/Elixir.Bandit.WebSocket.PerMessageDeflate.beam and /dev/null differ diff --git a/_build/dev/lib/bandit/ebin/Elixir.Bandit.WebSocket.Socket.ThousandIsland.Socket.beam b/_build/dev/lib/bandit/ebin/Elixir.Bandit.WebSocket.Socket.ThousandIsland.Socket.beam deleted file mode 100644 index cb44c9d..0000000 Binary files a/_build/dev/lib/bandit/ebin/Elixir.Bandit.WebSocket.Socket.ThousandIsland.Socket.beam and /dev/null differ diff --git a/_build/dev/lib/bandit/ebin/Elixir.Bandit.WebSocket.Socket.beam b/_build/dev/lib/bandit/ebin/Elixir.Bandit.WebSocket.Socket.beam deleted file mode 100644 index 9957acc..0000000 Binary files a/_build/dev/lib/bandit/ebin/Elixir.Bandit.WebSocket.Socket.beam and /dev/null differ diff --git a/_build/dev/lib/bandit/ebin/Elixir.Bandit.WebSocket.UpgradeValidation.beam b/_build/dev/lib/bandit/ebin/Elixir.Bandit.WebSocket.UpgradeValidation.beam deleted file mode 100644 index c1dd155..0000000 Binary files a/_build/dev/lib/bandit/ebin/Elixir.Bandit.WebSocket.UpgradeValidation.beam and /dev/null differ diff --git a/_build/dev/lib/bandit/ebin/Elixir.Bandit.beam b/_build/dev/lib/bandit/ebin/Elixir.Bandit.beam deleted file mode 100644 index c7ffc44..0000000 Binary files a/_build/dev/lib/bandit/ebin/Elixir.Bandit.beam and /dev/null differ diff --git a/_build/dev/lib/bandit/ebin/bandit.app b/_build/dev/lib/bandit/ebin/bandit.app deleted file mode 100644 index 5cfd6d3..0000000 --- a/_build/dev/lib/bandit/ebin/bandit.app +++ /dev/null @@ -1 +0,0 @@ -{application,bandit,[{modules,['Elixir.Bandit','Elixir.Bandit.Adapter','Elixir.Bandit.Application','Elixir.Bandit.Clock','Elixir.Bandit.Compression','Elixir.Bandit.DelegatingHandler','Elixir.Bandit.Extractor','Elixir.Bandit.HTTP1.Handler','Elixir.Bandit.HTTP1.Socket','Elixir.Bandit.HTTP2.Connection','Elixir.Bandit.HTTP2.Errors','Elixir.Bandit.HTTP2.Errors.ConnectionError','Elixir.Bandit.HTTP2.Errors.StreamError','Elixir.Bandit.HTTP2.FlowControl','Elixir.Bandit.HTTP2.Frame','Elixir.Bandit.HTTP2.Frame.Continuation','Elixir.Bandit.HTTP2.Frame.Data','Elixir.Bandit.HTTP2.Frame.Flags','Elixir.Bandit.HTTP2.Frame.Goaway','Elixir.Bandit.HTTP2.Frame.Headers','Elixir.Bandit.HTTP2.Frame.Ping','Elixir.Bandit.HTTP2.Frame.Priority','Elixir.Bandit.HTTP2.Frame.PushPromise','Elixir.Bandit.HTTP2.Frame.RstStream','Elixir.Bandit.HTTP2.Frame.Serializable','Elixir.Bandit.HTTP2.Frame.Serializable.Bandit.HTTP2.Frame.Continuation','Elixir.Bandit.HTTP2.Frame.Serializable.Bandit.HTTP2.Frame.Data','Elixir.Bandit.HTTP2.Frame.Serializable.Bandit.HTTP2.Frame.Goaway','Elixir.Bandit.HTTP2.Frame.Serializable.Bandit.HTTP2.Frame.Headers','Elixir.Bandit.HTTP2.Frame.Serializable.Bandit.HTTP2.Frame.Ping','Elixir.Bandit.HTTP2.Frame.Serializable.Bandit.HTTP2.Frame.Priority','Elixir.Bandit.HTTP2.Frame.Serializable.Bandit.HTTP2.Frame.RstStream','Elixir.Bandit.HTTP2.Frame.Serializable.Bandit.HTTP2.Frame.Settings','Elixir.Bandit.HTTP2.Frame.Serializable.Bandit.HTTP2.Frame.WindowUpdate','Elixir.Bandit.HTTP2.Frame.Settings','Elixir.Bandit.HTTP2.Frame.Unknown','Elixir.Bandit.HTTP2.Frame.WindowUpdate','Elixir.Bandit.HTTP2.Handler','Elixir.Bandit.HTTP2.Settings','Elixir.Bandit.HTTP2.Stream','Elixir.Bandit.HTTP2.StreamCollection','Elixir.Bandit.HTTP2.StreamProcess','Elixir.Bandit.HTTPError','Elixir.Bandit.HTTPTransport','Elixir.Bandit.HTTPTransport.Bandit.HTTP1.Socket','Elixir.Bandit.HTTPTransport.Bandit.HTTP2.Stream','Elixir.Bandit.Headers','Elixir.Bandit.InitialHandler','Elixir.Bandit.Logger','Elixir.Bandit.PhoenixAdapter','Elixir.Bandit.Pipeline','Elixir.Bandit.PrimitiveOps.WebSocket','Elixir.Bandit.SocketHelpers','Elixir.Bandit.Telemetry','Elixir.Bandit.Trace','Elixir.Bandit.TransportError','Elixir.Bandit.WebSocket.Connection','Elixir.Bandit.WebSocket.Frame','Elixir.Bandit.WebSocket.Frame.Binary','Elixir.Bandit.WebSocket.Frame.ConnectionClose','Elixir.Bandit.WebSocket.Frame.Continuation','Elixir.Bandit.WebSocket.Frame.Ping','Elixir.Bandit.WebSocket.Frame.Pong','Elixir.Bandit.WebSocket.Frame.Serializable','Elixir.Bandit.WebSocket.Frame.Serializable.Bandit.WebSocket.Frame.Binary','Elixir.Bandit.WebSocket.Frame.Serializable.Bandit.WebSocket.Frame.ConnectionClose','Elixir.Bandit.WebSocket.Frame.Serializable.Bandit.WebSocket.Frame.Continuation','Elixir.Bandit.WebSocket.Frame.Serializable.Bandit.WebSocket.Frame.Ping','Elixir.Bandit.WebSocket.Frame.Serializable.Bandit.WebSocket.Frame.Pong','Elixir.Bandit.WebSocket.Frame.Serializable.Bandit.WebSocket.Frame.Text','Elixir.Bandit.WebSocket.Frame.Text','Elixir.Bandit.WebSocket.Handler','Elixir.Bandit.WebSocket.Handshake','Elixir.Bandit.WebSocket.PerMessageDeflate','Elixir.Bandit.WebSocket.Socket','Elixir.Bandit.WebSocket.Socket.ThousandIsland.Socket','Elixir.Bandit.WebSocket.UpgradeValidation']},{optional_applications,[]},{applications,[kernel,stdlib,elixir,logger,thousand_island,plug,websock,hpax,telemetry]},{description,"A pure-Elixir HTTP server built for Plug & WebSock apps"},{registered,[]},{vsn,"1.10.3"},{mod,{'Elixir.Bandit.Application',[]}}]}. \ No newline at end of file diff --git a/_build/dev/lib/hpax/.mix/compile.elixir b/_build/dev/lib/hpax/.mix/compile.elixir deleted file mode 100644 index 2f6dd5d..0000000 Binary files a/_build/dev/lib/hpax/.mix/compile.elixir and /dev/null differ diff --git a/_build/dev/lib/hpax/.mix/compile.elixir_scm b/_build/dev/lib/hpax/.mix/compile.elixir_scm deleted file mode 100644 index 4066741..0000000 Binary files a/_build/dev/lib/hpax/.mix/compile.elixir_scm and /dev/null differ diff --git a/_build/dev/lib/hpax/ebin/Elixir.HPAX.Huffman.beam b/_build/dev/lib/hpax/ebin/Elixir.HPAX.Huffman.beam deleted file mode 100644 index f06d6df..0000000 Binary files a/_build/dev/lib/hpax/ebin/Elixir.HPAX.Huffman.beam and /dev/null differ diff --git a/_build/dev/lib/hpax/ebin/Elixir.HPAX.Table.beam b/_build/dev/lib/hpax/ebin/Elixir.HPAX.Table.beam deleted file mode 100644 index 5c94668..0000000 Binary files a/_build/dev/lib/hpax/ebin/Elixir.HPAX.Table.beam and /dev/null differ diff --git a/_build/dev/lib/hpax/ebin/Elixir.HPAX.Types.beam b/_build/dev/lib/hpax/ebin/Elixir.HPAX.Types.beam deleted file mode 100644 index d8bdeae..0000000 Binary files a/_build/dev/lib/hpax/ebin/Elixir.HPAX.Types.beam and /dev/null differ diff --git a/_build/dev/lib/hpax/ebin/Elixir.HPAX.beam b/_build/dev/lib/hpax/ebin/Elixir.HPAX.beam deleted file mode 100644 index 5b027d3..0000000 Binary files a/_build/dev/lib/hpax/ebin/Elixir.HPAX.beam and /dev/null differ diff --git a/_build/dev/lib/hpax/ebin/hpax.app b/_build/dev/lib/hpax/ebin/hpax.app deleted file mode 100644 index d514d1e..0000000 --- a/_build/dev/lib/hpax/ebin/hpax.app +++ /dev/null @@ -1 +0,0 @@ -{application,hpax,[{modules,['Elixir.HPAX','Elixir.HPAX.Huffman','Elixir.HPAX.Table','Elixir.HPAX.Types']},{optional_applications,[]},{applications,[kernel,stdlib,elixir]},{description,"Implementation of the HPACK protocol (RFC 7541) for Elixir"},{registered,[]},{vsn,"1.0.3"}]}. \ No newline at end of file diff --git a/_build/dev/lib/jason/.mix/compile.elixir b/_build/dev/lib/jason/.mix/compile.elixir deleted file mode 100644 index 12d243e..0000000 Binary files a/_build/dev/lib/jason/.mix/compile.elixir and /dev/null differ diff --git a/_build/dev/lib/jason/.mix/compile.elixir_scm b/_build/dev/lib/jason/.mix/compile.elixir_scm deleted file mode 100644 index 4066741..0000000 Binary files a/_build/dev/lib/jason/.mix/compile.elixir_scm and /dev/null differ diff --git a/_build/dev/lib/jason/ebin/Elixir.Enumerable.Jason.OrderedObject.beam b/_build/dev/lib/jason/ebin/Elixir.Enumerable.Jason.OrderedObject.beam deleted file mode 100644 index 7099c0e..0000000 Binary files a/_build/dev/lib/jason/ebin/Elixir.Enumerable.Jason.OrderedObject.beam and /dev/null differ diff --git a/_build/dev/lib/jason/ebin/Elixir.Jason.Codegen.beam b/_build/dev/lib/jason/ebin/Elixir.Jason.Codegen.beam deleted file mode 100644 index 0e0221c..0000000 Binary files a/_build/dev/lib/jason/ebin/Elixir.Jason.Codegen.beam and /dev/null differ diff --git a/_build/dev/lib/jason/ebin/Elixir.Jason.DecodeError.beam b/_build/dev/lib/jason/ebin/Elixir.Jason.DecodeError.beam deleted file mode 100644 index ce29c2e..0000000 Binary files a/_build/dev/lib/jason/ebin/Elixir.Jason.DecodeError.beam and /dev/null differ diff --git a/_build/dev/lib/jason/ebin/Elixir.Jason.Decoder.Unescape.beam b/_build/dev/lib/jason/ebin/Elixir.Jason.Decoder.Unescape.beam deleted file mode 100644 index 083597a..0000000 Binary files a/_build/dev/lib/jason/ebin/Elixir.Jason.Decoder.Unescape.beam and /dev/null differ diff --git a/_build/dev/lib/jason/ebin/Elixir.Jason.Decoder.beam b/_build/dev/lib/jason/ebin/Elixir.Jason.Decoder.beam deleted file mode 100644 index dc463be..0000000 Binary files a/_build/dev/lib/jason/ebin/Elixir.Jason.Decoder.beam and /dev/null differ diff --git a/_build/dev/lib/jason/ebin/Elixir.Jason.Encode.beam b/_build/dev/lib/jason/ebin/Elixir.Jason.Encode.beam deleted file mode 100644 index d2c56c9..0000000 Binary files a/_build/dev/lib/jason/ebin/Elixir.Jason.Encode.beam and /dev/null differ diff --git a/_build/dev/lib/jason/ebin/Elixir.Jason.EncodeError.beam b/_build/dev/lib/jason/ebin/Elixir.Jason.EncodeError.beam deleted file mode 100644 index d694656..0000000 Binary files a/_build/dev/lib/jason/ebin/Elixir.Jason.EncodeError.beam and /dev/null differ diff --git a/_build/dev/lib/jason/ebin/Elixir.Jason.Encoder.Any.beam b/_build/dev/lib/jason/ebin/Elixir.Jason.Encoder.Any.beam deleted file mode 100644 index e752fd3..0000000 Binary files a/_build/dev/lib/jason/ebin/Elixir.Jason.Encoder.Any.beam and /dev/null differ diff --git a/_build/dev/lib/jason/ebin/Elixir.Jason.Encoder.Atom.beam b/_build/dev/lib/jason/ebin/Elixir.Jason.Encoder.Atom.beam deleted file mode 100644 index 9420f1a..0000000 Binary files a/_build/dev/lib/jason/ebin/Elixir.Jason.Encoder.Atom.beam and /dev/null differ diff --git a/_build/dev/lib/jason/ebin/Elixir.Jason.Encoder.BitString.beam b/_build/dev/lib/jason/ebin/Elixir.Jason.Encoder.BitString.beam deleted file mode 100644 index ba4448d..0000000 Binary files a/_build/dev/lib/jason/ebin/Elixir.Jason.Encoder.BitString.beam and /dev/null differ diff --git a/_build/dev/lib/jason/ebin/Elixir.Jason.Encoder.Date.beam b/_build/dev/lib/jason/ebin/Elixir.Jason.Encoder.Date.beam deleted file mode 100644 index 4e5b6a6..0000000 Binary files a/_build/dev/lib/jason/ebin/Elixir.Jason.Encoder.Date.beam and /dev/null differ diff --git a/_build/dev/lib/jason/ebin/Elixir.Jason.Encoder.DateTime.beam b/_build/dev/lib/jason/ebin/Elixir.Jason.Encoder.DateTime.beam deleted file mode 100644 index eeba8c3..0000000 Binary files a/_build/dev/lib/jason/ebin/Elixir.Jason.Encoder.DateTime.beam and /dev/null differ diff --git a/_build/dev/lib/jason/ebin/Elixir.Jason.Encoder.Float.beam b/_build/dev/lib/jason/ebin/Elixir.Jason.Encoder.Float.beam deleted file mode 100644 index 49bfc5b..0000000 Binary files a/_build/dev/lib/jason/ebin/Elixir.Jason.Encoder.Float.beam and /dev/null differ diff --git a/_build/dev/lib/jason/ebin/Elixir.Jason.Encoder.Integer.beam b/_build/dev/lib/jason/ebin/Elixir.Jason.Encoder.Integer.beam deleted file mode 100644 index 438e32e..0000000 Binary files a/_build/dev/lib/jason/ebin/Elixir.Jason.Encoder.Integer.beam and /dev/null differ diff --git a/_build/dev/lib/jason/ebin/Elixir.Jason.Encoder.Jason.Fragment.beam b/_build/dev/lib/jason/ebin/Elixir.Jason.Encoder.Jason.Fragment.beam deleted file mode 100644 index b6f47fa..0000000 Binary files a/_build/dev/lib/jason/ebin/Elixir.Jason.Encoder.Jason.Fragment.beam and /dev/null differ diff --git a/_build/dev/lib/jason/ebin/Elixir.Jason.Encoder.Jason.OrderedObject.beam b/_build/dev/lib/jason/ebin/Elixir.Jason.Encoder.Jason.OrderedObject.beam deleted file mode 100644 index a5941e4..0000000 Binary files a/_build/dev/lib/jason/ebin/Elixir.Jason.Encoder.Jason.OrderedObject.beam and /dev/null differ diff --git a/_build/dev/lib/jason/ebin/Elixir.Jason.Encoder.List.beam b/_build/dev/lib/jason/ebin/Elixir.Jason.Encoder.List.beam deleted file mode 100644 index d3bbec9..0000000 Binary files a/_build/dev/lib/jason/ebin/Elixir.Jason.Encoder.List.beam and /dev/null differ diff --git a/_build/dev/lib/jason/ebin/Elixir.Jason.Encoder.Map.beam b/_build/dev/lib/jason/ebin/Elixir.Jason.Encoder.Map.beam deleted file mode 100644 index 8c27e63..0000000 Binary files a/_build/dev/lib/jason/ebin/Elixir.Jason.Encoder.Map.beam and /dev/null differ diff --git a/_build/dev/lib/jason/ebin/Elixir.Jason.Encoder.NaiveDateTime.beam b/_build/dev/lib/jason/ebin/Elixir.Jason.Encoder.NaiveDateTime.beam deleted file mode 100644 index 2ad5ed0..0000000 Binary files a/_build/dev/lib/jason/ebin/Elixir.Jason.Encoder.NaiveDateTime.beam and /dev/null differ diff --git a/_build/dev/lib/jason/ebin/Elixir.Jason.Encoder.Time.beam b/_build/dev/lib/jason/ebin/Elixir.Jason.Encoder.Time.beam deleted file mode 100644 index b3408c1..0000000 Binary files a/_build/dev/lib/jason/ebin/Elixir.Jason.Encoder.Time.beam and /dev/null differ diff --git a/_build/dev/lib/jason/ebin/Elixir.Jason.Encoder.beam b/_build/dev/lib/jason/ebin/Elixir.Jason.Encoder.beam deleted file mode 100644 index 8109bf1..0000000 Binary files a/_build/dev/lib/jason/ebin/Elixir.Jason.Encoder.beam and /dev/null differ diff --git a/_build/dev/lib/jason/ebin/Elixir.Jason.Formatter.beam b/_build/dev/lib/jason/ebin/Elixir.Jason.Formatter.beam deleted file mode 100644 index 76e7fdd..0000000 Binary files a/_build/dev/lib/jason/ebin/Elixir.Jason.Formatter.beam and /dev/null differ diff --git a/_build/dev/lib/jason/ebin/Elixir.Jason.Fragment.beam b/_build/dev/lib/jason/ebin/Elixir.Jason.Fragment.beam deleted file mode 100644 index 0c3db6f..0000000 Binary files a/_build/dev/lib/jason/ebin/Elixir.Jason.Fragment.beam and /dev/null differ diff --git a/_build/dev/lib/jason/ebin/Elixir.Jason.Helpers.beam b/_build/dev/lib/jason/ebin/Elixir.Jason.Helpers.beam deleted file mode 100644 index 1d136f7..0000000 Binary files a/_build/dev/lib/jason/ebin/Elixir.Jason.Helpers.beam and /dev/null differ diff --git a/_build/dev/lib/jason/ebin/Elixir.Jason.OrderedObject.beam b/_build/dev/lib/jason/ebin/Elixir.Jason.OrderedObject.beam deleted file mode 100644 index 3bd0da3..0000000 Binary files a/_build/dev/lib/jason/ebin/Elixir.Jason.OrderedObject.beam and /dev/null differ diff --git a/_build/dev/lib/jason/ebin/Elixir.Jason.Sigil.beam b/_build/dev/lib/jason/ebin/Elixir.Jason.Sigil.beam deleted file mode 100644 index a418c75..0000000 Binary files a/_build/dev/lib/jason/ebin/Elixir.Jason.Sigil.beam and /dev/null differ diff --git a/_build/dev/lib/jason/ebin/Elixir.Jason.beam b/_build/dev/lib/jason/ebin/Elixir.Jason.beam deleted file mode 100644 index 9a9c5b6..0000000 Binary files a/_build/dev/lib/jason/ebin/Elixir.Jason.beam and /dev/null differ diff --git a/_build/dev/lib/jason/ebin/jason.app b/_build/dev/lib/jason/ebin/jason.app deleted file mode 100644 index 2d536c0..0000000 --- a/_build/dev/lib/jason/ebin/jason.app +++ /dev/null @@ -1 +0,0 @@ -{application,jason,[{modules,['Elixir.Enumerable.Jason.OrderedObject','Elixir.Jason','Elixir.Jason.Codegen','Elixir.Jason.DecodeError','Elixir.Jason.Decoder','Elixir.Jason.Decoder.Unescape','Elixir.Jason.Encode','Elixir.Jason.EncodeError','Elixir.Jason.Encoder','Elixir.Jason.Encoder.Any','Elixir.Jason.Encoder.Atom','Elixir.Jason.Encoder.BitString','Elixir.Jason.Encoder.Date','Elixir.Jason.Encoder.DateTime','Elixir.Jason.Encoder.Float','Elixir.Jason.Encoder.Integer','Elixir.Jason.Encoder.Jason.Fragment','Elixir.Jason.Encoder.Jason.OrderedObject','Elixir.Jason.Encoder.List','Elixir.Jason.Encoder.Map','Elixir.Jason.Encoder.NaiveDateTime','Elixir.Jason.Encoder.Time','Elixir.Jason.Formatter','Elixir.Jason.Fragment','Elixir.Jason.Helpers','Elixir.Jason.OrderedObject','Elixir.Jason.Sigil']},{optional_applications,[decimal]},{applications,[kernel,stdlib,elixir,decimal]},{description,"A blazing fast JSON parser and generator in pure Elixir.\n"},{registered,[]},{vsn,"1.4.4"}]}. \ No newline at end of file diff --git a/_build/dev/lib/mime/.mix/compile.elixir b/_build/dev/lib/mime/.mix/compile.elixir deleted file mode 100644 index 6174eb5..0000000 Binary files a/_build/dev/lib/mime/.mix/compile.elixir and /dev/null differ diff --git a/_build/dev/lib/mime/.mix/compile.elixir_scm b/_build/dev/lib/mime/.mix/compile.elixir_scm deleted file mode 100644 index 4066741..0000000 Binary files a/_build/dev/lib/mime/.mix/compile.elixir_scm and /dev/null differ diff --git a/_build/dev/lib/mime/ebin/Elixir.MIME.beam b/_build/dev/lib/mime/ebin/Elixir.MIME.beam deleted file mode 100644 index da9ca3b..0000000 Binary files a/_build/dev/lib/mime/ebin/Elixir.MIME.beam and /dev/null differ diff --git a/_build/dev/lib/mime/ebin/mime.app b/_build/dev/lib/mime/ebin/mime.app deleted file mode 100644 index cdfbbb8..0000000 --- a/_build/dev/lib/mime/ebin/mime.app +++ /dev/null @@ -1 +0,0 @@ -{application,mime,[{modules,['Elixir.MIME']},{compile_env,[{mime,[extensions],error},{mime,[suffixes],error},{mime,[types],error}]},{optional_applications,[]},{applications,[kernel,stdlib,elixir,logger]},{description,"A MIME type module for Elixir"},{registered,[]},{vsn,"2.0.7"},{env,[]}]}. \ No newline at end of file diff --git a/_build/dev/lib/plug/.mix/compile.elixir b/_build/dev/lib/plug/.mix/compile.elixir deleted file mode 100644 index 538513a..0000000 Binary files a/_build/dev/lib/plug/.mix/compile.elixir and /dev/null differ diff --git a/_build/dev/lib/plug/.mix/compile.elixir_scm b/_build/dev/lib/plug/.mix/compile.elixir_scm deleted file mode 100644 index 4066741..0000000 Binary files a/_build/dev/lib/plug/.mix/compile.elixir_scm and /dev/null differ diff --git a/_build/dev/lib/plug/.mix/compile.erlang b/_build/dev/lib/plug/.mix/compile.erlang deleted file mode 100644 index 377ce1b..0000000 Binary files a/_build/dev/lib/plug/.mix/compile.erlang and /dev/null differ diff --git a/_build/dev/lib/plug/ebin/Elixir.Inspect.Plug.Conn.beam b/_build/dev/lib/plug/ebin/Elixir.Inspect.Plug.Conn.beam deleted file mode 100644 index 678d766..0000000 Binary files a/_build/dev/lib/plug/ebin/Elixir.Inspect.Plug.Conn.beam and /dev/null differ diff --git a/_build/dev/lib/plug/ebin/Elixir.Plug.Adapters.Cowboy.beam b/_build/dev/lib/plug/ebin/Elixir.Plug.Adapters.Cowboy.beam deleted file mode 100644 index b3f79b1..0000000 Binary files a/_build/dev/lib/plug/ebin/Elixir.Plug.Adapters.Cowboy.beam and /dev/null differ diff --git a/_build/dev/lib/plug/ebin/Elixir.Plug.Adapters.Test.Conn.beam b/_build/dev/lib/plug/ebin/Elixir.Plug.Adapters.Test.Conn.beam deleted file mode 100644 index c203a17..0000000 Binary files a/_build/dev/lib/plug/ebin/Elixir.Plug.Adapters.Test.Conn.beam and /dev/null differ diff --git a/_build/dev/lib/plug/ebin/Elixir.Plug.Application.beam b/_build/dev/lib/plug/ebin/Elixir.Plug.Application.beam deleted file mode 100644 index b4ef468..0000000 Binary files a/_build/dev/lib/plug/ebin/Elixir.Plug.Application.beam and /dev/null differ diff --git a/_build/dev/lib/plug/ebin/Elixir.Plug.BadRequestError.beam b/_build/dev/lib/plug/ebin/Elixir.Plug.BadRequestError.beam deleted file mode 100644 index 9785a8d..0000000 Binary files a/_build/dev/lib/plug/ebin/Elixir.Plug.BadRequestError.beam and /dev/null differ diff --git a/_build/dev/lib/plug/ebin/Elixir.Plug.BasicAuth.beam b/_build/dev/lib/plug/ebin/Elixir.Plug.BasicAuth.beam deleted file mode 100644 index ab4b5b0..0000000 Binary files a/_build/dev/lib/plug/ebin/Elixir.Plug.BasicAuth.beam and /dev/null differ diff --git a/_build/dev/lib/plug/ebin/Elixir.Plug.Builder.beam b/_build/dev/lib/plug/ebin/Elixir.Plug.Builder.beam deleted file mode 100644 index e1c23fe..0000000 Binary files a/_build/dev/lib/plug/ebin/Elixir.Plug.Builder.beam and /dev/null differ diff --git a/_build/dev/lib/plug/ebin/Elixir.Plug.CSRFProtection.InvalidCSRFTokenError.beam b/_build/dev/lib/plug/ebin/Elixir.Plug.CSRFProtection.InvalidCSRFTokenError.beam deleted file mode 100644 index 4e18975..0000000 Binary files a/_build/dev/lib/plug/ebin/Elixir.Plug.CSRFProtection.InvalidCSRFTokenError.beam and /dev/null differ diff --git a/_build/dev/lib/plug/ebin/Elixir.Plug.CSRFProtection.InvalidCrossOriginRequestError.beam b/_build/dev/lib/plug/ebin/Elixir.Plug.CSRFProtection.InvalidCrossOriginRequestError.beam deleted file mode 100644 index 4215cfb..0000000 Binary files a/_build/dev/lib/plug/ebin/Elixir.Plug.CSRFProtection.InvalidCrossOriginRequestError.beam and /dev/null differ diff --git a/_build/dev/lib/plug/ebin/Elixir.Plug.CSRFProtection.beam b/_build/dev/lib/plug/ebin/Elixir.Plug.CSRFProtection.beam deleted file mode 100644 index 993b79c..0000000 Binary files a/_build/dev/lib/plug/ebin/Elixir.Plug.CSRFProtection.beam and /dev/null differ diff --git a/_build/dev/lib/plug/ebin/Elixir.Plug.Conn.Adapter.beam b/_build/dev/lib/plug/ebin/Elixir.Plug.Conn.Adapter.beam deleted file mode 100644 index bb713db..0000000 Binary files a/_build/dev/lib/plug/ebin/Elixir.Plug.Conn.Adapter.beam and /dev/null differ diff --git a/_build/dev/lib/plug/ebin/Elixir.Plug.Conn.AlreadySentError.beam b/_build/dev/lib/plug/ebin/Elixir.Plug.Conn.AlreadySentError.beam deleted file mode 100644 index b072f02..0000000 Binary files a/_build/dev/lib/plug/ebin/Elixir.Plug.Conn.AlreadySentError.beam and /dev/null differ diff --git a/_build/dev/lib/plug/ebin/Elixir.Plug.Conn.CookieOverflowError.beam b/_build/dev/lib/plug/ebin/Elixir.Plug.Conn.CookieOverflowError.beam deleted file mode 100644 index 634ea8b..0000000 Binary files a/_build/dev/lib/plug/ebin/Elixir.Plug.Conn.CookieOverflowError.beam and /dev/null differ diff --git a/_build/dev/lib/plug/ebin/Elixir.Plug.Conn.Cookies.beam b/_build/dev/lib/plug/ebin/Elixir.Plug.Conn.Cookies.beam deleted file mode 100644 index 0a9ceb5..0000000 Binary files a/_build/dev/lib/plug/ebin/Elixir.Plug.Conn.Cookies.beam and /dev/null differ diff --git a/_build/dev/lib/plug/ebin/Elixir.Plug.Conn.InvalidHeaderError.beam b/_build/dev/lib/plug/ebin/Elixir.Plug.Conn.InvalidHeaderError.beam deleted file mode 100644 index 15db502..0000000 Binary files a/_build/dev/lib/plug/ebin/Elixir.Plug.Conn.InvalidHeaderError.beam and /dev/null differ diff --git a/_build/dev/lib/plug/ebin/Elixir.Plug.Conn.InvalidQueryError.beam b/_build/dev/lib/plug/ebin/Elixir.Plug.Conn.InvalidQueryError.beam deleted file mode 100644 index 2e6436e..0000000 Binary files a/_build/dev/lib/plug/ebin/Elixir.Plug.Conn.InvalidQueryError.beam and /dev/null differ diff --git a/_build/dev/lib/plug/ebin/Elixir.Plug.Conn.NotSentError.beam b/_build/dev/lib/plug/ebin/Elixir.Plug.Conn.NotSentError.beam deleted file mode 100644 index 7bd58fe..0000000 Binary files a/_build/dev/lib/plug/ebin/Elixir.Plug.Conn.NotSentError.beam and /dev/null differ diff --git a/_build/dev/lib/plug/ebin/Elixir.Plug.Conn.Query.beam b/_build/dev/lib/plug/ebin/Elixir.Plug.Conn.Query.beam deleted file mode 100644 index 73975ff..0000000 Binary files a/_build/dev/lib/plug/ebin/Elixir.Plug.Conn.Query.beam and /dev/null differ diff --git a/_build/dev/lib/plug/ebin/Elixir.Plug.Conn.Status.beam b/_build/dev/lib/plug/ebin/Elixir.Plug.Conn.Status.beam deleted file mode 100644 index 058259b..0000000 Binary files a/_build/dev/lib/plug/ebin/Elixir.Plug.Conn.Status.beam and /dev/null differ diff --git a/_build/dev/lib/plug/ebin/Elixir.Plug.Conn.Unfetched.beam b/_build/dev/lib/plug/ebin/Elixir.Plug.Conn.Unfetched.beam deleted file mode 100644 index 1c8d897..0000000 Binary files a/_build/dev/lib/plug/ebin/Elixir.Plug.Conn.Unfetched.beam and /dev/null differ diff --git a/_build/dev/lib/plug/ebin/Elixir.Plug.Conn.Utils.beam b/_build/dev/lib/plug/ebin/Elixir.Plug.Conn.Utils.beam deleted file mode 100644 index 2094593..0000000 Binary files a/_build/dev/lib/plug/ebin/Elixir.Plug.Conn.Utils.beam and /dev/null differ diff --git a/_build/dev/lib/plug/ebin/Elixir.Plug.Conn.WrapperError.beam b/_build/dev/lib/plug/ebin/Elixir.Plug.Conn.WrapperError.beam deleted file mode 100644 index 869b4a9..0000000 Binary files a/_build/dev/lib/plug/ebin/Elixir.Plug.Conn.WrapperError.beam and /dev/null differ diff --git a/_build/dev/lib/plug/ebin/Elixir.Plug.Conn.beam b/_build/dev/lib/plug/ebin/Elixir.Plug.Conn.beam deleted file mode 100644 index dcb38e7..0000000 Binary files a/_build/dev/lib/plug/ebin/Elixir.Plug.Conn.beam and /dev/null differ diff --git a/_build/dev/lib/plug/ebin/Elixir.Plug.Debugger.beam b/_build/dev/lib/plug/ebin/Elixir.Plug.Debugger.beam deleted file mode 100644 index 1765fa3..0000000 Binary files a/_build/dev/lib/plug/ebin/Elixir.Plug.Debugger.beam and /dev/null differ diff --git a/_build/dev/lib/plug/ebin/Elixir.Plug.ErrorHandler.beam b/_build/dev/lib/plug/ebin/Elixir.Plug.ErrorHandler.beam deleted file mode 100644 index 0221932..0000000 Binary files a/_build/dev/lib/plug/ebin/Elixir.Plug.ErrorHandler.beam and /dev/null differ diff --git a/_build/dev/lib/plug/ebin/Elixir.Plug.Exception.Any.beam b/_build/dev/lib/plug/ebin/Elixir.Plug.Exception.Any.beam deleted file mode 100644 index c070159..0000000 Binary files a/_build/dev/lib/plug/ebin/Elixir.Plug.Exception.Any.beam and /dev/null differ diff --git a/_build/dev/lib/plug/ebin/Elixir.Plug.Exception.beam b/_build/dev/lib/plug/ebin/Elixir.Plug.Exception.beam deleted file mode 100644 index e0e0d2d..0000000 Binary files a/_build/dev/lib/plug/ebin/Elixir.Plug.Exception.beam and /dev/null differ diff --git a/_build/dev/lib/plug/ebin/Elixir.Plug.HTML.beam b/_build/dev/lib/plug/ebin/Elixir.Plug.HTML.beam deleted file mode 100644 index b68d3fa..0000000 Binary files a/_build/dev/lib/plug/ebin/Elixir.Plug.HTML.beam and /dev/null differ diff --git a/_build/dev/lib/plug/ebin/Elixir.Plug.Head.beam b/_build/dev/lib/plug/ebin/Elixir.Plug.Head.beam deleted file mode 100644 index 04d8538..0000000 Binary files a/_build/dev/lib/plug/ebin/Elixir.Plug.Head.beam and /dev/null differ diff --git a/_build/dev/lib/plug/ebin/Elixir.Plug.Logger.beam b/_build/dev/lib/plug/ebin/Elixir.Plug.Logger.beam deleted file mode 100644 index ea99ceb..0000000 Binary files a/_build/dev/lib/plug/ebin/Elixir.Plug.Logger.beam and /dev/null differ diff --git a/_build/dev/lib/plug/ebin/Elixir.Plug.MIME.beam b/_build/dev/lib/plug/ebin/Elixir.Plug.MIME.beam deleted file mode 100644 index bf4ffb7..0000000 Binary files a/_build/dev/lib/plug/ebin/Elixir.Plug.MIME.beam and /dev/null differ diff --git a/_build/dev/lib/plug/ebin/Elixir.Plug.MethodOverride.beam b/_build/dev/lib/plug/ebin/Elixir.Plug.MethodOverride.beam deleted file mode 100644 index f7ff812..0000000 Binary files a/_build/dev/lib/plug/ebin/Elixir.Plug.MethodOverride.beam and /dev/null differ diff --git a/_build/dev/lib/plug/ebin/Elixir.Plug.Parsers.BadEncodingError.beam b/_build/dev/lib/plug/ebin/Elixir.Plug.Parsers.BadEncodingError.beam deleted file mode 100644 index b4a0d2a..0000000 Binary files a/_build/dev/lib/plug/ebin/Elixir.Plug.Parsers.BadEncodingError.beam and /dev/null differ diff --git a/_build/dev/lib/plug/ebin/Elixir.Plug.Parsers.JSON.beam b/_build/dev/lib/plug/ebin/Elixir.Plug.Parsers.JSON.beam deleted file mode 100644 index 4b6de52..0000000 Binary files a/_build/dev/lib/plug/ebin/Elixir.Plug.Parsers.JSON.beam and /dev/null differ diff --git a/_build/dev/lib/plug/ebin/Elixir.Plug.Parsers.MULTIPART.beam b/_build/dev/lib/plug/ebin/Elixir.Plug.Parsers.MULTIPART.beam deleted file mode 100644 index 0c4667d..0000000 Binary files a/_build/dev/lib/plug/ebin/Elixir.Plug.Parsers.MULTIPART.beam and /dev/null differ diff --git a/_build/dev/lib/plug/ebin/Elixir.Plug.Parsers.ParseError.beam b/_build/dev/lib/plug/ebin/Elixir.Plug.Parsers.ParseError.beam deleted file mode 100644 index 1da6a8c..0000000 Binary files a/_build/dev/lib/plug/ebin/Elixir.Plug.Parsers.ParseError.beam and /dev/null differ diff --git a/_build/dev/lib/plug/ebin/Elixir.Plug.Parsers.RequestTooLargeError.beam b/_build/dev/lib/plug/ebin/Elixir.Plug.Parsers.RequestTooLargeError.beam deleted file mode 100644 index ed5ee86..0000000 Binary files a/_build/dev/lib/plug/ebin/Elixir.Plug.Parsers.RequestTooLargeError.beam and /dev/null differ diff --git a/_build/dev/lib/plug/ebin/Elixir.Plug.Parsers.URLENCODED.beam b/_build/dev/lib/plug/ebin/Elixir.Plug.Parsers.URLENCODED.beam deleted file mode 100644 index a345f21..0000000 Binary files a/_build/dev/lib/plug/ebin/Elixir.Plug.Parsers.URLENCODED.beam and /dev/null differ diff --git a/_build/dev/lib/plug/ebin/Elixir.Plug.Parsers.UnsupportedMediaTypeError.beam b/_build/dev/lib/plug/ebin/Elixir.Plug.Parsers.UnsupportedMediaTypeError.beam deleted file mode 100644 index fffd3bd..0000000 Binary files a/_build/dev/lib/plug/ebin/Elixir.Plug.Parsers.UnsupportedMediaTypeError.beam and /dev/null differ diff --git a/_build/dev/lib/plug/ebin/Elixir.Plug.Parsers.beam b/_build/dev/lib/plug/ebin/Elixir.Plug.Parsers.beam deleted file mode 100644 index 57f3f0c..0000000 Binary files a/_build/dev/lib/plug/ebin/Elixir.Plug.Parsers.beam and /dev/null differ diff --git a/_build/dev/lib/plug/ebin/Elixir.Plug.RequestId.beam b/_build/dev/lib/plug/ebin/Elixir.Plug.RequestId.beam deleted file mode 100644 index 297ec19..0000000 Binary files a/_build/dev/lib/plug/ebin/Elixir.Plug.RequestId.beam and /dev/null differ diff --git a/_build/dev/lib/plug/ebin/Elixir.Plug.RewriteOn.beam b/_build/dev/lib/plug/ebin/Elixir.Plug.RewriteOn.beam deleted file mode 100644 index 25d8e9e..0000000 Binary files a/_build/dev/lib/plug/ebin/Elixir.Plug.RewriteOn.beam and /dev/null differ diff --git a/_build/dev/lib/plug/ebin/Elixir.Plug.Router.InvalidSpecError.beam b/_build/dev/lib/plug/ebin/Elixir.Plug.Router.InvalidSpecError.beam deleted file mode 100644 index 485e878..0000000 Binary files a/_build/dev/lib/plug/ebin/Elixir.Plug.Router.InvalidSpecError.beam and /dev/null differ diff --git a/_build/dev/lib/plug/ebin/Elixir.Plug.Router.MalformedURIError.beam b/_build/dev/lib/plug/ebin/Elixir.Plug.Router.MalformedURIError.beam deleted file mode 100644 index a6e4753..0000000 Binary files a/_build/dev/lib/plug/ebin/Elixir.Plug.Router.MalformedURIError.beam and /dev/null differ diff --git a/_build/dev/lib/plug/ebin/Elixir.Plug.Router.Utils.beam b/_build/dev/lib/plug/ebin/Elixir.Plug.Router.Utils.beam deleted file mode 100644 index 647e6d5..0000000 Binary files a/_build/dev/lib/plug/ebin/Elixir.Plug.Router.Utils.beam and /dev/null differ diff --git a/_build/dev/lib/plug/ebin/Elixir.Plug.Router.beam b/_build/dev/lib/plug/ebin/Elixir.Plug.Router.beam deleted file mode 100644 index 931c07c..0000000 Binary files a/_build/dev/lib/plug/ebin/Elixir.Plug.Router.beam and /dev/null differ diff --git a/_build/dev/lib/plug/ebin/Elixir.Plug.SSL.beam b/_build/dev/lib/plug/ebin/Elixir.Plug.SSL.beam deleted file mode 100644 index 6b825bd..0000000 Binary files a/_build/dev/lib/plug/ebin/Elixir.Plug.SSL.beam and /dev/null differ diff --git a/_build/dev/lib/plug/ebin/Elixir.Plug.Session.COOKIE.beam b/_build/dev/lib/plug/ebin/Elixir.Plug.Session.COOKIE.beam deleted file mode 100644 index 9c40217..0000000 Binary files a/_build/dev/lib/plug/ebin/Elixir.Plug.Session.COOKIE.beam and /dev/null differ diff --git a/_build/dev/lib/plug/ebin/Elixir.Plug.Session.ETS.beam b/_build/dev/lib/plug/ebin/Elixir.Plug.Session.ETS.beam deleted file mode 100644 index 66d65a3..0000000 Binary files a/_build/dev/lib/plug/ebin/Elixir.Plug.Session.ETS.beam and /dev/null differ diff --git a/_build/dev/lib/plug/ebin/Elixir.Plug.Session.Store.beam b/_build/dev/lib/plug/ebin/Elixir.Plug.Session.Store.beam deleted file mode 100644 index b2add0e..0000000 Binary files a/_build/dev/lib/plug/ebin/Elixir.Plug.Session.Store.beam and /dev/null differ diff --git a/_build/dev/lib/plug/ebin/Elixir.Plug.Session.beam b/_build/dev/lib/plug/ebin/Elixir.Plug.Session.beam deleted file mode 100644 index af41b86..0000000 Binary files a/_build/dev/lib/plug/ebin/Elixir.Plug.Session.beam and /dev/null differ diff --git a/_build/dev/lib/plug/ebin/Elixir.Plug.Static.InvalidPathError.beam b/_build/dev/lib/plug/ebin/Elixir.Plug.Static.InvalidPathError.beam deleted file mode 100644 index 4f0fae2..0000000 Binary files a/_build/dev/lib/plug/ebin/Elixir.Plug.Static.InvalidPathError.beam and /dev/null differ diff --git a/_build/dev/lib/plug/ebin/Elixir.Plug.Static.beam b/_build/dev/lib/plug/ebin/Elixir.Plug.Static.beam deleted file mode 100644 index fe6059d..0000000 Binary files a/_build/dev/lib/plug/ebin/Elixir.Plug.Static.beam and /dev/null differ diff --git a/_build/dev/lib/plug/ebin/Elixir.Plug.Telemetry.beam b/_build/dev/lib/plug/ebin/Elixir.Plug.Telemetry.beam deleted file mode 100644 index d201369..0000000 Binary files a/_build/dev/lib/plug/ebin/Elixir.Plug.Telemetry.beam and /dev/null differ diff --git a/_build/dev/lib/plug/ebin/Elixir.Plug.Test.beam b/_build/dev/lib/plug/ebin/Elixir.Plug.Test.beam deleted file mode 100644 index 158740c..0000000 Binary files a/_build/dev/lib/plug/ebin/Elixir.Plug.Test.beam and /dev/null differ diff --git a/_build/dev/lib/plug/ebin/Elixir.Plug.TimeoutError.beam b/_build/dev/lib/plug/ebin/Elixir.Plug.TimeoutError.beam deleted file mode 100644 index 5998a74..0000000 Binary files a/_build/dev/lib/plug/ebin/Elixir.Plug.TimeoutError.beam and /dev/null differ diff --git a/_build/dev/lib/plug/ebin/Elixir.Plug.Upload.Supervisor.beam b/_build/dev/lib/plug/ebin/Elixir.Plug.Upload.Supervisor.beam deleted file mode 100644 index 48bb0b9..0000000 Binary files a/_build/dev/lib/plug/ebin/Elixir.Plug.Upload.Supervisor.beam and /dev/null differ diff --git a/_build/dev/lib/plug/ebin/Elixir.Plug.Upload.Terminator.beam b/_build/dev/lib/plug/ebin/Elixir.Plug.Upload.Terminator.beam deleted file mode 100644 index f87fc4e..0000000 Binary files a/_build/dev/lib/plug/ebin/Elixir.Plug.Upload.Terminator.beam and /dev/null differ diff --git a/_build/dev/lib/plug/ebin/Elixir.Plug.Upload.beam b/_build/dev/lib/plug/ebin/Elixir.Plug.Upload.beam deleted file mode 100644 index 2bb1ec0..0000000 Binary files a/_build/dev/lib/plug/ebin/Elixir.Plug.Upload.beam and /dev/null differ diff --git a/_build/dev/lib/plug/ebin/Elixir.Plug.UploadError.beam b/_build/dev/lib/plug/ebin/Elixir.Plug.UploadError.beam deleted file mode 100644 index 326e9cd..0000000 Binary files a/_build/dev/lib/plug/ebin/Elixir.Plug.UploadError.beam and /dev/null differ diff --git a/_build/dev/lib/plug/ebin/Elixir.Plug.beam b/_build/dev/lib/plug/ebin/Elixir.Plug.beam deleted file mode 100644 index 3eb76a4..0000000 Binary files a/_build/dev/lib/plug/ebin/Elixir.Plug.beam and /dev/null differ diff --git a/_build/dev/lib/plug/ebin/plug.app b/_build/dev/lib/plug/ebin/plug.app deleted file mode 100644 index c00d088..0000000 --- a/_build/dev/lib/plug/ebin/plug.app +++ /dev/null @@ -1 +0,0 @@ -{application,plug,[{modules,['Elixir.Inspect.Plug.Conn','Elixir.Plug','Elixir.Plug.Adapters.Cowboy','Elixir.Plug.Adapters.Test.Conn','Elixir.Plug.Application','Elixir.Plug.BadRequestError','Elixir.Plug.BasicAuth','Elixir.Plug.Builder','Elixir.Plug.CSRFProtection','Elixir.Plug.CSRFProtection.InvalidCSRFTokenError','Elixir.Plug.CSRFProtection.InvalidCrossOriginRequestError','Elixir.Plug.Conn','Elixir.Plug.Conn.Adapter','Elixir.Plug.Conn.AlreadySentError','Elixir.Plug.Conn.CookieOverflowError','Elixir.Plug.Conn.Cookies','Elixir.Plug.Conn.InvalidHeaderError','Elixir.Plug.Conn.InvalidQueryError','Elixir.Plug.Conn.NotSentError','Elixir.Plug.Conn.Query','Elixir.Plug.Conn.Status','Elixir.Plug.Conn.Unfetched','Elixir.Plug.Conn.Utils','Elixir.Plug.Conn.WrapperError','Elixir.Plug.Debugger','Elixir.Plug.ErrorHandler','Elixir.Plug.Exception','Elixir.Plug.Exception.Any','Elixir.Plug.HTML','Elixir.Plug.Head','Elixir.Plug.Logger','Elixir.Plug.MIME','Elixir.Plug.MethodOverride','Elixir.Plug.Parsers','Elixir.Plug.Parsers.BadEncodingError','Elixir.Plug.Parsers.JSON','Elixir.Plug.Parsers.MULTIPART','Elixir.Plug.Parsers.ParseError','Elixir.Plug.Parsers.RequestTooLargeError','Elixir.Plug.Parsers.URLENCODED','Elixir.Plug.Parsers.UnsupportedMediaTypeError','Elixir.Plug.RequestId','Elixir.Plug.RewriteOn','Elixir.Plug.Router','Elixir.Plug.Router.InvalidSpecError','Elixir.Plug.Router.MalformedURIError','Elixir.Plug.Router.Utils','Elixir.Plug.SSL','Elixir.Plug.Session','Elixir.Plug.Session.COOKIE','Elixir.Plug.Session.ETS','Elixir.Plug.Session.Store','Elixir.Plug.Static','Elixir.Plug.Static.InvalidPathError','Elixir.Plug.Telemetry','Elixir.Plug.Test','Elixir.Plug.TimeoutError','Elixir.Plug.Upload','Elixir.Plug.Upload.Supervisor','Elixir.Plug.Upload.Terminator','Elixir.Plug.UploadError',plug_multipart]},{compile_env,[{plug,[mimes],error},{plug,[statuses],error}]},{optional_applications,[]},{applications,[kernel,stdlib,elixir,logger,eex,mime,plug_crypto,telemetry]},{description,"Compose web applications with functions"},{registered,[]},{vsn,"1.19.1"},{mod,{'Elixir.Plug.Application',[]}},{env,[{validate_header_keys_during_test,true}]}]}. \ No newline at end of file diff --git a/_build/dev/lib/plug/ebin/plug_multipart.beam b/_build/dev/lib/plug/ebin/plug_multipart.beam deleted file mode 100644 index 6ac3545..0000000 Binary files a/_build/dev/lib/plug/ebin/plug_multipart.beam and /dev/null differ diff --git a/_build/dev/lib/plug_crypto/.mix/compile.elixir b/_build/dev/lib/plug_crypto/.mix/compile.elixir deleted file mode 100644 index bd2f7cb..0000000 Binary files a/_build/dev/lib/plug_crypto/.mix/compile.elixir and /dev/null differ diff --git a/_build/dev/lib/plug_crypto/.mix/compile.elixir_scm b/_build/dev/lib/plug_crypto/.mix/compile.elixir_scm deleted file mode 100644 index 4066741..0000000 Binary files a/_build/dev/lib/plug_crypto/.mix/compile.elixir_scm and /dev/null differ diff --git a/_build/dev/lib/plug_crypto/ebin/Elixir.Plug.Crypto.Application.beam b/_build/dev/lib/plug_crypto/ebin/Elixir.Plug.Crypto.Application.beam deleted file mode 100644 index 35d0872..0000000 Binary files a/_build/dev/lib/plug_crypto/ebin/Elixir.Plug.Crypto.Application.beam and /dev/null differ diff --git a/_build/dev/lib/plug_crypto/ebin/Elixir.Plug.Crypto.KeyGenerator.beam b/_build/dev/lib/plug_crypto/ebin/Elixir.Plug.Crypto.KeyGenerator.beam deleted file mode 100644 index d041718..0000000 Binary files a/_build/dev/lib/plug_crypto/ebin/Elixir.Plug.Crypto.KeyGenerator.beam and /dev/null differ diff --git a/_build/dev/lib/plug_crypto/ebin/Elixir.Plug.Crypto.MessageEncryptor.beam b/_build/dev/lib/plug_crypto/ebin/Elixir.Plug.Crypto.MessageEncryptor.beam deleted file mode 100644 index daf3769..0000000 Binary files a/_build/dev/lib/plug_crypto/ebin/Elixir.Plug.Crypto.MessageEncryptor.beam and /dev/null differ diff --git a/_build/dev/lib/plug_crypto/ebin/Elixir.Plug.Crypto.MessageVerifier.beam b/_build/dev/lib/plug_crypto/ebin/Elixir.Plug.Crypto.MessageVerifier.beam deleted file mode 100644 index 3937903..0000000 Binary files a/_build/dev/lib/plug_crypto/ebin/Elixir.Plug.Crypto.MessageVerifier.beam and /dev/null differ diff --git a/_build/dev/lib/plug_crypto/ebin/Elixir.Plug.Crypto.beam b/_build/dev/lib/plug_crypto/ebin/Elixir.Plug.Crypto.beam deleted file mode 100644 index ced9674..0000000 Binary files a/_build/dev/lib/plug_crypto/ebin/Elixir.Plug.Crypto.beam and /dev/null differ diff --git a/_build/dev/lib/plug_crypto/ebin/plug_crypto.app b/_build/dev/lib/plug_crypto/ebin/plug_crypto.app deleted file mode 100644 index 7997244..0000000 --- a/_build/dev/lib/plug_crypto/ebin/plug_crypto.app +++ /dev/null @@ -1 +0,0 @@ -{application,plug_crypto,[{modules,['Elixir.Plug.Crypto','Elixir.Plug.Crypto.Application','Elixir.Plug.Crypto.KeyGenerator','Elixir.Plug.Crypto.MessageEncryptor','Elixir.Plug.Crypto.MessageVerifier']},{optional_applications,[]},{applications,[kernel,stdlib,elixir,crypto]},{description,"Crypto-related functionality for the web"},{registered,[]},{vsn,"2.1.1"},{mod,{'Elixir.Plug.Crypto.Application',[]}}]}. \ No newline at end of file diff --git a/_build/dev/lib/symbiont/.mix/compile.app_cache b/_build/dev/lib/symbiont/.mix/compile.app_cache deleted file mode 100644 index f2af339..0000000 Binary files a/_build/dev/lib/symbiont/.mix/compile.app_cache and /dev/null differ diff --git a/_build/dev/lib/symbiont/.mix/compile.elixir b/_build/dev/lib/symbiont/.mix/compile.elixir deleted file mode 100644 index 9973c9e..0000000 Binary files a/_build/dev/lib/symbiont/.mix/compile.elixir and /dev/null differ diff --git a/_build/dev/lib/symbiont/.mix/compile.elixir_scm b/_build/dev/lib/symbiont/.mix/compile.elixir_scm deleted file mode 100644 index f1e974f..0000000 Binary files a/_build/dev/lib/symbiont/.mix/compile.elixir_scm and /dev/null differ diff --git a/_build/dev/lib/symbiont/.mix/compile.lock b/_build/dev/lib/symbiont/.mix/compile.lock deleted file mode 100644 index e69de29..0000000 diff --git a/_build/dev/lib/symbiont/consolidated/Elixir.Bandit.HTTP2.Frame.Serializable.beam b/_build/dev/lib/symbiont/consolidated/Elixir.Bandit.HTTP2.Frame.Serializable.beam deleted file mode 100644 index adc09ce..0000000 Binary files a/_build/dev/lib/symbiont/consolidated/Elixir.Bandit.HTTP2.Frame.Serializable.beam and /dev/null differ diff --git a/_build/dev/lib/symbiont/consolidated/Elixir.Bandit.HTTPTransport.beam b/_build/dev/lib/symbiont/consolidated/Elixir.Bandit.HTTPTransport.beam deleted file mode 100644 index 94d2d7a..0000000 Binary files a/_build/dev/lib/symbiont/consolidated/Elixir.Bandit.HTTPTransport.beam and /dev/null differ diff --git a/_build/dev/lib/symbiont/consolidated/Elixir.Bandit.WebSocket.Frame.Serializable.beam b/_build/dev/lib/symbiont/consolidated/Elixir.Bandit.WebSocket.Frame.Serializable.beam deleted file mode 100644 index 515c9da..0000000 Binary files a/_build/dev/lib/symbiont/consolidated/Elixir.Bandit.WebSocket.Frame.Serializable.beam and /dev/null differ diff --git a/_build/dev/lib/symbiont/consolidated/Elixir.Bandit.WebSocket.Socket.beam b/_build/dev/lib/symbiont/consolidated/Elixir.Bandit.WebSocket.Socket.beam deleted file mode 100644 index 5646ce3..0000000 Binary files a/_build/dev/lib/symbiont/consolidated/Elixir.Bandit.WebSocket.Socket.beam and /dev/null differ diff --git a/_build/dev/lib/symbiont/consolidated/Elixir.Collectable.beam b/_build/dev/lib/symbiont/consolidated/Elixir.Collectable.beam deleted file mode 100644 index 8e5c284..0000000 Binary files a/_build/dev/lib/symbiont/consolidated/Elixir.Collectable.beam and /dev/null differ diff --git a/_build/dev/lib/symbiont/consolidated/Elixir.Enumerable.beam b/_build/dev/lib/symbiont/consolidated/Elixir.Enumerable.beam deleted file mode 100644 index 17a06c1..0000000 Binary files a/_build/dev/lib/symbiont/consolidated/Elixir.Enumerable.beam and /dev/null differ diff --git a/_build/dev/lib/symbiont/consolidated/Elixir.IEx.Info.beam b/_build/dev/lib/symbiont/consolidated/Elixir.IEx.Info.beam deleted file mode 100644 index b353a23..0000000 Binary files a/_build/dev/lib/symbiont/consolidated/Elixir.IEx.Info.beam and /dev/null differ diff --git a/_build/dev/lib/symbiont/consolidated/Elixir.Inspect.beam b/_build/dev/lib/symbiont/consolidated/Elixir.Inspect.beam deleted file mode 100644 index 1d7a158..0000000 Binary files a/_build/dev/lib/symbiont/consolidated/Elixir.Inspect.beam and /dev/null differ diff --git a/_build/dev/lib/symbiont/consolidated/Elixir.JSON.Encoder.beam b/_build/dev/lib/symbiont/consolidated/Elixir.JSON.Encoder.beam deleted file mode 100644 index 54aed03..0000000 Binary files a/_build/dev/lib/symbiont/consolidated/Elixir.JSON.Encoder.beam and /dev/null differ diff --git a/_build/dev/lib/symbiont/consolidated/Elixir.Jason.Encoder.beam b/_build/dev/lib/symbiont/consolidated/Elixir.Jason.Encoder.beam deleted file mode 100644 index eb2b370..0000000 Binary files a/_build/dev/lib/symbiont/consolidated/Elixir.Jason.Encoder.beam and /dev/null differ diff --git a/_build/dev/lib/symbiont/consolidated/Elixir.List.Chars.beam b/_build/dev/lib/symbiont/consolidated/Elixir.List.Chars.beam deleted file mode 100644 index a32010d..0000000 Binary files a/_build/dev/lib/symbiont/consolidated/Elixir.List.Chars.beam and /dev/null differ diff --git a/_build/dev/lib/symbiont/consolidated/Elixir.Plug.Exception.beam b/_build/dev/lib/symbiont/consolidated/Elixir.Plug.Exception.beam deleted file mode 100644 index 5762b0e..0000000 Binary files a/_build/dev/lib/symbiont/consolidated/Elixir.Plug.Exception.beam and /dev/null differ diff --git a/_build/dev/lib/symbiont/consolidated/Elixir.String.Chars.beam b/_build/dev/lib/symbiont/consolidated/Elixir.String.Chars.beam deleted file mode 100644 index 1d65575..0000000 Binary files a/_build/dev/lib/symbiont/consolidated/Elixir.String.Chars.beam and /dev/null differ diff --git a/_build/dev/lib/symbiont/ebin/Elixir.Symbiont.API.beam b/_build/dev/lib/symbiont/ebin/Elixir.Symbiont.API.beam deleted file mode 100644 index 407ce2c..0000000 Binary files a/_build/dev/lib/symbiont/ebin/Elixir.Symbiont.API.beam and /dev/null differ diff --git a/_build/dev/lib/symbiont/ebin/Elixir.Symbiont.Application.beam b/_build/dev/lib/symbiont/ebin/Elixir.Symbiont.Application.beam deleted file mode 100644 index 2ef9df6..0000000 Binary files a/_build/dev/lib/symbiont/ebin/Elixir.Symbiont.Application.beam and /dev/null differ diff --git a/_build/dev/lib/symbiont/ebin/Elixir.Symbiont.Dispatcher.beam b/_build/dev/lib/symbiont/ebin/Elixir.Symbiont.Dispatcher.beam deleted file mode 100644 index de03d2d..0000000 Binary files a/_build/dev/lib/symbiont/ebin/Elixir.Symbiont.Dispatcher.beam and /dev/null differ diff --git a/_build/dev/lib/symbiont/ebin/Elixir.Symbiont.Heartbeat.beam b/_build/dev/lib/symbiont/ebin/Elixir.Symbiont.Heartbeat.beam deleted file mode 100644 index b9de174..0000000 Binary files a/_build/dev/lib/symbiont/ebin/Elixir.Symbiont.Heartbeat.beam and /dev/null differ diff --git a/_build/dev/lib/symbiont/ebin/Elixir.Symbiont.Ledger.beam b/_build/dev/lib/symbiont/ebin/Elixir.Symbiont.Ledger.beam deleted file mode 100644 index 96a5f6f..0000000 Binary files a/_build/dev/lib/symbiont/ebin/Elixir.Symbiont.Ledger.beam and /dev/null differ diff --git a/_build/dev/lib/symbiont/ebin/Elixir.Symbiont.Queue.beam b/_build/dev/lib/symbiont/ebin/Elixir.Symbiont.Queue.beam deleted file mode 100644 index 505dac7..0000000 Binary files a/_build/dev/lib/symbiont/ebin/Elixir.Symbiont.Queue.beam and /dev/null differ diff --git a/_build/dev/lib/symbiont/ebin/Elixir.Symbiont.Router.beam b/_build/dev/lib/symbiont/ebin/Elixir.Symbiont.Router.beam deleted file mode 100644 index 3d85bd9..0000000 Binary files a/_build/dev/lib/symbiont/ebin/Elixir.Symbiont.Router.beam and /dev/null differ diff --git a/_build/dev/lib/symbiont/ebin/Elixir.Symbiont.beam b/_build/dev/lib/symbiont/ebin/Elixir.Symbiont.beam deleted file mode 100644 index bf5f052..0000000 Binary files a/_build/dev/lib/symbiont/ebin/Elixir.Symbiont.beam and /dev/null differ diff --git a/_build/dev/lib/symbiont/ebin/symbiont.app b/_build/dev/lib/symbiont/ebin/symbiont.app deleted file mode 100644 index 4e22c01..0000000 --- a/_build/dev/lib/symbiont/ebin/symbiont.app +++ /dev/null @@ -1 +0,0 @@ -{application,symbiont,[{modules,['Elixir.Symbiont','Elixir.Symbiont.API','Elixir.Symbiont.Application','Elixir.Symbiont.Dispatcher','Elixir.Symbiont.Engram','Elixir.Symbiont.Heartbeat','Elixir.Symbiont.Ledger','Elixir.Symbiont.Queue','Elixir.Symbiont.Router']},{optional_applications,[]},{applications,[kernel,stdlib,elixir,logger,crypto,bandit,plug,jason,exqlite]},{description,"symbiont"},{registered,[]},{vsn,"0.2.0"},{mod,{'Elixir.Symbiont.Application',[]}}]}. \ No newline at end of file diff --git a/_build/dev/lib/telemetry/.mix/compile.elixir_scm b/_build/dev/lib/telemetry/.mix/compile.elixir_scm deleted file mode 100644 index 4066741..0000000 Binary files a/_build/dev/lib/telemetry/.mix/compile.elixir_scm and /dev/null differ diff --git a/_build/dev/lib/telemetry/ebin/telemetry.app b/_build/dev/lib/telemetry/ebin/telemetry.app deleted file mode 100644 index b09b016..0000000 --- a/_build/dev/lib/telemetry/ebin/telemetry.app +++ /dev/null @@ -1,15 +0,0 @@ -{application,telemetry, - [{description,"Dynamic dispatching library for metrics and instrumentations"}, - {vsn,"1.4.1"}, - {registered,[]}, - {mod,{telemetry_app,[]}}, - {applications,[kernel,stdlib]}, - {env,[]}, - {modules,[telemetry,telemetry_app,telemetry_ets, - telemetry_handler_table,telemetry_pt,telemetry_sup, - telemetry_test]}, - {licenses,["Apache-2.0"]}, - {links,[{"GitHub", - "https://github.com/beam-telemetry/telemetry"}]}, - {doc,"doc"}, - {include_files,["mix.exs"]}]}. diff --git a/_build/dev/lib/telemetry/ebin/telemetry.beam b/_build/dev/lib/telemetry/ebin/telemetry.beam deleted file mode 100644 index 5774f26..0000000 Binary files a/_build/dev/lib/telemetry/ebin/telemetry.beam and /dev/null differ diff --git a/_build/dev/lib/telemetry/ebin/telemetry_app.beam b/_build/dev/lib/telemetry/ebin/telemetry_app.beam deleted file mode 100644 index 49cb683..0000000 Binary files a/_build/dev/lib/telemetry/ebin/telemetry_app.beam and /dev/null differ diff --git a/_build/dev/lib/telemetry/ebin/telemetry_ets.beam b/_build/dev/lib/telemetry/ebin/telemetry_ets.beam deleted file mode 100644 index 8899bec..0000000 Binary files a/_build/dev/lib/telemetry/ebin/telemetry_ets.beam and /dev/null differ diff --git a/_build/dev/lib/telemetry/ebin/telemetry_handler_table.beam b/_build/dev/lib/telemetry/ebin/telemetry_handler_table.beam deleted file mode 100644 index 8fbe421..0000000 Binary files a/_build/dev/lib/telemetry/ebin/telemetry_handler_table.beam and /dev/null differ diff --git a/_build/dev/lib/telemetry/ebin/telemetry_pt.beam b/_build/dev/lib/telemetry/ebin/telemetry_pt.beam deleted file mode 100644 index aca06b3..0000000 Binary files a/_build/dev/lib/telemetry/ebin/telemetry_pt.beam and /dev/null differ diff --git a/_build/dev/lib/telemetry/ebin/telemetry_sup.beam b/_build/dev/lib/telemetry/ebin/telemetry_sup.beam deleted file mode 100644 index 6a8efe0..0000000 Binary files a/_build/dev/lib/telemetry/ebin/telemetry_sup.beam and /dev/null differ diff --git a/_build/dev/lib/telemetry/ebin/telemetry_test.beam b/_build/dev/lib/telemetry/ebin/telemetry_test.beam deleted file mode 100644 index 20c18bb..0000000 Binary files a/_build/dev/lib/telemetry/ebin/telemetry_test.beam and /dev/null differ diff --git a/_build/dev/lib/telemetry/mix.rebar.config b/_build/dev/lib/telemetry/mix.rebar.config deleted file mode 100644 index ca1ef50..0000000 --- a/_build/dev/lib/telemetry/mix.rebar.config +++ /dev/null @@ -1,17 +0,0 @@ -{erl_opts,[debug_info]}. -{deps,[]}. -{profiles,[{test,[{erl_opts,[nowarn_export_all]}, - {ct_opts,[{ct_hooks,[cth_surefire]}]}, - {cover_enabled,true}, - {cover_opts,[verbose]}, - {plugins,[covertool]}, - {covertool,[{coverdata_files,["ct.coverdata"]}]}]}]}. -{shell,[{apps,[telemetry]}]}. -{xref_checks,[undefined_function_calls,undefined_functions,locals_not_used, - deprecated_function_calls,deprecated_functions]}. -{hex,[{doc,#{provider => ex_doc}}]}. -{ex_doc,[{source_url,<<"https://github.com/beam-telemetry/telemetry">>}, - {extras,[<<"README.md">>,<<"CHANGELOG.md">>,<<"LICENSE">>, - <<"NOTICE">>]}, - {main,<<"readme">>}]}. -{overrides,[]}. diff --git a/_build/dev/lib/telemetry/src b/_build/dev/lib/telemetry/src deleted file mode 120000 index f3de4ce..0000000 --- a/_build/dev/lib/telemetry/src +++ /dev/null @@ -1 +0,0 @@ -../../../../deps/telemetry/src \ No newline at end of file diff --git a/_build/dev/lib/thousand_island/.mix/compile.elixir b/_build/dev/lib/thousand_island/.mix/compile.elixir deleted file mode 100644 index 3d4b02e..0000000 Binary files a/_build/dev/lib/thousand_island/.mix/compile.elixir and /dev/null differ diff --git a/_build/dev/lib/thousand_island/.mix/compile.elixir_scm b/_build/dev/lib/thousand_island/.mix/compile.elixir_scm deleted file mode 100644 index 4066741..0000000 Binary files a/_build/dev/lib/thousand_island/.mix/compile.elixir_scm and /dev/null differ diff --git a/_build/dev/lib/thousand_island/ebin/Elixir.ThousandIsland.Acceptor.beam b/_build/dev/lib/thousand_island/ebin/Elixir.ThousandIsland.Acceptor.beam deleted file mode 100644 index eeaec07..0000000 Binary files a/_build/dev/lib/thousand_island/ebin/Elixir.ThousandIsland.Acceptor.beam and /dev/null differ diff --git a/_build/dev/lib/thousand_island/ebin/Elixir.ThousandIsland.AcceptorPoolSupervisor.beam b/_build/dev/lib/thousand_island/ebin/Elixir.ThousandIsland.AcceptorPoolSupervisor.beam deleted file mode 100644 index 258e80b..0000000 Binary files a/_build/dev/lib/thousand_island/ebin/Elixir.ThousandIsland.AcceptorPoolSupervisor.beam and /dev/null differ diff --git a/_build/dev/lib/thousand_island/ebin/Elixir.ThousandIsland.AcceptorSupervisor.beam b/_build/dev/lib/thousand_island/ebin/Elixir.ThousandIsland.AcceptorSupervisor.beam deleted file mode 100644 index a31e396..0000000 Binary files a/_build/dev/lib/thousand_island/ebin/Elixir.ThousandIsland.AcceptorSupervisor.beam and /dev/null differ diff --git a/_build/dev/lib/thousand_island/ebin/Elixir.ThousandIsland.Connection.beam b/_build/dev/lib/thousand_island/ebin/Elixir.ThousandIsland.Connection.beam deleted file mode 100644 index 117f199..0000000 Binary files a/_build/dev/lib/thousand_island/ebin/Elixir.ThousandIsland.Connection.beam and /dev/null differ diff --git a/_build/dev/lib/thousand_island/ebin/Elixir.ThousandIsland.Handler.beam b/_build/dev/lib/thousand_island/ebin/Elixir.ThousandIsland.Handler.beam deleted file mode 100644 index acdf258..0000000 Binary files a/_build/dev/lib/thousand_island/ebin/Elixir.ThousandIsland.Handler.beam and /dev/null differ diff --git a/_build/dev/lib/thousand_island/ebin/Elixir.ThousandIsland.HandlerConfig.beam b/_build/dev/lib/thousand_island/ebin/Elixir.ThousandIsland.HandlerConfig.beam deleted file mode 100644 index 61865cf..0000000 Binary files a/_build/dev/lib/thousand_island/ebin/Elixir.ThousandIsland.HandlerConfig.beam and /dev/null differ diff --git a/_build/dev/lib/thousand_island/ebin/Elixir.ThousandIsland.Listener.beam b/_build/dev/lib/thousand_island/ebin/Elixir.ThousandIsland.Listener.beam deleted file mode 100644 index a4eab8c..0000000 Binary files a/_build/dev/lib/thousand_island/ebin/Elixir.ThousandIsland.Listener.beam and /dev/null differ diff --git a/_build/dev/lib/thousand_island/ebin/Elixir.ThousandIsland.Logger.beam b/_build/dev/lib/thousand_island/ebin/Elixir.ThousandIsland.Logger.beam deleted file mode 100644 index 4e77013..0000000 Binary files a/_build/dev/lib/thousand_island/ebin/Elixir.ThousandIsland.Logger.beam and /dev/null differ diff --git a/_build/dev/lib/thousand_island/ebin/Elixir.ThousandIsland.ProcessLabel.beam b/_build/dev/lib/thousand_island/ebin/Elixir.ThousandIsland.ProcessLabel.beam deleted file mode 100644 index 1fffbf5..0000000 Binary files a/_build/dev/lib/thousand_island/ebin/Elixir.ThousandIsland.ProcessLabel.beam and /dev/null differ diff --git a/_build/dev/lib/thousand_island/ebin/Elixir.ThousandIsland.Server.beam b/_build/dev/lib/thousand_island/ebin/Elixir.ThousandIsland.Server.beam deleted file mode 100644 index 390d2ce..0000000 Binary files a/_build/dev/lib/thousand_island/ebin/Elixir.ThousandIsland.Server.beam and /dev/null differ diff --git a/_build/dev/lib/thousand_island/ebin/Elixir.ThousandIsland.ServerConfig.beam b/_build/dev/lib/thousand_island/ebin/Elixir.ThousandIsland.ServerConfig.beam deleted file mode 100644 index 7ce76d9..0000000 Binary files a/_build/dev/lib/thousand_island/ebin/Elixir.ThousandIsland.ServerConfig.beam and /dev/null differ diff --git a/_build/dev/lib/thousand_island/ebin/Elixir.ThousandIsland.ShutdownListener.beam b/_build/dev/lib/thousand_island/ebin/Elixir.ThousandIsland.ShutdownListener.beam deleted file mode 100644 index 4777534..0000000 Binary files a/_build/dev/lib/thousand_island/ebin/Elixir.ThousandIsland.ShutdownListener.beam and /dev/null differ diff --git a/_build/dev/lib/thousand_island/ebin/Elixir.ThousandIsland.Socket.beam b/_build/dev/lib/thousand_island/ebin/Elixir.ThousandIsland.Socket.beam deleted file mode 100644 index 9366638..0000000 Binary files a/_build/dev/lib/thousand_island/ebin/Elixir.ThousandIsland.Socket.beam and /dev/null differ diff --git a/_build/dev/lib/thousand_island/ebin/Elixir.ThousandIsland.Telemetry.beam b/_build/dev/lib/thousand_island/ebin/Elixir.ThousandIsland.Telemetry.beam deleted file mode 100644 index abfcb05..0000000 Binary files a/_build/dev/lib/thousand_island/ebin/Elixir.ThousandIsland.Telemetry.beam and /dev/null differ diff --git a/_build/dev/lib/thousand_island/ebin/Elixir.ThousandIsland.Transport.beam b/_build/dev/lib/thousand_island/ebin/Elixir.ThousandIsland.Transport.beam deleted file mode 100644 index 01c358d..0000000 Binary files a/_build/dev/lib/thousand_island/ebin/Elixir.ThousandIsland.Transport.beam and /dev/null differ diff --git a/_build/dev/lib/thousand_island/ebin/Elixir.ThousandIsland.Transports.SSL.beam b/_build/dev/lib/thousand_island/ebin/Elixir.ThousandIsland.Transports.SSL.beam deleted file mode 100644 index b3b8417..0000000 Binary files a/_build/dev/lib/thousand_island/ebin/Elixir.ThousandIsland.Transports.SSL.beam and /dev/null differ diff --git a/_build/dev/lib/thousand_island/ebin/Elixir.ThousandIsland.Transports.TCP.beam b/_build/dev/lib/thousand_island/ebin/Elixir.ThousandIsland.Transports.TCP.beam deleted file mode 100644 index d1893bf..0000000 Binary files a/_build/dev/lib/thousand_island/ebin/Elixir.ThousandIsland.Transports.TCP.beam and /dev/null differ diff --git a/_build/dev/lib/thousand_island/ebin/Elixir.ThousandIsland.beam b/_build/dev/lib/thousand_island/ebin/Elixir.ThousandIsland.beam deleted file mode 100644 index f44e43c..0000000 Binary files a/_build/dev/lib/thousand_island/ebin/Elixir.ThousandIsland.beam and /dev/null differ diff --git a/_build/dev/lib/thousand_island/ebin/thousand_island.app b/_build/dev/lib/thousand_island/ebin/thousand_island.app deleted file mode 100644 index fe65be4..0000000 --- a/_build/dev/lib/thousand_island/ebin/thousand_island.app +++ /dev/null @@ -1 +0,0 @@ -{application,thousand_island,[{modules,['Elixir.ThousandIsland','Elixir.ThousandIsland.Acceptor','Elixir.ThousandIsland.AcceptorPoolSupervisor','Elixir.ThousandIsland.AcceptorSupervisor','Elixir.ThousandIsland.Connection','Elixir.ThousandIsland.Handler','Elixir.ThousandIsland.HandlerConfig','Elixir.ThousandIsland.Listener','Elixir.ThousandIsland.Logger','Elixir.ThousandIsland.ProcessLabel','Elixir.ThousandIsland.Server','Elixir.ThousandIsland.ServerConfig','Elixir.ThousandIsland.ShutdownListener','Elixir.ThousandIsland.Socket','Elixir.ThousandIsland.Telemetry','Elixir.ThousandIsland.Transport','Elixir.ThousandIsland.Transports.SSL','Elixir.ThousandIsland.Transports.TCP']},{optional_applications,[]},{applications,[kernel,stdlib,elixir,logger,ssl,telemetry]},{description,"A simple & modern pure Elixir socket server"},{registered,[]},{vsn,"1.4.3"}]}. \ No newline at end of file diff --git a/_build/dev/lib/websock/.mix/compile.elixir b/_build/dev/lib/websock/.mix/compile.elixir deleted file mode 100644 index f56fa21..0000000 Binary files a/_build/dev/lib/websock/.mix/compile.elixir and /dev/null differ diff --git a/_build/dev/lib/websock/.mix/compile.elixir_scm b/_build/dev/lib/websock/.mix/compile.elixir_scm deleted file mode 100644 index 4066741..0000000 Binary files a/_build/dev/lib/websock/.mix/compile.elixir_scm and /dev/null differ diff --git a/_build/dev/lib/websock/ebin/Elixir.WebSock.beam b/_build/dev/lib/websock/ebin/Elixir.WebSock.beam deleted file mode 100644 index af0821e..0000000 Binary files a/_build/dev/lib/websock/ebin/Elixir.WebSock.beam and /dev/null differ diff --git a/_build/dev/lib/websock/ebin/websock.app b/_build/dev/lib/websock/ebin/websock.app deleted file mode 100644 index b9acb14..0000000 --- a/_build/dev/lib/websock/ebin/websock.app +++ /dev/null @@ -1 +0,0 @@ -{application,websock,[{modules,['Elixir.WebSock']},{optional_applications,[]},{applications,[kernel,stdlib,elixir]},{description,"A specification for WebSocket connections"},{registered,[]},{vsn,"0.5.3"}]}. \ No newline at end of file diff --git a/_build/prod/lib/bandit/.mix/compile.elixir b/_build/prod/lib/bandit/.mix/compile.elixir deleted file mode 100644 index 6581b5c..0000000 Binary files a/_build/prod/lib/bandit/.mix/compile.elixir and /dev/null differ diff --git a/_build/prod/lib/bandit/.mix/compile.elixir_scm b/_build/prod/lib/bandit/.mix/compile.elixir_scm deleted file mode 100644 index 4066741..0000000 Binary files a/_build/prod/lib/bandit/.mix/compile.elixir_scm and /dev/null differ diff --git a/_build/prod/lib/bandit/ebin/Elixir.Bandit.Adapter.beam b/_build/prod/lib/bandit/ebin/Elixir.Bandit.Adapter.beam deleted file mode 100644 index 9dba560..0000000 Binary files a/_build/prod/lib/bandit/ebin/Elixir.Bandit.Adapter.beam and /dev/null differ diff --git a/_build/prod/lib/bandit/ebin/Elixir.Bandit.Application.beam b/_build/prod/lib/bandit/ebin/Elixir.Bandit.Application.beam deleted file mode 100644 index 8082cf4..0000000 Binary files a/_build/prod/lib/bandit/ebin/Elixir.Bandit.Application.beam and /dev/null differ diff --git a/_build/prod/lib/bandit/ebin/Elixir.Bandit.Clock.beam b/_build/prod/lib/bandit/ebin/Elixir.Bandit.Clock.beam deleted file mode 100644 index e38796e..0000000 Binary files a/_build/prod/lib/bandit/ebin/Elixir.Bandit.Clock.beam and /dev/null differ diff --git a/_build/prod/lib/bandit/ebin/Elixir.Bandit.Compression.beam b/_build/prod/lib/bandit/ebin/Elixir.Bandit.Compression.beam deleted file mode 100644 index b393a2e..0000000 Binary files a/_build/prod/lib/bandit/ebin/Elixir.Bandit.Compression.beam and /dev/null differ diff --git a/_build/prod/lib/bandit/ebin/Elixir.Bandit.DelegatingHandler.beam b/_build/prod/lib/bandit/ebin/Elixir.Bandit.DelegatingHandler.beam deleted file mode 100644 index f6f35eb..0000000 Binary files a/_build/prod/lib/bandit/ebin/Elixir.Bandit.DelegatingHandler.beam and /dev/null differ diff --git a/_build/prod/lib/bandit/ebin/Elixir.Bandit.Extractor.beam b/_build/prod/lib/bandit/ebin/Elixir.Bandit.Extractor.beam deleted file mode 100644 index df4718f..0000000 Binary files a/_build/prod/lib/bandit/ebin/Elixir.Bandit.Extractor.beam and /dev/null differ diff --git a/_build/prod/lib/bandit/ebin/Elixir.Bandit.HTTP1.Handler.beam b/_build/prod/lib/bandit/ebin/Elixir.Bandit.HTTP1.Handler.beam deleted file mode 100644 index 69a4dc8..0000000 Binary files a/_build/prod/lib/bandit/ebin/Elixir.Bandit.HTTP1.Handler.beam and /dev/null differ diff --git a/_build/prod/lib/bandit/ebin/Elixir.Bandit.HTTP1.Socket.beam b/_build/prod/lib/bandit/ebin/Elixir.Bandit.HTTP1.Socket.beam deleted file mode 100644 index 7d80651..0000000 Binary files a/_build/prod/lib/bandit/ebin/Elixir.Bandit.HTTP1.Socket.beam and /dev/null differ diff --git a/_build/prod/lib/bandit/ebin/Elixir.Bandit.HTTP2.Connection.beam b/_build/prod/lib/bandit/ebin/Elixir.Bandit.HTTP2.Connection.beam deleted file mode 100644 index 6af8ab7..0000000 Binary files a/_build/prod/lib/bandit/ebin/Elixir.Bandit.HTTP2.Connection.beam and /dev/null differ diff --git a/_build/prod/lib/bandit/ebin/Elixir.Bandit.HTTP2.Errors.ConnectionError.beam b/_build/prod/lib/bandit/ebin/Elixir.Bandit.HTTP2.Errors.ConnectionError.beam deleted file mode 100644 index 7d48f4f..0000000 Binary files a/_build/prod/lib/bandit/ebin/Elixir.Bandit.HTTP2.Errors.ConnectionError.beam and /dev/null differ diff --git a/_build/prod/lib/bandit/ebin/Elixir.Bandit.HTTP2.Errors.StreamError.beam b/_build/prod/lib/bandit/ebin/Elixir.Bandit.HTTP2.Errors.StreamError.beam deleted file mode 100644 index 4720588..0000000 Binary files a/_build/prod/lib/bandit/ebin/Elixir.Bandit.HTTP2.Errors.StreamError.beam and /dev/null differ diff --git a/_build/prod/lib/bandit/ebin/Elixir.Bandit.HTTP2.Errors.beam b/_build/prod/lib/bandit/ebin/Elixir.Bandit.HTTP2.Errors.beam deleted file mode 100644 index 499bb46..0000000 Binary files a/_build/prod/lib/bandit/ebin/Elixir.Bandit.HTTP2.Errors.beam and /dev/null differ diff --git a/_build/prod/lib/bandit/ebin/Elixir.Bandit.HTTP2.FlowControl.beam b/_build/prod/lib/bandit/ebin/Elixir.Bandit.HTTP2.FlowControl.beam deleted file mode 100644 index b9ce4f6..0000000 Binary files a/_build/prod/lib/bandit/ebin/Elixir.Bandit.HTTP2.FlowControl.beam and /dev/null differ diff --git a/_build/prod/lib/bandit/ebin/Elixir.Bandit.HTTP2.Frame.Continuation.beam b/_build/prod/lib/bandit/ebin/Elixir.Bandit.HTTP2.Frame.Continuation.beam deleted file mode 100644 index 2fd182d..0000000 Binary files a/_build/prod/lib/bandit/ebin/Elixir.Bandit.HTTP2.Frame.Continuation.beam and /dev/null differ diff --git a/_build/prod/lib/bandit/ebin/Elixir.Bandit.HTTP2.Frame.Data.beam b/_build/prod/lib/bandit/ebin/Elixir.Bandit.HTTP2.Frame.Data.beam deleted file mode 100644 index 20d1861..0000000 Binary files a/_build/prod/lib/bandit/ebin/Elixir.Bandit.HTTP2.Frame.Data.beam and /dev/null differ diff --git a/_build/prod/lib/bandit/ebin/Elixir.Bandit.HTTP2.Frame.Flags.beam b/_build/prod/lib/bandit/ebin/Elixir.Bandit.HTTP2.Frame.Flags.beam deleted file mode 100644 index df5ebb5..0000000 Binary files a/_build/prod/lib/bandit/ebin/Elixir.Bandit.HTTP2.Frame.Flags.beam and /dev/null differ diff --git a/_build/prod/lib/bandit/ebin/Elixir.Bandit.HTTP2.Frame.Goaway.beam b/_build/prod/lib/bandit/ebin/Elixir.Bandit.HTTP2.Frame.Goaway.beam deleted file mode 100644 index 270ba36..0000000 Binary files a/_build/prod/lib/bandit/ebin/Elixir.Bandit.HTTP2.Frame.Goaway.beam and /dev/null differ diff --git a/_build/prod/lib/bandit/ebin/Elixir.Bandit.HTTP2.Frame.Headers.beam b/_build/prod/lib/bandit/ebin/Elixir.Bandit.HTTP2.Frame.Headers.beam deleted file mode 100644 index 3ba1938..0000000 Binary files a/_build/prod/lib/bandit/ebin/Elixir.Bandit.HTTP2.Frame.Headers.beam and /dev/null differ diff --git a/_build/prod/lib/bandit/ebin/Elixir.Bandit.HTTP2.Frame.Ping.beam b/_build/prod/lib/bandit/ebin/Elixir.Bandit.HTTP2.Frame.Ping.beam deleted file mode 100644 index 4a6b576..0000000 Binary files a/_build/prod/lib/bandit/ebin/Elixir.Bandit.HTTP2.Frame.Ping.beam and /dev/null differ diff --git a/_build/prod/lib/bandit/ebin/Elixir.Bandit.HTTP2.Frame.Priority.beam b/_build/prod/lib/bandit/ebin/Elixir.Bandit.HTTP2.Frame.Priority.beam deleted file mode 100644 index 1343366..0000000 Binary files a/_build/prod/lib/bandit/ebin/Elixir.Bandit.HTTP2.Frame.Priority.beam and /dev/null differ diff --git a/_build/prod/lib/bandit/ebin/Elixir.Bandit.HTTP2.Frame.PushPromise.beam b/_build/prod/lib/bandit/ebin/Elixir.Bandit.HTTP2.Frame.PushPromise.beam deleted file mode 100644 index afacfb5..0000000 Binary files a/_build/prod/lib/bandit/ebin/Elixir.Bandit.HTTP2.Frame.PushPromise.beam and /dev/null differ diff --git a/_build/prod/lib/bandit/ebin/Elixir.Bandit.HTTP2.Frame.RstStream.beam b/_build/prod/lib/bandit/ebin/Elixir.Bandit.HTTP2.Frame.RstStream.beam deleted file mode 100644 index 772723b..0000000 Binary files a/_build/prod/lib/bandit/ebin/Elixir.Bandit.HTTP2.Frame.RstStream.beam and /dev/null differ diff --git a/_build/prod/lib/bandit/ebin/Elixir.Bandit.HTTP2.Frame.Serializable.Bandit.HTTP2.Frame.Continuation.beam b/_build/prod/lib/bandit/ebin/Elixir.Bandit.HTTP2.Frame.Serializable.Bandit.HTTP2.Frame.Continuation.beam deleted file mode 100644 index 796ebe1..0000000 Binary files a/_build/prod/lib/bandit/ebin/Elixir.Bandit.HTTP2.Frame.Serializable.Bandit.HTTP2.Frame.Continuation.beam and /dev/null differ diff --git a/_build/prod/lib/bandit/ebin/Elixir.Bandit.HTTP2.Frame.Serializable.Bandit.HTTP2.Frame.Data.beam b/_build/prod/lib/bandit/ebin/Elixir.Bandit.HTTP2.Frame.Serializable.Bandit.HTTP2.Frame.Data.beam deleted file mode 100644 index 25d4ee2..0000000 Binary files a/_build/prod/lib/bandit/ebin/Elixir.Bandit.HTTP2.Frame.Serializable.Bandit.HTTP2.Frame.Data.beam and /dev/null differ diff --git a/_build/prod/lib/bandit/ebin/Elixir.Bandit.HTTP2.Frame.Serializable.Bandit.HTTP2.Frame.Goaway.beam b/_build/prod/lib/bandit/ebin/Elixir.Bandit.HTTP2.Frame.Serializable.Bandit.HTTP2.Frame.Goaway.beam deleted file mode 100644 index 3dcaa50..0000000 Binary files a/_build/prod/lib/bandit/ebin/Elixir.Bandit.HTTP2.Frame.Serializable.Bandit.HTTP2.Frame.Goaway.beam and /dev/null differ diff --git a/_build/prod/lib/bandit/ebin/Elixir.Bandit.HTTP2.Frame.Serializable.Bandit.HTTP2.Frame.Headers.beam b/_build/prod/lib/bandit/ebin/Elixir.Bandit.HTTP2.Frame.Serializable.Bandit.HTTP2.Frame.Headers.beam deleted file mode 100644 index c47b41e..0000000 Binary files a/_build/prod/lib/bandit/ebin/Elixir.Bandit.HTTP2.Frame.Serializable.Bandit.HTTP2.Frame.Headers.beam and /dev/null differ diff --git a/_build/prod/lib/bandit/ebin/Elixir.Bandit.HTTP2.Frame.Serializable.Bandit.HTTP2.Frame.Ping.beam b/_build/prod/lib/bandit/ebin/Elixir.Bandit.HTTP2.Frame.Serializable.Bandit.HTTP2.Frame.Ping.beam deleted file mode 100644 index dcdc37d..0000000 Binary files a/_build/prod/lib/bandit/ebin/Elixir.Bandit.HTTP2.Frame.Serializable.Bandit.HTTP2.Frame.Ping.beam and /dev/null differ diff --git a/_build/prod/lib/bandit/ebin/Elixir.Bandit.HTTP2.Frame.Serializable.Bandit.HTTP2.Frame.Priority.beam b/_build/prod/lib/bandit/ebin/Elixir.Bandit.HTTP2.Frame.Serializable.Bandit.HTTP2.Frame.Priority.beam deleted file mode 100644 index 3fafc8a..0000000 Binary files a/_build/prod/lib/bandit/ebin/Elixir.Bandit.HTTP2.Frame.Serializable.Bandit.HTTP2.Frame.Priority.beam and /dev/null differ diff --git a/_build/prod/lib/bandit/ebin/Elixir.Bandit.HTTP2.Frame.Serializable.Bandit.HTTP2.Frame.RstStream.beam b/_build/prod/lib/bandit/ebin/Elixir.Bandit.HTTP2.Frame.Serializable.Bandit.HTTP2.Frame.RstStream.beam deleted file mode 100644 index f7e36ca..0000000 Binary files a/_build/prod/lib/bandit/ebin/Elixir.Bandit.HTTP2.Frame.Serializable.Bandit.HTTP2.Frame.RstStream.beam and /dev/null differ diff --git a/_build/prod/lib/bandit/ebin/Elixir.Bandit.HTTP2.Frame.Serializable.Bandit.HTTP2.Frame.Settings.beam b/_build/prod/lib/bandit/ebin/Elixir.Bandit.HTTP2.Frame.Serializable.Bandit.HTTP2.Frame.Settings.beam deleted file mode 100644 index dc2b3cd..0000000 Binary files a/_build/prod/lib/bandit/ebin/Elixir.Bandit.HTTP2.Frame.Serializable.Bandit.HTTP2.Frame.Settings.beam and /dev/null differ diff --git a/_build/prod/lib/bandit/ebin/Elixir.Bandit.HTTP2.Frame.Serializable.Bandit.HTTP2.Frame.WindowUpdate.beam b/_build/prod/lib/bandit/ebin/Elixir.Bandit.HTTP2.Frame.Serializable.Bandit.HTTP2.Frame.WindowUpdate.beam deleted file mode 100644 index d74297c..0000000 Binary files a/_build/prod/lib/bandit/ebin/Elixir.Bandit.HTTP2.Frame.Serializable.Bandit.HTTP2.Frame.WindowUpdate.beam and /dev/null differ diff --git a/_build/prod/lib/bandit/ebin/Elixir.Bandit.HTTP2.Frame.Serializable.beam b/_build/prod/lib/bandit/ebin/Elixir.Bandit.HTTP2.Frame.Serializable.beam deleted file mode 100644 index b5b4301..0000000 Binary files a/_build/prod/lib/bandit/ebin/Elixir.Bandit.HTTP2.Frame.Serializable.beam and /dev/null differ diff --git a/_build/prod/lib/bandit/ebin/Elixir.Bandit.HTTP2.Frame.Settings.beam b/_build/prod/lib/bandit/ebin/Elixir.Bandit.HTTP2.Frame.Settings.beam deleted file mode 100644 index a48a24b..0000000 Binary files a/_build/prod/lib/bandit/ebin/Elixir.Bandit.HTTP2.Frame.Settings.beam and /dev/null differ diff --git a/_build/prod/lib/bandit/ebin/Elixir.Bandit.HTTP2.Frame.Unknown.beam b/_build/prod/lib/bandit/ebin/Elixir.Bandit.HTTP2.Frame.Unknown.beam deleted file mode 100644 index a118760..0000000 Binary files a/_build/prod/lib/bandit/ebin/Elixir.Bandit.HTTP2.Frame.Unknown.beam and /dev/null differ diff --git a/_build/prod/lib/bandit/ebin/Elixir.Bandit.HTTP2.Frame.WindowUpdate.beam b/_build/prod/lib/bandit/ebin/Elixir.Bandit.HTTP2.Frame.WindowUpdate.beam deleted file mode 100644 index 22ae2f3..0000000 Binary files a/_build/prod/lib/bandit/ebin/Elixir.Bandit.HTTP2.Frame.WindowUpdate.beam and /dev/null differ diff --git a/_build/prod/lib/bandit/ebin/Elixir.Bandit.HTTP2.Frame.beam b/_build/prod/lib/bandit/ebin/Elixir.Bandit.HTTP2.Frame.beam deleted file mode 100644 index ff22d55..0000000 Binary files a/_build/prod/lib/bandit/ebin/Elixir.Bandit.HTTP2.Frame.beam and /dev/null differ diff --git a/_build/prod/lib/bandit/ebin/Elixir.Bandit.HTTP2.Handler.beam b/_build/prod/lib/bandit/ebin/Elixir.Bandit.HTTP2.Handler.beam deleted file mode 100644 index f42f160..0000000 Binary files a/_build/prod/lib/bandit/ebin/Elixir.Bandit.HTTP2.Handler.beam and /dev/null differ diff --git a/_build/prod/lib/bandit/ebin/Elixir.Bandit.HTTP2.Settings.beam b/_build/prod/lib/bandit/ebin/Elixir.Bandit.HTTP2.Settings.beam deleted file mode 100644 index 63623c4..0000000 Binary files a/_build/prod/lib/bandit/ebin/Elixir.Bandit.HTTP2.Settings.beam and /dev/null differ diff --git a/_build/prod/lib/bandit/ebin/Elixir.Bandit.HTTP2.Stream.beam b/_build/prod/lib/bandit/ebin/Elixir.Bandit.HTTP2.Stream.beam deleted file mode 100644 index fc39f03..0000000 Binary files a/_build/prod/lib/bandit/ebin/Elixir.Bandit.HTTP2.Stream.beam and /dev/null differ diff --git a/_build/prod/lib/bandit/ebin/Elixir.Bandit.HTTP2.StreamCollection.beam b/_build/prod/lib/bandit/ebin/Elixir.Bandit.HTTP2.StreamCollection.beam deleted file mode 100644 index 32fe830..0000000 Binary files a/_build/prod/lib/bandit/ebin/Elixir.Bandit.HTTP2.StreamCollection.beam and /dev/null differ diff --git a/_build/prod/lib/bandit/ebin/Elixir.Bandit.HTTP2.StreamProcess.beam b/_build/prod/lib/bandit/ebin/Elixir.Bandit.HTTP2.StreamProcess.beam deleted file mode 100644 index 8207fe1..0000000 Binary files a/_build/prod/lib/bandit/ebin/Elixir.Bandit.HTTP2.StreamProcess.beam and /dev/null differ diff --git a/_build/prod/lib/bandit/ebin/Elixir.Bandit.HTTPError.beam b/_build/prod/lib/bandit/ebin/Elixir.Bandit.HTTPError.beam deleted file mode 100644 index 772d948..0000000 Binary files a/_build/prod/lib/bandit/ebin/Elixir.Bandit.HTTPError.beam and /dev/null differ diff --git a/_build/prod/lib/bandit/ebin/Elixir.Bandit.HTTPTransport.Bandit.HTTP1.Socket.beam b/_build/prod/lib/bandit/ebin/Elixir.Bandit.HTTPTransport.Bandit.HTTP1.Socket.beam deleted file mode 100644 index f0c50ec..0000000 Binary files a/_build/prod/lib/bandit/ebin/Elixir.Bandit.HTTPTransport.Bandit.HTTP1.Socket.beam and /dev/null differ diff --git a/_build/prod/lib/bandit/ebin/Elixir.Bandit.HTTPTransport.Bandit.HTTP2.Stream.beam b/_build/prod/lib/bandit/ebin/Elixir.Bandit.HTTPTransport.Bandit.HTTP2.Stream.beam deleted file mode 100644 index 46ebb3b..0000000 Binary files a/_build/prod/lib/bandit/ebin/Elixir.Bandit.HTTPTransport.Bandit.HTTP2.Stream.beam and /dev/null differ diff --git a/_build/prod/lib/bandit/ebin/Elixir.Bandit.HTTPTransport.beam b/_build/prod/lib/bandit/ebin/Elixir.Bandit.HTTPTransport.beam deleted file mode 100644 index f1929ba..0000000 Binary files a/_build/prod/lib/bandit/ebin/Elixir.Bandit.HTTPTransport.beam and /dev/null differ diff --git a/_build/prod/lib/bandit/ebin/Elixir.Bandit.Headers.beam b/_build/prod/lib/bandit/ebin/Elixir.Bandit.Headers.beam deleted file mode 100644 index 09bac73..0000000 Binary files a/_build/prod/lib/bandit/ebin/Elixir.Bandit.Headers.beam and /dev/null differ diff --git a/_build/prod/lib/bandit/ebin/Elixir.Bandit.InitialHandler.beam b/_build/prod/lib/bandit/ebin/Elixir.Bandit.InitialHandler.beam deleted file mode 100644 index 94bd216..0000000 Binary files a/_build/prod/lib/bandit/ebin/Elixir.Bandit.InitialHandler.beam and /dev/null differ diff --git a/_build/prod/lib/bandit/ebin/Elixir.Bandit.Logger.beam b/_build/prod/lib/bandit/ebin/Elixir.Bandit.Logger.beam deleted file mode 100644 index 7e70a01..0000000 Binary files a/_build/prod/lib/bandit/ebin/Elixir.Bandit.Logger.beam and /dev/null differ diff --git a/_build/prod/lib/bandit/ebin/Elixir.Bandit.PhoenixAdapter.beam b/_build/prod/lib/bandit/ebin/Elixir.Bandit.PhoenixAdapter.beam deleted file mode 100644 index 02c8f02..0000000 Binary files a/_build/prod/lib/bandit/ebin/Elixir.Bandit.PhoenixAdapter.beam and /dev/null differ diff --git a/_build/prod/lib/bandit/ebin/Elixir.Bandit.Pipeline.beam b/_build/prod/lib/bandit/ebin/Elixir.Bandit.Pipeline.beam deleted file mode 100644 index dc973b5..0000000 Binary files a/_build/prod/lib/bandit/ebin/Elixir.Bandit.Pipeline.beam and /dev/null differ diff --git a/_build/prod/lib/bandit/ebin/Elixir.Bandit.PrimitiveOps.WebSocket.beam b/_build/prod/lib/bandit/ebin/Elixir.Bandit.PrimitiveOps.WebSocket.beam deleted file mode 100644 index 033222f..0000000 Binary files a/_build/prod/lib/bandit/ebin/Elixir.Bandit.PrimitiveOps.WebSocket.beam and /dev/null differ diff --git a/_build/prod/lib/bandit/ebin/Elixir.Bandit.SocketHelpers.beam b/_build/prod/lib/bandit/ebin/Elixir.Bandit.SocketHelpers.beam deleted file mode 100644 index 76a2405..0000000 Binary files a/_build/prod/lib/bandit/ebin/Elixir.Bandit.SocketHelpers.beam and /dev/null differ diff --git a/_build/prod/lib/bandit/ebin/Elixir.Bandit.Telemetry.beam b/_build/prod/lib/bandit/ebin/Elixir.Bandit.Telemetry.beam deleted file mode 100644 index 2190d40..0000000 Binary files a/_build/prod/lib/bandit/ebin/Elixir.Bandit.Telemetry.beam and /dev/null differ diff --git a/_build/prod/lib/bandit/ebin/Elixir.Bandit.Trace.beam b/_build/prod/lib/bandit/ebin/Elixir.Bandit.Trace.beam deleted file mode 100644 index 2cbb111..0000000 Binary files a/_build/prod/lib/bandit/ebin/Elixir.Bandit.Trace.beam and /dev/null differ diff --git a/_build/prod/lib/bandit/ebin/Elixir.Bandit.TransportError.beam b/_build/prod/lib/bandit/ebin/Elixir.Bandit.TransportError.beam deleted file mode 100644 index 8e9b5bc..0000000 Binary files a/_build/prod/lib/bandit/ebin/Elixir.Bandit.TransportError.beam and /dev/null differ diff --git a/_build/prod/lib/bandit/ebin/Elixir.Bandit.WebSocket.Connection.beam b/_build/prod/lib/bandit/ebin/Elixir.Bandit.WebSocket.Connection.beam deleted file mode 100644 index 7a57a23..0000000 Binary files a/_build/prod/lib/bandit/ebin/Elixir.Bandit.WebSocket.Connection.beam and /dev/null differ diff --git a/_build/prod/lib/bandit/ebin/Elixir.Bandit.WebSocket.Frame.Binary.beam b/_build/prod/lib/bandit/ebin/Elixir.Bandit.WebSocket.Frame.Binary.beam deleted file mode 100644 index ff23ad3..0000000 Binary files a/_build/prod/lib/bandit/ebin/Elixir.Bandit.WebSocket.Frame.Binary.beam and /dev/null differ diff --git a/_build/prod/lib/bandit/ebin/Elixir.Bandit.WebSocket.Frame.ConnectionClose.beam b/_build/prod/lib/bandit/ebin/Elixir.Bandit.WebSocket.Frame.ConnectionClose.beam deleted file mode 100644 index 1a70f9e..0000000 Binary files a/_build/prod/lib/bandit/ebin/Elixir.Bandit.WebSocket.Frame.ConnectionClose.beam and /dev/null differ diff --git a/_build/prod/lib/bandit/ebin/Elixir.Bandit.WebSocket.Frame.Continuation.beam b/_build/prod/lib/bandit/ebin/Elixir.Bandit.WebSocket.Frame.Continuation.beam deleted file mode 100644 index 7823a49..0000000 Binary files a/_build/prod/lib/bandit/ebin/Elixir.Bandit.WebSocket.Frame.Continuation.beam and /dev/null differ diff --git a/_build/prod/lib/bandit/ebin/Elixir.Bandit.WebSocket.Frame.Ping.beam b/_build/prod/lib/bandit/ebin/Elixir.Bandit.WebSocket.Frame.Ping.beam deleted file mode 100644 index c94504d..0000000 Binary files a/_build/prod/lib/bandit/ebin/Elixir.Bandit.WebSocket.Frame.Ping.beam and /dev/null differ diff --git a/_build/prod/lib/bandit/ebin/Elixir.Bandit.WebSocket.Frame.Pong.beam b/_build/prod/lib/bandit/ebin/Elixir.Bandit.WebSocket.Frame.Pong.beam deleted file mode 100644 index 39bfb45..0000000 Binary files a/_build/prod/lib/bandit/ebin/Elixir.Bandit.WebSocket.Frame.Pong.beam and /dev/null differ diff --git a/_build/prod/lib/bandit/ebin/Elixir.Bandit.WebSocket.Frame.Serializable.Bandit.WebSocket.Frame.Binary.beam b/_build/prod/lib/bandit/ebin/Elixir.Bandit.WebSocket.Frame.Serializable.Bandit.WebSocket.Frame.Binary.beam deleted file mode 100644 index 90b70da..0000000 Binary files a/_build/prod/lib/bandit/ebin/Elixir.Bandit.WebSocket.Frame.Serializable.Bandit.WebSocket.Frame.Binary.beam and /dev/null differ diff --git a/_build/prod/lib/bandit/ebin/Elixir.Bandit.WebSocket.Frame.Serializable.Bandit.WebSocket.Frame.ConnectionClose.beam b/_build/prod/lib/bandit/ebin/Elixir.Bandit.WebSocket.Frame.Serializable.Bandit.WebSocket.Frame.ConnectionClose.beam deleted file mode 100644 index 0de4a89..0000000 Binary files a/_build/prod/lib/bandit/ebin/Elixir.Bandit.WebSocket.Frame.Serializable.Bandit.WebSocket.Frame.ConnectionClose.beam and /dev/null differ diff --git a/_build/prod/lib/bandit/ebin/Elixir.Bandit.WebSocket.Frame.Serializable.Bandit.WebSocket.Frame.Continuation.beam b/_build/prod/lib/bandit/ebin/Elixir.Bandit.WebSocket.Frame.Serializable.Bandit.WebSocket.Frame.Continuation.beam deleted file mode 100644 index 866767d..0000000 Binary files a/_build/prod/lib/bandit/ebin/Elixir.Bandit.WebSocket.Frame.Serializable.Bandit.WebSocket.Frame.Continuation.beam and /dev/null differ diff --git a/_build/prod/lib/bandit/ebin/Elixir.Bandit.WebSocket.Frame.Serializable.Bandit.WebSocket.Frame.Ping.beam b/_build/prod/lib/bandit/ebin/Elixir.Bandit.WebSocket.Frame.Serializable.Bandit.WebSocket.Frame.Ping.beam deleted file mode 100644 index a9041f2..0000000 Binary files a/_build/prod/lib/bandit/ebin/Elixir.Bandit.WebSocket.Frame.Serializable.Bandit.WebSocket.Frame.Ping.beam and /dev/null differ diff --git a/_build/prod/lib/bandit/ebin/Elixir.Bandit.WebSocket.Frame.Serializable.Bandit.WebSocket.Frame.Pong.beam b/_build/prod/lib/bandit/ebin/Elixir.Bandit.WebSocket.Frame.Serializable.Bandit.WebSocket.Frame.Pong.beam deleted file mode 100644 index 83a58c2..0000000 Binary files a/_build/prod/lib/bandit/ebin/Elixir.Bandit.WebSocket.Frame.Serializable.Bandit.WebSocket.Frame.Pong.beam and /dev/null differ diff --git a/_build/prod/lib/bandit/ebin/Elixir.Bandit.WebSocket.Frame.Serializable.Bandit.WebSocket.Frame.Text.beam b/_build/prod/lib/bandit/ebin/Elixir.Bandit.WebSocket.Frame.Serializable.Bandit.WebSocket.Frame.Text.beam deleted file mode 100644 index 8409645..0000000 Binary files a/_build/prod/lib/bandit/ebin/Elixir.Bandit.WebSocket.Frame.Serializable.Bandit.WebSocket.Frame.Text.beam and /dev/null differ diff --git a/_build/prod/lib/bandit/ebin/Elixir.Bandit.WebSocket.Frame.Serializable.beam b/_build/prod/lib/bandit/ebin/Elixir.Bandit.WebSocket.Frame.Serializable.beam deleted file mode 100644 index 351d03d..0000000 Binary files a/_build/prod/lib/bandit/ebin/Elixir.Bandit.WebSocket.Frame.Serializable.beam and /dev/null differ diff --git a/_build/prod/lib/bandit/ebin/Elixir.Bandit.WebSocket.Frame.Text.beam b/_build/prod/lib/bandit/ebin/Elixir.Bandit.WebSocket.Frame.Text.beam deleted file mode 100644 index dbc31c2..0000000 Binary files a/_build/prod/lib/bandit/ebin/Elixir.Bandit.WebSocket.Frame.Text.beam and /dev/null differ diff --git a/_build/prod/lib/bandit/ebin/Elixir.Bandit.WebSocket.Frame.beam b/_build/prod/lib/bandit/ebin/Elixir.Bandit.WebSocket.Frame.beam deleted file mode 100644 index 555219c..0000000 Binary files a/_build/prod/lib/bandit/ebin/Elixir.Bandit.WebSocket.Frame.beam and /dev/null differ diff --git a/_build/prod/lib/bandit/ebin/Elixir.Bandit.WebSocket.Handler.beam b/_build/prod/lib/bandit/ebin/Elixir.Bandit.WebSocket.Handler.beam deleted file mode 100644 index 56fb548..0000000 Binary files a/_build/prod/lib/bandit/ebin/Elixir.Bandit.WebSocket.Handler.beam and /dev/null differ diff --git a/_build/prod/lib/bandit/ebin/Elixir.Bandit.WebSocket.Handshake.beam b/_build/prod/lib/bandit/ebin/Elixir.Bandit.WebSocket.Handshake.beam deleted file mode 100644 index eb53639..0000000 Binary files a/_build/prod/lib/bandit/ebin/Elixir.Bandit.WebSocket.Handshake.beam and /dev/null differ diff --git a/_build/prod/lib/bandit/ebin/Elixir.Bandit.WebSocket.PerMessageDeflate.beam b/_build/prod/lib/bandit/ebin/Elixir.Bandit.WebSocket.PerMessageDeflate.beam deleted file mode 100644 index 95a46b5..0000000 Binary files a/_build/prod/lib/bandit/ebin/Elixir.Bandit.WebSocket.PerMessageDeflate.beam and /dev/null differ diff --git a/_build/prod/lib/bandit/ebin/Elixir.Bandit.WebSocket.Socket.ThousandIsland.Socket.beam b/_build/prod/lib/bandit/ebin/Elixir.Bandit.WebSocket.Socket.ThousandIsland.Socket.beam deleted file mode 100644 index cb44c9d..0000000 Binary files a/_build/prod/lib/bandit/ebin/Elixir.Bandit.WebSocket.Socket.ThousandIsland.Socket.beam and /dev/null differ diff --git a/_build/prod/lib/bandit/ebin/Elixir.Bandit.WebSocket.Socket.beam b/_build/prod/lib/bandit/ebin/Elixir.Bandit.WebSocket.Socket.beam deleted file mode 100644 index 9957acc..0000000 Binary files a/_build/prod/lib/bandit/ebin/Elixir.Bandit.WebSocket.Socket.beam and /dev/null differ diff --git a/_build/prod/lib/bandit/ebin/Elixir.Bandit.WebSocket.UpgradeValidation.beam b/_build/prod/lib/bandit/ebin/Elixir.Bandit.WebSocket.UpgradeValidation.beam deleted file mode 100644 index c1dd155..0000000 Binary files a/_build/prod/lib/bandit/ebin/Elixir.Bandit.WebSocket.UpgradeValidation.beam and /dev/null differ diff --git a/_build/prod/lib/bandit/ebin/Elixir.Bandit.beam b/_build/prod/lib/bandit/ebin/Elixir.Bandit.beam deleted file mode 100644 index 57e93c7..0000000 Binary files a/_build/prod/lib/bandit/ebin/Elixir.Bandit.beam and /dev/null differ diff --git a/_build/prod/lib/bandit/ebin/bandit.app b/_build/prod/lib/bandit/ebin/bandit.app deleted file mode 100644 index 5cfd6d3..0000000 --- a/_build/prod/lib/bandit/ebin/bandit.app +++ /dev/null @@ -1 +0,0 @@ -{application,bandit,[{modules,['Elixir.Bandit','Elixir.Bandit.Adapter','Elixir.Bandit.Application','Elixir.Bandit.Clock','Elixir.Bandit.Compression','Elixir.Bandit.DelegatingHandler','Elixir.Bandit.Extractor','Elixir.Bandit.HTTP1.Handler','Elixir.Bandit.HTTP1.Socket','Elixir.Bandit.HTTP2.Connection','Elixir.Bandit.HTTP2.Errors','Elixir.Bandit.HTTP2.Errors.ConnectionError','Elixir.Bandit.HTTP2.Errors.StreamError','Elixir.Bandit.HTTP2.FlowControl','Elixir.Bandit.HTTP2.Frame','Elixir.Bandit.HTTP2.Frame.Continuation','Elixir.Bandit.HTTP2.Frame.Data','Elixir.Bandit.HTTP2.Frame.Flags','Elixir.Bandit.HTTP2.Frame.Goaway','Elixir.Bandit.HTTP2.Frame.Headers','Elixir.Bandit.HTTP2.Frame.Ping','Elixir.Bandit.HTTP2.Frame.Priority','Elixir.Bandit.HTTP2.Frame.PushPromise','Elixir.Bandit.HTTP2.Frame.RstStream','Elixir.Bandit.HTTP2.Frame.Serializable','Elixir.Bandit.HTTP2.Frame.Serializable.Bandit.HTTP2.Frame.Continuation','Elixir.Bandit.HTTP2.Frame.Serializable.Bandit.HTTP2.Frame.Data','Elixir.Bandit.HTTP2.Frame.Serializable.Bandit.HTTP2.Frame.Goaway','Elixir.Bandit.HTTP2.Frame.Serializable.Bandit.HTTP2.Frame.Headers','Elixir.Bandit.HTTP2.Frame.Serializable.Bandit.HTTP2.Frame.Ping','Elixir.Bandit.HTTP2.Frame.Serializable.Bandit.HTTP2.Frame.Priority','Elixir.Bandit.HTTP2.Frame.Serializable.Bandit.HTTP2.Frame.RstStream','Elixir.Bandit.HTTP2.Frame.Serializable.Bandit.HTTP2.Frame.Settings','Elixir.Bandit.HTTP2.Frame.Serializable.Bandit.HTTP2.Frame.WindowUpdate','Elixir.Bandit.HTTP2.Frame.Settings','Elixir.Bandit.HTTP2.Frame.Unknown','Elixir.Bandit.HTTP2.Frame.WindowUpdate','Elixir.Bandit.HTTP2.Handler','Elixir.Bandit.HTTP2.Settings','Elixir.Bandit.HTTP2.Stream','Elixir.Bandit.HTTP2.StreamCollection','Elixir.Bandit.HTTP2.StreamProcess','Elixir.Bandit.HTTPError','Elixir.Bandit.HTTPTransport','Elixir.Bandit.HTTPTransport.Bandit.HTTP1.Socket','Elixir.Bandit.HTTPTransport.Bandit.HTTP2.Stream','Elixir.Bandit.Headers','Elixir.Bandit.InitialHandler','Elixir.Bandit.Logger','Elixir.Bandit.PhoenixAdapter','Elixir.Bandit.Pipeline','Elixir.Bandit.PrimitiveOps.WebSocket','Elixir.Bandit.SocketHelpers','Elixir.Bandit.Telemetry','Elixir.Bandit.Trace','Elixir.Bandit.TransportError','Elixir.Bandit.WebSocket.Connection','Elixir.Bandit.WebSocket.Frame','Elixir.Bandit.WebSocket.Frame.Binary','Elixir.Bandit.WebSocket.Frame.ConnectionClose','Elixir.Bandit.WebSocket.Frame.Continuation','Elixir.Bandit.WebSocket.Frame.Ping','Elixir.Bandit.WebSocket.Frame.Pong','Elixir.Bandit.WebSocket.Frame.Serializable','Elixir.Bandit.WebSocket.Frame.Serializable.Bandit.WebSocket.Frame.Binary','Elixir.Bandit.WebSocket.Frame.Serializable.Bandit.WebSocket.Frame.ConnectionClose','Elixir.Bandit.WebSocket.Frame.Serializable.Bandit.WebSocket.Frame.Continuation','Elixir.Bandit.WebSocket.Frame.Serializable.Bandit.WebSocket.Frame.Ping','Elixir.Bandit.WebSocket.Frame.Serializable.Bandit.WebSocket.Frame.Pong','Elixir.Bandit.WebSocket.Frame.Serializable.Bandit.WebSocket.Frame.Text','Elixir.Bandit.WebSocket.Frame.Text','Elixir.Bandit.WebSocket.Handler','Elixir.Bandit.WebSocket.Handshake','Elixir.Bandit.WebSocket.PerMessageDeflate','Elixir.Bandit.WebSocket.Socket','Elixir.Bandit.WebSocket.Socket.ThousandIsland.Socket','Elixir.Bandit.WebSocket.UpgradeValidation']},{optional_applications,[]},{applications,[kernel,stdlib,elixir,logger,thousand_island,plug,websock,hpax,telemetry]},{description,"A pure-Elixir HTTP server built for Plug & WebSock apps"},{registered,[]},{vsn,"1.10.3"},{mod,{'Elixir.Bandit.Application',[]}}]}. \ No newline at end of file diff --git a/_build/prod/lib/hpax/.mix/compile.elixir b/_build/prod/lib/hpax/.mix/compile.elixir deleted file mode 100644 index a4784d7..0000000 Binary files a/_build/prod/lib/hpax/.mix/compile.elixir and /dev/null differ diff --git a/_build/prod/lib/hpax/.mix/compile.elixir_scm b/_build/prod/lib/hpax/.mix/compile.elixir_scm deleted file mode 100644 index 4066741..0000000 Binary files a/_build/prod/lib/hpax/.mix/compile.elixir_scm and /dev/null differ diff --git a/_build/prod/lib/hpax/ebin/Elixir.HPAX.Huffman.beam b/_build/prod/lib/hpax/ebin/Elixir.HPAX.Huffman.beam deleted file mode 100644 index f06d6df..0000000 Binary files a/_build/prod/lib/hpax/ebin/Elixir.HPAX.Huffman.beam and /dev/null differ diff --git a/_build/prod/lib/hpax/ebin/Elixir.HPAX.Table.beam b/_build/prod/lib/hpax/ebin/Elixir.HPAX.Table.beam deleted file mode 100644 index f5c44c8..0000000 Binary files a/_build/prod/lib/hpax/ebin/Elixir.HPAX.Table.beam and /dev/null differ diff --git a/_build/prod/lib/hpax/ebin/Elixir.HPAX.Types.beam b/_build/prod/lib/hpax/ebin/Elixir.HPAX.Types.beam deleted file mode 100644 index d8bdeae..0000000 Binary files a/_build/prod/lib/hpax/ebin/Elixir.HPAX.Types.beam and /dev/null differ diff --git a/_build/prod/lib/hpax/ebin/Elixir.HPAX.beam b/_build/prod/lib/hpax/ebin/Elixir.HPAX.beam deleted file mode 100644 index ad75910..0000000 Binary files a/_build/prod/lib/hpax/ebin/Elixir.HPAX.beam and /dev/null differ diff --git a/_build/prod/lib/hpax/ebin/hpax.app b/_build/prod/lib/hpax/ebin/hpax.app deleted file mode 100644 index d514d1e..0000000 --- a/_build/prod/lib/hpax/ebin/hpax.app +++ /dev/null @@ -1 +0,0 @@ -{application,hpax,[{modules,['Elixir.HPAX','Elixir.HPAX.Huffman','Elixir.HPAX.Table','Elixir.HPAX.Types']},{optional_applications,[]},{applications,[kernel,stdlib,elixir]},{description,"Implementation of the HPACK protocol (RFC 7541) for Elixir"},{registered,[]},{vsn,"1.0.3"}]}. \ No newline at end of file diff --git a/_build/prod/lib/jason/.mix/compile.elixir b/_build/prod/lib/jason/.mix/compile.elixir deleted file mode 100644 index 3ec121f..0000000 Binary files a/_build/prod/lib/jason/.mix/compile.elixir and /dev/null differ diff --git a/_build/prod/lib/jason/.mix/compile.elixir_scm b/_build/prod/lib/jason/.mix/compile.elixir_scm deleted file mode 100644 index 4066741..0000000 Binary files a/_build/prod/lib/jason/.mix/compile.elixir_scm and /dev/null differ diff --git a/_build/prod/lib/jason/ebin/Elixir.Enumerable.Jason.OrderedObject.beam b/_build/prod/lib/jason/ebin/Elixir.Enumerable.Jason.OrderedObject.beam deleted file mode 100644 index 7099c0e..0000000 Binary files a/_build/prod/lib/jason/ebin/Elixir.Enumerable.Jason.OrderedObject.beam and /dev/null differ diff --git a/_build/prod/lib/jason/ebin/Elixir.Jason.Codegen.beam b/_build/prod/lib/jason/ebin/Elixir.Jason.Codegen.beam deleted file mode 100644 index 0e0221c..0000000 Binary files a/_build/prod/lib/jason/ebin/Elixir.Jason.Codegen.beam and /dev/null differ diff --git a/_build/prod/lib/jason/ebin/Elixir.Jason.DecodeError.beam b/_build/prod/lib/jason/ebin/Elixir.Jason.DecodeError.beam deleted file mode 100644 index ce29c2e..0000000 Binary files a/_build/prod/lib/jason/ebin/Elixir.Jason.DecodeError.beam and /dev/null differ diff --git a/_build/prod/lib/jason/ebin/Elixir.Jason.Decoder.Unescape.beam b/_build/prod/lib/jason/ebin/Elixir.Jason.Decoder.Unescape.beam deleted file mode 100644 index 083597a..0000000 Binary files a/_build/prod/lib/jason/ebin/Elixir.Jason.Decoder.Unescape.beam and /dev/null differ diff --git a/_build/prod/lib/jason/ebin/Elixir.Jason.Decoder.beam b/_build/prod/lib/jason/ebin/Elixir.Jason.Decoder.beam deleted file mode 100644 index dc463be..0000000 Binary files a/_build/prod/lib/jason/ebin/Elixir.Jason.Decoder.beam and /dev/null differ diff --git a/_build/prod/lib/jason/ebin/Elixir.Jason.Encode.beam b/_build/prod/lib/jason/ebin/Elixir.Jason.Encode.beam deleted file mode 100644 index 3519fdc..0000000 Binary files a/_build/prod/lib/jason/ebin/Elixir.Jason.Encode.beam and /dev/null differ diff --git a/_build/prod/lib/jason/ebin/Elixir.Jason.EncodeError.beam b/_build/prod/lib/jason/ebin/Elixir.Jason.EncodeError.beam deleted file mode 100644 index d694656..0000000 Binary files a/_build/prod/lib/jason/ebin/Elixir.Jason.EncodeError.beam and /dev/null differ diff --git a/_build/prod/lib/jason/ebin/Elixir.Jason.Encoder.Any.beam b/_build/prod/lib/jason/ebin/Elixir.Jason.Encoder.Any.beam deleted file mode 100644 index e752fd3..0000000 Binary files a/_build/prod/lib/jason/ebin/Elixir.Jason.Encoder.Any.beam and /dev/null differ diff --git a/_build/prod/lib/jason/ebin/Elixir.Jason.Encoder.Atom.beam b/_build/prod/lib/jason/ebin/Elixir.Jason.Encoder.Atom.beam deleted file mode 100644 index 9420f1a..0000000 Binary files a/_build/prod/lib/jason/ebin/Elixir.Jason.Encoder.Atom.beam and /dev/null differ diff --git a/_build/prod/lib/jason/ebin/Elixir.Jason.Encoder.BitString.beam b/_build/prod/lib/jason/ebin/Elixir.Jason.Encoder.BitString.beam deleted file mode 100644 index ba4448d..0000000 Binary files a/_build/prod/lib/jason/ebin/Elixir.Jason.Encoder.BitString.beam and /dev/null differ diff --git a/_build/prod/lib/jason/ebin/Elixir.Jason.Encoder.Date.beam b/_build/prod/lib/jason/ebin/Elixir.Jason.Encoder.Date.beam deleted file mode 100644 index 4e5b6a6..0000000 Binary files a/_build/prod/lib/jason/ebin/Elixir.Jason.Encoder.Date.beam and /dev/null differ diff --git a/_build/prod/lib/jason/ebin/Elixir.Jason.Encoder.DateTime.beam b/_build/prod/lib/jason/ebin/Elixir.Jason.Encoder.DateTime.beam deleted file mode 100644 index eeba8c3..0000000 Binary files a/_build/prod/lib/jason/ebin/Elixir.Jason.Encoder.DateTime.beam and /dev/null differ diff --git a/_build/prod/lib/jason/ebin/Elixir.Jason.Encoder.Float.beam b/_build/prod/lib/jason/ebin/Elixir.Jason.Encoder.Float.beam deleted file mode 100644 index 49bfc5b..0000000 Binary files a/_build/prod/lib/jason/ebin/Elixir.Jason.Encoder.Float.beam and /dev/null differ diff --git a/_build/prod/lib/jason/ebin/Elixir.Jason.Encoder.Integer.beam b/_build/prod/lib/jason/ebin/Elixir.Jason.Encoder.Integer.beam deleted file mode 100644 index 438e32e..0000000 Binary files a/_build/prod/lib/jason/ebin/Elixir.Jason.Encoder.Integer.beam and /dev/null differ diff --git a/_build/prod/lib/jason/ebin/Elixir.Jason.Encoder.Jason.Fragment.beam b/_build/prod/lib/jason/ebin/Elixir.Jason.Encoder.Jason.Fragment.beam deleted file mode 100644 index b6f47fa..0000000 Binary files a/_build/prod/lib/jason/ebin/Elixir.Jason.Encoder.Jason.Fragment.beam and /dev/null differ diff --git a/_build/prod/lib/jason/ebin/Elixir.Jason.Encoder.Jason.OrderedObject.beam b/_build/prod/lib/jason/ebin/Elixir.Jason.Encoder.Jason.OrderedObject.beam deleted file mode 100644 index a5941e4..0000000 Binary files a/_build/prod/lib/jason/ebin/Elixir.Jason.Encoder.Jason.OrderedObject.beam and /dev/null differ diff --git a/_build/prod/lib/jason/ebin/Elixir.Jason.Encoder.List.beam b/_build/prod/lib/jason/ebin/Elixir.Jason.Encoder.List.beam deleted file mode 100644 index d3bbec9..0000000 Binary files a/_build/prod/lib/jason/ebin/Elixir.Jason.Encoder.List.beam and /dev/null differ diff --git a/_build/prod/lib/jason/ebin/Elixir.Jason.Encoder.Map.beam b/_build/prod/lib/jason/ebin/Elixir.Jason.Encoder.Map.beam deleted file mode 100644 index c0397c9..0000000 Binary files a/_build/prod/lib/jason/ebin/Elixir.Jason.Encoder.Map.beam and /dev/null differ diff --git a/_build/prod/lib/jason/ebin/Elixir.Jason.Encoder.NaiveDateTime.beam b/_build/prod/lib/jason/ebin/Elixir.Jason.Encoder.NaiveDateTime.beam deleted file mode 100644 index 2ad5ed0..0000000 Binary files a/_build/prod/lib/jason/ebin/Elixir.Jason.Encoder.NaiveDateTime.beam and /dev/null differ diff --git a/_build/prod/lib/jason/ebin/Elixir.Jason.Encoder.Time.beam b/_build/prod/lib/jason/ebin/Elixir.Jason.Encoder.Time.beam deleted file mode 100644 index b3408c1..0000000 Binary files a/_build/prod/lib/jason/ebin/Elixir.Jason.Encoder.Time.beam and /dev/null differ diff --git a/_build/prod/lib/jason/ebin/Elixir.Jason.Encoder.beam b/_build/prod/lib/jason/ebin/Elixir.Jason.Encoder.beam deleted file mode 100644 index 8109bf1..0000000 Binary files a/_build/prod/lib/jason/ebin/Elixir.Jason.Encoder.beam and /dev/null differ diff --git a/_build/prod/lib/jason/ebin/Elixir.Jason.Formatter.beam b/_build/prod/lib/jason/ebin/Elixir.Jason.Formatter.beam deleted file mode 100644 index 76e7fdd..0000000 Binary files a/_build/prod/lib/jason/ebin/Elixir.Jason.Formatter.beam and /dev/null differ diff --git a/_build/prod/lib/jason/ebin/Elixir.Jason.Fragment.beam b/_build/prod/lib/jason/ebin/Elixir.Jason.Fragment.beam deleted file mode 100644 index 0c3db6f..0000000 Binary files a/_build/prod/lib/jason/ebin/Elixir.Jason.Fragment.beam and /dev/null differ diff --git a/_build/prod/lib/jason/ebin/Elixir.Jason.Helpers.beam b/_build/prod/lib/jason/ebin/Elixir.Jason.Helpers.beam deleted file mode 100644 index 1d136f7..0000000 Binary files a/_build/prod/lib/jason/ebin/Elixir.Jason.Helpers.beam and /dev/null differ diff --git a/_build/prod/lib/jason/ebin/Elixir.Jason.OrderedObject.beam b/_build/prod/lib/jason/ebin/Elixir.Jason.OrderedObject.beam deleted file mode 100644 index 3bd0da3..0000000 Binary files a/_build/prod/lib/jason/ebin/Elixir.Jason.OrderedObject.beam and /dev/null differ diff --git a/_build/prod/lib/jason/ebin/Elixir.Jason.Sigil.beam b/_build/prod/lib/jason/ebin/Elixir.Jason.Sigil.beam deleted file mode 100644 index a418c75..0000000 Binary files a/_build/prod/lib/jason/ebin/Elixir.Jason.Sigil.beam and /dev/null differ diff --git a/_build/prod/lib/jason/ebin/Elixir.Jason.beam b/_build/prod/lib/jason/ebin/Elixir.Jason.beam deleted file mode 100644 index 9a9c5b6..0000000 Binary files a/_build/prod/lib/jason/ebin/Elixir.Jason.beam and /dev/null differ diff --git a/_build/prod/lib/jason/ebin/jason.app b/_build/prod/lib/jason/ebin/jason.app deleted file mode 100644 index 2d536c0..0000000 --- a/_build/prod/lib/jason/ebin/jason.app +++ /dev/null @@ -1 +0,0 @@ -{application,jason,[{modules,['Elixir.Enumerable.Jason.OrderedObject','Elixir.Jason','Elixir.Jason.Codegen','Elixir.Jason.DecodeError','Elixir.Jason.Decoder','Elixir.Jason.Decoder.Unescape','Elixir.Jason.Encode','Elixir.Jason.EncodeError','Elixir.Jason.Encoder','Elixir.Jason.Encoder.Any','Elixir.Jason.Encoder.Atom','Elixir.Jason.Encoder.BitString','Elixir.Jason.Encoder.Date','Elixir.Jason.Encoder.DateTime','Elixir.Jason.Encoder.Float','Elixir.Jason.Encoder.Integer','Elixir.Jason.Encoder.Jason.Fragment','Elixir.Jason.Encoder.Jason.OrderedObject','Elixir.Jason.Encoder.List','Elixir.Jason.Encoder.Map','Elixir.Jason.Encoder.NaiveDateTime','Elixir.Jason.Encoder.Time','Elixir.Jason.Formatter','Elixir.Jason.Fragment','Elixir.Jason.Helpers','Elixir.Jason.OrderedObject','Elixir.Jason.Sigil']},{optional_applications,[decimal]},{applications,[kernel,stdlib,elixir,decimal]},{description,"A blazing fast JSON parser and generator in pure Elixir.\n"},{registered,[]},{vsn,"1.4.4"}]}. \ No newline at end of file diff --git a/_build/prod/lib/mime/.mix/compile.elixir b/_build/prod/lib/mime/.mix/compile.elixir deleted file mode 100644 index e635b02..0000000 Binary files a/_build/prod/lib/mime/.mix/compile.elixir and /dev/null differ diff --git a/_build/prod/lib/mime/.mix/compile.elixir_scm b/_build/prod/lib/mime/.mix/compile.elixir_scm deleted file mode 100644 index 4066741..0000000 Binary files a/_build/prod/lib/mime/.mix/compile.elixir_scm and /dev/null differ diff --git a/_build/prod/lib/mime/ebin/Elixir.MIME.beam b/_build/prod/lib/mime/ebin/Elixir.MIME.beam deleted file mode 100644 index da9ca3b..0000000 Binary files a/_build/prod/lib/mime/ebin/Elixir.MIME.beam and /dev/null differ diff --git a/_build/prod/lib/mime/ebin/mime.app b/_build/prod/lib/mime/ebin/mime.app deleted file mode 100644 index cdfbbb8..0000000 --- a/_build/prod/lib/mime/ebin/mime.app +++ /dev/null @@ -1 +0,0 @@ -{application,mime,[{modules,['Elixir.MIME']},{compile_env,[{mime,[extensions],error},{mime,[suffixes],error},{mime,[types],error}]},{optional_applications,[]},{applications,[kernel,stdlib,elixir,logger]},{description,"A MIME type module for Elixir"},{registered,[]},{vsn,"2.0.7"},{env,[]}]}. \ No newline at end of file diff --git a/_build/prod/lib/plug/.mix/compile.elixir b/_build/prod/lib/plug/.mix/compile.elixir deleted file mode 100644 index 24af96b..0000000 Binary files a/_build/prod/lib/plug/.mix/compile.elixir and /dev/null differ diff --git a/_build/prod/lib/plug/.mix/compile.elixir_scm b/_build/prod/lib/plug/.mix/compile.elixir_scm deleted file mode 100644 index 4066741..0000000 Binary files a/_build/prod/lib/plug/.mix/compile.elixir_scm and /dev/null differ diff --git a/_build/prod/lib/plug/.mix/compile.erlang b/_build/prod/lib/plug/.mix/compile.erlang deleted file mode 100644 index d2904ef..0000000 Binary files a/_build/prod/lib/plug/.mix/compile.erlang and /dev/null differ diff --git a/_build/prod/lib/plug/ebin/Elixir.Inspect.Plug.Conn.beam b/_build/prod/lib/plug/ebin/Elixir.Inspect.Plug.Conn.beam deleted file mode 100644 index dfc3431..0000000 Binary files a/_build/prod/lib/plug/ebin/Elixir.Inspect.Plug.Conn.beam and /dev/null differ diff --git a/_build/prod/lib/plug/ebin/Elixir.Plug.Adapters.Cowboy.beam b/_build/prod/lib/plug/ebin/Elixir.Plug.Adapters.Cowboy.beam deleted file mode 100644 index b3f79b1..0000000 Binary files a/_build/prod/lib/plug/ebin/Elixir.Plug.Adapters.Cowboy.beam and /dev/null differ diff --git a/_build/prod/lib/plug/ebin/Elixir.Plug.Adapters.Test.Conn.beam b/_build/prod/lib/plug/ebin/Elixir.Plug.Adapters.Test.Conn.beam deleted file mode 100644 index 3492d0f..0000000 Binary files a/_build/prod/lib/plug/ebin/Elixir.Plug.Adapters.Test.Conn.beam and /dev/null differ diff --git a/_build/prod/lib/plug/ebin/Elixir.Plug.Application.beam b/_build/prod/lib/plug/ebin/Elixir.Plug.Application.beam deleted file mode 100644 index b4ef468..0000000 Binary files a/_build/prod/lib/plug/ebin/Elixir.Plug.Application.beam and /dev/null differ diff --git a/_build/prod/lib/plug/ebin/Elixir.Plug.BadRequestError.beam b/_build/prod/lib/plug/ebin/Elixir.Plug.BadRequestError.beam deleted file mode 100644 index 9785a8d..0000000 Binary files a/_build/prod/lib/plug/ebin/Elixir.Plug.BadRequestError.beam and /dev/null differ diff --git a/_build/prod/lib/plug/ebin/Elixir.Plug.BasicAuth.beam b/_build/prod/lib/plug/ebin/Elixir.Plug.BasicAuth.beam deleted file mode 100644 index 4040cce..0000000 Binary files a/_build/prod/lib/plug/ebin/Elixir.Plug.BasicAuth.beam and /dev/null differ diff --git a/_build/prod/lib/plug/ebin/Elixir.Plug.Builder.beam b/_build/prod/lib/plug/ebin/Elixir.Plug.Builder.beam deleted file mode 100644 index e1c23fe..0000000 Binary files a/_build/prod/lib/plug/ebin/Elixir.Plug.Builder.beam and /dev/null differ diff --git a/_build/prod/lib/plug/ebin/Elixir.Plug.CSRFProtection.InvalidCSRFTokenError.beam b/_build/prod/lib/plug/ebin/Elixir.Plug.CSRFProtection.InvalidCSRFTokenError.beam deleted file mode 100644 index 4e18975..0000000 Binary files a/_build/prod/lib/plug/ebin/Elixir.Plug.CSRFProtection.InvalidCSRFTokenError.beam and /dev/null differ diff --git a/_build/prod/lib/plug/ebin/Elixir.Plug.CSRFProtection.InvalidCrossOriginRequestError.beam b/_build/prod/lib/plug/ebin/Elixir.Plug.CSRFProtection.InvalidCrossOriginRequestError.beam deleted file mode 100644 index 4215cfb..0000000 Binary files a/_build/prod/lib/plug/ebin/Elixir.Plug.CSRFProtection.InvalidCrossOriginRequestError.beam and /dev/null differ diff --git a/_build/prod/lib/plug/ebin/Elixir.Plug.CSRFProtection.beam b/_build/prod/lib/plug/ebin/Elixir.Plug.CSRFProtection.beam deleted file mode 100644 index 993b79c..0000000 Binary files a/_build/prod/lib/plug/ebin/Elixir.Plug.CSRFProtection.beam and /dev/null differ diff --git a/_build/prod/lib/plug/ebin/Elixir.Plug.Conn.Adapter.beam b/_build/prod/lib/plug/ebin/Elixir.Plug.Conn.Adapter.beam deleted file mode 100644 index 03a01f0..0000000 Binary files a/_build/prod/lib/plug/ebin/Elixir.Plug.Conn.Adapter.beam and /dev/null differ diff --git a/_build/prod/lib/plug/ebin/Elixir.Plug.Conn.AlreadySentError.beam b/_build/prod/lib/plug/ebin/Elixir.Plug.Conn.AlreadySentError.beam deleted file mode 100644 index b072f02..0000000 Binary files a/_build/prod/lib/plug/ebin/Elixir.Plug.Conn.AlreadySentError.beam and /dev/null differ diff --git a/_build/prod/lib/plug/ebin/Elixir.Plug.Conn.CookieOverflowError.beam b/_build/prod/lib/plug/ebin/Elixir.Plug.Conn.CookieOverflowError.beam deleted file mode 100644 index 634ea8b..0000000 Binary files a/_build/prod/lib/plug/ebin/Elixir.Plug.Conn.CookieOverflowError.beam and /dev/null differ diff --git a/_build/prod/lib/plug/ebin/Elixir.Plug.Conn.Cookies.beam b/_build/prod/lib/plug/ebin/Elixir.Plug.Conn.Cookies.beam deleted file mode 100644 index 0a9ceb5..0000000 Binary files a/_build/prod/lib/plug/ebin/Elixir.Plug.Conn.Cookies.beam and /dev/null differ diff --git a/_build/prod/lib/plug/ebin/Elixir.Plug.Conn.InvalidHeaderError.beam b/_build/prod/lib/plug/ebin/Elixir.Plug.Conn.InvalidHeaderError.beam deleted file mode 100644 index 15db502..0000000 Binary files a/_build/prod/lib/plug/ebin/Elixir.Plug.Conn.InvalidHeaderError.beam and /dev/null differ diff --git a/_build/prod/lib/plug/ebin/Elixir.Plug.Conn.InvalidQueryError.beam b/_build/prod/lib/plug/ebin/Elixir.Plug.Conn.InvalidQueryError.beam deleted file mode 100644 index 2e6436e..0000000 Binary files a/_build/prod/lib/plug/ebin/Elixir.Plug.Conn.InvalidQueryError.beam and /dev/null differ diff --git a/_build/prod/lib/plug/ebin/Elixir.Plug.Conn.NotSentError.beam b/_build/prod/lib/plug/ebin/Elixir.Plug.Conn.NotSentError.beam deleted file mode 100644 index 7bd58fe..0000000 Binary files a/_build/prod/lib/plug/ebin/Elixir.Plug.Conn.NotSentError.beam and /dev/null differ diff --git a/_build/prod/lib/plug/ebin/Elixir.Plug.Conn.Query.beam b/_build/prod/lib/plug/ebin/Elixir.Plug.Conn.Query.beam deleted file mode 100644 index 73975ff..0000000 Binary files a/_build/prod/lib/plug/ebin/Elixir.Plug.Conn.Query.beam and /dev/null differ diff --git a/_build/prod/lib/plug/ebin/Elixir.Plug.Conn.Status.beam b/_build/prod/lib/plug/ebin/Elixir.Plug.Conn.Status.beam deleted file mode 100644 index db1eb02..0000000 Binary files a/_build/prod/lib/plug/ebin/Elixir.Plug.Conn.Status.beam and /dev/null differ diff --git a/_build/prod/lib/plug/ebin/Elixir.Plug.Conn.Unfetched.beam b/_build/prod/lib/plug/ebin/Elixir.Plug.Conn.Unfetched.beam deleted file mode 100644 index 1c8d897..0000000 Binary files a/_build/prod/lib/plug/ebin/Elixir.Plug.Conn.Unfetched.beam and /dev/null differ diff --git a/_build/prod/lib/plug/ebin/Elixir.Plug.Conn.Utils.beam b/_build/prod/lib/plug/ebin/Elixir.Plug.Conn.Utils.beam deleted file mode 100644 index 2094593..0000000 Binary files a/_build/prod/lib/plug/ebin/Elixir.Plug.Conn.Utils.beam and /dev/null differ diff --git a/_build/prod/lib/plug/ebin/Elixir.Plug.Conn.WrapperError.beam b/_build/prod/lib/plug/ebin/Elixir.Plug.Conn.WrapperError.beam deleted file mode 100644 index 869b4a9..0000000 Binary files a/_build/prod/lib/plug/ebin/Elixir.Plug.Conn.WrapperError.beam and /dev/null differ diff --git a/_build/prod/lib/plug/ebin/Elixir.Plug.Conn.beam b/_build/prod/lib/plug/ebin/Elixir.Plug.Conn.beam deleted file mode 100644 index 22178be..0000000 Binary files a/_build/prod/lib/plug/ebin/Elixir.Plug.Conn.beam and /dev/null differ diff --git a/_build/prod/lib/plug/ebin/Elixir.Plug.Debugger.beam b/_build/prod/lib/plug/ebin/Elixir.Plug.Debugger.beam deleted file mode 100644 index 4b349ee..0000000 Binary files a/_build/prod/lib/plug/ebin/Elixir.Plug.Debugger.beam and /dev/null differ diff --git a/_build/prod/lib/plug/ebin/Elixir.Plug.ErrorHandler.beam b/_build/prod/lib/plug/ebin/Elixir.Plug.ErrorHandler.beam deleted file mode 100644 index 0221932..0000000 Binary files a/_build/prod/lib/plug/ebin/Elixir.Plug.ErrorHandler.beam and /dev/null differ diff --git a/_build/prod/lib/plug/ebin/Elixir.Plug.Exception.Any.beam b/_build/prod/lib/plug/ebin/Elixir.Plug.Exception.Any.beam deleted file mode 100644 index c070159..0000000 Binary files a/_build/prod/lib/plug/ebin/Elixir.Plug.Exception.Any.beam and /dev/null differ diff --git a/_build/prod/lib/plug/ebin/Elixir.Plug.Exception.beam b/_build/prod/lib/plug/ebin/Elixir.Plug.Exception.beam deleted file mode 100644 index e0e0d2d..0000000 Binary files a/_build/prod/lib/plug/ebin/Elixir.Plug.Exception.beam and /dev/null differ diff --git a/_build/prod/lib/plug/ebin/Elixir.Plug.HTML.beam b/_build/prod/lib/plug/ebin/Elixir.Plug.HTML.beam deleted file mode 100644 index b68d3fa..0000000 Binary files a/_build/prod/lib/plug/ebin/Elixir.Plug.HTML.beam and /dev/null differ diff --git a/_build/prod/lib/plug/ebin/Elixir.Plug.Head.beam b/_build/prod/lib/plug/ebin/Elixir.Plug.Head.beam deleted file mode 100644 index 493ca97..0000000 Binary files a/_build/prod/lib/plug/ebin/Elixir.Plug.Head.beam and /dev/null differ diff --git a/_build/prod/lib/plug/ebin/Elixir.Plug.Logger.beam b/_build/prod/lib/plug/ebin/Elixir.Plug.Logger.beam deleted file mode 100644 index ea99ceb..0000000 Binary files a/_build/prod/lib/plug/ebin/Elixir.Plug.Logger.beam and /dev/null differ diff --git a/_build/prod/lib/plug/ebin/Elixir.Plug.MIME.beam b/_build/prod/lib/plug/ebin/Elixir.Plug.MIME.beam deleted file mode 100644 index bf4ffb7..0000000 Binary files a/_build/prod/lib/plug/ebin/Elixir.Plug.MIME.beam and /dev/null differ diff --git a/_build/prod/lib/plug/ebin/Elixir.Plug.MethodOverride.beam b/_build/prod/lib/plug/ebin/Elixir.Plug.MethodOverride.beam deleted file mode 100644 index 54dfbd4..0000000 Binary files a/_build/prod/lib/plug/ebin/Elixir.Plug.MethodOverride.beam and /dev/null differ diff --git a/_build/prod/lib/plug/ebin/Elixir.Plug.Parsers.BadEncodingError.beam b/_build/prod/lib/plug/ebin/Elixir.Plug.Parsers.BadEncodingError.beam deleted file mode 100644 index b4a0d2a..0000000 Binary files a/_build/prod/lib/plug/ebin/Elixir.Plug.Parsers.BadEncodingError.beam and /dev/null differ diff --git a/_build/prod/lib/plug/ebin/Elixir.Plug.Parsers.JSON.beam b/_build/prod/lib/plug/ebin/Elixir.Plug.Parsers.JSON.beam deleted file mode 100644 index 4b6de52..0000000 Binary files a/_build/prod/lib/plug/ebin/Elixir.Plug.Parsers.JSON.beam and /dev/null differ diff --git a/_build/prod/lib/plug/ebin/Elixir.Plug.Parsers.MULTIPART.beam b/_build/prod/lib/plug/ebin/Elixir.Plug.Parsers.MULTIPART.beam deleted file mode 100644 index 0c4667d..0000000 Binary files a/_build/prod/lib/plug/ebin/Elixir.Plug.Parsers.MULTIPART.beam and /dev/null differ diff --git a/_build/prod/lib/plug/ebin/Elixir.Plug.Parsers.ParseError.beam b/_build/prod/lib/plug/ebin/Elixir.Plug.Parsers.ParseError.beam deleted file mode 100644 index 1da6a8c..0000000 Binary files a/_build/prod/lib/plug/ebin/Elixir.Plug.Parsers.ParseError.beam and /dev/null differ diff --git a/_build/prod/lib/plug/ebin/Elixir.Plug.Parsers.RequestTooLargeError.beam b/_build/prod/lib/plug/ebin/Elixir.Plug.Parsers.RequestTooLargeError.beam deleted file mode 100644 index ed5ee86..0000000 Binary files a/_build/prod/lib/plug/ebin/Elixir.Plug.Parsers.RequestTooLargeError.beam and /dev/null differ diff --git a/_build/prod/lib/plug/ebin/Elixir.Plug.Parsers.URLENCODED.beam b/_build/prod/lib/plug/ebin/Elixir.Plug.Parsers.URLENCODED.beam deleted file mode 100644 index a345f21..0000000 Binary files a/_build/prod/lib/plug/ebin/Elixir.Plug.Parsers.URLENCODED.beam and /dev/null differ diff --git a/_build/prod/lib/plug/ebin/Elixir.Plug.Parsers.UnsupportedMediaTypeError.beam b/_build/prod/lib/plug/ebin/Elixir.Plug.Parsers.UnsupportedMediaTypeError.beam deleted file mode 100644 index fffd3bd..0000000 Binary files a/_build/prod/lib/plug/ebin/Elixir.Plug.Parsers.UnsupportedMediaTypeError.beam and /dev/null differ diff --git a/_build/prod/lib/plug/ebin/Elixir.Plug.Parsers.beam b/_build/prod/lib/plug/ebin/Elixir.Plug.Parsers.beam deleted file mode 100644 index 57f3f0c..0000000 Binary files a/_build/prod/lib/plug/ebin/Elixir.Plug.Parsers.beam and /dev/null differ diff --git a/_build/prod/lib/plug/ebin/Elixir.Plug.RequestId.beam b/_build/prod/lib/plug/ebin/Elixir.Plug.RequestId.beam deleted file mode 100644 index 297ec19..0000000 Binary files a/_build/prod/lib/plug/ebin/Elixir.Plug.RequestId.beam and /dev/null differ diff --git a/_build/prod/lib/plug/ebin/Elixir.Plug.RewriteOn.beam b/_build/prod/lib/plug/ebin/Elixir.Plug.RewriteOn.beam deleted file mode 100644 index 25d8e9e..0000000 Binary files a/_build/prod/lib/plug/ebin/Elixir.Plug.RewriteOn.beam and /dev/null differ diff --git a/_build/prod/lib/plug/ebin/Elixir.Plug.Router.InvalidSpecError.beam b/_build/prod/lib/plug/ebin/Elixir.Plug.Router.InvalidSpecError.beam deleted file mode 100644 index 485e878..0000000 Binary files a/_build/prod/lib/plug/ebin/Elixir.Plug.Router.InvalidSpecError.beam and /dev/null differ diff --git a/_build/prod/lib/plug/ebin/Elixir.Plug.Router.MalformedURIError.beam b/_build/prod/lib/plug/ebin/Elixir.Plug.Router.MalformedURIError.beam deleted file mode 100644 index a6e4753..0000000 Binary files a/_build/prod/lib/plug/ebin/Elixir.Plug.Router.MalformedURIError.beam and /dev/null differ diff --git a/_build/prod/lib/plug/ebin/Elixir.Plug.Router.Utils.beam b/_build/prod/lib/plug/ebin/Elixir.Plug.Router.Utils.beam deleted file mode 100644 index 647e6d5..0000000 Binary files a/_build/prod/lib/plug/ebin/Elixir.Plug.Router.Utils.beam and /dev/null differ diff --git a/_build/prod/lib/plug/ebin/Elixir.Plug.Router.beam b/_build/prod/lib/plug/ebin/Elixir.Plug.Router.beam deleted file mode 100644 index 29380b4..0000000 Binary files a/_build/prod/lib/plug/ebin/Elixir.Plug.Router.beam and /dev/null differ diff --git a/_build/prod/lib/plug/ebin/Elixir.Plug.SSL.beam b/_build/prod/lib/plug/ebin/Elixir.Plug.SSL.beam deleted file mode 100644 index 6b825bd..0000000 Binary files a/_build/prod/lib/plug/ebin/Elixir.Plug.SSL.beam and /dev/null differ diff --git a/_build/prod/lib/plug/ebin/Elixir.Plug.Session.COOKIE.beam b/_build/prod/lib/plug/ebin/Elixir.Plug.Session.COOKIE.beam deleted file mode 100644 index 9c40217..0000000 Binary files a/_build/prod/lib/plug/ebin/Elixir.Plug.Session.COOKIE.beam and /dev/null differ diff --git a/_build/prod/lib/plug/ebin/Elixir.Plug.Session.ETS.beam b/_build/prod/lib/plug/ebin/Elixir.Plug.Session.ETS.beam deleted file mode 100644 index 66d65a3..0000000 Binary files a/_build/prod/lib/plug/ebin/Elixir.Plug.Session.ETS.beam and /dev/null differ diff --git a/_build/prod/lib/plug/ebin/Elixir.Plug.Session.Store.beam b/_build/prod/lib/plug/ebin/Elixir.Plug.Session.Store.beam deleted file mode 100644 index b2add0e..0000000 Binary files a/_build/prod/lib/plug/ebin/Elixir.Plug.Session.Store.beam and /dev/null differ diff --git a/_build/prod/lib/plug/ebin/Elixir.Plug.Session.beam b/_build/prod/lib/plug/ebin/Elixir.Plug.Session.beam deleted file mode 100644 index af41b86..0000000 Binary files a/_build/prod/lib/plug/ebin/Elixir.Plug.Session.beam and /dev/null differ diff --git a/_build/prod/lib/plug/ebin/Elixir.Plug.Static.InvalidPathError.beam b/_build/prod/lib/plug/ebin/Elixir.Plug.Static.InvalidPathError.beam deleted file mode 100644 index 4f0fae2..0000000 Binary files a/_build/prod/lib/plug/ebin/Elixir.Plug.Static.InvalidPathError.beam and /dev/null differ diff --git a/_build/prod/lib/plug/ebin/Elixir.Plug.Static.beam b/_build/prod/lib/plug/ebin/Elixir.Plug.Static.beam deleted file mode 100644 index 82118ef..0000000 Binary files a/_build/prod/lib/plug/ebin/Elixir.Plug.Static.beam and /dev/null differ diff --git a/_build/prod/lib/plug/ebin/Elixir.Plug.Telemetry.beam b/_build/prod/lib/plug/ebin/Elixir.Plug.Telemetry.beam deleted file mode 100644 index d201369..0000000 Binary files a/_build/prod/lib/plug/ebin/Elixir.Plug.Telemetry.beam and /dev/null differ diff --git a/_build/prod/lib/plug/ebin/Elixir.Plug.Test.beam b/_build/prod/lib/plug/ebin/Elixir.Plug.Test.beam deleted file mode 100644 index 8e63d5e..0000000 Binary files a/_build/prod/lib/plug/ebin/Elixir.Plug.Test.beam and /dev/null differ diff --git a/_build/prod/lib/plug/ebin/Elixir.Plug.TimeoutError.beam b/_build/prod/lib/plug/ebin/Elixir.Plug.TimeoutError.beam deleted file mode 100644 index 5998a74..0000000 Binary files a/_build/prod/lib/plug/ebin/Elixir.Plug.TimeoutError.beam and /dev/null differ diff --git a/_build/prod/lib/plug/ebin/Elixir.Plug.Upload.Supervisor.beam b/_build/prod/lib/plug/ebin/Elixir.Plug.Upload.Supervisor.beam deleted file mode 100644 index e0fafea..0000000 Binary files a/_build/prod/lib/plug/ebin/Elixir.Plug.Upload.Supervisor.beam and /dev/null differ diff --git a/_build/prod/lib/plug/ebin/Elixir.Plug.Upload.Terminator.beam b/_build/prod/lib/plug/ebin/Elixir.Plug.Upload.Terminator.beam deleted file mode 100644 index f87fc4e..0000000 Binary files a/_build/prod/lib/plug/ebin/Elixir.Plug.Upload.Terminator.beam and /dev/null differ diff --git a/_build/prod/lib/plug/ebin/Elixir.Plug.Upload.beam b/_build/prod/lib/plug/ebin/Elixir.Plug.Upload.beam deleted file mode 100644 index 2bb1ec0..0000000 Binary files a/_build/prod/lib/plug/ebin/Elixir.Plug.Upload.beam and /dev/null differ diff --git a/_build/prod/lib/plug/ebin/Elixir.Plug.UploadError.beam b/_build/prod/lib/plug/ebin/Elixir.Plug.UploadError.beam deleted file mode 100644 index 326e9cd..0000000 Binary files a/_build/prod/lib/plug/ebin/Elixir.Plug.UploadError.beam and /dev/null differ diff --git a/_build/prod/lib/plug/ebin/Elixir.Plug.beam b/_build/prod/lib/plug/ebin/Elixir.Plug.beam deleted file mode 100644 index 3d3998e..0000000 Binary files a/_build/prod/lib/plug/ebin/Elixir.Plug.beam and /dev/null differ diff --git a/_build/prod/lib/plug/ebin/plug.app b/_build/prod/lib/plug/ebin/plug.app deleted file mode 100644 index c00d088..0000000 --- a/_build/prod/lib/plug/ebin/plug.app +++ /dev/null @@ -1 +0,0 @@ -{application,plug,[{modules,['Elixir.Inspect.Plug.Conn','Elixir.Plug','Elixir.Plug.Adapters.Cowboy','Elixir.Plug.Adapters.Test.Conn','Elixir.Plug.Application','Elixir.Plug.BadRequestError','Elixir.Plug.BasicAuth','Elixir.Plug.Builder','Elixir.Plug.CSRFProtection','Elixir.Plug.CSRFProtection.InvalidCSRFTokenError','Elixir.Plug.CSRFProtection.InvalidCrossOriginRequestError','Elixir.Plug.Conn','Elixir.Plug.Conn.Adapter','Elixir.Plug.Conn.AlreadySentError','Elixir.Plug.Conn.CookieOverflowError','Elixir.Plug.Conn.Cookies','Elixir.Plug.Conn.InvalidHeaderError','Elixir.Plug.Conn.InvalidQueryError','Elixir.Plug.Conn.NotSentError','Elixir.Plug.Conn.Query','Elixir.Plug.Conn.Status','Elixir.Plug.Conn.Unfetched','Elixir.Plug.Conn.Utils','Elixir.Plug.Conn.WrapperError','Elixir.Plug.Debugger','Elixir.Plug.ErrorHandler','Elixir.Plug.Exception','Elixir.Plug.Exception.Any','Elixir.Plug.HTML','Elixir.Plug.Head','Elixir.Plug.Logger','Elixir.Plug.MIME','Elixir.Plug.MethodOverride','Elixir.Plug.Parsers','Elixir.Plug.Parsers.BadEncodingError','Elixir.Plug.Parsers.JSON','Elixir.Plug.Parsers.MULTIPART','Elixir.Plug.Parsers.ParseError','Elixir.Plug.Parsers.RequestTooLargeError','Elixir.Plug.Parsers.URLENCODED','Elixir.Plug.Parsers.UnsupportedMediaTypeError','Elixir.Plug.RequestId','Elixir.Plug.RewriteOn','Elixir.Plug.Router','Elixir.Plug.Router.InvalidSpecError','Elixir.Plug.Router.MalformedURIError','Elixir.Plug.Router.Utils','Elixir.Plug.SSL','Elixir.Plug.Session','Elixir.Plug.Session.COOKIE','Elixir.Plug.Session.ETS','Elixir.Plug.Session.Store','Elixir.Plug.Static','Elixir.Plug.Static.InvalidPathError','Elixir.Plug.Telemetry','Elixir.Plug.Test','Elixir.Plug.TimeoutError','Elixir.Plug.Upload','Elixir.Plug.Upload.Supervisor','Elixir.Plug.Upload.Terminator','Elixir.Plug.UploadError',plug_multipart]},{compile_env,[{plug,[mimes],error},{plug,[statuses],error}]},{optional_applications,[]},{applications,[kernel,stdlib,elixir,logger,eex,mime,plug_crypto,telemetry]},{description,"Compose web applications with functions"},{registered,[]},{vsn,"1.19.1"},{mod,{'Elixir.Plug.Application',[]}},{env,[{validate_header_keys_during_test,true}]}]}. \ No newline at end of file diff --git a/_build/prod/lib/plug/ebin/plug_multipart.beam b/_build/prod/lib/plug/ebin/plug_multipart.beam deleted file mode 100644 index 6ac3545..0000000 Binary files a/_build/prod/lib/plug/ebin/plug_multipart.beam and /dev/null differ diff --git a/_build/prod/lib/plug_crypto/.mix/compile.elixir b/_build/prod/lib/plug_crypto/.mix/compile.elixir deleted file mode 100644 index 0e74261..0000000 Binary files a/_build/prod/lib/plug_crypto/.mix/compile.elixir and /dev/null differ diff --git a/_build/prod/lib/plug_crypto/.mix/compile.elixir_scm b/_build/prod/lib/plug_crypto/.mix/compile.elixir_scm deleted file mode 100644 index 4066741..0000000 Binary files a/_build/prod/lib/plug_crypto/.mix/compile.elixir_scm and /dev/null differ diff --git a/_build/prod/lib/plug_crypto/ebin/Elixir.Plug.Crypto.Application.beam b/_build/prod/lib/plug_crypto/ebin/Elixir.Plug.Crypto.Application.beam deleted file mode 100644 index 35d0872..0000000 Binary files a/_build/prod/lib/plug_crypto/ebin/Elixir.Plug.Crypto.Application.beam and /dev/null differ diff --git a/_build/prod/lib/plug_crypto/ebin/Elixir.Plug.Crypto.KeyGenerator.beam b/_build/prod/lib/plug_crypto/ebin/Elixir.Plug.Crypto.KeyGenerator.beam deleted file mode 100644 index d041718..0000000 Binary files a/_build/prod/lib/plug_crypto/ebin/Elixir.Plug.Crypto.KeyGenerator.beam and /dev/null differ diff --git a/_build/prod/lib/plug_crypto/ebin/Elixir.Plug.Crypto.MessageEncryptor.beam b/_build/prod/lib/plug_crypto/ebin/Elixir.Plug.Crypto.MessageEncryptor.beam deleted file mode 100644 index daf3769..0000000 Binary files a/_build/prod/lib/plug_crypto/ebin/Elixir.Plug.Crypto.MessageEncryptor.beam and /dev/null differ diff --git a/_build/prod/lib/plug_crypto/ebin/Elixir.Plug.Crypto.MessageVerifier.beam b/_build/prod/lib/plug_crypto/ebin/Elixir.Plug.Crypto.MessageVerifier.beam deleted file mode 100644 index 3937903..0000000 Binary files a/_build/prod/lib/plug_crypto/ebin/Elixir.Plug.Crypto.MessageVerifier.beam and /dev/null differ diff --git a/_build/prod/lib/plug_crypto/ebin/Elixir.Plug.Crypto.beam b/_build/prod/lib/plug_crypto/ebin/Elixir.Plug.Crypto.beam deleted file mode 100644 index ced9674..0000000 Binary files a/_build/prod/lib/plug_crypto/ebin/Elixir.Plug.Crypto.beam and /dev/null differ diff --git a/_build/prod/lib/plug_crypto/ebin/plug_crypto.app b/_build/prod/lib/plug_crypto/ebin/plug_crypto.app deleted file mode 100644 index 7997244..0000000 --- a/_build/prod/lib/plug_crypto/ebin/plug_crypto.app +++ /dev/null @@ -1 +0,0 @@ -{application,plug_crypto,[{modules,['Elixir.Plug.Crypto','Elixir.Plug.Crypto.Application','Elixir.Plug.Crypto.KeyGenerator','Elixir.Plug.Crypto.MessageEncryptor','Elixir.Plug.Crypto.MessageVerifier']},{optional_applications,[]},{applications,[kernel,stdlib,elixir,crypto]},{description,"Crypto-related functionality for the web"},{registered,[]},{vsn,"2.1.1"},{mod,{'Elixir.Plug.Crypto.Application',[]}}]}. \ No newline at end of file diff --git a/_build/prod/lib/symbiont/.mix/compile.app_cache b/_build/prod/lib/symbiont/.mix/compile.app_cache deleted file mode 100644 index f2af339..0000000 Binary files a/_build/prod/lib/symbiont/.mix/compile.app_cache and /dev/null differ diff --git a/_build/prod/lib/symbiont/.mix/compile.elixir b/_build/prod/lib/symbiont/.mix/compile.elixir deleted file mode 100644 index c62876e..0000000 Binary files a/_build/prod/lib/symbiont/.mix/compile.elixir and /dev/null differ diff --git a/_build/prod/lib/symbiont/.mix/compile.elixir_scm b/_build/prod/lib/symbiont/.mix/compile.elixir_scm deleted file mode 100644 index f1e974f..0000000 Binary files a/_build/prod/lib/symbiont/.mix/compile.elixir_scm and /dev/null differ diff --git a/_build/prod/lib/symbiont/.mix/compile.lock b/_build/prod/lib/symbiont/.mix/compile.lock deleted file mode 100644 index e69de29..0000000 diff --git a/_build/prod/lib/symbiont/consolidated/Elixir.Bandit.HTTP2.Frame.Serializable.beam b/_build/prod/lib/symbiont/consolidated/Elixir.Bandit.HTTP2.Frame.Serializable.beam deleted file mode 100644 index adc09ce..0000000 Binary files a/_build/prod/lib/symbiont/consolidated/Elixir.Bandit.HTTP2.Frame.Serializable.beam and /dev/null differ diff --git a/_build/prod/lib/symbiont/consolidated/Elixir.Bandit.HTTPTransport.beam b/_build/prod/lib/symbiont/consolidated/Elixir.Bandit.HTTPTransport.beam deleted file mode 100644 index 94d2d7a..0000000 Binary files a/_build/prod/lib/symbiont/consolidated/Elixir.Bandit.HTTPTransport.beam and /dev/null differ diff --git a/_build/prod/lib/symbiont/consolidated/Elixir.Bandit.WebSocket.Frame.Serializable.beam b/_build/prod/lib/symbiont/consolidated/Elixir.Bandit.WebSocket.Frame.Serializable.beam deleted file mode 100644 index 515c9da..0000000 Binary files a/_build/prod/lib/symbiont/consolidated/Elixir.Bandit.WebSocket.Frame.Serializable.beam and /dev/null differ diff --git a/_build/prod/lib/symbiont/consolidated/Elixir.Bandit.WebSocket.Socket.beam b/_build/prod/lib/symbiont/consolidated/Elixir.Bandit.WebSocket.Socket.beam deleted file mode 100644 index 5646ce3..0000000 Binary files a/_build/prod/lib/symbiont/consolidated/Elixir.Bandit.WebSocket.Socket.beam and /dev/null differ diff --git a/_build/prod/lib/symbiont/consolidated/Elixir.Collectable.beam b/_build/prod/lib/symbiont/consolidated/Elixir.Collectable.beam deleted file mode 100644 index 8e5c284..0000000 Binary files a/_build/prod/lib/symbiont/consolidated/Elixir.Collectable.beam and /dev/null differ diff --git a/_build/prod/lib/symbiont/consolidated/Elixir.Enumerable.beam b/_build/prod/lib/symbiont/consolidated/Elixir.Enumerable.beam deleted file mode 100644 index 5ec861c..0000000 Binary files a/_build/prod/lib/symbiont/consolidated/Elixir.Enumerable.beam and /dev/null differ diff --git a/_build/prod/lib/symbiont/consolidated/Elixir.IEx.Info.beam b/_build/prod/lib/symbiont/consolidated/Elixir.IEx.Info.beam deleted file mode 100644 index b353a23..0000000 Binary files a/_build/prod/lib/symbiont/consolidated/Elixir.IEx.Info.beam and /dev/null differ diff --git a/_build/prod/lib/symbiont/consolidated/Elixir.Inspect.beam b/_build/prod/lib/symbiont/consolidated/Elixir.Inspect.beam deleted file mode 100644 index 1d7a158..0000000 Binary files a/_build/prod/lib/symbiont/consolidated/Elixir.Inspect.beam and /dev/null differ diff --git a/_build/prod/lib/symbiont/consolidated/Elixir.JSON.Encoder.beam b/_build/prod/lib/symbiont/consolidated/Elixir.JSON.Encoder.beam deleted file mode 100644 index 54aed03..0000000 Binary files a/_build/prod/lib/symbiont/consolidated/Elixir.JSON.Encoder.beam and /dev/null differ diff --git a/_build/prod/lib/symbiont/consolidated/Elixir.Jason.Encoder.beam b/_build/prod/lib/symbiont/consolidated/Elixir.Jason.Encoder.beam deleted file mode 100644 index eb2b370..0000000 Binary files a/_build/prod/lib/symbiont/consolidated/Elixir.Jason.Encoder.beam and /dev/null differ diff --git a/_build/prod/lib/symbiont/consolidated/Elixir.List.Chars.beam b/_build/prod/lib/symbiont/consolidated/Elixir.List.Chars.beam deleted file mode 100644 index a32010d..0000000 Binary files a/_build/prod/lib/symbiont/consolidated/Elixir.List.Chars.beam and /dev/null differ diff --git a/_build/prod/lib/symbiont/consolidated/Elixir.Plug.Exception.beam b/_build/prod/lib/symbiont/consolidated/Elixir.Plug.Exception.beam deleted file mode 100644 index 5762b0e..0000000 Binary files a/_build/prod/lib/symbiont/consolidated/Elixir.Plug.Exception.beam and /dev/null differ diff --git a/_build/prod/lib/symbiont/consolidated/Elixir.String.Chars.beam b/_build/prod/lib/symbiont/consolidated/Elixir.String.Chars.beam deleted file mode 100644 index 1d65575..0000000 Binary files a/_build/prod/lib/symbiont/consolidated/Elixir.String.Chars.beam and /dev/null differ diff --git a/_build/prod/lib/symbiont/ebin/Elixir.Symbiont.API.beam b/_build/prod/lib/symbiont/ebin/Elixir.Symbiont.API.beam deleted file mode 100644 index 407ce2c..0000000 Binary files a/_build/prod/lib/symbiont/ebin/Elixir.Symbiont.API.beam and /dev/null differ diff --git a/_build/prod/lib/symbiont/ebin/Elixir.Symbiont.Application.beam b/_build/prod/lib/symbiont/ebin/Elixir.Symbiont.Application.beam deleted file mode 100644 index 2ef9df6..0000000 Binary files a/_build/prod/lib/symbiont/ebin/Elixir.Symbiont.Application.beam and /dev/null differ diff --git a/_build/prod/lib/symbiont/ebin/Elixir.Symbiont.Dispatcher.beam b/_build/prod/lib/symbiont/ebin/Elixir.Symbiont.Dispatcher.beam deleted file mode 100644 index ff70b4d..0000000 Binary files a/_build/prod/lib/symbiont/ebin/Elixir.Symbiont.Dispatcher.beam and /dev/null differ diff --git a/_build/prod/lib/symbiont/ebin/Elixir.Symbiont.Heartbeat.beam b/_build/prod/lib/symbiont/ebin/Elixir.Symbiont.Heartbeat.beam deleted file mode 100644 index 1652d1c..0000000 Binary files a/_build/prod/lib/symbiont/ebin/Elixir.Symbiont.Heartbeat.beam and /dev/null differ diff --git a/_build/prod/lib/symbiont/ebin/Elixir.Symbiont.Ledger.beam b/_build/prod/lib/symbiont/ebin/Elixir.Symbiont.Ledger.beam deleted file mode 100644 index 96a5f6f..0000000 Binary files a/_build/prod/lib/symbiont/ebin/Elixir.Symbiont.Ledger.beam and /dev/null differ diff --git a/_build/prod/lib/symbiont/ebin/Elixir.Symbiont.Queue.beam b/_build/prod/lib/symbiont/ebin/Elixir.Symbiont.Queue.beam deleted file mode 100644 index 505dac7..0000000 Binary files a/_build/prod/lib/symbiont/ebin/Elixir.Symbiont.Queue.beam and /dev/null differ diff --git a/_build/prod/lib/symbiont/ebin/Elixir.Symbiont.Router.beam b/_build/prod/lib/symbiont/ebin/Elixir.Symbiont.Router.beam deleted file mode 100644 index 3d85bd9..0000000 Binary files a/_build/prod/lib/symbiont/ebin/Elixir.Symbiont.Router.beam and /dev/null differ diff --git a/_build/prod/lib/symbiont/ebin/Elixir.Symbiont.beam b/_build/prod/lib/symbiont/ebin/Elixir.Symbiont.beam deleted file mode 100644 index bf5f052..0000000 Binary files a/_build/prod/lib/symbiont/ebin/Elixir.Symbiont.beam and /dev/null differ diff --git a/_build/prod/lib/symbiont/ebin/symbiont.app b/_build/prod/lib/symbiont/ebin/symbiont.app deleted file mode 100644 index 4e22c01..0000000 --- a/_build/prod/lib/symbiont/ebin/symbiont.app +++ /dev/null @@ -1 +0,0 @@ -{application,symbiont,[{modules,['Elixir.Symbiont','Elixir.Symbiont.API','Elixir.Symbiont.Application','Elixir.Symbiont.Dispatcher','Elixir.Symbiont.Engram','Elixir.Symbiont.Heartbeat','Elixir.Symbiont.Ledger','Elixir.Symbiont.Queue','Elixir.Symbiont.Router']},{optional_applications,[]},{applications,[kernel,stdlib,elixir,logger,crypto,bandit,plug,jason,exqlite]},{description,"symbiont"},{registered,[]},{vsn,"0.2.0"},{mod,{'Elixir.Symbiont.Application',[]}}]}. \ No newline at end of file diff --git a/_build/prod/lib/telemetry/.mix/compile.elixir_scm b/_build/prod/lib/telemetry/.mix/compile.elixir_scm deleted file mode 100644 index 4066741..0000000 Binary files a/_build/prod/lib/telemetry/.mix/compile.elixir_scm and /dev/null differ diff --git a/_build/prod/lib/telemetry/ebin/telemetry.app b/_build/prod/lib/telemetry/ebin/telemetry.app deleted file mode 100644 index b09b016..0000000 --- a/_build/prod/lib/telemetry/ebin/telemetry.app +++ /dev/null @@ -1,15 +0,0 @@ -{application,telemetry, - [{description,"Dynamic dispatching library for metrics and instrumentations"}, - {vsn,"1.4.1"}, - {registered,[]}, - {mod,{telemetry_app,[]}}, - {applications,[kernel,stdlib]}, - {env,[]}, - {modules,[telemetry,telemetry_app,telemetry_ets, - telemetry_handler_table,telemetry_pt,telemetry_sup, - telemetry_test]}, - {licenses,["Apache-2.0"]}, - {links,[{"GitHub", - "https://github.com/beam-telemetry/telemetry"}]}, - {doc,"doc"}, - {include_files,["mix.exs"]}]}. diff --git a/_build/prod/lib/telemetry/ebin/telemetry.beam b/_build/prod/lib/telemetry/ebin/telemetry.beam deleted file mode 100644 index 93ae8f0..0000000 Binary files a/_build/prod/lib/telemetry/ebin/telemetry.beam and /dev/null differ diff --git a/_build/prod/lib/telemetry/ebin/telemetry_app.beam b/_build/prod/lib/telemetry/ebin/telemetry_app.beam deleted file mode 100644 index f775bee..0000000 Binary files a/_build/prod/lib/telemetry/ebin/telemetry_app.beam and /dev/null differ diff --git a/_build/prod/lib/telemetry/ebin/telemetry_ets.beam b/_build/prod/lib/telemetry/ebin/telemetry_ets.beam deleted file mode 100644 index 03edab8..0000000 Binary files a/_build/prod/lib/telemetry/ebin/telemetry_ets.beam and /dev/null differ diff --git a/_build/prod/lib/telemetry/ebin/telemetry_handler_table.beam b/_build/prod/lib/telemetry/ebin/telemetry_handler_table.beam deleted file mode 100644 index 630206e..0000000 Binary files a/_build/prod/lib/telemetry/ebin/telemetry_handler_table.beam and /dev/null differ diff --git a/_build/prod/lib/telemetry/ebin/telemetry_pt.beam b/_build/prod/lib/telemetry/ebin/telemetry_pt.beam deleted file mode 100644 index 60cf5dc..0000000 Binary files a/_build/prod/lib/telemetry/ebin/telemetry_pt.beam and /dev/null differ diff --git a/_build/prod/lib/telemetry/ebin/telemetry_sup.beam b/_build/prod/lib/telemetry/ebin/telemetry_sup.beam deleted file mode 100644 index 962a0d8..0000000 Binary files a/_build/prod/lib/telemetry/ebin/telemetry_sup.beam and /dev/null differ diff --git a/_build/prod/lib/telemetry/ebin/telemetry_test.beam b/_build/prod/lib/telemetry/ebin/telemetry_test.beam deleted file mode 100644 index da1ec96..0000000 Binary files a/_build/prod/lib/telemetry/ebin/telemetry_test.beam and /dev/null differ diff --git a/_build/prod/lib/telemetry/mix.rebar.config b/_build/prod/lib/telemetry/mix.rebar.config deleted file mode 100644 index ca1ef50..0000000 --- a/_build/prod/lib/telemetry/mix.rebar.config +++ /dev/null @@ -1,17 +0,0 @@ -{erl_opts,[debug_info]}. -{deps,[]}. -{profiles,[{test,[{erl_opts,[nowarn_export_all]}, - {ct_opts,[{ct_hooks,[cth_surefire]}]}, - {cover_enabled,true}, - {cover_opts,[verbose]}, - {plugins,[covertool]}, - {covertool,[{coverdata_files,["ct.coverdata"]}]}]}]}. -{shell,[{apps,[telemetry]}]}. -{xref_checks,[undefined_function_calls,undefined_functions,locals_not_used, - deprecated_function_calls,deprecated_functions]}. -{hex,[{doc,#{provider => ex_doc}}]}. -{ex_doc,[{source_url,<<"https://github.com/beam-telemetry/telemetry">>}, - {extras,[<<"README.md">>,<<"CHANGELOG.md">>,<<"LICENSE">>, - <<"NOTICE">>]}, - {main,<<"readme">>}]}. -{overrides,[]}. diff --git a/_build/prod/lib/telemetry/src b/_build/prod/lib/telemetry/src deleted file mode 120000 index f3de4ce..0000000 --- a/_build/prod/lib/telemetry/src +++ /dev/null @@ -1 +0,0 @@ -../../../../deps/telemetry/src \ No newline at end of file diff --git a/_build/prod/lib/thousand_island/.mix/compile.elixir b/_build/prod/lib/thousand_island/.mix/compile.elixir deleted file mode 100644 index aeaf62f..0000000 Binary files a/_build/prod/lib/thousand_island/.mix/compile.elixir and /dev/null differ diff --git a/_build/prod/lib/thousand_island/.mix/compile.elixir_scm b/_build/prod/lib/thousand_island/.mix/compile.elixir_scm deleted file mode 100644 index 4066741..0000000 Binary files a/_build/prod/lib/thousand_island/.mix/compile.elixir_scm and /dev/null differ diff --git a/_build/prod/lib/thousand_island/ebin/Elixir.ThousandIsland.Acceptor.beam b/_build/prod/lib/thousand_island/ebin/Elixir.ThousandIsland.Acceptor.beam deleted file mode 100644 index b48911d..0000000 Binary files a/_build/prod/lib/thousand_island/ebin/Elixir.ThousandIsland.Acceptor.beam and /dev/null differ diff --git a/_build/prod/lib/thousand_island/ebin/Elixir.ThousandIsland.AcceptorPoolSupervisor.beam b/_build/prod/lib/thousand_island/ebin/Elixir.ThousandIsland.AcceptorPoolSupervisor.beam deleted file mode 100644 index 0c5b9b7..0000000 Binary files a/_build/prod/lib/thousand_island/ebin/Elixir.ThousandIsland.AcceptorPoolSupervisor.beam and /dev/null differ diff --git a/_build/prod/lib/thousand_island/ebin/Elixir.ThousandIsland.AcceptorSupervisor.beam b/_build/prod/lib/thousand_island/ebin/Elixir.ThousandIsland.AcceptorSupervisor.beam deleted file mode 100644 index 7770ba0..0000000 Binary files a/_build/prod/lib/thousand_island/ebin/Elixir.ThousandIsland.AcceptorSupervisor.beam and /dev/null differ diff --git a/_build/prod/lib/thousand_island/ebin/Elixir.ThousandIsland.Connection.beam b/_build/prod/lib/thousand_island/ebin/Elixir.ThousandIsland.Connection.beam deleted file mode 100644 index b404890..0000000 Binary files a/_build/prod/lib/thousand_island/ebin/Elixir.ThousandIsland.Connection.beam and /dev/null differ diff --git a/_build/prod/lib/thousand_island/ebin/Elixir.ThousandIsland.Handler.beam b/_build/prod/lib/thousand_island/ebin/Elixir.ThousandIsland.Handler.beam deleted file mode 100644 index acdf258..0000000 Binary files a/_build/prod/lib/thousand_island/ebin/Elixir.ThousandIsland.Handler.beam and /dev/null differ diff --git a/_build/prod/lib/thousand_island/ebin/Elixir.ThousandIsland.HandlerConfig.beam b/_build/prod/lib/thousand_island/ebin/Elixir.ThousandIsland.HandlerConfig.beam deleted file mode 100644 index defd98c..0000000 Binary files a/_build/prod/lib/thousand_island/ebin/Elixir.ThousandIsland.HandlerConfig.beam and /dev/null differ diff --git a/_build/prod/lib/thousand_island/ebin/Elixir.ThousandIsland.Listener.beam b/_build/prod/lib/thousand_island/ebin/Elixir.ThousandIsland.Listener.beam deleted file mode 100644 index 44bf7cb..0000000 Binary files a/_build/prod/lib/thousand_island/ebin/Elixir.ThousandIsland.Listener.beam and /dev/null differ diff --git a/_build/prod/lib/thousand_island/ebin/Elixir.ThousandIsland.Logger.beam b/_build/prod/lib/thousand_island/ebin/Elixir.ThousandIsland.Logger.beam deleted file mode 100644 index 4e77013..0000000 Binary files a/_build/prod/lib/thousand_island/ebin/Elixir.ThousandIsland.Logger.beam and /dev/null differ diff --git a/_build/prod/lib/thousand_island/ebin/Elixir.ThousandIsland.ProcessLabel.beam b/_build/prod/lib/thousand_island/ebin/Elixir.ThousandIsland.ProcessLabel.beam deleted file mode 100644 index 6a61380..0000000 Binary files a/_build/prod/lib/thousand_island/ebin/Elixir.ThousandIsland.ProcessLabel.beam and /dev/null differ diff --git a/_build/prod/lib/thousand_island/ebin/Elixir.ThousandIsland.Server.beam b/_build/prod/lib/thousand_island/ebin/Elixir.ThousandIsland.Server.beam deleted file mode 100644 index 14116d5..0000000 Binary files a/_build/prod/lib/thousand_island/ebin/Elixir.ThousandIsland.Server.beam and /dev/null differ diff --git a/_build/prod/lib/thousand_island/ebin/Elixir.ThousandIsland.ServerConfig.beam b/_build/prod/lib/thousand_island/ebin/Elixir.ThousandIsland.ServerConfig.beam deleted file mode 100644 index 17eabf5..0000000 Binary files a/_build/prod/lib/thousand_island/ebin/Elixir.ThousandIsland.ServerConfig.beam and /dev/null differ diff --git a/_build/prod/lib/thousand_island/ebin/Elixir.ThousandIsland.ShutdownListener.beam b/_build/prod/lib/thousand_island/ebin/Elixir.ThousandIsland.ShutdownListener.beam deleted file mode 100644 index 4777534..0000000 Binary files a/_build/prod/lib/thousand_island/ebin/Elixir.ThousandIsland.ShutdownListener.beam and /dev/null differ diff --git a/_build/prod/lib/thousand_island/ebin/Elixir.ThousandIsland.Socket.beam b/_build/prod/lib/thousand_island/ebin/Elixir.ThousandIsland.Socket.beam deleted file mode 100644 index 9366638..0000000 Binary files a/_build/prod/lib/thousand_island/ebin/Elixir.ThousandIsland.Socket.beam and /dev/null differ diff --git a/_build/prod/lib/thousand_island/ebin/Elixir.ThousandIsland.Telemetry.beam b/_build/prod/lib/thousand_island/ebin/Elixir.ThousandIsland.Telemetry.beam deleted file mode 100644 index abfcb05..0000000 Binary files a/_build/prod/lib/thousand_island/ebin/Elixir.ThousandIsland.Telemetry.beam and /dev/null differ diff --git a/_build/prod/lib/thousand_island/ebin/Elixir.ThousandIsland.Transport.beam b/_build/prod/lib/thousand_island/ebin/Elixir.ThousandIsland.Transport.beam deleted file mode 100644 index 01c358d..0000000 Binary files a/_build/prod/lib/thousand_island/ebin/Elixir.ThousandIsland.Transport.beam and /dev/null differ diff --git a/_build/prod/lib/thousand_island/ebin/Elixir.ThousandIsland.Transports.SSL.beam b/_build/prod/lib/thousand_island/ebin/Elixir.ThousandIsland.Transports.SSL.beam deleted file mode 100644 index b3b8417..0000000 Binary files a/_build/prod/lib/thousand_island/ebin/Elixir.ThousandIsland.Transports.SSL.beam and /dev/null differ diff --git a/_build/prod/lib/thousand_island/ebin/Elixir.ThousandIsland.Transports.TCP.beam b/_build/prod/lib/thousand_island/ebin/Elixir.ThousandIsland.Transports.TCP.beam deleted file mode 100644 index d1893bf..0000000 Binary files a/_build/prod/lib/thousand_island/ebin/Elixir.ThousandIsland.Transports.TCP.beam and /dev/null differ diff --git a/_build/prod/lib/thousand_island/ebin/Elixir.ThousandIsland.beam b/_build/prod/lib/thousand_island/ebin/Elixir.ThousandIsland.beam deleted file mode 100644 index f44e43c..0000000 Binary files a/_build/prod/lib/thousand_island/ebin/Elixir.ThousandIsland.beam and /dev/null differ diff --git a/_build/prod/lib/thousand_island/ebin/thousand_island.app b/_build/prod/lib/thousand_island/ebin/thousand_island.app deleted file mode 100644 index fe65be4..0000000 --- a/_build/prod/lib/thousand_island/ebin/thousand_island.app +++ /dev/null @@ -1 +0,0 @@ -{application,thousand_island,[{modules,['Elixir.ThousandIsland','Elixir.ThousandIsland.Acceptor','Elixir.ThousandIsland.AcceptorPoolSupervisor','Elixir.ThousandIsland.AcceptorSupervisor','Elixir.ThousandIsland.Connection','Elixir.ThousandIsland.Handler','Elixir.ThousandIsland.HandlerConfig','Elixir.ThousandIsland.Listener','Elixir.ThousandIsland.Logger','Elixir.ThousandIsland.ProcessLabel','Elixir.ThousandIsland.Server','Elixir.ThousandIsland.ServerConfig','Elixir.ThousandIsland.ShutdownListener','Elixir.ThousandIsland.Socket','Elixir.ThousandIsland.Telemetry','Elixir.ThousandIsland.Transport','Elixir.ThousandIsland.Transports.SSL','Elixir.ThousandIsland.Transports.TCP']},{optional_applications,[]},{applications,[kernel,stdlib,elixir,logger,ssl,telemetry]},{description,"A simple & modern pure Elixir socket server"},{registered,[]},{vsn,"1.4.3"}]}. \ No newline at end of file diff --git a/_build/prod/lib/websock/.mix/compile.elixir b/_build/prod/lib/websock/.mix/compile.elixir deleted file mode 100644 index 651596c..0000000 Binary files a/_build/prod/lib/websock/.mix/compile.elixir and /dev/null differ diff --git a/_build/prod/lib/websock/.mix/compile.elixir_scm b/_build/prod/lib/websock/.mix/compile.elixir_scm deleted file mode 100644 index 4066741..0000000 Binary files a/_build/prod/lib/websock/.mix/compile.elixir_scm and /dev/null differ diff --git a/_build/prod/lib/websock/ebin/Elixir.WebSock.beam b/_build/prod/lib/websock/ebin/Elixir.WebSock.beam deleted file mode 100644 index af0821e..0000000 Binary files a/_build/prod/lib/websock/ebin/Elixir.WebSock.beam and /dev/null differ diff --git a/_build/prod/lib/websock/ebin/websock.app b/_build/prod/lib/websock/ebin/websock.app deleted file mode 100644 index b9acb14..0000000 --- a/_build/prod/lib/websock/ebin/websock.app +++ /dev/null @@ -1 +0,0 @@ -{application,websock,[{modules,['Elixir.WebSock']},{optional_applications,[]},{applications,[kernel,stdlib,elixir]},{description,"A specification for WebSocket connections"},{registered,[]},{vsn,"0.5.3"}]}. \ No newline at end of file diff --git a/_build/test/lib/bandit/.mix/compile.elixir b/_build/test/lib/bandit/.mix/compile.elixir deleted file mode 100644 index 15858fa..0000000 Binary files a/_build/test/lib/bandit/.mix/compile.elixir and /dev/null differ diff --git a/_build/test/lib/bandit/.mix/compile.elixir_scm b/_build/test/lib/bandit/.mix/compile.elixir_scm deleted file mode 100644 index 4066741..0000000 Binary files a/_build/test/lib/bandit/.mix/compile.elixir_scm and /dev/null differ diff --git a/_build/test/lib/bandit/ebin/Elixir.Bandit.Adapter.beam b/_build/test/lib/bandit/ebin/Elixir.Bandit.Adapter.beam deleted file mode 100644 index 9dba560..0000000 Binary files a/_build/test/lib/bandit/ebin/Elixir.Bandit.Adapter.beam and /dev/null differ diff --git a/_build/test/lib/bandit/ebin/Elixir.Bandit.Application.beam b/_build/test/lib/bandit/ebin/Elixir.Bandit.Application.beam deleted file mode 100644 index 8082cf4..0000000 Binary files a/_build/test/lib/bandit/ebin/Elixir.Bandit.Application.beam and /dev/null differ diff --git a/_build/test/lib/bandit/ebin/Elixir.Bandit.Clock.beam b/_build/test/lib/bandit/ebin/Elixir.Bandit.Clock.beam deleted file mode 100644 index e38796e..0000000 Binary files a/_build/test/lib/bandit/ebin/Elixir.Bandit.Clock.beam and /dev/null differ diff --git a/_build/test/lib/bandit/ebin/Elixir.Bandit.Compression.beam b/_build/test/lib/bandit/ebin/Elixir.Bandit.Compression.beam deleted file mode 100644 index b393a2e..0000000 Binary files a/_build/test/lib/bandit/ebin/Elixir.Bandit.Compression.beam and /dev/null differ diff --git a/_build/test/lib/bandit/ebin/Elixir.Bandit.DelegatingHandler.beam b/_build/test/lib/bandit/ebin/Elixir.Bandit.DelegatingHandler.beam deleted file mode 100644 index f6f35eb..0000000 Binary files a/_build/test/lib/bandit/ebin/Elixir.Bandit.DelegatingHandler.beam and /dev/null differ diff --git a/_build/test/lib/bandit/ebin/Elixir.Bandit.Extractor.beam b/_build/test/lib/bandit/ebin/Elixir.Bandit.Extractor.beam deleted file mode 100644 index df4718f..0000000 Binary files a/_build/test/lib/bandit/ebin/Elixir.Bandit.Extractor.beam and /dev/null differ diff --git a/_build/test/lib/bandit/ebin/Elixir.Bandit.HTTP1.Handler.beam b/_build/test/lib/bandit/ebin/Elixir.Bandit.HTTP1.Handler.beam deleted file mode 100644 index 69a4dc8..0000000 Binary files a/_build/test/lib/bandit/ebin/Elixir.Bandit.HTTP1.Handler.beam and /dev/null differ diff --git a/_build/test/lib/bandit/ebin/Elixir.Bandit.HTTP1.Socket.beam b/_build/test/lib/bandit/ebin/Elixir.Bandit.HTTP1.Socket.beam deleted file mode 100644 index 7d80651..0000000 Binary files a/_build/test/lib/bandit/ebin/Elixir.Bandit.HTTP1.Socket.beam and /dev/null differ diff --git a/_build/test/lib/bandit/ebin/Elixir.Bandit.HTTP2.Connection.beam b/_build/test/lib/bandit/ebin/Elixir.Bandit.HTTP2.Connection.beam deleted file mode 100644 index a6df251..0000000 Binary files a/_build/test/lib/bandit/ebin/Elixir.Bandit.HTTP2.Connection.beam and /dev/null differ diff --git a/_build/test/lib/bandit/ebin/Elixir.Bandit.HTTP2.Errors.ConnectionError.beam b/_build/test/lib/bandit/ebin/Elixir.Bandit.HTTP2.Errors.ConnectionError.beam deleted file mode 100644 index 7d48f4f..0000000 Binary files a/_build/test/lib/bandit/ebin/Elixir.Bandit.HTTP2.Errors.ConnectionError.beam and /dev/null differ diff --git a/_build/test/lib/bandit/ebin/Elixir.Bandit.HTTP2.Errors.StreamError.beam b/_build/test/lib/bandit/ebin/Elixir.Bandit.HTTP2.Errors.StreamError.beam deleted file mode 100644 index 4720588..0000000 Binary files a/_build/test/lib/bandit/ebin/Elixir.Bandit.HTTP2.Errors.StreamError.beam and /dev/null differ diff --git a/_build/test/lib/bandit/ebin/Elixir.Bandit.HTTP2.Errors.beam b/_build/test/lib/bandit/ebin/Elixir.Bandit.HTTP2.Errors.beam deleted file mode 100644 index 499bb46..0000000 Binary files a/_build/test/lib/bandit/ebin/Elixir.Bandit.HTTP2.Errors.beam and /dev/null differ diff --git a/_build/test/lib/bandit/ebin/Elixir.Bandit.HTTP2.FlowControl.beam b/_build/test/lib/bandit/ebin/Elixir.Bandit.HTTP2.FlowControl.beam deleted file mode 100644 index b9ce4f6..0000000 Binary files a/_build/test/lib/bandit/ebin/Elixir.Bandit.HTTP2.FlowControl.beam and /dev/null differ diff --git a/_build/test/lib/bandit/ebin/Elixir.Bandit.HTTP2.Frame.Continuation.beam b/_build/test/lib/bandit/ebin/Elixir.Bandit.HTTP2.Frame.Continuation.beam deleted file mode 100644 index 2fd182d..0000000 Binary files a/_build/test/lib/bandit/ebin/Elixir.Bandit.HTTP2.Frame.Continuation.beam and /dev/null differ diff --git a/_build/test/lib/bandit/ebin/Elixir.Bandit.HTTP2.Frame.Data.beam b/_build/test/lib/bandit/ebin/Elixir.Bandit.HTTP2.Frame.Data.beam deleted file mode 100644 index 20d1861..0000000 Binary files a/_build/test/lib/bandit/ebin/Elixir.Bandit.HTTP2.Frame.Data.beam and /dev/null differ diff --git a/_build/test/lib/bandit/ebin/Elixir.Bandit.HTTP2.Frame.Flags.beam b/_build/test/lib/bandit/ebin/Elixir.Bandit.HTTP2.Frame.Flags.beam deleted file mode 100644 index df5ebb5..0000000 Binary files a/_build/test/lib/bandit/ebin/Elixir.Bandit.HTTP2.Frame.Flags.beam and /dev/null differ diff --git a/_build/test/lib/bandit/ebin/Elixir.Bandit.HTTP2.Frame.Goaway.beam b/_build/test/lib/bandit/ebin/Elixir.Bandit.HTTP2.Frame.Goaway.beam deleted file mode 100644 index 270ba36..0000000 Binary files a/_build/test/lib/bandit/ebin/Elixir.Bandit.HTTP2.Frame.Goaway.beam and /dev/null differ diff --git a/_build/test/lib/bandit/ebin/Elixir.Bandit.HTTP2.Frame.Headers.beam b/_build/test/lib/bandit/ebin/Elixir.Bandit.HTTP2.Frame.Headers.beam deleted file mode 100644 index 3ba1938..0000000 Binary files a/_build/test/lib/bandit/ebin/Elixir.Bandit.HTTP2.Frame.Headers.beam and /dev/null differ diff --git a/_build/test/lib/bandit/ebin/Elixir.Bandit.HTTP2.Frame.Ping.beam b/_build/test/lib/bandit/ebin/Elixir.Bandit.HTTP2.Frame.Ping.beam deleted file mode 100644 index 4a6b576..0000000 Binary files a/_build/test/lib/bandit/ebin/Elixir.Bandit.HTTP2.Frame.Ping.beam and /dev/null differ diff --git a/_build/test/lib/bandit/ebin/Elixir.Bandit.HTTP2.Frame.Priority.beam b/_build/test/lib/bandit/ebin/Elixir.Bandit.HTTP2.Frame.Priority.beam deleted file mode 100644 index 1343366..0000000 Binary files a/_build/test/lib/bandit/ebin/Elixir.Bandit.HTTP2.Frame.Priority.beam and /dev/null differ diff --git a/_build/test/lib/bandit/ebin/Elixir.Bandit.HTTP2.Frame.PushPromise.beam b/_build/test/lib/bandit/ebin/Elixir.Bandit.HTTP2.Frame.PushPromise.beam deleted file mode 100644 index afacfb5..0000000 Binary files a/_build/test/lib/bandit/ebin/Elixir.Bandit.HTTP2.Frame.PushPromise.beam and /dev/null differ diff --git a/_build/test/lib/bandit/ebin/Elixir.Bandit.HTTP2.Frame.RstStream.beam b/_build/test/lib/bandit/ebin/Elixir.Bandit.HTTP2.Frame.RstStream.beam deleted file mode 100644 index 772723b..0000000 Binary files a/_build/test/lib/bandit/ebin/Elixir.Bandit.HTTP2.Frame.RstStream.beam and /dev/null differ diff --git a/_build/test/lib/bandit/ebin/Elixir.Bandit.HTTP2.Frame.Serializable.Bandit.HTTP2.Frame.Continuation.beam b/_build/test/lib/bandit/ebin/Elixir.Bandit.HTTP2.Frame.Serializable.Bandit.HTTP2.Frame.Continuation.beam deleted file mode 100644 index 796ebe1..0000000 Binary files a/_build/test/lib/bandit/ebin/Elixir.Bandit.HTTP2.Frame.Serializable.Bandit.HTTP2.Frame.Continuation.beam and /dev/null differ diff --git a/_build/test/lib/bandit/ebin/Elixir.Bandit.HTTP2.Frame.Serializable.Bandit.HTTP2.Frame.Data.beam b/_build/test/lib/bandit/ebin/Elixir.Bandit.HTTP2.Frame.Serializable.Bandit.HTTP2.Frame.Data.beam deleted file mode 100644 index 25d4ee2..0000000 Binary files a/_build/test/lib/bandit/ebin/Elixir.Bandit.HTTP2.Frame.Serializable.Bandit.HTTP2.Frame.Data.beam and /dev/null differ diff --git a/_build/test/lib/bandit/ebin/Elixir.Bandit.HTTP2.Frame.Serializable.Bandit.HTTP2.Frame.Goaway.beam b/_build/test/lib/bandit/ebin/Elixir.Bandit.HTTP2.Frame.Serializable.Bandit.HTTP2.Frame.Goaway.beam deleted file mode 100644 index 3dcaa50..0000000 Binary files a/_build/test/lib/bandit/ebin/Elixir.Bandit.HTTP2.Frame.Serializable.Bandit.HTTP2.Frame.Goaway.beam and /dev/null differ diff --git a/_build/test/lib/bandit/ebin/Elixir.Bandit.HTTP2.Frame.Serializable.Bandit.HTTP2.Frame.Headers.beam b/_build/test/lib/bandit/ebin/Elixir.Bandit.HTTP2.Frame.Serializable.Bandit.HTTP2.Frame.Headers.beam deleted file mode 100644 index c47b41e..0000000 Binary files a/_build/test/lib/bandit/ebin/Elixir.Bandit.HTTP2.Frame.Serializable.Bandit.HTTP2.Frame.Headers.beam and /dev/null differ diff --git a/_build/test/lib/bandit/ebin/Elixir.Bandit.HTTP2.Frame.Serializable.Bandit.HTTP2.Frame.Ping.beam b/_build/test/lib/bandit/ebin/Elixir.Bandit.HTTP2.Frame.Serializable.Bandit.HTTP2.Frame.Ping.beam deleted file mode 100644 index dcdc37d..0000000 Binary files a/_build/test/lib/bandit/ebin/Elixir.Bandit.HTTP2.Frame.Serializable.Bandit.HTTP2.Frame.Ping.beam and /dev/null differ diff --git a/_build/test/lib/bandit/ebin/Elixir.Bandit.HTTP2.Frame.Serializable.Bandit.HTTP2.Frame.Priority.beam b/_build/test/lib/bandit/ebin/Elixir.Bandit.HTTP2.Frame.Serializable.Bandit.HTTP2.Frame.Priority.beam deleted file mode 100644 index 3fafc8a..0000000 Binary files a/_build/test/lib/bandit/ebin/Elixir.Bandit.HTTP2.Frame.Serializable.Bandit.HTTP2.Frame.Priority.beam and /dev/null differ diff --git a/_build/test/lib/bandit/ebin/Elixir.Bandit.HTTP2.Frame.Serializable.Bandit.HTTP2.Frame.RstStream.beam b/_build/test/lib/bandit/ebin/Elixir.Bandit.HTTP2.Frame.Serializable.Bandit.HTTP2.Frame.RstStream.beam deleted file mode 100644 index f7e36ca..0000000 Binary files a/_build/test/lib/bandit/ebin/Elixir.Bandit.HTTP2.Frame.Serializable.Bandit.HTTP2.Frame.RstStream.beam and /dev/null differ diff --git a/_build/test/lib/bandit/ebin/Elixir.Bandit.HTTP2.Frame.Serializable.Bandit.HTTP2.Frame.Settings.beam b/_build/test/lib/bandit/ebin/Elixir.Bandit.HTTP2.Frame.Serializable.Bandit.HTTP2.Frame.Settings.beam deleted file mode 100644 index dc2b3cd..0000000 Binary files a/_build/test/lib/bandit/ebin/Elixir.Bandit.HTTP2.Frame.Serializable.Bandit.HTTP2.Frame.Settings.beam and /dev/null differ diff --git a/_build/test/lib/bandit/ebin/Elixir.Bandit.HTTP2.Frame.Serializable.Bandit.HTTP2.Frame.WindowUpdate.beam b/_build/test/lib/bandit/ebin/Elixir.Bandit.HTTP2.Frame.Serializable.Bandit.HTTP2.Frame.WindowUpdate.beam deleted file mode 100644 index d74297c..0000000 Binary files a/_build/test/lib/bandit/ebin/Elixir.Bandit.HTTP2.Frame.Serializable.Bandit.HTTP2.Frame.WindowUpdate.beam and /dev/null differ diff --git a/_build/test/lib/bandit/ebin/Elixir.Bandit.HTTP2.Frame.Serializable.beam b/_build/test/lib/bandit/ebin/Elixir.Bandit.HTTP2.Frame.Serializable.beam deleted file mode 100644 index b5b4301..0000000 Binary files a/_build/test/lib/bandit/ebin/Elixir.Bandit.HTTP2.Frame.Serializable.beam and /dev/null differ diff --git a/_build/test/lib/bandit/ebin/Elixir.Bandit.HTTP2.Frame.Settings.beam b/_build/test/lib/bandit/ebin/Elixir.Bandit.HTTP2.Frame.Settings.beam deleted file mode 100644 index a48a24b..0000000 Binary files a/_build/test/lib/bandit/ebin/Elixir.Bandit.HTTP2.Frame.Settings.beam and /dev/null differ diff --git a/_build/test/lib/bandit/ebin/Elixir.Bandit.HTTP2.Frame.Unknown.beam b/_build/test/lib/bandit/ebin/Elixir.Bandit.HTTP2.Frame.Unknown.beam deleted file mode 100644 index a118760..0000000 Binary files a/_build/test/lib/bandit/ebin/Elixir.Bandit.HTTP2.Frame.Unknown.beam and /dev/null differ diff --git a/_build/test/lib/bandit/ebin/Elixir.Bandit.HTTP2.Frame.WindowUpdate.beam b/_build/test/lib/bandit/ebin/Elixir.Bandit.HTTP2.Frame.WindowUpdate.beam deleted file mode 100644 index 22ae2f3..0000000 Binary files a/_build/test/lib/bandit/ebin/Elixir.Bandit.HTTP2.Frame.WindowUpdate.beam and /dev/null differ diff --git a/_build/test/lib/bandit/ebin/Elixir.Bandit.HTTP2.Frame.beam b/_build/test/lib/bandit/ebin/Elixir.Bandit.HTTP2.Frame.beam deleted file mode 100644 index ff22d55..0000000 Binary files a/_build/test/lib/bandit/ebin/Elixir.Bandit.HTTP2.Frame.beam and /dev/null differ diff --git a/_build/test/lib/bandit/ebin/Elixir.Bandit.HTTP2.Handler.beam b/_build/test/lib/bandit/ebin/Elixir.Bandit.HTTP2.Handler.beam deleted file mode 100644 index f42f160..0000000 Binary files a/_build/test/lib/bandit/ebin/Elixir.Bandit.HTTP2.Handler.beam and /dev/null differ diff --git a/_build/test/lib/bandit/ebin/Elixir.Bandit.HTTP2.Settings.beam b/_build/test/lib/bandit/ebin/Elixir.Bandit.HTTP2.Settings.beam deleted file mode 100644 index 63623c4..0000000 Binary files a/_build/test/lib/bandit/ebin/Elixir.Bandit.HTTP2.Settings.beam and /dev/null differ diff --git a/_build/test/lib/bandit/ebin/Elixir.Bandit.HTTP2.Stream.beam b/_build/test/lib/bandit/ebin/Elixir.Bandit.HTTP2.Stream.beam deleted file mode 100644 index fc39f03..0000000 Binary files a/_build/test/lib/bandit/ebin/Elixir.Bandit.HTTP2.Stream.beam and /dev/null differ diff --git a/_build/test/lib/bandit/ebin/Elixir.Bandit.HTTP2.StreamCollection.beam b/_build/test/lib/bandit/ebin/Elixir.Bandit.HTTP2.StreamCollection.beam deleted file mode 100644 index 32fe830..0000000 Binary files a/_build/test/lib/bandit/ebin/Elixir.Bandit.HTTP2.StreamCollection.beam and /dev/null differ diff --git a/_build/test/lib/bandit/ebin/Elixir.Bandit.HTTP2.StreamProcess.beam b/_build/test/lib/bandit/ebin/Elixir.Bandit.HTTP2.StreamProcess.beam deleted file mode 100644 index 8207fe1..0000000 Binary files a/_build/test/lib/bandit/ebin/Elixir.Bandit.HTTP2.StreamProcess.beam and /dev/null differ diff --git a/_build/test/lib/bandit/ebin/Elixir.Bandit.HTTPError.beam b/_build/test/lib/bandit/ebin/Elixir.Bandit.HTTPError.beam deleted file mode 100644 index 772d948..0000000 Binary files a/_build/test/lib/bandit/ebin/Elixir.Bandit.HTTPError.beam and /dev/null differ diff --git a/_build/test/lib/bandit/ebin/Elixir.Bandit.HTTPTransport.Bandit.HTTP1.Socket.beam b/_build/test/lib/bandit/ebin/Elixir.Bandit.HTTPTransport.Bandit.HTTP1.Socket.beam deleted file mode 100644 index f0c50ec..0000000 Binary files a/_build/test/lib/bandit/ebin/Elixir.Bandit.HTTPTransport.Bandit.HTTP1.Socket.beam and /dev/null differ diff --git a/_build/test/lib/bandit/ebin/Elixir.Bandit.HTTPTransport.Bandit.HTTP2.Stream.beam b/_build/test/lib/bandit/ebin/Elixir.Bandit.HTTPTransport.Bandit.HTTP2.Stream.beam deleted file mode 100644 index 46ebb3b..0000000 Binary files a/_build/test/lib/bandit/ebin/Elixir.Bandit.HTTPTransport.Bandit.HTTP2.Stream.beam and /dev/null differ diff --git a/_build/test/lib/bandit/ebin/Elixir.Bandit.HTTPTransport.beam b/_build/test/lib/bandit/ebin/Elixir.Bandit.HTTPTransport.beam deleted file mode 100644 index f1929ba..0000000 Binary files a/_build/test/lib/bandit/ebin/Elixir.Bandit.HTTPTransport.beam and /dev/null differ diff --git a/_build/test/lib/bandit/ebin/Elixir.Bandit.Headers.beam b/_build/test/lib/bandit/ebin/Elixir.Bandit.Headers.beam deleted file mode 100644 index 09bac73..0000000 Binary files a/_build/test/lib/bandit/ebin/Elixir.Bandit.Headers.beam and /dev/null differ diff --git a/_build/test/lib/bandit/ebin/Elixir.Bandit.InitialHandler.beam b/_build/test/lib/bandit/ebin/Elixir.Bandit.InitialHandler.beam deleted file mode 100644 index 94bd216..0000000 Binary files a/_build/test/lib/bandit/ebin/Elixir.Bandit.InitialHandler.beam and /dev/null differ diff --git a/_build/test/lib/bandit/ebin/Elixir.Bandit.Logger.beam b/_build/test/lib/bandit/ebin/Elixir.Bandit.Logger.beam deleted file mode 100644 index 7e70a01..0000000 Binary files a/_build/test/lib/bandit/ebin/Elixir.Bandit.Logger.beam and /dev/null differ diff --git a/_build/test/lib/bandit/ebin/Elixir.Bandit.PhoenixAdapter.beam b/_build/test/lib/bandit/ebin/Elixir.Bandit.PhoenixAdapter.beam deleted file mode 100644 index 02c8f02..0000000 Binary files a/_build/test/lib/bandit/ebin/Elixir.Bandit.PhoenixAdapter.beam and /dev/null differ diff --git a/_build/test/lib/bandit/ebin/Elixir.Bandit.Pipeline.beam b/_build/test/lib/bandit/ebin/Elixir.Bandit.Pipeline.beam deleted file mode 100644 index dc973b5..0000000 Binary files a/_build/test/lib/bandit/ebin/Elixir.Bandit.Pipeline.beam and /dev/null differ diff --git a/_build/test/lib/bandit/ebin/Elixir.Bandit.PrimitiveOps.WebSocket.beam b/_build/test/lib/bandit/ebin/Elixir.Bandit.PrimitiveOps.WebSocket.beam deleted file mode 100644 index 033222f..0000000 Binary files a/_build/test/lib/bandit/ebin/Elixir.Bandit.PrimitiveOps.WebSocket.beam and /dev/null differ diff --git a/_build/test/lib/bandit/ebin/Elixir.Bandit.SocketHelpers.beam b/_build/test/lib/bandit/ebin/Elixir.Bandit.SocketHelpers.beam deleted file mode 100644 index 76a2405..0000000 Binary files a/_build/test/lib/bandit/ebin/Elixir.Bandit.SocketHelpers.beam and /dev/null differ diff --git a/_build/test/lib/bandit/ebin/Elixir.Bandit.Telemetry.beam b/_build/test/lib/bandit/ebin/Elixir.Bandit.Telemetry.beam deleted file mode 100644 index 2190d40..0000000 Binary files a/_build/test/lib/bandit/ebin/Elixir.Bandit.Telemetry.beam and /dev/null differ diff --git a/_build/test/lib/bandit/ebin/Elixir.Bandit.Trace.beam b/_build/test/lib/bandit/ebin/Elixir.Bandit.Trace.beam deleted file mode 100644 index 2cbb111..0000000 Binary files a/_build/test/lib/bandit/ebin/Elixir.Bandit.Trace.beam and /dev/null differ diff --git a/_build/test/lib/bandit/ebin/Elixir.Bandit.TransportError.beam b/_build/test/lib/bandit/ebin/Elixir.Bandit.TransportError.beam deleted file mode 100644 index 8e9b5bc..0000000 Binary files a/_build/test/lib/bandit/ebin/Elixir.Bandit.TransportError.beam and /dev/null differ diff --git a/_build/test/lib/bandit/ebin/Elixir.Bandit.WebSocket.Connection.beam b/_build/test/lib/bandit/ebin/Elixir.Bandit.WebSocket.Connection.beam deleted file mode 100644 index 7a57a23..0000000 Binary files a/_build/test/lib/bandit/ebin/Elixir.Bandit.WebSocket.Connection.beam and /dev/null differ diff --git a/_build/test/lib/bandit/ebin/Elixir.Bandit.WebSocket.Frame.Binary.beam b/_build/test/lib/bandit/ebin/Elixir.Bandit.WebSocket.Frame.Binary.beam deleted file mode 100644 index ff23ad3..0000000 Binary files a/_build/test/lib/bandit/ebin/Elixir.Bandit.WebSocket.Frame.Binary.beam and /dev/null differ diff --git a/_build/test/lib/bandit/ebin/Elixir.Bandit.WebSocket.Frame.ConnectionClose.beam b/_build/test/lib/bandit/ebin/Elixir.Bandit.WebSocket.Frame.ConnectionClose.beam deleted file mode 100644 index 1a70f9e..0000000 Binary files a/_build/test/lib/bandit/ebin/Elixir.Bandit.WebSocket.Frame.ConnectionClose.beam and /dev/null differ diff --git a/_build/test/lib/bandit/ebin/Elixir.Bandit.WebSocket.Frame.Continuation.beam b/_build/test/lib/bandit/ebin/Elixir.Bandit.WebSocket.Frame.Continuation.beam deleted file mode 100644 index 7823a49..0000000 Binary files a/_build/test/lib/bandit/ebin/Elixir.Bandit.WebSocket.Frame.Continuation.beam and /dev/null differ diff --git a/_build/test/lib/bandit/ebin/Elixir.Bandit.WebSocket.Frame.Ping.beam b/_build/test/lib/bandit/ebin/Elixir.Bandit.WebSocket.Frame.Ping.beam deleted file mode 100644 index c94504d..0000000 Binary files a/_build/test/lib/bandit/ebin/Elixir.Bandit.WebSocket.Frame.Ping.beam and /dev/null differ diff --git a/_build/test/lib/bandit/ebin/Elixir.Bandit.WebSocket.Frame.Pong.beam b/_build/test/lib/bandit/ebin/Elixir.Bandit.WebSocket.Frame.Pong.beam deleted file mode 100644 index 39bfb45..0000000 Binary files a/_build/test/lib/bandit/ebin/Elixir.Bandit.WebSocket.Frame.Pong.beam and /dev/null differ diff --git a/_build/test/lib/bandit/ebin/Elixir.Bandit.WebSocket.Frame.Serializable.Bandit.WebSocket.Frame.Binary.beam b/_build/test/lib/bandit/ebin/Elixir.Bandit.WebSocket.Frame.Serializable.Bandit.WebSocket.Frame.Binary.beam deleted file mode 100644 index 90b70da..0000000 Binary files a/_build/test/lib/bandit/ebin/Elixir.Bandit.WebSocket.Frame.Serializable.Bandit.WebSocket.Frame.Binary.beam and /dev/null differ diff --git a/_build/test/lib/bandit/ebin/Elixir.Bandit.WebSocket.Frame.Serializable.Bandit.WebSocket.Frame.ConnectionClose.beam b/_build/test/lib/bandit/ebin/Elixir.Bandit.WebSocket.Frame.Serializable.Bandit.WebSocket.Frame.ConnectionClose.beam deleted file mode 100644 index 0de4a89..0000000 Binary files a/_build/test/lib/bandit/ebin/Elixir.Bandit.WebSocket.Frame.Serializable.Bandit.WebSocket.Frame.ConnectionClose.beam and /dev/null differ diff --git a/_build/test/lib/bandit/ebin/Elixir.Bandit.WebSocket.Frame.Serializable.Bandit.WebSocket.Frame.Continuation.beam b/_build/test/lib/bandit/ebin/Elixir.Bandit.WebSocket.Frame.Serializable.Bandit.WebSocket.Frame.Continuation.beam deleted file mode 100644 index 866767d..0000000 Binary files a/_build/test/lib/bandit/ebin/Elixir.Bandit.WebSocket.Frame.Serializable.Bandit.WebSocket.Frame.Continuation.beam and /dev/null differ diff --git a/_build/test/lib/bandit/ebin/Elixir.Bandit.WebSocket.Frame.Serializable.Bandit.WebSocket.Frame.Ping.beam b/_build/test/lib/bandit/ebin/Elixir.Bandit.WebSocket.Frame.Serializable.Bandit.WebSocket.Frame.Ping.beam deleted file mode 100644 index a9041f2..0000000 Binary files a/_build/test/lib/bandit/ebin/Elixir.Bandit.WebSocket.Frame.Serializable.Bandit.WebSocket.Frame.Ping.beam and /dev/null differ diff --git a/_build/test/lib/bandit/ebin/Elixir.Bandit.WebSocket.Frame.Serializable.Bandit.WebSocket.Frame.Pong.beam b/_build/test/lib/bandit/ebin/Elixir.Bandit.WebSocket.Frame.Serializable.Bandit.WebSocket.Frame.Pong.beam deleted file mode 100644 index 83a58c2..0000000 Binary files a/_build/test/lib/bandit/ebin/Elixir.Bandit.WebSocket.Frame.Serializable.Bandit.WebSocket.Frame.Pong.beam and /dev/null differ diff --git a/_build/test/lib/bandit/ebin/Elixir.Bandit.WebSocket.Frame.Serializable.Bandit.WebSocket.Frame.Text.beam b/_build/test/lib/bandit/ebin/Elixir.Bandit.WebSocket.Frame.Serializable.Bandit.WebSocket.Frame.Text.beam deleted file mode 100644 index 8409645..0000000 Binary files a/_build/test/lib/bandit/ebin/Elixir.Bandit.WebSocket.Frame.Serializable.Bandit.WebSocket.Frame.Text.beam and /dev/null differ diff --git a/_build/test/lib/bandit/ebin/Elixir.Bandit.WebSocket.Frame.Serializable.beam b/_build/test/lib/bandit/ebin/Elixir.Bandit.WebSocket.Frame.Serializable.beam deleted file mode 100644 index 351d03d..0000000 Binary files a/_build/test/lib/bandit/ebin/Elixir.Bandit.WebSocket.Frame.Serializable.beam and /dev/null differ diff --git a/_build/test/lib/bandit/ebin/Elixir.Bandit.WebSocket.Frame.Text.beam b/_build/test/lib/bandit/ebin/Elixir.Bandit.WebSocket.Frame.Text.beam deleted file mode 100644 index dbc31c2..0000000 Binary files a/_build/test/lib/bandit/ebin/Elixir.Bandit.WebSocket.Frame.Text.beam and /dev/null differ diff --git a/_build/test/lib/bandit/ebin/Elixir.Bandit.WebSocket.Frame.beam b/_build/test/lib/bandit/ebin/Elixir.Bandit.WebSocket.Frame.beam deleted file mode 100644 index 555219c..0000000 Binary files a/_build/test/lib/bandit/ebin/Elixir.Bandit.WebSocket.Frame.beam and /dev/null differ diff --git a/_build/test/lib/bandit/ebin/Elixir.Bandit.WebSocket.Handler.beam b/_build/test/lib/bandit/ebin/Elixir.Bandit.WebSocket.Handler.beam deleted file mode 100644 index 56fb548..0000000 Binary files a/_build/test/lib/bandit/ebin/Elixir.Bandit.WebSocket.Handler.beam and /dev/null differ diff --git a/_build/test/lib/bandit/ebin/Elixir.Bandit.WebSocket.Handshake.beam b/_build/test/lib/bandit/ebin/Elixir.Bandit.WebSocket.Handshake.beam deleted file mode 100644 index 5d0c748..0000000 Binary files a/_build/test/lib/bandit/ebin/Elixir.Bandit.WebSocket.Handshake.beam and /dev/null differ diff --git a/_build/test/lib/bandit/ebin/Elixir.Bandit.WebSocket.PerMessageDeflate.beam b/_build/test/lib/bandit/ebin/Elixir.Bandit.WebSocket.PerMessageDeflate.beam deleted file mode 100644 index 95a46b5..0000000 Binary files a/_build/test/lib/bandit/ebin/Elixir.Bandit.WebSocket.PerMessageDeflate.beam and /dev/null differ diff --git a/_build/test/lib/bandit/ebin/Elixir.Bandit.WebSocket.Socket.ThousandIsland.Socket.beam b/_build/test/lib/bandit/ebin/Elixir.Bandit.WebSocket.Socket.ThousandIsland.Socket.beam deleted file mode 100644 index cb44c9d..0000000 Binary files a/_build/test/lib/bandit/ebin/Elixir.Bandit.WebSocket.Socket.ThousandIsland.Socket.beam and /dev/null differ diff --git a/_build/test/lib/bandit/ebin/Elixir.Bandit.WebSocket.Socket.beam b/_build/test/lib/bandit/ebin/Elixir.Bandit.WebSocket.Socket.beam deleted file mode 100644 index 9957acc..0000000 Binary files a/_build/test/lib/bandit/ebin/Elixir.Bandit.WebSocket.Socket.beam and /dev/null differ diff --git a/_build/test/lib/bandit/ebin/Elixir.Bandit.WebSocket.UpgradeValidation.beam b/_build/test/lib/bandit/ebin/Elixir.Bandit.WebSocket.UpgradeValidation.beam deleted file mode 100644 index c1dd155..0000000 Binary files a/_build/test/lib/bandit/ebin/Elixir.Bandit.WebSocket.UpgradeValidation.beam and /dev/null differ diff --git a/_build/test/lib/bandit/ebin/Elixir.Bandit.beam b/_build/test/lib/bandit/ebin/Elixir.Bandit.beam deleted file mode 100644 index 837c441..0000000 Binary files a/_build/test/lib/bandit/ebin/Elixir.Bandit.beam and /dev/null differ diff --git a/_build/test/lib/bandit/ebin/bandit.app b/_build/test/lib/bandit/ebin/bandit.app deleted file mode 100644 index 5cfd6d3..0000000 --- a/_build/test/lib/bandit/ebin/bandit.app +++ /dev/null @@ -1 +0,0 @@ -{application,bandit,[{modules,['Elixir.Bandit','Elixir.Bandit.Adapter','Elixir.Bandit.Application','Elixir.Bandit.Clock','Elixir.Bandit.Compression','Elixir.Bandit.DelegatingHandler','Elixir.Bandit.Extractor','Elixir.Bandit.HTTP1.Handler','Elixir.Bandit.HTTP1.Socket','Elixir.Bandit.HTTP2.Connection','Elixir.Bandit.HTTP2.Errors','Elixir.Bandit.HTTP2.Errors.ConnectionError','Elixir.Bandit.HTTP2.Errors.StreamError','Elixir.Bandit.HTTP2.FlowControl','Elixir.Bandit.HTTP2.Frame','Elixir.Bandit.HTTP2.Frame.Continuation','Elixir.Bandit.HTTP2.Frame.Data','Elixir.Bandit.HTTP2.Frame.Flags','Elixir.Bandit.HTTP2.Frame.Goaway','Elixir.Bandit.HTTP2.Frame.Headers','Elixir.Bandit.HTTP2.Frame.Ping','Elixir.Bandit.HTTP2.Frame.Priority','Elixir.Bandit.HTTP2.Frame.PushPromise','Elixir.Bandit.HTTP2.Frame.RstStream','Elixir.Bandit.HTTP2.Frame.Serializable','Elixir.Bandit.HTTP2.Frame.Serializable.Bandit.HTTP2.Frame.Continuation','Elixir.Bandit.HTTP2.Frame.Serializable.Bandit.HTTP2.Frame.Data','Elixir.Bandit.HTTP2.Frame.Serializable.Bandit.HTTP2.Frame.Goaway','Elixir.Bandit.HTTP2.Frame.Serializable.Bandit.HTTP2.Frame.Headers','Elixir.Bandit.HTTP2.Frame.Serializable.Bandit.HTTP2.Frame.Ping','Elixir.Bandit.HTTP2.Frame.Serializable.Bandit.HTTP2.Frame.Priority','Elixir.Bandit.HTTP2.Frame.Serializable.Bandit.HTTP2.Frame.RstStream','Elixir.Bandit.HTTP2.Frame.Serializable.Bandit.HTTP2.Frame.Settings','Elixir.Bandit.HTTP2.Frame.Serializable.Bandit.HTTP2.Frame.WindowUpdate','Elixir.Bandit.HTTP2.Frame.Settings','Elixir.Bandit.HTTP2.Frame.Unknown','Elixir.Bandit.HTTP2.Frame.WindowUpdate','Elixir.Bandit.HTTP2.Handler','Elixir.Bandit.HTTP2.Settings','Elixir.Bandit.HTTP2.Stream','Elixir.Bandit.HTTP2.StreamCollection','Elixir.Bandit.HTTP2.StreamProcess','Elixir.Bandit.HTTPError','Elixir.Bandit.HTTPTransport','Elixir.Bandit.HTTPTransport.Bandit.HTTP1.Socket','Elixir.Bandit.HTTPTransport.Bandit.HTTP2.Stream','Elixir.Bandit.Headers','Elixir.Bandit.InitialHandler','Elixir.Bandit.Logger','Elixir.Bandit.PhoenixAdapter','Elixir.Bandit.Pipeline','Elixir.Bandit.PrimitiveOps.WebSocket','Elixir.Bandit.SocketHelpers','Elixir.Bandit.Telemetry','Elixir.Bandit.Trace','Elixir.Bandit.TransportError','Elixir.Bandit.WebSocket.Connection','Elixir.Bandit.WebSocket.Frame','Elixir.Bandit.WebSocket.Frame.Binary','Elixir.Bandit.WebSocket.Frame.ConnectionClose','Elixir.Bandit.WebSocket.Frame.Continuation','Elixir.Bandit.WebSocket.Frame.Ping','Elixir.Bandit.WebSocket.Frame.Pong','Elixir.Bandit.WebSocket.Frame.Serializable','Elixir.Bandit.WebSocket.Frame.Serializable.Bandit.WebSocket.Frame.Binary','Elixir.Bandit.WebSocket.Frame.Serializable.Bandit.WebSocket.Frame.ConnectionClose','Elixir.Bandit.WebSocket.Frame.Serializable.Bandit.WebSocket.Frame.Continuation','Elixir.Bandit.WebSocket.Frame.Serializable.Bandit.WebSocket.Frame.Ping','Elixir.Bandit.WebSocket.Frame.Serializable.Bandit.WebSocket.Frame.Pong','Elixir.Bandit.WebSocket.Frame.Serializable.Bandit.WebSocket.Frame.Text','Elixir.Bandit.WebSocket.Frame.Text','Elixir.Bandit.WebSocket.Handler','Elixir.Bandit.WebSocket.Handshake','Elixir.Bandit.WebSocket.PerMessageDeflate','Elixir.Bandit.WebSocket.Socket','Elixir.Bandit.WebSocket.Socket.ThousandIsland.Socket','Elixir.Bandit.WebSocket.UpgradeValidation']},{optional_applications,[]},{applications,[kernel,stdlib,elixir,logger,thousand_island,plug,websock,hpax,telemetry]},{description,"A pure-Elixir HTTP server built for Plug & WebSock apps"},{registered,[]},{vsn,"1.10.3"},{mod,{'Elixir.Bandit.Application',[]}}]}. \ No newline at end of file diff --git a/_build/test/lib/hpax/.mix/compile.elixir b/_build/test/lib/hpax/.mix/compile.elixir deleted file mode 100644 index dcb684d..0000000 Binary files a/_build/test/lib/hpax/.mix/compile.elixir and /dev/null differ diff --git a/_build/test/lib/hpax/.mix/compile.elixir_scm b/_build/test/lib/hpax/.mix/compile.elixir_scm deleted file mode 100644 index 4066741..0000000 Binary files a/_build/test/lib/hpax/.mix/compile.elixir_scm and /dev/null differ diff --git a/_build/test/lib/hpax/ebin/Elixir.HPAX.Huffman.beam b/_build/test/lib/hpax/ebin/Elixir.HPAX.Huffman.beam deleted file mode 100644 index f06d6df..0000000 Binary files a/_build/test/lib/hpax/ebin/Elixir.HPAX.Huffman.beam and /dev/null differ diff --git a/_build/test/lib/hpax/ebin/Elixir.HPAX.Table.beam b/_build/test/lib/hpax/ebin/Elixir.HPAX.Table.beam deleted file mode 100644 index 5c94668..0000000 Binary files a/_build/test/lib/hpax/ebin/Elixir.HPAX.Table.beam and /dev/null differ diff --git a/_build/test/lib/hpax/ebin/Elixir.HPAX.Types.beam b/_build/test/lib/hpax/ebin/Elixir.HPAX.Types.beam deleted file mode 100644 index d8bdeae..0000000 Binary files a/_build/test/lib/hpax/ebin/Elixir.HPAX.Types.beam and /dev/null differ diff --git a/_build/test/lib/hpax/ebin/Elixir.HPAX.beam b/_build/test/lib/hpax/ebin/Elixir.HPAX.beam deleted file mode 100644 index 5b027d3..0000000 Binary files a/_build/test/lib/hpax/ebin/Elixir.HPAX.beam and /dev/null differ diff --git a/_build/test/lib/hpax/ebin/hpax.app b/_build/test/lib/hpax/ebin/hpax.app deleted file mode 100644 index d514d1e..0000000 --- a/_build/test/lib/hpax/ebin/hpax.app +++ /dev/null @@ -1 +0,0 @@ -{application,hpax,[{modules,['Elixir.HPAX','Elixir.HPAX.Huffman','Elixir.HPAX.Table','Elixir.HPAX.Types']},{optional_applications,[]},{applications,[kernel,stdlib,elixir]},{description,"Implementation of the HPACK protocol (RFC 7541) for Elixir"},{registered,[]},{vsn,"1.0.3"}]}. \ No newline at end of file diff --git a/_build/test/lib/jason/.mix/compile.elixir b/_build/test/lib/jason/.mix/compile.elixir deleted file mode 100644 index 4ae689f..0000000 Binary files a/_build/test/lib/jason/.mix/compile.elixir and /dev/null differ diff --git a/_build/test/lib/jason/.mix/compile.elixir_scm b/_build/test/lib/jason/.mix/compile.elixir_scm deleted file mode 100644 index 4066741..0000000 Binary files a/_build/test/lib/jason/.mix/compile.elixir_scm and /dev/null differ diff --git a/_build/test/lib/jason/ebin/Elixir.Enumerable.Jason.OrderedObject.beam b/_build/test/lib/jason/ebin/Elixir.Enumerable.Jason.OrderedObject.beam deleted file mode 100644 index 7099c0e..0000000 Binary files a/_build/test/lib/jason/ebin/Elixir.Enumerable.Jason.OrderedObject.beam and /dev/null differ diff --git a/_build/test/lib/jason/ebin/Elixir.Jason.Codegen.beam b/_build/test/lib/jason/ebin/Elixir.Jason.Codegen.beam deleted file mode 100644 index 0e0221c..0000000 Binary files a/_build/test/lib/jason/ebin/Elixir.Jason.Codegen.beam and /dev/null differ diff --git a/_build/test/lib/jason/ebin/Elixir.Jason.DecodeError.beam b/_build/test/lib/jason/ebin/Elixir.Jason.DecodeError.beam deleted file mode 100644 index ce29c2e..0000000 Binary files a/_build/test/lib/jason/ebin/Elixir.Jason.DecodeError.beam and /dev/null differ diff --git a/_build/test/lib/jason/ebin/Elixir.Jason.Decoder.Unescape.beam b/_build/test/lib/jason/ebin/Elixir.Jason.Decoder.Unescape.beam deleted file mode 100644 index 083597a..0000000 Binary files a/_build/test/lib/jason/ebin/Elixir.Jason.Decoder.Unescape.beam and /dev/null differ diff --git a/_build/test/lib/jason/ebin/Elixir.Jason.Decoder.beam b/_build/test/lib/jason/ebin/Elixir.Jason.Decoder.beam deleted file mode 100644 index dc463be..0000000 Binary files a/_build/test/lib/jason/ebin/Elixir.Jason.Decoder.beam and /dev/null differ diff --git a/_build/test/lib/jason/ebin/Elixir.Jason.Encode.beam b/_build/test/lib/jason/ebin/Elixir.Jason.Encode.beam deleted file mode 100644 index d2c56c9..0000000 Binary files a/_build/test/lib/jason/ebin/Elixir.Jason.Encode.beam and /dev/null differ diff --git a/_build/test/lib/jason/ebin/Elixir.Jason.EncodeError.beam b/_build/test/lib/jason/ebin/Elixir.Jason.EncodeError.beam deleted file mode 100644 index d694656..0000000 Binary files a/_build/test/lib/jason/ebin/Elixir.Jason.EncodeError.beam and /dev/null differ diff --git a/_build/test/lib/jason/ebin/Elixir.Jason.Encoder.Any.beam b/_build/test/lib/jason/ebin/Elixir.Jason.Encoder.Any.beam deleted file mode 100644 index e752fd3..0000000 Binary files a/_build/test/lib/jason/ebin/Elixir.Jason.Encoder.Any.beam and /dev/null differ diff --git a/_build/test/lib/jason/ebin/Elixir.Jason.Encoder.Atom.beam b/_build/test/lib/jason/ebin/Elixir.Jason.Encoder.Atom.beam deleted file mode 100644 index 9420f1a..0000000 Binary files a/_build/test/lib/jason/ebin/Elixir.Jason.Encoder.Atom.beam and /dev/null differ diff --git a/_build/test/lib/jason/ebin/Elixir.Jason.Encoder.BitString.beam b/_build/test/lib/jason/ebin/Elixir.Jason.Encoder.BitString.beam deleted file mode 100644 index ba4448d..0000000 Binary files a/_build/test/lib/jason/ebin/Elixir.Jason.Encoder.BitString.beam and /dev/null differ diff --git a/_build/test/lib/jason/ebin/Elixir.Jason.Encoder.Date.beam b/_build/test/lib/jason/ebin/Elixir.Jason.Encoder.Date.beam deleted file mode 100644 index 4e5b6a6..0000000 Binary files a/_build/test/lib/jason/ebin/Elixir.Jason.Encoder.Date.beam and /dev/null differ diff --git a/_build/test/lib/jason/ebin/Elixir.Jason.Encoder.DateTime.beam b/_build/test/lib/jason/ebin/Elixir.Jason.Encoder.DateTime.beam deleted file mode 100644 index eeba8c3..0000000 Binary files a/_build/test/lib/jason/ebin/Elixir.Jason.Encoder.DateTime.beam and /dev/null differ diff --git a/_build/test/lib/jason/ebin/Elixir.Jason.Encoder.Float.beam b/_build/test/lib/jason/ebin/Elixir.Jason.Encoder.Float.beam deleted file mode 100644 index 49bfc5b..0000000 Binary files a/_build/test/lib/jason/ebin/Elixir.Jason.Encoder.Float.beam and /dev/null differ diff --git a/_build/test/lib/jason/ebin/Elixir.Jason.Encoder.Integer.beam b/_build/test/lib/jason/ebin/Elixir.Jason.Encoder.Integer.beam deleted file mode 100644 index 438e32e..0000000 Binary files a/_build/test/lib/jason/ebin/Elixir.Jason.Encoder.Integer.beam and /dev/null differ diff --git a/_build/test/lib/jason/ebin/Elixir.Jason.Encoder.Jason.Fragment.beam b/_build/test/lib/jason/ebin/Elixir.Jason.Encoder.Jason.Fragment.beam deleted file mode 100644 index b6f47fa..0000000 Binary files a/_build/test/lib/jason/ebin/Elixir.Jason.Encoder.Jason.Fragment.beam and /dev/null differ diff --git a/_build/test/lib/jason/ebin/Elixir.Jason.Encoder.Jason.OrderedObject.beam b/_build/test/lib/jason/ebin/Elixir.Jason.Encoder.Jason.OrderedObject.beam deleted file mode 100644 index a5941e4..0000000 Binary files a/_build/test/lib/jason/ebin/Elixir.Jason.Encoder.Jason.OrderedObject.beam and /dev/null differ diff --git a/_build/test/lib/jason/ebin/Elixir.Jason.Encoder.List.beam b/_build/test/lib/jason/ebin/Elixir.Jason.Encoder.List.beam deleted file mode 100644 index d3bbec9..0000000 Binary files a/_build/test/lib/jason/ebin/Elixir.Jason.Encoder.List.beam and /dev/null differ diff --git a/_build/test/lib/jason/ebin/Elixir.Jason.Encoder.Map.beam b/_build/test/lib/jason/ebin/Elixir.Jason.Encoder.Map.beam deleted file mode 100644 index 8c27e63..0000000 Binary files a/_build/test/lib/jason/ebin/Elixir.Jason.Encoder.Map.beam and /dev/null differ diff --git a/_build/test/lib/jason/ebin/Elixir.Jason.Encoder.NaiveDateTime.beam b/_build/test/lib/jason/ebin/Elixir.Jason.Encoder.NaiveDateTime.beam deleted file mode 100644 index 2ad5ed0..0000000 Binary files a/_build/test/lib/jason/ebin/Elixir.Jason.Encoder.NaiveDateTime.beam and /dev/null differ diff --git a/_build/test/lib/jason/ebin/Elixir.Jason.Encoder.Time.beam b/_build/test/lib/jason/ebin/Elixir.Jason.Encoder.Time.beam deleted file mode 100644 index b3408c1..0000000 Binary files a/_build/test/lib/jason/ebin/Elixir.Jason.Encoder.Time.beam and /dev/null differ diff --git a/_build/test/lib/jason/ebin/Elixir.Jason.Encoder.beam b/_build/test/lib/jason/ebin/Elixir.Jason.Encoder.beam deleted file mode 100644 index 8109bf1..0000000 Binary files a/_build/test/lib/jason/ebin/Elixir.Jason.Encoder.beam and /dev/null differ diff --git a/_build/test/lib/jason/ebin/Elixir.Jason.Formatter.beam b/_build/test/lib/jason/ebin/Elixir.Jason.Formatter.beam deleted file mode 100644 index 76e7fdd..0000000 Binary files a/_build/test/lib/jason/ebin/Elixir.Jason.Formatter.beam and /dev/null differ diff --git a/_build/test/lib/jason/ebin/Elixir.Jason.Fragment.beam b/_build/test/lib/jason/ebin/Elixir.Jason.Fragment.beam deleted file mode 100644 index 0c3db6f..0000000 Binary files a/_build/test/lib/jason/ebin/Elixir.Jason.Fragment.beam and /dev/null differ diff --git a/_build/test/lib/jason/ebin/Elixir.Jason.Helpers.beam b/_build/test/lib/jason/ebin/Elixir.Jason.Helpers.beam deleted file mode 100644 index 1d136f7..0000000 Binary files a/_build/test/lib/jason/ebin/Elixir.Jason.Helpers.beam and /dev/null differ diff --git a/_build/test/lib/jason/ebin/Elixir.Jason.OrderedObject.beam b/_build/test/lib/jason/ebin/Elixir.Jason.OrderedObject.beam deleted file mode 100644 index 3bd0da3..0000000 Binary files a/_build/test/lib/jason/ebin/Elixir.Jason.OrderedObject.beam and /dev/null differ diff --git a/_build/test/lib/jason/ebin/Elixir.Jason.Sigil.beam b/_build/test/lib/jason/ebin/Elixir.Jason.Sigil.beam deleted file mode 100644 index a418c75..0000000 Binary files a/_build/test/lib/jason/ebin/Elixir.Jason.Sigil.beam and /dev/null differ diff --git a/_build/test/lib/jason/ebin/Elixir.Jason.beam b/_build/test/lib/jason/ebin/Elixir.Jason.beam deleted file mode 100644 index 9a9c5b6..0000000 Binary files a/_build/test/lib/jason/ebin/Elixir.Jason.beam and /dev/null differ diff --git a/_build/test/lib/jason/ebin/jason.app b/_build/test/lib/jason/ebin/jason.app deleted file mode 100644 index 2d536c0..0000000 --- a/_build/test/lib/jason/ebin/jason.app +++ /dev/null @@ -1 +0,0 @@ -{application,jason,[{modules,['Elixir.Enumerable.Jason.OrderedObject','Elixir.Jason','Elixir.Jason.Codegen','Elixir.Jason.DecodeError','Elixir.Jason.Decoder','Elixir.Jason.Decoder.Unescape','Elixir.Jason.Encode','Elixir.Jason.EncodeError','Elixir.Jason.Encoder','Elixir.Jason.Encoder.Any','Elixir.Jason.Encoder.Atom','Elixir.Jason.Encoder.BitString','Elixir.Jason.Encoder.Date','Elixir.Jason.Encoder.DateTime','Elixir.Jason.Encoder.Float','Elixir.Jason.Encoder.Integer','Elixir.Jason.Encoder.Jason.Fragment','Elixir.Jason.Encoder.Jason.OrderedObject','Elixir.Jason.Encoder.List','Elixir.Jason.Encoder.Map','Elixir.Jason.Encoder.NaiveDateTime','Elixir.Jason.Encoder.Time','Elixir.Jason.Formatter','Elixir.Jason.Fragment','Elixir.Jason.Helpers','Elixir.Jason.OrderedObject','Elixir.Jason.Sigil']},{optional_applications,[decimal]},{applications,[kernel,stdlib,elixir,decimal]},{description,"A blazing fast JSON parser and generator in pure Elixir.\n"},{registered,[]},{vsn,"1.4.4"}]}. \ No newline at end of file diff --git a/_build/test/lib/mime/.mix/compile.elixir b/_build/test/lib/mime/.mix/compile.elixir deleted file mode 100644 index dbb2ff2..0000000 Binary files a/_build/test/lib/mime/.mix/compile.elixir and /dev/null differ diff --git a/_build/test/lib/mime/.mix/compile.elixir_scm b/_build/test/lib/mime/.mix/compile.elixir_scm deleted file mode 100644 index 4066741..0000000 Binary files a/_build/test/lib/mime/.mix/compile.elixir_scm and /dev/null differ diff --git a/_build/test/lib/mime/ebin/Elixir.MIME.beam b/_build/test/lib/mime/ebin/Elixir.MIME.beam deleted file mode 100644 index da9ca3b..0000000 Binary files a/_build/test/lib/mime/ebin/Elixir.MIME.beam and /dev/null differ diff --git a/_build/test/lib/mime/ebin/mime.app b/_build/test/lib/mime/ebin/mime.app deleted file mode 100644 index cdfbbb8..0000000 --- a/_build/test/lib/mime/ebin/mime.app +++ /dev/null @@ -1 +0,0 @@ -{application,mime,[{modules,['Elixir.MIME']},{compile_env,[{mime,[extensions],error},{mime,[suffixes],error},{mime,[types],error}]},{optional_applications,[]},{applications,[kernel,stdlib,elixir,logger]},{description,"A MIME type module for Elixir"},{registered,[]},{vsn,"2.0.7"},{env,[]}]}. \ No newline at end of file diff --git a/_build/test/lib/plug/.mix/compile.elixir b/_build/test/lib/plug/.mix/compile.elixir deleted file mode 100644 index 1ff8170..0000000 Binary files a/_build/test/lib/plug/.mix/compile.elixir and /dev/null differ diff --git a/_build/test/lib/plug/.mix/compile.elixir_scm b/_build/test/lib/plug/.mix/compile.elixir_scm deleted file mode 100644 index 4066741..0000000 Binary files a/_build/test/lib/plug/.mix/compile.elixir_scm and /dev/null differ diff --git a/_build/test/lib/plug/.mix/compile.erlang b/_build/test/lib/plug/.mix/compile.erlang deleted file mode 100644 index fe5f242..0000000 Binary files a/_build/test/lib/plug/.mix/compile.erlang and /dev/null differ diff --git a/_build/test/lib/plug/ebin/Elixir.Inspect.Plug.Conn.beam b/_build/test/lib/plug/ebin/Elixir.Inspect.Plug.Conn.beam deleted file mode 100644 index 678d766..0000000 Binary files a/_build/test/lib/plug/ebin/Elixir.Inspect.Plug.Conn.beam and /dev/null differ diff --git a/_build/test/lib/plug/ebin/Elixir.Plug.Adapters.Cowboy.beam b/_build/test/lib/plug/ebin/Elixir.Plug.Adapters.Cowboy.beam deleted file mode 100644 index b3f79b1..0000000 Binary files a/_build/test/lib/plug/ebin/Elixir.Plug.Adapters.Cowboy.beam and /dev/null differ diff --git a/_build/test/lib/plug/ebin/Elixir.Plug.Adapters.Test.Conn.beam b/_build/test/lib/plug/ebin/Elixir.Plug.Adapters.Test.Conn.beam deleted file mode 100644 index c203a17..0000000 Binary files a/_build/test/lib/plug/ebin/Elixir.Plug.Adapters.Test.Conn.beam and /dev/null differ diff --git a/_build/test/lib/plug/ebin/Elixir.Plug.Application.beam b/_build/test/lib/plug/ebin/Elixir.Plug.Application.beam deleted file mode 100644 index b4ef468..0000000 Binary files a/_build/test/lib/plug/ebin/Elixir.Plug.Application.beam and /dev/null differ diff --git a/_build/test/lib/plug/ebin/Elixir.Plug.BadRequestError.beam b/_build/test/lib/plug/ebin/Elixir.Plug.BadRequestError.beam deleted file mode 100644 index 9785a8d..0000000 Binary files a/_build/test/lib/plug/ebin/Elixir.Plug.BadRequestError.beam and /dev/null differ diff --git a/_build/test/lib/plug/ebin/Elixir.Plug.BasicAuth.beam b/_build/test/lib/plug/ebin/Elixir.Plug.BasicAuth.beam deleted file mode 100644 index ab4b5b0..0000000 Binary files a/_build/test/lib/plug/ebin/Elixir.Plug.BasicAuth.beam and /dev/null differ diff --git a/_build/test/lib/plug/ebin/Elixir.Plug.Builder.beam b/_build/test/lib/plug/ebin/Elixir.Plug.Builder.beam deleted file mode 100644 index e1c23fe..0000000 Binary files a/_build/test/lib/plug/ebin/Elixir.Plug.Builder.beam and /dev/null differ diff --git a/_build/test/lib/plug/ebin/Elixir.Plug.CSRFProtection.InvalidCSRFTokenError.beam b/_build/test/lib/plug/ebin/Elixir.Plug.CSRFProtection.InvalidCSRFTokenError.beam deleted file mode 100644 index 4e18975..0000000 Binary files a/_build/test/lib/plug/ebin/Elixir.Plug.CSRFProtection.InvalidCSRFTokenError.beam and /dev/null differ diff --git a/_build/test/lib/plug/ebin/Elixir.Plug.CSRFProtection.InvalidCrossOriginRequestError.beam b/_build/test/lib/plug/ebin/Elixir.Plug.CSRFProtection.InvalidCrossOriginRequestError.beam deleted file mode 100644 index 4215cfb..0000000 Binary files a/_build/test/lib/plug/ebin/Elixir.Plug.CSRFProtection.InvalidCrossOriginRequestError.beam and /dev/null differ diff --git a/_build/test/lib/plug/ebin/Elixir.Plug.CSRFProtection.beam b/_build/test/lib/plug/ebin/Elixir.Plug.CSRFProtection.beam deleted file mode 100644 index 993b79c..0000000 Binary files a/_build/test/lib/plug/ebin/Elixir.Plug.CSRFProtection.beam and /dev/null differ diff --git a/_build/test/lib/plug/ebin/Elixir.Plug.Conn.Adapter.beam b/_build/test/lib/plug/ebin/Elixir.Plug.Conn.Adapter.beam deleted file mode 100644 index bb713db..0000000 Binary files a/_build/test/lib/plug/ebin/Elixir.Plug.Conn.Adapter.beam and /dev/null differ diff --git a/_build/test/lib/plug/ebin/Elixir.Plug.Conn.AlreadySentError.beam b/_build/test/lib/plug/ebin/Elixir.Plug.Conn.AlreadySentError.beam deleted file mode 100644 index b072f02..0000000 Binary files a/_build/test/lib/plug/ebin/Elixir.Plug.Conn.AlreadySentError.beam and /dev/null differ diff --git a/_build/test/lib/plug/ebin/Elixir.Plug.Conn.CookieOverflowError.beam b/_build/test/lib/plug/ebin/Elixir.Plug.Conn.CookieOverflowError.beam deleted file mode 100644 index 634ea8b..0000000 Binary files a/_build/test/lib/plug/ebin/Elixir.Plug.Conn.CookieOverflowError.beam and /dev/null differ diff --git a/_build/test/lib/plug/ebin/Elixir.Plug.Conn.Cookies.beam b/_build/test/lib/plug/ebin/Elixir.Plug.Conn.Cookies.beam deleted file mode 100644 index 0a9ceb5..0000000 Binary files a/_build/test/lib/plug/ebin/Elixir.Plug.Conn.Cookies.beam and /dev/null differ diff --git a/_build/test/lib/plug/ebin/Elixir.Plug.Conn.InvalidHeaderError.beam b/_build/test/lib/plug/ebin/Elixir.Plug.Conn.InvalidHeaderError.beam deleted file mode 100644 index 15db502..0000000 Binary files a/_build/test/lib/plug/ebin/Elixir.Plug.Conn.InvalidHeaderError.beam and /dev/null differ diff --git a/_build/test/lib/plug/ebin/Elixir.Plug.Conn.InvalidQueryError.beam b/_build/test/lib/plug/ebin/Elixir.Plug.Conn.InvalidQueryError.beam deleted file mode 100644 index 2e6436e..0000000 Binary files a/_build/test/lib/plug/ebin/Elixir.Plug.Conn.InvalidQueryError.beam and /dev/null differ diff --git a/_build/test/lib/plug/ebin/Elixir.Plug.Conn.NotSentError.beam b/_build/test/lib/plug/ebin/Elixir.Plug.Conn.NotSentError.beam deleted file mode 100644 index 7bd58fe..0000000 Binary files a/_build/test/lib/plug/ebin/Elixir.Plug.Conn.NotSentError.beam and /dev/null differ diff --git a/_build/test/lib/plug/ebin/Elixir.Plug.Conn.Query.beam b/_build/test/lib/plug/ebin/Elixir.Plug.Conn.Query.beam deleted file mode 100644 index 73975ff..0000000 Binary files a/_build/test/lib/plug/ebin/Elixir.Plug.Conn.Query.beam and /dev/null differ diff --git a/_build/test/lib/plug/ebin/Elixir.Plug.Conn.Status.beam b/_build/test/lib/plug/ebin/Elixir.Plug.Conn.Status.beam deleted file mode 100644 index ecb4a52..0000000 Binary files a/_build/test/lib/plug/ebin/Elixir.Plug.Conn.Status.beam and /dev/null differ diff --git a/_build/test/lib/plug/ebin/Elixir.Plug.Conn.Unfetched.beam b/_build/test/lib/plug/ebin/Elixir.Plug.Conn.Unfetched.beam deleted file mode 100644 index 1c8d897..0000000 Binary files a/_build/test/lib/plug/ebin/Elixir.Plug.Conn.Unfetched.beam and /dev/null differ diff --git a/_build/test/lib/plug/ebin/Elixir.Plug.Conn.Utils.beam b/_build/test/lib/plug/ebin/Elixir.Plug.Conn.Utils.beam deleted file mode 100644 index 2094593..0000000 Binary files a/_build/test/lib/plug/ebin/Elixir.Plug.Conn.Utils.beam and /dev/null differ diff --git a/_build/test/lib/plug/ebin/Elixir.Plug.Conn.WrapperError.beam b/_build/test/lib/plug/ebin/Elixir.Plug.Conn.WrapperError.beam deleted file mode 100644 index 869b4a9..0000000 Binary files a/_build/test/lib/plug/ebin/Elixir.Plug.Conn.WrapperError.beam and /dev/null differ diff --git a/_build/test/lib/plug/ebin/Elixir.Plug.Conn.beam b/_build/test/lib/plug/ebin/Elixir.Plug.Conn.beam deleted file mode 100644 index dcb38e7..0000000 Binary files a/_build/test/lib/plug/ebin/Elixir.Plug.Conn.beam and /dev/null differ diff --git a/_build/test/lib/plug/ebin/Elixir.Plug.Debugger.beam b/_build/test/lib/plug/ebin/Elixir.Plug.Debugger.beam deleted file mode 100644 index 1765fa3..0000000 Binary files a/_build/test/lib/plug/ebin/Elixir.Plug.Debugger.beam and /dev/null differ diff --git a/_build/test/lib/plug/ebin/Elixir.Plug.ErrorHandler.beam b/_build/test/lib/plug/ebin/Elixir.Plug.ErrorHandler.beam deleted file mode 100644 index 0221932..0000000 Binary files a/_build/test/lib/plug/ebin/Elixir.Plug.ErrorHandler.beam and /dev/null differ diff --git a/_build/test/lib/plug/ebin/Elixir.Plug.Exception.Any.beam b/_build/test/lib/plug/ebin/Elixir.Plug.Exception.Any.beam deleted file mode 100644 index c070159..0000000 Binary files a/_build/test/lib/plug/ebin/Elixir.Plug.Exception.Any.beam and /dev/null differ diff --git a/_build/test/lib/plug/ebin/Elixir.Plug.Exception.beam b/_build/test/lib/plug/ebin/Elixir.Plug.Exception.beam deleted file mode 100644 index e0e0d2d..0000000 Binary files a/_build/test/lib/plug/ebin/Elixir.Plug.Exception.beam and /dev/null differ diff --git a/_build/test/lib/plug/ebin/Elixir.Plug.HTML.beam b/_build/test/lib/plug/ebin/Elixir.Plug.HTML.beam deleted file mode 100644 index b68d3fa..0000000 Binary files a/_build/test/lib/plug/ebin/Elixir.Plug.HTML.beam and /dev/null differ diff --git a/_build/test/lib/plug/ebin/Elixir.Plug.Head.beam b/_build/test/lib/plug/ebin/Elixir.Plug.Head.beam deleted file mode 100644 index 04d8538..0000000 Binary files a/_build/test/lib/plug/ebin/Elixir.Plug.Head.beam and /dev/null differ diff --git a/_build/test/lib/plug/ebin/Elixir.Plug.Logger.beam b/_build/test/lib/plug/ebin/Elixir.Plug.Logger.beam deleted file mode 100644 index ea99ceb..0000000 Binary files a/_build/test/lib/plug/ebin/Elixir.Plug.Logger.beam and /dev/null differ diff --git a/_build/test/lib/plug/ebin/Elixir.Plug.MIME.beam b/_build/test/lib/plug/ebin/Elixir.Plug.MIME.beam deleted file mode 100644 index bf4ffb7..0000000 Binary files a/_build/test/lib/plug/ebin/Elixir.Plug.MIME.beam and /dev/null differ diff --git a/_build/test/lib/plug/ebin/Elixir.Plug.MethodOverride.beam b/_build/test/lib/plug/ebin/Elixir.Plug.MethodOverride.beam deleted file mode 100644 index f7ff812..0000000 Binary files a/_build/test/lib/plug/ebin/Elixir.Plug.MethodOverride.beam and /dev/null differ diff --git a/_build/test/lib/plug/ebin/Elixir.Plug.Parsers.BadEncodingError.beam b/_build/test/lib/plug/ebin/Elixir.Plug.Parsers.BadEncodingError.beam deleted file mode 100644 index b4a0d2a..0000000 Binary files a/_build/test/lib/plug/ebin/Elixir.Plug.Parsers.BadEncodingError.beam and /dev/null differ diff --git a/_build/test/lib/plug/ebin/Elixir.Plug.Parsers.JSON.beam b/_build/test/lib/plug/ebin/Elixir.Plug.Parsers.JSON.beam deleted file mode 100644 index 4b6de52..0000000 Binary files a/_build/test/lib/plug/ebin/Elixir.Plug.Parsers.JSON.beam and /dev/null differ diff --git a/_build/test/lib/plug/ebin/Elixir.Plug.Parsers.MULTIPART.beam b/_build/test/lib/plug/ebin/Elixir.Plug.Parsers.MULTIPART.beam deleted file mode 100644 index 0c4667d..0000000 Binary files a/_build/test/lib/plug/ebin/Elixir.Plug.Parsers.MULTIPART.beam and /dev/null differ diff --git a/_build/test/lib/plug/ebin/Elixir.Plug.Parsers.ParseError.beam b/_build/test/lib/plug/ebin/Elixir.Plug.Parsers.ParseError.beam deleted file mode 100644 index 1da6a8c..0000000 Binary files a/_build/test/lib/plug/ebin/Elixir.Plug.Parsers.ParseError.beam and /dev/null differ diff --git a/_build/test/lib/plug/ebin/Elixir.Plug.Parsers.RequestTooLargeError.beam b/_build/test/lib/plug/ebin/Elixir.Plug.Parsers.RequestTooLargeError.beam deleted file mode 100644 index ed5ee86..0000000 Binary files a/_build/test/lib/plug/ebin/Elixir.Plug.Parsers.RequestTooLargeError.beam and /dev/null differ diff --git a/_build/test/lib/plug/ebin/Elixir.Plug.Parsers.URLENCODED.beam b/_build/test/lib/plug/ebin/Elixir.Plug.Parsers.URLENCODED.beam deleted file mode 100644 index a345f21..0000000 Binary files a/_build/test/lib/plug/ebin/Elixir.Plug.Parsers.URLENCODED.beam and /dev/null differ diff --git a/_build/test/lib/plug/ebin/Elixir.Plug.Parsers.UnsupportedMediaTypeError.beam b/_build/test/lib/plug/ebin/Elixir.Plug.Parsers.UnsupportedMediaTypeError.beam deleted file mode 100644 index fffd3bd..0000000 Binary files a/_build/test/lib/plug/ebin/Elixir.Plug.Parsers.UnsupportedMediaTypeError.beam and /dev/null differ diff --git a/_build/test/lib/plug/ebin/Elixir.Plug.Parsers.beam b/_build/test/lib/plug/ebin/Elixir.Plug.Parsers.beam deleted file mode 100644 index 57f3f0c..0000000 Binary files a/_build/test/lib/plug/ebin/Elixir.Plug.Parsers.beam and /dev/null differ diff --git a/_build/test/lib/plug/ebin/Elixir.Plug.RequestId.beam b/_build/test/lib/plug/ebin/Elixir.Plug.RequestId.beam deleted file mode 100644 index 297ec19..0000000 Binary files a/_build/test/lib/plug/ebin/Elixir.Plug.RequestId.beam and /dev/null differ diff --git a/_build/test/lib/plug/ebin/Elixir.Plug.RewriteOn.beam b/_build/test/lib/plug/ebin/Elixir.Plug.RewriteOn.beam deleted file mode 100644 index 25d8e9e..0000000 Binary files a/_build/test/lib/plug/ebin/Elixir.Plug.RewriteOn.beam and /dev/null differ diff --git a/_build/test/lib/plug/ebin/Elixir.Plug.Router.InvalidSpecError.beam b/_build/test/lib/plug/ebin/Elixir.Plug.Router.InvalidSpecError.beam deleted file mode 100644 index 485e878..0000000 Binary files a/_build/test/lib/plug/ebin/Elixir.Plug.Router.InvalidSpecError.beam and /dev/null differ diff --git a/_build/test/lib/plug/ebin/Elixir.Plug.Router.MalformedURIError.beam b/_build/test/lib/plug/ebin/Elixir.Plug.Router.MalformedURIError.beam deleted file mode 100644 index a6e4753..0000000 Binary files a/_build/test/lib/plug/ebin/Elixir.Plug.Router.MalformedURIError.beam and /dev/null differ diff --git a/_build/test/lib/plug/ebin/Elixir.Plug.Router.Utils.beam b/_build/test/lib/plug/ebin/Elixir.Plug.Router.Utils.beam deleted file mode 100644 index 647e6d5..0000000 Binary files a/_build/test/lib/plug/ebin/Elixir.Plug.Router.Utils.beam and /dev/null differ diff --git a/_build/test/lib/plug/ebin/Elixir.Plug.Router.beam b/_build/test/lib/plug/ebin/Elixir.Plug.Router.beam deleted file mode 100644 index 931c07c..0000000 Binary files a/_build/test/lib/plug/ebin/Elixir.Plug.Router.beam and /dev/null differ diff --git a/_build/test/lib/plug/ebin/Elixir.Plug.SSL.beam b/_build/test/lib/plug/ebin/Elixir.Plug.SSL.beam deleted file mode 100644 index 6b825bd..0000000 Binary files a/_build/test/lib/plug/ebin/Elixir.Plug.SSL.beam and /dev/null differ diff --git a/_build/test/lib/plug/ebin/Elixir.Plug.Session.COOKIE.beam b/_build/test/lib/plug/ebin/Elixir.Plug.Session.COOKIE.beam deleted file mode 100644 index 9c40217..0000000 Binary files a/_build/test/lib/plug/ebin/Elixir.Plug.Session.COOKIE.beam and /dev/null differ diff --git a/_build/test/lib/plug/ebin/Elixir.Plug.Session.ETS.beam b/_build/test/lib/plug/ebin/Elixir.Plug.Session.ETS.beam deleted file mode 100644 index 66d65a3..0000000 Binary files a/_build/test/lib/plug/ebin/Elixir.Plug.Session.ETS.beam and /dev/null differ diff --git a/_build/test/lib/plug/ebin/Elixir.Plug.Session.Store.beam b/_build/test/lib/plug/ebin/Elixir.Plug.Session.Store.beam deleted file mode 100644 index b2add0e..0000000 Binary files a/_build/test/lib/plug/ebin/Elixir.Plug.Session.Store.beam and /dev/null differ diff --git a/_build/test/lib/plug/ebin/Elixir.Plug.Session.beam b/_build/test/lib/plug/ebin/Elixir.Plug.Session.beam deleted file mode 100644 index af41b86..0000000 Binary files a/_build/test/lib/plug/ebin/Elixir.Plug.Session.beam and /dev/null differ diff --git a/_build/test/lib/plug/ebin/Elixir.Plug.Static.InvalidPathError.beam b/_build/test/lib/plug/ebin/Elixir.Plug.Static.InvalidPathError.beam deleted file mode 100644 index 4f0fae2..0000000 Binary files a/_build/test/lib/plug/ebin/Elixir.Plug.Static.InvalidPathError.beam and /dev/null differ diff --git a/_build/test/lib/plug/ebin/Elixir.Plug.Static.beam b/_build/test/lib/plug/ebin/Elixir.Plug.Static.beam deleted file mode 100644 index fe6059d..0000000 Binary files a/_build/test/lib/plug/ebin/Elixir.Plug.Static.beam and /dev/null differ diff --git a/_build/test/lib/plug/ebin/Elixir.Plug.Telemetry.beam b/_build/test/lib/plug/ebin/Elixir.Plug.Telemetry.beam deleted file mode 100644 index d201369..0000000 Binary files a/_build/test/lib/plug/ebin/Elixir.Plug.Telemetry.beam and /dev/null differ diff --git a/_build/test/lib/plug/ebin/Elixir.Plug.Test.beam b/_build/test/lib/plug/ebin/Elixir.Plug.Test.beam deleted file mode 100644 index 158740c..0000000 Binary files a/_build/test/lib/plug/ebin/Elixir.Plug.Test.beam and /dev/null differ diff --git a/_build/test/lib/plug/ebin/Elixir.Plug.TimeoutError.beam b/_build/test/lib/plug/ebin/Elixir.Plug.TimeoutError.beam deleted file mode 100644 index 5998a74..0000000 Binary files a/_build/test/lib/plug/ebin/Elixir.Plug.TimeoutError.beam and /dev/null differ diff --git a/_build/test/lib/plug/ebin/Elixir.Plug.Upload.Supervisor.beam b/_build/test/lib/plug/ebin/Elixir.Plug.Upload.Supervisor.beam deleted file mode 100644 index 48bb0b9..0000000 Binary files a/_build/test/lib/plug/ebin/Elixir.Plug.Upload.Supervisor.beam and /dev/null differ diff --git a/_build/test/lib/plug/ebin/Elixir.Plug.Upload.Terminator.beam b/_build/test/lib/plug/ebin/Elixir.Plug.Upload.Terminator.beam deleted file mode 100644 index f87fc4e..0000000 Binary files a/_build/test/lib/plug/ebin/Elixir.Plug.Upload.Terminator.beam and /dev/null differ diff --git a/_build/test/lib/plug/ebin/Elixir.Plug.Upload.beam b/_build/test/lib/plug/ebin/Elixir.Plug.Upload.beam deleted file mode 100644 index 2bb1ec0..0000000 Binary files a/_build/test/lib/plug/ebin/Elixir.Plug.Upload.beam and /dev/null differ diff --git a/_build/test/lib/plug/ebin/Elixir.Plug.UploadError.beam b/_build/test/lib/plug/ebin/Elixir.Plug.UploadError.beam deleted file mode 100644 index 326e9cd..0000000 Binary files a/_build/test/lib/plug/ebin/Elixir.Plug.UploadError.beam and /dev/null differ diff --git a/_build/test/lib/plug/ebin/Elixir.Plug.beam b/_build/test/lib/plug/ebin/Elixir.Plug.beam deleted file mode 100644 index 3eb76a4..0000000 Binary files a/_build/test/lib/plug/ebin/Elixir.Plug.beam and /dev/null differ diff --git a/_build/test/lib/plug/ebin/plug.app b/_build/test/lib/plug/ebin/plug.app deleted file mode 100644 index c00d088..0000000 --- a/_build/test/lib/plug/ebin/plug.app +++ /dev/null @@ -1 +0,0 @@ -{application,plug,[{modules,['Elixir.Inspect.Plug.Conn','Elixir.Plug','Elixir.Plug.Adapters.Cowboy','Elixir.Plug.Adapters.Test.Conn','Elixir.Plug.Application','Elixir.Plug.BadRequestError','Elixir.Plug.BasicAuth','Elixir.Plug.Builder','Elixir.Plug.CSRFProtection','Elixir.Plug.CSRFProtection.InvalidCSRFTokenError','Elixir.Plug.CSRFProtection.InvalidCrossOriginRequestError','Elixir.Plug.Conn','Elixir.Plug.Conn.Adapter','Elixir.Plug.Conn.AlreadySentError','Elixir.Plug.Conn.CookieOverflowError','Elixir.Plug.Conn.Cookies','Elixir.Plug.Conn.InvalidHeaderError','Elixir.Plug.Conn.InvalidQueryError','Elixir.Plug.Conn.NotSentError','Elixir.Plug.Conn.Query','Elixir.Plug.Conn.Status','Elixir.Plug.Conn.Unfetched','Elixir.Plug.Conn.Utils','Elixir.Plug.Conn.WrapperError','Elixir.Plug.Debugger','Elixir.Plug.ErrorHandler','Elixir.Plug.Exception','Elixir.Plug.Exception.Any','Elixir.Plug.HTML','Elixir.Plug.Head','Elixir.Plug.Logger','Elixir.Plug.MIME','Elixir.Plug.MethodOverride','Elixir.Plug.Parsers','Elixir.Plug.Parsers.BadEncodingError','Elixir.Plug.Parsers.JSON','Elixir.Plug.Parsers.MULTIPART','Elixir.Plug.Parsers.ParseError','Elixir.Plug.Parsers.RequestTooLargeError','Elixir.Plug.Parsers.URLENCODED','Elixir.Plug.Parsers.UnsupportedMediaTypeError','Elixir.Plug.RequestId','Elixir.Plug.RewriteOn','Elixir.Plug.Router','Elixir.Plug.Router.InvalidSpecError','Elixir.Plug.Router.MalformedURIError','Elixir.Plug.Router.Utils','Elixir.Plug.SSL','Elixir.Plug.Session','Elixir.Plug.Session.COOKIE','Elixir.Plug.Session.ETS','Elixir.Plug.Session.Store','Elixir.Plug.Static','Elixir.Plug.Static.InvalidPathError','Elixir.Plug.Telemetry','Elixir.Plug.Test','Elixir.Plug.TimeoutError','Elixir.Plug.Upload','Elixir.Plug.Upload.Supervisor','Elixir.Plug.Upload.Terminator','Elixir.Plug.UploadError',plug_multipart]},{compile_env,[{plug,[mimes],error},{plug,[statuses],error}]},{optional_applications,[]},{applications,[kernel,stdlib,elixir,logger,eex,mime,plug_crypto,telemetry]},{description,"Compose web applications with functions"},{registered,[]},{vsn,"1.19.1"},{mod,{'Elixir.Plug.Application',[]}},{env,[{validate_header_keys_during_test,true}]}]}. \ No newline at end of file diff --git a/_build/test/lib/plug/ebin/plug_multipart.beam b/_build/test/lib/plug/ebin/plug_multipart.beam deleted file mode 100644 index 6ac3545..0000000 Binary files a/_build/test/lib/plug/ebin/plug_multipart.beam and /dev/null differ diff --git a/_build/test/lib/plug_crypto/.mix/compile.elixir b/_build/test/lib/plug_crypto/.mix/compile.elixir deleted file mode 100644 index 33cb85a..0000000 Binary files a/_build/test/lib/plug_crypto/.mix/compile.elixir and /dev/null differ diff --git a/_build/test/lib/plug_crypto/.mix/compile.elixir_scm b/_build/test/lib/plug_crypto/.mix/compile.elixir_scm deleted file mode 100644 index 4066741..0000000 Binary files a/_build/test/lib/plug_crypto/.mix/compile.elixir_scm and /dev/null differ diff --git a/_build/test/lib/plug_crypto/ebin/Elixir.Plug.Crypto.Application.beam b/_build/test/lib/plug_crypto/ebin/Elixir.Plug.Crypto.Application.beam deleted file mode 100644 index 35d0872..0000000 Binary files a/_build/test/lib/plug_crypto/ebin/Elixir.Plug.Crypto.Application.beam and /dev/null differ diff --git a/_build/test/lib/plug_crypto/ebin/Elixir.Plug.Crypto.KeyGenerator.beam b/_build/test/lib/plug_crypto/ebin/Elixir.Plug.Crypto.KeyGenerator.beam deleted file mode 100644 index d041718..0000000 Binary files a/_build/test/lib/plug_crypto/ebin/Elixir.Plug.Crypto.KeyGenerator.beam and /dev/null differ diff --git a/_build/test/lib/plug_crypto/ebin/Elixir.Plug.Crypto.MessageEncryptor.beam b/_build/test/lib/plug_crypto/ebin/Elixir.Plug.Crypto.MessageEncryptor.beam deleted file mode 100644 index daf3769..0000000 Binary files a/_build/test/lib/plug_crypto/ebin/Elixir.Plug.Crypto.MessageEncryptor.beam and /dev/null differ diff --git a/_build/test/lib/plug_crypto/ebin/Elixir.Plug.Crypto.MessageVerifier.beam b/_build/test/lib/plug_crypto/ebin/Elixir.Plug.Crypto.MessageVerifier.beam deleted file mode 100644 index 3937903..0000000 Binary files a/_build/test/lib/plug_crypto/ebin/Elixir.Plug.Crypto.MessageVerifier.beam and /dev/null differ diff --git a/_build/test/lib/plug_crypto/ebin/Elixir.Plug.Crypto.beam b/_build/test/lib/plug_crypto/ebin/Elixir.Plug.Crypto.beam deleted file mode 100644 index ced9674..0000000 Binary files a/_build/test/lib/plug_crypto/ebin/Elixir.Plug.Crypto.beam and /dev/null differ diff --git a/_build/test/lib/plug_crypto/ebin/plug_crypto.app b/_build/test/lib/plug_crypto/ebin/plug_crypto.app deleted file mode 100644 index 7997244..0000000 --- a/_build/test/lib/plug_crypto/ebin/plug_crypto.app +++ /dev/null @@ -1 +0,0 @@ -{application,plug_crypto,[{modules,['Elixir.Plug.Crypto','Elixir.Plug.Crypto.Application','Elixir.Plug.Crypto.KeyGenerator','Elixir.Plug.Crypto.MessageEncryptor','Elixir.Plug.Crypto.MessageVerifier']},{optional_applications,[]},{applications,[kernel,stdlib,elixir,crypto]},{description,"Crypto-related functionality for the web"},{registered,[]},{vsn,"2.1.1"},{mod,{'Elixir.Plug.Crypto.Application',[]}}]}. \ No newline at end of file diff --git a/_build/test/lib/symbiont/.mix/.mix_test_failures b/_build/test/lib/symbiont/.mix/.mix_test_failures deleted file mode 100644 index 002e9d7..0000000 Binary files a/_build/test/lib/symbiont/.mix/.mix_test_failures and /dev/null differ diff --git a/_build/test/lib/symbiont/.mix/compile.app_cache b/_build/test/lib/symbiont/.mix/compile.app_cache deleted file mode 100644 index 5b6cb00..0000000 Binary files a/_build/test/lib/symbiont/.mix/compile.app_cache and /dev/null differ diff --git a/_build/test/lib/symbiont/.mix/compile.elixir b/_build/test/lib/symbiont/.mix/compile.elixir deleted file mode 100644 index a9f8916..0000000 Binary files a/_build/test/lib/symbiont/.mix/compile.elixir and /dev/null differ diff --git a/_build/test/lib/symbiont/.mix/compile.elixir_scm b/_build/test/lib/symbiont/.mix/compile.elixir_scm deleted file mode 100644 index f1e974f..0000000 Binary files a/_build/test/lib/symbiont/.mix/compile.elixir_scm and /dev/null differ diff --git a/_build/test/lib/symbiont/.mix/compile.lock b/_build/test/lib/symbiont/.mix/compile.lock deleted file mode 100644 index e69de29..0000000 diff --git a/_build/test/lib/symbiont/consolidated/Elixir.Bandit.HTTP2.Frame.Serializable.beam b/_build/test/lib/symbiont/consolidated/Elixir.Bandit.HTTP2.Frame.Serializable.beam deleted file mode 100644 index ed072fa..0000000 Binary files a/_build/test/lib/symbiont/consolidated/Elixir.Bandit.HTTP2.Frame.Serializable.beam and /dev/null differ diff --git a/_build/test/lib/symbiont/consolidated/Elixir.Bandit.HTTPTransport.beam b/_build/test/lib/symbiont/consolidated/Elixir.Bandit.HTTPTransport.beam deleted file mode 100644 index 94d2d7a..0000000 Binary files a/_build/test/lib/symbiont/consolidated/Elixir.Bandit.HTTPTransport.beam and /dev/null differ diff --git a/_build/test/lib/symbiont/consolidated/Elixir.Bandit.WebSocket.Frame.Serializable.beam b/_build/test/lib/symbiont/consolidated/Elixir.Bandit.WebSocket.Frame.Serializable.beam deleted file mode 100644 index 6113b1a..0000000 Binary files a/_build/test/lib/symbiont/consolidated/Elixir.Bandit.WebSocket.Frame.Serializable.beam and /dev/null differ diff --git a/_build/test/lib/symbiont/consolidated/Elixir.Bandit.WebSocket.Socket.beam b/_build/test/lib/symbiont/consolidated/Elixir.Bandit.WebSocket.Socket.beam deleted file mode 100644 index 5646ce3..0000000 Binary files a/_build/test/lib/symbiont/consolidated/Elixir.Bandit.WebSocket.Socket.beam and /dev/null differ diff --git a/_build/test/lib/symbiont/consolidated/Elixir.Collectable.beam b/_build/test/lib/symbiont/consolidated/Elixir.Collectable.beam deleted file mode 100644 index 8e5c284..0000000 Binary files a/_build/test/lib/symbiont/consolidated/Elixir.Collectable.beam and /dev/null differ diff --git a/_build/test/lib/symbiont/consolidated/Elixir.Enumerable.beam b/_build/test/lib/symbiont/consolidated/Elixir.Enumerable.beam deleted file mode 100644 index 79cb005..0000000 Binary files a/_build/test/lib/symbiont/consolidated/Elixir.Enumerable.beam and /dev/null differ diff --git a/_build/test/lib/symbiont/consolidated/Elixir.IEx.Info.beam b/_build/test/lib/symbiont/consolidated/Elixir.IEx.Info.beam deleted file mode 100644 index b353a23..0000000 Binary files a/_build/test/lib/symbiont/consolidated/Elixir.IEx.Info.beam and /dev/null differ diff --git a/_build/test/lib/symbiont/consolidated/Elixir.Inspect.beam b/_build/test/lib/symbiont/consolidated/Elixir.Inspect.beam deleted file mode 100644 index 1d7a158..0000000 Binary files a/_build/test/lib/symbiont/consolidated/Elixir.Inspect.beam and /dev/null differ diff --git a/_build/test/lib/symbiont/consolidated/Elixir.JSON.Encoder.beam b/_build/test/lib/symbiont/consolidated/Elixir.JSON.Encoder.beam deleted file mode 100644 index 54aed03..0000000 Binary files a/_build/test/lib/symbiont/consolidated/Elixir.JSON.Encoder.beam and /dev/null differ diff --git a/_build/test/lib/symbiont/consolidated/Elixir.Jason.Encoder.beam b/_build/test/lib/symbiont/consolidated/Elixir.Jason.Encoder.beam deleted file mode 100644 index eb2b370..0000000 Binary files a/_build/test/lib/symbiont/consolidated/Elixir.Jason.Encoder.beam and /dev/null differ diff --git a/_build/test/lib/symbiont/consolidated/Elixir.List.Chars.beam b/_build/test/lib/symbiont/consolidated/Elixir.List.Chars.beam deleted file mode 100644 index a32010d..0000000 Binary files a/_build/test/lib/symbiont/consolidated/Elixir.List.Chars.beam and /dev/null differ diff --git a/_build/test/lib/symbiont/consolidated/Elixir.Plug.Exception.beam b/_build/test/lib/symbiont/consolidated/Elixir.Plug.Exception.beam deleted file mode 100644 index 5762b0e..0000000 Binary files a/_build/test/lib/symbiont/consolidated/Elixir.Plug.Exception.beam and /dev/null differ diff --git a/_build/test/lib/symbiont/consolidated/Elixir.String.Chars.beam b/_build/test/lib/symbiont/consolidated/Elixir.String.Chars.beam deleted file mode 100644 index 0b8fd00..0000000 Binary files a/_build/test/lib/symbiont/consolidated/Elixir.String.Chars.beam and /dev/null differ diff --git a/_build/test/lib/symbiont/ebin/Elixir.Symbiont.API.beam b/_build/test/lib/symbiont/ebin/Elixir.Symbiont.API.beam deleted file mode 100644 index 87e0de0..0000000 Binary files a/_build/test/lib/symbiont/ebin/Elixir.Symbiont.API.beam and /dev/null differ diff --git a/_build/test/lib/symbiont/ebin/Elixir.Symbiont.Application.beam b/_build/test/lib/symbiont/ebin/Elixir.Symbiont.Application.beam deleted file mode 100644 index 472c187..0000000 Binary files a/_build/test/lib/symbiont/ebin/Elixir.Symbiont.Application.beam and /dev/null differ diff --git a/_build/test/lib/symbiont/ebin/Elixir.Symbiont.Dispatcher.beam b/_build/test/lib/symbiont/ebin/Elixir.Symbiont.Dispatcher.beam deleted file mode 100644 index de03d2d..0000000 Binary files a/_build/test/lib/symbiont/ebin/Elixir.Symbiont.Dispatcher.beam and /dev/null differ diff --git a/_build/test/lib/symbiont/ebin/Elixir.Symbiont.Heartbeat.beam b/_build/test/lib/symbiont/ebin/Elixir.Symbiont.Heartbeat.beam deleted file mode 100644 index b9de174..0000000 Binary files a/_build/test/lib/symbiont/ebin/Elixir.Symbiont.Heartbeat.beam and /dev/null differ diff --git a/_build/test/lib/symbiont/ebin/Elixir.Symbiont.Ledger.beam b/_build/test/lib/symbiont/ebin/Elixir.Symbiont.Ledger.beam deleted file mode 100644 index 96a5f6f..0000000 Binary files a/_build/test/lib/symbiont/ebin/Elixir.Symbiont.Ledger.beam and /dev/null differ diff --git a/_build/test/lib/symbiont/ebin/Elixir.Symbiont.Queue.beam b/_build/test/lib/symbiont/ebin/Elixir.Symbiont.Queue.beam deleted file mode 100644 index 505dac7..0000000 Binary files a/_build/test/lib/symbiont/ebin/Elixir.Symbiont.Queue.beam and /dev/null differ diff --git a/_build/test/lib/symbiont/ebin/Elixir.Symbiont.Router.beam b/_build/test/lib/symbiont/ebin/Elixir.Symbiont.Router.beam deleted file mode 100644 index 3d85bd9..0000000 Binary files a/_build/test/lib/symbiont/ebin/Elixir.Symbiont.Router.beam and /dev/null differ diff --git a/_build/test/lib/symbiont/ebin/Elixir.Symbiont.TestHelpers.beam b/_build/test/lib/symbiont/ebin/Elixir.Symbiont.TestHelpers.beam deleted file mode 100644 index fdc6288..0000000 Binary files a/_build/test/lib/symbiont/ebin/Elixir.Symbiont.TestHelpers.beam and /dev/null differ diff --git a/_build/test/lib/symbiont/ebin/Elixir.Symbiont.beam b/_build/test/lib/symbiont/ebin/Elixir.Symbiont.beam deleted file mode 100644 index bf5f052..0000000 Binary files a/_build/test/lib/symbiont/ebin/Elixir.Symbiont.beam and /dev/null differ diff --git a/_build/test/lib/symbiont/ebin/symbiont.app b/_build/test/lib/symbiont/ebin/symbiont.app deleted file mode 100644 index b4ee50f..0000000 --- a/_build/test/lib/symbiont/ebin/symbiont.app +++ /dev/null @@ -1 +0,0 @@ -{application,symbiont,[{modules,['Elixir.Symbiont','Elixir.Symbiont.API','Elixir.Symbiont.Application','Elixir.Symbiont.Dispatcher','Elixir.Symbiont.Heartbeat','Elixir.Symbiont.Ledger','Elixir.Symbiont.Queue','Elixir.Symbiont.Router','Elixir.Symbiont.TestHelpers']},{optional_applications,[]},{applications,[kernel,stdlib,elixir,logger,bandit,plug,jason]},{description,"symbiont"},{registered,[]},{vsn,"0.1.0"},{mod,{'Elixir.Symbiont.Application',[]}}]}. \ No newline at end of file diff --git a/_build/test/lib/telemetry/.mix/compile.elixir_scm b/_build/test/lib/telemetry/.mix/compile.elixir_scm deleted file mode 100644 index 4066741..0000000 Binary files a/_build/test/lib/telemetry/.mix/compile.elixir_scm and /dev/null differ diff --git a/_build/test/lib/telemetry/ebin/telemetry.app b/_build/test/lib/telemetry/ebin/telemetry.app deleted file mode 100644 index b09b016..0000000 --- a/_build/test/lib/telemetry/ebin/telemetry.app +++ /dev/null @@ -1,15 +0,0 @@ -{application,telemetry, - [{description,"Dynamic dispatching library for metrics and instrumentations"}, - {vsn,"1.4.1"}, - {registered,[]}, - {mod,{telemetry_app,[]}}, - {applications,[kernel,stdlib]}, - {env,[]}, - {modules,[telemetry,telemetry_app,telemetry_ets, - telemetry_handler_table,telemetry_pt,telemetry_sup, - telemetry_test]}, - {licenses,["Apache-2.0"]}, - {links,[{"GitHub", - "https://github.com/beam-telemetry/telemetry"}]}, - {doc,"doc"}, - {include_files,["mix.exs"]}]}. diff --git a/_build/test/lib/telemetry/ebin/telemetry.beam b/_build/test/lib/telemetry/ebin/telemetry.beam deleted file mode 100644 index 678f62e..0000000 Binary files a/_build/test/lib/telemetry/ebin/telemetry.beam and /dev/null differ diff --git a/_build/test/lib/telemetry/ebin/telemetry_app.beam b/_build/test/lib/telemetry/ebin/telemetry_app.beam deleted file mode 100644 index 4a19835..0000000 Binary files a/_build/test/lib/telemetry/ebin/telemetry_app.beam and /dev/null differ diff --git a/_build/test/lib/telemetry/ebin/telemetry_ets.beam b/_build/test/lib/telemetry/ebin/telemetry_ets.beam deleted file mode 100644 index 582f166..0000000 Binary files a/_build/test/lib/telemetry/ebin/telemetry_ets.beam and /dev/null differ diff --git a/_build/test/lib/telemetry/ebin/telemetry_handler_table.beam b/_build/test/lib/telemetry/ebin/telemetry_handler_table.beam deleted file mode 100644 index b90a090..0000000 Binary files a/_build/test/lib/telemetry/ebin/telemetry_handler_table.beam and /dev/null differ diff --git a/_build/test/lib/telemetry/ebin/telemetry_pt.beam b/_build/test/lib/telemetry/ebin/telemetry_pt.beam deleted file mode 100644 index 79ca3f1..0000000 Binary files a/_build/test/lib/telemetry/ebin/telemetry_pt.beam and /dev/null differ diff --git a/_build/test/lib/telemetry/ebin/telemetry_sup.beam b/_build/test/lib/telemetry/ebin/telemetry_sup.beam deleted file mode 100644 index c77fe57..0000000 Binary files a/_build/test/lib/telemetry/ebin/telemetry_sup.beam and /dev/null differ diff --git a/_build/test/lib/telemetry/ebin/telemetry_test.beam b/_build/test/lib/telemetry/ebin/telemetry_test.beam deleted file mode 100644 index b9514a1..0000000 Binary files a/_build/test/lib/telemetry/ebin/telemetry_test.beam and /dev/null differ diff --git a/_build/test/lib/telemetry/mix.rebar.config b/_build/test/lib/telemetry/mix.rebar.config deleted file mode 100644 index ca1ef50..0000000 --- a/_build/test/lib/telemetry/mix.rebar.config +++ /dev/null @@ -1,17 +0,0 @@ -{erl_opts,[debug_info]}. -{deps,[]}. -{profiles,[{test,[{erl_opts,[nowarn_export_all]}, - {ct_opts,[{ct_hooks,[cth_surefire]}]}, - {cover_enabled,true}, - {cover_opts,[verbose]}, - {plugins,[covertool]}, - {covertool,[{coverdata_files,["ct.coverdata"]}]}]}]}. -{shell,[{apps,[telemetry]}]}. -{xref_checks,[undefined_function_calls,undefined_functions,locals_not_used, - deprecated_function_calls,deprecated_functions]}. -{hex,[{doc,#{provider => ex_doc}}]}. -{ex_doc,[{source_url,<<"https://github.com/beam-telemetry/telemetry">>}, - {extras,[<<"README.md">>,<<"CHANGELOG.md">>,<<"LICENSE">>, - <<"NOTICE">>]}, - {main,<<"readme">>}]}. -{overrides,[]}. diff --git a/_build/test/lib/telemetry/src b/_build/test/lib/telemetry/src deleted file mode 120000 index f3de4ce..0000000 --- a/_build/test/lib/telemetry/src +++ /dev/null @@ -1 +0,0 @@ -../../../../deps/telemetry/src \ No newline at end of file diff --git a/_build/test/lib/thousand_island/.mix/compile.elixir b/_build/test/lib/thousand_island/.mix/compile.elixir deleted file mode 100644 index 41f2a0a..0000000 Binary files a/_build/test/lib/thousand_island/.mix/compile.elixir and /dev/null differ diff --git a/_build/test/lib/thousand_island/.mix/compile.elixir_scm b/_build/test/lib/thousand_island/.mix/compile.elixir_scm deleted file mode 100644 index 4066741..0000000 Binary files a/_build/test/lib/thousand_island/.mix/compile.elixir_scm and /dev/null differ diff --git a/_build/test/lib/thousand_island/ebin/Elixir.ThousandIsland.Acceptor.beam b/_build/test/lib/thousand_island/ebin/Elixir.ThousandIsland.Acceptor.beam deleted file mode 100644 index ec5d1cf..0000000 Binary files a/_build/test/lib/thousand_island/ebin/Elixir.ThousandIsland.Acceptor.beam and /dev/null differ diff --git a/_build/test/lib/thousand_island/ebin/Elixir.ThousandIsland.AcceptorPoolSupervisor.beam b/_build/test/lib/thousand_island/ebin/Elixir.ThousandIsland.AcceptorPoolSupervisor.beam deleted file mode 100644 index 1dc2434..0000000 Binary files a/_build/test/lib/thousand_island/ebin/Elixir.ThousandIsland.AcceptorPoolSupervisor.beam and /dev/null differ diff --git a/_build/test/lib/thousand_island/ebin/Elixir.ThousandIsland.AcceptorSupervisor.beam b/_build/test/lib/thousand_island/ebin/Elixir.ThousandIsland.AcceptorSupervisor.beam deleted file mode 100644 index 2ca7b16..0000000 Binary files a/_build/test/lib/thousand_island/ebin/Elixir.ThousandIsland.AcceptorSupervisor.beam and /dev/null differ diff --git a/_build/test/lib/thousand_island/ebin/Elixir.ThousandIsland.Connection.beam b/_build/test/lib/thousand_island/ebin/Elixir.ThousandIsland.Connection.beam deleted file mode 100644 index a994670..0000000 Binary files a/_build/test/lib/thousand_island/ebin/Elixir.ThousandIsland.Connection.beam and /dev/null differ diff --git a/_build/test/lib/thousand_island/ebin/Elixir.ThousandIsland.Handler.beam b/_build/test/lib/thousand_island/ebin/Elixir.ThousandIsland.Handler.beam deleted file mode 100644 index acdf258..0000000 Binary files a/_build/test/lib/thousand_island/ebin/Elixir.ThousandIsland.Handler.beam and /dev/null differ diff --git a/_build/test/lib/thousand_island/ebin/Elixir.ThousandIsland.HandlerConfig.beam b/_build/test/lib/thousand_island/ebin/Elixir.ThousandIsland.HandlerConfig.beam deleted file mode 100644 index bb0dc56..0000000 Binary files a/_build/test/lib/thousand_island/ebin/Elixir.ThousandIsland.HandlerConfig.beam and /dev/null differ diff --git a/_build/test/lib/thousand_island/ebin/Elixir.ThousandIsland.Listener.beam b/_build/test/lib/thousand_island/ebin/Elixir.ThousandIsland.Listener.beam deleted file mode 100644 index f47649d..0000000 Binary files a/_build/test/lib/thousand_island/ebin/Elixir.ThousandIsland.Listener.beam and /dev/null differ diff --git a/_build/test/lib/thousand_island/ebin/Elixir.ThousandIsland.Logger.beam b/_build/test/lib/thousand_island/ebin/Elixir.ThousandIsland.Logger.beam deleted file mode 100644 index 4e77013..0000000 Binary files a/_build/test/lib/thousand_island/ebin/Elixir.ThousandIsland.Logger.beam and /dev/null differ diff --git a/_build/test/lib/thousand_island/ebin/Elixir.ThousandIsland.ProcessLabel.beam b/_build/test/lib/thousand_island/ebin/Elixir.ThousandIsland.ProcessLabel.beam deleted file mode 100644 index 0687e56..0000000 Binary files a/_build/test/lib/thousand_island/ebin/Elixir.ThousandIsland.ProcessLabel.beam and /dev/null differ diff --git a/_build/test/lib/thousand_island/ebin/Elixir.ThousandIsland.Server.beam b/_build/test/lib/thousand_island/ebin/Elixir.ThousandIsland.Server.beam deleted file mode 100644 index 7158222..0000000 Binary files a/_build/test/lib/thousand_island/ebin/Elixir.ThousandIsland.Server.beam and /dev/null differ diff --git a/_build/test/lib/thousand_island/ebin/Elixir.ThousandIsland.ServerConfig.beam b/_build/test/lib/thousand_island/ebin/Elixir.ThousandIsland.ServerConfig.beam deleted file mode 100644 index 37c27d9..0000000 Binary files a/_build/test/lib/thousand_island/ebin/Elixir.ThousandIsland.ServerConfig.beam and /dev/null differ diff --git a/_build/test/lib/thousand_island/ebin/Elixir.ThousandIsland.ShutdownListener.beam b/_build/test/lib/thousand_island/ebin/Elixir.ThousandIsland.ShutdownListener.beam deleted file mode 100644 index 4777534..0000000 Binary files a/_build/test/lib/thousand_island/ebin/Elixir.ThousandIsland.ShutdownListener.beam and /dev/null differ diff --git a/_build/test/lib/thousand_island/ebin/Elixir.ThousandIsland.Socket.beam b/_build/test/lib/thousand_island/ebin/Elixir.ThousandIsland.Socket.beam deleted file mode 100644 index 9366638..0000000 Binary files a/_build/test/lib/thousand_island/ebin/Elixir.ThousandIsland.Socket.beam and /dev/null differ diff --git a/_build/test/lib/thousand_island/ebin/Elixir.ThousandIsland.Telemetry.beam b/_build/test/lib/thousand_island/ebin/Elixir.ThousandIsland.Telemetry.beam deleted file mode 100644 index abfcb05..0000000 Binary files a/_build/test/lib/thousand_island/ebin/Elixir.ThousandIsland.Telemetry.beam and /dev/null differ diff --git a/_build/test/lib/thousand_island/ebin/Elixir.ThousandIsland.Transport.beam b/_build/test/lib/thousand_island/ebin/Elixir.ThousandIsland.Transport.beam deleted file mode 100644 index 01c358d..0000000 Binary files a/_build/test/lib/thousand_island/ebin/Elixir.ThousandIsland.Transport.beam and /dev/null differ diff --git a/_build/test/lib/thousand_island/ebin/Elixir.ThousandIsland.Transports.SSL.beam b/_build/test/lib/thousand_island/ebin/Elixir.ThousandIsland.Transports.SSL.beam deleted file mode 100644 index b3b8417..0000000 Binary files a/_build/test/lib/thousand_island/ebin/Elixir.ThousandIsland.Transports.SSL.beam and /dev/null differ diff --git a/_build/test/lib/thousand_island/ebin/Elixir.ThousandIsland.Transports.TCP.beam b/_build/test/lib/thousand_island/ebin/Elixir.ThousandIsland.Transports.TCP.beam deleted file mode 100644 index d1893bf..0000000 Binary files a/_build/test/lib/thousand_island/ebin/Elixir.ThousandIsland.Transports.TCP.beam and /dev/null differ diff --git a/_build/test/lib/thousand_island/ebin/Elixir.ThousandIsland.beam b/_build/test/lib/thousand_island/ebin/Elixir.ThousandIsland.beam deleted file mode 100644 index f44e43c..0000000 Binary files a/_build/test/lib/thousand_island/ebin/Elixir.ThousandIsland.beam and /dev/null differ diff --git a/_build/test/lib/thousand_island/ebin/thousand_island.app b/_build/test/lib/thousand_island/ebin/thousand_island.app deleted file mode 100644 index fe65be4..0000000 --- a/_build/test/lib/thousand_island/ebin/thousand_island.app +++ /dev/null @@ -1 +0,0 @@ -{application,thousand_island,[{modules,['Elixir.ThousandIsland','Elixir.ThousandIsland.Acceptor','Elixir.ThousandIsland.AcceptorPoolSupervisor','Elixir.ThousandIsland.AcceptorSupervisor','Elixir.ThousandIsland.Connection','Elixir.ThousandIsland.Handler','Elixir.ThousandIsland.HandlerConfig','Elixir.ThousandIsland.Listener','Elixir.ThousandIsland.Logger','Elixir.ThousandIsland.ProcessLabel','Elixir.ThousandIsland.Server','Elixir.ThousandIsland.ServerConfig','Elixir.ThousandIsland.ShutdownListener','Elixir.ThousandIsland.Socket','Elixir.ThousandIsland.Telemetry','Elixir.ThousandIsland.Transport','Elixir.ThousandIsland.Transports.SSL','Elixir.ThousandIsland.Transports.TCP']},{optional_applications,[]},{applications,[kernel,stdlib,elixir,logger,ssl,telemetry]},{description,"A simple & modern pure Elixir socket server"},{registered,[]},{vsn,"1.4.3"}]}. \ No newline at end of file diff --git a/_build/test/lib/websock/.mix/compile.elixir b/_build/test/lib/websock/.mix/compile.elixir deleted file mode 100644 index 94c9674..0000000 Binary files a/_build/test/lib/websock/.mix/compile.elixir and /dev/null differ diff --git a/_build/test/lib/websock/.mix/compile.elixir_scm b/_build/test/lib/websock/.mix/compile.elixir_scm deleted file mode 100644 index 4066741..0000000 Binary files a/_build/test/lib/websock/.mix/compile.elixir_scm and /dev/null differ diff --git a/_build/test/lib/websock/ebin/Elixir.WebSock.beam b/_build/test/lib/websock/ebin/Elixir.WebSock.beam deleted file mode 100644 index af0821e..0000000 Binary files a/_build/test/lib/websock/ebin/Elixir.WebSock.beam and /dev/null differ diff --git a/_build/test/lib/websock/ebin/websock.app b/_build/test/lib/websock/ebin/websock.app deleted file mode 100644 index b9acb14..0000000 --- a/_build/test/lib/websock/ebin/websock.app +++ /dev/null @@ -1 +0,0 @@ -{application,websock,[{modules,['Elixir.WebSock']},{optional_applications,[]},{applications,[kernel,stdlib,elixir]},{description,"A specification for WebSocket connections"},{registered,[]},{vsn,"0.5.3"}]}. \ No newline at end of file diff --git a/deps/bandit/.hex b/deps/bandit/.hex deleted file mode 100644 index 873cd55..0000000 Binary files a/deps/bandit/.hex and /dev/null differ diff --git a/deps/bandit/CHANGELOG.md b/deps/bandit/CHANGELOG.md deleted file mode 100644 index 717eeb8..0000000 --- a/deps/bandit/CHANGELOG.md +++ /dev/null @@ -1,833 +0,0 @@ -## 1.10.3 (22 Feb 2026) - -### Enhancements - -* Support authority form requests for CONNECT requests (#571) -* Narrow acceptance of asterisk form requests to OPTIONS requests (#571) -* Detect client disconnect on timeout in ensure_completed (#566, thanks @pepicrft!) -* Improve http2 sendfile streaming (#565, thanks @elibosley!) - -## 1.10.2 (22 Jan 2026) - -### Enhancements - -* Distinguish client disconnects from genuine body read timeouts (#564, thanks @pepicrft!) - -## 1.10.1 (5 Jan 2026) - -### Changes - -* Change default preference order for compression methods to be 'zstd (if present), gzip, deflate' (#562) - -### Fixes - -* Allow `:zstd_options` key to be set in config (#558, thanks @Fudoshiki!) -* Fix error where deflate responses weren't always completely sent (#559, thanks @josevalim!) - -## 1.10.0 (29 Dec 2025) - -### Enhancements - -* Expose `response_encodings` to allow specifying an explicit preference order to compression encodings (#555) - -## 1.9.0 (12 Dec 2025) - -### Enhancements - -* Skip body draining when Connection: close is set (#546, thanks @pepicrft!) -* Make deflate options for WebSockets configurable (#540, thanks @proxima!) -* Mitigate HTTP/2 rapid reset attacks (#533, thanks @NelsonVides!) -* Implement improved respect for SETTINGS_MAX_CONCURRENT_STREAMS (#524, thanks @NelsonVides!) -* Support zstd HTTP compression (#514, thanks @mattmatters!) - -## 1.8.0 (18 Aug 2025) - -### Enhancements - -* If the user has set a `content-length` header when calling `send_chunked/3`, -the response is streamed via content-length delimited framing and not chunked (#510) - -## 1.7.0 (29 May 2025) - -### Enhancements - -* Add support for new `get_sock_data/1` and `get_ssl_data/1` callbacks from Plug 1.18 (#497) -* Honour server-sent `Connection: close` headers (#495, thanks @ruslandoga!) - -### Fixes - -* Don't overwrite non-default HTTP/2 settings when receiving HTTP/2 settings (#494, thanks @ns-blee!) -* Fix handling of early-connection error handling in HTTP/2 (#486) - -## 1.6.11 (31 Mar 2025) - -### Changes - -* Ensure that HTTP/1 request headers are sent to the Plug in the order they're -sent (#482) -* Do not populate the `cookies` header with an empty string if no cookies were -sent in HTTP/2 (#483) - -## 1.6.10 (25 Mar 2025) - -### Fixes - -* Fix bug introduced when closing compressed websock connections in certain circumstances (#478) - -### Enhancements - -* Standardize & document the format of messages sent to HTTP/2 Stream processes (#481) - -## 1.6.9 (21 Mar 2025) - -### Fixes - -* Do not close compression context before calling websock close callback (#462, - thanks @thiagopromano!) - -## 1.6.8 (5 Mar 2025) - -### Fixes - -* Do not send stream WINDOW_UPDATEs on the last data frame of a stream - -### Enhancements - -* Add `status` to the telemetry metadata emitted on WebSocket upgrades (#466) - -## 1.6.7 (30 Jan 2025) - -### Changes - -* Consider timeouts when reading HTTP/1 headers as a connection error and not an HTTP error -* Enhance logging for WebSocket deflation errors - -## 1.6.6 (25 Jan 2025) - -### Fixes - -* Consider closures during HTTP/1 header reading as a socket error to silence them by default via `log_client_closures` config flag -* Send `connection: close` when closing connection on error per RFC9112§9.6 - -### Enhancements - -* Add experimental opt-in trace logging to help diagnose hard to reproduce errors -* Move CI to 1.18 & improve tests (#459, #461, thanks @grzuy!) - -## 1.6.5 (15 Jan 2025) - -### Fixes - -* Fix regression introduced in 1.6.1 where we would not send headers set by the Plug during WebSocket upgrades (#458) - -### Enhancements - -* Properly normalize Erlang errors before emitting telemetry and logged crash_reason (#455, thanks @grzuy!) - -## 1.6.4 (11 Jan 2025) - -### Fixes - -* Fix error in socket setup error handling introduced in 1.6.2 (thanks @danielspofford!) - -## 1.6.3 (8 Jan 2025) - -### Fixes - -* Always close HTTP/1 connection in any case where an error comes out of the plug (#452, thanks @zookzook!) -* Fix dialyzer warning introduced by Thousand Island 1.3.9 - -## 1.6.2 (4 Jan 2025) - -### Enhancements - -* Send telemetry events on Plugs that throw or exit (#443) -* Improve test robustness & speed (#446) -* Read a minimal number of bytes when sniffing for protocol (#449) -* Add `plug` and `websock` to logging metadata whenever possible (#448) -* Add `plug` and `websock` to telemetry metadata whenever possible (#447) -* Silently eat Bandit.TransportError errors during HTTP/1 error fallback handling - -### Fixes - -* Bump hpax to 1.0.2, fixes https://github.com/phoenixframework/phoenix/issues/6020 (thanks @krainboltgreene!) -* Fix cases where we would desync on pipelined POST requests (#442) - -### Changes - -* Unwrap Plug.Conn.WrapperErrors raised by Plug and handle the wrapped error per policy -* Surface socket setup errors as Bandit.TransportError for consistency in logging - -## 1.6.1 (6 Dec 2024) - -### Enhancements - -* Add deflate support when sending chunked responses (#429) - -### Fixes - -* Bring in updated HPAX to fix HTTP/2 error cases seen in AWS load balancing - environments (#392) -* Improve handle of pipelined HTTP/1.1 requests (#437) -* Improve error handling when dealing with socket errors (#433) - -### Changes - -* Use `Plug.Call.inform/2` to send websocket upgrades (#428) - -## 1.6.0 (18 Nov 2024) - -### Enhancements - -* Add framework for supporting optimized native code on various hot paths (#394, - thanks @alisinabh!) -* Pass conn and exception data as logger metadata (#417 & #420, thanks @grzuy!) -* Loosen hpax dependency requirements -* Add `log_client_closures` http option, defaulting to false (#397, thanks @goncalotomas!) -* Handle plugs that throw a result (#411, thanks @grzuy!) - -### Fixes - -* Improve content-length send logic per RFC9110§8.6/8.7 -* Explicitly signal keepalives in HTTP/1.0 requests - -### Changes - -* Fix typo & clarify docs -* Update security policy - -## 1.5.7 (1 Aug 2024) - -### Changes - -* Timeouts encountered while reading a request body will now result in a `408 - Request Timeout` being returned to the client by way of a `Bandit.HTTPError` - being raised. Previously, a `:more` tuple was returned (#385, thanks - @martosaur!) - -## 1.5.6 (1 Aug 2024) - -### Fixes - -* Improve handling of the end of stream condition for HTTP/2 requests that send - a body which isn't read by the Plug (#387, thanks @fekle!) - -## 1.5.5 (19 Jun 2024) - -### Changes - -* Add `domain: [:bandit]` to the metadata of all logger calls -* Bring logging of early-connect HTTP2 errors under the `log_protocol_errors` umbrella - -## 1.5.4 (14 Jun 2024) - -### Changes - -* Raise HTTP/2 send window timeouts as stream errors so that they're logged as - protocol errors (thanks @hunterboerner!) - -## 1.5.3 (7 Jun 2024) - -### Changes - -* Add `:short` and `:verbose` options to `log_protocol_errors` configuration - option. **Change default value to `:short`, which will log protocol - errors as a single summary line instead of a full stack trace** -* Raise `Bandit.HTTPError` errors when attempting to write to a closed client - connection (except for chunk/2 calls, which now return `{:error, reason}`). - Unless otherwise caught by the user, these errors will bubble out past the - configured plug and terminate the plug process. This closely mimics the - behaviour of Cowboy in this regard (#359) -* Respect the plug-provided content-length on HEAD responses (#353, thanks - @meeq!) -* Minor changes to how 'non-system process dictionary entries' are identified - -### Fixes - -* No longer closes on HTTP/1 requests smaller than the size of the HTTP/2 - preamble -* Close deflate contexts more eagerly for reduced memory use - -## 1.5.2 (10 May 2024) - -### Fixes - -* Don't crash on non-stringable process dictionary keys (#350, thanks - @ryanwinchester, @chrismccord!) - -## 1.5.1 (10 May 2024) - -### Enhancements - -* Process dictionary is now cleared of all non-system process dictionary entries - between keepalive requests (#349) -* Explicitly run a GC before upgrading a connection to websocket (#348) -* Improve docs around deflate options (thanks @kotsius!) - -## 1.5.0 (21 Apr 2024) - -### Enhancements - -* Bandit now respects an exception's conformance to `Plug.Exception` when - determining which status code to return to the client (if the plug did not - already send one). Previously they were always returned as 500 (for HTTP/1) - or an 'internal error' stream error (for HTTP/2) -* Bandit now only logs the stacktrace of plug-generated exceptions whose status - code (as determined by `Plug.Exception.status/1`) is contained within the new - `log_exceptions_with_status_codes` configuration option (defaulting to - `500..599`) -* As a corollary to the above, Bandit request handler processes no longer exit - abnormally in the case of plug-generated exceptions - -### Changes - -* HTTP semantic errors encountered in an HTTP/2 request are returned to the - client using their proper status code instead of as a 'protocol error' stream - error - -## 1.4.2 (2 Apr 2024) - -### Enhancements - -* Support top-level :inet and :inet6 options for Plug.Cowboy compatibility (#337) - -## 1.4.1 (27 Mar 2024) - -### Changes - -* **BREAKING CHANGE** Move `log_protocol_errors` configuration option into - shared `http_options` top-level config (and apply it to HTTP/2 errors as well) -* **BREAKING CHANGE** Remove `origin_telemetry_span_context` from WebSocket - telemetry events -* **BREAKING CHANGE** Remove `stream_id` from HTTP/2 telemetry events -* Add `conn` to the metadata of telemetry start events for HTTP requests -* Stop sending WebSocket upgrade failure reasons to the client (they're still - logged) - -### Fixes - -* Return HTTP semantic errors to HTTP/2 clients as protocol errors instead of - internal errors - -## 1.4.0 (26 Mar 2024) - -> [!WARNING] -> **IMPORTANT** Phoenix users MUST upgrade to WebSockAdapter `0.5.6` or newer when -> upgrading to Bandit `1.4.0` or newer as some internal module names have changed - -### Enhancements - -* Complete refactor of HTTP/2. Improved process model is MUCH easier to - understand and yields about a 10% performance boost to HTTP/2 requests (#286 / - #307) -* Substantial refactor of the HTTP/1 and HTTP/2 stacks to share a common code - path for much of their implementations, with the protocol-specific parts being - factored out to a minimal `Bandit.HTTPTransport` protocol internally, which - allows each protocol to define its own implementation for the minimal set of - things that are different between the two stacks (#297 / #329) - -### Changes - -* **BREAKING CHANGE** Move configuration options that are common between HTTP/1 - and HTTP/2 stacks into a shared `http_options` top-level config -* **BREAKING CHANGE** The HTTP/2 header size limit options have been deprecated, - and have been replaced with a single `max_header_block_size` option. The setting - defaults to 50k bytes, and refers to the size of the compressed header block - as sent on the wire (including any continuation frames) -* **BREAKING CHANGE** Remove `req_line_bytes`, `req_header_bytes`, `resp_line_bytes` and - `resp_header_bytes` from HTTP/1 request telemetry measurements -* **BREAKING CHANGE** Remove `status`, `method` and `request_target` from - telemetry metadata. All of this information can be obtained from the `conn` - struct attached to most telemetry events -* **BREAKING CHANGE** Re-reading a body that has already been read returns `{:ok, - "", conn}` instead of raising a `Bandit.BodyAlreadyReadError` -* **BREAKING CHANGE** Remove `Bandit.BodyAlreadyReadError` -* **BREAKING CHANGE** Remove h2c support via Upgrade header. This was deprecated - in RFC9113 and never in widespread use. We continue to support h2c via prior - knowledge, which remains the only supported mechanism for h2c in RFC9113 -* Treat trailing bytes beyond the indicated content-length on HTTP/1 requests as - an error -* Surface request body read timeouts on HTTP/1 requests as `{:more...}` tuples - and not errors -* Socket sending errors are no longer surfaced on chunk sends in HTTP/1 -* We no longer log if processes that are linked to an HTTP/2 stream process - terminate unexpectedly. This has always been unspecified behaviour so is not - considered a breaking change -* Calls of `Plug.Conn` functions for an HTTP/2 connection must now come from the - stream process; any other process will raise an error. Again, this has always - been unspecified behaviour -* We now send an empty DATA frame for explicitly zero byte bodies instead of - optimizing to a HEADERS frame with end_stream set (we still do so for cases - such as 204/304 and HEAD requests) -* We now send RST_STREAM frames if we complete a stream and the remote end is - still open. This optimizes cases where the client may still be sending a body - that we never consumed and don't care about -* We no longer explicitly close the connection when we receive a GOAWAY frame - -## 1.3.0 (8 Mar 2024) - -### Enhancements - -* Run an explicit garbage collection between every 'n' keepalive requests on the same HTTP/1.1 connection in order to keep reported (but not actual!) memory usage from growing over time. Add `gc_every_n_keepalive_requests` option to configure this (default value of - `5`). #322, thanks @ianko & @Nilsonn!) -* Add `log_protocol_errors` option to optionally quell console logging of 4xx errors generated by Bandit. Defaults to `true` for now; may switch to `false` in the future based on adoption (#321, thanks @Stroemgren!) - -### Changes - -* Don't send a `transfer-encoding` header for 1xx or 204 responses (#317, thanks - @mwhitworth!) - -## 1.2.3 (23 Feb 2024) - -### Changes - -* Log port number when listen fails (#312, thanks @jonatanklosko!) -* Accept mixed-case keepalive directives (#308, thanks @gregors!) - -## 1.2.2 (16 Feb 2024) - -### Changes - -* Reset Logger metadata on every request - -## 1.2.1 (12 Feb 2024) - -### Changes - -* Disable logging of unknown messages received by an idle HTTP/1 handler to - avoid noise on long polling clients. This can be changed via the - `log_unknown_messages` http_1 option (#299) - -## 1.2.0 (31 Jan 2024) - -### Enhancements - -* Automatically pull in `:otp_app` value in Bandit.PhoenixAdapter (thanks - @krns!) -* Include response body metrics for HTTP/1 chunk responses - -### Fixes - -* Fix broken HTTP/1 inform/3 return value (thanks @wojtekmach!) -* Maintain HTTP/1 read timeout after receiving unknown messages - -## 1.1.3 (12 Jan 2024) - -### Fixes - -* Do not send a fallback response if the plug has already sent one (#288 & #289, thanks @jclem!) - -### Changes - -* Packagaing improvements (#283, thanks @wojtekmach!) - -## 1.1.2 (20 Dec 2023) - -### Fixes - -* Fix support for proplist-style arguments (#277, thanks @jjcarstens!) -* Speed up WebSocket framing (#272, thanks @crertel!) -* Fix off-by-one error in HTTP2 sendfile (#269, thanks @OrangeDrangon!) -* Improve mix file packaging (#266, thanks @patrickjaberg!) - -## 1.1.1 (14 Nov 2023) - -### Fixes - -* Do not advertise disabled protocols via ALPN (#263) - -## 1.1.0 (2 Nov 2023) - -### Changes - -* Messages sent to Bandit HTTP/1 handlers no longer intentionally crash the - handler process but are now logged in the same manner as messages sent to a - no-op GenServer (#259) -* Messages regarding normal termination of monitored processes are no longer - handled by the WebSocket handler, but are now passed to the configured - `c:WebSock.handle_info/2` callback (#259) - -### Enhancements - -* Add support for `Phoenix.Endpoint.server_info/1` (now in Phoenix main; #258) -* Add support for `:max_heap_size` option in WebSocket handler (introduced in - websock_adapter 0.5.5; #255, thanks @v0idpwn!) - -## 1.0.0 (18 Oct 2023) - -### Changes - -* Remove internal tracking of remote `max_concurrent_streams` setting (#248) - -## 1.0.0-pre.18 (10 Oct 2023) - -### Fixes - -* Fix startup when plug module has not yet been loaded by the BEAM - -## 1.0.0-pre.17 (9 Oct 2023) - -### Enhancements - -* Support function based plugs & improve startup analysis of plug configuration - (#236) -* Improve keepalive support when Plug does not read request bodies (#244) -* Improve logic around not sending bodies on HEAD requests (#242) - -### Changes - -* Internal refactor of WebSocket validation (#229) - - -## 1.0.0-pre.16 (18 Sep 2023) - -### Changes - -* Use protocol default port in the event that no port is provided in host header (#228) - -### Fixes - -* Improve handling of iolist response bodies (#231, thanks @travelmassive!) - -## 1.0.0-pre.15 (9 Sep 2023) - -### Fixes - -* Fix issue with setting remote IP at connection startup (#227, thanks @jimc64!) - -## 1.0.0-pre.14 (28 Aug 2023) - -### Enhancements - -* Add `Bandit.PhoenixAdapter.bandit_pid/2` (#212) -* Return errors to `Plug.Conn.Adapter.chunk/2` HTTP/1 calls (#216) - -### Changes - -* `Plug.Conn` function calls must come from the process on which `Plug.call/2` was called (#217, reverts #117) - -## 1.0.0-pre.13 (15 Aug 2023) - -### Enhancements - -* Add ability to send preamble frames when closing a WebSock connection (#211) - -## 1.0.0-pre.12 (12 Aug 2023) - -## Fixes - -* Bump ThousandIsland to 1.0.0-pre.7 to fix leaking file descriptors on - `Plug.Conn.sendfile/5` calls (thanks @Hermanverschooten!) - -## 1.0.0-pre.11 (11 Aug 2023) - -## Changes - -* **BREAKING CHANGE** Move `conn` value in telemetry events from measurements to metadata - -## Enhancements - -* Add `method`, `request_target` and `status` fields to telemetry metadata on HTTP stop events -* Improve RFC compliance regarding cache-related headers on deflated responses (#207, thanks @tanguilp!) -* Bump to Thousand Island `1.0.0-pre.6` -* Doc improvements (particularly around implementation notes) -* Typespec improvements (thanks @moogle19!) - -## 1.0.0-pre.10 (28 Jun 2023) - -## Enhancements - -* Add support for `Plug.Conn.inform/3` on HTTP/1 connections (#180) -* Add support for h2c upgrades (#186, thanks @alisinabh!) -* Internal refactoring of HTTP/1 content-length encoded body reads (#184, #190, - thanks @asakura & @moogle19!) - -## Changes - -* Bump Thousand Island to 1.0.0-pre.6 (gaining support for suspend/resume API) -* Drop Elixir 1.12 as a supported target (it should continue to work, but is no - longer covered by CI) - -## Fixes - -* Fix crash when Plug used `Plug.Conn.get_peer_data/1` function on HTTP/1 - connections (#170, thanks @moogle19!) -* Fix port behaviour when connecting over unix socket (#176, thanks @asakura - & @ibarchenkov!) - -## 1.0.0-pre.9 (16 Jun 2023) - -## Changes - -* Use new ThousandIsland APIs for socket info (#167, thanks @asakura!) - -## Fixes - -* Handle nil connection close reason when closing a WebSocket - -## 1.0.0-pre.8 (15 Jun 2023) - -## Fixes - -* Further improve logging on WebSocket upgrade errors (#149) - -## 1.0.0-pre.7 (14 Jun 2023) - -## Enhancements - -* Refactor HTTP/1 read routines (#158 & #166, thanks @asakura!) -* Improve logging on WebSocket upgrade errors (#149) - -## Changes - -* Override any content-length headers that may have been set by Plug (#165) -* Send content-length on HTTP/2 responses where appropriate (#165) - -## Fixes - -* Send correct content-length header when sending deflated response (#151) -* Do not attempt to deflate if Plug sends a content-encoding header (#165) -* Improve corner case handling of content-length request header (#163, thanks - @ryanwinchester!) -* Handle case where ThousandIsland returns error tuples on some helper routines - (#162) - -## 1.0.0-pre.6 (8 Jun 2023) - -### Changes - -* Always use the declaed scheme if declared in a request-line or `:scheme` - pseudo-header (#159) -* Internal tidying (thanks @asakura!) - -## 1.0.0-pre.5 (2 Jun 2023) - -### Enhancements - -* Total overhaul of typespecs throughout the library (thanks @asakura!) - -## 1.0.0-pre.4 (23 May 2023) - -### Enhancements - -* Performance / correctness improvements to header length validation (#143, - thanks @moogle19!) -* Performance improvements to host header port parsing (#145 & #147, thanks - @ryanwinchester!) -* Improve WebSocket upgrade failure error messages to aid in diagnosis (#152) - -### Changes - -* Consolidate credo config (#146, thanks @ryanwinchester!) - -### Fixes - -* Fix error in suggested version dependencies during 1.0-pre series (#142, - thanks @cvkmohan!) - -## 1.0.0-pre.3 (3 May 2023) - -### Enhancements - -* Respect read timeout for HTTP/1 keepalives (#140) -* Support Websock 0.5.1, including support for optional `c:WebSock.terminate/2` - (#131) - -### Changes - -* Use Req instead of Finch in tests (#137) -* Improve a few corner cases in tests (#136) - -## 1.0.0-pre.2 (24 Apr 2023) - -### Fixes - -* Don't require transport_options to be a keyword list (#130, thanks @justinludwig!) - -## 1.0.0-pre.1 (21 Apr 2023) - -### Changes - -* Update Thousand Island dependency to 1.0-pre - -# Changelog for 0.7.x - -## 0.7.7 (11 Apr 2023) - -### Changes - -* Bandit will now raise an error at startup if no plug is specified in config - (thanks @moogle19!) - -### Fixes - -* Fix crash at startup when using `otp_app` option (thanks @moogle19!) -* Minor doc formatting fixes - -## 0.7.6 (9 Apr 2023) - -### Changes - -* **BREAKING CHANGE** Rename top-level `options` field to `thousand_island_options` -* **BREAKING CHANGE** Rename `deflate_opts` to `deflate_options` where used -* Massive overhaul of documentation to use types where possible -* Bandit now uses a term of the form `{Bandit, ref()}` for `id` in our child spec -* Bumped to Thousand Island 0.6.7. `num_connections` is now 16384 by default - -### Enhancements - -* Added top level support for the following convenience parameters: - * `port` can now be set at the top level of your configuration - * `ip` can now be set at the top level of your configuration - * `keyfile` and `certfile` can now be set at the top level of your configuration -* Transport options are now validated by `Plug.SSL.configure/1` when starting - an HTTPS server -* Rely on Thousand Island to validate options specified in `thousand_island_options`. This should avoid cases like #125 in the future. - -## 0.7.5 (4 Apr 2023) - -### Changes - -* Drop explicit support for Elixir 1.11 since we no longer test it in CI (should - still work, just that it's now at-your-own-risk) -* Add logo to ex_doc and README - -### Fixes - -* Allow access to Thousand Island's underlying `shutdown_timeout` option -* Fix test errors that cropped up in OTP 26 - - -## 0.7.4 (27 Mar 2023) - -### Changes - -* Calling `Plug.Conn` adapter functions for HTTP/2 based requests are no longer - restricted to being called from the process which called `c:Plug.call/2` - -### Enhancements - -* Added `startup_log` to control whether / how Bandit logs the bound host & port - at startup (Thanks @danschultzer) -* Improved logging when the configured port is in use at startup (Thanks - @danschultzer) -* Update to Thousand Island 0.6.5 - -## 0.7.3 (20 Mar 2023) - -### Enhancements - -* Added advanced `handler_module` configuration option to `options` - -### Fixes - -* Support returning `x-gzip` as negotiated `content-encoding` (previously would - negotiate a request for `x-gzip` as `gzip`) - -## 0.7.2 (18 Mar 2023) - -### Enhancements - -* Added HTTP compression via 'Content-Encoding' negotiation, enabled by default. - Configuration is available; see [Bandit - docs](https://hexdocs.pm/bandit/Bandit.html#module-config-options) for details - -### Changes - -* Minor refactor of internal HTTP/2 plumbing. No user visible changes - -## 0.7.1 (17 Mar 2023) - -### Changes - -* Update documentation & messaging to refer to RFC911x RFCs where appropriate -* Validate top-level config options at startup -* Revise Phoenix adapter to support new config options -* Doc updates - -## 0.7.0 (17 Mar 2023) - -### Enhancements - -* Add configuration points for various parameters within the HTTP/1, HTTP/2 and - WebSocket stacks. See [Bandit - docs](https://hexdocs.pm/bandit/Bandit.html#module-config-options) for details - -# Changelog for 0.6.x - -## 0.6.11 (17 Mar 2023) - -### Changes - -* Modified telemetry event payloads to match the conventions espoused by - `:telemetry.span/3` -* Default shutdown timeout is now 15s (up from 5s) - -### Enhancements - -* Update to Thosuand Island 0.6.4 (from 0.6.2) - -## 0.6.10 (10 Mar 2023) - -### Enhancements - -* Support explicit setting of WebSocket close codes & reasons as added in WebSock -0.5.0 - -## 0.6.9 (20 Feb 2023) - -### Enhancements - -* Add comprehensive Telemetry support within Bandit, as documented in the - `Bandit.Telemetry` module -* Update our ThousandIsland dependnecy to pull in Thousand Island's newly - updated Telemetry support as documented in the `ThousandIsland.Telemetry` - module -* Fix parsing of host / request headers which contain IPv6 addresses (#97). - Thanks @derekkraan! - -# Changes - -* Use Plug's list of response code reason phrases (#96). Thanks @jclem! -* Minor doc updates - -## 0.6.8 (31 Jan 2023) - -### Changes - -* Close WebSocket connections with a code of 1000 (instead of 1001) when - shutting down the server (#89) -* Use 100 acceptor processes by default (instead of 10) -* Improvements to make WebSocket frame masking faster - -## 0.6.7 (17 Jan 2023) - -### Enhancements - -* Remove logging entirely when client connections do not contain a valid protocol -* Refactor WebSocket support for about a 20% performance lift - -### Bug Fixes - -* Add `nodelay` option to test suite to fix artificially slow WebSocket perf tests - -## 0.6.6 (11 Jan 2023) - -### Enhancements - -* Log useful message when a TLS connection is made to plaintext server (#74) - -## 0.6.5 (10 Jan 2023) - -### Enhancements - -* Update Thousand Island to 0.5.15 (quiets logging in timeout cases) -* Quiet logging in when client connections do not contain a valid protocol -* Refactor HTTP/1 for about a 20% performance lift -* Add WebSocket support to CI benchmark workflow -* Doc updates - -### Bug Fixes - -* Allow multiple instances of Bandit to be started in the same node (#75) -* Improve error handling in HTTP/1 when protocol errors are encountered (#74) diff --git a/deps/bandit/LICENSE b/deps/bandit/LICENSE deleted file mode 100644 index 10c0f8e..0000000 --- a/deps/bandit/LICENSE +++ /dev/null @@ -1,21 +0,0 @@ -MIT License - -Copyright (c) 2020 Mat Trudel - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. diff --git a/deps/bandit/README.md b/deps/bandit/README.md deleted file mode 100644 index 6351b72..0000000 --- a/deps/bandit/README.md +++ /dev/null @@ -1,245 +0,0 @@ -![Bandit](https://github.com/mtrudel/bandit/raw/main/assets/readme_logo.png#gh-light-mode-only) -![Bandit](https://github.com/mtrudel/bandit/raw/main/assets/readme_logo-darkmode.png#gh-dark-mode-only) - -[![Build Status](https://github.com/mtrudel/bandit/workflows/Elixir%20CI/badge.svg)](https://github.com/mtrudel/bandit/actions) -[![Docs](https://img.shields.io/badge/api-docs-green.svg?style=flat)](https://hexdocs.pm/bandit) -[![Hex.pm](https://img.shields.io/hexpm/v/bandit.svg?style=flat&color=blue)](https://hex.pm/packages/bandit) - -Bandit is an HTTP server for Plug and WebSock apps. - -Bandit is written entirely in Elixir and is built atop [Thousand -Island](https://github.com/mtrudel/thousand_island). It can serve HTTP/1.x, -HTTP/2 and WebSocket clients over both HTTP and HTTPS. It is written with -correctness, clarity & performance as fundamental goals. It is the default HTTP -server for [Phoenix](https://github.com/phoenixframework/phoenix) since release 1.7.11 of the framework. - -In [ongoing automated performance -tests](https://github.com/mtrudel/bandit/actions/workflows/manual_benchmark.yml), -Bandit's HTTP/1.x engine is up to 4x faster than Cowboy depending on the number of concurrent -requests. When comparing HTTP/2 performance, Bandit is up to 1.5x faster than Cowboy. This is -possible because Bandit has been built from the ground up for use with Plug applications; this -focus pays dividends in both performance and also in the approachability of the code base. - -Bandit also emphasizes correctness. Its HTTP/2 implementation scores 100% on the -[h2spec](https://github.com/summerwind/h2spec) suite in strict mode, and its -WebSocket implementation scores 100% on the -[Autobahn](https://github.com/crossbario/autobahn-testsuite) test suite, both of -which run as part of Bandit's comprehensive CI suite. Extensive unit test, -credo, dialyzer, and performance regression test coverage round out a test suite -that ensures that Bandit is and will remain a platform you can count on. - -Lastly, Bandit exists to demystify the lower layers of infrastructure code. In a world where -The New Thing is nearly always adding abstraction on top of abstraction, it's important to have -foundational work that is approachable & understandable by users above it in the stack. - -## Project Goals - -* Implement comprehensive support for HTTP/1.0 through HTTP/2 & WebSockets (and - beyond) backed by obsessive RFC literacy and automated conformance testing -* Aim for minimal internal policy and HTTP-level configuration. Delegate to Plug & WebSock as much as - possible, and only interpret requests to the extent necessary to safely manage a connection - & fulfill the requirements of safely supporting protocol correctness -* Prioritize (in order): correctness, clarity, performance. Seek to remove the mystery of - infrastructure code by being approachable and easy to understand -* Along with our companion library [Thousand - Island](https://github.com/mtrudel/thousand_island), become the go-to HTTP - & low-level networking stack of choice for the Elixir community by being - reliable, efficient, and approachable - -## Project Status - -* Complete support for [Phoenix](https://github.com/phoenixframework/phoenix) applications (WebSocket - support requires Phoenix 1.7+) -* Complete support of the [Plug API](https://github.com/elixir-plug/plug) -* Complete support of the [WebSock API](https://github.com/phoenixframework/websock) -* Complete server support for HTTP/1.x as defined in [RFC - 9112](https://datatracker.ietf.org/doc/html/rfc9112) & [RFC - 9110](https://datatracker.ietf.org/doc/html/rfc9110) -* Complete server support for HTTP/2 as defined in [RFC - 9113](https://datatracker.ietf.org/doc/html/rfc9113) & [RFC - 9110](https://datatracker.ietf.org/doc/html/rfc9110), comprehensively covered - by automated [h2spec](https://github.com/summerwind/h2spec) conformance testing -* Support for HTTP content encoding compression on both HTTP/1.x and HTTP/2. - gzip and deflate methods are supported per - [RFC9110§8.4.1.{2,3}](https://www.rfc-editor.org/rfc/rfc9110.html#section-8.4.1.2) -* Complete server support for WebSockets as defined in [RFC - 6455](https://datatracker.ietf.org/doc/html/rfc6455), comprehensively covered by automated - [Autobahn](https://github.com/crossbario/autobahn-testsuite) conformance testing. Per-message - compression as defined in [RFC 7692](https://datatracker.ietf.org/doc/html/rfc7692) is also - supported -* Extremely scalable and performant client handling at a rate up to 4x that of Cowboy for the same - workload with as-good-or-better memory use - -Any Phoenix or Plug app should work with Bandit as a drop-in replacement for -Cowboy; exceptions to this are errors (if you find one, please [file an -issue!](https://github.com/mtrudel/bandit/issues)). - - - -## Using Bandit With Phoenix - -Bandit fully supports Phoenix. Phoenix applications which use WebSockets for -features such as Channels or LiveView require Phoenix 1.7 or later. - -Using Bandit to host your Phoenix application couldn't be simpler: - -1. Add Bandit as a dependency in your Phoenix application's `mix.exs`: - - ```elixir - {:bandit, "~> 1.8"} - ``` -2. Add the following `adapter:` line to your endpoint configuration in `config/config.exs`, as in the following example: - - ```elixir - # config/config.exs - - config :your_app, YourAppWeb.Endpoint, - adapter: Bandit.PhoenixAdapter, # <---- ADD THIS LINE - url: [host: "localhost"], - render_errors: ... - ``` -3. That's it! **You should now see messages at startup indicating that Phoenix is - using Bandit to serve your endpoint**, and everything should 'just work'. Note - that if you have set any exotic configuration options within your endpoint, - you may need to update that configuration to work with Bandit; see the - [Bandit.PhoenixAdapter](https://hexdocs.pm/bandit/Bandit.PhoenixAdapter.html) - documentation for more information. - -## Using Bandit With Plug Applications - -Using Bandit to host your own Plug is very straightforward. Assuming you have -a Plug module implemented already, you can host it within Bandit by adding -something similar to the following to your application's `Application.start/2` -function: - -```elixir -# lib/my_app/application.ex - -defmodule MyApp.Application do - use Application - - def start(_type, _args) do - children = [ - {Bandit, plug: MyApp.MyPlug} - ] - - opts = [strategy: :one_for_one, name: MyApp.Supervisor] - Supervisor.start_link(children, opts) - end -end -``` - -For less formal usage, you can also start Bandit using the same configuration -options via the `Bandit.start_link/1` function: - -```elixir -# Start an http server on the default port 4000, serving MyApp.MyPlug -Bandit.start_link(plug: MyPlug) -``` - -## Configuration - -A number of options are defined when starting a server. The complete list is -defined by the [`t:Bandit.options/0`](https://hexdocs.pm/bandit/Bandit.html#summary) type. - -## Setting up an HTTPS Server - -By far the most common stumbling block encountered when setting up an HTTPS -server involves configuring key and certificate data. Bandit is comparatively -easy to set up in this regard, with a working example looking similar to the -following: - -```elixir -# lib/my_app/application.ex - -defmodule MyApp.Application do - use Application - - def start(_type, _args) do - children = [ - {Bandit, - plug: MyApp.MyPlug, - scheme: :https, - certfile: "/absolute/path/to/cert.pem", - keyfile: "/absolute/path/to/key.pem"} - ] - - opts = [strategy: :one_for_one, name: MyApp.Supervisor] - Supervisor.start_link(children, opts) - end -end -``` - -## WebSocket Support - -If you're using Bandit to run a Phoenix application as suggested above, there is -nothing more for you to do; WebSocket support will 'just work'. - -If you wish to interact with WebSockets at a more fundamental level, the -[WebSock](https://hexdocs.pm/websock/WebSock.html) and -[WebSockAdapter](https://hexdocs.pm/websock_adapter/WebSockAdapter.html) libraries -provides a generic abstraction for WebSockets (very similar to how Plug is -a generic abstraction on top of HTTP). Bandit fully supports all aspects of -these libraries. - -## Receiving messages in your Plug process: A word of warning - -The Plug specification is concerned only with the shape of the `c:Plug.init/1` -and `c:Plug.call/2` functions; it says nothing about the process model that -underlies the call, nor about how the Plug function should respond to any -messages it may receive. Although it is occasionally necessary to receive -messages from within your Plug call, this must be done with caution as Bandit -makes extensive use of messaging internally, especially with HTTP/2 based -requests. - -In particular, you must ensure that your code *never* receives messages that -match the patterns `{:bandit, _}` or `{:plug_conn, :sent}`. Any `receive` calls -you make should be appropriately guarded to ensure that these messages remain in -the process' mailbox for Bandit to process them when required. - - - -## Implementation Details - -Bandit primarily consists of three protocol-specific implementations, one each -for [HTTP/1][], [HTTP/2][] and [WebSockets][]. Each of these implementations is -largely distinct from one another, and is described in its own README linked -above. - -If you're just taking a casual look at Bandit or trying to understand how an -HTTP server works, the [HTTP/1][] implementation is likely the best place to -start exploring. - -[HTTP/1]: lib/bandit/http1/README.md -[HTTP/2]: lib/bandit/http2/README.md -[WebSockets]: lib/bandit/websocket/README.md - -## Contributing - -Contributions to Bandit are very much welcome! Before undertaking any substantial work, please -open an issue on the project to discuss ideas and planned approaches so we can ensure we keep -progress moving in the same direction. - -All contributors must agree and adhere to the project's [Code of -Conduct](https://github.com/mtrudel/bandit/blob/main/CODE_OF_CONDUCT.md). - -Security disclosures should be handled per Bandit's published [security policy](https://github.com/mtrudel/bandit/blob/main/SECURITY.md). - -## Installation - -Bandit is [available in Hex](https://hex.pm/docs/publish). The package can be installed -by adding `bandit` to your list of dependencies in `mix.exs`: - -```elixir -def deps do - [ - {:bandit, "~> 1.8"} - ] -end -``` - -Documentation can be found at [https://hexdocs.pm/bandit](https://hexdocs.pm/bandit). - -# License - -MIT diff --git a/deps/bandit/hex_metadata.config b/deps/bandit/hex_metadata.config deleted file mode 100644 index 29572ef..0000000 --- a/deps/bandit/hex_metadata.config +++ /dev/null @@ -1,81 +0,0 @@ -{<<"links">>, - [{<<"Changelog">>,<<"https://hexdocs.pm/bandit/changelog.html">>}, - {<<"GitHub">>,<<"https://github.com/mtrudel/bandit">>}]}. -{<<"name">>,<<"bandit">>}. -{<<"version">>,<<"1.10.3">>}. -{<<"description">>, - <<"A pure-Elixir HTTP server built for Plug & WebSock apps">>}. -{<<"elixir">>,<<"~> 1.13">>}. -{<<"app">>,<<"bandit">>}. -{<<"licenses">>,[<<"MIT">>]}. -{<<"files">>, - [<<"lib">>,<<"lib/bandit">>,<<"lib/bandit/telemetry.ex">>, - <<"lib/bandit/compression.ex">>,<<"lib/bandit/http_error.ex">>, - <<"lib/bandit/phoenix_adapter.ex">>,<<"lib/bandit/http_transport.ex">>, - <<"lib/bandit/adapter.ex">>,<<"lib/bandit/logger.ex">>, - <<"lib/bandit/extractor.ex">>,<<"lib/bandit/primitive_ops">>, - <<"lib/bandit/primitive_ops/websocket.ex">>,<<"lib/bandit/pipeline.ex">>, - <<"lib/bandit/headers.ex">>,<<"lib/bandit/http2">>, - <<"lib/bandit/http2/errors.ex">>,<<"lib/bandit/http2/settings.ex">>, - <<"lib/bandit/http2/stream_process.ex">>, - <<"lib/bandit/http2/connection.ex">>,<<"lib/bandit/http2/README.md">>, - <<"lib/bandit/http2/frame.ex">>,<<"lib/bandit/http2/stream.ex">>, - <<"lib/bandit/http2/stream_collection.ex">>,<<"lib/bandit/http2/frame">>, - <<"lib/bandit/http2/frame/ping.ex">>,<<"lib/bandit/http2/frame/goaway.ex">>, - <<"lib/bandit/http2/frame/continuation.ex">>, - <<"lib/bandit/http2/frame/settings.ex">>, - <<"lib/bandit/http2/frame/data.ex">>, - <<"lib/bandit/http2/frame/headers.ex">>, - <<"lib/bandit/http2/frame/rst_stream.ex">>, - <<"lib/bandit/http2/frame/window_update.ex">>, - <<"lib/bandit/http2/frame/priority.ex">>, - <<"lib/bandit/http2/frame/push_promise.ex">>, - <<"lib/bandit/http2/frame/unknown.ex">>, - <<"lib/bandit/http2/flow_control.ex">>,<<"lib/bandit/http2/handler.ex">>, - <<"lib/bandit/clock.ex">>,<<"lib/bandit/trace.ex">>, - <<"lib/bandit/initial_handler.ex">>,<<"lib/bandit/application.ex">>, - <<"lib/bandit/socket_helpers.ex">>,<<"lib/bandit/websocket">>, - <<"lib/bandit/websocket/connection.ex">>, - <<"lib/bandit/websocket/socket.ex">>,<<"lib/bandit/websocket/README.md">>, - <<"lib/bandit/websocket/permessage_deflate.ex">>, - <<"lib/bandit/websocket/frame.ex">>, - <<"lib/bandit/websocket/upgrade_validation.ex">>, - <<"lib/bandit/websocket/handshake.ex">>,<<"lib/bandit/websocket/frame">>, - <<"lib/bandit/websocket/frame/ping.ex">>, - <<"lib/bandit/websocket/frame/continuation.ex">>, - <<"lib/bandit/websocket/frame/binary.ex">>, - <<"lib/bandit/websocket/frame/connection_close.ex">>, - <<"lib/bandit/websocket/frame/pong.ex">>, - <<"lib/bandit/websocket/frame/text.ex">>, - <<"lib/bandit/websocket/handler.ex">>,<<"lib/bandit/transport_error.ex">>, - <<"lib/bandit/delegating_handler.ex">>,<<"lib/bandit/http1">>, - <<"lib/bandit/http1/socket.ex">>,<<"lib/bandit/http1/README.md">>, - <<"lib/bandit/http1/handler.ex">>,<<"lib/bandit.ex">>,<<"mix.exs">>, - <<"README.md">>,<<"LICENSE">>,<<"CHANGELOG.md">>]}. -{<<"requirements">>, - [[{<<"name">>,<<"thousand_island">>}, - {<<"app">>,<<"thousand_island">>}, - {<<"optional">>,false}, - {<<"requirement">>,<<"~> 1.0">>}, - {<<"repository">>,<<"hexpm">>}], - [{<<"name">>,<<"plug">>}, - {<<"app">>,<<"plug">>}, - {<<"optional">>,false}, - {<<"requirement">>,<<"~> 1.18">>}, - {<<"repository">>,<<"hexpm">>}], - [{<<"name">>,<<"websock">>}, - {<<"app">>,<<"websock">>}, - {<<"optional">>,false}, - {<<"requirement">>,<<"~> 0.5">>}, - {<<"repository">>,<<"hexpm">>}], - [{<<"name">>,<<"hpax">>}, - {<<"app">>,<<"hpax">>}, - {<<"optional">>,false}, - {<<"requirement">>,<<"~> 1.0">>}, - {<<"repository">>,<<"hexpm">>}], - [{<<"name">>,<<"telemetry">>}, - {<<"app">>,<<"telemetry">>}, - {<<"optional">>,false}, - {<<"requirement">>,<<"~> 0.4 or ~> 1.0">>}, - {<<"repository">>,<<"hexpm">>}]]}. -{<<"build_tools">>,[<<"mix">>]}. diff --git a/deps/bandit/lib/bandit.ex b/deps/bandit/lib/bandit.ex deleted file mode 100644 index 90799a5..0000000 --- a/deps/bandit/lib/bandit.ex +++ /dev/null @@ -1,436 +0,0 @@ -defmodule Bandit do - @external_resource Path.join([__DIR__, "../README.md"]) - - @moduledoc """ - Bandit is an HTTP server for Plug and WebSock apps. - - As an HTTP server, Bandit's primary goal is to act as 'glue' between client connections managed - by [Thousand Island](https://github.com/mtrudel/thousand_island) and application code defined - via the [Plug](https://github.com/elixir-plug/plug) and/or - [WebSock](https://github.com/phoenixframework/websock) APIs. As such there really isn't a whole lot of - user-visible surface area to Bandit, and as a consequence the API documentation presented here - is somewhat sparse. This is by design! Bandit is intended to 'just work' in almost all cases; - the only thought users typically have to put into Bandit comes in the choice of which options (if - any) they would like to change when starting a Bandit server. The sparseness of the Bandit API - should not be taken as an indicator of the comprehensiveness or robustness of the project. - - #{@external_resource |> File.read!() |> String.split("") |> Enum.fetch!(1)} - """ - - @typedoc """ - Possible top-level options to configure a Bandit server - - * `plug`: The Plug to use to handle connections. Can be specified as `MyPlug` or `{MyPlug, plug_opts}` - * `scheme`: One of `:http` or `:https`. If `:https` is specified, you will also need to specify - valid `certfile` and `keyfile` values (or an equivalent value within - `thousand_island_options.transport_options`). Defaults to `:http` - * `port`: The TCP port to listen on. This option is offered as a convenience and actually sets - the option of the same name within `thousand_island_options`. If a string value is passed, it - will be parsed as an integer. Defaults to 4000 if `scheme` is `:http`, and 4040 if `scheme` is - `:https` - * `ip`: The interface(s) to listen on. This option is offered as a convenience and actually sets the - option of the same name within `thousand_island_options.transport_options`. Can be specified as: - * `{1, 2, 3, 4}` for IPv4 addresses - * `{1, 2, 3, 4, 5, 6, 7, 8}` for IPv6 addresses - * `:loopback` for local loopback (ie: `127.0.0.1`) - * `:any` for all interfaces (ie: `0.0.0.0`) - * `{:local, "/path/to/socket"}` for a Unix domain socket. If this option is used, the `port` - option *must* be set to `0` - * `inet`: Only bind to IPv4 interfaces. This option is offered as a convenience and actually sets the - option of the same name within `thousand_island_options.transport_options`. Must be specified - as a bare atom `:inet` - * `inet6`: Only bind to IPv6 interfaces. This option is offered as a convenience and actually sets the - option of the same name within `thousand_island_options.transport_options`. Must be specified - as a bare atom `:inet6` - * `keyfile`: The path to a file containing the SSL key to use for this server. This option is - offered as a convenience and actually sets the option of the same name within - `thousand_island_options.transport_options`. If a relative path is used here, you will also - need to set the `otp_app` parameter and ensure that the named file is part of your application - build - * `certfile`: The path to a file containing the SSL certificate to use for this server. This option is - offered as a convenience and actually sets the option of the same name within - `thousand_island_options.transport_options`. If a relative path is used here, you will also - need to set the `otp_app` parameter and ensure that the named file is part of your application - build - * `otp_app`: Provided as a convenience when using relative paths for `keyfile` and `certfile` - * `cipher_suite`: Used to define a pre-selected set of ciphers, as described by - `Plug.SSL.configure/1`. Optional, can be either `:strong` or `:compatible` - * `display_plug`: The plug to use when describing the connection in logs. Useful for situations - such as Phoenix code reloading where you have a 'wrapper' plug but wish to refer to the - connection by the endpoint name - * `startup_log`: The log level at which Bandit should log startup info. - Defaults to `:info` log level, can be set to false to disable it - * `thousand_island_options`: A list of options to pass to Thousand Island. Bandit sets some - default values in this list based on your top-level configuration; these values will be - overridden by values appearing here. A complete list can be found at - `t:ThousandIsland.options/0` - * `http_options`: A list of options to configure the shared aspects of Bandit's HTTP stack. A - complete list can be found at `t:http_options/0` - * `http_1_options`: A list of options to configure Bandit's HTTP/1 stack. A complete list can - be found at `t:http_1_options/0` - * `http_2_options`: A list of options to configure Bandit's HTTP/2 stack. A complete list can - be found at `t:http_2_options/0` - * `websocket_options`: A list of options to configure Bandit's WebSocket stack. A complete list can - be found at `t:websocket_options/0` - """ - @type options :: [ - {:plug, module() | {module(), Plug.opts()}} - | {:scheme, :http | :https} - | {:port, :inet.port_number()} - | {:ip, :inet.socket_address()} - | :inet - | :inet6 - | {:keyfile, binary()} - | {:certfile, binary()} - | {:otp_app, Application.app()} - | {:cipher_suite, :strong | :compatible} - | {:display_plug, module()} - | {:startup_log, Logger.level() | false} - | {:thousand_island_options, ThousandIsland.options()} - | {:http_options, http_options()} - | {:http_1_options, http_1_options()} - | {:http_2_options, http_2_options()} - | {:websocket_options, websocket_options()} - ] - - @typedoc """ - Options to configure shared aspects of the HTTP stack in Bandit - - * `compress`: Whether or not to attempt compression of responses via content-encoding - negotiation as described in - [RFC9110§8.4](https://www.rfc-editor.org/rfc/rfc9110.html#section-8.4). Defaults to true - * `response_encodings`: A list of compression encodings, expressed in order of preference. - Defaults to `~w(zstd gzip x-gzip deflate)`, with `zstd` only being present on platforms which - have the zstd library compiled in - * `deflate_options`: A keyword list of options to set on the deflate library. A complete list can - be found at `t:deflate_options/0`. Note that these options only affect the behaviour of the - 'deflate' content encoding; 'gzip' does not have any configurable options (this is a - limitation of the underlying `:zlib` library) - * `zstd_options`: A map of options passed verbatim to :zstd, review the options [here](https://www.erlang.org/doc/apps/stdlib/zstd.html#t:compress_parameters/0) - * `log_exceptions_with_status_codes`: Which exceptions to log. Bandit will log only those - exceptions whose status codes (as determined by `Plug.Exception.status/1`) match the specified - list or range. Defaults to `500..599` - * `log_protocol_errors`: How to log protocol errors such as malformed requests. `:short` will - log a single-line summary, while `:verbose` will log full stack traces. The value of `false` - will disable protocol error logging entirely. Defaults to `:short` - * `log_client_closures`: How to log cases where the client closes the connection. These happen - routinely in the real world and so the handling of them is configured separately since they - can be quite noisy. Takes the same options as `log_protocol_errors`, but defaults to `false` - """ - @type http_options :: [ - {:compress, boolean()} - | {:response_encodings, list()} - | {:deflate_options, deflate_options()} - | {:zstd_options, zstd_options()} - | {:log_exceptions_with_status_codes, list() | Range.t()} - | {:log_protocol_errors, :short | :verbose | false} - | {:log_client_closures, :short | :verbose | false} - ] - - @typedoc """ - Options to configure the HTTP/1 stack in Bandit - - * `enabled`: Whether or not to serve HTTP/1 requests. Defaults to true - * `max_request_line_length`: The maximum permitted length of the request line - (expressed as the number of bytes on the wire) in an HTTP/1.1 request. Defaults to 10_000 bytes - * `max_header_length`: The maximum permitted length of any single header (combined - key & value, expressed as the number of bytes on the wire) in an HTTP/1.1 request. Defaults to 10_000 bytes - * `max_header_count`: The maximum permitted number of headers in an HTTP/1.1 request. - Defaults to 50 headers - * `max_requests`: The maximum number of requests to serve in a single - HTTP/1.1 connection before closing the connection. Defaults to 0 (no limit) - * `clear_process_dict`: Whether to clear the process dictionary of all non-internal entries - between subsequent keepalive requests. If set, all keys not starting with `$` are removed from - the process dictionary between requests. Defaults to `true` - * `gc_every_n_keepalive_requests`: How often to run a full garbage collection pass between subsequent - keepalive requests on the same HTTP/1.1 connection. Defaults to 5 (garbage collect between - every 5 requests). This option is currently experimental, and may change at any time - * `log_unknown_messages`: Whether or not to log unknown messages sent to the handler process. - Defaults to `false` - """ - @type http_1_options :: [ - {:enabled, boolean()} - | {:max_request_line_length, pos_integer()} - | {:max_header_length, pos_integer()} - | {:max_header_count, pos_integer()} - | {:max_requests, pos_integer()} - | {:clear_process_dict, boolean()} - | {:gc_every_n_keepalive_requests, pos_integer()} - | {:log_unknown_messages, boolean()} - ] - - @typedoc """ - Options to configure the HTTP/2 stack in Bandit - - * `enabled`: Whether or not to serve HTTP/2 requests. Defaults to true - * `max_header_block_size`: The maximum permitted length of a field block of an HTTP/2 request - (expressed as the number of compressed bytes). Includes any concatenated block fragments from - continuation frames. Defaults to 50_000 bytes - * `max_requests`: The maximum number of requests to serve in a single - HTTP/2 connection before closing the connection. Defaults to 0 (no limit) - * `max_reset_stream_rate`: The maximum rate of stream resets (RST_STREAM frames) allowed. - Specified as a tuple of `{count, milliseconds}` where `count` is the maximum number of - RST_STREAM frames allowed within the time window of `milliseconds`. Defaults to `{500, 10_000}` - (500 resets per 10 seconds). Setting this to `nil` disables rate limiting - * `sendfile_chunk_size`: The maximum number of bytes read per sendfile chunk when streaming - HTTP/2 responses. Defaults to 1_048_576 (1 MiB) - * `default_local_settings`: Options to override the default values for local HTTP/2 - settings. Values provided here will override the defaults specified in RFC9113§6.5.2 - """ - @type http_2_options :: [ - {:enabled, boolean()} - | {:max_header_block_size, pos_integer()} - | {:max_requests, pos_integer()} - | {:max_reset_stream_rate, {pos_integer(), pos_integer()} | nil} - | {:sendfile_chunk_size, pos_integer()} - | {:default_local_settings, keyword()} - ] - - @typedoc """ - Options to configure the WebSocket stack in Bandit - - * `enabled`: Whether or not to serve WebSocket upgrade requests. Defaults to true - * `max_frame_size`: The maximum size of a single WebSocket frame (expressed as - a number of bytes on the wire). Defaults to 0 (no limit) - * `validate_text_frames`: Whether or not to validate text frames as being UTF-8. Strictly - speaking this is required per RFC6455§5.6, however it can be an expensive operation and one - that may be safely skipped in some situations. Defaults to true - * `compress`: Whether or not to allow per-message deflate compression globally. Note that - upgrade requests still need to set the `compress: true` option in `connection_opts` on - a per-upgrade basis for compression to be negotiated (see 'WebSocket Support' section below - for details). Defaults to `true` - * `deflate_options`: A keyword list of options to set on the deflate library when using the - per-message deflate extension. A complete list can be found at `t:deflate_options/0`. - `window_bits` is currently ignored and left to negotiation. - """ - @type websocket_options :: [ - {:enabled, boolean()} - | {:max_frame_size, pos_integer()} - | {:validate_text_frames, boolean()} - | {:compress, boolean()} - | {:deflate_options, deflate_options()} - ] - - @typedoc """ - Options to configure the deflate library used for HTTP and WebSocket compression - """ - @type deflate_options :: [ - {:level, :zlib.zlevel()} - | {:window_bits, :zlib.zwindowbits()} - | {:memory_level, :zlib.zmemlevel()} - | {:strategy, :zlib.zstrategy()} - ] - - @typedoc """ - Options to configure the zstd library used for HTTP compression - """ - @type zstd_options :: map - - @typep scheme :: :http | :https - - require Logger - - @doc false - @spec child_spec(options()) :: Supervisor.child_spec() - def child_spec(arg) do - %{ - id: {__MODULE__, make_ref()}, - start: {__MODULE__, :start_link, [arg]}, - type: :supervisor, - restart: :permanent - } - end - - @top_level_keys ~w(plug scheme port ip keyfile certfile otp_app cipher_suite display_plug startup_log thousand_island_options http_options http_1_options http_2_options websocket_options)a - @http_keys ~w(compress response_encodings deflate_options zstd_options log_exceptions_with_status_codes log_protocol_errors log_client_closures)a - @http_1_keys ~w(enabled max_request_line_length max_header_length max_header_count max_requests clear_process_dict gc_every_n_keepalive_requests log_unknown_messages)a - @http_2_keys ~w(enabled max_header_block_size max_requests max_reset_stream_rate sendfile_chunk_size default_local_settings)a - @websocket_keys ~w(enabled max_frame_size validate_text_frames compress deflate_options primitive_ops_module)a - @thousand_island_keys ThousandIsland.ServerConfig.__struct__() - |> Map.from_struct() - |> Map.keys() - - @doc """ - Starts a Bandit server using the provided arguments. See `t:options/0` for specific options to - pass to this function. - """ - @spec start_link(options()) :: Supervisor.on_start() - def start_link(arg) do - # Special case top-level `:inet` and `:inet6` options so we can use keyword logic everywhere else - arg = arg |> special_case_inet_options() |> validate_options(@top_level_keys, "top level") - - thousand_island_options = - Keyword.get(arg, :thousand_island_options, []) - |> validate_options(@thousand_island_keys, :thousand_island_options) - - http_options = - Keyword.get(arg, :http_options, []) - |> validate_options(@http_keys, :http_options) - - http_1_options = - Keyword.get(arg, :http_1_options, []) - |> validate_options(@http_1_keys, :http_1_options) - - http_2_options = - Keyword.get(arg, :http_2_options, []) - |> validate_options(@http_2_keys, :http_2_options) - - websocket_options = - Keyword.get(arg, :websocket_options, []) - |> validate_options(@websocket_keys, :websocket_options) - - {plug_mod, _} = plug = plug(arg) - display_plug = Keyword.get(arg, :display_plug, plug_mod) - startup_log = Keyword.get(arg, :startup_log, :info) - - {http_1_enabled, http_1_options} = Keyword.pop(http_1_options, :enabled, true) - {http_2_enabled, http_2_options} = Keyword.pop(http_2_options, :enabled, true) - - handler_options = %{ - plug: plug, - handler_module: Bandit.InitialHandler, - opts: %{ - http: http_options, - http_1: http_1_options, - http_2: http_2_options, - websocket: websocket_options - }, - http_1_enabled: http_1_enabled, - http_2_enabled: http_2_enabled - } - - scheme = Keyword.get(arg, :scheme, :http) - - {transport_module, transport_options, default_port} = - case scheme do - :http -> - transport_options = - Keyword.take(arg, [:ip]) - |> then(&(Keyword.get(thousand_island_options, :transport_options, []) ++ &1)) - - {ThousandIsland.Transports.TCP, transport_options, 4000} - - :https -> - supported_protocols = - if(http_2_enabled, do: ["h2"], else: []) ++ - if http_1_enabled, do: ["http/1.1"], else: [] - - transport_options = - Keyword.take(arg, [:ip, :keyfile, :certfile, :otp_app, :cipher_suite]) - |> Keyword.merge(alpn_preferred_protocols: supported_protocols) - |> then(&(Keyword.get(thousand_island_options, :transport_options, []) ++ &1)) - |> Plug.SSL.configure() - |> case do - {:ok, options} -> options - {:error, message} -> raise "Plug.SSL.configure/1 encountered error: #{message}" - end - |> Enum.reject(&(is_tuple(&1) and elem(&1, 0) == :otp_app)) - - {ThousandIsland.Transports.SSL, transport_options, 4040} - end - - port = Keyword.get(arg, :port, default_port) |> parse_as_number() - - thousand_island_options - |> Keyword.put_new(:port, port) - |> Keyword.put_new(:transport_module, transport_module) - |> Keyword.put(:transport_options, transport_options) - |> Keyword.put_new(:handler_module, Bandit.DelegatingHandler) - |> Keyword.put_new(:handler_options, handler_options) - |> ThousandIsland.start_link() - |> case do - {:ok, pid} -> - startup_log && - Logger.log(startup_log, info(scheme, display_plug, pid), domain: [:bandit], plug: plug) - - {:ok, pid} - - {:error, {:shutdown, {:failed_to_start_child, :listener, :eaddrinuse}}} = error -> - Logger.error([info(scheme, display_plug, nil), " failed, port #{port} already in use"], - domain: [:bandit], - plug: plug - ) - - error - - {:error, _} = error -> - error - end - end - - @spec special_case_inet_options(options()) :: options() - defp special_case_inet_options(opts) do - {inet_opts, opts} = Enum.split_with(opts, &(&1 in [:inet, :inet6])) - - if inet_opts == [] do - opts - else - Keyword.update( - opts, - :thousand_island_options, - [transport_options: inet_opts], - fn thousand_island_opts -> - Keyword.update(thousand_island_opts, :transport_options, inet_opts, &(&1 ++ inet_opts)) - end - ) - end - end - - @spec validate_options(Keyword.t(), [atom(), ...], String.t() | atom()) :: - Keyword.t() | no_return() - defp validate_options(options, valid_values, name) do - case Keyword.split(options, valid_values) do - {options, []} -> - options - - {_, illegal_options} -> - raise "Unsupported key(s) in #{name} config: #{inspect(Keyword.keys(illegal_options))}" - end - end - - @spec plug(options()) :: {module(), Plug.opts()} - defp plug(arg) do - arg - |> Keyword.get(:plug) - |> case do - nil -> raise "A value is required for :plug" - {plug_fn, plug_options} when is_function(plug_fn, 2) -> {plug_fn, plug_options} - plug_fn when is_function(plug_fn) -> {plug_fn, []} - {plug, plug_options} when is_atom(plug) -> validate_plug(plug, plug_options) - plug when is_atom(plug) -> validate_plug(plug, []) - other -> raise "Invalid value for plug: #{inspect(other)}" - end - end - - defp validate_plug(plug, plug_options) do - Code.ensure_loaded!(plug) - if !function_exported?(plug, :init, 1), do: raise("plug module does not define init/1") - if !function_exported?(plug, :call, 2), do: raise("plug module does not define call/2") - - {plug, plug.init(plug_options)} - end - - @spec parse_as_number(binary() | integer()) :: integer() - defp parse_as_number(value) when is_binary(value), do: String.to_integer(value) - defp parse_as_number(value) when is_integer(value), do: value - - @spec info(scheme(), module(), nil | pid()) :: String.t() - defp info(scheme, plug, pid) do - server_vsn = Application.spec(:bandit)[:vsn] - "Running #{inspect(plug)} with Bandit #{server_vsn} at #{bound_address(scheme, pid)}" - end - - @spec bound_address(scheme(), nil | pid()) :: String.t() | scheme() - defp bound_address(scheme, nil), do: scheme - - defp bound_address(scheme, pid) do - {:ok, {address, port}} = ThousandIsland.listener_info(pid) - - case address do - :local -> "#{_unix_path = port} (#{scheme}+unix)" - :undefined -> "#{inspect(port)} (#{scheme}+undefined)" - :unspec -> "unspec (#{scheme})" - address -> "#{:inet.ntoa(address)}:#{port} (#{scheme})" - end - end -end diff --git a/deps/bandit/lib/bandit/adapter.ex b/deps/bandit/lib/bandit/adapter.ex deleted file mode 100644 index b4fa0a3..0000000 --- a/deps/bandit/lib/bandit/adapter.ex +++ /dev/null @@ -1,294 +0,0 @@ -defmodule Bandit.Adapter do - @moduledoc false - # Implements the Plug-facing `Plug.Conn.Adapter` behaviour. These functions provide the primary - # mechanism for Plug applications to interact with a client, including functions to read the - # client body (if sent) and send response information back to the client. The concerns in this - # module are broadly about the semantics of HTTP in general, and less about transport-specific - # concerns, which are managed by the underlying `Bandit.HTTPTransport` implementation - - @behaviour Plug.Conn.Adapter - @already_sent {:plug_conn, :sent} - - defstruct transport: nil, - owner_pid: nil, - method: nil, - status: nil, - content_encoding: nil, - compression_context: nil, - upgrade: nil, - metrics: %{}, - opts: [] - - @typedoc "A struct for backing a Plug.Conn.Adapter" - @type t :: %__MODULE__{ - transport: Bandit.HTTPTransport.t(), - owner_pid: pid() | nil, - method: Plug.Conn.method() | nil, - status: Plug.Conn.status() | nil, - content_encoding: String.t(), - compression_context: Bandit.Compression.t() | nil, - upgrade: nil | {:websocket, opts :: keyword(), websocket_opts :: keyword()}, - metrics: %{}, - opts: %{ - required(:http) => Bandit.http_options(), - required(:websocket) => Bandit.websocket_options() - } - } - - def init(owner_pid, transport, method, headers, opts) do - content_encoding = - Bandit.Compression.negotiate_content_encoding( - Bandit.Headers.get_header(headers, "accept-encoding"), - opts.http - ) - - %__MODULE__{ - transport: transport, - owner_pid: owner_pid, - method: method, - content_encoding: content_encoding, - metrics: %{req_header_end_time: Bandit.Telemetry.monotonic_time()}, - opts: opts - } - end - - @impl Plug.Conn.Adapter - def read_req_body(%__MODULE__{} = adapter, opts) do - validate_calling_process!(adapter) - - metrics = - adapter.metrics - |> Map.put_new_lazy(:req_body_start_time, &Bandit.Telemetry.monotonic_time/0) - - case Bandit.HTTPTransport.read_data(adapter.transport, opts) do - {:ok, body, transport} -> - body = IO.iodata_to_binary(body) - - metrics = - metrics - |> Map.update(:req_body_bytes, byte_size(body), &(&1 + byte_size(body))) - |> Map.put(:req_body_end_time, Bandit.Telemetry.monotonic_time()) - - {:ok, body, %{adapter | transport: transport, metrics: metrics}} - - {:more, body, transport} -> - body = IO.iodata_to_binary(body) - - metrics = - metrics - |> Map.update(:req_body_bytes, byte_size(body), &(&1 + byte_size(body))) - - {:more, body, %{adapter | transport: transport, metrics: metrics}} - end - end - - ################## - # Response Sending - ################## - - @impl Plug.Conn.Adapter - def send_resp(%__MODULE__{} = adapter, status, headers, body) do - validate_calling_process!(adapter) - start_time = Bandit.Telemetry.monotonic_time() - - # Save an extra iodata_length by checking common cases - empty_body? = Bandit.SocketHelpers.iodata_empty?(body) - {headers, compression_context} = Bandit.Compression.new(adapter, status, headers, empty_body?) - - {compress_chunk, compression_context} = - Bandit.Compression.compress_chunk(body, compression_context) - - {close_chunk, compression_metrics} = Bandit.Compression.close(compression_context) - - encoded_body = [compress_chunk | close_chunk] - encoded_length = IO.iodata_length(encoded_body) - headers = Bandit.Headers.add_content_length(headers, encoded_length, status, adapter.method) - - metrics = - adapter.metrics - |> Map.put(:resp_start_time, start_time) - |> Map.merge(compression_metrics) - - adapter = - %{adapter | metrics: metrics} - |> send_headers(status, headers, :raw) - |> send_data(encoded_body, true) - - send(adapter.owner_pid, @already_sent) - {:ok, nil, adapter} - end - - @impl Plug.Conn.Adapter - def send_file( - %__MODULE__{} = adapter, - status, - headers, - path, - offset, - length - ) do - validate_calling_process!(adapter) - start_time = Bandit.Telemetry.monotonic_time() - {:ok, fileinfo} = :file.read_file_info(path, [:raw, time: :universal]) - %File.Stat{type: :regular, size: size} = File.Stat.from_record(fileinfo) - length = if length == :all, do: size - offset, else: length - - if offset + length <= size do - headers = Bandit.Headers.add_content_length(headers, length, status, adapter.method) - adapter = send_headers(adapter, status, headers, :raw) - - {socket, bytes_actually_written} = - if send_resp_body?(adapter), - do: {Bandit.HTTPTransport.sendfile(adapter.transport, path, offset, length), length}, - else: {adapter.transport, 0} - - metrics = - adapter.metrics - |> Map.put(:resp_body_bytes, bytes_actually_written) - |> Map.put(:resp_start_time, start_time) - |> Map.put(:resp_end_time, Bandit.Telemetry.monotonic_time()) - - send(adapter.owner_pid, @already_sent) - {:ok, nil, %{adapter | transport: socket, metrics: metrics}} - else - raise "Cannot read #{length} bytes starting at #{offset} as #{path} is only #{size} octets in length" - end - end - - @impl Plug.Conn.Adapter - def send_chunked(%__MODULE__{} = adapter, status, headers) do - validate_calling_process!(adapter) - start_time = Bandit.Telemetry.monotonic_time() - metrics = Map.put(adapter.metrics, :resp_start_time, start_time) - - {headers, compression_context} = Bandit.Compression.new(adapter, status, headers, false, true) - adapter = %{adapter | metrics: metrics, compression_context: compression_context} - send(adapter.owner_pid, @already_sent) - {:ok, nil, send_headers(adapter, status, headers, :chunk_encoded)} - end - - @impl Plug.Conn.Adapter - def chunk(%__MODULE__{} = adapter, chunk) do - # Sending an empty chunk implicitly ends the response. This is a bit of an undefined corner of - # the Plug.Conn.Adapter behaviour (see https://github.com/elixir-plug/plug/pull/535 for - # details) and ending the response here carves closest to the underlying HTTP/1.1 behaviour - # (RFC9112§7.1). Since there is no notion of chunked encoding is in HTTP/2 anyway (RFC9113§8.1) - # this entire section of the API is a bit slanty regardless. - - validate_calling_process!(adapter) - - # chunk/2 is unique among Plug.Conn.Adapter's sending callbacks in that it can return an error - # tuple instead of just raising or dying on error. Rescue here to implement this - try do - if Bandit.SocketHelpers.iodata_empty?(chunk) do - {encoded_chunk, compression_metrics} = - Bandit.Compression.close(adapter.compression_context) - - adapter = %{adapter | metrics: Map.merge(adapter.metrics, compression_metrics)} - - adapter = - if encoded_chunk != [] do - send_data(adapter, encoded_chunk, false) - else - adapter - end - - {:ok, nil, send_data(adapter, "", true)} - else - {encoded_chunk, compression_context} = - Bandit.Compression.compress_chunk(chunk, adapter.compression_context) - - adapter = %{adapter | compression_context: compression_context} - {:ok, nil, send_data(adapter, encoded_chunk, false)} - end - rescue - error in Bandit.TransportError -> {:error, error.error} - error -> {:error, Exception.message(error)} - end - end - - @impl Plug.Conn.Adapter - def inform(%__MODULE__{} = adapter, status, headers) do - validate_calling_process!(adapter) - # It's a bit weird to be casing on the underlying version here, but whether or not to send - # an informational response is actually defined in RFC9110§15.2 so we consider it as an aspect - # of semantics that belongs here and not in the underlying transport - if get_http_protocol(adapter) == :"HTTP/1.0" do - {:error, :not_supported} - else - # inform/3 is unique in that headers comes in as a keyword list - headers = Enum.map(headers, fn {header, value} -> {to_string(header), value} end) - {:ok, send_headers(adapter, status, headers, :inform)} - end - end - - defp send_headers(adapter, status, headers, body_disposition) do - headers = - if is_nil(Bandit.Headers.get_header(headers, "date")) do - [Bandit.Clock.date_header() | headers] - else - headers - end - - adapter = %{adapter | status: status} - - body_disposition = if send_resp_body?(adapter), do: body_disposition, else: :no_body - - socket = - Bandit.HTTPTransport.send_headers(adapter.transport, status, headers, body_disposition) - - %{adapter | transport: socket} - end - - defp send_data(adapter, data, end_request) do - socket = - if send_resp_body?(adapter), - do: Bandit.HTTPTransport.send_data(adapter.transport, data, end_request), - else: adapter.transport - - data_size = IO.iodata_length(data) - metrics = Map.update(adapter.metrics, :resp_body_bytes, data_size, &(&1 + data_size)) - - metrics = - if end_request, - do: Map.put(metrics, :resp_end_time, Bandit.Telemetry.monotonic_time()), - else: metrics - - %{adapter | transport: socket, metrics: metrics} - end - - defp send_resp_body?(%{method: "HEAD"}), do: false - defp send_resp_body?(%{status: 204}), do: false - defp send_resp_body?(%{status: 304}), do: false - defp send_resp_body?(_adapter), do: true - - @impl Plug.Conn.Adapter - def upgrade(%__MODULE__{} = adapter, protocol, opts) do - if Keyword.get(adapter.opts.websocket, :enabled, true) && - Bandit.HTTPTransport.supported_upgrade?(adapter.transport, protocol), - do: {:ok, %{adapter | upgrade: {protocol, opts, adapter.opts.websocket}}}, - else: {:error, :not_supported} - end - - @impl Plug.Conn.Adapter - def push(_adapter, _path, _headers), do: {:error, :not_supported} - - @impl Plug.Conn.Adapter - def get_peer_data(%__MODULE__{} = adapter), - do: Bandit.HTTPTransport.peer_data(adapter.transport) - - @impl Plug.Conn.Adapter - def get_sock_data(%__MODULE__{} = adapter), - do: Bandit.HTTPTransport.sock_data(adapter.transport) - - @impl Plug.Conn.Adapter - def get_ssl_data(%__MODULE__{} = adapter), - do: Bandit.HTTPTransport.ssl_data(adapter.transport) - - @impl Plug.Conn.Adapter - def get_http_protocol(%__MODULE__{} = adapter), - do: Bandit.HTTPTransport.version(adapter.transport) - - defp validate_calling_process!(%{owner_pid: owner}) when owner == self(), do: :ok - defp validate_calling_process!(_), do: raise("Adapter functions must be called by stream owner") -end diff --git a/deps/bandit/lib/bandit/application.ex b/deps/bandit/lib/bandit/application.ex deleted file mode 100644 index 4786f34..0000000 --- a/deps/bandit/lib/bandit/application.ex +++ /dev/null @@ -1,14 +0,0 @@ -defmodule Bandit.Application do - @moduledoc false - - use Application - - @impl Application - @spec start(Application.start_type(), start_args :: term) :: - {:ok, pid} - | {:error, {:already_started, pid} | {:shutdown, term} | term} - def start(_type, _args) do - children = [Bandit.Clock] - Supervisor.start_link(children, strategy: :one_for_one) - end -end diff --git a/deps/bandit/lib/bandit/clock.ex b/deps/bandit/lib/bandit/clock.ex deleted file mode 100644 index 64dcb4b..0000000 --- a/deps/bandit/lib/bandit/clock.ex +++ /dev/null @@ -1,56 +0,0 @@ -defmodule Bandit.Clock do - @moduledoc false - # Task which updates an ETS table with the current pre-formatted HTTP header - # timestamp once a second. This saves the individual request processes from - # having to construct this themselves, since it is a surprisingly expensive - # operation - - use Task, restart: :permanent - - require Logger - - @doc """ - Returns the current timestamp according to RFC9110§5.6.7. - - If the timestamp doesn't exist in the ETS table or the table doesn't exist - the timestamp is newly created for every request - """ - @spec date_header() :: {header :: binary(), date :: binary()} - def date_header do - date = - try do - :ets.lookup_element(__MODULE__, :date_header, 2) - rescue - ArgumentError -> - Logger.warning("Header timestamp couldn't be fetched from ETS cache", domain: [:bandit]) - get_date_header() - end - - {"date", date} - end - - @spec start_link(any()) :: {:ok, pid()} - def start_link(_opts) do - Task.start_link(__MODULE__, :init, []) - end - - @spec init :: no_return() - def init do - __MODULE__ = :ets.new(__MODULE__, [:set, :protected, :named_table, {:read_concurrency, true}]) - - run() - end - - @spec run() :: no_return() - defp run do - _ = update_header() - Process.sleep(1_000) - run() - end - - @spec get_date_header() :: String.t() - defp get_date_header, do: Calendar.strftime(DateTime.utc_now(), "%a, %d %b %Y %X GMT") - - @spec update_header() :: true - defp update_header, do: :ets.insert(__MODULE__, {:date_header, get_date_header()}) -end diff --git a/deps/bandit/lib/bandit/compression.ex b/deps/bandit/lib/bandit/compression.ex deleted file mode 100644 index 24c03ce..0000000 --- a/deps/bandit/lib/bandit/compression.ex +++ /dev/null @@ -1,168 +0,0 @@ -defmodule Bandit.Compression do - @moduledoc false - - defstruct method: nil, bytes_in: 0, lib_context: nil - - @typedoc "A struct containing the context for response compression" - @type t :: %__MODULE__{ - method: :deflate | :gzip | :identity | :zstd, - bytes_in: non_neg_integer(), - lib_context: term() - } - - @accepted_encodings ~w(gzip x-gzip deflate) - - if Code.ensure_loaded?(:zstd) do - @accepted_encodings ~w(zstd) ++ @accepted_encodings - end - - @spec negotiate_content_encoding(nil | binary(), keyword()) :: String.t() | nil - def negotiate_content_encoding(nil, _), do: nil - - def negotiate_content_encoding(accept_encoding, http_opts) do - if Keyword.get(http_opts, :compress, true) do - client_accept_encoding = Plug.Conn.Utils.list(accept_encoding) - - Keyword.get(http_opts, :response_encodings, @accepted_encodings) - |> Enum.find(&(&1 in client_accept_encoding)) - else - nil - end - end - - def new(adapter, status, headers, empty_body?, streamable \\ false) do - response_content_encoding_header = Bandit.Headers.get_header(headers, "content-encoding") - - headers = maybe_add_vary_header(adapter, status, headers) - - if status not in [204, 304] && not is_nil(adapter.content_encoding) && - is_nil(response_content_encoding_header) && - !response_has_strong_etag(headers) && !response_indicates_no_transform(headers) && - !empty_body? do - case start_stream(adapter.content_encoding, adapter.opts.http, streamable) do - {:ok, context} -> {[{"content-encoding", adapter.content_encoding} | headers], context} - {:error, :unsupported_encoding} -> {headers, %__MODULE__{method: :identity}} - end - else - {headers, %__MODULE__{method: :identity}} - end - end - - defp maybe_add_vary_header(adapter, status, headers) do - if status != 204 && Keyword.get(adapter.opts.http, :compress, true), - do: [{"vary", "accept-encoding"} | headers], - else: headers - end - - defp response_has_strong_etag(headers) do - case Bandit.Headers.get_header(headers, "etag") do - nil -> false - "\W" <> _rest -> false - _strong_etag -> true - end - end - - defp response_indicates_no_transform(headers) do - case Bandit.Headers.get_header(headers, "cache-control") do - nil -> false - header -> "no-transform" in Plug.Conn.Utils.list(header) - end - end - - defp start_stream("deflate", http_opts, _streamable) do - opts = Keyword.get(http_opts, :deflate_options, []) - deflate_context = :zlib.open() - - :zlib.deflateInit( - deflate_context, - Keyword.get(opts, :level, :default), - :deflated, - Keyword.get(opts, :window_bits, 15), - Keyword.get(opts, :mem_level, 8), - Keyword.get(opts, :strategy, :default) - ) - - {:ok, %__MODULE__{method: :deflate, lib_context: deflate_context}} - end - - defp start_stream("x-gzip", _opts, false), do: {:ok, %__MODULE__{method: :gzip}} - defp start_stream("gzip", _opts, false), do: {:ok, %__MODULE__{method: :gzip}} - - if Code.ensure_loaded?(:zstd) do - defp start_stream("zstd", http_opts, false) do - opts = Keyword.get(http_opts, :zstd_options, %{}) - {:ok, zstd_context} = :zstd.context(:compress, opts) - - {:ok, %__MODULE__{method: :zstd, lib_context: zstd_context}} - end - end - - defp start_stream(_encoding, _opts, _streamable), do: {:error, :unsupported_encoding} - - def compress_chunk(chunk, %__MODULE__{method: :deflate} = context) do - result = :zlib.deflate(context.lib_context, chunk, :sync) - - context = - context - |> Map.update!(:bytes_in, &(&1 + IO.iodata_length(chunk))) - - {result, context} - end - - if Code.ensure_loaded?(:zstd) do - def compress_chunk(chunk, %__MODULE__{method: :zstd} = context) do - result = :zstd.compress(chunk, context.lib_context) - - context = - context - |> Map.update!(:bytes_in, &(&1 + IO.iodata_length(chunk))) - - {result, context} - end - end - - def compress_chunk(chunk, %__MODULE__{method: :gzip, lib_context: nil} = context) do - result = :zlib.gzip(chunk) - - context = - context - |> Map.update!(:bytes_in, &(&1 + IO.iodata_length(chunk))) - |> Map.put(:lib_context, :done) - - {result, context} - end - - def compress_chunk(chunk, %__MODULE__{method: :identity} = context) do - {chunk, context} - end - - def close(%__MODULE__{} = context) do - chunk = close_context(context) - - if context.method == :identity do - {chunk, %{}} - else - {chunk, - %{ - resp_compression_method: to_string(context.method), - resp_uncompressed_body_bytes: context.bytes_in - }} - end - end - - defp close_context(%__MODULE__{method: :deflate, lib_context: lib_context}) do - last = :zlib.deflate(lib_context, [], :finish) - :ok = :zlib.deflateEnd(lib_context) - :zlib.close(lib_context) - last - end - - if Code.ensure_loaded?(:zstd) do - defp close_context(%__MODULE__{method: :zstd, lib_context: lib_context}) do - :zstd.close(lib_context) - [] - end - end - - defp close_context(_context), do: [] -end diff --git a/deps/bandit/lib/bandit/delegating_handler.ex b/deps/bandit/lib/bandit/delegating_handler.ex deleted file mode 100644 index 9951b21..0000000 --- a/deps/bandit/lib/bandit/delegating_handler.ex +++ /dev/null @@ -1,78 +0,0 @@ -defmodule Bandit.DelegatingHandler do - @moduledoc false - # Delegates all implementation of the ThousandIsland.Handler behaviour - # to an implementation specified in state. Allows for clean separation - # between protocol implementations & friction free protocol selection & - # upgrades. - - use ThousandIsland.Handler - - @impl ThousandIsland.Handler - def handle_connection(socket, %{handler_module: handler_module} = state) do - handler_module.handle_connection(socket, state) - |> handle_bandit_continuation(socket) - end - - @impl ThousandIsland.Handler - def handle_data(data, socket, %{handler_module: handler_module} = state) do - handler_module.handle_data(data, socket, state) - |> handle_bandit_continuation(socket) - end - - @impl ThousandIsland.Handler - def handle_shutdown(socket, %{handler_module: handler_module} = state) do - handler_module.handle_shutdown(socket, state) - end - - @impl ThousandIsland.Handler - def handle_close(socket, %{handler_module: handler_module} = state) do - handler_module.handle_close(socket, state) - end - - @impl ThousandIsland.Handler - def handle_timeout(socket, %{handler_module: handler_module} = state) do - handler_module.handle_timeout(socket, state) - end - - @impl ThousandIsland.Handler - def handle_error(error, socket, %{handler_module: handler_module} = state) do - handler_module.handle_error(error, socket, state) - end - - @impl GenServer - def handle_call(msg, from, {_socket, %{handler_module: handler_module}} = state) do - handler_module.handle_call(msg, from, state) - end - - @impl GenServer - def handle_cast(msg, {_socket, %{handler_module: handler_module}} = state) do - handler_module.handle_cast(msg, state) - end - - @impl GenServer - def handle_info(msg, {_socket, %{handler_module: handler_module}} = state) do - handler_module.handle_info(msg, state) - end - - defp handle_bandit_continuation(continuation, socket) do - case continuation do - {:switch, next_handler, state} -> - handle_connection(socket, %{state | handler_module: next_handler}) - - {:switch, next_handler, data, state} -> - case handle_connection(socket, %{state | handler_module: next_handler}) do - {:continue, state} -> - handle_data(data, socket, state) - - {:continue, state, _timeout} -> - handle_data(data, socket, state) - - other -> - other - end - - other -> - other - end - end -end diff --git a/deps/bandit/lib/bandit/extractor.ex b/deps/bandit/lib/bandit/extractor.ex deleted file mode 100644 index 004dc03..0000000 --- a/deps/bandit/lib/bandit/extractor.ex +++ /dev/null @@ -1,113 +0,0 @@ -defmodule Bandit.Extractor do - @moduledoc false - # A state machine for efficiently extracting full frames from received packets - - @type deserialize_result :: any() - - @callback header_and_payload_length(binary(), max_frame_size :: integer()) :: - {:ok, {header_length :: integer(), payload_length :: integer()}} - | {:error, term()} - | :more - - @callback deserialize(binary(), primitive_ops_module :: module()) :: deserialize_result() - - @type t :: %__MODULE__{ - header: binary(), - payload: iodata(), - payload_length: non_neg_integer(), - required_length: non_neg_integer(), - mode: :header_parsing | :payload_parsing, - max_frame_size: non_neg_integer(), - frame_parser: atom(), - primitive_ops_module: module() - } - - defstruct header: <<>>, - payload: [], - payload_length: 0, - required_length: 0, - mode: :header_parsing, - max_frame_size: 0, - frame_parser: nil, - primitive_ops_module: nil - - @spec new(module(), module(), Keyword.t()) :: t() - def new(frame_parser, primitive_ops_module, opts) do - max_frame_size = Keyword.get(opts, :max_frame_size, 0) - - %__MODULE__{ - max_frame_size: max_frame_size, - frame_parser: frame_parser, - primitive_ops_module: primitive_ops_module - } - end - - @spec push_data(t(), binary()) :: t() - def push_data(%__MODULE__{} = state, data) do - case state do - %{mode: :header_parsing} -> - %{state | header: state.header <> data} - - %{mode: :payload_parsing, payload: payload, payload_length: length} -> - %{state | payload: [payload, data], payload_length: length + byte_size(data)} - end - end - - @spec pop_frame(t()) :: {t(), :more | deserialize_result()} - def pop_frame(state) - - def pop_frame(%__MODULE__{mode: :header_parsing} = state) do - case state.frame_parser.header_and_payload_length(state.header, state.max_frame_size) do - {:ok, {header_length, required_length}} -> - state - |> transition_to_payload_parsing(header_length, required_length) - |> pop_frame() - - {:error, message} -> - {state, {:error, message}} - - :more -> - {state, :more} - end - end - - def pop_frame( - %__MODULE__{ - mode: :payload_parsing, - payload_length: payload_length, - required_length: required_length - } = state - ) do - if payload_length >= required_length do - <> = - IO.iodata_to_binary(state.payload) - - frame = state.frame_parser.deserialize(state.header <> payload, state.primitive_ops_module) - state = transition_to_header_parsing(state, rest) - - {state, frame} - else - {state, :more} - end - end - - defp transition_to_payload_parsing(state, header_length, required_length) do - payload_length = byte_size(state.header) - header_length - - state - |> Map.put(:header, binary_part(state.header, 0, header_length)) - |> Map.put(:payload, binary_part(state.header, header_length, payload_length)) - |> Map.put(:payload_length, payload_length) - |> Map.put(:required_length, required_length) - |> Map.put(:mode, :payload_parsing) - end - - defp transition_to_header_parsing(state, rest) do - state - |> Map.put(:header, rest) - |> Map.put(:payload, []) - |> Map.put(:payload_length, 0) - |> Map.put(:required_length, 0) - |> Map.put(:mode, :header_parsing) - end -end diff --git a/deps/bandit/lib/bandit/headers.ex b/deps/bandit/lib/bandit/headers.ex deleted file mode 100644 index 5fb0ab0..0000000 --- a/deps/bandit/lib/bandit/headers.ex +++ /dev/null @@ -1,123 +0,0 @@ -defmodule Bandit.Headers do - @moduledoc false - # Conveniences for dealing with headers. - - @spec is_port_number(integer()) :: Macro.t() - defguardp is_port_number(port) when Bitwise.band(port, 0xFFFF) === port - - @spec get_header(Plug.Conn.headers(), header :: binary()) :: binary() | nil - def get_header(headers, header) do - case List.keyfind(headers, header, 0) do - {_, value} -> value - nil -> nil - end - end - - # Covers IPv6 addresses, like `[::1]:4000` as defined in RFC3986. - @spec parse_hostlike_header!(host_header :: binary()) :: - {Plug.Conn.host(), nil | Plug.Conn.port_number()} - def parse_hostlike_header!("[" <> _ = host_header) do - host_header - |> :binary.split("]:") - |> case do - [host, port] -> - case parse_integer(port) do - {port, ""} when is_port_number(port) -> {host <> "]", port} - _ -> raise Bandit.HTTPError, "Header contains invalid port" - end - - [host] -> - {host, nil} - end - end - - def parse_hostlike_header!(host_header) do - host_header - |> :binary.split(":") - |> case do - [host, port] -> - case parse_integer(port) do - {port, ""} when is_port_number(port) -> {host, port} - _ -> raise Bandit.HTTPError, "Header contains invalid port" - end - - [host] -> - {host, nil} - end - end - - @spec get_content_length(Plug.Conn.headers()) :: - {:ok, nil | non_neg_integer()} | {:error, String.t()} - def get_content_length(headers) do - case get_header(headers, "content-length") do - nil -> {:ok, nil} - value -> parse_content_length(value) - end - end - - @spec parse_content_length(binary()) :: {:ok, non_neg_integer()} | {:error, String.t()} - defp parse_content_length(value) do - case parse_integer(value) do - {length, ""} -> - {:ok, length} - - {length, _rest} -> - if value |> Plug.Conn.Utils.list() |> Enum.all?(&(&1 == to_string(length))), - do: {:ok, length}, - else: {:error, "invalid content-length header (RFC9112§6.3.5)"} - - :error -> - {:error, "invalid content-length header (RFC9112§6.3.5)"} - end - end - - # Parses non-negative integers from strings. Return the valid portion of an - # integer and the remaining string as a tuple like `{123, ""}` or `:error`. - @spec parse_integer(String.t()) :: {non_neg_integer(), rest :: String.t()} | :error - defp parse_integer(<>) when digit >= ?0 and digit <= ?9 do - parse_integer(rest, digit - ?0) - end - - defp parse_integer(_), do: :error - - @spec parse_integer(String.t(), non_neg_integer()) :: {non_neg_integer(), String.t()} - defp parse_integer(<>, total) when digit >= ?0 and digit <= ?9 do - parse_integer(rest, total * 10 + digit - ?0) - end - - defp parse_integer(rest, total), do: {total, rest} - - @spec add_content_length( - headers :: Plug.Conn.headers(), - length :: non_neg_integer(), - status :: Plug.Conn.int_status(), - method :: Plug.Conn.method() - ) :: - Plug.Conn.headers() - - # Per RFC9110§8.6, we use the following logic: - # - # * If the response is 1xx or 204, content-length is NEVER sent - # * If the response is 304 or the method is HEAD AND the body length is zero, respect any - # content-length header the plug may have set on the assumption that it knows what it would - # have sent - # * For all other responses, use the length of the provided response body as the content-length, - # overwriting any content-length the plug may have set - def add_content_length(headers, _length, status, _method) - when status in 100..199 or status == 204 do - drop_content_length(headers) - end - - def add_content_length(headers, 0, status, method) when status == 304 or method == "HEAD" do - headers - end - - def add_content_length(headers, length, _status, _method) do - [{"content-length", to_string(length)} | drop_content_length(headers)] - end - - @spec drop_content_length(Plug.Conn.headers()) :: Plug.Conn.headers() - defp drop_content_length(headers) do - Enum.reject(headers, &(elem(&1, 0) == "content-length")) - end -end diff --git a/deps/bandit/lib/bandit/http1/README.md b/deps/bandit/lib/bandit/http1/README.md deleted file mode 100644 index 2fc7197..0000000 --- a/deps/bandit/lib/bandit/http1/README.md +++ /dev/null @@ -1,30 +0,0 @@ -# HTTP/1 Handler - -Included in this folder is a complete `ThousandIsland.Handler` based implementation of HTTP/1.x as -defined in [RFC 9112](https://datatracker.ietf.org/doc/rfc9112). - -## Process model - -Within a Bandit server, an HTTP/1 connection is modeled as a single process. -This process is tied to the lifecycle of the underlying TCP connection; in the -case of an HTTP client which makes use of HTTP's keep-alive feature to make -multiple requests on the same connection, all of these requests will be serviced -by this same process. - -The execution model to handle a given request is quite straightforward: the -underlying [Thousand Island](https://github.com/mtrudel/thousand_island) library -will call `Bandit.HTTP1.Handler.handle_data/3`, which will then construct a -`Bandit.HTTP1.Socket` struct that conforms to the `Bandit.HTTPTransport` -protocol. It will then call `Bandit.Pipeline.run/3`, which will go through the -process of reading the request (by calling functions on the -`Bandit.HTTPTransport` protocol), and constructing a `Plug.Conn` structure to -represent the request and subsequently pass it to the configured `Plug` module. - -# Testing - -All of this is exhaustively tested. Tests are located in `request_test.exs`, and -are broadly either concerned with testing network-facing aspects of the -implementation (ie: how well Bandit satisfies the relevant RFCs) or the Plug-facing -aspects of the implementation. - -Unfortunately, there is no HTTP/1 equivalent to the external h2spec test suite. diff --git a/deps/bandit/lib/bandit/http1/handler.ex b/deps/bandit/lib/bandit/http1/handler.ex deleted file mode 100644 index 459ee59..0000000 --- a/deps/bandit/lib/bandit/http1/handler.ex +++ /dev/null @@ -1,96 +0,0 @@ -defmodule Bandit.HTTP1.Handler do - @moduledoc false - # An HTTP 1.0 & 1.1 Thousand Island Handler - - use ThousandIsland.Handler - - @impl ThousandIsland.Handler - def handle_data(data, socket, state) do - transport = %Bandit.HTTP1.Socket{socket: socket, buffer: data, opts: state.opts} - connection_span = ThousandIsland.Socket.telemetry_span(socket) - conn_data = Bandit.SocketHelpers.conn_data(socket) - - case Bandit.Pipeline.run(transport, state.plug, connection_span, conn_data, state.opts) do - {:ok, transport} -> maybe_keepalive(transport, state) - {:error, _reason} -> {:close, state} - {:upgrade, _transport, :websocket, opts} -> do_websocket_upgrade(opts, state) - end - end - - defp maybe_keepalive(transport, state) do - requests_processed = Map.get(state, :requests_processed, 0) + 1 - request_limit = Keyword.get(state.opts.http_1, :max_requests, 0) - under_limit = request_limit == 0 || requests_processed < request_limit - - if under_limit && transport.keepalive do - if Keyword.get(state.opts.http_1, :clear_process_dict, true), do: clear_process_dict() - gc_every_n_requests = Keyword.get(state.opts.http_1, :gc_every_n_keepalive_requests, 5) - if rem(requests_processed, gc_every_n_requests) == 0, do: :erlang.garbage_collect() - - state = Map.put(state, :requests_processed, requests_processed) - - # We have bytes that we've read but haven't yet processed, tail call handle_data to start - # reading the next request - if Bandit.SocketHelpers.iodata_empty?(transport.buffer) do - {:continue, state} - else - handle_data(transport.buffer, transport.socket, state) - end - else - {:close, state} - end - end - - defp clear_process_dict do - Process.get_keys() - |> Enum.each( - &if &1 not in ~w[$ancestors $initial_call $process_label]a, do: Process.delete(&1) - ) - end - - defp do_websocket_upgrade(upgrade_opts, state) do - :erlang.garbage_collect() - {:switch, Bandit.WebSocket.Handler, Map.put(state, :upgrade_opts, upgrade_opts)} - end - - def handle_info({:plug_conn, :sent}, {socket, state}), - do: {:noreply, {socket, state}, socket.read_timeout} - - def handle_info({:EXIT, _pid, :normal}, {socket, state}), - do: {:noreply, {socket, state}, socket.read_timeout} - - def handle_info(msg, {socket, state}) do - if Keyword.get(state.opts.http_1, :log_unknown_messages, false), do: log_no_handle_info(msg) - {:noreply, {socket, state}, socket.read_timeout} - end - - def handle_info(msg, state) do - log_no_handle_info(msg) - {:noreply, state} - end - - defp log_no_handle_info(msg) do - # Copied verbatim from lib/elixir/lib/gen_server.ex - proc = - case Process.info(self(), :registered_name) do - {_, []} -> self() - {_, name} -> name - end - - :logger.error( - %{ - label: {GenServer, :no_handle_info}, - report: %{ - module: __MODULE__, - message: msg, - name: proc - } - }, - %{ - domain: [:otp, :elixir], - error_logger: %{tag: :error_msg}, - report_cb: &GenServer.format_report/1 - } - ) - end -end diff --git a/deps/bandit/lib/bandit/http1/socket.ex b/deps/bandit/lib/bandit/http1/socket.ex deleted file mode 100644 index 84ce945..0000000 --- a/deps/bandit/lib/bandit/http1/socket.ex +++ /dev/null @@ -1,503 +0,0 @@ -defmodule Bandit.HTTP1.Socket do - @moduledoc false - # This module implements the lower level parts of HTTP/1 (roughly, the aspects of the protocol - # described in RFC 9112 as opposed to RFC 9110). It is similar in spirit to - # `Bandit.HTTP2.Stream` for HTTP/2, and indeed both implement the `Bandit.HTTPTransport` - # behaviour. An instance of this struct is maintained as the state of a `Bandit.HTTP1.Handler` - # process, and it moves an HTTP/1 request through its lifecycle by calling functions defined on - # this module. This state is also tracked within the `Bandit.Adapter` instance that backs - # Bandit's Plug API. - - defstruct socket: nil, - buffer: <<>>, - read_state: :unread, - write_state: :unsent, - unread_content_length: nil, - body_encoding: nil, - version: :"HTTP/1.0", - send_buffer: nil, - request_connection_header: nil, - keepalive: nil, - opts: %{} - - @typedoc "An HTTP/1 read state" - @type read_state :: :unread | :headers_read | :read - - @typedoc "An HTTP/1 write state" - @type write_state :: :unsent | :writing | :chunking | :chunk_streaming | :sent - - @typedoc "The information necessary to communicate to/from a socket" - @type t :: %__MODULE__{ - socket: ThousandIsland.Socket.t(), - buffer: iodata(), - read_state: read_state(), - write_state: write_state(), - unread_content_length: non_neg_integer() | :chunked | nil, - body_encoding: nil | binary(), - version: nil | :"HTTP/1.1" | :"HTTP/1.0", - send_buffer: iolist(), - request_connection_header: binary(), - keepalive: boolean(), - opts: %{ - required(:http_1) => Bandit.http_1_options() - } - } - - defimpl Bandit.HTTPTransport do - def peer_data(%@for{} = socket), do: Bandit.SocketHelpers.peer_data(socket.socket) - - def sock_data(%@for{} = socket), do: Bandit.SocketHelpers.sock_data(socket.socket) - - def ssl_data(%@for{} = socket), do: Bandit.SocketHelpers.ssl_data(socket.socket) - - def version(%@for{} = socket), do: socket.version - - def read_headers(%@for{read_state: :unread} = socket) do - {method, request_target, socket} = do_read_request_line!(socket) - {headers, socket} = do_read_headers!(socket) - content_length = get_content_length!(headers) - body_encoding = Bandit.Headers.get_header(headers, "transfer-encoding") - request_connection_header = safe_downcase(Bandit.Headers.get_header(headers, "connection")) - socket = %{socket | request_connection_header: request_connection_header} - - case {content_length, body_encoding} do - {nil, nil} -> - # No body, so just go straight to 'read' - {:ok, method, request_target, headers, %{socket | read_state: :read}} - - {content_length, nil} -> - socket = %{socket | read_state: :headers_read, unread_content_length: content_length} - {:ok, method, request_target, headers, socket} - - {nil, body_encoding} -> - socket = %{socket | read_state: :headers_read, body_encoding: body_encoding} - {:ok, method, request_target, headers, socket} - - {_content_length, _body_encoding} -> - request_error!( - "Request cannot contain both 'content-length' and 'transfer-encoding' (RFC9112§6.3.3)" - ) - end - end - - defp do_read_request_line!(socket, request_target \\ nil) do - packet_size = Keyword.get(socket.opts.http_1, :max_request_line_length, 10_000) - - case :erlang.decode_packet(:http_bin, socket.buffer, packet_size: packet_size) do - {:more, _len} -> - chunk = read_available_for_header!(socket.socket) - do_read_request_line!(%{socket | buffer: socket.buffer <> chunk}, request_target) - - {:ok, {:http_request, method, request_target, version}, rest} -> - version = get_version!(version) - # decode_packet is inconsistent about atom/string method returns - method = to_string(method) - request_target = resolve_request_target!(request_target, method) - socket = %{socket | buffer: rest, version: version} - {method, request_target, socket} - - {:ok, {:http_error, reason}, _rest} -> - request_error!("Request line HTTP error: #{inspect(reason)}") - - {:error, :invalid} -> - request_error!("Request URI is too long", :request_uri_too_long) - - {:error, reason} -> - request_error!("Request line unknown error: #{inspect(reason)}") - end - end - - defp get_version!({1, 1}), do: :"HTTP/1.1" - defp get_version!({1, 0}), do: :"HTTP/1.0" - defp get_version!(other), do: request_error!("Invalid HTTP version: #{inspect(other)}") - - # Unwrap different request_targets returned by :erlang.decode_packet/3 - defp resolve_request_target!({:abs_path, path}, _), do: {nil, nil, nil, path} - - defp resolve_request_target!({:absoluteURI, scheme, host, :undefined, path}, _), - do: {to_string(scheme), host, nil, path} - - defp resolve_request_target!({:absoluteURI, scheme, host, port, path}, _), - do: {to_string(scheme), host, port, path} - - defp resolve_request_target!(:*, "OPTIONS"), do: {nil, nil, nil, :*} - - defp resolve_request_target!({:scheme, scheme, port}, "CONNECT"), - do: {nil, scheme, port, nil} - - defp resolve_request_target!(_request_target, _method), - do: request_error!("Unsupported request target (RFC9112§3.2)") - - defp do_read_headers!(socket, headers \\ []) do - packet_size = Keyword.get(socket.opts.http_1, :max_header_length, 10_000) - - case :erlang.decode_packet(:httph_bin, socket.buffer, packet_size: packet_size) do - {:more, _len} -> - chunk = read_available_for_header!(socket.socket) - socket = %{socket | buffer: socket.buffer <> chunk} - do_read_headers!(socket, headers) - - {:ok, {:http_header, _, header, _, value}, rest} -> - socket = %{socket | buffer: rest} - headers = [{header |> to_string() |> String.downcase(:ascii), value} | headers] - - if length(headers) <= Keyword.get(socket.opts.http_1, :max_header_count, 50) do - do_read_headers!(socket, headers) - else - request_error!("Too many headers", :request_header_fields_too_large) - end - - {:ok, :http_eoh, rest} -> - socket = %{socket | read_state: :headers_read, buffer: rest} - {Enum.reverse(headers), socket} - - {:ok, {:http_error, reason}, _rest} -> - request_error!("Header read HTTP error: #{inspect(reason)}") - - {:error, :invalid} -> - request_error!("Header too long", :request_header_fields_too_large) - - {:error, reason} -> - request_error!("Header read unknown error: #{inspect(reason)}") - end - end - - defp get_content_length!(headers) do - case Bandit.Headers.get_content_length(headers) do - {:ok, content_length} -> content_length - {:error, reason} -> request_error!("Content length unknown error: #{inspect(reason)}") - end - end - - def read_data( - %@for{read_state: :headers_read, unread_content_length: unread_content_length} = socket, - opts - ) - when is_number(unread_content_length) do - {to_return, buffer, remaining_unread_content_length} = - do_read_content_length_data!(socket.socket, socket.buffer, unread_content_length, opts) - - socket = %{socket | buffer: buffer, unread_content_length: remaining_unread_content_length} - - if remaining_unread_content_length == 0 do - {:ok, to_return, %{socket | read_state: :read}} - else - {:more, to_return, socket} - end - end - - def read_data(%@for{read_state: :headers_read, body_encoding: "chunked"} = socket, opts) do - read_size = Keyword.get(opts, :read_length, 1_000_000) - read_timeout = Keyword.get(opts, :read_timeout) - - {body, buffer} = - do_read_chunked_data!(socket.socket, socket.buffer, <<>>, read_size, read_timeout) - - body = IO.iodata_to_binary(body) - - {:ok, body, %{socket | read_state: :read, buffer: buffer}} - end - - def read_data(%@for{read_state: :headers_read, body_encoding: body_encoding}, _opts) - when not is_nil(body_encoding) do - request_error!("Unsupported transfer-encoding") - end - - def read_data(%@for{} = socket, _opts), do: {:ok, <<>>, socket} - - @dialyzer {:no_improper_lists, do_read_content_length_data!: 4} - defp do_read_content_length_data!(socket, buffer, unread_content_length, opts) do - max_to_return = min(unread_content_length, Keyword.get(opts, :length, 8_000_000)) - - cond do - max_to_return == 0 -> - # We have already satisfied our content length - {<<>>, buffer, unread_content_length} - - byte_size(buffer) >= max_to_return -> - # We can satisfy the read request entirely from our buffer - <> = buffer - {to_return, rest, unread_content_length - max_to_return} - - byte_size(buffer) < max_to_return -> - # We need to read off the wire - read_size = Keyword.get(opts, :read_length, 1_000_000) - read_timeout = Keyword.get(opts, :read_timeout) - - to_return = - read!(socket, max_to_return - byte_size(buffer), [buffer], read_size, read_timeout) - |> IO.iodata_to_binary() - - # We may have read more than we need to return - if byte_size(to_return) >= max_to_return do - <> = to_return - {to_return, rest, unread_content_length - max_to_return} - else - {to_return, <<>>, unread_content_length - byte_size(to_return)} - end - end - end - - @dialyzer {:no_improper_lists, do_read_chunked_data!: 5} - defp do_read_chunked_data!(socket, buffer, body, read_size, read_timeout) do - case :binary.split(buffer, "\r\n") do - ["0", "\r\n" <> rest] -> - # We should be reading (and ignoring) trailers here - {IO.iodata_to_binary(body), rest} - - [chunk_size, rest] -> - chunk_size = String.to_integer(chunk_size, 16) - - case rest do - <> -> - do_read_chunked_data!(socket, rest, [body, next_chunk], read_size, read_timeout) - - _ -> - to_read = chunk_size - byte_size(rest) - - if to_read > 0 do - iolist = read!(socket, to_read, [], read_size, read_timeout) - buffer = IO.iodata_to_binary([buffer | iolist]) - do_read_chunked_data!(socket, buffer, body, read_size, read_timeout) - else - chunk = read_available!(socket, read_timeout) - buffer = buffer <> chunk - do_read_chunked_data!(socket, buffer, body, read_size, read_timeout) - end - end - - _ -> - chunk = read_available!(socket, read_timeout) - buffer = buffer <> chunk - do_read_chunked_data!(socket, buffer, body, read_size, read_timeout) - end - end - - ################## - # Internal Reading - ################## - - @compile {:inline, read_available_for_header!: 1} - @spec read_available_for_header!(ThousandIsland.Socket.t()) :: binary() - defp read_available_for_header!(socket) do - case ThousandIsland.Socket.recv(socket, 0) do - {:ok, chunk} -> chunk - {:error, reason} -> socket_error!(reason) - end - end - - @compile {:inline, read_available!: 2} - @spec read_available!(ThousandIsland.Socket.t(), timeout()) :: binary() - defp read_available!(socket, read_timeout) do - case ThousandIsland.Socket.recv(socket, 0, read_timeout) do - {:ok, chunk} -> chunk - {:error, :timeout} -> <<>> - {:error, reason} -> socket_error!(reason) - end - end - - @dialyzer {:no_improper_lists, read!: 5} - @spec read!( - ThousandIsland.Socket.t(), - non_neg_integer(), - iolist(), - non_neg_integer(), - timeout() - ) :: - iolist() - defp read!(socket, to_read, already_read, read_size, read_timeout) do - case ThousandIsland.Socket.recv(socket, min(to_read, read_size), read_timeout) do - {:ok, chunk} -> - remaining_bytes = to_read - byte_size(chunk) - - if remaining_bytes > 0 do - read!(socket, remaining_bytes, [already_read | chunk], read_size, read_timeout) - else - [already_read | chunk] - end - - {:error, :timeout} -> - handle_timeout_with_disconnect_check!(socket) - - {:error, reason} -> - socket_error!(reason) - end - end - - # After a timeout, check if the peer is still connected. If not, this is - # likely a client disconnect that manifested as a timeout. - # We raise TransportError for disconnects and HTTPError for genuine timeouts. - # Use a non-blocking recv (timeout: 0) to detect closed connections. - @spec handle_timeout_with_disconnect_check!(ThousandIsland.Socket.t()) :: no_return() - defp handle_timeout_with_disconnect_check!(socket) do - case ThousandIsland.Socket.recv(socket, 0, 0) do - {:error, :timeout} -> - # Socket is still open but no data - genuine timeout - request_error!("Body read timeout", :request_timeout) - - {:error, reason} -> - # Socket error (e.g., :closed) - client disconnected - socket_error!(reason) - - {:ok, _data} -> - # Unexpected: data arrived just after timeout. Treat as timeout - # since we already committed to the timeout path. - request_error!("Body read timeout", :request_timeout) - end - end - - def send_headers(%@for{write_state: :unsent} = socket, status, headers, body_disposition) do - resp_line = "#{socket.version} #{status} #{Plug.Conn.Status.reason_phrase(status)}\r\n" - - {headers, socket} = handle_keepalive(status, headers, socket) - - has_content_length = Bandit.Headers.get_header(headers, "content-length") != nil - - case body_disposition do - :raw -> - # This is an optimization for the common case of sending a non-encoded body (or file), - # and coalesces the header and body send calls into a single ThousandIsland.Socket.send/2 - # call. This makes a _substantial_ difference in practice - %{socket | write_state: :writing, send_buffer: [resp_line | encode_headers(headers)]} - - :chunk_encoded when not has_content_length -> - headers = [{"transfer-encoding", "chunked"} | headers] - send!(socket.socket, [resp_line | encode_headers(headers)]) - %{socket | write_state: :chunking} - - :chunk_encoded when has_content_length -> - send!(socket.socket, [resp_line | encode_headers(headers)]) - %{socket | write_state: :chunk_streaming} - - :no_body -> - send!(socket.socket, [resp_line | encode_headers(headers)]) - %{socket | write_state: :sent} - - :inform -> - send!(socket.socket, [resp_line | encode_headers(headers)]) - %{socket | write_state: :unsent} - end - end - - defp handle_keepalive(status, headers, socket) do - response_connection_header = safe_downcase(Bandit.Headers.get_header(headers, "connection")) - - # Per RFC9112§9.3 - cond do - status in 100..199 -> - {headers, socket} - - socket.request_connection_header == "close" || response_connection_header == "close" -> - {headers, %{socket | keepalive: false}} - - socket.version == :"HTTP/1.1" -> - {headers, %{socket | keepalive: true}} - - socket.version == :"HTTP/1.0" && socket.request_connection_header == "keep-alive" -> - {[{"connection", "keep-alive"} | headers], %{socket | keepalive: true}} - - true -> - {[{"connection", "close"} | headers], %{socket | keepalive: false}} - end - end - - defp safe_downcase(str) when is_binary(str), do: String.downcase(str, :ascii) - defp safe_downcase(str), do: str - - defp encode_headers(headers) do - headers - |> Enum.map(fn {k, v} -> [k, ": ", v, "\r\n"] end) - |> then(&[&1 | ["\r\n"]]) - end - - def send_data(%@for{write_state: :writing} = socket, data, end_request) do - send!(socket.socket, [socket.send_buffer | data]) - write_state = if end_request, do: :sent, else: :writing - %{socket | write_state: write_state, send_buffer: []} - end - - def send_data(%@for{write_state: :chunking} = socket, data, end_request) do - byte_size = data |> IO.iodata_length() - send!(socket.socket, [Integer.to_string(byte_size, 16), "\r\n", data, "\r\n"]) - write_state = if end_request, do: :sent, else: :chunking - %{socket | write_state: write_state} - end - - def send_data(%@for{write_state: :chunk_streaming} = socket, data, end_request) do - send!(socket.socket, data) - write_state = if end_request, do: :sent, else: :chunk_streaming - %{socket | write_state: write_state} - end - - def sendfile(%@for{write_state: :writing} = socket, path, offset, length) do - send!(socket.socket, socket.send_buffer) - - case ThousandIsland.Socket.sendfile(socket.socket, path, offset, length) do - {:ok, _bytes_written} -> %{socket | write_state: :sent} - {:error, reason} -> socket_error!(reason) - end - end - - @spec send!(ThousandIsland.Socket.t(), iolist()) :: :ok | no_return() - defp send!(socket, payload) do - case ThousandIsland.Socket.send(socket, payload) do - :ok -> - :ok - - {:error, reason} -> - # Prevent error handlers from possibly trying to send again - send(self(), {:plug_conn, :sent}) - socket_error!(reason) - end - end - - def ensure_completed(%@for{read_state: :read} = socket), do: socket - def ensure_completed(%@for{keepalive: false} = socket), do: socket - - def ensure_completed(%@for{} = socket) do - case read_data(socket, []) do - {:ok, _data, socket} -> socket - {:more, _data, _socket} -> request_error!("Unable to read remaining data in request body") - end - rescue - e in [Bandit.HTTPError] -> - # If we got a timeout during ensure_completed (draining the body), - # check if the client actually disconnected. - if e.plug_status == :request_timeout do - handle_timeout_with_disconnect_check!(socket.socket) - else - reraise e, __STACKTRACE__ - end - end - - def supported_upgrade?(%@for{} = _socket, protocol), do: protocol == :websocket - - def send_on_error(%@for{}, %Bandit.TransportError{}), do: :ok - - def send_on_error(%@for{} = socket, error) do - receive do - {:plug_conn, :sent} -> %{socket | write_state: :sent} - after - 0 -> - status = error |> Plug.Exception.status() |> Plug.Conn.Status.code() - - try do - send_headers(socket, status, [{"connection", "close"}], :no_body) - rescue - _e in [Bandit.TransportError, Bandit.HTTPError] -> :ok - end - end - end - - @spec request_error!(term()) :: no_return() - @spec request_error!(term(), Plug.Conn.status()) :: no_return() - defp request_error!(reason, plug_status \\ :bad_request) do - raise Bandit.HTTPError, message: to_string(reason), plug_status: plug_status - end - - @spec socket_error!(term()) :: no_return() - defp socket_error!(reason) do - raise Bandit.TransportError, message: "Unrecoverable error: #{reason}", error: reason - end - end -end diff --git a/deps/bandit/lib/bandit/http2/README.md b/deps/bandit/lib/bandit/http2/README.md deleted file mode 100644 index d9aac52..0000000 --- a/deps/bandit/lib/bandit/http2/README.md +++ /dev/null @@ -1,108 +0,0 @@ -# HTTP/2 Handler - -Included in this folder is a complete `ThousandIsland.Handler` based implementation of HTTP/2 as -defined in [RFC 9110](https://datatracker.ietf.org/doc/rfc9110) & [RFC -9113](https://datatracker.ietf.org/doc/rfc9113) - -## Process model - -Within a Bandit server, an HTTP/2 connection is modeled as a set of processes: - -* 1 process per connection, a `Bandit.HTTP2.Handler` module implementing the - `ThousandIsland.Handler` behaviour, and; -* 1 process per stream (i.e.: per HTTP request) within the connection, implemented as - a `Bandit.HTTP2.StreamProcess` process - -Each of these processes model the majority of their state via a -`Bandit.HTTP2.Connection` & `Bandit.HTTP2.Stream` struct, respectively. - -The lifetimes of these processes correspond to their role; a connection process lives for as long -as a client is connected, and a stream process lives only as long as is required to process -a single stream request within a connection. - -Connection processes are the 'root' of each connection's process group, and are supervised by -Thousand Island in the same manner that `ThousandIsland.Handler` processes are usually supervised -(see the [project README](https://github.com/mtrudel/thousand_island) for details). - -Stream processes are not supervised by design. The connection process starts new -stream processes as required, via a standard `start_link` -call, and manages the termination of the resultant linked stream processes by -handling `{:EXIT,...}` messages as described in the Elixir documentation. Each -stream process stays alive long enough to fully model an HTTP/2 stream, -beginning its life in the `:init` state and ending it in the `:closed` state (or -else by a stream or connection error being raised). This approach is aligned -with the realities of the HTTP/2 model, insofar as if a connection process -terminates there is no reason to keep its constituent stream processes around, -and if a stream process dies the connection should be able to handle this -without itself terminating. It also means that our process model is very -lightweight - there is no extra supervision overhead present because no such -supervision is required for the system to function in the desired way. - -## Reading client data - -The overall structure of the implementation is managed by the `Bandit.HTTP2.Handler` module, and -looks like the following: - -1. Bytes are asynchronously received from ThousandIsland via the - `Bandit.HTTP2.Handler.handle_data/3` function -2. Frames are parsed from these bytes by calling the `Bandit.HTTP2.Frame.deserialize/2` - function. If successful, the parsed frame(s) are returned. We retain any unparsed bytes in - a buffer in order to attempt parsing them upon receipt of subsequent data from the client -3. Parsed frames are passed into the `Bandit.HTTP2.Connection` module along with a struct of - same module. Frames are processed via the `Bandit.HTTP2.Connection.handle_frame/3` function. - Connection-level frames are handled within the `Bandit.HTTP2.Connection` - struct, and stream-level frames are passed along to the corresponding stream - process, which is wholly responsible for managing all aspects of a stream's - state (which is tracked via the `Bandit.HTTP2.Stream` struct). The one - exception to this is the handling of frames sent to streams which have - already been closed (and whose corresponding processes have thus terminated). - Any such frames are discarded without effect. -4. This process is repeated every time we receive data from the client until the - `Bandit.HTTP2.Connection` module indicates that the connection should be closed, either - normally or due to error. Note that frame deserialization may end up returning a connection - error if the parsed frames fail specific criteria (generally, the frame parsing modules are - responsible for identifying errors as described in [section - 6](https://datatracker.ietf.org/doc/html/rfc9113#section-6) of RFC 9113). In these cases, the - failure is passed through to the connection module for processing in order to coordinate an - orderly shutdown or client notification as appropriate - -## Processing requests - -The state of a particular stream are contained within a `Bandit.HTTP2.Stream` -struct, maintained within a `Bandit.HTTP2.StreamProcess` process. As part of the -stream's lifecycle, the server's configured Plug is called, with an instance of -the `Bandit.Adapter` struct being used to interface with the Plug. There -is a separation of concerns between the aspect of HTTP semantics managed by -`Bandit.Adapter` (roughly, those concerns laid out in -[RFC9110](https://datatracker.ietf.org/doc/html/rfc9110)) and the more -transport-specific HTTP/2 concerns managed by `Bandit.HTTP2.Stream` (roughly the -concerns specified in [RFC9113](https://datatracker.ietf.org/doc/html/rfc9113)). - -# Testing - -All of this is exhaustively tested. Tests are broken up primarily into `protocol_test.exs`, which -is concerned with aspects of the implementation relating to protocol conformance and -client-facing concerns, while `plug_test.exs` is concerned with aspects of the implementation -having to do with the Plug API and application-facing concerns. There are also more -unit-style tests covering frame serialization and deserialization. - -In addition, the `h2spec` conformance suite is run via a `System` wrapper & executes the entirety -of the suite (in strict mode) against a running Bandit server. - -## Limitations and Assumptions - -Some limitations and assumptions of this implementation: - -* This handler assumes that the HTTP/2 connection preface has already been consumed from the - client. The `Bandit.InitialHandler` module uses this preface to discriminate between various - HTTP versions when determining which handler to use -* Priority frames are parsed and validated, but do not induce any action on the part of the - server. There is no priority assigned to respective streams in terms of processing; all streams - are run in parallel as soon as they arrive -* While flow control is completely implemented here, the specific values used for upload flow - control (that is, the end that we control) are fixed. Specifically, we attempt to maintain - fairly large windows in order to not restrict client uploads (we 'slow-start' window changes - upon receipt of first byte, mostly to retain parity between connection and stream window - management since connection windows cannot be changed via settings). The majority of flow - control logic has been encapsulated in the `Bandit.HTTP2.FlowControl` module should future - refinement be required diff --git a/deps/bandit/lib/bandit/http2/connection.ex b/deps/bandit/lib/bandit/http2/connection.ex deleted file mode 100644 index 03804e0..0000000 --- a/deps/bandit/lib/bandit/http2/connection.ex +++ /dev/null @@ -1,473 +0,0 @@ -defmodule Bandit.HTTP2.Connection do - @moduledoc false - # Represents the state of an HTTP/2 connection, in a process-free manner. An instance of this - # struct is maintained as the state of a `Bandit.HTTP2.Handler` process, and it moves an HTTP/2 - # connection through its lifecycle by calling functions defined on this module - - require Logger - - defstruct local_settings: %Bandit.HTTP2.Settings{}, - remote_settings: %Bandit.HTTP2.Settings{}, - fragment_frame: nil, - send_hpack_state: HPAX.new(4096), - recv_hpack_state: HPAX.new(4096), - send_window_size: 65_535, - recv_window_size: 65_535, - streams: %Bandit.HTTP2.StreamCollection{}, - pending_sends: [], - conn_data: nil, - telemetry_span: nil, - plug: nil, - opts: %{}, - reset_stream_timestamps: [] - - @typedoc "Encapsulates the state of an HTTP/2 connection" - @type t :: %__MODULE__{ - local_settings: Bandit.HTTP2.Settings.t(), - remote_settings: Bandit.HTTP2.Settings.t(), - fragment_frame: Bandit.HTTP2.Frame.Headers.t() | nil, - send_hpack_state: term(), - recv_hpack_state: term(), - send_window_size: non_neg_integer(), - recv_window_size: non_neg_integer(), - streams: Bandit.HTTP2.StreamCollection.t(), - pending_sends: [{Bandit.HTTP2.Stream.stream_id(), iodata(), boolean(), fun()}], - conn_data: Bandit.Pipeline.conn_data(), - telemetry_span: ThousandIsland.Telemetry.t(), - plug: Bandit.Pipeline.plug_def(), - opts: %{ - required(:http) => Bandit.http_options(), - required(:http_2) => Bandit.http_2_options() - }, - reset_stream_timestamps: [integer()] - } - - @spec init(ThousandIsland.Socket.t(), Bandit.Pipeline.plug_def(), map()) :: t() - def init(socket, plug, opts) do - connection = %__MODULE__{ - local_settings: - struct!(Bandit.HTTP2.Settings, Keyword.get(opts.http_2, :default_local_settings, [])), - conn_data: Bandit.SocketHelpers.conn_data(socket), - telemetry_span: ThousandIsland.Socket.telemetry_span(socket), - plug: plug, - opts: opts - } - - # Send SETTINGS frame per RFC9113§3.4 - %Bandit.HTTP2.Frame.Settings{ack: false, settings: Map.from_struct(connection.local_settings)} - |> send_frame(socket, connection) - - connection - end - - # - # Receiving while expecting CONTINUATION frames is a special case (RFC9113§6.10); handle it first - # - - @spec handle_frame(Bandit.HTTP2.Frame.frame(), ThousandIsland.Socket.t(), t()) :: t() - def handle_frame( - %Bandit.HTTP2.Frame.Continuation{end_headers: true, stream_id: stream_id} = frame, - socket, - %__MODULE__{fragment_frame: %Bandit.HTTP2.Frame.Headers{stream_id: stream_id}} = - connection - ) do - header_block = connection.fragment_frame.fragment <> frame.fragment - header_frame = %{connection.fragment_frame | end_headers: true, fragment: header_block} - handle_frame(header_frame, socket, %{connection | fragment_frame: nil}) - end - - def handle_frame( - %Bandit.HTTP2.Frame.Continuation{end_headers: false, stream_id: stream_id} = frame, - _socket, - %__MODULE__{fragment_frame: %Bandit.HTTP2.Frame.Headers{stream_id: stream_id}} = - connection - ) do - fragment = connection.fragment_frame.fragment <> frame.fragment - check_oversize_fragment!(fragment, connection) - fragment_frame = %{connection.fragment_frame | fragment: fragment} - %{connection | fragment_frame: fragment_frame} - end - - def handle_frame(_frame, _socket, %__MODULE__{fragment_frame: %Bandit.HTTP2.Frame.Headers{}}) do - connection_error!("Expected CONTINUATION frame (RFC9113§6.10)") - end - - # - # Connection-level receiving - # - - def handle_frame(%Bandit.HTTP2.Frame.Settings{ack: true}, _socket, connection), do: connection - - def handle_frame(%Bandit.HTTP2.Frame.Settings{ack: false} = frame, socket, connection) do - %Bandit.HTTP2.Frame.Settings{ack: true} |> send_frame(socket, connection) - - # Merge whatever new settings were sent with our existing remote settings - remote_settings = struct(connection.remote_settings, frame.settings) - - send_hpack_state = HPAX.resize(connection.send_hpack_state, remote_settings.header_table_size) - delta = remote_settings.initial_window_size - connection.remote_settings.initial_window_size - - Bandit.HTTP2.StreamCollection.get_pids(connection.streams) - |> Enum.each(&Bandit.HTTP2.Stream.deliver_send_window_update(&1, delta)) - - do_pending_sends(socket, %{ - connection - | remote_settings: remote_settings, - send_hpack_state: send_hpack_state - }) - end - - def handle_frame(%Bandit.HTTP2.Frame.Ping{ack: true}, _socket, connection), do: connection - - def handle_frame(%Bandit.HTTP2.Frame.Ping{ack: false} = frame, socket, connection) do - %Bandit.HTTP2.Frame.Ping{ack: true, payload: frame.payload} |> send_frame(socket, connection) - connection - end - - def handle_frame(%Bandit.HTTP2.Frame.Goaway{}, _socket, connection), do: connection - - def handle_frame(%Bandit.HTTP2.Frame.WindowUpdate{stream_id: 0} = frame, socket, connection) do - case Bandit.HTTP2.FlowControl.update_send_window( - connection.send_window_size, - frame.size_increment - ) do - {:ok, new_window} -> do_pending_sends(socket, %{connection | send_window_size: new_window}) - {:error, error} -> connection_error!(error, Bandit.HTTP2.Errors.flow_control_error()) - end - end - - # - # Stream-level receiving - # - - def handle_frame(%Bandit.HTTP2.Frame.WindowUpdate{} = frame, _socket, connection) do - streams = - with_stream(connection, frame.stream_id, fn stream -> - Bandit.HTTP2.Stream.deliver_send_window_update(stream, frame.size_increment) - end) - - %{connection | streams: streams} - end - - def handle_frame(%Bandit.HTTP2.Frame.Headers{end_headers: true} = frame, _socket, connection) do - check_oversize_fragment!(frame.fragment, connection) - - case HPAX.decode(frame.fragment, connection.recv_hpack_state) do - {:ok, headers, recv_hpack_state} -> - streams = - with_stream(connection, frame.stream_id, fn stream -> - Bandit.HTTP2.Stream.deliver_headers(stream, headers, frame.end_stream) - end) - - %{connection | recv_hpack_state: recv_hpack_state, streams: streams} - - _ -> - connection_error!("Header decode error", Bandit.HTTP2.Errors.compression_error()) - end - end - - def handle_frame(%Bandit.HTTP2.Frame.Headers{end_headers: false} = frame, _socket, connection) do - check_oversize_fragment!(frame.fragment, connection) - %{connection | fragment_frame: frame} - end - - def handle_frame(%Bandit.HTTP2.Frame.Continuation{}, _socket, _connection) do - connection_error!("Received unexpected CONTINUATION frame (RFC9113§6.10)") - end - - def handle_frame(%Bandit.HTTP2.Frame.Data{} = frame, socket, connection) do - streams = - with_stream(connection, frame.stream_id, fn stream -> - Bandit.HTTP2.Stream.deliver_data(stream, frame.data, frame.end_stream) - end) - - {recv_window_size, window_increment} = - Bandit.HTTP2.FlowControl.compute_recv_window( - connection.recv_window_size, - byte_size(frame.data) - ) - - if window_increment > 0 do - %Bandit.HTTP2.Frame.WindowUpdate{stream_id: 0, size_increment: window_increment} - |> send_frame(socket, connection) - end - - %{connection | recv_window_size: recv_window_size, streams: streams} - end - - def handle_frame(%Bandit.HTTP2.Frame.Priority{}, _socket, connection), do: connection - - def handle_frame(%Bandit.HTTP2.Frame.RstStream{} = frame, _socket, connection) do - streams = - with_stream(connection, frame.stream_id, fn stream -> - Bandit.HTTP2.Stream.deliver_rst_stream(stream, frame.error_code) - end) - - %{connection | streams: streams} - |> check_reset_stream_rate_limit!() - end - - # Catch-all handler for unknown frame types - - def handle_frame(%Bandit.HTTP2.Frame.Unknown{} = frame, _socket, connection) do - Logger.warning("Unknown frame (#{inspect(Map.from_struct(frame))})", - domain: [:bandit], - plug: connection.plug - ) - - connection - end - - defp with_stream(connection, stream_id, fun) do - case Bandit.HTTP2.StreamCollection.get_pid(connection.streams, stream_id) do - pid when is_pid(pid) or pid == :closed -> - fun.(pid) - connection.streams - - :new -> - new_stream!(connection, stream_id) - - sendfile_chunk_size = - Keyword.get(connection.opts.http_2, :sendfile_chunk_size, 1_048_576) - - stream = - Bandit.HTTP2.Stream.init( - self(), - stream_id, - connection.remote_settings.initial_window_size, - sendfile_chunk_size - ) - - case Bandit.HTTP2.StreamProcess.start_link( - stream, - connection.plug, - connection.telemetry_span, - connection.conn_data, - connection.opts - ) do - {:ok, pid} -> - streams = Bandit.HTTP2.StreamCollection.insert(connection.streams, stream_id, pid) - with_stream(%{connection | streams: streams}, stream_id, fun) - - _ -> - raise "Unable to start stream process" - end - - :invalid -> - connection_error!("Received invalid stream identifier") - end - end - - defp new_stream!(connection, stream_id) do - max_requests = Keyword.get(connection.opts.http_2, :max_requests, 0) - - if max_requests != 0 and - max_requests <= Bandit.HTTP2.StreamCollection.stream_count(connection.streams) do - connection_error!("Connection count exceeded", Bandit.HTTP2.Errors.refused_stream()) - end - - if connection.local_settings.max_concurrent_streams <= - Bandit.HTTP2.StreamCollection.open_stream_count(connection.streams) do - stream_error!( - "Concurrent stream count exceeded", - stream_id, - Bandit.HTTP2.Errors.refused_stream() - ) - end - end - - defp check_oversize_fragment!(fragment, connection) do - if byte_size(fragment) > Keyword.get(connection.opts.http_2, :max_header_block_size, 50_000), - do: connection_error!("Received overlong headers") - end - - @spec check_reset_stream_rate_limit!(t()) :: t() - defp check_reset_stream_rate_limit!(connection) do - case Keyword.get(connection.opts.http_2, :max_reset_stream_rate, {500, 10_000}) do - nil -> - connection - - {intensity, period} -> - now = :erlang.monotonic_time(:millisecond) - threshold = now - period - resets = connection.reset_stream_timestamps - recent_timestamps = can_reset(intensity - 1, threshold, resets, [], intensity, period) - %{connection | reset_stream_timestamps: [now | recent_timestamps]} - end - end - - defp can_reset(_, _, [], acc, _, _), - do: :lists.reverse(acc) - - defp can_reset(_, threshold, [restart | _], acc, _, _) when restart < threshold, - do: :lists.reverse(acc) - - defp can_reset(0, _, [_ | _], _acc, intensity, period), - do: - connection_error!( - "Stream resets rate exceeded #{intensity} resets in #{period}ms", - Bandit.HTTP2.Errors.enhance_your_calm() - ) - - defp can_reset(n, threshold, [restart | restarts], acc, intensity, period), - do: can_reset(n - 1, threshold, restarts, [restart | acc], intensity, period) - - # Shared logic to send any pending frames upon adjustment of our send window - defp do_pending_sends(socket, connection) do - connection.pending_sends - |> Enum.reverse() - |> Enum.reduce(connection, fn pending_send, connection -> - connection = connection |> Map.update!(:pending_sends, &List.delete(&1, pending_send)) - {stream_id, rest, end_stream, on_unblock} = pending_send - send_data(stream_id, rest, end_stream, on_unblock, socket, connection) - end) - end - - # - # Sending logic - # - # All callers of functions below will be from stream processes - # - - # - # Stream-level sending - # - - @spec send_headers( - Bandit.HTTP2.Stream.stream_id(), - Plug.Conn.headers(), - boolean(), - ThousandIsland.Socket.t(), - t() - ) :: t() - def send_headers(stream_id, headers, end_stream, socket, connection) do - with enc_headers <- Enum.map(headers, fn {key, value} -> {:store, key, value} end), - {block, send_hpack_state} <- HPAX.encode(enc_headers, connection.send_hpack_state) do - %Bandit.HTTP2.Frame.Headers{ - stream_id: stream_id, - end_stream: end_stream, - fragment: block - } - |> send_frame(socket, connection) - - %{connection | send_hpack_state: send_hpack_state} - end - end - - @spec send_data( - Bandit.HTTP2.Stream.stream_id(), - iodata(), - boolean(), - fun(), - ThousandIsland.Socket.t(), - t() - ) :: t() - def send_data(stream_id, data, end_stream, on_unblock, socket, connection) do - with connection_window_size <- connection.send_window_size, - max_bytes_to_send <- max(connection_window_size, 0), - {data_to_send, bytes_to_send, rest} <- split_data(data, max_bytes_to_send), - connection <- %{connection | send_window_size: connection_window_size - bytes_to_send}, - end_stream_to_send <- end_stream && byte_size(rest) == 0 do - if end_stream_to_send || bytes_to_send > 0 do - %Bandit.HTTP2.Frame.Data{ - stream_id: stream_id, - end_stream: end_stream_to_send, - data: data_to_send - } - |> send_frame(socket, connection) - end - - if byte_size(rest) == 0 do - on_unblock.() - connection - else - pending_sends = [{stream_id, rest, end_stream, on_unblock} | connection.pending_sends] - %{connection | pending_sends: pending_sends} - end - end - end - - defp split_data(data, desired_length) do - data_length = IO.iodata_length(data) - - if data_length <= desired_length do - {data, data_length, <<>>} - else - <> = IO.iodata_to_binary(data) - {to_send, desired_length, rest} - end - end - - @spec send_recv_window_update( - Bandit.HTTP2.Stream.stream_id(), - non_neg_integer(), - ThousandIsland.Socket.t(), - t() - ) :: term() - def send_recv_window_update(stream_id, size_increment, socket, connection) do - %Bandit.HTTP2.Frame.WindowUpdate{stream_id: stream_id, size_increment: size_increment} - |> send_frame(socket, connection) - end - - @spec send_rst_stream( - Bandit.HTTP2.Stream.stream_id(), - Bandit.HTTP2.Errors.error_code(), - ThousandIsland.Socket.t(), - t() - ) :: term() - def send_rst_stream(stream_id, error_code, socket, connection) do - %Bandit.HTTP2.Frame.RstStream{stream_id: stream_id, error_code: error_code} - |> send_frame(socket, connection) - end - - @spec stream_terminated(pid(), t()) :: t() - def stream_terminated(pid, connection) do - %{connection | streams: Bandit.HTTP2.StreamCollection.delete(connection.streams, pid)} - end - - # - # Helper functions - # - - @spec close_connection(Bandit.HTTP2.Errors.error_code(), term(), ThousandIsland.Socket.t(), t()) :: - {:close, t()} | {:error, term(), t()} - def close_connection(error_code, reason, socket, connection) do - last_stream_id = Bandit.HTTP2.StreamCollection.last_stream_id(connection.streams) - - %Bandit.HTTP2.Frame.Goaway{last_stream_id: last_stream_id, error_code: error_code} - |> send_frame(socket, connection) - - if error_code == Bandit.HTTP2.Errors.no_error(), - do: {:close, connection}, - else: {:error, reason, connection} - end - - @spec connection_error!(term()) :: no_return() - @spec connection_error!(term(), Bandit.HTTP2.Errors.error_code()) :: no_return() - defp connection_error!(message, error_code \\ Bandit.HTTP2.Errors.protocol_error()) do - raise Bandit.HTTP2.Errors.ConnectionError, message: message, error_code: error_code - end - - @spec stream_error!( - String.t(), - Bandit.HTTP2.Stream.stream_id(), - Bandit.HTTP2.Errors.error_code() - ) :: - no_return() - defp stream_error!(message, stream_id, error_code) do - raise Bandit.HTTP2.Errors.StreamError, - message: message, - error_code: error_code, - stream_id: stream_id - end - - defp send_frame(frame, socket, connection) do - _ = - ThousandIsland.Socket.send( - socket, - Bandit.HTTP2.Frame.serialize(frame, connection.remote_settings.max_frame_size) - ) - - :ok - end -end diff --git a/deps/bandit/lib/bandit/http2/errors.ex b/deps/bandit/lib/bandit/http2/errors.ex deleted file mode 100644 index 8d0bd90..0000000 --- a/deps/bandit/lib/bandit/http2/errors.ex +++ /dev/null @@ -1,59 +0,0 @@ -defmodule Bandit.HTTP2.Errors do - @moduledoc false - # Errors as defined in RFC9113§7 - - @typedoc "An error code as defined for GOAWAY and RST_STREAM errors" - @type error_code() :: - (no_error :: 0x0) - | (protocol_error :: 0x1) - | (internal_error :: 0x2) - | (flow_control_error :: 0x3) - | (settings_timeout :: 0x4) - | (stream_closed :: 0x5) - | (frame_size_error :: 0x6) - | (refused_stream :: 0x7) - | (cancel :: 0x8) - | (compression_error :: 0x9) - | (connect_error :: 0xA) - | (enhance_your_calm :: 0xB) - | (inadequate_security :: 0xC) - | (http_1_1_requires :: 0xD) - - error_codes = %{ - no_error: 0x0, - protocol_error: 0x1, - internal_error: 0x2, - flow_control_error: 0x3, - settings_timeout: 0x4, - stream_closed: 0x5, - frame_size_error: 0x6, - refused_stream: 0x7, - cancel: 0x8, - compression_error: 0x9, - connect_error: 0xA, - enhance_your_calm: 0xB, - inadequate_security: 0xC, - http_1_1_requires: 0xD - } - - @spec to_reason(integer()) :: atom() - - for {name, value} <- error_codes do - @spec unquote(name)() :: unquote(Macro.var(name, Elixir)) :: unquote(value) - def unquote(name)(), do: unquote(value) - - def to_reason(unquote(value)), do: unquote(name) - end - - def to_reason(_), do: :unknown - - # Represents a stream error as defined in RFC9113§5.4.2 - defmodule StreamError do - defexception [:message, :error_code, :stream_id] - end - - # Represents a stream error as defined in RFC9113§5.4.3 - defmodule ConnectionError do - defexception [:message, :error_code] - end -end diff --git a/deps/bandit/lib/bandit/http2/flow_control.ex b/deps/bandit/lib/bandit/http2/flow_control.ex deleted file mode 100644 index db67a38..0000000 --- a/deps/bandit/lib/bandit/http2/flow_control.ex +++ /dev/null @@ -1,43 +0,0 @@ -defmodule Bandit.HTTP2.FlowControl do - @moduledoc false - # Helpers for working with flow control window calculations - - import Bitwise - - @max_window_increment (1 <<< 31) - 1 - @max_window_size (1 <<< 31) - 1 - @min_window_size 1 <<< 30 - - @spec compute_recv_window(non_neg_integer(), non_neg_integer()) :: - {non_neg_integer(), non_neg_integer()} - def compute_recv_window(recv_window_size, data_size) do - # This is what our window size will be after receiving data_size bytes - recv_window_size = recv_window_size - data_size - - if recv_window_size > @min_window_size do - # We have room to go before we need to update our window - {recv_window_size, 0} - else - # We want our new window to be as large as possible, but are limited by both the maximum size - # of the window (2^31-1) and the maximum size of the increment we can send to the client, both - # per RFC9113§6.9. Be careful about handling cases where we have a negative window due to - # misbehaving clients or network races - new_recv_window_size = min(recv_window_size + @max_window_increment, @max_window_size) - - # Finally, determine what increment to send to the client - increment = new_recv_window_size - recv_window_size - - {new_recv_window_size, increment} - end - end - - @spec update_send_window(non_neg_integer(), non_neg_integer()) :: - {:ok, non_neg_integer()} | {:error, String.t()} - def update_send_window(current_send_window, increment) do - if current_send_window + increment > @max_window_size do - {:error, "Invalid WINDOW_UPDATE increment RFC9113§6.9.1"} - else - {:ok, current_send_window + increment} - end - end -end diff --git a/deps/bandit/lib/bandit/http2/frame.ex b/deps/bandit/lib/bandit/http2/frame.ex deleted file mode 100644 index 076fb85..0000000 --- a/deps/bandit/lib/bandit/http2/frame.ex +++ /dev/null @@ -1,106 +0,0 @@ -defmodule Bandit.HTTP2.Frame do - @moduledoc false - - @typedoc "Indicates a frame type" - @type frame_type :: non_neg_integer() - - @typedoc "The flags passed along with a frame" - @type flags :: byte() - - @typedoc "A valid HTTP/2 frame" - @type frame :: - Bandit.HTTP2.Frame.Data.t() - | Bandit.HTTP2.Frame.Headers.t() - | Bandit.HTTP2.Frame.Priority.t() - | Bandit.HTTP2.Frame.RstStream.t() - | Bandit.HTTP2.Frame.Settings.t() - | Bandit.HTTP2.Frame.Ping.t() - | Bandit.HTTP2.Frame.Goaway.t() - | Bandit.HTTP2.Frame.WindowUpdate.t() - | Bandit.HTTP2.Frame.Continuation.t() - | Bandit.HTTP2.Frame.Unknown.t() - - @spec deserialize(binary(), non_neg_integer()) :: - {{:ok, frame()}, iodata()} - | {{:more, iodata()}, <<>>} - | {{:error, Bandit.HTTP2.Errors.error_code(), binary()}, iodata()} - | nil - def deserialize( - <>, - max_frame_size - ) - when length <= max_frame_size do - type - |> case do - 0x0 -> Bandit.HTTP2.Frame.Data.deserialize(flags, stream_id, payload) - 0x1 -> Bandit.HTTP2.Frame.Headers.deserialize(flags, stream_id, payload) - 0x2 -> Bandit.HTTP2.Frame.Priority.deserialize(flags, stream_id, payload) - 0x3 -> Bandit.HTTP2.Frame.RstStream.deserialize(flags, stream_id, payload) - 0x4 -> Bandit.HTTP2.Frame.Settings.deserialize(flags, stream_id, payload) - 0x5 -> Bandit.HTTP2.Frame.PushPromise.deserialize(flags, stream_id, payload) - 0x6 -> Bandit.HTTP2.Frame.Ping.deserialize(flags, stream_id, payload) - 0x7 -> Bandit.HTTP2.Frame.Goaway.deserialize(flags, stream_id, payload) - 0x8 -> Bandit.HTTP2.Frame.WindowUpdate.deserialize(flags, stream_id, payload) - 0x9 -> Bandit.HTTP2.Frame.Continuation.deserialize(flags, stream_id, payload) - unknown -> Bandit.HTTP2.Frame.Unknown.deserialize(unknown, flags, stream_id, payload) - end - |> then(&{&1, rest}) - end - - # This is a little more aggressive than necessary. RFC9113§4.2 says we only need - # to treat frame size violations as connection level errors if the frame in - # question would affect the connection as a whole, so we could be more surgical - # here and send stream level errors in some cases. However, we are well within - # our rights to consider such errors as connection errors - def deserialize( - <>, - max_frame_size - ) - when length > max_frame_size do - {{:error, Bandit.HTTP2.Errors.frame_size_error(), "Payload size too large (RFC9113§4.2)"}, - rest} - end - - # nil is used to indicate for Stream.unfold/2 that the frame deserialization is finished - def deserialize(<<>>, _max_frame_size) do - nil - end - - def deserialize(msg, _max_frame_size) do - {{:more, msg}, <<>>} - end - - defmodule Flags do - @moduledoc false - - import Bitwise - - defguard set?(flags, bit) when band(flags, bsl(1, bit)) != 0 - defguard clear?(flags, bit) when band(flags, bsl(1, bit)) == 0 - - @spec set([0..255]) :: 0..255 - def set([]), do: 0x0 - def set([bit | rest]), do: bor(bsl(1, bit), set(rest)) - end - - defprotocol Serializable do - @moduledoc false - - @spec serialize(any(), non_neg_integer()) :: [ - {Bandit.HTTP2.Frame.frame_type(), Bandit.HTTP2.Frame.flags(), - Bandit.HTTP2.Stream.stream_id(), iodata()} - ] - def serialize(frame, max_frame_size) - end - - @spec serialize(frame(), non_neg_integer()) :: iolist() - def serialize(frame, max_frame_size) do - frame - |> Serializable.serialize(max_frame_size) - |> Enum.map(fn {type, flags, stream_id, payload} -> - [<>, payload] - end) - end -end diff --git a/deps/bandit/lib/bandit/http2/frame/continuation.ex b/deps/bandit/lib/bandit/http2/frame/continuation.ex deleted file mode 100644 index 65fb59a..0000000 --- a/deps/bandit/lib/bandit/http2/frame/continuation.ex +++ /dev/null @@ -1,57 +0,0 @@ -defmodule Bandit.HTTP2.Frame.Continuation do - @moduledoc false - - import Bandit.HTTP2.Frame.Flags - - defstruct stream_id: nil, - end_headers: false, - fragment: nil - - @typedoc "An HTTP/2 CONTINUATION frame" - @type t :: %__MODULE__{ - stream_id: Bandit.HTTP2.Stream.stream_id(), - end_headers: boolean(), - fragment: iodata() - } - - @end_headers_bit 2 - - @spec deserialize(Bandit.HTTP2.Frame.flags(), Bandit.HTTP2.Stream.stream_id(), iodata()) :: - {:ok, t()} | {:error, Bandit.HTTP2.Errors.error_code(), binary()} - def deserialize(_flags, 0, _payload) do - {:error, Bandit.HTTP2.Errors.protocol_error(), - "CONTINUATION frame with zero stream_id (RFC9113§6.10)"} - end - - def deserialize(flags, stream_id, <>) do - {:ok, - %__MODULE__{ - stream_id: stream_id, - end_headers: set?(flags, @end_headers_bit), - fragment: fragment - }} - end - - defimpl Bandit.HTTP2.Frame.Serializable do - @end_headers_bit 2 - - def serialize(%Bandit.HTTP2.Frame.Continuation{} = frame, max_frame_size) do - fragment_length = IO.iodata_length(frame.fragment) - - if fragment_length <= max_frame_size do - [{0x9, set([@end_headers_bit]), frame.stream_id, frame.fragment}] - else - <> = - IO.iodata_to_binary(frame.fragment) - - [ - {0x9, 0x00, frame.stream_id, this_frame} - | Bandit.HTTP2.Frame.Serializable.serialize( - %Bandit.HTTP2.Frame.Continuation{stream_id: frame.stream_id, fragment: rest}, - max_frame_size - ) - ] - end - end - end -end diff --git a/deps/bandit/lib/bandit/http2/frame/data.ex b/deps/bandit/lib/bandit/http2/frame/data.ex deleted file mode 100644 index 01b7b63..0000000 --- a/deps/bandit/lib/bandit/http2/frame/data.ex +++ /dev/null @@ -1,78 +0,0 @@ -defmodule Bandit.HTTP2.Frame.Data do - @moduledoc false - - import Bandit.HTTP2.Frame.Flags - - defstruct stream_id: nil, - end_stream: false, - data: nil - - @typedoc "An HTTP/2 DATA frame" - @type t :: %__MODULE__{ - stream_id: Bandit.HTTP2.Stream.stream_id(), - end_stream: boolean(), - data: iodata() - } - - @end_stream_bit 0 - @padding_bit 3 - - @spec deserialize(Bandit.HTTP2.Frame.flags(), Bandit.HTTP2.Stream.stream_id(), iodata()) :: - {:ok, t()} | {:error, Bandit.HTTP2.Errors.error_code(), binary()} - def deserialize(_flags, 0, _payload) do - {:error, Bandit.HTTP2.Errors.protocol_error(), "DATA frame with zero stream_id (RFC9113§6.1)"} - end - - def deserialize(flags, stream_id, <>) - when set?(flags, @padding_bit) and byte_size(rest) >= padding_length do - {:ok, - %__MODULE__{ - stream_id: stream_id, - end_stream: set?(flags, @end_stream_bit), - data: binary_part(rest, 0, byte_size(rest) - padding_length) - }} - end - - def deserialize(flags, stream_id, <>) when clear?(flags, @padding_bit) do - {:ok, - %__MODULE__{ - stream_id: stream_id, - end_stream: set?(flags, @end_stream_bit), - data: data - }} - end - - def deserialize(flags, _stream_id, <<_padding_length::8, _rest::binary>>) - when set?(flags, @padding_bit) do - {:error, Bandit.HTTP2.Errors.protocol_error(), - "DATA frame with invalid padding length (RFC9113§6.1)"} - end - - defimpl Bandit.HTTP2.Frame.Serializable do - @end_stream_bit 0 - - def serialize(%Bandit.HTTP2.Frame.Data{} = frame, max_frame_size) do - data_length = IO.iodata_length(frame.data) - - if data_length <= max_frame_size do - flags = if frame.end_stream, do: [@end_stream_bit], else: [] - [{0x0, set(flags), frame.stream_id, frame.data}] - else - <> = - IO.iodata_to_binary(frame.data) - - [ - {0x0, 0x00, frame.stream_id, this_frame} - | Bandit.HTTP2.Frame.Serializable.serialize( - %Bandit.HTTP2.Frame.Data{ - stream_id: frame.stream_id, - end_stream: frame.end_stream, - data: rest - }, - max_frame_size - ) - ] - end - end - end -end diff --git a/deps/bandit/lib/bandit/http2/frame/goaway.ex b/deps/bandit/lib/bandit/http2/frame/goaway.ex deleted file mode 100644 index 6825653..0000000 --- a/deps/bandit/lib/bandit/http2/frame/goaway.ex +++ /dev/null @@ -1,42 +0,0 @@ -defmodule Bandit.HTTP2.Frame.Goaway do - @moduledoc false - - defstruct last_stream_id: 0, error_code: 0, debug_data: <<>> - - @typedoc "An HTTP/2 GOAWAY frame" - @type t :: %__MODULE__{ - last_stream_id: Bandit.HTTP2.Stream.stream_id(), - error_code: Bandit.HTTP2.Errors.error_code(), - debug_data: iodata() - } - - @spec deserialize(Bandit.HTTP2.Frame.flags(), Bandit.HTTP2.Stream.stream_id(), iodata()) :: - {:ok, t()} | {:error, Bandit.HTTP2.Errors.error_code(), binary()} - def deserialize( - _flags, - 0, - <<_reserved::1, last_stream_id::31, error_code::32, debug_data::binary>> - ) do - {:ok, - %__MODULE__{last_stream_id: last_stream_id, error_code: error_code, debug_data: debug_data}} - end - - def deserialize(_flags, stream_id, _payload) when stream_id != 0 do - {:error, Bandit.HTTP2.Errors.protocol_error(), - "Invalid stream ID in GOAWAY frame (RFC9113§6.8)"} - end - - def deserialize(_flags, _stream_id, _payload) do - {:error, Bandit.HTTP2.Errors.frame_size_error(), - "GOAWAY frame with invalid payload size (RFC9113§6.8)"} - end - - defimpl Bandit.HTTP2.Frame.Serializable do - def serialize(%Bandit.HTTP2.Frame.Goaway{} = frame, _max_frame_size) do - [ - {0x7, 0x0, 0, - <<0x0::1, frame.last_stream_id::31, frame.error_code::32, frame.debug_data::binary>>} - ] - end - end -end diff --git a/deps/bandit/lib/bandit/http2/frame/headers.ex b/deps/bandit/lib/bandit/http2/frame/headers.ex deleted file mode 100644 index 0ed43b7..0000000 --- a/deps/bandit/lib/bandit/http2/frame/headers.ex +++ /dev/null @@ -1,140 +0,0 @@ -defmodule Bandit.HTTP2.Frame.Headers do - @moduledoc false - - import Bandit.HTTP2.Frame.Flags - - defstruct stream_id: nil, - end_stream: false, - end_headers: false, - exclusive_dependency: false, - stream_dependency: nil, - weight: nil, - fragment: nil - - @typedoc "An HTTP/2 HEADERS frame" - @type t :: %__MODULE__{ - stream_id: Bandit.HTTP2.Stream.stream_id(), - end_stream: boolean(), - end_headers: boolean(), - exclusive_dependency: boolean(), - stream_dependency: Bandit.HTTP2.Stream.stream_id() | nil, - weight: non_neg_integer() | nil, - fragment: iodata() - } - - @end_stream_bit 0 - @end_headers_bit 2 - @padding_bit 3 - @priority_bit 5 - - @spec deserialize(Bandit.HTTP2.Frame.flags(), Bandit.HTTP2.Stream.stream_id(), iodata()) :: - {:ok, t()} | {:error, Bandit.HTTP2.Errors.error_code(), binary()} - def deserialize(_flags, 0, _payload) do - {:error, Bandit.HTTP2.Errors.protocol_error(), - "HEADERS frame with zero stream_id (RFC9113§6.2)"} - end - - # Padding and priority - def deserialize( - flags, - stream_id, - <> - ) - when set?(flags, @padding_bit) and set?(flags, @priority_bit) and - byte_size(rest) >= padding_length do - {:ok, - %__MODULE__{ - stream_id: stream_id, - end_stream: set?(flags, @end_stream_bit), - end_headers: set?(flags, @end_headers_bit), - exclusive_dependency: exclusive_dependency == 0x01, - stream_dependency: stream_dependency, - weight: weight, - fragment: binary_part(rest, 0, byte_size(rest) - padding_length) - }} - end - - # Padding but not priority - def deserialize(flags, stream_id, <>) - when set?(flags, @padding_bit) and clear?(flags, @priority_bit) and - byte_size(rest) >= padding_length do - {:ok, - %__MODULE__{ - stream_id: stream_id, - end_stream: set?(flags, @end_stream_bit), - end_headers: set?(flags, @end_headers_bit), - fragment: binary_part(rest, 0, byte_size(rest) - padding_length) - }} - end - - # Any other case where padding is set - def deserialize(flags, _stream_id, <<_padding_length::8, _rest::binary>>) - when set?(flags, @padding_bit) do - {:error, Bandit.HTTP2.Errors.protocol_error(), - "HEADERS frame with invalid padding length (RFC9113§6.2)"} - end - - def deserialize( - flags, - stream_id, - <> - ) - when set?(flags, @priority_bit) do - {:ok, - %__MODULE__{ - stream_id: stream_id, - end_stream: set?(flags, @end_stream_bit), - end_headers: set?(flags, @end_headers_bit), - exclusive_dependency: exclusive_dependency == 0x01, - stream_dependency: stream_dependency, - weight: weight, - fragment: fragment - }} - end - - def deserialize(flags, stream_id, <>) - when clear?(flags, @priority_bit) and clear?(flags, @padding_bit) do - {:ok, - %__MODULE__{ - stream_id: stream_id, - end_stream: set?(flags, @end_stream_bit), - end_headers: set?(flags, @end_headers_bit), - fragment: fragment - }} - end - - defimpl Bandit.HTTP2.Frame.Serializable do - @end_stream_bit 0 - @end_headers_bit 2 - - def serialize( - %Bandit.HTTP2.Frame.Headers{ - exclusive_dependency: false, - stream_dependency: nil, - weight: nil - } = - frame, - max_frame_size - ) do - flags = if frame.end_stream, do: [@end_stream_bit], else: [] - - fragment_length = IO.iodata_length(frame.fragment) - - if fragment_length <= max_frame_size do - [{0x1, set([@end_headers_bit | flags]), frame.stream_id, frame.fragment}] - else - <> = - IO.iodata_to_binary(frame.fragment) - - [ - {0x1, set(flags), frame.stream_id, this_frame} - | Bandit.HTTP2.Frame.Serializable.serialize( - %Bandit.HTTP2.Frame.Continuation{stream_id: frame.stream_id, fragment: rest}, - max_frame_size - ) - ] - end - end - end -end diff --git a/deps/bandit/lib/bandit/http2/frame/ping.ex b/deps/bandit/lib/bandit/http2/frame/ping.ex deleted file mode 100644 index 83eedc4..0000000 --- a/deps/bandit/lib/bandit/http2/frame/ping.ex +++ /dev/null @@ -1,45 +0,0 @@ -defmodule Bandit.HTTP2.Frame.Ping do - @moduledoc false - - import Bandit.HTTP2.Frame.Flags - - defstruct ack: false, payload: nil - - @typedoc "An HTTP/2 PING frame" - @type t :: %__MODULE__{ - ack: boolean(), - payload: iodata() - } - - @ack_bit 0 - - @spec deserialize(Bandit.HTTP2.Frame.flags(), Bandit.HTTP2.Stream.stream_id(), iodata()) :: - {:ok, t()} | {:error, Bandit.HTTP2.Errors.error_code(), binary()} - def deserialize(flags, 0, <>) when set?(flags, @ack_bit) do - {:ok, %__MODULE__{ack: true, payload: payload}} - end - - def deserialize(flags, 0, <>) when clear?(flags, @ack_bit) do - {:ok, %__MODULE__{ack: false, payload: payload}} - end - - def deserialize(_flags, stream_id, _payload) when stream_id != 0 do - {:error, Bandit.HTTP2.Errors.protocol_error(), - "Invalid stream ID in PING frame (RFC9113§6.7)"} - end - - def deserialize(_flags, _stream_id, _payload) do - {:error, Bandit.HTTP2.Errors.frame_size_error(), - "PING frame with invalid payload size (RFC9113§6.7)"} - end - - defimpl Bandit.HTTP2.Frame.Serializable do - @ack_bit 0 - - def serialize(%Bandit.HTTP2.Frame.Ping{ack: true} = frame, _max_frame_size), - do: [{0x6, set([@ack_bit]), 0, frame.payload}] - - def serialize(%Bandit.HTTP2.Frame.Ping{ack: false} = frame, _max_frame_size), - do: [{0x6, 0x0, 0, frame.payload}] - end -end diff --git a/deps/bandit/lib/bandit/http2/frame/priority.ex b/deps/bandit/lib/bandit/http2/frame/priority.ex deleted file mode 100644 index 7b3f776..0000000 --- a/deps/bandit/lib/bandit/http2/frame/priority.ex +++ /dev/null @@ -1,35 +0,0 @@ -defmodule Bandit.HTTP2.Frame.Priority do - @moduledoc false - - defstruct stream_id: nil, dependent_stream_id: nil, weight: nil - - @typedoc "An HTTP/2 PRIORITY frame" - @type t :: %__MODULE__{ - stream_id: Bandit.HTTP2.Stream.stream_id(), - dependent_stream_id: Bandit.HTTP2.Stream.stream_id(), - weight: non_neg_integer() - } - - @spec deserialize(Bandit.HTTP2.Frame.flags(), Bandit.HTTP2.Stream.stream_id(), iodata()) :: - {:ok, t()} | {:error, Bandit.HTTP2.Errors.error_code(), binary()} - def deserialize(_flags, 0, _payload) do - {:error, Bandit.HTTP2.Errors.protocol_error(), - "PRIORITY frame with zero stream_id (RFC9113§6.3)"} - end - - def deserialize(_flags, stream_id, <<_reserved::1, dependent_stream_id::31, weight::8>>) do - {:ok, - %__MODULE__{stream_id: stream_id, dependent_stream_id: dependent_stream_id, weight: weight}} - end - - def deserialize(_flags, _stream_id, _payload) do - {:error, Bandit.HTTP2.Errors.frame_size_error(), - "Invalid payload size in PRIORITY frame (RFC9113§6.3)"} - end - - defimpl Bandit.HTTP2.Frame.Serializable do - def serialize(%Bandit.HTTP2.Frame.Priority{} = frame, _max_frame_size) do - [{0x2, 0x0, frame.stream_id, <<0::1, frame.dependent_stream_id::31, frame.weight::8>>}] - end - end -end diff --git a/deps/bandit/lib/bandit/http2/frame/push_promise.ex b/deps/bandit/lib/bandit/http2/frame/push_promise.ex deleted file mode 100644 index f1d46c4..0000000 --- a/deps/bandit/lib/bandit/http2/frame/push_promise.ex +++ /dev/null @@ -1,9 +0,0 @@ -defmodule Bandit.HTTP2.Frame.PushPromise do - @moduledoc false - - @spec deserialize(Bandit.HTTP2.Frame.flags(), Bandit.HTTP2.Stream.stream_id(), iodata()) :: - {:error, Bandit.HTTP2.Errors.error_code(), binary()} - def deserialize(_flags, _stream, _payload) do - {:error, Bandit.HTTP2.Errors.protocol_error(), "PUSH_PROMISE frame received (RFC9113§8.4)"} - end -end diff --git a/deps/bandit/lib/bandit/http2/frame/rst_stream.ex b/deps/bandit/lib/bandit/http2/frame/rst_stream.ex deleted file mode 100644 index 8bfa799..0000000 --- a/deps/bandit/lib/bandit/http2/frame/rst_stream.ex +++ /dev/null @@ -1,33 +0,0 @@ -defmodule Bandit.HTTP2.Frame.RstStream do - @moduledoc false - - defstruct stream_id: nil, error_code: nil - - @typedoc "An HTTP/2 RST_STREAM frame" - @type t :: %__MODULE__{ - stream_id: Bandit.HTTP2.Stream.stream_id(), - error_code: Bandit.HTTP2.Errors.error_code() - } - - @spec deserialize(Bandit.HTTP2.Frame.flags(), Bandit.HTTP2.Stream.stream_id(), iodata()) :: - {:ok, t()} | {:error, Bandit.HTTP2.Errors.error_code(), binary()} - def deserialize(_flags, 0, _payload) do - {:error, Bandit.HTTP2.Errors.protocol_error(), - "RST_STREAM frame with zero stream_id (RFC9113§6.4)"} - end - - def deserialize(_flags, stream_id, <>) do - {:ok, %__MODULE__{stream_id: stream_id, error_code: error_code}} - end - - def deserialize(_flags, _stream_id, _payload) do - {:error, Bandit.HTTP2.Errors.frame_size_error(), - "Invalid payload size in RST_STREAM frame (RFC9113§6.4)"} - end - - defimpl Bandit.HTTP2.Frame.Serializable do - def serialize(%Bandit.HTTP2.Frame.RstStream{} = frame, _max_frame_size) do - [{0x3, 0x0, frame.stream_id, <>}] - end - end -end diff --git a/deps/bandit/lib/bandit/http2/frame/settings.ex b/deps/bandit/lib/bandit/http2/frame/settings.ex deleted file mode 100644 index f3a0844..0000000 --- a/deps/bandit/lib/bandit/http2/frame/settings.ex +++ /dev/null @@ -1,117 +0,0 @@ -defmodule Bandit.HTTP2.Frame.Settings do - @moduledoc false - - import Bandit.HTTP2.Frame.Flags - import Bitwise - - @max_window_size (1 <<< 31) - 1 - @min_frame_size 1 <<< 14 - @max_frame_size (1 <<< 24) - 1 - - defstruct ack: false, settings: nil - - @typedoc "An HTTP/2 SETTINGS frame" - @type t :: %__MODULE__{ack: true, settings: nil} | %__MODULE__{ack: false, settings: map()} - - @ack_bit 0 - - @spec deserialize(Bandit.HTTP2.Frame.flags(), Bandit.HTTP2.Stream.stream_id(), iodata()) :: - {:ok, t()} | {:error, Bandit.HTTP2.Errors.error_code(), binary()} - def deserialize(flags, 0, payload) when clear?(flags, @ack_bit) do - payload - |> Stream.unfold(fn - <<>> -> nil - <> -> {{:ok, {setting, value}}, rest} - <> -> {{:error, rest}, <<>>} - end) - |> Enum.reduce_while({:ok, %{}}, fn - {:ok, {0x01, value}}, {:ok, acc} -> - {:cont, {:ok, Map.put(acc, :header_table_size, value)}} - - {:ok, {0x02, val}}, {:ok, acc} when val in [0x00, 0x01] -> - {:cont, {:ok, acc}} - - {:ok, {0x02, _value}}, {:ok, _acc} -> - {:halt, - {:error, Bandit.HTTP2.Errors.protocol_error(), "Invalid enable_push value (RFC9113§6.5)"}} - - {:ok, {0x03, value}}, {:ok, acc} -> - {:cont, {:ok, Map.put(acc, :max_concurrent_streams, value)}} - - {:ok, {0x04, value}}, {:ok, _acc} when value > @max_window_size -> - {:halt, - {:error, Bandit.HTTP2.Errors.flow_control_error(), "Invalid window_size (RFC9113§6.5)"}} - - {:ok, {0x04, value}}, {:ok, acc} -> - {:cont, {:ok, Map.put(acc, :initial_window_size, value)}} - - {:ok, {0x05, value}}, {:ok, _acc} when value < @min_frame_size -> - {:halt, - {:error, Bandit.HTTP2.Errors.frame_size_error(), "Invalid max_frame_size (RFC9113§6.5)"}} - - {:ok, {0x05, value}}, {:ok, _acc} when value > @max_frame_size -> - {:halt, - {:error, Bandit.HTTP2.Errors.frame_size_error(), "Invalid max_frame_size (RFC9113§6.5)"}} - - {:ok, {0x05, value}}, {:ok, acc} -> - {:cont, {:ok, Map.put(acc, :max_frame_size, value)}} - - {:ok, {0x06, value}}, {:ok, acc} -> - {:cont, {:ok, Map.put(acc, :max_header_list_size, value)}} - - {:ok, {_setting, _value}}, {:ok, acc} -> - {:cont, {:ok, acc}} - - {:error, _rest}, _acc -> - {:halt, - {:error, Bandit.HTTP2.Errors.frame_size_error(), "Invalid SETTINGS size (RFC9113§6.5)"}} - end) - |> case do - {:ok, settings} -> {:ok, %__MODULE__{ack: false, settings: settings}} - {:error, error_code, reason} -> {:error, error_code, reason} - end - end - - def deserialize(flags, 0, <<>>) when set?(flags, @ack_bit) do - {:ok, %__MODULE__{ack: true}} - end - - def deserialize(flags, 0, _payload) when set?(flags, @ack_bit) do - {:error, Bandit.HTTP2.Errors.frame_size_error(), - "SETTINGS ack frame with non-empty payload (RFC9113§6.5)"} - end - - def deserialize(_flags, _stream_id, _payload) do - {:error, Bandit.HTTP2.Errors.protocol_error(), "Invalid SETTINGS frame (RFC9113§6.5)"} - end - - defimpl Bandit.HTTP2.Frame.Serializable do - @ack_bit 0 - - def serialize(%Bandit.HTTP2.Frame.Settings{ack: true}, _max_frame_size), - do: [{0x4, set([@ack_bit]), 0, <<>>}] - - def serialize(%Bandit.HTTP2.Frame.Settings{ack: false} = frame, _max_frame_size) do - # Encode default settings values as empty binaries so that we do not send - # them. This means we can't restore settings back to default values if we - # change them, but since we don't ever change our settings this is fine - payload = - frame.settings - |> Enum.uniq_by(fn {setting, _} -> setting end) - |> Enum.map(fn - {:header_table_size, 4_096} -> <<>> - {:header_table_size, value} -> <<0x01::16, value::32>> - {:max_concurrent_streams, :infinity} -> <<>> - {:max_concurrent_streams, value} -> <<0x03::16, value::32>> - {:initial_window_size, 65_535} -> <<>> - {:initial_window_size, value} -> <<0x04::16, value::32>> - {:max_frame_size, 16_384} -> <<>> - {:max_frame_size, value} -> <<0x05::16, value::32>> - {:max_header_list_size, :infinity} -> <<>> - {:max_header_list_size, value} -> <<0x06::16, value::32>> - end) - - [{0x4, 0x0, 0, payload}] - end - end -end diff --git a/deps/bandit/lib/bandit/http2/frame/unknown.ex b/deps/bandit/lib/bandit/http2/frame/unknown.ex deleted file mode 100644 index 652a976..0000000 --- a/deps/bandit/lib/bandit/http2/frame/unknown.ex +++ /dev/null @@ -1,27 +0,0 @@ -defmodule Bandit.HTTP2.Frame.Unknown do - @moduledoc false - - defstruct type: nil, - flags: nil, - stream_id: nil, - payload: nil - - @typedoc "An HTTP/2 frame of unknown type" - @type t :: %__MODULE__{ - type: Bandit.HTTP2.Frame.frame_type(), - flags: Bandit.HTTP2.Frame.flags(), - stream_id: Bandit.HTTP2.Stream.stream_id(), - payload: iodata() - } - - # Note this is arity 4 - @spec deserialize( - Bandit.HTTP2.Frame.frame_type(), - Bandit.HTTP2.Frame.flags(), - Bandit.HTTP2.Stream.stream_id(), - iodata() - ) :: {:ok, t()} - def deserialize(type, flags, stream_id, payload) do - {:ok, %__MODULE__{type: type, flags: flags, stream_id: stream_id, payload: payload}} - end -end diff --git a/deps/bandit/lib/bandit/http2/frame/window_update.ex b/deps/bandit/lib/bandit/http2/frame/window_update.ex deleted file mode 100644 index 85fa879..0000000 --- a/deps/bandit/lib/bandit/http2/frame/window_update.ex +++ /dev/null @@ -1,33 +0,0 @@ -defmodule Bandit.HTTP2.Frame.WindowUpdate do - @moduledoc false - - defstruct stream_id: nil, - size_increment: nil - - @typedoc "An HTTP/2 WINDOW_UPDATE frame" - @type t :: %__MODULE__{ - stream_id: Bandit.HTTP2.Stream.stream_id(), - size_increment: non_neg_integer() - } - - @spec deserialize(Bandit.HTTP2.Frame.flags(), Bandit.HTTP2.Stream.stream_id(), iodata()) :: - {:ok, t()} | {:error, Bandit.HTTP2.Errors.error_code(), binary()} - def deserialize(_flags, _stream_id, <<_reserved::1, 0::31>>) do - {:error, Bandit.HTTP2.Errors.flow_control_error(), - "Invalid WINDOW_UPDATE size increment (RFC9113§6.9)"} - end - - def deserialize(_flags, stream_id, <<_reserved::1, size_increment::31>>) do - {:ok, %__MODULE__{stream_id: stream_id, size_increment: size_increment}} - end - - def deserialize(_flags, _stream_id, _payload) do - {:error, Bandit.HTTP2.Errors.frame_size_error(), "Invalid WINDOW_UPDATE frame (RFC9113§6.9)"} - end - - defimpl Bandit.HTTP2.Frame.Serializable do - def serialize(%Bandit.HTTP2.Frame.WindowUpdate{} = frame, _max_frame_size) do - [{0x8, 0, frame.stream_id, <<0::1, frame.size_increment::31>>}] - end - end -end diff --git a/deps/bandit/lib/bandit/http2/handler.ex b/deps/bandit/lib/bandit/http2/handler.ex deleted file mode 100644 index c737eee..0000000 --- a/deps/bandit/lib/bandit/http2/handler.ex +++ /dev/null @@ -1,186 +0,0 @@ -defmodule Bandit.HTTP2.Handler do - @moduledoc false - # An HTTP/2 handler, this module comprises the primary interface between Thousand Island and an - # HTTP connection. It is responsible for: - # - # * All socket-level sending and receiving from the client - # * Coordinating the parsing of frames & attendant error handling - # * Tracking connection state as represented by a `Bandit.HTTP2.Connection` struct - - use ThousandIsland.Handler - - @impl ThousandIsland.Handler - def handle_connection(socket, state) do - connection = Bandit.HTTP2.Connection.init(socket, state.plug, state.opts) - {:continue, Map.merge(state, %{buffer: <<>>, connection: connection})} - rescue - error -> rescue_connection_error(error, __STACKTRACE__, socket, state) - end - - @impl ThousandIsland.Handler - def handle_data(data, socket, state) do - (state.buffer <> data) - |> Stream.unfold( - &Bandit.HTTP2.Frame.deserialize(&1, state.connection.local_settings.max_frame_size) - ) - |> Enum.reduce_while(state, fn - {:ok, frame}, state -> - connection = Bandit.HTTP2.Connection.handle_frame(frame, socket, state.connection) - {:cont, %{state | connection: connection, buffer: <<>>}} - - {:more, rest}, state -> - {:halt, %{state | buffer: rest}} - - {:error, error_code, message}, _state -> - # We encountered an error while deserializing the frame. Let the connection figure out - # how to respond to it - raise Bandit.HTTP2.Errors.ConnectionError, message: message, error_code: error_code - end) - |> then(&{:continue, &1}) - rescue - error in Bandit.HTTP2.Errors.StreamError -> rescue_stream_error(error, socket, state) - error -> rescue_connection_error(error, __STACKTRACE__, socket, state) - end - - @impl ThousandIsland.Handler - def handle_shutdown(socket, state) do - Bandit.HTTP2.Connection.close_connection( - Bandit.HTTP2.Errors.no_error(), - "Server shutdown", - socket, - state.connection - ) - end - - @impl ThousandIsland.Handler - def handle_timeout(socket, state) do - Bandit.HTTP2.Connection.close_connection( - Bandit.HTTP2.Errors.no_error(), - "Client timeout", - socket, - state.connection - ) - end - - def handle_call({:peer_data, _stream_id}, _from, {socket, state}) do - {:reply, Bandit.SocketHelpers.peer_data(socket), {socket, state}, socket.read_timeout} - end - - def handle_call({:sock_data, _stream_id}, _from, {socket, state}) do - {:reply, Bandit.SocketHelpers.sock_data(socket), {socket, state}, socket.read_timeout} - end - - def handle_call({:ssl_data, _stream_id}, _from, {socket, state}) do - {:reply, Bandit.SocketHelpers.ssl_data(socket), {socket, state}, socket.read_timeout} - end - - def handle_call({{:send_data, data, end_stream}, stream_id}, from, {socket, state}) do - # In 'normal' cases where there is sufficient space in the send windows for this message to be - # sent, Connection will call `unblock` synchronously in the `Connection.send_data` call below. - # In cases where there is not enough space in the connection window, Connection will call - # `unblock` at some point in the future once space opens up in the window. This - # keeps this code simple in that we can blindly send noreply here and let Connection handle - # the separate cases. This ensures that we have backpressure all the way back to the - # stream's handler process in the event of window overruns. - # - # Note that the above only applies to the connection-level send window; stream-level windows - # are managed internally by the stream and are not considered here at all. If the stream has - # managed to send this message, it is because there was enough room in the stream's send - # window to do so. - unblock = fn -> GenServer.reply(from, :ok) end - - connection = - Bandit.HTTP2.Connection.send_data( - stream_id, - data, - end_stream, - unblock, - socket, - state.connection - ) - - {:noreply, {socket, %{state | connection: connection}}, socket.read_timeout} - rescue - error -> rescue_error_handle_info(error, __STACKTRACE__, socket, state) - end - - def handle_info({{:send_headers, headers, end_stream}, stream_id}, {socket, state}) do - connection = - Bandit.HTTP2.Connection.send_headers( - stream_id, - headers, - end_stream, - socket, - state.connection - ) - - {:noreply, {socket, %{state | connection: connection}}, socket.read_timeout} - rescue - error -> rescue_error_handle_info(error, __STACKTRACE__, socket, state) - end - - def handle_info({{:send_recv_window_update, size_increment}, stream_id}, {socket, state}) do - Bandit.HTTP2.Connection.send_recv_window_update( - stream_id, - size_increment, - socket, - state.connection - ) - - {:noreply, {socket, state}, socket.read_timeout} - rescue - error -> rescue_error_handle_info(error, __STACKTRACE__, socket, state) - end - - def handle_info({{:send_rst_stream, error_code}, stream_id}, {socket, state}) do - Bandit.HTTP2.Connection.send_rst_stream(stream_id, error_code, socket, state.connection) - {:noreply, {socket, state}, socket.read_timeout} - rescue - error -> rescue_error_handle_info(error, __STACKTRACE__, socket, state) - end - - def handle_info({{:close_connection, error_code, msg}, _stream_id}, {socket, state}) do - _ = Bandit.HTTP2.Connection.close_connection(error_code, msg, socket, state.connection) - {:stop, :normal, {socket, state}} - end - - def handle_info({:EXIT, pid, _reason}, {socket, state}) do - connection = Bandit.HTTP2.Connection.stream_terminated(pid, state.connection) - {:noreply, {socket, %{state | connection: connection}}, socket.read_timeout} - end - - defp rescue_stream_error(error, socket, state) do - Bandit.HTTP2.Connection.send_rst_stream( - error.stream_id, - error.error_code, - socket, - state.connection - ) - - {:continue, state} - end - - defp rescue_connection_error(error, stacktrace, socket, state) do - do_rescue_error(error, stacktrace, socket, state) - {:close, state} - end - - defp rescue_error_handle_info(error, stacktrace, socket, state) do - do_rescue_error(error, stacktrace, socket, state) - {:stop, :normal} - end - - defp do_rescue_error(error, stacktrace, socket, state) do - _ = - if state[:connection] do - Bandit.HTTP2.Connection.close_connection( - error.error_code, - error.message, - socket, - state[:connection] - ) - end - - Bandit.Logger.maybe_log_protocol_error(error, stacktrace, state.opts, plug: state.plug) - end -end diff --git a/deps/bandit/lib/bandit/http2/settings.ex b/deps/bandit/lib/bandit/http2/settings.ex deleted file mode 100644 index 48b922d..0000000 --- a/deps/bandit/lib/bandit/http2/settings.ex +++ /dev/null @@ -1,20 +0,0 @@ -defmodule Bandit.HTTP2.Settings do - @moduledoc """ - Settings as defined in RFC9113§6.5.2 - """ - - defstruct header_table_size: 4_096, - max_concurrent_streams: :infinity, - initial_window_size: 65_535, - max_frame_size: 16_384, - max_header_list_size: :infinity - - @typedoc "A collection of settings as defined in RFC9113§6.5" - @type t :: %__MODULE__{ - header_table_size: non_neg_integer(), - max_concurrent_streams: non_neg_integer() | :infinity, - initial_window_size: non_neg_integer(), - max_frame_size: non_neg_integer(), - max_header_list_size: non_neg_integer() | :infinity - } -end diff --git a/deps/bandit/lib/bandit/http2/stream.ex b/deps/bandit/lib/bandit/http2/stream.ex deleted file mode 100644 index 60a182c..0000000 --- a/deps/bandit/lib/bandit/http2/stream.ex +++ /dev/null @@ -1,634 +0,0 @@ -defmodule Bandit.HTTP2.Stream do - @moduledoc false - # This module implements an HTTP/2 stream as described in RFC 9113, without concern for the higher-level - # HTTP semantics described in RFC 9110. It is similar in spirit to `Bandit.HTTP1.Socket` for - # HTTP/1, and indeed both implement the `Bandit.HTTPTransport` behaviour. An instance of this - # struct is maintained as the state of a `Bandit.HTTP2.StreamProcess` process, and it moves an - # HTTP/2 stream through its lifecycle by calling functions defined on this module. This state is - # also tracked within the `Bandit.Adapter` instance that backs Bandit's Plug API. - # - # A note about naming: - # - # This module has several intended callers, and due to its nature as a coordinator, needs to be - # careful about how it uses terms like 'read', 'send', 'receive', etc. To that end, there are - # some conventions in place: - # - # * Functions on this module which are intended to be called internally by the containing - # `Bandit.HTTP2.Connection` to pass information received from the client (such as headers or - # request data) to this stream. These functions are named `deliver_*`, and are intended to be - # called by the connection process. As such, they take a `stream_handle()` argument, which - # corresponds either to a pid (in the case of an active stream), or the value `:closed` (in the - # case of a stream which has already completed processing) - # - # * Functions on this module which are intended to be called by the higher-level implementation - # that is processing this stream are implemented via the `Bandit.HTTPTransport` protocol - # - # * In order for this stream to receive information from the containing connection process, we - # use carefully crafted `receive` calls (we do this in a manner that is safe to do within a - # GenServer). This work is handled internally by a number of functions named `do_recv_*`, which - # generally present a blocking interface in order to align with the expectations of the - # `Plug.Conn.Adapter` behaviour. - # - # This module also uses exceptions by convention rather than error tuples since many - # of these functions are called within `Plug.Conn.Adapter` calls, which makes it - # difficult to properly unwind many error conditions back to a place where we can properly shut - # down the stream by sending a RstStream frame to the client and terminating our process. The - # pattern here is to raise exceptions, and have the `Bandit.HTTP2.StreamProcess`'s `terminate/2` - # callback take care of calling back into us via the `reset_stream/2` and `close_connection/2` - # functions here, with the luxury of a nicely unwound stack and a process that is guaranteed to - # be terminated as soon as these functions are called - - require Logger - - defstruct connection_pid: nil, - stream_id: nil, - state: :idle, - recv_window_size: 65_535, - send_window_size: nil, - sendfile_chunk_size: nil, - bytes_remaining: nil, - read_timeout: 15_000 - - @typedoc "An HTTP/2 stream identifier" - @type stream_id :: non_neg_integer() - - @typedoc "A handle to a stream, suitable for passing to the `deliver_*` functions on this module" - @type stream_handle :: pid() | :closed - - @typedoc "An HTTP/2 stream state" - @type state :: :idle | :open | :local_closed | :remote_closed | :closed - - @typedoc "The information necessary to communicate to/from a stream" - @type t :: %__MODULE__{ - connection_pid: pid(), - stream_id: non_neg_integer(), - state: state(), - recv_window_size: non_neg_integer(), - send_window_size: non_neg_integer(), - sendfile_chunk_size: pos_integer(), - bytes_remaining: non_neg_integer() | nil, - read_timeout: timeout() - } - - def init(connection_pid, stream_id, initial_send_window_size, sendfile_chunk_size) do - %__MODULE__{ - connection_pid: connection_pid, - stream_id: stream_id, - send_window_size: initial_send_window_size, - sendfile_chunk_size: sendfile_chunk_size - } - end - - # Collection API - Delivery - # - # These functions are intended to be called by the connection process which contains this - # stream. All of these start with `deliver_` - - @spec deliver_headers(stream_handle(), Plug.Conn.headers(), boolean()) :: term() - def deliver_headers(:closed, _headers, _end_stream), do: :ok - - def deliver_headers(pid, headers, end_stream), - do: send(pid, {:bandit, {:headers, headers, end_stream}}) - - @spec deliver_data(stream_handle(), iodata(), boolean()) :: term() - def deliver_data(:closed, _data, _end_stream), do: :ok - def deliver_data(pid, data, end_stream), do: send(pid, {:bandit, {:data, data, end_stream}}) - - @spec deliver_send_window_update(stream_handle(), non_neg_integer()) :: term() - def deliver_send_window_update(:closed, _delta), do: :ok - - def deliver_send_window_update(pid, delta), - do: send(pid, {:bandit, {:send_window_update, delta}}) - - @spec deliver_rst_stream(stream_handle(), Bandit.HTTP2.Errors.error_code()) :: term() - def deliver_rst_stream(:closed, _error_code), do: :ok - def deliver_rst_stream(pid, error_code), do: send(pid, {:bandit, {:rst_stream, error_code}}) - - defimpl Bandit.HTTPTransport do - def peer_data(%@for{} = stream), do: call(stream, :peer_data, :infinity) - - def sock_data(%@for{} = stream), do: call(stream, :sock_data, :infinity) - - def ssl_data(%@for{} = stream), do: call(stream, :ssl_data, :infinity) - - def version(%@for{}), do: :"HTTP/2" - - def read_headers(%@for{state: :idle} = stream) do - case do_recv(stream, stream.read_timeout) do - {:headers, headers, stream} -> - method = Bandit.Headers.get_header(headers, ":method") - request_target = build_request_target!(headers, stream) - {pseudo_headers, headers} = split_headers!(headers, stream) - pseudo_headers_all_request!(pseudo_headers, stream) - exactly_one_instance_of!(pseudo_headers, ":scheme", stream) - exactly_one_instance_of!(pseudo_headers, ":method", stream) - exactly_one_instance_of!(pseudo_headers, ":path", stream) - headers_all_lowercase!(headers, stream) - no_connection_headers!(headers, stream) - valid_te_header!(headers, stream) - content_length = get_content_length!(headers, stream) - headers = combine_cookie_crumbs(headers) - stream = %{stream | bytes_remaining: content_length} - {:ok, method, request_target, headers, stream} - - :timeout -> - stream_error!("Timed out waiting for HEADER", stream) - - %@for{} = stream -> - read_headers(stream) - end - end - - defp build_request_target!(headers, stream) do - scheme = Bandit.Headers.get_header(headers, ":scheme") - {host, port} = get_host_and_port!(headers) - path = get_path!(headers, stream) - {scheme, host, port, path} - end - - defp get_host_and_port!(headers) do - case Bandit.Headers.get_header(headers, ":authority") do - authority when not is_nil(authority) -> Bandit.Headers.parse_hostlike_header!(authority) - nil -> {nil, nil} - end - end - - # RFC9113§8.3.1 - path should be non-empty and absolute - defp get_path!(headers, stream) do - headers - |> Bandit.Headers.get_header(":path") - |> case do - nil -> stream_error!("Received empty :path", stream) - "*" -> :* - "/" <> _ = path -> split_path!(path, stream) - _ -> stream_error!("Path does not start with /", stream) - end - end - - # RFC9113§8.3.1 - path should match the path-absolute production from RFC3986 - defp split_path!(path, stream) do - if path |> String.split("/") |> Enum.all?(&(&1 not in [".", ".."])), - do: path, - else: stream_error!("Path contains dot segment", stream) - end - - # RFC9113§8.3 - pseudo headers must appear first - defp split_headers!(headers, stream) do - {pseudo_headers, headers} = - Enum.split_while(headers, fn {key, _value} -> String.starts_with?(key, ":") end) - - if Enum.any?(headers, fn {key, _value} -> String.starts_with?(key, ":") end), - do: stream_error!("Received pseudo headers after regular one", stream), - else: {pseudo_headers, headers} - end - - # RFC9113§8.3.1 - only request pseudo headers may appear - defp pseudo_headers_all_request!(headers, stream) do - if Enum.any?(headers, fn {key, _value} -> - key not in ~w[:method :scheme :authority :path] - end), - do: stream_error!("Received invalid pseudo header", stream) - end - - # RFC9113§8.3.1 - method, scheme, path pseudo headers must appear exactly once - defp exactly_one_instance_of!(headers, header, stream) do - if Enum.count(headers, fn {key, _value} -> key == header end) != 1, - do: stream_error!("Expected 1 #{header} headers", stream) - end - - # RFC9113§8.2 - all headers name fields must be lowercsae - defp headers_all_lowercase!(headers, stream) do - if !Enum.all?(headers, fn {key, _value} -> lowercase?(key) end), - do: stream_error!("Received uppercase header", stream) - end - - defp lowercase?(<>) when char >= ?A and char <= ?Z, do: false - defp lowercase?(<<_char, rest::bits>>), do: lowercase?(rest) - defp lowercase?(<<>>), do: true - - # RFC9113§8.2.2 - no hop-by-hop headers - # Note that we do not filter out the TE header here, since it is allowed in - # specific cases by RFC9113§8.2.2. We check those cases in a separate filter - defp no_connection_headers!(headers, stream) do - connection_headers = - ~w[connection keep-alive proxy-authenticate proxy-authorization trailers transfer-encoding upgrade] - - if Enum.any?(headers, fn {key, _value} -> key in connection_headers end), - do: stream_error!("Received connection-specific header", stream) - end - - # RFC9113§8.2.2 - TE header may be present if it contains exactly 'trailers' - defp valid_te_header!(headers, stream) do - if Bandit.Headers.get_header(headers, "te") not in [nil, "trailers"], - do: stream_error!("Received invalid TE header", stream) - end - - defp get_content_length!(headers, stream) do - case Bandit.Headers.get_content_length(headers) do - {:ok, content_length} -> content_length - {:error, reason} -> stream_error!(reason, stream) - end - end - - # RFC9113§8.2.3 - cookie headers may be split during transmission - defp combine_cookie_crumbs(headers) do - {crumbs, other_headers} = - headers |> Enum.split_with(fn {header, _} -> header == "cookie" end) - - case Enum.map_join(crumbs, "; ", fn {"cookie", crumb} -> crumb end) do - "" -> other_headers - combined_cookie -> [{"cookie", combined_cookie} | other_headers] - end - end - - def read_data(%@for{} = stream, opts) do - max_bytes = Keyword.get(opts, :length, 8_000_000) - timeout = Keyword.get(opts, :read_timeout, 15_000) - do_read_data(stream, max_bytes, timeout, []) - end - - defp do_read_data(%@for{state: state} = stream, max_bytes, timeout, acc) - when state in [:open, :local_closed] do - case do_recv(stream, timeout) do - {:headers, trailers, stream} -> - no_pseudo_headers!(trailers, stream) - Logger.warning("Ignoring trailers #{inspect(trailers)}", domain: [:bandit]) - do_read_data(stream, max_bytes, timeout, acc) - - {:data, data, stream} -> - acc = [data | acc] - max_bytes = max_bytes - byte_size(data) - - if max_bytes >= 0 do - do_read_data(stream, max_bytes, timeout, acc) - else - {:more, Enum.reverse(acc), stream} - end - - :timeout -> - {:more, Enum.reverse(acc), stream} - - %@for{} = stream -> - do_read_data(stream, max_bytes, timeout, acc) - end - end - - defp do_read_data(%@for{state: :remote_closed} = stream, _max_bytes, _timeout, acc) do - {:ok, Enum.reverse(acc), stream} - end - - defp no_pseudo_headers!(headers, stream) do - if Enum.any?(headers, fn {key, _value} -> String.starts_with?(key, ":") end), - do: stream_error!("Received trailers with pseudo headers", stream) - end - - defp do_recv(%@for{state: :idle} = stream, timeout) do - receive do - {:bandit, {:headers, headers, end_stream}} -> - {:headers, headers, stream |> do_recv_headers() |> do_recv_end_stream(end_stream)} - - {:bandit, {:data, _data, _end_stream}} -> - connection_error!("Received DATA in idle state") - - {:bandit, {:send_window_update, _delta}} -> - connection_error!("Received WINDOW_UPDATE in idle state") - - {:bandit, {:rst_stream, _error_code}} -> - connection_error!("Received RST_STREAM in idle state") - after - timeout -> :timeout - end - end - - defp do_recv(%@for{state: state} = stream, timeout) - when state in [:open, :local_closed] do - receive do - {:bandit, {:headers, headers, end_stream}} -> - {:headers, headers, stream |> do_recv_headers() |> do_recv_end_stream(end_stream)} - - {:bandit, {:data, data, end_stream}} -> - {:data, data, - stream |> do_recv_data(data, end_stream) |> do_recv_end_stream(end_stream)} - - {:bandit, {:send_window_update, delta}} -> - do_recv_send_window_update(stream, delta) - - {:bandit, {:rst_stream, error_code}} -> - do_recv_rst_stream!(stream, error_code) - after - timeout -> :timeout - end - end - - defp do_recv(%@for{state: :remote_closed} = stream, timeout) do - receive do - {:bandit, {:headers, _headers, _end_stream}} -> - do_stream_closed_error!("Received HEADERS in remote_closed state", stream) - - {:bandit, {:data, _data, _end_stream}} -> - do_stream_closed_error!("Received DATA in remote_closed state", stream) - - {:bandit, {:send_window_update, delta}} -> - do_recv_send_window_update(stream, delta) - - {:bandit, {:rst_stream, error_code}} -> - do_recv_rst_stream!(stream, error_code) - after - timeout -> :timeout - end - end - - defp do_recv(%@for{state: :closed} = stream, timeout) do - receive do - {:bandit, {:headers, _headers, _end_stream}} -> stream - {:bandit, {:data, _data, _end_stream}} -> stream - {:bandit, {:send_window_update, _delta}} -> stream - {:bandit, {:rst_stream, _error_code}} -> stream - after - timeout -> :timeout - end - end - - defp do_recv_headers(%@for{state: :idle} = stream), do: %{stream | state: :open} - defp do_recv_headers(stream), do: stream - - defp do_recv_data(stream, data, end_stream) do - {new_window, increment} = - Bandit.HTTP2.FlowControl.compute_recv_window(stream.recv_window_size, byte_size(data)) - - if increment > 0 && !end_stream, do: do_send(stream, {:send_recv_window_update, increment}) - - bytes_remaining = - case stream.bytes_remaining do - nil -> nil - bytes_remaining -> bytes_remaining - byte_size(data) - end - - %{stream | recv_window_size: new_window, bytes_remaining: bytes_remaining} - end - - defp do_recv_end_stream(stream, false), do: stream - - defp do_recv_end_stream(stream, true) do - next_state = - case stream.state do - :open -> :remote_closed - :local_closed -> :closed - end - - if stream.bytes_remaining not in [nil, 0], - do: stream_error!("Received END_STREAM with byte still pending", stream) - - %{stream | state: next_state} - end - - defp do_recv_send_window_update(stream, delta) do - case Bandit.HTTP2.FlowControl.update_send_window(stream.send_window_size, delta) do - {:ok, new_window} -> - %{stream | send_window_size: new_window} - - {:error, reason} -> - stream_error!(reason, stream, Bandit.HTTP2.Errors.flow_control_error()) - end - end - - @spec do_recv_rst_stream!(term(), term()) :: no_return() - defp do_recv_rst_stream!(_stream, error_code) do - case Bandit.HTTP2.Errors.to_reason(error_code) do - reason when reason in [:no_error, :cancel] -> - raise(Bandit.TransportError, message: "Client reset stream normally", error: :closed) - - reason -> - raise(Bandit.TransportError, - message: "Received RST_STREAM from client: #{reason} (#{error_code})", - error: reason - ) - end - end - - @spec do_stream_closed_error!(String.t(), Bandit.HTTP2.Stream.t()) :: no_return() - defp do_stream_closed_error!(msg, stream), - do: stream_error!(msg, stream, Bandit.HTTP2.Errors.stream_closed()) - - # Stream API - Sending - - def send_headers(%@for{state: state} = stream, status, headers, body_disposition) - when state in [:open, :remote_closed] do - # We need to map body_disposition into the state model of HTTP/2. This turns out to be really - # easy, since HTTP/2 only has one way to send data. The only bit we need from the disposition - # is whether there will be any data forthcoming (ie: whether or not to end the stream). That - # will possibly walk us to a different state per RFC9113§5.1, as determined by the tail call - # to set_state_on_send_end_stream/2 - end_stream = body_disposition == :no_body - headers = [{":status", to_string(status)} | split_cookies(headers)] - do_send(stream, {:send_headers, headers, end_stream}) - set_state_on_send_end_stream(stream, end_stream) - end - - # RFC9113§8.2.3 - cookie headers may be split during transmission - defp split_cookies(headers) do - headers - |> Enum.flat_map(fn - {"cookie", cookie} -> - cookie |> String.split("; ") |> Enum.map(fn crumb -> {"cookie", crumb} end) - - {header, value} -> - [{header, value}] - end) - end - - def send_data(%@for{state: state} = stream, data, end_stream) - when state in [:open, :remote_closed] do - stream = - receive do - {:bandit, {:send_window_update, delta}} -> do_recv_send_window_update(stream, delta) - {:bandit, {:rst_stream, error_code}} -> do_recv_rst_stream!(stream, error_code) - after - 0 -> stream - end - - max_bytes_to_send = max(stream.send_window_size, 0) - {data_to_send, bytes_to_send, rest} = split_data(data, max_bytes_to_send) - - stream = - if end_stream || bytes_to_send > 0 do - end_stream_to_send = end_stream && byte_size(rest) == 0 - call(stream, {:send_data, data_to_send, end_stream_to_send}, :infinity) - %{stream | send_window_size: stream.send_window_size - bytes_to_send} - else - stream - end - - if byte_size(rest) == 0 do - set_state_on_send_end_stream(stream, end_stream) - else - receive do - {:bandit, {:send_window_update, delta}} -> - stream - |> do_recv_send_window_update(delta) - |> send_data(rest, end_stream) - after - stream.read_timeout -> - stream_error!( - "Timeout waiting for space in the send_window", - stream, - Bandit.HTTP2.Errors.flow_control_error() - ) - end - end - end - - def sendfile(%@for{} = stream, path, offset, length) do - case :file.open(path, [:raw, :binary]) do - {:ok, fd} -> - try do - if length == 0 do - send_data(stream, "", true) - else - sendfile_loop(stream, fd, offset, length, 0) - end - after - :file.close(fd) - end - - {:error, reason} -> - raise "Error opening file for sendfile: #{inspect(reason)}" - end - end - - defp sendfile_loop(stream, _fd, _offset, length, sent) when sent >= length do - stream - end - - defp sendfile_loop(stream, fd, offset, length, sent) do - read_size = min(length - sent, sendfile_chunk_size(stream)) - - case :file.pread(fd, offset + sent, read_size) do - {:ok, data} -> - now_sent = byte_size(data) - end_stream = sent + now_sent >= length - stream = send_data(stream, data, end_stream) - - if end_stream do - stream - else - sendfile_loop(stream, fd, offset, length, sent + now_sent) - end - - :eof -> - raise "Error reading file for sendfile: :eof" - - {:error, reason} -> - raise "Error reading file for sendfile: #{inspect(reason)}" - end - end - - defp sendfile_chunk_size(%@for{sendfile_chunk_size: sendfile_chunk_size}) do - max(sendfile_chunk_size, 1) - end - - defp split_data(data, desired_length) do - data_length = IO.iodata_length(data) - - if data_length <= desired_length do - {data, data_length, <<>>} - else - <> = IO.iodata_to_binary(data) - {to_send, desired_length, rest} - end - end - - defp set_state_on_send_end_stream(stream, false), do: stream - - defp set_state_on_send_end_stream(%@for{state: :open} = stream, true), - do: %{stream | state: :local_closed} - - defp set_state_on_send_end_stream(%@for{state: :remote_closed} = stream, true), - do: %{stream | state: :closed} - - # Closing off the stream upon completion or error - - def ensure_completed(%@for{state: :closed} = stream), do: stream - - def ensure_completed(%@for{state: :local_closed} = stream) do - receive do - {:bandit, {:headers, _headers, true}} -> - do_recv_end_stream(stream, true) - - {:bandit, {:data, data, true}} -> - do_recv_data(stream, data, true) |> do_recv_end_stream(true) - after - # RFC9113§8.1 - hint the client to stop sending data - 0 -> do_send(stream, {:send_rst_stream, Bandit.HTTP2.Errors.no_error()}) - end - end - - def ensure_completed(%@for{state: state} = stream) do - stream_error!( - "Terminating stream in #{state} state", - stream, - Bandit.HTTP2.Errors.internal_error() - ) - end - - def supported_upgrade?(%@for{} = _stream, _protocol), do: false - - def send_on_error(%@for{} = stream, %Bandit.HTTP2.Errors.StreamError{} = error) do - do_send(stream, {:send_rst_stream, error.error_code}) - %{stream | state: :closed} - end - - def send_on_error(%@for{} = stream, %Bandit.HTTP2.Errors.ConnectionError{} = error) do - do_send(stream, {:close_connection, error.error_code, error.message}) - stream - end - - def send_on_error(%@for{state: state} = stream, error) when state in [:idle, :open] do - stream = maybe_send_error(%{stream | state: :open}, error) - %{stream | state: :local_closed} - end - - def send_on_error(%@for{state: :remote_closed} = stream, error) do - stream = maybe_send_error(%{stream | state: :open}, error) - %{stream | state: :closed} - end - - def send_on_error(%@for{} = stream, _error), do: stream - - defp maybe_send_error(stream, error) do - receive do - {:plug_conn, :sent} -> stream - after - 0 -> - status = error |> Plug.Exception.status() |> Plug.Conn.Status.code() - send_headers(stream, status, [], :no_body) - end - end - - # Helpers - - defp do_send(stream, msg), do: send(stream.connection_pid, {msg, stream.stream_id}) - - defp call(stream, msg, timeout), - do: GenServer.call(stream.connection_pid, {msg, stream.stream_id}, timeout) - - @spec stream_error!(String.t(), Bandit.HTTP2.Stream.t()) :: no_return() - @spec stream_error!( - String.t(), - Bandit.HTTP2.Stream.t(), - Bandit.HTTP2.Errors.error_code() - ) :: no_return() - defp stream_error!(message, stream, error_code \\ Bandit.HTTP2.Errors.protocol_error()), - do: - raise(Bandit.HTTP2.Errors.StreamError, - message: message, - error_code: error_code, - stream_id: stream.stream_id - ) - - @spec connection_error!(term()) :: no_return() - @spec connection_error!(term(), Bandit.HTTP2.Errors.error_code()) :: no_return() - defp connection_error!(message, error_code \\ Bandit.HTTP2.Errors.protocol_error()), - do: raise(Bandit.HTTP2.Errors.ConnectionError, message: message, error_code: error_code) - end -end diff --git a/deps/bandit/lib/bandit/http2/stream_collection.ex b/deps/bandit/lib/bandit/http2/stream_collection.ex deleted file mode 100644 index f0c3369..0000000 --- a/deps/bandit/lib/bandit/http2/stream_collection.ex +++ /dev/null @@ -1,78 +0,0 @@ -defmodule Bandit.HTTP2.StreamCollection do - @moduledoc false - # Represents a collection of stream IDs and what process IDs are running them. An instance of - # this struct is contained within each `Bandit.HTTP2.Connection` struct and is responsible for - # encapsulating the data about the streams which are currently active within the connection. - # - # This collection has a number of useful properties: - # - # * Process IDs are accessible by stream id - # * Process IDs are deletable by themselves (ie: deletion is via PID) - # * The collection is able to determine if a stream not currently contained in this collection - # represents a previously seen stream (in which case it is considered to be in a 'closed' - # state), or if it is a stream ID of a stream that has yet to be created - - require Integer - - defstruct last_stream_id: 0, - stream_count: 0, - id_to_pid: %{}, - pid_to_id: %{} - - @typedoc "A map from stream id to pid" - @type t :: %__MODULE__{ - last_stream_id: Bandit.HTTP2.Stream.stream_id(), - stream_count: non_neg_integer(), - id_to_pid: %{Bandit.HTTP2.Stream.stream_id() => pid()}, - pid_to_id: %{pid() => Bandit.HTTP2.Stream.stream_id()} - } - - @spec get_pids(t()) :: [pid()] - def get_pids(collection), do: Map.values(collection.id_to_pid) - - @spec get_pid(t(), Bandit.HTTP2.Stream.stream_id()) :: pid() | :new | :closed | :invalid - def get_pid(_collection, stream_id) when Integer.is_even(stream_id), do: :invalid - def get_pid(collection, stream_id) when stream_id > collection.last_stream_id, do: :new - - def get_pid(collection, stream_id) do - case Map.get(collection.id_to_pid, stream_id) do - pid when is_pid(pid) -> pid - nil -> :closed - end - end - - @spec insert(t(), Bandit.HTTP2.Stream.stream_id(), pid()) :: t() - def insert(collection, stream_id, pid) do - %__MODULE__{ - last_stream_id: stream_id, - stream_count: collection.stream_count + 1, - id_to_pid: Map.put(collection.id_to_pid, stream_id, pid), - pid_to_id: Map.put(collection.pid_to_id, pid, stream_id) - } - end - - # Dialyzer insists on the atom() here even though it doesn't make sense - @spec delete(t(), pid()) :: t() | atom() - def delete(collection, pid) do - case Map.pop(collection.pid_to_id, pid) do - {nil, _} -> - collection - - {stream_id, new_pid_to_id} -> - %{ - collection - | id_to_pid: Map.delete(collection.id_to_pid, stream_id), - pid_to_id: new_pid_to_id - } - end - end - - @spec stream_count(t()) :: non_neg_integer() - def stream_count(collection), do: collection.stream_count - - @spec open_stream_count(t()) :: non_neg_integer() - def open_stream_count(collection), do: collection.pid_to_id |> map_size() - - @spec last_stream_id(t()) :: Bandit.HTTP2.Stream.stream_id() - def last_stream_id(collection), do: collection.last_stream_id -end diff --git a/deps/bandit/lib/bandit/http2/stream_process.ex b/deps/bandit/lib/bandit/http2/stream_process.ex deleted file mode 100644 index 21c8cfd..0000000 --- a/deps/bandit/lib/bandit/http2/stream_process.ex +++ /dev/null @@ -1,31 +0,0 @@ -defmodule Bandit.HTTP2.StreamProcess do - @moduledoc false - # This process runs the lifecycle of an HTTP/2 stream, which is modeled by a - # `Bandit.HTTP2.Stream` struct that this process maintains in its state - # - # As part of this lifecycle, the execution of a Plug to handle this stream's request - # takes place here; the entirety of the Plug lifecycle takes place in a single - # `c:handle_continue/2` call. - - use GenServer, restart: :temporary - - @spec start_link( - Bandit.HTTP2.Stream.t(), - Bandit.Pipeline.plug_def(), - Bandit.Telemetry.t(), - Bandit.Pipeline.conn_data(), - keyword() - ) :: GenServer.on_start() - def start_link(stream, plug, connection_span, conn_data, opts) do - GenServer.start_link(__MODULE__, {stream, plug, connection_span, conn_data, opts}) - end - - @impl GenServer - def init(state), do: {:ok, state, {:continue, :start_stream}} - - @impl GenServer - def handle_continue(:start_stream, {stream, plug, connection_span, conn_data, opts} = state) do - _ = Bandit.Pipeline.run(stream, plug, connection_span, conn_data, opts) - {:stop, :normal, state} - end -end diff --git a/deps/bandit/lib/bandit/http_error.ex b/deps/bandit/lib/bandit/http_error.ex deleted file mode 100644 index d83a86b..0000000 --- a/deps/bandit/lib/bandit/http_error.ex +++ /dev/null @@ -1,6 +0,0 @@ -defmodule Bandit.HTTPError do - # Represents an error suitable for return as an HTTP status. Note that these may be surfaced - # from anywhere that such a message is well defined, including within HTTP/1 transport concerns - # and also within shared HTTP semantics (ie: within Bandit.Adapter or Bandit.Pipeline) - defexception message: nil, plug_status: :bad_request -end diff --git a/deps/bandit/lib/bandit/http_transport.ex b/deps/bandit/lib/bandit/http_transport.ex deleted file mode 100644 index b1a05bd..0000000 --- a/deps/bandit/lib/bandit/http_transport.ex +++ /dev/null @@ -1,47 +0,0 @@ -defprotocol Bandit.HTTPTransport do - @moduledoc false - # A protocol implemented by the lower level transports (HTTP/1 and HTTP/2) to encapsulate the - # low-level mechanics needed to complete an HTTP request/response cycle. Implementations of this - # protocol should be broadly concerned with the protocol-specific aspects of a connection, and - # can rely on higher-level code taking care of shared HTTP semantics - - @typedoc "How the response body is to be delivered" - @type body_disposition :: :raw | :chunk_encoded | :no_body | :inform - - @spec peer_data(t()) :: Plug.Conn.Adapter.peer_data() - def peer_data(transport) - - @spec sock_data(t()) :: Plug.Conn.Adapter.sock_data() - def sock_data(transport) - - @spec ssl_data(t()) :: Plug.Conn.Adapter.ssl_data() - def ssl_data(transport) - - @spec version(t()) :: Plug.Conn.Adapter.http_protocol() - def version(transport) - - @spec read_headers(t()) :: - {:ok, Plug.Conn.method(), Bandit.Pipeline.request_target(), Plug.Conn.headers(), t()} - def read_headers(transport) - - @spec read_data(t(), opts :: keyword()) :: {:ok, iodata(), t()} | {:more, iodata(), t()} - def read_data(transport, opts) - - @spec send_headers(t(), Plug.Conn.status(), Plug.Conn.headers(), body_disposition()) :: t() - def send_headers(transport, status, heeaders, disposition) - - @spec send_data(t(), data :: iodata(), end_request :: boolean()) :: t() - def send_data(transport, data, end_request) - - @spec sendfile(t(), Path.t(), offset :: integer(), length :: integer() | :all) :: t() - def sendfile(transport, path, offset, length) - - @spec ensure_completed(t()) :: t() - def ensure_completed(transport) - - @spec supported_upgrade?(t(), atom()) :: boolean() - def supported_upgrade?(transport, protocol) - - @spec send_on_error(t(), struct()) :: t() - def send_on_error(transport, error) -end diff --git a/deps/bandit/lib/bandit/initial_handler.ex b/deps/bandit/lib/bandit/initial_handler.ex deleted file mode 100644 index 7e5ab27..0000000 --- a/deps/bandit/lib/bandit/initial_handler.ex +++ /dev/null @@ -1,86 +0,0 @@ -defmodule Bandit.InitialHandler do - @moduledoc false - # The initial protocol implementation used for all connections. Switches to a - # specific protocol implementation based on configuration, ALPN negotiation, and - # line heuristics. - - use ThousandIsland.Handler - - require Logger - - @type on_switch_handler :: - {:switch, bandit_http_handler(), data :: term(), state :: term()} - | {:switch, bandit_http_handler(), state :: term()} - - @type bandit_http_handler :: Bandit.HTTP1.Handler | Bandit.HTTP2.Handler - - # Attempts to guess the protocol in use, returning the applicable next handler and any - # data consumed in the course of guessing which must be processed by the actual protocol handler - @impl ThousandIsland.Handler - @spec handle_connection(ThousandIsland.Socket.t(), state :: term()) :: - ThousandIsland.Handler.handler_result() | on_switch_handler() - def handle_connection(socket, state) do - case {state.http_1_enabled, state.http_2_enabled, alpn_protocol(socket), sniff_wire(socket)} do - {_, _, _, :likely_tls} -> - Logger.warning("Connection that looks like TLS received on a clear channel", - domain: [:bandit], - plug: state.plug - ) - - {:close, state} - - {_, true, Bandit.HTTP2.Handler, Bandit.HTTP2.Handler} -> - {:switch, Bandit.HTTP2.Handler, state} - - {true, _, Bandit.HTTP1.Handler, {:no_match, data}} -> - {:switch, Bandit.HTTP1.Handler, data, state} - - {_, true, :no_match, Bandit.HTTP2.Handler} -> - {:switch, Bandit.HTTP2.Handler, state} - - {true, _, :no_match, {:no_match, data}} -> - {:switch, Bandit.HTTP1.Handler, data, state} - - _other -> - {:close, state} - end - end - - # Returns the protocol as negotiated via ALPN, if applicable - @spec alpn_protocol(ThousandIsland.Socket.t()) :: - Bandit.HTTP2.Handler | Bandit.HTTP1.Handler | :no_match - defp alpn_protocol(socket) do - case ThousandIsland.Socket.negotiated_protocol(socket) do - {:ok, "h2"} -> Bandit.HTTP2.Handler - {:ok, "http/1.1"} -> Bandit.HTTP1.Handler - _ -> :no_match - end - end - - # Returns the protocol as suggested by received data, if possible. - # We do this in two phases so that we don't hang on *really* short HTTP/1 - # requests that are less than 24 bytes - @spec sniff_wire(ThousandIsland.Socket.t()) :: - Bandit.HTTP2.Handler - | :likely_tls - | {:no_match, binary()} - | {:error, :closed | :timeout | :inet.posix()} - defp sniff_wire(socket) do - case ThousandIsland.Socket.recv(socket, 3) do - {:ok, "PRI" = buffer} -> sniff_wire_for_http2(socket, buffer) - {:ok, <<22::8, 3::8, minor::8>>} when minor in [1, 3] -> :likely_tls - {:ok, data} -> {:no_match, data} - {:error, :timeout} -> {:no_match, <<>>} - {:error, error} -> {:error, error} - end - end - - defp sniff_wire_for_http2(socket, buffer) do - case ThousandIsland.Socket.recv(socket, 21) do - {:ok, " * HTTP/2.0\r\n\r\nSM\r\n\r\n"} -> Bandit.HTTP2.Handler - {:ok, data} -> {:no_match, buffer <> data} - {:error, :timeout} -> {:no_match, buffer} - {:error, error} -> {:error, error} - end - end -end diff --git a/deps/bandit/lib/bandit/logger.ex b/deps/bandit/lib/bandit/logger.ex deleted file mode 100644 index 351b84f..0000000 --- a/deps/bandit/lib/bandit/logger.ex +++ /dev/null @@ -1,46 +0,0 @@ -defmodule Bandit.Logger do - @moduledoc false - - require Logger - - def maybe_log_protocol_error(error, stacktrace, opts, metadata) do - logging_verbosity = - case error do - %Bandit.TransportError{error: :closed} -> - Keyword.get(opts.http, :log_client_closures, false) - - _error -> - Keyword.get(opts.http, :log_protocol_errors, :short) - end - - case logging_verbosity do - :short -> - logger_metadata = logger_metadata_for(:error, error, stacktrace, metadata) - Logger.error(Exception.format_banner(:error, error, stacktrace), logger_metadata) - - :verbose -> - logger_metadata = logger_metadata_for(:error, error, stacktrace, metadata) - Logger.error(Exception.format(:error, error, stacktrace), logger_metadata) - - false -> - :ok - end - end - - def logger_metadata_for(kind, reason, stacktrace, metadata) do - crash_reason = crash_reason(kind, reason, stacktrace) - - case reason do - %Bandit.HTTP2.Errors.StreamError{stream_id: stream_id} when is_integer(stream_id) -> - [stream_id: stream_id, domain: [:bandit], crash_reason: crash_reason] - |> Keyword.merge(metadata) - - _ -> - [domain: [:bandit], crash_reason: crash_reason] - |> Keyword.merge(metadata) - end - end - - defp crash_reason(:throw, reason, stacktrace), do: {{:nocatch, reason}, stacktrace} - defp crash_reason(_, reason, stacktrace), do: {reason, stacktrace} -end diff --git a/deps/bandit/lib/bandit/phoenix_adapter.ex b/deps/bandit/lib/bandit/phoenix_adapter.ex deleted file mode 100644 index 3ed8584..0000000 --- a/deps/bandit/lib/bandit/phoenix_adapter.ex +++ /dev/null @@ -1,116 +0,0 @@ -defmodule Bandit.PhoenixAdapter do - @moduledoc """ - A Bandit adapter for Phoenix. - - This adapter provides out-of-the-box support for all aspects of Phoenix 1.7 and later. Earlier - versions of Phoenix will work with this adapter, but without support for WebSockets. - - To use this adapter, your project will need to include Bandit as a dependency: - - ```elixir - {:bandit, "~> 1.0"} - ``` - - Once Bandit is included as a dependency of your Phoenix project, add the following `adapter:` - line to your endpoint configuration in `config/config.exs`, as in the following example: - - ``` - # config/config.exs - - config :your_app, YourAppWeb.Endpoint, - adapter: Bandit.PhoenixAdapter, # <---- ADD THIS LINE - url: [host: "localhost"], - render_errors: ... - ``` - - That's it! **After restarting Phoenix you should see the startup message indicate that it is being - served by Bandit**, and everything should 'just work'. Note that if you have set any exotic - configuration options within your endpoint, you may need to update that configuration to work - with Bandit; see below for details. - - ## Endpoint configuration - - This adapter supports the standard Phoenix structure for endpoint configuration. Top-level keys for - `:http` and `:https` are supported, and configuration values within each of those are interpreted - as raw Bandit configuration as specified by `t:Bandit.options/0`. Bandit's configuration supports - all values used in a standard out-of-the-box Phoenix application, so if you haven't made any - substantial changes to your endpoint configuration things should 'just work' for you. - - In the event that you *have* made advanced changes to your endpoint configuration, you may need - to update this config to work with Bandit. Consult Bandit's documentation at - `t:Bandit.options/0` for details. - - It can be difficult to know exactly *where* to put the options that you may need to set from the - ones available at `t:Bandit.options/0`. The general idea is that anything inside the `http:` or - `https:` keyword lists in your configuration are passed directly to `Bandit.start_link/1`, so an - example may look like so: - - ```elixir - # config/{dev,prod,etc}.exs - - config :your_app, YourAppWeb.Endpoint, - http: [ - ip: {127, 0, 0, 1}, - port: 4000, - thousand_island_options: [num_acceptors: 123], - http_options: [log_protocol_errors: false], - http_1_options: [max_requests: 1], - websocket_options: [compress: false] - ], - ``` - - Note that, unlike the `adapter: Bandit.PhoenixAdapter` configuration change outlined previously, - configuration of specific `http:` and `https:` values is done on a per-environment basis in - Phoenix, so these changes will typically be in your `config/dev.exs`, `config/prod.exs` and - similar files. - """ - - @doc """ - Returns the Bandit server process for the provided scheme within the given Phoenix Endpoint - """ - @spec bandit_pid(module()) :: - {:ok, Supervisor.child() | :restarting | :undefined} | {:error, :no_server_found} - def bandit_pid(endpoint, scheme \\ :http) do - endpoint - |> Supervisor.which_children() - |> Enum.find(fn {id, _, _, _} -> id == {endpoint, scheme} end) - |> case do - {_, pid, _, _} -> {:ok, pid} - nil -> {:error, :no_server_found} - end - end - - @doc """ - Returns the bound address and port of the Bandit server process for the provided - scheme within the given Phoenix Endpoint - """ - def server_info(endpoint, scheme) do - case bandit_pid(endpoint, scheme) do - {:ok, pid} -> ThousandIsland.listener_info(pid) - {:error, reason} -> {:error, reason} - end - end - - @doc false - def child_specs(endpoint, config) do - otp_app = Keyword.fetch!(config, :otp_app) - - plug = resolve_plug(config[:code_reloader], endpoint) - - for scheme <- [:http, :https], opts = config[scheme] do - ([plug: plug, display_plug: endpoint, scheme: scheme, otp_app: otp_app] ++ opts) - |> Bandit.child_spec() - |> Supervisor.child_spec(id: {endpoint, scheme}) - end - end - - defp resolve_plug(code_reload?, endpoint) do - if code_reload? && - Code.ensure_loaded?(Phoenix.Endpoint.SyncCodeReloadPlug) && - function_exported?(Phoenix.Endpoint.SyncCodeReloadPlug, :call, 2) do - {Phoenix.Endpoint.SyncCodeReloadPlug, {endpoint, []}} - else - endpoint - end - end -end diff --git a/deps/bandit/lib/bandit/pipeline.ex b/deps/bandit/lib/bandit/pipeline.ex deleted file mode 100644 index 079352a..0000000 --- a/deps/bandit/lib/bandit/pipeline.ex +++ /dev/null @@ -1,248 +0,0 @@ -defmodule Bandit.Pipeline do - @moduledoc false - # Provides a common pipeline for HTTP/1.1 and h2 adapters, factoring together shared - # functionality relating to `Plug.Conn` management - - @type plug_def :: {function() | module(), Plug.opts()} - @type conn_data :: {boolean(), :inet.ip_address()} - @type request_target :: - {scheme(), nil | Plug.Conn.host(), nil | Plug.Conn.port_number(), path()} - @type scheme :: String.t() | nil - @type path :: String.t() | :* - - require Logger - - @spec run( - Bandit.HTTPTransport.t(), - plug_def(), - ThousandIsland.Telemetry.t() | Bandit.Telemetry.t(), - conn_data(), - map() - ) :: - {:ok, Bandit.HTTPTransport.t()} - | {:upgrade, Bandit.HTTPTransport.t(), :websocket, tuple()} - | {:error, term()} - def run(transport, plug, connection_span, conn_data, opts) do - measurements = %{monotonic_time: Bandit.Telemetry.monotonic_time()} - - metadata = %{ - connection_telemetry_span_context: connection_span.telemetry_span_context, - plug: plug - } - - try do - {:ok, method, request_target, headers, transport} = - Bandit.HTTPTransport.read_headers(transport) - - conn = build_conn!(transport, method, request_target, headers, conn_data, opts) - span = Bandit.Telemetry.start_span(:request, measurements, Map.put(metadata, :conn, conn)) - - try do - conn - |> call_plug!(plug) - |> maybe_upgrade!() - |> case do - {:no_upgrade, conn} -> - %Plug.Conn{adapter: {_mod, adapter}} = conn = commit_response!(conn) - Bandit.Telemetry.stop_span(span, adapter.metrics, %{conn: conn}) - {:ok, adapter.transport} - - {:upgrade, %Plug.Conn{adapter: {_mod, adapter}} = conn, protocol, opts} -> - conn = Plug.Conn.put_status(conn, 101) - Bandit.Telemetry.stop_span(span, adapter.metrics, %{conn: conn}) - {:upgrade, adapter.transport, protocol, opts} - end - catch - kind, value -> - handle_error(kind, value, __STACKTRACE__, transport, span, opts, plug: plug, conn: conn) - end - rescue - exception -> - span = Bandit.Telemetry.start_span(:request, measurements, metadata) - handle_error(:error, exception, __STACKTRACE__, transport, span, opts, plug: plug) - end - end - - @spec build_conn!( - Bandit.HTTPTransport.t(), - Plug.Conn.method(), - request_target(), - Plug.Conn.headers(), - conn_data(), - map() - ) :: Plug.Conn.t() - defp build_conn!(transport, method, request_target, headers, {secure?, peer_address}, opts) do - adapter = Bandit.Adapter.init(self(), transport, method, headers, opts) - scheme = determine_scheme(secure?, request_target) - version = Bandit.HTTPTransport.version(transport) - {host, port} = determine_host_and_port!(scheme, version, request_target, headers) - {path, query} = determine_path_and_query(request_target) - uri = %URI{scheme: scheme, host: host, port: port, path: path, query: query} - Plug.Conn.Adapter.conn({Bandit.Adapter, adapter}, method, uri, peer_address, headers) - end - - @spec determine_scheme(boolean(), request_target()) :: String.t() | nil - defp determine_scheme(secure?, {scheme, _, _, _}) do - case {secure?, scheme} do - {true, nil} -> "https" - {false, nil} -> "http" - {_, scheme} -> scheme - end - end - - @spec determine_host_and_port!(binary(), atom(), request_target(), Plug.Conn.headers()) :: - {Plug.Conn.host(), Plug.Conn.port_number()} - defp determine_host_and_port!(scheme, version, {_, nil, nil, _}, headers) do - case {Bandit.Headers.get_header(headers, "host"), version} do - {nil, :"HTTP/1.0"} -> - {"", URI.default_port(scheme)} - - {nil, _} -> - request_error!("Unable to obtain host and port: No host header") - - {host_header, _} -> - {host, port} = Bandit.Headers.parse_hostlike_header!(host_header) - {host, port || URI.default_port(scheme)} - end - end - - defp determine_host_and_port!(scheme, _version, {_, host, port, _}, _headers), - do: {to_string(host), port || URI.default_port(scheme)} - - @spec determine_path_and_query(request_target()) :: {String.t(), nil | String.t()} - defp determine_path_and_query({_, _, _, :*}), do: {"*", nil} - defp determine_path_and_query({_, _, _, path}), do: split_path(path) - - @spec split_path(String.t()) :: {String.t(), nil | String.t()} - defp split_path(path) do - path - |> to_string() - |> :binary.split("#") - |> hd() - |> :binary.split("?") - |> case do - [path, query] -> {path, query} - [path] -> {path, nil} - end - end - - @spec call_plug!(Plug.Conn.t(), plug_def()) :: Plug.Conn.t() | no_return() - defp call_plug!(%Plug.Conn{} = conn, {plug, plug_opts}) when is_atom(plug) do - case plug.call(conn, plug_opts) do - %Plug.Conn{} = conn -> conn - other -> raise("Expected #{plug}.call/2 to return %Plug.Conn{} but got: #{inspect(other)}") - end - end - - defp call_plug!(%Plug.Conn{} = conn, {plug_fn, plug_opts}) when is_function(plug_fn) do - case plug_fn.(conn, plug_opts) do - %Plug.Conn{} = conn -> conn - other -> raise("Expected Plug function to return %Plug.Conn{} but got: #{inspect(other)}") - end - end - - @spec maybe_upgrade!(Plug.Conn.t()) :: - {:no_upgrade, Plug.Conn.t()} | {:upgrade, Plug.Conn.t(), :websocket, tuple()} - defp maybe_upgrade!( - %Plug.Conn{ - state: :upgraded, - adapter: - {_, - %{upgrade: {:websocket, {websock, websock_opts, connection_opts}, websocket_opts}}} - } = conn - ) do - # We can safely unset the state, since we match on :upgraded above - case Bandit.WebSocket.Handshake.handshake( - %{conn | state: :unset}, - connection_opts, - websocket_opts - ) do - {:ok, conn, connection_opts} -> - {:upgrade, conn, :websocket, {websock, websock_opts, connection_opts}} - - {:error, reason} -> - request_error!(reason) - end - end - - defp maybe_upgrade!(conn), do: {:no_upgrade, conn} - - @spec commit_response!(Plug.Conn.t()) :: Plug.Conn.t() | no_return() - defp commit_response!(conn) do - case conn do - %Plug.Conn{state: :unset} -> - raise(Plug.Conn.NotSentError) - - %Plug.Conn{state: :set} -> - Plug.Conn.send_resp(conn) - - %Plug.Conn{state: :chunked, adapter: {mod, adapter}} -> - adapter = - case mod.chunk(adapter, "") do - {:ok, _, adapter} -> adapter - _ -> adapter - end - - %{conn | adapter: {mod, adapter}} - - %Plug.Conn{} -> - conn - end - |> then(fn %Plug.Conn{adapter: {mod, adapter}} = conn -> - transport = Bandit.HTTPTransport.ensure_completed(adapter.transport) - %{conn | adapter: {mod, %{adapter | transport: transport}}} - end) - end - - @spec request_error!(term()) :: no_return() - @spec request_error!(term(), Plug.Conn.status()) :: no_return() - defp request_error!(reason, plug_status \\ :bad_request) do - raise Bandit.HTTPError, message: reason, plug_status: plug_status - end - - @spec handle_error( - :error | :throw | :exit, - Exception.t() | term(), - Exception.stacktrace(), - Bandit.HTTPTransport.t(), - Bandit.Telemetry.t(), - map(), - keyword() - ) :: {:ok, Bandit.HTTPTransport.t()} | {:error, term()} - defp handle_error(:error, %Plug.Conn.WrapperError{} = error, _, transport, span, opts, metadata) do - # Unwrap the inner error and handle it - handle_error(error.kind, error.reason, error.stack, transport, span, opts, metadata) - end - - defp handle_error(:error, %type{} = error, stacktrace, transport, span, opts, metadata) - when type in [ - Bandit.HTTPError, - Bandit.TransportError, - Bandit.HTTP2.Errors.StreamError, - Bandit.HTTP2.Errors.ConnectionError - ] do - Bandit.Telemetry.stop_span(span, %{}, Enum.into(metadata, %{error: error.message})) - - Bandit.Logger.maybe_log_protocol_error(error, stacktrace, opts, metadata) - - # We want to do this at the end of the function, since the HTTP2 stack may kill this process - # in the course of handling a ConnectionError - Bandit.HTTPTransport.send_on_error(transport, error) - {:error, error} - end - - defp handle_error(kind, reason, stacktrace, transport, span, opts, metadata) do - reason = Exception.normalize(kind, reason, stacktrace) - - Bandit.Telemetry.span_exception(span, kind, reason, stacktrace) - status = reason |> Plug.Exception.status() |> Plug.Conn.Status.code() - - if status in Keyword.get(opts.http, :log_exceptions_with_status_codes, 500..599) do - logger_metadata = Bandit.Logger.logger_metadata_for(kind, reason, stacktrace, metadata) - Logger.error(Exception.format(kind, reason, stacktrace), logger_metadata) - end - - Bandit.HTTPTransport.send_on_error(transport, reason) - {:error, reason} - end -end diff --git a/deps/bandit/lib/bandit/primitive_ops/websocket.ex b/deps/bandit/lib/bandit/primitive_ops/websocket.ex deleted file mode 100644 index d9af167..0000000 --- a/deps/bandit/lib/bandit/primitive_ops/websocket.ex +++ /dev/null @@ -1,34 +0,0 @@ -defmodule Bandit.PrimitiveOps.WebSocket do - @moduledoc """ - WebSocket primitive operations behaviour and default implementation - """ - - @doc """ - WebSocket masking according to [RFC6455§5.3](https://www.rfc-editor.org/rfc/rfc6455#section-5.3) - """ - @callback ws_mask(payload :: binary(), mask :: integer()) :: binary() - - @behaviour __MODULE__ - - # Note that masking is an involution, so we don't need a separate unmask function - @impl true - def ws_mask(payload, mask) - when is_binary(payload) and is_integer(mask) and mask >= 0x00000000 and mask <= 0xFFFFFFFF do - ws_mask(<<>>, payload, mask) - end - - defp ws_mask(acc, <>, mask) do - ws_mask(<>)>>, rest, mask) - end - - for size <- [24, 16, 8] do - defp ws_mask(acc, <>, mask) do - <> = <> - <>)>> - end - end - - defp ws_mask(acc, <<>>, _mask) do - acc - end -end diff --git a/deps/bandit/lib/bandit/socket_helpers.ex b/deps/bandit/lib/bandit/socket_helpers.ex deleted file mode 100644 index 4d3fb5a..0000000 --- a/deps/bandit/lib/bandit/socket_helpers.ex +++ /dev/null @@ -1,74 +0,0 @@ -defmodule Bandit.SocketHelpers do - @moduledoc false - - def iodata_empty?(""), do: true - def iodata_empty?([]), do: true - def iodata_empty?([head | tail]), do: iodata_empty?(head) and iodata_empty?(tail) - def iodata_empty?(_), do: false - - @spec conn_data(ThousandIsland.Socket.t()) :: Bandit.Pipeline.conn_data() - def conn_data(socket) do - secure? = ThousandIsland.Socket.secure?(socket) - - {peer_address, _port} = - case ThousandIsland.Socket.peername(socket) do - {:ok, peername} -> map_address(peername) - {:error, reason} -> transport_error!("Unable to obtain conn_data", reason) - end - - {secure?, peer_address} - end - - @spec peer_data(ThousandIsland.Socket.t()) :: Plug.Conn.Adapter.peer_data() - def peer_data(socket) do - with {:ok, peername} <- ThousandIsland.Socket.peername(socket), - {address, port} <- map_address(peername), - {:ok, ssl_cert} <- peercert(socket) do - %{address: address, port: port, ssl_cert: ssl_cert} - else - {:error, reason} -> transport_error!("Unable to obtain peer_data", reason) - end - end - - @spec sock_data(ThousandIsland.Socket.t()) :: Plug.Conn.Adapter.sock_data() - def sock_data(socket) do - with {:ok, sockname} <- ThousandIsland.Socket.sockname(socket), - {address, port} <- map_address(sockname) do - %{address: address, port: port} - else - {:error, reason} -> transport_error!("Unable to obtain sock_data", reason) - end - end - - @spec ssl_data(ThousandIsland.Socket.t()) :: Plug.Conn.Adapter.ssl_data() - def ssl_data(socket) do - case ThousandIsland.Socket.connection_information(socket) do - {:ok, connection_information} -> connection_information - {:error, :not_secure} -> nil - {:error, reason} -> transport_error!("Unable to obtain ssl_data", reason) - end - end - - defp map_address(address) do - case address do - {:local, path} -> {{:local, path}, 0} - {:unspec, <<>>} -> {:unspec, 0} - {:undefined, term} -> {{:undefined, term}, 0} - {ip, port} -> {ip, port} - end - end - - defp peercert(socket) do - case ThousandIsland.Socket.peercert(socket) do - {:ok, cert} -> {:ok, cert} - {:error, :no_peercert} -> {:ok, nil} - {:error, :not_secure} -> {:ok, nil} - {:error, reason} -> {:error, reason} - end - end - - @spec transport_error!(term(), term()) :: no_return() - defp transport_error!(message, error) do - raise Bandit.TransportError, message: message, error: error - end -end diff --git a/deps/bandit/lib/bandit/telemetry.ex b/deps/bandit/lib/bandit/telemetry.ex deleted file mode 100644 index c940189..0000000 --- a/deps/bandit/lib/bandit/telemetry.ex +++ /dev/null @@ -1,250 +0,0 @@ -defmodule Bandit.Telemetry do - @moduledoc """ - The following telemetry spans are emitted by bandit - - ## `[:bandit, :request, *]` - - Represents Bandit handling a specific client HTTP request - - This span is started by the following event: - - * `[:bandit, :request, :start]` - - Represents the start of the span - - This event contains the following measurements: - - * `monotonic_time`: The time of this event, in `:native` units - - This event contains the following metadata: - - * `telemetry_span_context`: A unique identifier for this span - * `connection_telemetry_span_context`: The span context of the Thousand Island `:connection` - span which contains this request - * `conn`: The `Plug.Conn` representing this connection. Not present in cases where `error` - is also set and the nature of error is such that Bandit was unable to successfully build - the conn - * `plug`: The Plug which is being used to serve this request. Specified as `{plug_module, plug_opts}` - - This span is ended by the following event: - - * `[:bandit, :request, :stop]` - - Represents the end of the span - - This event contains the following measurements: - - * `monotonic_time`: The time of this event, in `:native` units - * `duration`: The span duration, in `:native` units - * `req_header_end_time`: The time that header reading completed, in `:native` units - * `req_body_start_time`: The time that request body reading started, in `:native` units. - * `req_body_end_time`: The time that request body reading completed, in `:native` units - * `req_body_bytes`: The length of the request body, in octets - * `resp_start_time`: The time that the response started, in `:native` units - * `resp_end_time`: The time that the response completed, in `:native` units - * `resp_body_bytes`: The length of the response body, in octets. If the response is - compressed, this is the size of the compressed payload as sent on the wire - * `resp_uncompressed_body_bytes`: The length of the original, uncompressed body. Only - included for responses which are compressed - * `resp_compression_method`: The method of compression, as sent in the `Content-Encoding` - header of the response. Only included for responses which are compressed - - This event contains the following metadata: - - * `telemetry_span_context`: A unique identifier for this span - * `connection_telemetry_span_context`: The span context of the Thousand Island `:connection` - span which contains this request - * `conn`: The `Plug.Conn` representing this connection. Not present in cases where `error` - is also set and the nature of error is such that Bandit was unable to successfully build - the conn - * `plug`: The Plug which is being used to serve this request. Specified as `{plug_module, plug_opts}` - * `error`: The error that caused the span to end, if it ended in error - - The following events may be emitted within this span: - - * `[:bandit, :request, :exception]` - - The request for this span ended unexpectedly - - This event contains the following measurements: - - * `monotonic_time`: The time of this event, in `:native` units - - This event contains the following metadata: - - * `telemetry_span_context`: A unique identifier for this span - * `connection_telemetry_span_context`: The span context of the Thousand Island `:connection` - span which contains this request - * `conn`: The `Plug.Conn` representing this connection. Not present in cases where `error` - is also set and the nature of error is such that Bandit was unable to successfully build - the conn - * `plug`: The Plug which is being used to serve this request. Specified as `{plug_module, plug_opts}` - * `kind`: The kind of unexpected condition, typically `:exit` - * `exception`: The exception which caused this unexpected termination. May be an exception - or an arbitrary value when the event was an uncaught throw or an exit - * `stacktrace`: The stacktrace of the location which caused this unexpected termination - - ## `[:bandit, :websocket, *]` - - Represents Bandit handling a WebSocket connection - - This span is started by the following event: - - * `[:bandit, :websocket, :start]` - - Represents the start of the span - - This event contains the following measurements: - - * `monotonic_time`: The time of this event, in `:native` units - * `compress`: Details about the compression configuration for this connection - - This event contains the following metadata: - - * `telemetry_span_context`: A unique identifier for this span - * `connection_telemetry_span_context`: The span context of the Thousand Island `:connection` - span which contains this request - * `websock`: The WebSock which is being used to serve this request. Specified as `websock_module` - - This span is ended by the following event: - - * `[:bandit, :websocket, :stop]` - - Represents the end of the span - - This event contains the following measurements: - - * `monotonic_time`: The time of this event, in `:native` units - * `duration`: The span duration, in `:native` units - * `recv_text_frame_count`: The number of text frames received - * `recv_text_frame_bytes`: The total number of bytes received in the payload of text frames - * `recv_binary_frame_count`: The number of binary frames received - * `recv_binary_frame_bytes`: The total number of bytes received in the payload of binary frames - * `recv_ping_frame_count`: The number of ping frames received - * `recv_ping_frame_bytes`: The total number of bytes received in the payload of ping frames - * `recv_pong_frame_count`: The number of pong frames received - * `recv_pong_frame_bytes`: The total number of bytes received in the payload of pong frames - * `recv_connection_close_frame_count`: The number of connection close frames received - * `recv_connection_close_frame_bytes`: The total number of bytes received in the payload of connection close frames - * `recv_continuation_frame_count`: The number of continuation frames received - * `recv_continuation_frame_bytes`: The total number of bytes received in the payload of continuation frames - * `send_text_frame_count`: The number of text frames sent - * `send_text_frame_bytes`: The total number of bytes sent in the payload of text frames - * `send_binary_frame_count`: The number of binary frames sent - * `send_binary_frame_bytes`: The total number of bytes sent in the payload of binary frames - * `send_ping_frame_count`: The number of ping frames sent - * `send_ping_frame_bytes`: The total number of bytes sent in the payload of ping frames - * `send_pong_frame_count`: The number of pong frames sent - * `send_pong_frame_bytes`: The total number of bytes sent in the payload of pong frames - * `send_connection_close_frame_count`: The number of connection close frames sent - * `send_connection_close_frame_bytes`: The total number of bytes sent in the payload of connection close frames - * `send_continuation_frame_count`: The number of continuation frames sent - * `send_continuation_frame_bytes`: The total number of bytes sent in the payload of continuation frames - - This event contains the following metadata: - - * `telemetry_span_context`: A unique identifier for this span - * `origin_telemetry_span_context`: The span context of the Bandit `:request` span from which - this connection originated - * `connection_telemetry_span_context`: The span context of the Thousand Island `:connection` - span which contains this request - * `websock`: The WebSock which is being used to serve this request. Specified as `websock_module` - * `error`: The error that caused the span to end, if it ended in error - """ - - defstruct span_name: nil, telemetry_span_context: nil, start_time: nil, start_metadata: nil - - @typep span_name :: atom() - @opaque t :: %__MODULE__{ - span_name: span_name(), - telemetry_span_context: reference(), - start_time: integer(), - start_metadata: :telemetry.event_metadata() - } - - @app_name :bandit - - @doc false - @spec start_span(span_name(), :telemetry.event_measurements(), :telemetry.event_metadata()) :: - t() - def start_span(span_name, measurements \\ %{}, metadata \\ %{}) do - measurements = Map.put_new_lazy(measurements, :monotonic_time, &monotonic_time/0) - telemetry_span_context = make_ref() - metadata = Map.put(metadata, :telemetry_span_context, telemetry_span_context) - event([span_name, :start], measurements, metadata) - - %__MODULE__{ - span_name: span_name, - telemetry_span_context: telemetry_span_context, - start_time: measurements[:monotonic_time], - start_metadata: metadata - } - end - - @doc false - @spec stop_span(t(), :telemetry.event_measurements(), :telemetry.event_metadata()) :: :ok - def stop_span(span, measurements \\ %{}, metadata \\ %{}) do - measurements = Map.put_new_lazy(measurements, :monotonic_time, &monotonic_time/0) - - measurements = - Map.put(measurements, :duration, measurements[:monotonic_time] - span.start_time) - - metadata = Map.merge(span.start_metadata, metadata) - - untimed_span_event(span, :stop, measurements, metadata) - end - - @spec span_exception(t(), Exception.kind(), Exception.t() | term(), Exception.stacktrace()) :: - :ok - def span_exception(span, kind, reason, stacktrace) do - # Using :exit for backwards-compatibility with Bandit =< 1.5.7 - kind = if kind == :error, do: :exit, else: kind - - metadata = - Map.merge(span.start_metadata, %{ - kind: kind, - exception: reason, - stacktrace: stacktrace - }) - - span_event(span, :exception, %{}, metadata) - end - - @doc false - @spec span_event(t(), span_name(), :telemetry.event_measurements(), :telemetry.event_metadata()) :: - :ok - def span_event(span, name, measurements \\ %{}, metadata \\ %{}) do - measurements = Map.put_new_lazy(measurements, :monotonic_time, &monotonic_time/0) - untimed_span_event(span, name, measurements, metadata) - end - - @doc false - @spec untimed_span_event( - t(), - span_name(), - :telemetry.event_measurements(), - :telemetry.event_metadata() - ) :: :ok - def untimed_span_event(span, name, measurements \\ %{}, metadata \\ %{}) do - metadata = Map.put(metadata, :telemetry_span_context, span.telemetry_span_context) - event([span.span_name, name], measurements, metadata) - end - - @spec monotonic_time :: integer() - defdelegate monotonic_time, to: System - - @spec event( - :telemetry.event_name(), - :telemetry.event_measurements(), - :telemetry.event_metadata() - ) :: :ok - defp event(suffix, measurements, metadata) do - :telemetry.execute([@app_name | suffix], measurements, metadata) - end - - @doc false - @spec telemetry_span_context(t()) :: reference() - def telemetry_span_context(span) do - span.telemetry_span_context - end -end diff --git a/deps/bandit/lib/bandit/trace.ex b/deps/bandit/lib/bandit/trace.ex deleted file mode 100644 index 61f165e..0000000 --- a/deps/bandit/lib/bandit/trace.ex +++ /dev/null @@ -1,150 +0,0 @@ -defmodule Bandit.Trace do - @moduledoc """ - **THIS MODULE IS EXPERIMENTAL AND SUBJECT TO CHANGE** - - Helper functions to provide visibility into runtime errors within a running Bandit instance - - Can be used within an IEx session attached to a running Bandit instance, as follows: - - ``` - iex> Bandit.Trace.start_tracing() - ... # Wait for traces to show up whenever exceptions are raised - iex> Bandit.Trace.stop_tracing() - ``` - - It can also be started within your application by adding `Bandit.Trace` to your process tree. - - `Bandit.Trace` will emit a trace on every exception that Bandit sees (both those emitted from - within your Plug as well as internal ones due to protocol violations and the like). These traces - consist of a complete dump of all telemetry events that occur in the offending request's parent - connection. - - Tracing imposes a modest but non-zero load; it *should* be safe to run in most production - environments, but it is not intended to run on an ongoing basis. - - By default, `Bandit.Trace` maintains a FIFO log of the last 10000 telemetry events that Bandit - has emitted. Events which correlate to the parent connection which have been evicted from this - queue will not be included in this output. - - **WARNING** The emitted logs contains a *complete* copy of your request's Plug data, as well as *all* data - sent and received on all requests which are contained in the output. It is therefore of the utmost - importance that you carefully redact the output before sharing it publicly. - """ - - defstruct queue: nil, size: 0, max_size: 10_000, trace_on_exception: true - - use GenServer - - @events [ - [:bandit, :request, :start], - [:bandit, :request, :stop], - [:bandit, :request, :exception], - [:bandit, :websocket, :start], - [:bandit, :websocket, :stop], - [:thousand_island, :connection, :start], - [:thousand_island, :connection, :stop], - [:thousand_island, :connection, :ready], - [:thousand_island, :connection, :async_recv], - [:thousand_island, :connection, :recv], - [:thousand_island, :connection, :recv_error], - [:thousand_island, :connection, :send], - [:thousand_island, :connection, :send_error], - [:thousand_island, :connection, :sendfile], - [:thousand_island, :connection, :sendfile_error], - [:thousand_island, :connection, :socket_shutdown] - ] - - @doc """ - Start tracing of all Bandit requests - - See module documentation for intended usage. Accepts the following options: - - * `max_size`: The size of the telemetry event queue to maintain. By default, `Bandit.Trace` maintains a - queue of the last 10000 telemetry events - * `trace_on_exception`: Whether or not to emit traces when an error is raised within - Bandit. Defaults to `true` - """ - def start_tracing(opts \\ []), do: GenServer.start_link(__MODULE__, opts, name: __MODULE__) - - @doc """ - Stop any active trace session - """ - def stop_tracing, do: GenServer.stop(__MODULE__) - - def handle_event(event, measurements, metadata, pid), - do: GenServer.cast(pid, {:event, {event, measurements, metadata, :os.perf_counter()}}) - - @doc """ - Return the complete queue of telemetry events that `Bandit.Trace` is currently tracking - """ - def get_events, do: GenServer.call(__MODULE__, :get_events) - - @impl GenServer - def init(opts) do - _ = :telemetry.attach_many(self(), @events, &__MODULE__.handle_event/4, self()) - {:ok, struct!(%__MODULE__{queue: :queue.new()}, opts)} - end - - @impl GenServer - def terminate(_, _), do: :telemetry.detach(self()) - - @impl GenServer - def handle_cast({:event, event}, state) do - state - |> maybe_pop() - |> push(event) - |> tap(&maybe_trace(&1, event)) - |> then(&{:noreply, &1}) - end - - defp maybe_pop(%{size: size, max_size: max_size} = state) when size >= max_size, - do: maybe_pop(%{state | queue: :queue.drop(state.queue), size: size - 1}) - - defp maybe_pop(state), do: state - - defp push(state, event), - do: %{state | queue: :queue.in(event, state.queue), size: state.size + 1} - - defp maybe_trace( - %{trace_on_exception: true} = state, - {[:bandit, :request, :exception], _, metadata, _} - ) do - connection_span_context = Map.get(metadata, :connection_telemetry_span_context) - - IO.puts("======================================") - IO.puts("Starting telemetry trace for exception") - IO.puts("======================================") - - :queue.to_list(state.queue) - |> Enum.filter(fn {_, _, metadata, _} -> - Map.get(metadata, :telemetry_span_context) == connection_span_context || - Map.get(metadata, :connection_telemetry_span_context) == connection_span_context - end) - |> format_list() - |> inspect(limit: :infinity, pretty: true, printable_limit: :infinity) - |> IO.puts() - - IO.puts("=======================================") - IO.puts("Completed telemetry trace for exception") - IO.puts("=======================================") - - :ok - end - - defp maybe_trace(_state, _event), do: :ok - - @impl GenServer - def handle_call(:get_events, _from, state), - do: {:reply, :queue.to_list(state.queue) |> format_list(), state} - - defp format_list([]), do: :ok - - defp format_list([{_, _, _, start_time} | _] = events), - do: Enum.map(events, &format_tuple(&1, start_time)) - - defp format_tuple({event, measurements, metadata, time}, start_time) do - time = :erlang.convert_time_unit(time - start_time, :perf_counter, :microsecond) - %{telemetry_span_context: span_id} = metadata - {time, span_id, event, measurements, metadata} - end -end diff --git a/deps/bandit/lib/bandit/transport_error.ex b/deps/bandit/lib/bandit/transport_error.ex deleted file mode 100644 index 86e0101..0000000 --- a/deps/bandit/lib/bandit/transport_error.ex +++ /dev/null @@ -1,6 +0,0 @@ -defmodule Bandit.TransportError do - # Represents an error coming from the underlying transport which cannot be signalled back to the - # client by conventional means within the request. Examples include TCP socket closures and - # errors in the case of HTTP/1, and stream resets in HTTP/2 - defexception message: nil, error: nil -end diff --git a/deps/bandit/lib/bandit/websocket/README.md b/deps/bandit/lib/bandit/websocket/README.md deleted file mode 100644 index ba76d6f..0000000 --- a/deps/bandit/lib/bandit/websocket/README.md +++ /dev/null @@ -1,58 +0,0 @@ -# WebSocket Handler - -Included in this folder is a complete `ThousandIsland.Handler` based implementation of WebSockets -as defined in [RFC 6455](https://datatracker.ietf.org/doc/rfc6455). - -## Upgrade mechanism - -A good overview of this process is contained in this [ElixirConf EU -talk](https://www.youtube.com/watch?v=usKLrYl4zlY). - -Upgrading an HTTP connection to a WebSocket connection is coordinated by code -contained within several libraries, including Bandit, -[WebSockAdapter](https://github.com/phoenixframework/websock_adapter), and -[Plug](https://github.com/elixir-plug/plug). - -The HTTP request containing the upgrade request is first passed to the user's -application as a standard Plug call. After inspecting the request and deeming it -a suitable upgrade candidate (via whatever policy the application dictates), the -user indicates a desire to upgrade the connection to a WebSocket by calling -`WebSockAdapter.upgrade/4`, which checks that the request is a valid WebSocket -upgrade request, and then calls `Plug.Conn.upgrade_adapter/3` to signal to -Bandit that the connection should be upgraded at the conclusion of the request. -At the conclusion of the `Plug.call/2` callback, `Bandit.Pipeline` will then -attempt to upgrade the underlying connection. As part of this upgrade process, -`Bandit.DelegatingHandler` will switch the Handler for the connection to be -`Bandit.WebSocket.Handler`. This will cause any future communication after the -upgrade process to be handled directly by Bandit's WebSocket stack. - -## Process model - -Within a Bandit server, a WebSocket connection is modeled as a single process. -This process is directly tied to the lifecycle of the underlying WebSocket -connection; when upgrading from HTTP/1, the existing HTTP/1 handler process -'magically' becomes a WebSocket process by changing which Handler the -`Bandit.DelegatingHandler` delegates to. - -The execution model to handle a given request is quite straightforward: at -upgrade time, the `Bandit.DelegatingHandler` will call `handle_connection/2` to -allow the WebSocket handler to initialize any startup state. Connection state is -modeled by the `Bandit.WebSocket.Connection` struct and module. - -All data subsequently received by the underlying [Thousand -Island](https://github.com/mtrudel/thousand_island) library will result in -a call to `Bandit.WebSocket.Handler.handle_data/3`, which will then attempt to -parse the data into one or more WebSocket frames. Once a frame has been -constructed, it is them passed through to the configured `WebSock` handler by -way of the underlying `Bandit.WebSocket.Connection`. - -# Testing - -All of this is exhaustively tested. Tests are broken up primarily into `protocol_test.exs`, which -is concerned with aspects of the implementation relating to protocol conformance and -client-facing concerns, while `sock_test.exs` is concerned with aspects of the implementation -having to do with the WebSock API and application-facing concerns. There are also more -unit-style tests covering frame serialization and deserialization. - -In addition, the `autobahn` conformance suite is run via a `System` wrapper & executes the entirety -of the suite against a running Bandit server. diff --git a/deps/bandit/lib/bandit/websocket/connection.ex b/deps/bandit/lib/bandit/websocket/connection.ex deleted file mode 100644 index 4e32d95..0000000 --- a/deps/bandit/lib/bandit/websocket/connection.ex +++ /dev/null @@ -1,312 +0,0 @@ -defmodule Bandit.WebSocket.Connection do - @moduledoc false - # Implementation of a WebSocket lifecycle, implemented using a Socket protocol for communication - - alias Bandit.WebSocket.{Frame, PerMessageDeflate, Socket} - - defstruct websock: nil, - websock_state: nil, - state: :open, - compress: nil, - opts: [], - fragment_frame: nil, - span: nil, - metrics: %{} - - @typedoc "Connection state" - @type state :: :open | :closing | :closed - - @typedoc "Encapsulates the state of a WebSocket connection" - @type t :: %__MODULE__{ - websock: WebSock.impl(), - websock_state: WebSock.state(), - state: state(), - compress: PerMessageDeflate.t() | nil, - opts: keyword(), - fragment_frame: Frame.Text.t() | Frame.Binary.t() | nil, - span: Bandit.Telemetry.t(), - metrics: map() - } - - def init(websock, websock_state, connection_opts, socket) do - compress = Keyword.get(connection_opts, :compress) - - connection_telemetry_span_context = - ThousandIsland.Socket.telemetry_span(socket).telemetry_span_context - - span = - Bandit.Telemetry.start_span(:websocket, %{compress: compress}, %{ - connection_telemetry_span_context: connection_telemetry_span_context, - websock: websock - }) - - instance = %__MODULE__{ - websock: websock, - websock_state: websock_state, - compress: compress, - opts: connection_opts, - span: span - } - - websock.init(websock_state) |> handle_continutation(socket, instance) - end - - def handle_frame(frame, socket, %{fragment_frame: nil} = connection) do - connection = do_recv_metrics(frame, connection) - - case frame do - %Frame.Continuation{} -> - do_error(1002, "Received unexpected continuation frame (RFC6455§5.4)", socket, connection) - - %Frame.Text{fin: true, compressed: true} = frame -> - do_inflate(frame, socket, connection) - - %Frame.Text{fin: true} = frame -> - if !Keyword.get(connection.opts, :validate_text_frames, true) || String.valid?(frame.data) do - connection.websock.handle_in({frame.data, opcode: :text}, connection.websock_state) - |> handle_continutation(socket, connection) - else - do_error(1007, "Received non UTF-8 text frame (RFC6455§8.1)", socket, connection) - end - - %Frame.Text{fin: false} = frame -> - {:continue, %{connection | fragment_frame: frame}} - - %Frame.Binary{fin: true, compressed: true} = frame -> - do_inflate(frame, socket, connection) - - %Frame.Binary{fin: true} = frame -> - connection.websock.handle_in({frame.data, opcode: :binary}, connection.websock_state) - |> handle_continutation(socket, connection) - - %Frame.Binary{fin: false} = frame -> - {:continue, %{connection | fragment_frame: frame}} - - frame -> - handle_control_frame(frame, socket, connection) - end - end - - def handle_frame(frame, socket, %{fragment_frame: fragment_frame} = connection) - when not is_nil(fragment_frame) do - connection = do_recv_metrics(frame, connection) - - case frame do - %Frame.Continuation{fin: true} = frame -> - data = IO.iodata_to_binary([connection.fragment_frame.data | frame.data]) - frame = %{connection.fragment_frame | fin: true, data: data} - handle_frame(frame, socket, %{connection | fragment_frame: nil}) - - %Frame.Continuation{fin: false} = frame -> - data = [connection.fragment_frame.data | frame.data] - frame = %{connection.fragment_frame | fin: true, data: data} - {:continue, %{connection | fragment_frame: frame}} - - %Frame.Text{} -> - do_error(1002, "Received unexpected text frame (RFC6455§5.4)", socket, connection) - - %Frame.Binary{} -> - do_error(1002, "Received unexpected binary frame (RFC6455§5.4)", socket, connection) - - frame -> - handle_control_frame(frame, socket, connection) - end - end - - defp handle_control_frame(frame, socket, connection) do - case frame do - %Frame.ConnectionClose{} = frame -> - # This is a bit of a subtle case, see RFC6455§7.4.1-2 - reply_code = - case frame.code do - code when code in 1000..1003 or code in 1007..1011 or code > 2999 -> 1000 - _code -> 1002 - end - - {:continue, connection} = do_stop(reply_code, :remote, socket, connection) - {:close, %{connection | state: :closed, compress: nil}} - - %Frame.Ping{} = frame -> - connection = - Socket.send_frame(socket, {:pong, frame.data}, false) - |> do_send_metrics(connection) - - if function_exported?(connection.websock, :handle_control, 2) do - connection.websock.handle_control({frame.data, opcode: :ping}, connection.websock_state) - |> handle_continutation(socket, connection) - else - {:continue, connection} - end - - %Frame.Pong{} = frame -> - if function_exported?(connection.websock, :handle_control, 2) do - connection.websock.handle_control({frame.data, opcode: :pong}, connection.websock_state) - |> handle_continutation(socket, connection) - else - {:continue, connection} - end - end - end - - defp do_recv_metrics(frame, connection) do - metrics = - Bandit.WebSocket.Frame.recv_metrics(frame) - |> Enum.reduce(connection.metrics, fn {key, value}, metrics -> - Map.update(metrics, key, value, &(&1 + value)) - end) - - %{connection | metrics: metrics} - end - - defp do_send_metrics(metrics, connection) do - metrics = - metrics - |> Enum.reduce(connection.metrics, fn {key, value}, metrics -> - Map.update(metrics, key, value, &(&1 + value)) - end) - - %{connection | metrics: metrics} - end - - def handle_close(socket, connection), do: do_error(1006, :closed, socket, connection) - - # Some uncertainty if this should be 1000 or 1001 @ https://github.com/mtrudel/bandit/issues/89 - def handle_shutdown(socket, connection), do: do_stop(1000, :shutdown, socket, connection) - - def handle_error({:deserializing, :max_frame_size_exceeded = reason}, socket, connection), - do: do_error(1009, reason, socket, connection) - - def handle_error({:deserializing, reason}, socket, connection), - do: do_error(1002, reason, socket, connection) - - def handle_error(reason, socket, connection), do: do_error(1011, reason, socket, connection) - - def handle_timeout(socket, connection), do: do_error(1002, :timeout, socket, connection) - - def handle_info(msg, socket, connection) do - connection.websock.handle_info(msg, connection.websock_state) - |> handle_continutation(socket, connection) - end - - defp handle_continutation(continutation, socket, connection) do - case continutation do - {:ok, websock_state} -> - {:continue, %{connection | websock_state: websock_state}} - - {:reply, _status, msg, websock_state} -> - do_deflate(msg, socket, %{connection | websock_state: websock_state}) - - {:push, msg, websock_state} -> - do_deflate(msg, socket, %{connection | websock_state: websock_state}) - - {:stop, :normal, websock_state} -> - do_stop(1000, :normal, socket, %{connection | websock_state: websock_state}) - - {:stop, :normal, code, websock_state} -> - do_stop(code, :normal, socket, %{connection | websock_state: websock_state}) - - {:stop, :normal, code, msg, websock_state} -> - case do_deflate(msg, socket, %{connection | websock_state: websock_state}) do - {:continue, connection} -> do_stop(code, :normal, socket, connection) - other -> other - end - - {:stop, {:shutdown, :restart}, websock_state} -> - do_stop(1012, :normal, socket, %{connection | websock_state: websock_state}) - - {:stop, reason, websock_state} -> - do_error(1011, reason, socket, %{connection | websock_state: websock_state}) - - {:stop, reason, code, websock_state} -> - do_error(code, reason, socket, %{connection | websock_state: websock_state}) - - {:stop, reason, code, msg, websock_state} -> - case do_deflate(msg, socket, %{connection | websock_state: websock_state}) do - {:continue, connection} -> do_error(code, reason, socket, connection) - other -> other - end - end - end - - defp do_stop(code, reason, socket, connection) do - if connection.state == :open do - if function_exported?(connection.websock, :terminate, 2) do - connection.websock.terminate(reason, connection.websock_state) - end - - _ = Socket.close(socket, code) - if connection.compress, do: PerMessageDeflate.close(connection.compress) - Bandit.Telemetry.stop_span(connection.span, connection.metrics) - end - - {:continue, %{connection | state: :closing, compress: nil}} - end - - defp do_error(code, reason, socket, connection) do - if connection.state == :open do - if function_exported?(connection.websock, :terminate, 2) do - connection.websock.terminate(maybe_wrap_reason(reason), connection.websock_state) - end - - _ = Socket.close(socket, code) - if connection.compress, do: PerMessageDeflate.close(connection.compress) - Bandit.Telemetry.stop_span(connection.span, connection.metrics, %{error: reason}) - end - - {:error, reason, %{connection | state: :closed, compress: nil}} - end - - defp maybe_wrap_reason(:timeout), do: :timeout - defp maybe_wrap_reason(reason), do: {:error, reason} - - defp do_deflate(msgs, socket, connection) when is_list(msgs) do - Enum.reduce(msgs, {:continue, connection}, fn - msg, {:continue, connection} -> do_deflate(msg, socket, connection) - _msg, other -> other - end) - end - - defp do_deflate({opcode, data} = msg, socket, connection) when opcode in [:text, :binary] do - case PerMessageDeflate.deflate(data, connection.compress) do - {:ok, data, compress} -> - connection = - Socket.send_frame(socket, {opcode, data}, true) - |> do_send_metrics(connection) - - {:continue, %{connection | compress: compress}} - - {:error, :no_compress} -> - connection = - Socket.send_frame(socket, msg, false) - |> do_send_metrics(connection) - - {:continue, connection} - - {:error, reason} -> - do_error(1007, "Deflation error: #{inspect(reason)}", socket, connection) - end - end - - defp do_deflate({opcode, _data} = msg, socket, connection) when opcode in [:ping, :pong] do - connection = - Socket.send_frame(socket, msg, false) - |> do_send_metrics(connection) - - {:continue, connection} - end - - defp do_inflate(frame, socket, connection) do - case PerMessageDeflate.inflate(frame.data, connection.compress) do - {:ok, data, compress} -> - frame = %{frame | data: data, compressed: false} - connection = %{connection | compress: compress} - handle_frame(frame, socket, connection) - - {:error, :no_compress} -> - do_error(1002, "Received unexpected compressed frame (RFC6455§5.2)", socket, connection) - - {:error, _reason} -> - do_error(1007, "Inflation error", socket, connection) - end - end -end diff --git a/deps/bandit/lib/bandit/websocket/frame.ex b/deps/bandit/lib/bandit/websocket/frame.ex deleted file mode 100644 index 1d5b42c..0000000 --- a/deps/bandit/lib/bandit/websocket/frame.ex +++ /dev/null @@ -1,205 +0,0 @@ -defmodule Bandit.WebSocket.Frame do - @moduledoc false - - alias Bandit.WebSocket.Frame - - @behaviour Bandit.Extractor - - @typedoc "Indicates an opcode" - @type opcode :: - (binary :: 0x2) - | (connection_close :: 0x8) - | (continuation :: 0x0) - | (ping :: 0x9) - | (pong :: 0xA) - | (text :: 0x1) - - @typedoc "A valid WebSocket frame" - @type frame :: - Frame.Continuation.t() - | Frame.Text.t() - | Frame.Binary.t() - | Frame.ConnectionClose.t() - | Frame.Ping.t() - | Frame.Pong.t() - - @impl Bandit.Extractor - @spec header_and_payload_length(binary(), non_neg_integer()) :: - {:ok, {header_length :: integer(), payload_length :: integer()}} - | {:error, :max_frame_size_exceeded | :client_frame_without_mask} - | :more - def header_and_payload_length( - <<_fin::1, _compressed::1, _rsv::2, _opcode::4, 1::1, 127::7, length::64, _mask::32, - _rest::binary>>, - max_frame_size - ) do - validate_max_frame_size(14, length, max_frame_size) - end - - def header_and_payload_length( - <<_fin::1, _compressed::1, _rsv::2, _opcode::4, 1::1, 126::7, length::16, _mask::32, - _rest::binary>>, - max_frame_size - ) do - validate_max_frame_size(8, length, max_frame_size) - end - - def header_and_payload_length( - <<_fin::1, _compressed::1, _rsv::2, _opcode::4, 1::1, length::7, _mask::32, - _rest::binary>>, - max_frame_size - ) - when length <= 125 do - validate_max_frame_size(6, length, max_frame_size) - end - - def header_and_payload_length( - <<_fin::1, _compressed::1, _rsv::2, _opcode::4, 0::1, _rest::binary>>, - _max_frame_size - ) do - {:error, :client_frame_without_mask} - end - - def header_and_payload_length(_msg, _max_frame_size) do - :more - end - - defp validate_max_frame_size(header_length, payload_length, max_frame_size) do - if max_frame_size != 0 and header_length + payload_length > max_frame_size do - {:error, :max_frame_size_exceeded} - else - {:ok, {header_length, payload_length}} - end - end - - @impl Bandit.Extractor - @spec deserialize(binary(), module()) :: {:ok, frame()} | {:error, term()} - def deserialize( - <>, - primitive_ops_module - ) do - to_frame(fin, compressed, rsv, opcode, mask, payload, primitive_ops_module) - end - - def deserialize( - <>, - primitive_ops_module - ) do - to_frame(fin, compressed, rsv, opcode, mask, payload, primitive_ops_module) - end - - def deserialize( - <>, - primitive_ops_module - ) do - to_frame(fin, compressed, rsv, opcode, mask, payload, primitive_ops_module) - end - - def deserialize(_msg, _primitive_ops_module) do - {:error, :deserialization_failed} - end - - def recv_metrics(%frame_type{} = frame) do - case frame_type do - Frame.Continuation -> - [ - recv_continuation_frame_count: 1, - recv_continuation_frame_bytes: IO.iodata_length(frame.data) - ] - - Frame.Text -> - [recv_text_frame_count: 1, recv_text_frame_bytes: IO.iodata_length(frame.data)] - - Frame.Binary -> - [recv_binary_frame_count: 1, recv_binary_frame_bytes: IO.iodata_length(frame.data)] - - Frame.ConnectionClose -> - [ - recv_connection_close_frame_count: 1, - recv_connection_close_frame_bytes: IO.iodata_length(frame.reason) - ] - - Frame.Ping -> - [recv_ping_frame_count: 1, recv_ping_frame_bytes: IO.iodata_length(frame.data)] - - Frame.Pong -> - [recv_pong_frame_count: 1, recv_pong_frame_bytes: IO.iodata_length(frame.data)] - end - end - - def send_metrics(%frame_type{} = frame) do - case frame_type do - Frame.Continuation -> - [ - send_continuation_frame_count: 1, - send_continuation_frame_bytes: IO.iodata_length(frame.data) - ] - - Frame.Text -> - [send_text_frame_count: 1, send_text_frame_bytes: IO.iodata_length(frame.data)] - - Frame.Binary -> - [send_binary_frame_count: 1, send_binary_frame_bytes: IO.iodata_length(frame.data)] - - Frame.ConnectionClose -> - [ - send_connection_close_frame_count: 1, - send_connection_close_frame_bytes: IO.iodata_length(frame.reason) - ] - - Frame.Ping -> - [send_ping_frame_count: 1, send_ping_frame_bytes: IO.iodata_length(frame.data)] - - Frame.Pong -> - [send_pong_frame_count: 1, send_pong_frame_bytes: IO.iodata_length(frame.data)] - end - end - - defp to_frame(_fin, _compressed, rsv, _opcode, _mask, _payload, _primitive_ops_module) - when rsv != 0x0 do - {:error, "Received unsupported RSV flags #{rsv}"} - end - - defp to_frame(fin, compressed, 0x0, opcode, mask, payload, primitive_ops_module) do - fin = fin == 0x1 - compressed = compressed == 0x1 - unmasked_payload = primitive_ops_module.ws_mask(payload, mask) - - opcode - |> case do - 0x0 -> Frame.Continuation.deserialize(fin, compressed, unmasked_payload) - 0x1 -> Frame.Text.deserialize(fin, compressed, unmasked_payload) - 0x2 -> Frame.Binary.deserialize(fin, compressed, unmasked_payload) - 0x8 -> Frame.ConnectionClose.deserialize(fin, compressed, unmasked_payload) - 0x9 -> Frame.Ping.deserialize(fin, compressed, unmasked_payload) - 0xA -> Frame.Pong.deserialize(fin, compressed, unmasked_payload) - unknown -> {:error, "unknown opcode #{unknown}"} - end - end - - defprotocol Serializable do - @moduledoc false - - @spec serialize(any()) :: [{Frame.opcode(), boolean(), boolean(), iodata()}] - def serialize(frame) - end - - @spec serialize(frame()) :: iolist() - def serialize(frame) do - frame - |> Serializable.serialize() - |> Enum.map(fn {opcode, fin, compressed, payload} -> - fin = if fin, do: 0x1, else: 0x0 - compressed = if compressed, do: 0x1, else: 0x0 - mask_and_length = payload |> IO.iodata_length() |> mask_and_length() - [<>, mask_and_length, payload] - end) - end - - defp mask_and_length(length) when length <= 125, do: <<0::1, length::7>> - defp mask_and_length(length) when length <= 65_535, do: <<0::1, 126::7, length::16>> - defp mask_and_length(length), do: <<0::1, 127::7, length::64>> -end diff --git a/deps/bandit/lib/bandit/websocket/frame/binary.ex b/deps/bandit/lib/bandit/websocket/frame/binary.ex deleted file mode 100644 index 3041826..0000000 --- a/deps/bandit/lib/bandit/websocket/frame/binary.ex +++ /dev/null @@ -1,20 +0,0 @@ -defmodule Bandit.WebSocket.Frame.Binary do - @moduledoc false - - defstruct fin: nil, compressed: false, data: <<>> - - @typedoc "A WebSocket binary frame" - @type t :: %__MODULE__{fin: boolean(), compressed: boolean(), data: iodata()} - - @spec deserialize(boolean(), boolean(), iodata()) :: {:ok, t()} - def deserialize(fin, compressed, payload) do - {:ok, %__MODULE__{fin: fin, compressed: compressed, data: payload}} - end - - defimpl Bandit.WebSocket.Frame.Serializable do - alias Bandit.WebSocket.Frame - - @spec serialize(@for.t()) :: [{Frame.opcode(), boolean(), boolean(), iodata()}] - def serialize(%@for{} = frame), do: [{0x2, frame.fin, frame.compressed, frame.data}] - end -end diff --git a/deps/bandit/lib/bandit/websocket/frame/connection_close.ex b/deps/bandit/lib/bandit/websocket/frame/connection_close.ex deleted file mode 100644 index b073df1..0000000 --- a/deps/bandit/lib/bandit/websocket/frame/connection_close.ex +++ /dev/null @@ -1,49 +0,0 @@ -defmodule Bandit.WebSocket.Frame.ConnectionClose do - @moduledoc false - - defstruct code: nil, reason: <<>> - - @typedoc "A WebSocket status code, or none at all" - @type status_code :: non_neg_integer() | nil - - @typedoc "A WebSocket connection close frame" - @type t :: %__MODULE__{code: status_code(), reason: binary()} - - @spec deserialize(boolean(), boolean(), iodata()) :: {:ok, t()} | {:error, term()} - def deserialize(true, false, <<>>) do - {:ok, %__MODULE__{}} - end - - def deserialize(true, false, <>) do - {:ok, %__MODULE__{code: code}} - end - - def deserialize(true, false, <>) when byte_size(reason) <= 123 do - if String.valid?(reason) do - {:ok, %__MODULE__{code: code, reason: reason}} - else - {:error, "Received non UTF-8 connection close frame (RFC6455§5.5.1)"} - end - end - - def deserialize(true, false, _payload) do - {:error, "Invalid connection close payload (RFC6455§5.5)"} - end - - def deserialize(false, false, _payload) do - {:error, "Cannot have a fragmented connection close frame (RFC6455§5.5)"} - end - - def deserialize(true, true, _payload) do - {:error, "Cannot have a compressed connection close frame (RFC7692§6.1)"} - end - - defimpl Bandit.WebSocket.Frame.Serializable do - alias Bandit.WebSocket.Frame - - @spec serialize(@for.t()) :: [{Frame.opcode(), boolean(), boolean(), iodata()}] - def serialize(%@for{code: nil}), do: [{0x8, true, false, <<>>}] - def serialize(%@for{reason: nil} = frame), do: [{0x8, true, false, <>}] - def serialize(%@for{} = frame), do: [{0x8, true, false, [<>, frame.reason]}] - end -end diff --git a/deps/bandit/lib/bandit/websocket/frame/continuation.ex b/deps/bandit/lib/bandit/websocket/frame/continuation.ex deleted file mode 100644 index e629851..0000000 --- a/deps/bandit/lib/bandit/websocket/frame/continuation.ex +++ /dev/null @@ -1,24 +0,0 @@ -defmodule Bandit.WebSocket.Frame.Continuation do - @moduledoc false - - defstruct fin: nil, data: <<>> - - @typedoc "A WebSocket continuation frame" - @type t :: %__MODULE__{fin: boolean(), data: iodata()} - - @spec deserialize(boolean(), boolean(), iodata()) :: {:ok, t()} | {:error, term()} - def deserialize(fin, false, payload) do - {:ok, %__MODULE__{fin: fin, data: payload}} - end - - def deserialize(_fin, true, _payload) do - {:error, "Cannot have a compressed continuation frame (RFC7692§6.1)"} - end - - defimpl Bandit.WebSocket.Frame.Serializable do - alias Bandit.WebSocket.Frame - - @spec serialize(@for.t()) :: [{Frame.opcode(), boolean(), boolean(), iodata()}] - def serialize(%@for{} = frame), do: [{0x0, frame.fin, false, frame.data}] - end -end diff --git a/deps/bandit/lib/bandit/websocket/frame/ping.ex b/deps/bandit/lib/bandit/websocket/frame/ping.ex deleted file mode 100644 index 491ee3d..0000000 --- a/deps/bandit/lib/bandit/websocket/frame/ping.ex +++ /dev/null @@ -1,32 +0,0 @@ -defmodule Bandit.WebSocket.Frame.Ping do - @moduledoc false - - defstruct data: <<>> - - @typedoc "A WebSocket ping frame" - @type t :: %__MODULE__{data: iodata()} - - @spec deserialize(boolean(), boolean(), iodata()) :: {:ok, t()} | {:error, term()} - def deserialize(true, false, <>) when byte_size(data) <= 125 do - {:ok, %__MODULE__{data: data}} - end - - def deserialize(true, false, _payload) do - {:error, "Invalid ping payload (RFC6455§5.5.2)"} - end - - def deserialize(false, false, _payload) do - {:error, "Cannot have a fragmented ping frame (RFC6455§5.5.2)"} - end - - def deserialize(true, true, _payload) do - {:error, "Cannot have a compressed ping frame (RFC7692§6.1)"} - end - - defimpl Bandit.WebSocket.Frame.Serializable do - alias Bandit.WebSocket.Frame - - @spec serialize(@for.t()) :: [{Frame.opcode(), boolean(), boolean(), iodata()}] - def serialize(%@for{} = frame), do: [{0x9, true, false, frame.data}] - end -end diff --git a/deps/bandit/lib/bandit/websocket/frame/pong.ex b/deps/bandit/lib/bandit/websocket/frame/pong.ex deleted file mode 100644 index 88eb043..0000000 --- a/deps/bandit/lib/bandit/websocket/frame/pong.ex +++ /dev/null @@ -1,32 +0,0 @@ -defmodule Bandit.WebSocket.Frame.Pong do - @moduledoc false - - defstruct data: <<>> - - @typedoc "A WebSocket pong frame" - @type t :: %__MODULE__{data: iodata()} - - @spec deserialize(boolean(), boolean(), iodata()) :: {:ok, t()} | {:error, term()} - def deserialize(true, false, <>) when byte_size(data) <= 125 do - {:ok, %__MODULE__{data: data}} - end - - def deserialize(true, false, _payload) do - {:error, "Invalid pong payload (RFC6455§5.5.3)"} - end - - def deserialize(false, false, _payload) do - {:error, "Cannot have a fragmented pong frame (RFC6455§5.5.3)"} - end - - def deserialize(true, true, _payload) do - {:error, "Cannot have a compressed pong frame (RFC7692§6.1)"} - end - - defimpl Bandit.WebSocket.Frame.Serializable do - alias Bandit.WebSocket.Frame - - @spec serialize(@for.t()) :: [{Frame.opcode(), boolean(), boolean(), iodata()}] - def serialize(%@for{} = frame), do: [{0xA, true, false, frame.data}] - end -end diff --git a/deps/bandit/lib/bandit/websocket/frame/text.ex b/deps/bandit/lib/bandit/websocket/frame/text.ex deleted file mode 100644 index f2f4fc4..0000000 --- a/deps/bandit/lib/bandit/websocket/frame/text.ex +++ /dev/null @@ -1,20 +0,0 @@ -defmodule Bandit.WebSocket.Frame.Text do - @moduledoc false - - defstruct fin: nil, compressed: false, data: <<>> - - @typedoc "A WebSocket text frame" - @type t :: %__MODULE__{fin: boolean(), compressed: boolean(), data: iodata()} - - @spec deserialize(boolean(), boolean(), iodata()) :: {:ok, t()} - def deserialize(fin, compressed, payload) do - {:ok, %__MODULE__{fin: fin, compressed: compressed, data: payload}} - end - - defimpl Bandit.WebSocket.Frame.Serializable do - alias Bandit.WebSocket.Frame - - @spec serialize(@for.t()) :: [{Frame.opcode(), boolean(), boolean(), iodata()}] - def serialize(%@for{} = frame), do: [{0x1, frame.fin, frame.compressed, frame.data}] - end -end diff --git a/deps/bandit/lib/bandit/websocket/handler.ex b/deps/bandit/lib/bandit/websocket/handler.ex deleted file mode 100644 index 88e39c4..0000000 --- a/deps/bandit/lib/bandit/websocket/handler.ex +++ /dev/null @@ -1,97 +0,0 @@ -defmodule Bandit.WebSocket.Handler do - @moduledoc false - # A WebSocket handler conforming to RFC6455, structured as a ThousandIsland.Handler - - use ThousandIsland.Handler - - alias Bandit.Extractor - alias Bandit.WebSocket.{Connection, Frame} - - @impl ThousandIsland.Handler - def handle_connection(socket, state) do - {websock, websock_opts, connection_opts} = state.upgrade_opts - - connection_opts - |> Keyword.take([:fullsweep_after, :max_heap_size]) - |> Enum.each(fn {key, value} -> :erlang.process_flag(key, value) end) - - connection_opts = Keyword.merge(state.opts.websocket, connection_opts) - - primitive_ops_module = - Keyword.get(state.opts.websocket, :primitive_ops_module, Bandit.PrimitiveOps.WebSocket) - - state = - state - |> Map.take([:handler_module]) - |> Map.put(:extractor, Extractor.new(Frame, primitive_ops_module, connection_opts)) - - case Connection.init(websock, websock_opts, connection_opts, socket) do - {:continue, connection} -> - case Keyword.get(connection_opts, :timeout) do - nil -> {:continue, Map.put(state, :connection, connection)} - timeout -> {:continue, Map.put(state, :connection, connection), {:persistent, timeout}} - end - - {:error, reason, connection} -> - {:error, reason, Map.put(state, :connection, connection)} - end - end - - @impl ThousandIsland.Handler - def handle_data(data, socket, state) do - state.extractor - |> Extractor.push_data(data) - |> pop_frame(socket, state) - end - - defp pop_frame(extractor, socket, state) do - case Extractor.pop_frame(extractor) do - {extractor, {:ok, frame}} -> - case Connection.handle_frame(frame, socket, state.connection) do - {:continue, connection} -> - pop_frame(extractor, socket, %{state | extractor: extractor, connection: connection}) - - {:close, connection} -> - {:close, %{state | extractor: extractor, connection: connection}} - - {:error, reason, connection} -> - {:error, reason, %{state | extractor: extractor, connection: connection}} - end - - {extractor, {:error, reason}} -> - {:error, {:deserializing, reason}, %{state | extractor: extractor}} - - {extractor, :more} -> - {:continue, %{state | extractor: extractor}} - end - end - - @impl ThousandIsland.Handler - def handle_close(socket, %{connection: connection}), - do: Connection.handle_close(socket, connection) - - def handle_close(_socket, _state), do: :ok - - @impl ThousandIsland.Handler - def handle_shutdown(socket, state), do: Connection.handle_shutdown(socket, state.connection) - - @impl ThousandIsland.Handler - def handle_error(reason, socket, state), - do: Connection.handle_error(reason, socket, state.connection) - - @impl ThousandIsland.Handler - def handle_timeout(socket, state), do: Connection.handle_timeout(socket, state.connection) - - def handle_info({:plug_conn, :sent}, {socket, state}), - do: {:noreply, {socket, state}, socket.read_timeout} - - def handle_info(msg, {socket, state}) do - case Connection.handle_info(msg, socket, state.connection) do - {:continue, connection_state} -> - {:noreply, {socket, %{state | connection: connection_state}}, socket.read_timeout} - - {:error, reason, connection_state} -> - {:stop, reason, {socket, %{state | connection: connection_state}}} - end - end -end diff --git a/deps/bandit/lib/bandit/websocket/handshake.ex b/deps/bandit/lib/bandit/websocket/handshake.ex deleted file mode 100644 index a736162..0000000 --- a/deps/bandit/lib/bandit/websocket/handshake.ex +++ /dev/null @@ -1,105 +0,0 @@ -defmodule Bandit.WebSocket.Handshake do - @moduledoc false - # Functions to support WebSocket handshaking as described in RFC6455§4.2 & RFC7692 - - import Plug.Conn - - @type extensions :: [{String.t(), [{String.t(), String.t() | true}]}] - - @spec handshake(Plug.Conn.t(), keyword(), keyword()) :: - {:ok, Plug.Conn.t(), Keyword.t()} | {:error, String.t()} - def handshake(%Plug.Conn{} = conn, opts, websocket_opts) do - with :ok <- Bandit.WebSocket.UpgradeValidation.validate_upgrade(conn) do - do_handshake(conn, opts, websocket_opts) - end - end - - @spec do_handshake(Plug.Conn.t(), keyword(), keyword()) :: {:ok, Plug.Conn.t(), keyword()} - defp do_handshake(conn, opts, websocket_opts) do - requested_extensions = requested_extensions(conn) - - {negotiated_params, returned_data} = - if Keyword.get(opts, :compress) && Keyword.get(websocket_opts, :compress, true) do - Bandit.WebSocket.PerMessageDeflate.negotiate(requested_extensions, websocket_opts) - else - {nil, []} - end - - conn = send_handshake(conn, returned_data) - {:ok, conn, Keyword.put(opts, :compress, negotiated_params)} - end - - @spec requested_extensions(Plug.Conn.t()) :: extensions() - defp requested_extensions(%Plug.Conn{} = conn) do - conn - |> get_req_header("sec-websocket-extensions") - |> Enum.flat_map(&Plug.Conn.Utils.list/1) - |> Enum.map(fn extension -> - [name | params] = - extension - |> String.split(";", trim: true) - |> Enum.map(&String.trim/1) - - params = split_params(params) - - {name, params} - end) - end - - @spec split_params([String.t()]) :: [{String.t(), String.t() | true}] - defp split_params(params) do - params - |> Enum.map(fn param -> - param - |> String.split("=", trim: true) - |> Enum.map(&String.trim/1) - |> case do - [key, value] -> {key, value} - [key] -> {key, true} - end - end) - end - - @spec send_handshake(Plug.Conn.t(), extensions()) :: Plug.Conn.t() - defp send_handshake(%Plug.Conn{} = conn, extensions) do - # Taken from RFC6455§4.2.2/5. Note that we can take for granted the existence of the - # sec-websocket-key header in the request, since we check for it in the handshake? call above - [client_key] = get_req_header(conn, "sec-websocket-key") - concatenated_key = client_key <> "258EAFA5-E914-47DA-95CA-C5AB0DC85B11" - hashed_key = :crypto.hash(:sha, concatenated_key) - server_key = Base.encode64(hashed_key) - - headers = - [ - {:upgrade, "websocket"}, - {:connection, "Upgrade"}, - {:"sec-websocket-accept", server_key} - ] ++ - websocket_extension_header(extensions) ++ - conn.resp_headers - - inform(conn, 101, headers) - end - - @spec websocket_extension_header(extensions()) :: keyword() - defp websocket_extension_header([]), do: [] - - defp websocket_extension_header(extensions) do - extensions = - extensions - |> Enum.map_join(",", fn {extension, params} -> - params = - params - |> Enum.flat_map(fn - {_param, false} -> [] - {param, true} -> [to_string(param)] - {param, value} -> [to_string(param) <> "=" <> to_string(value)] - end) - - [to_string(extension) | params] - |> Enum.join(";") - end) - - [{:"sec-websocket-extensions", extensions}] - end -end diff --git a/deps/bandit/lib/bandit/websocket/permessage_deflate.ex b/deps/bandit/lib/bandit/websocket/permessage_deflate.ex deleted file mode 100644 index dbb2bfc..0000000 --- a/deps/bandit/lib/bandit/websocket/permessage_deflate.ex +++ /dev/null @@ -1,151 +0,0 @@ -defmodule Bandit.WebSocket.PerMessageDeflate do - @moduledoc false - # Support for per-message deflate extension, per RFC7692§7 - - @typedoc "Encapsulates the state of a WebSocket permessage-deflate context" - @type t :: %__MODULE__{ - server_no_context_takeover: boolean(), - client_no_context_takeover: boolean(), - server_max_window_bits: 8..15, - client_max_window_bits: 8..15, - inflate_context: :zlib.zstream(), - deflate_context: :zlib.zstream() - } - - defstruct server_no_context_takeover: false, - client_no_context_takeover: false, - server_max_window_bits: 15, - client_max_window_bits: 15, - inflate_context: nil, - deflate_context: nil - - @valid_params ~w[server_no_context_takeover client_no_context_takeover server_max_window_bits client_max_window_bits] - - def negotiate(requested_extensions, opts) do - :proplists.get_all_values("permessage-deflate", requested_extensions) - |> Enum.find_value(&do_negotiate/1) - |> case do - nil -> {nil, []} - params -> {init(params, opts), "permessage-deflate": params} - end - end - - defp do_negotiate(params) do - with params <- normalize_params(params), - true <- validate_params(params) do - resolve_params(params) - else - _ -> nil - end - end - - defp normalize_params(params) do - params - |> Enum.map(fn - {"server_max_window_bits", true} -> {"server_max_window_bits", true} - {"server_max_window_bits", value} -> {"server_max_window_bits", parse(value)} - {"client_max_window_bits", true} -> {"client_max_window_bits", 15} - {"client_max_window_bits", value} -> {"client_max_window_bits", parse(value)} - value -> value - end) - end - - defp parse(value) do - case Integer.parse(value) do - {int_value, ""} -> int_value - :error -> value - end - end - - defp validate_params(params) do - no_invalid_params = params |> :proplists.split(@valid_params) |> elem(1) == [] - no_repeat_params = params |> :proplists.get_keys() |> length() == length(params) - - no_invalid_values = - :proplists.get_value("server_no_context_takeover", params) in [:undefined, true] && - :proplists.get_value("client_no_context_takeover", params) in [:undefined, true] && - :proplists.get_value("server_max_window_bits", params, 15) in 8..15 && - :proplists.get_value("client_max_window_bits", params, 15) in 8..15 - - no_invalid_params && no_repeat_params && no_invalid_values - end - - # This is where we finally determine which parameters to accept. Note that we don't convert to - # atoms until this stage to avoid potential atom exhaustion - defp resolve_params(params) do - @valid_params - |> Enum.flat_map(fn param_name -> - case :proplists.get_value(param_name, params) do - :undefined -> [] - param -> [{String.to_existing_atom(param_name), param}] - end - end) - end - - defp init(params, opts) do - instance = struct(__MODULE__, params) - inflate_context = :zlib.open() - :ok = :zlib.inflateInit(inflate_context, fix_bits(-instance.client_max_window_bits)) - deflate_context = :zlib.open() - deflate_opts = Keyword.get(opts, :deflate_options, []) - - :ok = - :zlib.deflateInit( - deflate_context, - Keyword.get(deflate_opts, :level, :default), - :deflated, - fix_bits(-instance.server_max_window_bits), - Keyword.get(deflate_opts, :mem_level, 8), - Keyword.get(deflate_opts, :strategy, :default) - ) - - %{instance | inflate_context: inflate_context, deflate_context: deflate_context} - end - - # https://www.erlang.org/doc/man/zlib.html#deflateInit-6 - defp fix_bits(-8), do: -9 - defp fix_bits(other), do: other - - # Note that we pass back the context to the caller even though it is unmodified locally - - def inflate(data, %__MODULE__{} = context) do - inflated_data = - context.inflate_context - |> :zlib.inflate(<>) - |> IO.iodata_to_binary() - - if context.client_no_context_takeover, do: :zlib.inflateReset(context.inflate_context) - {:ok, inflated_data, context} - rescue - e -> {:error, "Error encountered #{inspect(e)}"} - end - - def inflate(_data, nil), do: {:error, :no_compress} - - def deflate(data, %__MODULE__{} = context) do - deflated_data = - context.deflate_context - |> :zlib.deflate(data, :sync) - |> IO.iodata_to_binary() - - deflated_size = byte_size(deflated_data) - 4 - - deflated_data = - case deflated_data do - <> -> deflated_data - deflated -> deflated - end - - if context.server_no_context_takeover, do: :zlib.deflateReset(context.deflate_context) - {:ok, deflated_data, context} - rescue - e -> {:error, "Error encountered #{inspect(e)}"} - end - - def deflate(_data, nil), do: {:error, :no_compress} - - def close(%__MODULE__{} = context) do - :zlib.close(context.inflate_context) - :zlib.close(context.deflate_context) - end -end diff --git a/deps/bandit/lib/bandit/websocket/socket.ex b/deps/bandit/lib/bandit/websocket/socket.ex deleted file mode 100644 index bec73e4..0000000 --- a/deps/bandit/lib/bandit/websocket/socket.ex +++ /dev/null @@ -1,75 +0,0 @@ -defprotocol Bandit.WebSocket.Socket do - @moduledoc false - # - # A protocol defining the low-level functionality of a WebSocket - # - - @type t :: term() - @type frame_type :: :text | :binary | :ping | :pong - @type send_frame_stats :: [ - send_binary_frame_bytes: non_neg_integer(), - send_binary_frame_count: non_neg_integer(), - send_ping_frame_bytes: non_neg_integer(), - send_ping_frame_count: non_neg_integer(), - send_pong_frame_bytes: non_neg_integer(), - send_pong_frame_count: non_neg_integer(), - send_text_frame_bytes: non_neg_integer(), - send_text_frame_count: non_neg_integer() - ] - - @spec send_frame(t(), {frame_type :: frame_type(), data :: iodata()}, boolean()) :: - send_frame_stats() - def send_frame(socket, data_and_frame_type, compressed) - - @spec close(t(), code :: WebSock.close_detail()) :: :ok | {:error, :inet.posix()} - def close(socket, code) -end - -defimpl Bandit.WebSocket.Socket, for: ThousandIsland.Socket do - @moduledoc false - # - # An implementation of Bandit.WebSocket.Socket for use with ThousandIsland.Socket instances - # - - alias Bandit.WebSocket.Frame - - @spec send_frame(@for.t(), {frame_type :: @protocol.frame_type(), data :: iodata()}, boolean()) :: - @protocol.send_frame_stats() - def send_frame(socket, {:text, data}, compressed) do - _ = do_send_frame(socket, %Frame.Text{fin: true, data: data, compressed: compressed}) - [send_text_frame_count: 1, send_text_frame_bytes: IO.iodata_length(data)] - end - - def send_frame(socket, {:binary, data}, compressed) do - _ = do_send_frame(socket, %Frame.Binary{fin: true, data: data, compressed: compressed}) - [send_binary_frame_count: 1, send_binary_frame_bytes: IO.iodata_length(data)] - end - - def send_frame(socket, {:ping, data}, false) do - _ = do_send_frame(socket, %Frame.Ping{data: data}) - [send_ping_frame_count: 1, send_ping_frame_bytes: IO.iodata_length(data)] - end - - def send_frame(socket, {:pong, data}, false) do - _ = do_send_frame(socket, %Frame.Pong{data: data}) - [send_pong_frame_count: 1, send_pong_frame_bytes: IO.iodata_length(data)] - end - - @spec close(@for.t(), non_neg_integer() | {non_neg_integer(), binary()}) :: - :ok | {:error, :inet.posix()} - def close(socket, {code, detail}) when is_integer(code) do - _ = do_send_frame(socket, %Frame.ConnectionClose{code: code, reason: detail}) - @for.shutdown(socket, :write) - end - - def close(socket, code) when is_integer(code) do - _ = do_send_frame(socket, %Frame.ConnectionClose{code: code}) - @for.shutdown(socket, :write) - end - - @spec do_send_frame(@for.t(), Frame.frame()) :: - :ok | {:error, :closed | :timeout | :inet.posix()} - defp do_send_frame(socket, frame) do - @for.send(socket, Frame.serialize(frame)) - end -end diff --git a/deps/bandit/lib/bandit/websocket/upgrade_validation.ex b/deps/bandit/lib/bandit/websocket/upgrade_validation.ex deleted file mode 100644 index 0b67352..0000000 --- a/deps/bandit/lib/bandit/websocket/upgrade_validation.ex +++ /dev/null @@ -1,65 +0,0 @@ -defmodule Bandit.WebSocket.UpgradeValidation do - @moduledoc false - # Provides validation of WebSocket upgrade requests as described in RFC6455§4.2 - - # Validates that the request satisfies the requirements to issue a WebSocket upgrade response. - # Validations are performed based on the clauses laid out in RFC6455§4.2 - # - # This function does not actually perform an upgrade or change the connection in any way - # - # Returns `:ok` if the connection satisfies the requirements for a WebSocket upgrade, and - # `{:error, reason}` if not - # - @spec validate_upgrade(Plug.Conn.t()) :: :ok | {:error, String.t()} - def validate_upgrade(conn) do - case Plug.Conn.get_http_protocol(conn) do - :"HTTP/1.1" -> validate_upgrade_http1(conn) - other -> {:error, "HTTP version #{other} unsupported"} - end - end - - # Validate the conn per RFC6455§4.2.1 - defp validate_upgrade_http1(conn) do - with :ok <- assert_method(conn, "GET"), - :ok <- assert_header_nonempty(conn, "host"), - :ok <- assert_header_contains(conn, "connection", "upgrade"), - :ok <- assert_header_contains(conn, "upgrade", "websocket"), - :ok <- assert_header_nonempty(conn, "sec-websocket-key"), - :ok <- assert_header_equals(conn, "sec-websocket-version", "13") do - :ok - end - end - - defp assert_method(conn, verb) do - case conn.method do - ^verb -> :ok - other -> {:error, "HTTP method #{other} unsupported"} - end - end - - defp assert_header_nonempty(conn, header) do - case Plug.Conn.get_req_header(conn, header) do - [] -> {:error, "'#{header}' header is absent"} - _ -> :ok - end - end - - defp assert_header_equals(conn, header, expected) do - case Plug.Conn.get_req_header(conn, header) |> Enum.map(&String.downcase(&1, :ascii)) do - [^expected] -> :ok - value -> {:error, "'#{header}' header must equal '#{expected}', got #{inspect(value)}"} - end - end - - defp assert_header_contains(conn, header, needle) do - haystack = Plug.Conn.get_req_header(conn, header) - - haystack - |> Enum.flat_map(&Plug.Conn.Utils.list/1) - |> Enum.any?(&(String.downcase(&1, :ascii) == needle)) - |> case do - true -> :ok - false -> {:error, "'#{header}' header must contain '#{needle}', got #{inspect(haystack)}"} - end - end -end diff --git a/deps/bandit/mix.exs b/deps/bandit/mix.exs deleted file mode 100644 index 8562c3d..0000000 --- a/deps/bandit/mix.exs +++ /dev/null @@ -1,95 +0,0 @@ -defmodule Bandit.MixProject do - use Mix.Project - - def project do - [ - app: :bandit, - version: "1.10.3", - elixir: "~> 1.13", - start_permanent: Mix.env() == :prod, - deps: deps(), - elixirc_paths: elixirc_path(Mix.env()), - dialyzer: dialyzer(), - name: "Bandit", - description: "A pure-Elixir HTTP server built for Plug & WebSock apps", - source_url: "https://github.com/mtrudel/bandit", - package: [ - maintainers: ["Mat Trudel"], - licenses: ["MIT"], - links: %{ - "GitHub" => "https://github.com/mtrudel/bandit", - "Changelog" => "https://hexdocs.pm/bandit/changelog.html" - }, - files: ["lib", "mix.exs", "README*", "LICENSE*", "CHANGELOG*"] - ], - docs: docs() - ] - end - - def application do - [extra_applications: [:logger], mod: {Bandit.Application, []}] - end - - defp deps do - [ - {:thousand_island, "~> 1.0"}, - {:plug, "~> 1.18"}, - {:websock, "~> 0.5"}, - {:hpax, "~> 1.0"}, - {:telemetry, "~> 0.4 or ~> 1.0"}, - {:req, "~> 0.3", only: [:dev, :test]}, - {:machete, ">= 0.0.0", only: [:dev, :test]}, - {:ex_doc, "~> 0.24", only: [:dev, :test], runtime: false}, - {:dialyxir, "~> 1.0", only: [:dev, :test], runtime: false}, - {:credo, "~> 1.0", only: [:dev, :test], runtime: false}, - {:mix_test_watch, "~> 1.0", only: :dev, runtime: false} - ] - end - - defp elixirc_path(:test), do: ["lib/", "test/support"] - defp elixirc_path(_), do: ["lib/"] - - defp dialyzer do - [ - plt_core_path: "priv/plts", - plt_file: {:no_warn, "priv/plts/dialyzer.plt"}, - plt_add_deps: :apps_direct, - plt_add_apps: [:ssl, :public_key], - flags: [ - "-Werror_handling", - "-Wextra_return", - "-Wmissing_return", - "-Wunknown", - "-Wunmatched_returns", - "-Wunderspecs" - ] - ] - end - - defp docs do - [ - extras: [ - "CHANGELOG.md": [title: "Changelog"], - "README.md": [title: "README"], - "lib/bandit/http1/README.md": [ - filename: "HTTP1_README.md", - title: "HTTP/1 Implementation Notes" - ], - "lib/bandit/http2/README.md": [ - filename: "HTTP2_README.md", - title: "HTTP/2 Implementation Notes" - ], - "lib/bandit/websocket/README.md": [ - filename: "WebSocket_README.md", - title: "WebSocket Implementation Notes" - ] - ], - groups_for_extras: [ - "Implementation Notes": Path.wildcard("lib/bandit/*/README.md") - ], - skip_undefined_reference_warnings_on: Path.wildcard("**/*.md"), - main: "Bandit", - logo: "assets/ex_doc_logo.png" - ] - end -end diff --git a/deps/hpax/.formatter.exs b/deps/hpax/.formatter.exs deleted file mode 100644 index 8c80937..0000000 --- a/deps/hpax/.formatter.exs +++ /dev/null @@ -1,5 +0,0 @@ -# Used by "mix format" -[ - inputs: ["{mix,.formatter}.exs", "{config,lib,test}/**/*.{ex,exs}"], - import_deps: [:stream_data] -] diff --git a/deps/hpax/.hex b/deps/hpax/.hex deleted file mode 100644 index c24a39e..0000000 Binary files a/deps/hpax/.hex and /dev/null differ diff --git a/deps/hpax/CHANGELOG.md b/deps/hpax/CHANGELOG.md deleted file mode 100644 index 73d4032..0000000 --- a/deps/hpax/CHANGELOG.md +++ /dev/null @@ -1,34 +0,0 @@ -# Changelog - -## v1.0.3 - - * Silence warnings on (upcoming, at this time) Elixir 1.19+. - -## v1.0.2 - - * The changes in v1.0.1 introduced some subtle compression errors with HPACK encoding. This has been fixed in this version. See [this issue](https://github.com/elixir-mint/hpax/issues/20) for more details. - -## v1.0.1 - - * Fix some issues with dynamic table resizing. You should not need to do anything to your code, it should Just Work™. If you want to read more, [this issue](https://github.com/elixir-mint/hpax/issues/18) has all the context. - -## v1.0.0 - - * Silence warnings on Elixir 1.17+. - * Require Elixir 1.12+. - -## v0.2.0 - - * Add `HPAX.new/2`, which supports a list of options. For now, the only option - is `:huffman_encoding`, to choose whether to use Huffman encoding or not. - * Add `HPAX.encode/3`, which supports encoding all headers with the same - action. - * Add the `HPAX.table/0` opaque type. - -## v0.1.2 - - * Fix `use Bitwise` deprecation warning. - -## v0.1.1 - - * Improve checking of dynamic resize updates. diff --git a/deps/hpax/LICENSE.txt b/deps/hpax/LICENSE.txt deleted file mode 100644 index d9a10c0..0000000 --- a/deps/hpax/LICENSE.txt +++ /dev/null @@ -1,176 +0,0 @@ - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS diff --git a/deps/hpax/README.md b/deps/hpax/README.md deleted file mode 100644 index 4cc27f7..0000000 --- a/deps/hpax/README.md +++ /dev/null @@ -1,74 +0,0 @@ -# HPAX - -![CI](https://github.com/elixir-mint/hpax/actions/workflows/main.yml/badge.svg) -[![Docs](https://img.shields.io/badge/api-docs-green.svg?style=flat)](https://hexdocs.pm/hpax) -[![Hex.pm Version](http://img.shields.io/hexpm/v/hpax.svg?style=flat)](https://hex.pm/packages/hpax) -[![Coverage Status](https://coveralls.io/repos/github/elixir-mint/hpax/badge.svg?branch=main)](https://coveralls.io/github/elixir-mint/hpax?branch=main) - -HPAX is an Elixir implementation of the HPACK header compression algorithm as used in HTTP/2 and -defined in RFC 7541. HPAX is used by several Elixir projects, including the -[Mint](https://github.com/elixir-mint/mint) HTTP client and -[bandit](https://github.com/mtrudel/bandit) HTTP server projects. - -## Installation - -To install HPAX, add it to your `mix.exs` file. - -```elixir -defp deps do - [ - {:hpax, "~> 0.1.0"} - ] -end -``` - -Then, run `$ mix deps.get`. - -## Usage - -HPAX is designed to be used in both encoding and decoding scenarios. In both cases, a context is -used to maintain state internal to the HPACK algorithm. In the common use case of using HPAX -within HTTP/2, this context is called a **table** and must be shared between any -subsequent encoding/decoding calls within -an endpoint. Note that the contexts used for encoding and decoding within HTTP/2 are completely -distinct from one another, even though they are structurally identical. - -To encode a set of headers into a binary with HPAX: - -```elixir -context = HPAX.new(4096) -headers = [{:store, ":status", "201"}, {:store, "location", "http://example.com"}] -{encoded_headers, context} = HPAX.encode(headers, context) -#=> {iodata, updated_context} -``` - -To decode a binary into a set of headers with HPAX: - -```elixir -context = HPAX.new(4096) -encoded_headers = <<...>> -{:ok, headers, context} = HPAX.decode(encoded_headers, context) -#=> {:ok, [{:store, ":status", "201"}, {:store, "location", "http://example.com"}], updated_context} -``` - -For complete usage information, please see the HPAX [documentation](https://hex.pm/packages/hpax). - -## Contributing - -If you wish to contribute check out the [issue list](https://github.com/elixir-mint/hpax/issues) and let us know what you want to work on so we can discuss it and reduce duplicate work. - -## License - -Copyright 2021 Eric Meadows-Jönsson and Andrea Leopardi - - 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. diff --git a/deps/hpax/hex_metadata.config b/deps/hpax/hex_metadata.config deleted file mode 100644 index b8f0824..0000000 --- a/deps/hpax/hex_metadata.config +++ /dev/null @@ -1,15 +0,0 @@ -{<<"links">>,[{<<"GitHub">>,<<"https://github.com/elixir-mint/hpax">>}]}. -{<<"name">>,<<"hpax">>}. -{<<"version">>,<<"1.0.3">>}. -{<<"description">>, - <<"Implementation of the HPACK protocol (RFC 7541) for Elixir">>}. -{<<"elixir">>,<<"~> 1.12">>}. -{<<"app">>,<<"hpax">>}. -{<<"licenses">>,[<<"Apache-2.0">>]}. -{<<"requirements">>,[]}. -{<<"files">>, - [<<"lib">>,<<"lib/hpax">>,<<"lib/hpax/huffman_table">>, - <<"lib/hpax/types.ex">>,<<"lib/hpax/huffman.ex">>,<<"lib/hpax/table.ex">>, - <<"lib/hpax.ex">>,<<".formatter.exs">>,<<"mix.exs">>,<<"README.md">>, - <<"LICENSE.txt">>,<<"CHANGELOG.md">>]}. -{<<"build_tools">>,[<<"mix">>]}. diff --git a/deps/hpax/lib/hpax.ex b/deps/hpax/lib/hpax.ex deleted file mode 100644 index 91c9401..0000000 --- a/deps/hpax/lib/hpax.ex +++ /dev/null @@ -1,360 +0,0 @@ -defmodule HPAX do - @moduledoc """ - Support for the HPACK header compression algorithm. - - This module provides support for the HPACK header compression algorithm used mainly in HTTP/2. - - ## Encoding and decoding contexts - - The HPACK algorithm requires both - - * an encoding context on the encoder side - * a decoding context on the decoder side - - These contexts are semantically different but structurally the same. In HPACK they are - implemented as **HPACK tables**. This library uses the name "tables" everywhere internally - - HPACK tables can be created through the `new/1` function. - """ - - alias HPAX.{Table, Types} - - @typedoc """ - An HPACK table. - - This can be used for encoding or decoding. - """ - @typedoc since: "0.2.0" - @opaque table() :: Table.t() - - @typedoc """ - An HPACK header name. - """ - @type header_name() :: binary() - - @typedoc """ - An HPACK header value. - """ - @type header_value() :: binary() - - @valid_header_actions [:store, :store_name, :no_store, :never_store] - - @doc """ - Creates a new HPACK table. - - Same as `new/2` with default options. - """ - @spec new(non_neg_integer()) :: table() - def new(max_table_size), do: new(max_table_size, []) - - @doc """ - Create a new HPACK table that can be used as encoding or decoding context. - - See the "Encoding and decoding contexts" section in the module documentation. - - `max_table_size` is the maximum table size (in bytes) for the newly created table. - - ## Options - - This function accepts the following `options`: - - * `:huffman_encoding` - (since 0.2.0) `:always` or `:never`. If `:always`, - then HPAX will always encode headers using Huffman encoding. If `:never`, - HPAX will not use any Huffman encoding. Defaults to `:never`. - - ## Examples - - encoding_context = HPAX.new(4096) - - """ - @doc since: "0.2.0" - @spec new(non_neg_integer(), [keyword()]) :: table() - def new(max_table_size, options) - when is_integer(max_table_size) and max_table_size >= 0 and is_list(options) do - options = Keyword.put_new(options, :huffman_encoding, :never) - - Enum.each(options, fn - {:huffman_encoding, _huffman_encoding} -> :ok - {key, _value} -> raise ArgumentError, "unknown option: #{inspect(key)}" - end) - - Table.new(max_table_size, Keyword.fetch!(options, :huffman_encoding)) - end - - @doc """ - Resizes the given table to the given maximum size. - - This is intended for use where the overlying protocol has signaled a change to the table's - maximum size, such as when an HTTP/2 `SETTINGS` frame is received. - - If the indicated size is less than the table's current size, entries - will be evicted as needed to fit within the specified size, and the table's - maximum size will be decreased to the specified value. A flag will also be - set which will enqueue a "dynamic table size update" command to be prefixed - to the next block encoded with this table, per - [RFC9113§4.3.1](https://www.rfc-editor.org/rfc/rfc9113.html#section-4.3.1). - - If the indicated size is greater than or equal to the table's current max size, no entries are evicted - and the table's maximum size changes to the specified value. - - ## Examples - - decoding_context = HPAX.new(4096) - HPAX.resize(decoding_context, 8192) - - """ - @spec resize(table(), non_neg_integer()) :: table() - defdelegate resize(table, new_max_size), to: Table - - @doc """ - Decodes a header block fragment (HBF) through a given table. - - If decoding is successful, this function returns a `{:ok, headers, updated_table}` tuple where - `headers` is a list of decoded headers, and `updated_table` is the updated table. If there's - an error in decoding, this function returns `{:error, reason}`. - - ## Examples - - decoding_context = HPAX.new(1000) - hbf = get_hbf_from_somewhere() - HPAX.decode(hbf, decoding_context) - #=> {:ok, [{":method", "GET"}], decoding_context} - - """ - @spec decode(binary(), table()) :: - {:ok, [{header_name(), header_value()}], table()} | {:error, term()} - - # Dynamic resizes must occur only at the start of a block - # https://datatracker.ietf.org/doc/html/rfc7541#section-4.2 - def decode(<<0b001::3, rest::bitstring>>, %Table{} = table) do - {new_max_size, rest} = decode_integer(rest, 5) - - # Dynamic resizes must be less than protocol max table size - # https://datatracker.ietf.org/doc/html/rfc7541#section-6.3 - if new_max_size <= table.protocol_max_table_size do - decode(rest, Table.dynamic_resize(table, new_max_size)) - else - {:error, :protocol_error} - end - end - - def decode(block, %Table{} = table) when is_binary(block) do - decode_headers(block, table, _acc = []) - catch - :throw, {:hpax, error} -> {:error, error} - end - - @doc """ - Encodes a list of headers through the given table. - - Returns a two-element tuple where the first element is a binary representing the encoded headers - and the second element is an updated table. - - ## Examples - - headers = [{:store, ":authority", "https://example.com"}] - encoding_context = HPAX.new(1000) - HPAX.encode(headers, encoding_context) - #=> {iodata, updated_encoding_context} - - """ - @spec encode([header], table()) :: {iodata(), table()} - when header: {action, header_name(), header_value()}, - action: :store | :store_name | :no_store | :never_store - def encode(headers, %Table{} = table) when is_list(headers) do - {table, pending_resizes} = Table.pop_pending_resizes(table) - acc = Enum.map(pending_resizes, &[<<0b001::3, Types.encode_integer(&1, 5)::bitstring>>]) - encode_headers(headers, table, acc) - end - - @doc """ - Encodes a list of headers through the given table, applying the same `action` to all of them. - - This function is the similar to `encode/2`, but `headers` are `{name, value}` tuples instead, - and the same `action` is applied to all headers. - - ## Examples - - headers = [{":authority", "https://example.com"}] - encoding_context = HPAX.new(1000) - HPAX.encode(:store, headers, encoding_context) - #=> {iodata, updated_encoding_context} - - """ - @doc since: "0.2.0" - @spec encode(action, [header], table()) :: {iodata(), table()} - when action: :store | :store_name | :no_store | :never_store, - header: {header_name(), header_value()} - def encode(action, headers, %Table{} = table) - when is_list(headers) and action in [:store, :store_name, :no_store, :never_store] do - headers - |> Enum.map(fn {name, value} -> {action, name, value} end) - |> encode(table) - end - - ## Helpers - - defp decode_headers(<<>>, table, acc) do - {:ok, Enum.reverse(acc), table} - end - - # Indexed header field - # http://httpwg.org/specs/rfc7541.html#rfc.section.6.1 - defp decode_headers(<<0b1::1, rest::bitstring>>, table, acc) do - {index, rest} = decode_integer(rest, 7) - decode_headers(rest, table, [lookup_by_index!(table, index) | acc]) - end - - # Literal header field with incremental indexing - # http://httpwg.org/specs/rfc7541.html#rfc.section.6.2.1 - defp decode_headers(<<0b01::2, rest::bitstring>>, table, acc) do - {name, value, rest} = - case rest do - # The header name is a string. - <<0::6, rest::binary>> -> - {name, rest} = decode_binary(rest) - {value, rest} = decode_binary(rest) - {name, value, rest} - - # The header name is an index to be looked up in the table. - _other -> - {index, rest} = decode_integer(rest, 6) - {value, rest} = decode_binary(rest) - {name, _value} = lookup_by_index!(table, index) - {name, value, rest} - end - - decode_headers(rest, Table.add(table, name, value), [{name, value} | acc]) - end - - # Literal header field without indexing - # http://httpwg.org/specs/rfc7541.html#rfc.section.6.2.2 - defp decode_headers(<<0b0000::4, rest::bitstring>>, table, acc) do - {name, value, rest} = - case rest do - <<0::4, rest::binary>> -> - {name, rest} = decode_binary(rest) - {value, rest} = decode_binary(rest) - {name, value, rest} - - _other -> - {index, rest} = decode_integer(rest, 4) - {value, rest} = decode_binary(rest) - {name, _value} = lookup_by_index!(table, index) - {name, value, rest} - end - - decode_headers(rest, table, [{name, value} | acc]) - end - - # Literal header field never indexed - # http://httpwg.org/specs/rfc7541.html#rfc.section.6.2.3 - defp decode_headers(<<0b0001::4, rest::bitstring>>, table, acc) do - {name, value, rest} = - case rest do - <<0::4, rest::binary>> -> - {name, rest} = decode_binary(rest) - {value, rest} = decode_binary(rest) - {name, value, rest} - - _other -> - {index, rest} = decode_integer(rest, 4) - {value, rest} = decode_binary(rest) - {name, _value} = lookup_by_index!(table, index) - {name, value, rest} - end - - # TODO: enforce the "never indexed" part somehow. - decode_headers(rest, table, [{name, value} | acc]) - end - - defp decode_headers(_other, _table, _acc) do - throw({:hpax, :protocol_error}) - end - - defp lookup_by_index!(table, index) do - case Table.lookup_by_index(table, index) do - {:ok, header} -> header - :error -> throw({:hpax, {:index_not_found, index}}) - end - end - - defp decode_integer(bitstring, prefix) do - case Types.decode_integer(bitstring, prefix) do - {:ok, int, rest} -> {int, rest} - :error -> throw({:hpax, :bad_integer_encoding}) - end - end - - defp decode_binary(binary) do - case Types.decode_binary(binary) do - {:ok, binary, rest} -> {binary, rest} - :error -> throw({:hpax, :bad_binary_encoding}) - end - end - - defp encode_headers([], table, acc) do - {acc, table} - end - - defp encode_headers([{action, name, value} | rest], table, acc) - when action in @valid_header_actions and is_binary(name) and is_binary(value) do - huffman? = table.huffman_encoding == :always - - {encoded, table} = - case Table.lookup_by_header(table, name, value) do - {:full, index} -> - {encode_indexed_header(index), table} - - {:name, index} when action == :store -> - {encode_literal_header_with_indexing(index, value, huffman?), - Table.add(table, name, value)} - - {:name, index} when action in [:store_name, :no_store] -> - {encode_literal_header_without_indexing(index, value, huffman?), table} - - {:name, index} when action == :never_store -> - {encode_literal_header_never_indexed(index, value, huffman?), table} - - :not_found when action in [:store, :store_name] -> - {encode_literal_header_with_indexing(name, value, huffman?), - Table.add(table, name, value)} - - :not_found when action == :no_store -> - {encode_literal_header_without_indexing(name, value, huffman?), table} - - :not_found when action == :never_store -> - {encode_literal_header_never_indexed(name, value, huffman?), table} - end - - encode_headers(rest, table, [acc, encoded]) - end - - defp encode_indexed_header(index) do - <<1::1, Types.encode_integer(index, 7)::bitstring>> - end - - defp encode_literal_header_with_indexing(index, value, huffman?) when is_integer(index) do - [<<1::2, Types.encode_integer(index, 6)::bitstring>>, Types.encode_binary(value, huffman?)] - end - - defp encode_literal_header_with_indexing(name, value, huffman?) when is_binary(name) do - [<<1::2, 0::6>>, Types.encode_binary(name, huffman?), Types.encode_binary(value, huffman?)] - end - - defp encode_literal_header_without_indexing(index, value, huffman?) when is_integer(index) do - [<<0::4, Types.encode_integer(index, 4)::bitstring>>, Types.encode_binary(value, huffman?)] - end - - defp encode_literal_header_without_indexing(name, value, huffman?) when is_binary(name) do - [<<0::4, 0::4>>, Types.encode_binary(name, huffman?), Types.encode_binary(value, huffman?)] - end - - defp encode_literal_header_never_indexed(index, value, huffman?) when is_integer(index) do - [<<1::4, Types.encode_integer(index, 4)::bitstring>>, Types.encode_binary(value, huffman?)] - end - - defp encode_literal_header_never_indexed(name, value, huffman?) when is_binary(name) do - [<<1::4, 0::4>>, Types.encode_binary(name, huffman?), Types.encode_binary(value, huffman?)] - end -end diff --git a/deps/hpax/lib/hpax/huffman.ex b/deps/hpax/lib/hpax/huffman.ex deleted file mode 100644 index e337fab..0000000 --- a/deps/hpax/lib/hpax/huffman.ex +++ /dev/null @@ -1,94 +0,0 @@ -defmodule HPAX.Huffman do - @moduledoc false - - import Bitwise, only: [>>>: 2] - - # This file is downloaded from the spec directly. - # http://httpwg.org/specs/rfc7541.html#huffman.code - table_file = Path.absname("huffman_table", __DIR__) - @external_resource table_file - - entries = - Enum.map(File.stream!(table_file), fn line -> - [byte_value, bits, _hex, bit_count] = - line - |> case do - <> -> rest - "EOS " <> rest -> rest - _other -> line - end - |> String.replace(["|", "(", ")", "[", "]"], "") - |> String.split() - - byte_value = String.to_integer(byte_value) - bits = String.to_integer(bits, 2) - bit_count = String.to_integer(bit_count) - - {byte_value, bits, bit_count} - end) - - {regular_entries, [eos_entry]} = Enum.split(entries, -1) - {_eos_byte_value, eos_bits, eos_bit_count} = eos_entry - - ## Encoding - - @spec encode(binary()) :: binary() - def encode(binary) do - encode(binary, _acc = <<>>) - end - - for {byte_value, bits, bit_count} <- regular_entries do - defp encode(<>, acc) do - encode(rest, <>) - end - end - - defp encode(<<>>, acc) do - overflowing_bits = rem(bit_size(acc), 8) - - if overflowing_bits == 0 do - acc - else - bits_to_add = 8 - overflowing_bits - - value_of_bits_to_add = - take_significant_bits(unquote(eos_bits), unquote(eos_bit_count), bits_to_add) - - <> - end - end - - ## Decoding - - @spec decode(binary()) :: binary() - def decode(binary) - - for {byte_value, bits, bit_count} <- regular_entries do - def decode(<>) do - <> - end - end - - def decode(<<>>) do - <<>> - end - - # Use binary syntax for single match context optimization. - def decode(<>) when bit_size(padding) in 1..7 do - padding_size = bit_size(padding) - <> = padding - - if take_significant_bits(unquote(eos_bits), unquote(eos_bit_count), padding_size) == padding do - <<>> - else - throw({:hpax, {:protocol_error, :invalid_huffman_encoding}}) - end - end - - ## Helpers - - @compile {:inline, take_significant_bits: 3} - defp take_significant_bits(value, bit_count, bits_to_take) do - value >>> (bit_count - bits_to_take) - end -end diff --git a/deps/hpax/lib/hpax/huffman_table b/deps/hpax/lib/hpax/huffman_table deleted file mode 100644 index b116ba3..0000000 --- a/deps/hpax/lib/hpax/huffman_table +++ /dev/null @@ -1,257 +0,0 @@ -( 0) |11111111|11000 1ff8 [13] -( 1) |11111111|11111111|1011000 7fffd8 [23] -( 2) |11111111|11111111|11111110|0010 fffffe2 [28] -( 3) |11111111|11111111|11111110|0011 fffffe3 [28] -( 4) |11111111|11111111|11111110|0100 fffffe4 [28] -( 5) |11111111|11111111|11111110|0101 fffffe5 [28] -( 6) |11111111|11111111|11111110|0110 fffffe6 [28] -( 7) |11111111|11111111|11111110|0111 fffffe7 [28] -( 8) |11111111|11111111|11111110|1000 fffffe8 [28] -( 9) |11111111|11111111|11101010 ffffea [24] -( 10) |11111111|11111111|11111111|111100 3ffffffc [30] -( 11) |11111111|11111111|11111110|1001 fffffe9 [28] -( 12) |11111111|11111111|11111110|1010 fffffea [28] -( 13) |11111111|11111111|11111111|111101 3ffffffd [30] -( 14) |11111111|11111111|11111110|1011 fffffeb [28] -( 15) |11111111|11111111|11111110|1100 fffffec [28] -( 16) |11111111|11111111|11111110|1101 fffffed [28] -( 17) |11111111|11111111|11111110|1110 fffffee [28] -( 18) |11111111|11111111|11111110|1111 fffffef [28] -( 19) |11111111|11111111|11111111|0000 ffffff0 [28] -( 20) |11111111|11111111|11111111|0001 ffffff1 [28] -( 21) |11111111|11111111|11111111|0010 ffffff2 [28] -( 22) |11111111|11111111|11111111|111110 3ffffffe [30] -( 23) |11111111|11111111|11111111|0011 ffffff3 [28] -( 24) |11111111|11111111|11111111|0100 ffffff4 [28] -( 25) |11111111|11111111|11111111|0101 ffffff5 [28] -( 26) |11111111|11111111|11111111|0110 ffffff6 [28] -( 27) |11111111|11111111|11111111|0111 ffffff7 [28] -( 28) |11111111|11111111|11111111|1000 ffffff8 [28] -( 29) |11111111|11111111|11111111|1001 ffffff9 [28] -( 30) |11111111|11111111|11111111|1010 ffffffa [28] -( 31) |11111111|11111111|11111111|1011 ffffffb [28] -' ' ( 32) |010100 14 [ 6] -'!' ( 33) |11111110|00 3f8 [10] -'"' ( 34) |11111110|01 3f9 [10] -'#' ( 35) |11111111|1010 ffa [12] -'$' ( 36) |11111111|11001 1ff9 [13] -'%' ( 37) |010101 15 [ 6] -'&' ( 38) |11111000 f8 [ 8] -''' ( 39) |11111111|010 7fa [11] -'(' ( 40) |11111110|10 3fa [10] -')' ( 41) |11111110|11 3fb [10] -'*' ( 42) |11111001 f9 [ 8] -'+' ( 43) |11111111|011 7fb [11] -',' ( 44) |11111010 fa [ 8] -'-' ( 45) |010110 16 [ 6] -'.' ( 46) |010111 17 [ 6] -'/' ( 47) |011000 18 [ 6] -'0' ( 48) |00000 0 [ 5] -'1' ( 49) |00001 1 [ 5] -'2' ( 50) |00010 2 [ 5] -'3' ( 51) |011001 19 [ 6] -'4' ( 52) |011010 1a [ 6] -'5' ( 53) |011011 1b [ 6] -'6' ( 54) |011100 1c [ 6] -'7' ( 55) |011101 1d [ 6] -'8' ( 56) |011110 1e [ 6] -'9' ( 57) |011111 1f [ 6] -':' ( 58) |1011100 5c [ 7] -';' ( 59) |11111011 fb [ 8] -'<' ( 60) |11111111|1111100 7ffc [15] -'=' ( 61) |100000 20 [ 6] -'>' ( 62) |11111111|1011 ffb [12] -'?' ( 63) |11111111|00 3fc [10] -'@' ( 64) |11111111|11010 1ffa [13] -'A' ( 65) |100001 21 [ 6] -'B' ( 66) |1011101 5d [ 7] -'C' ( 67) |1011110 5e [ 7] -'D' ( 68) |1011111 5f [ 7] -'E' ( 69) |1100000 60 [ 7] -'F' ( 70) |1100001 61 [ 7] -'G' ( 71) |1100010 62 [ 7] -'H' ( 72) |1100011 63 [ 7] -'I' ( 73) |1100100 64 [ 7] -'J' ( 74) |1100101 65 [ 7] -'K' ( 75) |1100110 66 [ 7] -'L' ( 76) |1100111 67 [ 7] -'M' ( 77) |1101000 68 [ 7] -'N' ( 78) |1101001 69 [ 7] -'O' ( 79) |1101010 6a [ 7] -'P' ( 80) |1101011 6b [ 7] -'Q' ( 81) |1101100 6c [ 7] -'R' ( 82) |1101101 6d [ 7] -'S' ( 83) |1101110 6e [ 7] -'T' ( 84) |1101111 6f [ 7] -'U' ( 85) |1110000 70 [ 7] -'V' ( 86) |1110001 71 [ 7] -'W' ( 87) |1110010 72 [ 7] -'X' ( 88) |11111100 fc [ 8] -'Y' ( 89) |1110011 73 [ 7] -'Z' ( 90) |11111101 fd [ 8] -'[' ( 91) |11111111|11011 1ffb [13] -'\' ( 92) |11111111|11111110|000 7fff0 [19] -']' ( 93) |11111111|11100 1ffc [13] -'^' ( 94) |11111111|111100 3ffc [14] -'_' ( 95) |100010 22 [ 6] -'`' ( 96) |11111111|1111101 7ffd [15] -'a' ( 97) |00011 3 [ 5] -'b' ( 98) |100011 23 [ 6] -'c' ( 99) |00100 4 [ 5] -'d' (100) |100100 24 [ 6] -'e' (101) |00101 5 [ 5] -'f' (102) |100101 25 [ 6] -'g' (103) |100110 26 [ 6] -'h' (104) |100111 27 [ 6] -'i' (105) |00110 6 [ 5] -'j' (106) |1110100 74 [ 7] -'k' (107) |1110101 75 [ 7] -'l' (108) |101000 28 [ 6] -'m' (109) |101001 29 [ 6] -'n' (110) |101010 2a [ 6] -'o' (111) |00111 7 [ 5] -'p' (112) |101011 2b [ 6] -'q' (113) |1110110 76 [ 7] -'r' (114) |101100 2c [ 6] -'s' (115) |01000 8 [ 5] -'t' (116) |01001 9 [ 5] -'u' (117) |101101 2d [ 6] -'v' (118) |1110111 77 [ 7] -'w' (119) |1111000 78 [ 7] -'x' (120) |1111001 79 [ 7] -'y' (121) |1111010 7a [ 7] -'z' (122) |1111011 7b [ 7] -'{' (123) |11111111|1111110 7ffe [15] -'|' (124) |11111111|100 7fc [11] -'}' (125) |11111111|111101 3ffd [14] -'~' (126) |11111111|11101 1ffd [13] -(127) |11111111|11111111|11111111|1100 ffffffc [28] -(128) |11111111|11111110|0110 fffe6 [20] -(129) |11111111|11111111|010010 3fffd2 [22] -(130) |11111111|11111110|0111 fffe7 [20] -(131) |11111111|11111110|1000 fffe8 [20] -(132) |11111111|11111111|010011 3fffd3 [22] -(133) |11111111|11111111|010100 3fffd4 [22] -(134) |11111111|11111111|010101 3fffd5 [22] -(135) |11111111|11111111|1011001 7fffd9 [23] -(136) |11111111|11111111|010110 3fffd6 [22] -(137) |11111111|11111111|1011010 7fffda [23] -(138) |11111111|11111111|1011011 7fffdb [23] -(139) |11111111|11111111|1011100 7fffdc [23] -(140) |11111111|11111111|1011101 7fffdd [23] -(141) |11111111|11111111|1011110 7fffde [23] -(142) |11111111|11111111|11101011 ffffeb [24] -(143) |11111111|11111111|1011111 7fffdf [23] -(144) |11111111|11111111|11101100 ffffec [24] -(145) |11111111|11111111|11101101 ffffed [24] -(146) |11111111|11111111|010111 3fffd7 [22] -(147) |11111111|11111111|1100000 7fffe0 [23] -(148) |11111111|11111111|11101110 ffffee [24] -(149) |11111111|11111111|1100001 7fffe1 [23] -(150) |11111111|11111111|1100010 7fffe2 [23] -(151) |11111111|11111111|1100011 7fffe3 [23] -(152) |11111111|11111111|1100100 7fffe4 [23] -(153) |11111111|11111110|11100 1fffdc [21] -(154) |11111111|11111111|011000 3fffd8 [22] -(155) |11111111|11111111|1100101 7fffe5 [23] -(156) |11111111|11111111|011001 3fffd9 [22] -(157) |11111111|11111111|1100110 7fffe6 [23] -(158) |11111111|11111111|1100111 7fffe7 [23] -(159) |11111111|11111111|11101111 ffffef [24] -(160) |11111111|11111111|011010 3fffda [22] -(161) |11111111|11111110|11101 1fffdd [21] -(162) |11111111|11111110|1001 fffe9 [20] -(163) |11111111|11111111|011011 3fffdb [22] -(164) |11111111|11111111|011100 3fffdc [22] -(165) |11111111|11111111|1101000 7fffe8 [23] -(166) |11111111|11111111|1101001 7fffe9 [23] -(167) |11111111|11111110|11110 1fffde [21] -(168) |11111111|11111111|1101010 7fffea [23] -(169) |11111111|11111111|011101 3fffdd [22] -(170) |11111111|11111111|011110 3fffde [22] -(171) |11111111|11111111|11110000 fffff0 [24] -(172) |11111111|11111110|11111 1fffdf [21] -(173) |11111111|11111111|011111 3fffdf [22] -(174) |11111111|11111111|1101011 7fffeb [23] -(175) |11111111|11111111|1101100 7fffec [23] -(176) |11111111|11111111|00000 1fffe0 [21] -(177) |11111111|11111111|00001 1fffe1 [21] -(178) |11111111|11111111|100000 3fffe0 [22] -(179) |11111111|11111111|00010 1fffe2 [21] -(180) |11111111|11111111|1101101 7fffed [23] -(181) |11111111|11111111|100001 3fffe1 [22] -(182) |11111111|11111111|1101110 7fffee [23] -(183) |11111111|11111111|1101111 7fffef [23] -(184) |11111111|11111110|1010 fffea [20] -(185) |11111111|11111111|100010 3fffe2 [22] -(186) |11111111|11111111|100011 3fffe3 [22] -(187) |11111111|11111111|100100 3fffe4 [22] -(188) |11111111|11111111|1110000 7ffff0 [23] -(189) |11111111|11111111|100101 3fffe5 [22] -(190) |11111111|11111111|100110 3fffe6 [22] -(191) |11111111|11111111|1110001 7ffff1 [23] -(192) |11111111|11111111|11111000|00 3ffffe0 [26] -(193) |11111111|11111111|11111000|01 3ffffe1 [26] -(194) |11111111|11111110|1011 fffeb [20] -(195) |11111111|11111110|001 7fff1 [19] -(196) |11111111|11111111|100111 3fffe7 [22] -(197) |11111111|11111111|1110010 7ffff2 [23] -(198) |11111111|11111111|101000 3fffe8 [22] -(199) |11111111|11111111|11110110|0 1ffffec [25] -(200) |11111111|11111111|11111000|10 3ffffe2 [26] -(201) |11111111|11111111|11111000|11 3ffffe3 [26] -(202) |11111111|11111111|11111001|00 3ffffe4 [26] -(203) |11111111|11111111|11111011|110 7ffffde [27] -(204) |11111111|11111111|11111011|111 7ffffdf [27] -(205) |11111111|11111111|11111001|01 3ffffe5 [26] -(206) |11111111|11111111|11110001 fffff1 [24] -(207) |11111111|11111111|11110110|1 1ffffed [25] -(208) |11111111|11111110|010 7fff2 [19] -(209) |11111111|11111111|00011 1fffe3 [21] -(210) |11111111|11111111|11111001|10 3ffffe6 [26] -(211) |11111111|11111111|11111100|000 7ffffe0 [27] -(212) |11111111|11111111|11111100|001 7ffffe1 [27] -(213) |11111111|11111111|11111001|11 3ffffe7 [26] -(214) |11111111|11111111|11111100|010 7ffffe2 [27] -(215) |11111111|11111111|11110010 fffff2 [24] -(216) |11111111|11111111|00100 1fffe4 [21] -(217) |11111111|11111111|00101 1fffe5 [21] -(218) |11111111|11111111|11111010|00 3ffffe8 [26] -(219) |11111111|11111111|11111010|01 3ffffe9 [26] -(220) |11111111|11111111|11111111|1101 ffffffd [28] -(221) |11111111|11111111|11111100|011 7ffffe3 [27] -(222) |11111111|11111111|11111100|100 7ffffe4 [27] -(223) |11111111|11111111|11111100|101 7ffffe5 [27] -(224) |11111111|11111110|1100 fffec [20] -(225) |11111111|11111111|11110011 fffff3 [24] -(226) |11111111|11111110|1101 fffed [20] -(227) |11111111|11111111|00110 1fffe6 [21] -(228) |11111111|11111111|101001 3fffe9 [22] -(229) |11111111|11111111|00111 1fffe7 [21] -(230) |11111111|11111111|01000 1fffe8 [21] -(231) |11111111|11111111|1110011 7ffff3 [23] -(232) |11111111|11111111|101010 3fffea [22] -(233) |11111111|11111111|101011 3fffeb [22] -(234) |11111111|11111111|11110111|0 1ffffee [25] -(235) |11111111|11111111|11110111|1 1ffffef [25] -(236) |11111111|11111111|11110100 fffff4 [24] -(237) |11111111|11111111|11110101 fffff5 [24] -(238) |11111111|11111111|11111010|10 3ffffea [26] -(239) |11111111|11111111|1110100 7ffff4 [23] -(240) |11111111|11111111|11111010|11 3ffffeb [26] -(241) |11111111|11111111|11111100|110 7ffffe6 [27] -(242) |11111111|11111111|11111011|00 3ffffec [26] -(243) |11111111|11111111|11111011|01 3ffffed [26] -(244) |11111111|11111111|11111100|111 7ffffe7 [27] -(245) |11111111|11111111|11111101|000 7ffffe8 [27] -(246) |11111111|11111111|11111101|001 7ffffe9 [27] -(247) |11111111|11111111|11111101|010 7ffffea [27] -(248) |11111111|11111111|11111101|011 7ffffeb [27] -(249) |11111111|11111111|11111111|1110 ffffffe [28] -(250) |11111111|11111111|11111101|100 7ffffec [27] -(251) |11111111|11111111|11111101|101 7ffffed [27] -(252) |11111111|11111111|11111101|110 7ffffee [27] -(253) |11111111|11111111|11111101|111 7ffffef [27] -(254) |11111111|11111111|11111110|000 7fffff0 [27] -(255) |11111111|11111111|11111011|10 3ffffee [26] -EOS (256) |11111111|11111111|11111111|111111 3fffffff [30] diff --git a/deps/hpax/lib/hpax/table.ex b/deps/hpax/lib/hpax/table.ex deleted file mode 100644 index 8873b45..0000000 --- a/deps/hpax/lib/hpax/table.ex +++ /dev/null @@ -1,348 +0,0 @@ -defmodule HPAX.Table do - @moduledoc false - - @enforce_keys [:max_table_size, :huffman_encoding] - defstruct [ - :protocol_max_table_size, - :max_table_size, - :huffman_encoding, - entries: [], - size: 0, - length: 0, - pending_minimum_resize: nil - ] - - @type huffman_encoding() :: :always | :never - - @type t() :: %__MODULE__{ - protocol_max_table_size: non_neg_integer(), - max_table_size: non_neg_integer(), - huffman_encoding: huffman_encoding(), - entries: [{binary(), binary()}], - size: non_neg_integer(), - length: non_neg_integer(), - pending_minimum_resize: non_neg_integer() | nil - } - - @static_table [ - {":authority", nil}, - {":method", "GET"}, - {":method", "POST"}, - {":path", "/"}, - {":path", "/index.html"}, - {":scheme", "http"}, - {":scheme", "https"}, - {":status", "200"}, - {":status", "204"}, - {":status", "206"}, - {":status", "304"}, - {":status", "400"}, - {":status", "404"}, - {":status", "500"}, - {"accept-charset", nil}, - {"accept-encoding", "gzip, deflate"}, - {"accept-language", nil}, - {"accept-ranges", nil}, - {"accept", nil}, - {"access-control-allow-origin", nil}, - {"age", nil}, - {"allow", nil}, - {"authorization", nil}, - {"cache-control", nil}, - {"content-disposition", nil}, - {"content-encoding", nil}, - {"content-language", nil}, - {"content-length", nil}, - {"content-location", nil}, - {"content-range", nil}, - {"content-type", nil}, - {"cookie", nil}, - {"date", nil}, - {"etag", nil}, - {"expect", nil}, - {"expires", nil}, - {"from", nil}, - {"host", nil}, - {"if-match", nil}, - {"if-modified-since", nil}, - {"if-none-match", nil}, - {"if-range", nil}, - {"if-unmodified-since", nil}, - {"last-modified", nil}, - {"link", nil}, - {"location", nil}, - {"max-forwards", nil}, - {"proxy-authenticate", nil}, - {"proxy-authorization", nil}, - {"range", nil}, - {"referer", nil}, - {"refresh", nil}, - {"retry-after", nil}, - {"server", nil}, - {"set-cookie", nil}, - {"strict-transport-security", nil}, - {"transfer-encoding", nil}, - {"user-agent", nil}, - {"vary", nil}, - {"via", nil}, - {"www-authenticate", nil} - ] - - @static_table_size length(@static_table) - @dynamic_table_start @static_table_size + 1 - - @doc """ - Creates a new HPACK table with the given maximum size. - - The maximum size is not the maximum number of entries but rather the maximum size as defined in - http://httpwg.org/specs/rfc7541.html#maximum.table.size. - """ - @spec new(non_neg_integer(), huffman_encoding()) :: t() - def new(protocol_max_table_size, huffman_encoding) - when is_integer(protocol_max_table_size) and protocol_max_table_size >= 0 and - huffman_encoding in [:always, :never] do - %__MODULE__{ - protocol_max_table_size: protocol_max_table_size, - max_table_size: protocol_max_table_size, - huffman_encoding: huffman_encoding - } - end - - @doc """ - Adds the given header to the given table. - - If the new entry does not fit within the max table size then the oldest entries will be evicted. - - Header names should be lowercase when added to the HPACK table - as per the [HTTP/2 spec](https://http2.github.io/http2-spec/#rfc.section.8.1.2): - - > header field names MUST be converted to lowercase prior to their encoding in HTTP/2 - - """ - @spec add(t(), binary(), binary()) :: t() - def add(%__MODULE__{} = table, name, value) do - %{max_table_size: max_table_size, size: size} = table - entry_size = entry_size(name, value) - - cond do - # An attempt to add an entry larger than the maximum size causes the table to be emptied of - # all existing entries and results in an empty table. - entry_size > max_table_size -> - %{table | entries: [], size: 0, length: 0} - - size + entry_size > max_table_size -> - table - |> evict_to_size(max_table_size - entry_size) - |> add_header(name, value, entry_size) - - true -> - add_header(table, name, value, entry_size) - end - end - - defp add_header(%__MODULE__{} = table, name, value, entry_size) do - %{entries: entries, size: size, length: length} = table - %{table | entries: [{name, value} | entries], size: size + entry_size, length: length + 1} - end - - @doc """ - Looks up a header by index `index` in the given `table`. - - Returns `{:ok, {name, value}}` if a header is found at the given `index`, otherwise returns - `:error`. `value` can be a binary in case both the header name and value are present in the - table, or `nil` if only the name is present (this can only happen in the static table). - """ - @spec lookup_by_index(t(), pos_integer()) :: {:ok, {binary(), binary() | nil}} | :error - def lookup_by_index(table, index) - - # Static table - for {header, index} <- Enum.with_index(@static_table, 1) do - def lookup_by_index(%__MODULE__{}, unquote(index)), do: {:ok, unquote(header)} - end - - def lookup_by_index(%__MODULE__{length: 0}, _index) do - :error - end - - def lookup_by_index(%__MODULE__{entries: entries, length: length}, index) - when index >= @dynamic_table_start and index <= @dynamic_table_start + length - 1 do - {:ok, Enum.at(entries, index - @dynamic_table_start)} - end - - def lookup_by_index(%__MODULE__{}, _index) do - :error - end - - @doc """ - Looks up the index of a header by its name and value. - - It returns: - - * `{:full, index}` if the full header (name and value) are present in the table at `index` - - * `{:name, index}` if `name` is present in the table but with a different value than `value` - - * `:not_found` if the header name is not in the table at all - - Header names should be lowercase when looked up in the HPACK table - as per the [HTTP/2 spec](https://http2.github.io/http2-spec/#rfc.section.8.1.2): - - > header field names MUST be converted to lowercase prior to their encoding in HTTP/2 - - """ - @spec lookup_by_header(t(), binary(), binary() | nil) :: - {:full, pos_integer()} | {:name, pos_integer()} | :not_found - def lookup_by_header(table, name, value) - - def lookup_by_header(%__MODULE__{entries: entries}, name, value) do - case static_lookup_by_header(name, value) do - {:full, _index} = result -> - result - - {:name, index} -> - # Check if we get full match in the dynamic tabble - case dynamic_lookup_by_header(entries, name, value, @dynamic_table_start, nil) do - {:full, _index} = result -> result - _other -> {:name, index} - end - - :not_found -> - dynamic_lookup_by_header(entries, name, value, @dynamic_table_start, nil) - end - end - - for {{name, value}, index} when is_binary(value) <- Enum.with_index(@static_table, 1) do - defp static_lookup_by_header(unquote(name), unquote(value)) do - {:full, unquote(index)} - end - end - - static_table_names = - @static_table - |> Enum.map(&elem(&1, 0)) - |> Enum.with_index(1) - |> Enum.uniq_by(&elem(&1, 0)) - - for {name, index} <- static_table_names do - defp static_lookup_by_header(unquote(name), _value) do - {:name, unquote(index)} - end - end - - defp static_lookup_by_header(_name, _value) do - :not_found - end - - defp dynamic_lookup_by_header([{name, value} | _rest], name, value, index, _name_index) do - {:full, index} - end - - defp dynamic_lookup_by_header([{name, _} | rest], name, value, index, _name_index) do - dynamic_lookup_by_header(rest, name, value, index + 1, index) - end - - defp dynamic_lookup_by_header([_other | rest], name, value, index, name_index) do - dynamic_lookup_by_header(rest, name, value, index + 1, name_index) - end - - defp dynamic_lookup_by_header([], _name, _value, _index, name_index) do - if name_index, do: {:name, name_index}, else: :not_found - end - - @doc """ - Changes the table's protocol negotiated maximum size, possibly evicting entries as needed to satisfy. - - If the indicated size is less than the table's current max size, entries - will be evicted as needed to fit within the specified size, and the table's - maximum size will be decreased to the specified value. An will also be - set which will enqueue a 'dynamic table size update' command to be prefixed - to the next block encoded with this table, per RFC9113§4.3.1. - - If the indicated size is greater than or equal to the table's current max size, no entries are evicted - and the table's maximum size changes to the specified value. - - In all cases, the table's `:protocol_max_table_size` is updated accordingly - """ - @spec resize(t(), non_neg_integer()) :: t() - def resize(%__MODULE__{} = table, new_protocol_max_table_size) do - pending_minimum_resize = - case table.pending_minimum_resize do - nil -> new_protocol_max_table_size - current -> min(current, new_protocol_max_table_size) - end - - %{ - evict_to_size(table, new_protocol_max_table_size) - | protocol_max_table_size: new_protocol_max_table_size, - max_table_size: new_protocol_max_table_size, - pending_minimum_resize: pending_minimum_resize - } - end - - def dynamic_resize(%__MODULE__{} = table, new_max_table_size) do - %{ - evict_to_size(table, new_max_table_size) - | max_table_size: new_max_table_size - } - end - - @doc """ - Returns (and clears) any pending resize events on the table which will need to be signalled to - the decoder via dynamic table size update messages. Intended to be called at the start of any - block encode to prepend such dynamic table size update(s) as needed. The value of - `pending_minimum_resize` indicates the smallest maximum size of this table which has not yet - been signalled to the decoder, and is always included in the list returned if it is set. - Additionally, if the current max table size is larger than this value, it is also included int - the list, per https://www.rfc-editor.org/rfc/rfc7541#section-4.2 - """ - def pop_pending_resizes(%__MODULE__{pending_minimum_resize: nil} = table), do: {table, []} - - def pop_pending_resizes(%__MODULE__{} = table) do - pending_resizes = - if table.max_table_size > table.pending_minimum_resize, - do: [table.pending_minimum_resize, table.max_table_size], - else: [table.pending_minimum_resize] - - {%{table | pending_minimum_resize: nil}, pending_resizes} - end - - # Removes records as necessary to have the total size of entries within the table be less than - # or equal to the specified value. Does not change the table's max size. - defp evict_to_size(%__MODULE__{size: size} = table, new_size) when size <= new_size, do: table - - defp evict_to_size(%__MODULE__{entries: entries, size: size} = table, new_size) do - {new_entries_reversed, new_size} = - evict_towards_size(Enum.reverse(entries), size, new_size) - - %{ - table - | entries: Enum.reverse(new_entries_reversed), - size: new_size, - length: length(new_entries_reversed) - } - end - - defp evict_towards_size([{name, value} | rest], size, max_target_size) do - new_size = size - entry_size(name, value) - - if new_size <= max_target_size do - {rest, new_size} - else - evict_towards_size(rest, new_size, max_target_size) - end - end - - defp evict_towards_size([], 0, _max_target_size) do - {[], 0} - end - - defp entry_size(name, value) do - byte_size(name) + byte_size(value) + 32 - end - - # Made public to be used in tests. - @doc false - def __static_table__() do - @static_table - end -end diff --git a/deps/hpax/lib/hpax/types.ex b/deps/hpax/lib/hpax/types.ex deleted file mode 100644 index 8106555..0000000 --- a/deps/hpax/lib/hpax/types.ex +++ /dev/null @@ -1,89 +0,0 @@ -defmodule HPAX.Types do - @moduledoc false - - import Bitwise, only: [<<<: 2] - - alias HPAX.Huffman - - # This is used as a macro and not an inlined function because we want to be able to use it in - # guards. - defmacrop power_of_two(n) do - quote do: 1 <<< unquote(n) - end - - ## Encoding - - @spec encode_integer(non_neg_integer(), 1..8) :: bitstring() - def encode_integer(integer, prefix) - - def encode_integer(integer, prefix) when integer < power_of_two(prefix) - 1 do - <> - end - - def encode_integer(integer, prefix) do - initial = power_of_two(prefix) - 1 - remaining = integer - initial - <> - end - - defp encode_remaining_integer(remaining) when remaining >= 128 do - first = rem(remaining, 128) + 128 - <> - end - - defp encode_remaining_integer(remaining) do - <> - end - - @spec encode_binary(binary(), boolean()) :: iodata() - def encode_binary(binary, huffman?) do - binary = if huffman?, do: Huffman.encode(binary), else: binary - huffman_bit = if huffman?, do: 1, else: 0 - binary_size = encode_integer(byte_size(binary), 7) - [<>, binary] - end - - ## Decoding - - @spec decode_integer(bitstring, 1..8) :: {:ok, non_neg_integer(), binary()} | :error - def decode_integer(bitstring, prefix) when is_bitstring(bitstring) and prefix in 1..8 do - with <> <- bitstring do - if value < power_of_two(prefix) - 1 do - {:ok, value, rest} - else - decode_remaining_integer(rest, value, 0) - end - else - _ -> :error - end - end - - defp decode_remaining_integer(<<0::1, value::7, rest::binary>>, int, m) do - {:ok, int + (value <<< m), rest} - end - - defp decode_remaining_integer(<<1::1, value::7, rest::binary>>, int, m) do - decode_remaining_integer(rest, int + (value <<< m), m + 7) - end - - defp decode_remaining_integer(_, _, _) do - :error - end - - @spec decode_binary(binary) :: {:ok, binary(), binary()} | :error - def decode_binary(binary) when is_binary(binary) do - with <> <- binary, - {:ok, length, rest} <- decode_integer(rest, 7), - <> <- rest do - contents = - case huffman_bit do - 0 -> contents - 1 -> Huffman.decode(contents) - end - - {:ok, contents, rest} - else - _ -> :error - end - end -end diff --git a/deps/hpax/mix.exs b/deps/hpax/mix.exs deleted file mode 100644 index a7ddaed..0000000 --- a/deps/hpax/mix.exs +++ /dev/null @@ -1,54 +0,0 @@ -defmodule HPAX.MixProject do - use Mix.Project - - @version "1.0.3" - @repo_url "https://github.com/elixir-mint/hpax" - - def project do - [ - app: :hpax, - version: @version, - elixir: "~> 1.12", - start_permanent: Mix.env() == :prod, - deps: deps(), - - # Tests - test_coverage: [tool: ExCoveralls], - - # Hex - package: package(), - description: "Implementation of the HPACK protocol (RFC 7541) for Elixir", - - # Docs - name: "HPAX", - docs: [ - source_ref: "v#{@version}", - source_url: @repo_url - ] - ] - end - - def application do - [ - extra_applications: [] - ] - end - - defp deps do - [ - {:ex_doc, "~> 0.34", only: :dev}, - {:hpack, ">= 0.0.0", hex: :hpack_erl, only: :test}, - {:stream_data, "~> 1.0", only: [:dev, :test]}, - {:dialyxir, "~> 1.0", only: [:dev, :test], runtime: false}, - {:excoveralls, "~> 0.18", only: :test}, - {:castore, "~> 1.0", only: :test} - ] - end - - defp package do - [ - licenses: ["Apache-2.0"], - links: %{"GitHub" => @repo_url} - ] - end -end diff --git a/deps/jason/.hex b/deps/jason/.hex deleted file mode 100644 index e2a73f2..0000000 Binary files a/deps/jason/.hex and /dev/null differ diff --git a/deps/jason/CHANGELOG.md b/deps/jason/CHANGELOG.md deleted file mode 100644 index c37dd2a..0000000 --- a/deps/jason/CHANGELOG.md +++ /dev/null @@ -1,132 +0,0 @@ -# Changelog - -## 1.4.4 (26.07.2024) - -* Fix warnings on Elixir 1.17 by conditionally compiling Decimal support - -## 1.4.3 (29.06.2024) - -* Fix derive with _ struct key - -## 1.4.2 (29.06.2024) - -* Fix compiler warnings for Elixir 1.17 - -## 1.4.1 (06.07.2023) - -* Add limit to decoded integer sizes of 1024 digits. This can be changed - with the `decoding_integer_digit_limit` app env config. - -## 1.4.0 (12.09.2022) - -### Enhancements - -* Use the `:erlang.float_to_binary(_, [:short])` function, instead of `io_lib_format.fwrite_g/1` - where available (OTP 24.1+). This provides equivalent output with much less memory used - and significantly improved performance. - -## 1.3.0 (21.12.2021) - -### Enhancements - -* Add the `Jason.OrderedObject` struct -* Support decoding objects preserving all the keys with `objects: :ordered_objects` option -* Support decoding floats to `Decimal` with `floats: :decimals` option -* Add `~j` and `~J` sigils in module `Jason.Sigil` to support writing JSON literals in code - -### Fixes -* Fix error reporting when decoding strings (it was possible to mis-attribute the offending byte) -* Verify fields given to `@derive` - -## 1.2.2 (08.09.2020) - -### Enhancements - -* Support Decimal 2.0 - -## 1.2.1 (04.05.2020) - -### Security - -* Fix `html_safe` escaping in `Jason.encode` - - The ` - -### Erlang - -```erlang -{Event, Ref, Measurements, Metadata} -``` - -### Elixir - -```elixir -{event, ref, measurements, metadata} -``` - - - -## Examples - - - -### Erlang - -An example of a test in Erlang (using [`ct`](https://www.erlang.org/docs/23/man/ct)) could -look like this: - -```erlang -Ref = telemetry_test:attach_event_handlers(self(), [[some, event]]), -function_that_emits_the_event(), -receive - {[some, event], Ref, #{measurement := _}, #{meta := _}} -> - telemetry:detach(Ref) -after 1000 -> - ct:fail(timeout_receive_attach_event_handlers) -end. -``` - -### Elixir - -An example of an ExUnit test in Elixir could look like this: - -```elixir -ref = :telemetry_test.attach_event_handlers(self(), [[:some, :event]]) -function_that_emits_the_event() -assert_received {[:some, :event], ^ref, %{measurement: _}, %{meta: _}} -``` - - - -"""). --spec attach_event_handlers(DestinationPID, Events) -> reference() when - DestinationPID :: pid(), - Events :: [telemetry:event_name(), ...]. -attach_event_handlers(DestPID, Events) when is_pid(DestPID) and is_list(Events) -> - Ref = make_ref(), - Config = #{dest_pid => DestPID, ref => Ref}, - telemetry:attach_many(Ref, Events, fun telemetry_test:handle_event/4, Config), - Ref. - -?DOC(false). -handle_event(Event, Measurements, Metadata, #{dest_pid := DestPID, ref := Ref}) -> - DestPID ! {Event, Ref, Measurements, Metadata}. diff --git a/deps/thousand_island/.hex b/deps/thousand_island/.hex deleted file mode 100644 index ea8641d..0000000 Binary files a/deps/thousand_island/.hex and /dev/null differ diff --git a/deps/thousand_island/CHANGELOG.md b/deps/thousand_island/CHANGELOG.md deleted file mode 100644 index 4c7780a..0000000 --- a/deps/thousand_island/CHANGELOG.md +++ /dev/null @@ -1,328 +0,0 @@ -## 1.4.3 (12 Dec 2025) - -### Enhancements - -* Add support for setting process labels for better observer visibility (#188, thanks @NelsonVides and @nathanl!) -* Improve memory usage and performance (#181 & #182, thanks @NelsonVides!) - -## 1.4.2 (19 Oct 2025) - -### Changes - -* Resolve compiler warnings in Elixir 1.19 (#171, thanks @psantos10!) - -## 1.4.1 (4 Sept 2025) - -### Enhancements - -* Improve performance of SSL sendfile function on larger files (#176, thanks @NelsonVides!) - -## 1.4.0 (22 Aug 2025) - -### Enhancements - -* Add `num_listen_sockets` parameter to allow for improved performance on -specific systems (#174, thanks @NelsonVides!) - -## 1.3.14 (25 May 2025) - -### Enhancements - -* Add support for `ThousandIsland.Socket.connection_information/1` to get info -about the underlying SSL connection, if one is present. - -## 1.3.13 (29 Apr 2025) - -### Enhancements - -* Allow `handle_connection` and `handle_data` callbacks to return tuples to call - `handle_continue` per GenServer conventions (#166) - -## 1.3.12 (21 Mar 2025) - -### Fixes - -* Do not kill off acceptors when encountering an `:einval` socket status (#162, - thanks @marschro!) - -## 1.3.11 (23 Feb 2025) - -### Fixes - -* Properly support `inet_backend` transport option for TCP connections (#155, thanks @paulswartz!) - -## 1.3.10 (17 Feb 2025) - -### Enhancements - -* Add support for `certs_keys` TLS config option (#153, thanks @joshk!) - -## 1.3.9 (6 Jan 2025) - -### Fixes - -* Explicitly ignore several Handler return values to silence Dialyzer in dependent libraries - -## 1.3.8 (5 Jan 2025) - -### Changes - -* Refactor `ThousandIsland.Handler` implementation to facilitate partial reuse -by custom Handler authors (#146 thanks @mruoss!) - -## 1.3.7 (29 Nov 2024) - -### Fixes - -* Use socket as returned from transport handshake (#142, thanks @danielspofford!) - -## 1.3.6 (18 Nov 2024) - -### Fixes - -* Don't consider remote end closure as an error condition for telemetry -* Fix typo & clarify docs (#117) -* Update security policy (#138) - -## 1.3.5 (24 Feb 2024) - -### Fixes - -* Fix regression on non-keyword options (such as `:inet6`) introduced in 1.3.4 - (#113, thanks @danschultzer!) - -## 1.3.4 (23 Feb 2024) - -### Fixes - -* Fix the ability to override default options (and not override hardcoded - options) for both TCP and SSL transports (#111, thanks @moogle19!) - -## 1.3.3 (21 Feb 2024) - -### Changes - -* Do not set `:linger` as a default option on either TCP or SSL transports. This - was causing oddball node hangs on larger instances (#110, thanks @jonjon & - @pojiro!) - -## 1.3.2 (31 Dec 2023) - -### Changes - -* Allow `sni_hosts` or `sni_fun` in place of `cert`/`certfile` and - `key`/`keyfile` - -### Fixes - -* Move `handle_info` fallback clause to module compilation hook (#105) - -## 1.3.1 (30 Dec 2023) - -### Fixes - -* Fix downstream dialyzer error introduced by #86 - -## 1.3.0 (30 Dec 2023) - -### Fixes - -* Fix issue with eventual acceptor starvation when handling certain network - conditions (#103) - -### Enhancements - -* Add check (and logging) for cases where a Handler implementation does not - return the expected state from GenServer handle_* calls (#96, thanks - @elfenlaid!) -* Allow protocol upgrades within an active connection (#86, thanks @icehaunter!) - -### Changes - -* Improve file list for hex packaging (#98, thanks @patrickjaberg and - @wojtekmach!) - -## 1.2.0 (11 Nov 2023) - -### Enhancements - -* Add `supervisor_options` option to specify top-level supervisor options (#97) - -## 1.1.0 (23 Oct 2023) - -### Enhancements - -* Add support for `silent_terminate_on_error` option to run quietly in case of - error (#92) - -## 1.0.0 (18 Oct 2023) - -### Changes - -* Do not consider `ECONNABORTED` errors to be exceptional at socket start time - (#72, thanks @dch!) - -## 1.0.0-pre.7 (12 Aug 2023) - -### Fixes - -* Fix file handle leak when calling `c:Socket.sendfile` (#78) - -## 1.0.0-pre.6 (28 Jun 2023) - -### Enhancements - -* Add support for suspending the acceptance of new requests while continuing to - process existing ones (#70) - -### Changes - -* Drop Elixir 1.12 as a supported target (it should continue to work, but is no - longer covered by CI) - -## 1.0.0-pre.5 (16 Jun 2023) - -### Changes - -* **BREAKING CHANGE** Refactor socket informational functions to mirror the - underlying `:gen_tcp` and `:ssl` APIs (#76, thanks @asakura!). Details: - * Add `ThousandIsland.Socket.sockname/1` - * Add `ThousandIsland.Socket.peername/1` - * Add `ThousandIsland.Socket.peercert/1` - * Remove `ThousandIsland.Socket.local_info/1` - * Remove `ThousandIsland.Socket.peer_info/1` -* Refactor telemetry (#65 thanks @asakura!) - -## 1.0.0-pre.4 (13 Jun 2023) - -### Enhancements - -* Improve typespecs (thanks @asakura!) -* Clean up docs & various internal cleanups (thanks @asakura!) - -## 1.0.0-pre.3 (2 Jun 2023) - -### Enhancements - -* Total overhaul of typespecs throughout the library (thanks @asakura!) -* Internal refactor of several ancillary functions (thanks @asakura!) - -## 1.0.0-pre.2 (3 May 2023) - -### Enhancements - -* Doc improvements - -## 1.0.0-pre.1 (19 Apr 2023) - -### Changes - -* None - -## 0.6.7 (9 Apr 2023) - -### Changes - -* Thousand Island now sets its `id` field in its spec to be `{ThousandIsland, ref()}` -* `num_connections` defaults to 16384 connections per acceptor - -### Enhancements - -* Doc improvements - -## 0.6.6 (7 Apr 2023) - -### Enhancements - -* Added `num_connections` parameter to specify the max number of concurrent - connections allowed per acceptor -* Added `max_connections_retry_count` and `max_connections_retry_wait` - parameters to configure how Thousand Island behaves when max connections are - reached -* Added `[:thousand_island, :acceptor, :spawn_error]` telemetry event to track - when max connections are reached -* Added max connection logging as part of the - `ThousandIsland.Logger.attach_logger(:error)` level - -### Changes - -* Refactored connection startup logic to move some burden from acceptor to - connection process - -## 0.6.5 (27 Mar 2023) - -### Changes - -* Handshake errors no longer loudly crash the handler process -* `handle_error/3` documentation updated to explicitly mention handshake errors - -## 0.6.4 (17 Mar 2023) - -### Changes - -* Modified telemetry event payloads to match the conventions espoused by - `:telemetry.span/3` - -## 0.6.3 (14 Mar 2023) - -### Enhancements - -* Added `shutdown_timeout` configuration parameter to configure how long to wait - for existing connections to shutdown before forcibly killing them at shutdown - -### Changes - -* Default value for `num_acceptors` is now 100 -* Default value for `read_timeout` is now 60000 ms - -### Fixes - -* Added missing documentation for read_timeout configuration parameter - -## 0.6.2 (22 Feb 2023) - -### Fixes - -* Fixes a race condition at application shutdown that caused spurious acceptor - crashes to litter the logs (#44). Thanks @danschultzer! - - -## 0.6.1 (19 Feb 2023) - -### Changes - -* Expose ThousandIsland.Telemetry.t() as a transparent type -* Pass telemetry errors in metadata rather than metrics -* Allow explicit passing of start times into telemetry spans - -## 0.6.0 (4 Feb 2023) - -### Enhancements - -* (Re)introduce telemetry support as specified in the `ThousandIsland.Telemetry` - module - -# Changelog for 0.5.x - -## 0.5.17 (31 Jan 2023) - -### Enhancements - -* Add `ThousandIsland.connection_pids/1` to enumerate connection processes - -## 0.5.16 (21 Jan 2023) - -### Enhancements - -* Narrow internal pattern matches to enable Handlers to use their own socket calls (#39) - -### Fixes - -* Fix documentation typos - -## 0.5.15 (10 Jan 2023) - -### Enhancements - -* Do not emit GenServer crash logs in connection timeout situations -* Doc updates diff --git a/deps/thousand_island/LICENSE b/deps/thousand_island/LICENSE deleted file mode 100644 index bdb77bc..0000000 --- a/deps/thousand_island/LICENSE +++ /dev/null @@ -1,21 +0,0 @@ -MIT License - -Copyright (c) 2018 Mat Trudel - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. diff --git a/deps/thousand_island/README.md b/deps/thousand_island/README.md deleted file mode 100644 index 1f3ec70..0000000 --- a/deps/thousand_island/README.md +++ /dev/null @@ -1,166 +0,0 @@ -![Thousand Island](https://github.com/mtrudel/thousand_island/raw/main/assets/readme_logo.png#gh-light-mode-only) -![Thousand Island](https://github.com/mtrudel/thousand_island/raw/main/assets/readme_logo-white.png#gh-dark-mode-only) - -[![Build Status](https://github.com/mtrudel/thousand_island/workflows/Elixir%20CI/badge.svg)](https://github.com/mtrudel/thousand_island/actions) -[![Docs](https://img.shields.io/badge/api-docs-green.svg?style=flat)](https://hexdocs.pm/thousand_island) -[![Hex.pm](https://img.shields.io/hexpm/v/thousand_island.svg?style=flat&color=blue)](https://hex.pm/packages/thousand_island) - -Thousand Island is a modern, pure Elixir socket server, inspired heavily by -[ranch](https://github.com/ninenines/ranch). It aims to be easy to understand -and reason about, while also being at least as stable and performant as alternatives. -Informal tests place ranch and Thousand Island at roughly the same level of -performance and overhead; short of synthetic scenarios on the busiest of servers, -they perform equally for all intents and purposes. - -Thousand Island is written entirely in Elixir, and is nearly dependency-free (the -only library used is [telemetry](https://github.com/beam-telemetry/telemetry)). -The application strongly embraces OTP design principles, and emphasizes readable, -simple code. The hope is that as much as Thousand Island is capable of backing -the most demanding of services, it is also useful as a simple and approachable -reference for idiomatic OTP design patterns. - -## Usage - -Thousand Island is implemented as a supervision tree which is intended to be hosted -inside a host application, often as a dependency embedded within a higher-level -protocol library such as [Bandit](https://github.com/mtrudel/bandit). Aside from -supervising the Thousand Island process tree, applications interact with Thousand -Island primarily via the -[`ThousandIsland.Handler`](https://hexdocs.pm/thousand_island/ThousandIsland.Handler.html) behaviour. - -### Handlers - -The [`ThousandIsland.Handler`](https://hexdocs.pm/thousand_island/ThousandIsland.Handler.html) behaviour defines the interface that Thousand Island -uses to pass [`ThousandIsland.Socket`](https://hexdocs.pm/thousand_island/ThousandIsland.Socket.html)s up to the application level; together they -form the primary interface that most applications will have with Thousand Island. -Thousand Island comes with a few simple protocol handlers to serve as examples; -these can be found in the [examples](https://github.com/mtrudel/thousand_island/tree/main/examples) -folder of this project. A simple implementation would look like this: - -```elixir -defmodule Echo do - use ThousandIsland.Handler - - @impl ThousandIsland.Handler - def handle_data(data, socket, state) do - ThousandIsland.Socket.send(socket, data) - {:continue, state} - end -end - -{:ok, pid} = ThousandIsland.start_link(port: 1234, handler_module: Echo) -``` - -For more information, please consult the [`ThousandIsland.Handler`](https://hexdocs.pm/thousand_island/ThousandIsland.Handler.html) documentation. - -### Starting a Thousand Island Server - -Thousand Island servers exist as a supervision tree, and are started by a call -to -[`ThousandIsland.start_link/1`](https://hexdocs.pm/thousand_island/ThousandIsland.html#start_link/1). -There are a number of options supported; for a complete description, consult the -[Thousand Island -docs](https://hexdocs.pm/thousand_island/ThousandIsland.html#t:options/0). - -### Connection Draining & Shutdown - -The `ThousandIsland.Server` process is just a standard `Supervisor`, so all the -usual rules regarding shutdown and shutdown timeouts apply. Immediately upon -beginning the shutdown sequence the `ThousandIsland.ShutdownListener` will cause -the listening socket to shut down, which in turn will cause all of the `Acceptor` -processes to shut down as well. At this point all that is left in the supervision -tree are several layers of Supervisors and whatever `Handler` processes were -in progress when shutdown was initiated. At this point, standard Supervisor shutdown -timeout semantics give existing connections a chance to finish things up. `Handler` -processes trap exit, so they continue running beyond shutdown until they either -complete or are `:brutal_kill`ed after their shutdown timeout expires. - -The `shutdown_timeout` configuration option allows for fine grained control of -the shutdown timeout value. It defaults to 15000 ms. - -### Logging & Telemetry - -As a low-level library, Thousand Island purposely does not do any inline -logging of any kind. The [`ThousandIsland.Logger`](https://hexdocs.pm/thousand_island/ThousandIsland.Logger.html) module defines a number of -functions to aid in tracing connections at various log levels, and such logging -can be dynamically enabled and disabled against an already running server. This -logging is backed by telemetry events internally. - -Thousand Island emits a rich set of telemetry events including spans for each -server, acceptor process, and individual client connection. These telemetry -events are documented in the [`ThousandIsland.Telemetry`](https://hexdocs.pm/thousand_island/ThousandIsland.Telemetry.html) module. - -## Implementation Notes - -At a top-level, a `Server` coordinates the processes involved in responding to -connections on a socket. A `Server` manages two top-level processes: a `Listener` -which is responsible for actually binding to the port and managing the resultant -listener socket, and an `AcceptorPoolSupervisor` which is responsible for managing -a pool of `AcceptorSupervisor` processes. - -Each `AcceptorSupervisor` process (there are 100 by default) manages two processes: -an `Acceptor` which accepts connections made to the server's listener socket, -and a `DynamicSupervisor` which supervises the processes backing individual -client connections. Every time a client connects to the server's port, one of -the `Acceptor`s receives the connection in the form of a socket. It then creates -a new process based on the configured handler to manage this connection, and -immediately waits for another connection. It is worth noting that `Acceptor` -processes are long-lived, and normally live for the entire period that the -`Server` is running. - -A handler process is tied to the lifecycle of a client connection, and is -only started when a client connects. The length of its lifetime beyond that of the -underlying connection is dependent on the behaviour of the configured Handler module. -In typical cases its lifetime is directly related to that of the underlying connection. - -This hierarchical approach reduces the time connections spend waiting to be accepted, -and also reduces contention for `DynamicSupervisor` access when creating new -`Handler` processes. Each `AcceptorSupervisor` subtree functions nearly -autonomously, improving scalability and crash resiliency. - -Graphically, this shakes out like so: - -```mermaid -graph TD; - Server(Server: supervisor, rest_for_one)-->Listener; - Server-->AcceptorPoolSupervisor(AcceptorPoolSupervisor: dynamic supervisor); - AcceptorPoolSupervisor--1...n-->AcceptorSupervisor(AcceptorSupervisor: supervisor, rest_for_one) - AcceptorSupervisor-->DynamicSupervisor - AcceptorSupervisor-->Acceptor(Acceptor: task) - DynamicSupervisor--1...n-->Handler(Handler: gen_server) - Server-->ShutdownListener; -``` - -Thousand Island does not use named processes or other 'global' state internally -(other than telemetry event names). It is completely supported for a single node -to host any number of `Server` processes each listening on a different port. - -## Contributing - -Contributions to Thousand Island are very much welcome! Before undertaking any substantial work, please -open an issue on the project to discuss ideas and planned approaches so we can ensure we keep -progress moving in the same direction. - -All contributors must agree and adhere to the project's [Code of -Conduct](https://github.com/mtrudel/thousand_island/blob/main/CODE_OF_CONDUCT.md). - -Security disclosures should be handled per Thousand Island's published [security policy](https://github.com/mtrudel/thousand_island/blob/main/SECURITY.md). - -## Installation - -Thousand Island is [available in Hex](https://hex.pm/packages/thousand_island). The package -can be installed by adding `thousand_island` to your list of dependencies in `mix.exs`: - -```elixir -def deps do - [ - {:thousand_island, "~> 1.0"} - ] -end -``` - -Documentation can be found at [https://hexdocs.pm/thousand_island](https://hexdocs.pm/thousand_island). - -## License - -MIT diff --git a/deps/thousand_island/hex_metadata.config b/deps/thousand_island/hex_metadata.config deleted file mode 100644 index 5bcaec3..0000000 --- a/deps/thousand_island/hex_metadata.config +++ /dev/null @@ -1,35 +0,0 @@ -{<<"links">>, - [{<<"Changelog">>,<<"https://hexdocs.pm/thousand_island/changelog.html">>}, - {<<"GitHub">>,<<"https://github.com/mtrudel/thousand_island">>}]}. -{<<"name">>,<<"thousand_island">>}. -{<<"version">>,<<"1.4.3">>}. -{<<"description">>,<<"A simple & modern pure Elixir socket server">>}. -{<<"elixir">>,<<"~> 1.13">>}. -{<<"app">>,<<"thousand_island">>}. -{<<"licenses">>,[<<"MIT">>]}. -{<<"files">>, - [<<"lib">>,<<"lib/thousand_island.ex">>,<<"lib/thousand_island">>, - <<"lib/thousand_island/telemetry.ex">>, - <<"lib/thousand_island/server_config.ex">>, - <<"lib/thousand_island/logger.ex">>, - <<"lib/thousand_island/shutdown_listener.ex">>, - <<"lib/thousand_island/transports">>, - <<"lib/thousand_island/transports/ssl.ex">>, - <<"lib/thousand_island/transports/tcp.ex">>, - <<"lib/thousand_island/server.ex">>,<<"lib/thousand_island/handler.ex">>, - <<"lib/thousand_island/acceptor_pool_supervisor.ex">>, - <<"lib/thousand_island/acceptor.ex">>, - <<"lib/thousand_island/transport.ex">>,<<"lib/thousand_island/socket.ex">>, - <<"lib/thousand_island/handler_config.ex">>, - <<"lib/thousand_island/listener.ex">>, - <<"lib/thousand_island/process_label.ex">>, - <<"lib/thousand_island/connection.ex">>, - <<"lib/thousand_island/acceptor_supervisor.ex">>,<<"mix.exs">>, - <<"README.md">>,<<"LICENSE">>,<<"CHANGELOG.md">>]}. -{<<"requirements">>, - [[{<<"name">>,<<"telemetry">>}, - {<<"app">>,<<"telemetry">>}, - {<<"optional">>,false}, - {<<"requirement">>,<<"~> 0.4 or ~> 1.0">>}, - {<<"repository">>,<<"hexpm">>}]]}. -{<<"build_tools">>,[<<"mix">>]}. diff --git a/deps/thousand_island/lib/thousand_island.ex b/deps/thousand_island/lib/thousand_island.ex deleted file mode 100644 index a0dfecd..0000000 --- a/deps/thousand_island/lib/thousand_island.ex +++ /dev/null @@ -1,286 +0,0 @@ -defmodule ThousandIsland do - @moduledoc """ - Thousand Island is a modern, pure Elixir socket server, inspired heavily by - [ranch](https://github.com/ninenines/ranch). It aims to be easy to understand - & reason about, while also being at least as stable and performant as alternatives. - - Thousand Island is implemented as a supervision tree which is intended to be hosted - inside a host application, often as a dependency embedded within a higher-level - protocol library such as [Bandit](https://github.com/mtrudel/bandit). Aside from - supervising the Thousand Island process tree, applications interact with Thousand - Island primarily via the `ThousandIsland.Handler` behaviour. - - ## Handlers - - The `ThousandIsland.Handler` behaviour defines the interface that Thousand Island - uses to pass `ThousandIsland.Socket`s up to the application level; together they - form the primary interface that most applications will have with Thousand Island. - Thousand Island comes with a few simple protocol handlers to serve as examples; - these can be found in the [examples](https://github.com/mtrudel/thousand_island/tree/main/examples) - folder of this project. A simple implementation would look like this: - - ```elixir - defmodule Echo do - use ThousandIsland.Handler - - @impl ThousandIsland.Handler - def handle_data(data, socket, state) do - ThousandIsland.Socket.send(socket, data) - {:continue, state} - end - end - - {:ok, pid} = ThousandIsland.start_link(port: 1234, handler_module: Echo) - ``` - - For more information, please consult the `ThousandIsland.Handler` documentation. - - ## Starting a Thousand Island Server - - A typical use of `ThousandIsland` might look like the following: - - ```elixir - defmodule MyApp.Supervisor do - # ... other Supervisor boilerplate - - def init(config) do - children = [ - # ... other children as dictated by your app - {ThousandIsland, port: 1234, handler_module: MyApp.ConnectionHandler} - ] - - Supervisor.init(children, strategy: :one_for_one) - end - end - ``` - - You can also start servers directly via the `start_link/1` function: - - ```elixir - {:ok, pid} = ThousandIsland.start_link(port: 1234, handler_module: MyApp.ConnectionHandler) - ``` - - ## Configuration - - A number of options are defined when starting a server. The complete list is - defined by the `t:ThousandIsland.options/0` type. - - ## Connection Draining & Shutdown - - `ThousandIsland` instances are just a process tree consisting of standard - `Supervisor`, `GenServer` and `Task` modules, and so the usual rules regarding - shutdown and shutdown timeouts apply. Immediately upon beginning the shutdown - sequence the ThousandIsland.ShutdownListener process will cause the listening - socket to shut down, which in turn will cause all of the - ThousandIsland.Acceptor processes to shut down as well. At this point all that - is left in the supervision tree are several layers of Supervisors and whatever - `Handler` processes were in progress when shutdown was initiated. At this - point, standard `Supervisor` shutdown timeout semantics give existing - connections a chance to finish things up. `Handler` processes trap exit, so - they continue running beyond shutdown until they either complete or are - `:brutal_kill`ed after their shutdown timeout expires. - - ## Logging & Telemetry - - As a low-level library, Thousand Island purposely does not do any inline - logging of any kind. The `ThousandIsland.Logger` module defines a number of - functions to aid in tracing connections at various log levels, and such logging - can be dynamically enabled and disabled against an already running server. This - logging is backed by telemetry events internally. - - Thousand Island emits a rich set of telemetry events including spans for each - server, acceptor process, and individual client connection. These telemetry - events are documented in the `ThousandIsland.Telemetry` module. - """ - - @typedoc """ - Possible options to configure a server. Valid option values are as follows: - - * `handler_module`: The name of the module used to handle connections to this server. - The module is expected to implement the `ThousandIsland.Handler` behaviour. Required - * `handler_options`: A term which is passed as the initial state value to - `c:ThousandIsland.Handler.handle_connection/2` calls. Optional, defaulting to nil - * `port`: The TCP port number to listen on. If not specified this defaults to 4000. - If a port number of `0` is given, the server will dynamically assign a port number - which can then be obtained via `ThousandIsland.listener_info/1` or - `ThousandIsland.Socket.sockname/1` - * `transport_module`: The name of the module which provides basic socket functions. - Thousand Island provides `ThousandIsland.Transports.TCP` and `ThousandIsland.Transports.SSL`, - which provide clear and TLS encrypted TCP sockets respectively. If not specified this - defaults to `ThousandIsland.Transports.TCP` - * `transport_options`: A keyword list of options to be passed to the transport module's - `c:ThousandIsland.Transport.listen/2` function. Valid values depend on the transport - module specified in `transport_module` and can be found in the documentation for the - `ThousandIsland.Transports.TCP` and `ThousandIsland.Transports.SSL` modules. Any options - in terms of interfaces to listen to / certificates and keys to use for SSL connections - will be passed in via this option - * `genserver_options`: A term which is passed as the option value to the handler module's - underlying `GenServer.start_link/3` call. Optional, defaulting to `[]` - * `supervisor_options`: A term which is passed as the option value to this server's top-level - supervisor's `Supervisor.start_link/3` call. Useful for setting the `name` for this server. - Optional, defaulting to `[]` - * `num_acceptors`: The number of acceptor processes to run. Defaults to 100 - * `num_listen_sockets`: The number of listener sockets to create. When set to a value greater - than 1, multiple listener sockets will be created to distribute incoming connections across - multiple sockets for improved performance on multi-core systems. This requires setting either - `reuseport: true` or `reuseport_lb: true` in the `transport_options`, and will only work on - systems that support such socket functionality (most modern Unix-like systems). If the system - does not support the required socket options, server startup will fail. This value must be - less than or equal to `num_acceptors`. Defaults to 1 - * `num_connections`: The maximum number of concurrent connections which each acceptor will - accept before throttling connections. Connections will be throttled by having the acceptor - process wait `max_connections_retry_wait` milliseconds, up to `max_connections_retry_count` - times for existing connections to terminate & make room for this new connection. If there is - still no room for this new connection after this interval, the acceptor will close the client - connection and emit a `[:thousand_island, :acceptor, :spawn_error]` telemetry event. This number - is expressed per-acceptor, so the total number of maximum connections for a Thousand Island - server is `num_acceptors * num_connections`. Defaults to `16_384` - * `max_connections_retry_wait`: How long to wait during each iteration as described in - `num_connectors` above, in milliseconds. Defaults to `1000` - * `max_connections_retry_count`: How many iterations to wait as described in `num_connectors` - above. Defaults to `5` - * `read_timeout`: How long to wait for client data before closing the connection, in - milliseconds. Defaults to 60_000 - * `shutdown_timeout`: How long to wait for existing client connections to complete before - forcibly shutting those connections down at server shutdown time, in milliseconds. Defaults to - 15_000. May also be `:infinity` or `:brutal_kill` as described in the `Supervisor` - documentation - * `silent_terminate_on_error`: Whether to silently ignore errors returned by the handler or to - surface them to the runtime via an abnormal termination result. This only applies to errors - returned via `{:error, reason, state}` responses; exceptions raised within a handler are always - logged regardless of this value. Note also that telemetry events will always be sent for errors - regardless of this value. Defaults to false - """ - @type options :: [ - handler_module: module(), - handler_options: term(), - genserver_options: GenServer.options(), - supervisor_options: [Supervisor.option()], - port: :inet.port_number(), - transport_module: module(), - transport_options: transport_options(), - num_acceptors: pos_integer(), - num_listen_sockets: pos_integer(), - num_connections: non_neg_integer() | :infinity, - max_connections_retry_count: non_neg_integer(), - max_connections_retry_wait: timeout(), - read_timeout: timeout(), - shutdown_timeout: timeout(), - silent_terminate_on_error: boolean() - ] - - @typedoc "A module implementing `ThousandIsland.Transport` behaviour" - @type transport_module :: ThousandIsland.Transports.TCP | ThousandIsland.Transports.SSL - - @typedoc "A keyword list of options to be passed to the transport module's `listen/2` function" - @type transport_options() :: - ThousandIsland.Transports.TCP.options() | ThousandIsland.Transports.SSL.options() - - @doc false - @spec child_spec(options()) :: Supervisor.child_spec() - def child_spec(opts) do - %{ - id: {__MODULE__, make_ref()}, - start: {__MODULE__, :start_link, [opts]}, - type: :supervisor, - restart: :permanent - } - end - - @doc """ - Starts a `ThousandIsland` instance with the given options. Returns a pid - that can be used to further manipulate the server via other functions defined on - this module in the case of success, or an error tuple describing the reason the - server was unable to start in the case of failure. - """ - @spec start_link(options()) :: Supervisor.on_start() - def start_link(opts \\ []) do - opts - |> ThousandIsland.ServerConfig.new() - |> ThousandIsland.Server.start_link() - end - - @doc """ - Returns information about the address and port that the server is listening on - """ - @spec listener_info(Supervisor.supervisor()) :: - {:ok, ThousandIsland.Transport.socket_info()} | :error - def listener_info(supervisor) do - case ThousandIsland.Server.listener_pid(supervisor) do - nil -> :error - pid -> {:ok, ThousandIsland.Listener.listener_info(pid)} - end - end - - @doc """ - Gets a list of active connection processes. This is inherently a bit of a leaky notion in the - face of concurrency, as there may be connections coming and going during the period that this - function takes to run. Callers should account for the possibility that new connections may have - been made since / during this call, and that processes returned by this call may have since - completed. The order that connection processes are returned in is not specified - """ - @spec connection_pids(Supervisor.supervisor()) :: {:ok, [pid()]} | :error - def connection_pids(supervisor) do - case ThousandIsland.Server.acceptor_pool_supervisor_pid(supervisor) do - nil -> :error - acceptor_pool_pid -> {:ok, collect_connection_pids(acceptor_pool_pid)} - end - end - - @doc """ - Suspend the server. This will close the listening port, and will stop the acceptance of new - connections. Existing connections will stay connected and will continue to be processed. - - The server can later be resumed by calling `resume/1`, or shut down via standard supervision - patterns. - - If this function returns `:error`, it is unlikely that the server is in a useable state - - Note that if you do not explicitly set a port (or if you set port to `0`), then the server will - bind to a different port when you resume it. This new port can be obtained as usual via the - `listener_info/1` function. This is not a concern if you explicitly set a port value when first - instantiating the server - """ - defdelegate suspend(supervisor), to: ThousandIsland.Server - - @doc """ - Resume a suspended server. This will reopen the listening port, and resume the acceptance of new - connections - """ - defdelegate resume(supervisor), to: ThousandIsland.Server - - defp collect_connection_pids(acceptor_pool_pid) do - acceptor_pool_pid - |> ThousandIsland.AcceptorPoolSupervisor.acceptor_supervisor_pids() - |> Enum.reduce([], fn acceptor_sup_pid, acc -> - case ThousandIsland.AcceptorSupervisor.connection_sup_pid(acceptor_sup_pid) do - nil -> acc - connection_sup_pid -> connection_pids(connection_sup_pid, acc) - end - end) - end - - defp connection_pids(connection_sup_pid, acc) do - connection_sup_pid - |> DynamicSupervisor.which_children() - |> Enum.reduce(acc, fn - {_, connection_pid, _, _}, acc when is_pid(connection_pid) -> - [connection_pid | acc] - - _, acc -> - acc - end) - end - - @doc """ - Synchronously stops the given server, waiting up to the given number of milliseconds - for existing connections to finish up. Immediately upon calling this function, - the server stops listening for new connections, and then proceeds to wait until - either all existing connections have completed or the specified timeout has - elapsed. - """ - @spec stop(Supervisor.supervisor(), timeout()) :: :ok - def stop(supervisor, connection_wait \\ 15_000) do - Supervisor.stop(supervisor, :normal, connection_wait) - end -end diff --git a/deps/thousand_island/lib/thousand_island/acceptor.ex b/deps/thousand_island/lib/thousand_island/acceptor.ex deleted file mode 100644 index f7c476c..0000000 --- a/deps/thousand_island/lib/thousand_island/acceptor.ex +++ /dev/null @@ -1,77 +0,0 @@ -defmodule ThousandIsland.Acceptor do - @moduledoc false - - use Task, restart: :transient - - @spec start_link( - {server :: Supervisor.supervisor(), parent :: Supervisor.supervisor(), pos_integer(), - ThousandIsland.ServerConfig.t()} - ) :: {:ok, pid()} - def start_link(arg), do: Task.start_link(__MODULE__, :run, [arg]) - - @spec run( - {server :: Supervisor.supervisor(), parent :: Supervisor.supervisor(), pos_integer(), - ThousandIsland.ServerConfig.t()} - ) :: no_return - def run({server_pid, parent_pid, acceptor_id, %ThousandIsland.ServerConfig{} = server_config}) do - ThousandIsland.ProcessLabel.set(:acceptor, server_config, acceptor_id) - - listener_pid = ThousandIsland.Server.listener_pid(server_pid) - - {listener_socket, listener_span} = - ThousandIsland.Listener.acceptor_info(listener_pid, acceptor_id) - - connection_sup_pid = ThousandIsland.AcceptorSupervisor.connection_sup_pid(parent_pid) - acceptor_span = ThousandIsland.Telemetry.start_child_span(listener_span, :acceptor) - - # Pre-create the handler config once to avoid Map.take on every connection (hot path) - handler_config = ThousandIsland.HandlerConfig.from_server_config(server_config) - - accept(listener_socket, connection_sup_pid, server_config, handler_config, acceptor_span, 0) - end - - defp accept(listener_socket, connection_sup_pid, server_config, handler_config, span, count) do - with {:ok, socket} <- server_config.transport_module.accept(listener_socket), - :ok <- - ThousandIsland.Connection.start( - connection_sup_pid, - socket, - server_config, - handler_config, - span - ) do - accept(listener_socket, connection_sup_pid, server_config, handler_config, span, count + 1) - else - {:error, :too_many_connections} -> - ThousandIsland.Telemetry.span_event(span, :spawn_error) - - accept( - listener_socket, - connection_sup_pid, - server_config, - handler_config, - span, - count + 1 - ) - - {:error, reason} when reason in [:econnaborted, :einval] -> - ThousandIsland.Telemetry.span_event(span, reason) - - accept( - listener_socket, - connection_sup_pid, - server_config, - handler_config, - span, - count + 1 - ) - - {:error, :closed} -> - ThousandIsland.Telemetry.stop_span(span, %{connections: count}) - - {:error, reason} -> - ThousandIsland.Telemetry.stop_span(span, %{connections: count}, %{error: reason}) - raise "Unexpected error in accept: #{inspect(reason)}" - end - end -end diff --git a/deps/thousand_island/lib/thousand_island/acceptor_pool_supervisor.ex b/deps/thousand_island/lib/thousand_island/acceptor_pool_supervisor.ex deleted file mode 100644 index dd230ca..0000000 --- a/deps/thousand_island/lib/thousand_island/acceptor_pool_supervisor.ex +++ /dev/null @@ -1,54 +0,0 @@ -defmodule ThousandIsland.AcceptorPoolSupervisor do - @moduledoc false - - use Supervisor - - @spec start_link({server_pid :: pid, ThousandIsland.ServerConfig.t()}) :: Supervisor.on_start() - def start_link(arg) do - Supervisor.start_link(__MODULE__, arg) - end - - @spec acceptor_supervisor_pids(Supervisor.supervisor()) :: [pid()] - def acceptor_supervisor_pids(supervisor) do - supervisor - |> Supervisor.which_children() - |> Enum.reduce([], fn - {_, acceptor_pid, _, _}, acc when is_pid(acceptor_pid) -> [acceptor_pid | acc] - _, acc -> acc - end) - end - - @spec suspend(Supervisor.supervisor()) :: :ok | :error - def suspend(pid) do - pid - |> acceptor_supervisor_pids() - |> Enum.map(&ThousandIsland.AcceptorSupervisor.suspend/1) - |> Enum.all?(&(&1 == :ok)) - |> if(do: :ok, else: :error) - end - - @spec resume(Supervisor.supervisor()) :: :ok | :error - def resume(pid) do - pid - |> acceptor_supervisor_pids() - |> Enum.map(&ThousandIsland.AcceptorSupervisor.resume/1) - |> Enum.all?(&(&1 == :ok)) - |> if(do: :ok, else: :error) - end - - @impl Supervisor - @spec init({server_pid :: pid, ThousandIsland.ServerConfig.t()}) :: - {:ok, - {Supervisor.sup_flags(), - [Supervisor.child_spec() | (old_erlang_child_spec :: :supervisor.child_spec())]}} - def init({server_pid, %ThousandIsland.ServerConfig{num_acceptors: num_acceptors} = config}) do - ThousandIsland.ProcessLabel.set(:acceptor_pool_supervisor, config) - - 1..num_acceptors - |> Enum.map(fn acceptor_id -> - child_spec = {ThousandIsland.AcceptorSupervisor, {server_pid, acceptor_id, config}} - Supervisor.child_spec(child_spec, id: "acceptor-#{acceptor_id}") - end) - |> Supervisor.init(strategy: :one_for_one) - end -end diff --git a/deps/thousand_island/lib/thousand_island/acceptor_supervisor.ex b/deps/thousand_island/lib/thousand_island/acceptor_supervisor.ex deleted file mode 100644 index 4ebea87..0000000 --- a/deps/thousand_island/lib/thousand_island/acceptor_supervisor.ex +++ /dev/null @@ -1,59 +0,0 @@ -defmodule ThousandIsland.AcceptorSupervisor do - @moduledoc false - - use Supervisor - - @spec start_link({server_pid :: pid, pos_integer(), ThousandIsland.ServerConfig.t()}) :: - Supervisor.on_start() - def start_link(arg) do - Supervisor.start_link(__MODULE__, arg) - end - - @spec connection_sup_pid(Supervisor.supervisor()) :: pid() | nil - def connection_sup_pid(supervisor) do - supervisor - |> Supervisor.which_children() - |> Enum.find_value(fn - {:connection_sup, connection_sup_pid, _, _} when is_pid(connection_sup_pid) -> - connection_sup_pid - - _ -> - false - end) - end - - @spec suspend(Supervisor.supervisor()) :: :ok | :error - def suspend(pid) do - case Supervisor.terminate_child(pid, :acceptor) do - :ok -> :ok - {:error, :not_found} -> :error - end - end - - @spec resume(Supervisor.supervisor()) :: :ok | :error - def resume(pid) do - case Supervisor.restart_child(pid, :acceptor) do - {:ok, _child} -> :ok - {:error, reason} when reason in [:running, :restarting] -> :ok - {:error, _reason} -> :error - end - end - - @impl Supervisor - @spec init({server_pid :: pid, pos_integer(), ThousandIsland.ServerConfig.t()}) :: - {:ok, - {Supervisor.sup_flags(), - [Supervisor.child_spec() | (old_erlang_child_spec :: :supervisor.child_spec())]}} - def init({server_pid, acceptor_id, %ThousandIsland.ServerConfig{} = config}) do - ThousandIsland.ProcessLabel.set(:acceptor_supervisor, config) - - children = [ - {DynamicSupervisor, strategy: :one_for_one, max_children: config.num_connections} - |> Supervisor.child_spec(id: :connection_sup), - {ThousandIsland.Acceptor, {server_pid, self(), acceptor_id, config}} - |> Supervisor.child_spec(id: :acceptor) - ] - - Supervisor.init(children, strategy: :rest_for_one) - end -end diff --git a/deps/thousand_island/lib/thousand_island/connection.ex b/deps/thousand_island/lib/thousand_island/connection.ex deleted file mode 100644 index 81f0482..0000000 --- a/deps/thousand_island/lib/thousand_island/connection.ex +++ /dev/null @@ -1,102 +0,0 @@ -defmodule ThousandIsland.Connection do - @moduledoc false - - @spec start( - Supervisor.supervisor(), - ThousandIsland.Transport.socket(), - ThousandIsland.ServerConfig.t(), - ThousandIsland.HandlerConfig.t(), - ThousandIsland.Telemetry.t() - ) :: - :ignore - | :ok - | {:ok, pid, info :: term} - | {:error, :too_many_connections | {:already_started, pid} | term} - def start( - sup_pid, - raw_socket, - %ThousandIsland.ServerConfig{} = server_config, - %ThousandIsland.HandlerConfig{} = handler_config, - acceptor_span - ) do - # This is a multi-step process since we need to do a bit of work from within - # the process which owns the socket (us, at this point). - - # First, capture the start time for telemetry purposes - start_time = ThousandIsland.Telemetry.monotonic_time() - - # Start by defining the worker process which will eventually handle this socket - child_spec = - {server_config.handler_module, - {server_config.handler_options, server_config.genserver_options}} - |> Supervisor.child_spec(shutdown: server_config.shutdown_timeout) - - # Then try to create it - do_start( - sup_pid, - child_spec, - raw_socket, - server_config, - handler_config, - acceptor_span, - start_time, - server_config.max_connections_retry_count - ) - end - - defp do_start( - sup_pid, - child_spec, - raw_socket, - server_config, - handler_config, - acceptor_span, - start_time, - retries - ) do - case DynamicSupervisor.start_child(sup_pid, child_spec) do - {:ok, pid} -> - # Since this process owns the socket at this point, it needs to be the - # one to make this call. connection_pid is sitting and waiting for the - # word from us to start processing, in order to ensure that we've made - # the following call. Note that we purposefully do not match on the - # return from this function; if there's an error the connection process - # will see it, but it's no longer our problem if that's the case - _ = handler_config.transport_module.controlling_process(raw_socket, pid) - - # Now that we have transferred ownership over to the new process, send a message to the - # new process with all the info it needs to start working with the socket (note that the - # new process will still need to handshake with the remote end). handler_config was - # pre-created by the acceptor to avoid Map.take on every connection. - send(pid, {:thousand_island_ready, raw_socket, handler_config, acceptor_span, start_time}) - - :ok - - {:error, :max_children} when retries > 0 -> - # We're in a tricky spot here; we have a client connection in hand, but no room to put it - # into the connection supervisor. We try to wait a maximum number of times to see if any - # room opens up before we give up - Process.sleep(server_config.max_connections_retry_wait) - - do_start( - sup_pid, - child_spec, - raw_socket, - server_config, - handler_config, - acceptor_span, - start_time, - retries - 1 - ) - - {:error, :max_children} -> - # We gave up trying to find room for this connection in our supervisor. - # Close the raw socket here and let the acceptor process handle propagating the error - handler_config.transport_module.close(raw_socket) - {:error, :too_many_connections} - - other -> - other - end - end -end diff --git a/deps/thousand_island/lib/thousand_island/handler.ex b/deps/thousand_island/lib/thousand_island/handler.ex deleted file mode 100644 index 85acea5..0000000 --- a/deps/thousand_island/lib/thousand_island/handler.ex +++ /dev/null @@ -1,600 +0,0 @@ -defmodule ThousandIsland.Handler do - @moduledoc """ - `ThousandIsland.Handler` defines the behaviour required of the application layer of a Thousand Island server. When starting a - Thousand Island server, you must pass the name of a module implementing this behaviour as the `handler_module` parameter. - Thousand Island will then use the specified module to handle each connection that is made to the server. - - The lifecycle of a Handler instance is as follows: - - 1. After a client connection to a Thousand Island server is made, Thousand Island will complete the initial setup of the - connection (performing a TLS handshake, for example), and then call `c:handle_connection/2`. - - 2. A handler implementation may choose to process a client connection within the `c:handle_connection/2` callback by - calling functions against the passed `ThousandIsland.Socket`. In many cases, this may be all that may be required of - an implementation & the value `{:close, state}` can be returned which will cause Thousand Island to close the connection - to the client. - - 3. In cases where the server wishes to keep the connection open and wait for subsequent requests from the client on the - same socket, it may elect to return `{:continue, state}`. This will cause Thousand Island to wait for client data - asynchronously; `c:handle_data/3` will be invoked when the client sends more data. - - 4. In the meantime, the process which is hosting connection is idle & able to receive messages sent from elsewhere in your - application as needed. The implementation included in the `use ThousandIsland.Handler` macro uses a `GenServer` structure, - so you may implement such behaviour via standard `GenServer` patterns. Note that in these cases that state is provided (and - must be returned) in a `{socket, state}` format, where the second tuple is the same state value that is passed to the various `handle_*` callbacks - defined on this behaviour. It also critical to maintain the socket's `read_timeout` value by - ensuring the relevant timeout value is returned as your callback's final argument. Both of these - concerns are illustrated in the following example: - - ```elixir - defmodule ExampleHandler do - use ThousandIsland.Handler - - # ...handle_data and other Handler callbacks - - @impl GenServer - def handle_call(msg, from, {socket, state}) do - # Do whatever you'd like with msg & from - {:reply, :ok, {socket, state}, socket.read_timeout} - end - - @impl GenServer - def handle_cast(msg, {socket, state}) do - # Do whatever you'd like with msg - {:noreply, {socket, state}, socket.read_timeout} - end - - @impl GenServer - def handle_info(msg, {socket, state}) do - # Do whatever you'd like with msg - {:noreply, {socket, state}, socket.read_timeout} - end - end - ``` - - It is fully supported to intermix synchronous `ThousandIsland.Socket.recv` calls with async return values from `c:handle_connection/2` - and `c:handle_data/3` callbacks. - - # Example - - A simple example of a Hello World server is as follows: - - ```elixir - defmodule HelloWorld do - use ThousandIsland.Handler - - @impl ThousandIsland.Handler - def handle_connection(socket, state) do - ThousandIsland.Socket.send(socket, "Hello, World") - {:close, state} - end - end - ``` - - Another example of a server that echoes back all data sent to it is as follows: - - ```elixir - defmodule Echo do - use ThousandIsland.Handler - - @impl ThousandIsland.Handler - def handle_data(data, socket, state) do - ThousandIsland.Socket.send(socket, data) - {:continue, state} - end - end - ``` - - Note that in this example there is no `c:handle_connection/2` callback defined. The default implementation of this - callback will simply return `{:continue, state}`, which is appropriate for cases where the client is the first - party to communicate. - - Another example of a server which can send and receive messages asynchronously is as follows: - - ```elixir - defmodule Messenger do - use ThousandIsland.Handler - - @impl ThousandIsland.Handler - def handle_data(msg, _socket, state) do - IO.puts(msg) - {:continue, state} - end - - def handle_info({:send, msg}, {socket, state}) do - ThousandIsland.Socket.send(socket, msg) - {:noreply, {socket, state}, socket.read_timeout} - end - end - ``` - - Note that in this example we make use of the fact that the handler process is really just a GenServer to send it messages - which are able to make use of the underlying socket. This allows for bidirectional sending and receiving of messages in - an asynchronous manner. - - You can pass options to the default handler underlying `GenServer` by passing a `genserver_options` key to `ThousandIsland.start_link/1` - containing `t:GenServer.options/0` to be passed to the last argument of `GenServer.start_link/3`. - - Please note that you should not pass the `name` `t:GenServer.option/0`. If you need to register handler processes for - later lookup and use, you should perform process registration in `handle_connection/2`, ensuring the handler process is - registered only after the underlying connection is established and you have access to the connection socket and metadata - via `ThousandIsland.Socket.peername/1`. - - For example, using a custom process registry via `Registry`: - - ```elixir - - defmodule Messenger do - use ThousandIsland.Handler - - @impl ThousandIsland.Handler - def handle_connection(socket, state) do - {:ok, {ip, port}} = ThousandIsland.Socket.peername(socket) - {:ok, _pid} = Registry.register(MessengerRegistry, {state[:my_key], address}, nil) - {:continue, state} - end - - @impl ThousandIsland.Handler - def handle_data(data, socket, state) do - ThousandIsland.Socket.send(socket, data) - {:continue, state} - end - end - ``` - - This example assumes you have started a `Registry` and registered it under the name `MessengerRegistry`. - - # When Handler Isn't Enough - - The `use ThousandIsland.Handler` implementation should be flexible enough to power just about any handler, however if - this should not be the case for you, there is an escape hatch available. If you require more flexibility than the - `ThousandIsland.Handler` behaviour provides, you are free to specify any module which implements `start_link/1` as the - `handler_module` parameter. The process of getting from this new process to a ready-to-use socket is somewhat - delicate, however. The steps required are as follows: - - 1. Thousand Island calls `start_link/1` on the configured `handler_module`, passing in a tuple - consisting of the configured handler and genserver opts. This function is expected to return a - conventional `GenServer.on_start()` style tuple. Note that this newly created process is not - passed the connection socket immediately. - 2. The raw `t:ThousandIsland.Transport.socket()` socket will be passed to the new process via a - message of the form `{:thousand_island_ready, raw_socket, handler_config, acceptor_span, - start_time}`. - 3. Your implementation must turn this into a `to:ThousandIsland.Socket.t()` socket by using the - `ThousandIsland.Socket.new/3` call. - 4. Your implementation must then call `ThousandIsland.Socket.handshake/1` with the socket as the - sole argument in order to finalize the setup of the socket. - 5. The socket is now ready to use. - - In addition to this process, there are several other considerations to be aware of: - - * The underlying socket is closed automatically when the handler process ends. - - * Handler processes should have a restart strategy of `:temporary` to ensure that Thousand Island does not attempt to - restart crashed handlers. - - * Handler processes should trap exit if possible so that existing connections can be given a chance to cleanly shut - down when shutting down a Thousand Island server instance. - - * Some of the `:connection` family of telemetry span events are emitted by the - `ThousandIsland.Handler` implementation. If you use your own implementation in its place it is - likely that such spans will not behave as expected. - """ - - @typedoc "The possible ways to indicate a timeout when returning values to Thousand Island" - @type timeout_options :: timeout() | {:persistent, timeout()} - - @typedoc "The value returned by `c:handle_connection/2` and `c:handle_data/3`" - @type handler_result :: - {:continue, state :: term()} - | {:continue, state :: term(), timeout_options() | {:continue, term()}} - | {:switch_transport, {module(), upgrade_opts :: [term()]}, state :: term()} - | {:switch_transport, {module(), upgrade_opts :: [term()]}, state :: term(), - timeout_options() | {:continue, term()}} - | {:close, state :: term()} - | {:error, term(), state :: term()} - - @doc """ - This callback is called shortly after a client connection has been made, immediately after the socket handshake process has - completed. It is called with the server's configured `handler_options` value as initial state. Handlers may choose to - interact synchronously with the socket in this callback via calls to various `ThousandIsland.Socket` functions. - - The value returned by this callback causes Thousand Island to proceed in one of several ways: - - * Returning `{:close, state}` will cause Thousand Island to close the socket & call the `c:handle_close/2` callback to - allow final cleanup to be done. - * Returning `{:continue, state}` will cause Thousand Island to switch the socket to an asynchronous mode. When the - client subsequently sends data (or if there is already unread data waiting from the client), Thousand Island will call - `c:handle_data/3` to allow this data to be processed. - * Returning `{:continue, state, timeout}` is identical to the previous case with the - addition of a timeout. If `timeout` milliseconds passes with no data being received or messages - being sent to the process, the socket will be closed and `c:handle_timeout/2` will be called. - Note that this timeout is not persistent; it applies only to the interval until the next message - is received. In order to set a persistent timeout for all future messages (essentially - overwriting the value of `read_timeout` that was set at server startup), a value of - `{:persistent, timeout}` may be returned. - * Returning `{:continue, state, {:continue, continue}}` is identical to the previous case with the - addition of a `c:GenServer.handle_continue/2` callback being made immediately after, in line with - similar behaviour on `GenServer` callbacks. - * Returning `{:switch_transport, {module, opts}, state}` will cause Thousand Island to try switching the transport of the - current socket. The `module` should be an Elixir module that implements the `ThousandIsland.Transport` behaviour. - Thousand Island will call `c:ThousandIsland.Transport.upgrade/2` for the given module to upgrade the transport in-place. - After a successful upgrade Thousand Island will switch the socket to an asynchronous mode, as if `{:continue, state}` - was returned. As with `:continue` return values, there are also timeout-specifying variants of - this return value. - * Returning `{:error, reason, state}` will cause Thousand Island to close the socket & call the `c:handle_error/3` callback to - allow final cleanup to be done. - """ - @callback handle_connection(socket :: ThousandIsland.Socket.t(), state :: term()) :: - handler_result() - - @doc """ - This callback is called whenever client data is received after `c:handle_connection/2` or `c:handle_data/3` have returned an - `{:continue, state}` tuple. The data received is passed as the first argument, and handlers may choose to interact - synchronously with the socket in this callback via calls to various `ThousandIsland.Socket` functions. - - The value returned by this callback causes Thousand Island to proceed in one of several ways: - - * Returning `{:close, state}` will cause Thousand Island to close the socket & call the `c:handle_close/2` callback to - allow final cleanup to be done. - * Returning `{:continue, state}` will cause Thousand Island to switch the socket to an asynchronous mode. When the - client subsequently sends data (or if there is already unread data waiting from the client), Thousand Island will call - `c:handle_data/3` to allow this data to be processed. - * Returning `{:continue, state, timeout}` is identical to the previous case with the - addition of a timeout. If `timeout` milliseconds passes with no data being received or messages - being sent to the process, the socket will be closed and `c:handle_timeout/2` will be called. - Note that this timeout is not persistent; it applies only to the interval until the next message - is received. In order to set a persistent timeout for all future messages (essentially - overwriting the value of `read_timeout` that was set at server startup), a value of - `{:persistent, timeout}` may be returned. - * Returning `{:continue, state, {:continue, continue}}` is identical to the previous case with the - addition of a `c:GenServer.handle_continue/2` callback being made immediately after, in line with - similar behaviour on `GenServer` callbacks. - * Returning `{:error, reason, state}` will cause Thousand Island to close the socket & call the `c:handle_error/3` callback to - allow final cleanup to be done. - """ - @callback handle_data(data :: binary(), socket :: ThousandIsland.Socket.t(), state :: term()) :: - handler_result() - - @doc """ - This callback is called when the underlying socket is closed by the remote end; it should perform any cleanup required - as it is the last callback called before the process backing this connection is terminated. The underlying socket - has already been closed by the time this callback is called. The return value is ignored. - - This callback is not called if the connection is explicitly closed via `ThousandIsland.Socket.close/1`, however it - will be called in cases where `handle_connection/2` or `handle_data/3` return a `{:close, state}` tuple. - """ - @callback handle_close(socket :: ThousandIsland.Socket.t(), state :: term()) :: term() - - @doc """ - This callback is called when the underlying socket encounters an error; it should perform any cleanup required - as it is the last callback called before the process backing this connection is terminated. The underlying socket - has already been closed by the time this callback is called. The return value is ignored. - - In addition to socket level errors, this callback is also called in cases where `handle_connection/2` or `handle_data/3` - return a `{:error, reason, state}` tuple, or when connection handshaking (typically TLS - negotiation) fails. - """ - @callback handle_error(reason :: any(), socket :: ThousandIsland.Socket.t(), state :: term()) :: - term() - - @doc """ - This callback is called when the server process itself is being shut down; it should perform any cleanup required - as it is the last callback called before the process backing this connection is terminated. The underlying socket - has NOT been closed by the time this callback is called. The return value is ignored. - - This callback is only called when the shutdown reason is `:normal`, and is subject to the same caveats described - in `c:GenServer.terminate/2`. - """ - @callback handle_shutdown(socket :: ThousandIsland.Socket.t(), state :: term()) :: term() - - @doc """ - This callback is called when a handler process has gone more than `timeout` ms without receiving - either remote data or a local message. The value used for `timeout` defaults to the - `read_timeout` value specified at server startup, and may be overridden on a one-shot or - persistent basis based on values returned from `c:handle_connection/2` or `c:handle_data/3` - calls. Note that it is NOT called on explicit `ThousandIsland.Socket.recv/3` calls as they have - their own timeout semantics. The underlying socket has NOT been closed by the time this callback - is called. The return value is ignored. - """ - @callback handle_timeout(socket :: ThousandIsland.Socket.t(), state :: term()) :: term() - - @optional_callbacks handle_connection: 2, - handle_data: 3, - handle_close: 2, - handle_error: 3, - handle_shutdown: 2, - handle_timeout: 2 - - @spec __using__(any) :: Macro.t() - defmacro __using__(_opts) do - quote location: :keep do - @behaviour ThousandIsland.Handler - - use GenServer, restart: :temporary - - @spec start_link({handler_options :: term(), GenServer.options()}) :: GenServer.on_start() - def start_link({handler_options, genserver_options}) do - GenServer.start_link(__MODULE__, handler_options, genserver_options) - end - - unquote(genserver_impl()) - unquote(handler_impl()) - end - end - - @doc false - defmacro add_handle_info_fallback(_module) do - quote do - def handle_info({msg, _raw_socket, _data}, _state) when msg in [:tcp, :ssl] do - raise """ - The callback's `state` doesn't match the expected `{socket, state}` form. - Please ensure that you are returning a `{socket, state}` tuple from any - `GenServer.handle_*` callbacks you have implemented - """ - end - end - end - - # credo:disable-for-next-line Credo.Check.Refactor.CyclomaticComplexity - def genserver_impl do - quote do - @impl true - def init(handler_options) do - Process.flag(:trap_exit, true) - {:ok, {nil, handler_options}} - end - - @impl true - def handle_info( - {:thousand_island_ready, raw_socket, handler_config, acceptor_span, start_time}, - {nil, state} - ) do - {ip, port} = - case handler_config.transport_module.peername(raw_socket) do - {:ok, remote_info} -> - remote_info - - {:error, reason} -> - # the socket has been prematurely closed by the client, we can't do anything with it - # so we just close the socket, stop the GenServer with the error reason and move on. - _ = handler_config.transport_module.close(raw_socket) - throw({:stop, {:shutdown, {:premature_conn_closing, reason}}, {raw_socket, state}}) - end - - ThousandIsland.ProcessLabel.set(:connection, handler_config, {ip, port}) - - span_meta = %{remote_address: ip, remote_port: port} - - connection_span = - ThousandIsland.Telemetry.start_child_span( - acceptor_span, - :connection, - %{monotonic_time: start_time}, - span_meta - ) - - socket = ThousandIsland.Socket.new(raw_socket, handler_config, connection_span) - ThousandIsland.Telemetry.span_event(connection_span, :ready) - - case ThousandIsland.Socket.handshake(socket) do - {:ok, socket} -> {:noreply, {socket, state}, {:continue, :handle_connection}} - {:error, reason} -> {:stop, {:shutdown, {:handshake, reason}}, {socket, state}} - end - catch - {:stop, _, _} = stop -> stop - end - - def handle_info( - {msg, raw_socket, data}, - {%ThousandIsland.Socket{socket: raw_socket} = socket, state} - ) - when msg in [:tcp, :ssl] do - ThousandIsland.Telemetry.untimed_span_event(socket.span, :async_recv, %{data: data}) - - __MODULE__.handle_data(data, socket, state) - |> ThousandIsland.Handler.handle_continuation(socket) - end - - def handle_info( - {msg, raw_socket}, - {%ThousandIsland.Socket{socket: raw_socket} = socket, state} - ) - when msg in [:tcp_closed, :ssl_closed] do - {:stop, {:shutdown, :peer_closed}, {socket, state}} - end - - def handle_info( - {msg, raw_socket, reason}, - {%ThousandIsland.Socket{socket: raw_socket} = socket, state} - ) - when msg in [:tcp_error, :ssl_error] do - {:stop, reason, {socket, state}} - end - - def handle_info(:timeout, {%ThousandIsland.Socket{} = socket, state}) do - {:stop, {:shutdown, :timeout}, {socket, state}} - end - - @before_compile {ThousandIsland.Handler, :add_handle_info_fallback} - - # Use a continue pattern here so that we have committed the socket - # to state in case the `c:handle_connection/2` callback raises an error. - # This ensures that the `c:terminate/2` calls below are able to properly - # close down the process - @impl true - def handle_continue(:handle_connection, {%ThousandIsland.Socket{} = socket, state}) do - __MODULE__.handle_connection(socket, state) - |> ThousandIsland.Handler.handle_continuation(socket) - end - - # Called if the remote end closed the connection before we could initialize it - @impl true - def terminate({:shutdown, {:premature_conn_closing, _reason}}, {_raw_socket, _state}) do - :ok - end - - # Called by GenServer if we hit our read_timeout. Socket is still open - def terminate({:shutdown, :timeout}, {%ThousandIsland.Socket{} = socket, state}) do - _ = __MODULE__.handle_timeout(socket, state) - ThousandIsland.Handler.do_socket_close(socket, :timeout) - end - - # Called if we're being shutdown in an orderly manner. Socket is still open - def terminate(:shutdown, {%ThousandIsland.Socket{} = socket, state}) do - _ = __MODULE__.handle_shutdown(socket, state) - ThousandIsland.Handler.do_socket_close(socket, :shutdown) - end - - # Called if the socket encountered an error during handshaking - def terminate({:shutdown, {:handshake, reason}}, {%ThousandIsland.Socket{} = socket, state}) do - _ = __MODULE__.handle_error(reason, socket, state) - ThousandIsland.Handler.do_socket_close(socket, reason) - end - - # Called if the socket encountered an error and we are configured to shutdown silently. - # Socket is closed - def terminate( - {:shutdown, {:silent_termination, reason}}, - {%ThousandIsland.Socket{} = socket, state} - ) do - _ = __MODULE__.handle_error(reason, socket, state) - ThousandIsland.Handler.do_socket_close(socket, reason) - end - - # Called if the socket encountered an error during upgrading - def terminate({:shutdown, {:upgrade, reason}}, {socket, state}) do - _ = __MODULE__.handle_error(reason, socket, state) - ThousandIsland.Handler.do_socket_close(socket, reason) - end - - # Called if the remote end shut down the connection, or if the local end closed the - # connection by returning a `{:close,...}` tuple (in which case the socket will be open) - def terminate({:shutdown, reason}, {%ThousandIsland.Socket{} = socket, state}) do - _ = __MODULE__.handle_close(socket, state) - ThousandIsland.Handler.do_socket_close(socket, reason) - end - - # Called if the socket encountered an error. Socket is closed - def terminate(reason, {%ThousandIsland.Socket{} = socket, state}) do - _ = __MODULE__.handle_error(reason, socket, state) - ThousandIsland.Handler.do_socket_close(socket, reason) - end - - # This clause could happen if we do not have a socket defined in state (either because the - # process crashed before setting it up, or because the user sent an invalid state) - def terminate(_reason, _state) do - :ok - end - end - end - - def handler_impl do - quote do - @impl true - def handle_connection(_socket, state), do: {:continue, state} - - @impl true - def handle_data(_data, _socket, state), do: {:continue, state} - - @impl true - def handle_close(_socket, _state), do: :ok - - @impl true - def handle_error(_error, _socket, _state), do: :ok - - @impl true - def handle_shutdown(_socket, _state), do: :ok - - @impl true - def handle_timeout(_socket, _state), do: :ok - - defoverridable ThousandIsland.Handler - end - end - - @spec do_socket_close( - ThousandIsland.Socket.t(), - reason :: :shutdown | :local_closed | term() - ) :: :ok - @doc false - def do_socket_close(socket, reason) do - measurements = - case ThousandIsland.Socket.getstat(socket) do - {:ok, stats} -> - %{ - send_oct: stats[:send_oct], - send_cnt: stats[:send_cnt], - recv_oct: stats[:recv_oct], - recv_cnt: stats[:recv_cnt] - } - - _ -> - %{} - end - - metadata = - if reason in [:shutdown, :local_closed, :peer_closed], do: %{}, else: %{error: reason} - - _ = ThousandIsland.Socket.close(socket) - ThousandIsland.Telemetry.stop_span(socket.span, measurements, metadata) - end - - @doc false - def handle_continuation(continuation, socket) do - case continuation do - {:continue, state} -> - _ = ThousandIsland.Socket.setopts(socket, active: :once) - {:noreply, {socket, state}, socket.read_timeout} - - {:continue, state, {:continue, continue}} -> - _ = ThousandIsland.Socket.setopts(socket, active: :once) - {:noreply, {socket, state}, {:continue, continue}} - - {:continue, state, {:persistent, timeout}} -> - socket = %{socket | read_timeout: timeout} - _ = ThousandIsland.Socket.setopts(socket, active: :once) - {:noreply, {socket, state}, timeout} - - {:continue, state, timeout} -> - _ = ThousandIsland.Socket.setopts(socket, active: :once) - {:noreply, {socket, state}, timeout} - - {:switch_transport, {module, upgrade_opts}, state} -> - handle_switch_continuation(socket, module, upgrade_opts, state, socket.read_timeout) - - {:switch_transport, {module, upgrade_opts}, state, {:continue, continue}} -> - handle_switch_continuation(socket, module, upgrade_opts, state, {:continue, continue}) - - {:switch_transport, {module, upgrade_opts}, state, {:persistent, timeout}} -> - socket = %{socket | read_timeout: timeout} - handle_switch_continuation(socket, module, upgrade_opts, state, timeout) - - {:switch_transport, {module, upgrade_opts}, state, timeout} -> - handle_switch_continuation(socket, module, upgrade_opts, state, timeout) - - {:close, state} -> - {:stop, {:shutdown, :local_closed}, {socket, state}} - - {:error, :timeout, state} -> - {:stop, {:shutdown, :timeout}, {socket, state}} - - {:error, reason, state} -> - if socket.silent_terminate_on_error do - {:stop, {:shutdown, {:silent_termination, reason}}, {socket, state}} - else - {:stop, reason, {socket, state}} - end - end - end - - defp handle_switch_continuation(socket, module, upgrade_opts, state, timeout_or_continue) do - case ThousandIsland.Socket.upgrade(socket, module, upgrade_opts) do - {:ok, socket} -> - _ = ThousandIsland.Socket.setopts(socket, active: :once) - {:noreply, {socket, state}, timeout_or_continue} - - {:error, reason} -> - {:stop, {:shutdown, {:upgrade, reason}}, {socket, state}} - end - end -end diff --git a/deps/thousand_island/lib/thousand_island/handler_config.ex b/deps/thousand_island/lib/thousand_island/handler_config.ex deleted file mode 100644 index d9608d3..0000000 --- a/deps/thousand_island/lib/thousand_island/handler_config.ex +++ /dev/null @@ -1,31 +0,0 @@ -defmodule ThousandIsland.HandlerConfig do - @moduledoc """ - A minimal config struct containing only the fields needed by connection handlers. - - This is used internally by `ThousandIsland.Handler` - """ - - @enforce_keys [:handler_module, :transport_module, :read_timeout, :silent_terminate_on_error] - defstruct @enforce_keys - - @type t :: %__MODULE__{ - handler_module: nil, - transport_module: module(), - read_timeout: timeout(), - silent_terminate_on_error: boolean() - } - - @doc """ - Creates a HandlerConfig from a ServerConfig, extracting only the fields needed - by connection handlers. This should be called once per acceptor at initialization. - """ - @spec from_server_config(ThousandIsland.ServerConfig.t()) :: t() - def from_server_config(%ThousandIsland.ServerConfig{} = config) do - %__MODULE__{ - handler_module: config.handler_module, - transport_module: config.transport_module, - read_timeout: config.read_timeout, - silent_terminate_on_error: config.silent_terminate_on_error - } - end -end diff --git a/deps/thousand_island/lib/thousand_island/listener.ex b/deps/thousand_island/lib/thousand_island/listener.ex deleted file mode 100644 index 7c57c10..0000000 --- a/deps/thousand_island/lib/thousand_island/listener.ex +++ /dev/null @@ -1,109 +0,0 @@ -defmodule ThousandIsland.Listener do - @moduledoc false - - use GenServer, restart: :transient - - @type state :: %{ - listener_sockets: [{pos_integer(), ThousandIsland.Transport.listener_socket()}], - listener_span: ThousandIsland.Telemetry.t(), - local_info: ThousandIsland.Transport.socket_info() - } - - @spec start_link(ThousandIsland.ServerConfig.t()) :: GenServer.on_start() - def start_link(config), do: GenServer.start_link(__MODULE__, config) - - @spec stop(GenServer.server()) :: :ok - def stop(server), do: GenServer.stop(server) - - @spec listener_info(GenServer.server()) :: ThousandIsland.Transport.socket_info() - def listener_info(server), do: GenServer.call(server, :listener_info) - - @spec acceptor_info(GenServer.server(), pos_integer()) :: - {ThousandIsland.Transport.listener_socket(), ThousandIsland.Telemetry.t()} - def acceptor_info(server, acceptor_id), - do: GenServer.call(server, {:acceptor_info, acceptor_id}) - - @impl GenServer - @spec init(ThousandIsland.ServerConfig.t()) :: {:ok, state} | {:stop, reason :: term} - def init(%ThousandIsland.ServerConfig{} = server_config) do - case start_listen_sockets(server_config) do - {:ok, listener_sockets, local_info} -> - ThousandIsland.ProcessLabel.set(:listener, server_config) - - span_metadata = %{ - handler: server_config.handler_module, - local_address: elem(local_info, 0), - local_port: elem(local_info, 1), - transport_module: server_config.transport_module, - transport_options: server_config.transport_options - } - - listener_span = ThousandIsland.Telemetry.start_span(:listener, %{}, span_metadata) - - {:ok, - %{ - listener_sockets: listener_sockets, - local_info: local_info, - listener_span: listener_span - }} - - {:error, reason} -> - {:stop, reason} - end - end - - defp start_listen_sockets(%ThousandIsland.ServerConfig{} = server_config) do - num_sockets = server_config.num_listen_sockets - - sockets = - for socket_id <- 1..num_sockets do - case server_config.transport_module.listen( - server_config.port, - server_config.transport_options - ) do - {:ok, socket} -> {socket_id, socket} - {:error, reason} -> throw({:error, reason}) - end - end - - # Get local info from first socket - {1, first_socket} = List.keyfind(sockets, 1, 0) - - case server_config.transport_module.sockname(first_socket) do - {:ok, {ip, port}} -> - {:ok, sockets, {ip, port}} - - {:error, reason} -> - # Cleanup all sockets on error - Enum.each(sockets, fn {_, socket} -> - server_config.transport_module.close(socket) - end) - - {:error, reason} - end - catch - {:error, reason} -> - {:error, reason} - end - - @impl GenServer - @spec handle_call(:listener_info | {:acceptor_info, pos_integer()}, any, state) :: - {:reply, - ThousandIsland.Transport.socket_info() - | {ThousandIsland.Transport.listener_socket(), ThousandIsland.Telemetry.t()}, state} - def handle_call(:listener_info, _from, state), do: {:reply, state.local_info, state} - - def handle_call({:acceptor_info, acceptor_id}, _from, state) do - num_listen_sockets = length(state.listener_sockets) - socket_id = rem(acceptor_id - 1, num_listen_sockets) + 1 - {^socket_id, listener_socket} = List.keyfind(state.listener_sockets, socket_id, 0) - {:reply, {listener_socket, state.listener_span}, state} - end - - @impl GenServer - @spec terminate(reason, state) :: :ok - when reason: :normal | :shutdown | {:shutdown, term} | term - def terminate(_reason, state) do - ThousandIsland.Telemetry.stop_span(state.listener_span) - end -end diff --git a/deps/thousand_island/lib/thousand_island/logger.ex b/deps/thousand_island/lib/thousand_island/logger.ex deleted file mode 100644 index 94894a3..0000000 --- a/deps/thousand_island/lib/thousand_island/logger.ex +++ /dev/null @@ -1,149 +0,0 @@ -defmodule ThousandIsland.Logger do - @moduledoc """ - Logging conveniences for Thousand Island servers - - Allows dynamically adding and altering the log level used to trace connections - within a Thousand Island server via the use of telemetry hooks. Should you wish - to do your own logging or tracking of these events, a complete list of the - telemetry events emitted by Thousand Island is described in the module - documentation for `ThousandIsland.Telemetry`. - """ - - require Logger - - @typedoc "Supported log levels" - @type log_level :: :error | :info | :debug | :trace - - @doc """ - Start logging Thousand Island at the specified log level. Valid values for log - level are `:error`, `:info`, `:debug`, and `:trace`. Enabling a given log - level implicitly enables all higher log levels as well. - """ - @spec attach_logger(log_level()) :: :ok | {:error, :already_exists} - def attach_logger(:error) do - events = [ - [:thousand_island, :acceptor, :spawn_error], - [:thousand_island, :acceptor, :econnaborted] - ] - - :telemetry.attach_many("#{__MODULE__}.error", events, &__MODULE__.log_error/4, nil) - end - - def attach_logger(:info) do - _ = attach_logger(:error) - - events = [ - [:thousand_island, :listener, :start], - [:thousand_island, :listener, :stop] - ] - - :telemetry.attach_many("#{__MODULE__}.info", events, &__MODULE__.log_info/4, nil) - end - - def attach_logger(:debug) do - _ = attach_logger(:info) - - events = [ - [:thousand_island, :acceptor, :start], - [:thousand_island, :acceptor, :stop], - [:thousand_island, :connection, :start], - [:thousand_island, :connection, :stop] - ] - - :telemetry.attach_many("#{__MODULE__}.debug", events, &__MODULE__.log_debug/4, nil) - end - - def attach_logger(:trace) do - _ = attach_logger(:debug) - - events = [ - [:thousand_island, :connection, :ready], - [:thousand_island, :connection, :async_recv], - [:thousand_island, :connection, :recv], - [:thousand_island, :connection, :recv_error], - [:thousand_island, :connection, :send], - [:thousand_island, :connection, :send_error], - [:thousand_island, :connection, :sendfile], - [:thousand_island, :connection, :sendfile_error], - [:thousand_island, :connection, :socket_shutdown] - ] - - :telemetry.attach_many("#{__MODULE__}.trace", events, &__MODULE__.log_trace/4, nil) - end - - @doc """ - Stop logging Thousand Island at the specified log level. Disabling a given log - level implicitly disables all lower log levels as well. - """ - @spec detach_logger(log_level()) :: :ok | {:error, :not_found} - def detach_logger(:error) do - _ = detach_logger(:info) - :telemetry.detach("#{__MODULE__}.error") - end - - def detach_logger(:info) do - _ = detach_logger(:debug) - :telemetry.detach("#{__MODULE__}.info") - end - - def detach_logger(:debug) do - _ = detach_logger(:trace) - :telemetry.detach("#{__MODULE__}.debug") - end - - def detach_logger(:trace) do - :telemetry.detach("#{__MODULE__}.trace") - end - - @doc false - @spec log_error( - :telemetry.event_name(), - :telemetry.event_measurements(), - :telemetry.event_metadata(), - :telemetry.handler_config() - ) :: :ok - def log_error(event, measurements, metadata, _config) do - Logger.error( - "#{inspect(event)} metadata: #{inspect(metadata)}, measurements: #{inspect(measurements)}" - ) - end - - @doc false - @spec log_info( - :telemetry.event_name(), - :telemetry.event_measurements(), - :telemetry.event_metadata(), - :telemetry.handler_config() - ) :: :ok - def log_info(event, measurements, metadata, _config) do - Logger.info( - "#{inspect(event)} metadata: #{inspect(metadata)}, measurements: #{inspect(measurements)}" - ) - end - - @doc false - @spec log_debug( - :telemetry.event_name(), - :telemetry.event_measurements(), - :telemetry.event_metadata(), - :telemetry.handler_config() - ) :: :ok - def log_debug(event, measurements, metadata, _config) do - Logger.debug( - "#{inspect(event)} metadata: #{inspect(metadata)}, measurements: #{inspect(measurements)}" - ) - end - - @doc false - @spec log_trace( - :telemetry.event_name(), - :telemetry.event_measurements(), - :telemetry.event_metadata(), - :telemetry.handler_config() - ) :: :ok - def log_trace(event, measurements, metadata, _config) do - Logger.debug( - "#{inspect(event)} metadata: #{inspect(metadata)}, measurements: #{inspect(measurements)}" - ) - end -end diff --git a/deps/thousand_island/lib/thousand_island/process_label.ex b/deps/thousand_island/lib/thousand_island/process_label.ex deleted file mode 100644 index 949f243..0000000 --- a/deps/thousand_island/lib/thousand_island/process_label.ex +++ /dev/null @@ -1,52 +0,0 @@ -defmodule ThousandIsland.ProcessLabel do - @moduledoc false - # Provides compile-time conditional support for Process.set_label/1 - # which was introduced in Elixir 1.17.0 and OTP 27. - @supports_labels Version.match?(System.version(), ">= 1.17.0") and - String.to_integer(System.otp_release()) >= 27 - - @type config() :: ThousandIsland.ServerConfig.t() | ThousandIsland.HandlerConfig.t() - - if @supports_labels do - @doc """ - Sets a process label if the current Elixir version supports it (>= 1.17). - """ - @spec set(atom(), config(), term()) :: - :ok - def set(name, %ThousandIsland.ServerConfig{} = config, state) when is_atom(name) do - Process.set_label({:thousand_island, name, {{config.port, config.handler_module}, state}}) - end - - def set(name, %ThousandIsland.HandlerConfig{} = config, state) when is_atom(name) do - Process.set_label({:thousand_island, name, {config.handler_module, state}}) - end - - @doc """ - Sets a process label if the current Elixir version supports it (>= 1.17). - """ - @spec set(atom(), term()) :: :ok - def set(name, %ThousandIsland.ServerConfig{} = config) when is_atom(name) do - Process.set_label({:thousand_island, name, {config.port, config.handler_module}}) - end - - def set(name, state) when is_atom(name) do - Process.set_label({:thousand_island, name, state}) - end - else - @doc """ - No-op on Elixir versions < 1.17 that don't support Process.set_label/1. - """ - @spec set(atom(), config(), term()) :: :ok - def set(_, _, _) do - :ok - end - - @doc """ - No-op on Elixir versions < 1.17 that don't support Process.set_label/1. - """ - @spec set(atom(), term()) :: :ok - def set(_, _) do - :ok - end - end -end diff --git a/deps/thousand_island/lib/thousand_island/server.ex b/deps/thousand_island/lib/thousand_island/server.ex deleted file mode 100644 index be88fb1..0000000 --- a/deps/thousand_island/lib/thousand_island/server.ex +++ /dev/null @@ -1,88 +0,0 @@ -defmodule ThousandIsland.Server do - @moduledoc false - - use Supervisor - - @spec start_link(ThousandIsland.ServerConfig.t()) :: Supervisor.on_start() - def start_link(%ThousandIsland.ServerConfig{} = config) do - Supervisor.start_link(__MODULE__, config, config.supervisor_options) - end - - @spec listener_pid(Supervisor.supervisor()) :: pid() | nil - def listener_pid(supervisor) do - supervisor - |> Supervisor.which_children() - |> Enum.find_value(fn - {:listener, listener_pid, _, _} when is_pid(listener_pid) -> - listener_pid - - _ -> - false - end) - end - - @spec acceptor_pool_supervisor_pid(Supervisor.supervisor()) :: pid() | nil - def acceptor_pool_supervisor_pid(supervisor) do - supervisor - |> Supervisor.which_children() - |> Enum.find_value(fn - {:acceptor_pool_supervisor, acceptor_pool_sup_pid, _, _} - when is_pid(acceptor_pool_sup_pid) -> - acceptor_pool_sup_pid - - _ -> - false - end) - end - - @spec suspend(Supervisor.supervisor()) :: :ok | :error - def suspend(pid) do - with pool_sup_pid when is_pid(pool_sup_pid) <- acceptor_pool_supervisor_pid(pid), - :ok <- ThousandIsland.AcceptorPoolSupervisor.suspend(pool_sup_pid), - :ok <- Supervisor.terminate_child(pid, :shutdown_listener), - :ok <- Supervisor.terminate_child(pid, :listener) do - :ok - else - _ -> :error - end - end - - @spec resume(Supervisor.supervisor()) :: :ok | :error - def resume(pid) do - with :ok <- wrap_restart_child(pid, :listener), - :ok <- wrap_restart_child(pid, :shutdown_listener), - pool_sup_pid when is_pid(pool_sup_pid) <- acceptor_pool_supervisor_pid(pid), - :ok <- ThousandIsland.AcceptorPoolSupervisor.resume(pool_sup_pid) do - :ok - else - _ -> :error - end - end - - defp wrap_restart_child(pid, id) do - case Supervisor.restart_child(pid, id) do - {:ok, _child} -> :ok - {:error, reason} when reason in [:running, :restarting] -> :ok - {:error, _reason} -> :error - end - end - - @impl Supervisor - @spec init(ThousandIsland.ServerConfig.t()) :: - {:ok, - {Supervisor.sup_flags(), - [Supervisor.child_spec() | (old_erlang_child_spec :: :supervisor.child_spec())]}} - def init(config) do - ThousandIsland.ProcessLabel.set(:server, config) - - children = [ - {ThousandIsland.Listener, config} |> Supervisor.child_spec(id: :listener), - {ThousandIsland.AcceptorPoolSupervisor, {self(), config}} - |> Supervisor.child_spec(id: :acceptor_pool_supervisor), - {ThousandIsland.ShutdownListener, {self(), config}} - |> Supervisor.child_spec(id: :shutdown_listener) - ] - - Supervisor.init(children, strategy: :rest_for_one) - end -end diff --git a/deps/thousand_island/lib/thousand_island/server_config.ex b/deps/thousand_island/lib/thousand_island/server_config.ex deleted file mode 100644 index eec77cb..0000000 --- a/deps/thousand_island/lib/thousand_island/server_config.ex +++ /dev/null @@ -1,77 +0,0 @@ -defmodule ThousandIsland.ServerConfig do - @moduledoc """ - Encapsulates the configuration of a ThousandIsland server instance - - This is used internally by `ThousandIsland.Handler` - """ - - @typedoc "A set of configuration parameters for a ThousandIsland server instance" - @type t :: %__MODULE__{ - port: :inet.port_number(), - transport_module: ThousandIsland.transport_module(), - transport_options: ThousandIsland.transport_options(), - handler_module: module(), - handler_options: term(), - genserver_options: GenServer.options(), - supervisor_options: [Supervisor.option()], - num_acceptors: pos_integer(), - num_listen_sockets: pos_integer(), - num_connections: non_neg_integer() | :infinity, - max_connections_retry_count: non_neg_integer(), - max_connections_retry_wait: timeout(), - read_timeout: timeout(), - shutdown_timeout: timeout(), - silent_terminate_on_error: boolean() - } - - defstruct port: 4000, - transport_module: ThousandIsland.Transports.TCP, - transport_options: [], - handler_module: nil, - handler_options: [], - genserver_options: [], - supervisor_options: [], - num_acceptors: 100, - num_listen_sockets: 1, - num_connections: 16_384, - max_connections_retry_count: 5, - max_connections_retry_wait: 1000, - read_timeout: 60_000, - shutdown_timeout: 15_000, - silent_terminate_on_error: false - - @spec new(ThousandIsland.options()) :: t() - def new(opts \\ []) do - config = struct!(__MODULE__, opts) - validate_handler_module!(config) - validate_num_sockets!(config) - validate_reuseport_options!(config) - config - end - - defp validate_handler_module!(config) do - if !config.handler_module do - raise("No handler_module defined in server configuration") - end - end - - defp validate_num_sockets!(config) do - if config.num_listen_sockets > config.num_acceptors do - raise( - "num_listen_sockets (#{config.num_listen_sockets}) must be less than or equal to num_acceptors (#{config.num_acceptors})" - ) - end - end - - defp validate_reuseport_options!(config) do - num_listen_sockets = config.num_listen_sockets - transport_options = config.transport_options - has_reuseport = :proplists.get_value(:reuseport, transport_options, false) - has_reuseport_lb = :proplists.get_value(:reuseport_lb, transport_options, false) - - unless num_listen_sockets <= 1 or has_reuseport or has_reuseport_lb do - raise ArgumentError, - "reuseport: true or reuseport_lb: true must be set in transport_options when using num_listen_sockets > 1" - end - end -end diff --git a/deps/thousand_island/lib/thousand_island/shutdown_listener.ex b/deps/thousand_island/lib/thousand_island/shutdown_listener.ex deleted file mode 100644 index 6543b41..0000000 --- a/deps/thousand_island/lib/thousand_island/shutdown_listener.ex +++ /dev/null @@ -1,47 +0,0 @@ -defmodule ThousandIsland.ShutdownListener do - @moduledoc false - - # Used as part of the `ThousandIsland.Server` supervision tree to facilitate - # stopping the server's listener process early in the shutdown process, in order - # to allow existing connections to drain without accepting new ones - - use GenServer - - @type state :: %{ - optional(:server_pid) => pid(), - optional(:listener_pid) => pid() | nil - } - - @doc false - @spec start_link({pid(), any()}) :: :ignore | {:error, any} | {:ok, pid} - def start_link({server_pid, key}) do - GenServer.start_link(__MODULE__, {server_pid, key}) - end - - @doc false - @impl GenServer - @spec init({pid(), any()}) :: {:ok, state, {:continue, :setup_listener_pid}} - def init({server_pid, key}) do - Process.flag(:trap_exit, true) - ThousandIsland.ProcessLabel.set(:shutdown_listener, key) - {:ok, %{server_pid: server_pid}, {:continue, :setup_listener_pid}} - end - - @doc false - @impl GenServer - @spec handle_continue(:setup_listener_pid, state) :: {:noreply, state} - def handle_continue(:setup_listener_pid, %{server_pid: server_pid}) do - listener_pid = ThousandIsland.Server.listener_pid(server_pid) - {:noreply, %{listener_pid: listener_pid}} - end - - @doc false - @impl GenServer - @spec terminate(reason, state) :: :ok - when reason: :normal | :shutdown | {:shutdown, term} | term - def terminate(_reason, %{listener_pid: listener_pid}) do - ThousandIsland.Listener.stop(listener_pid) - end - - def terminate(_reason, _state), do: :ok -end diff --git a/deps/thousand_island/lib/thousand_island/socket.ex b/deps/thousand_island/lib/thousand_island/socket.ex deleted file mode 100644 index 9a712e6..0000000 --- a/deps/thousand_island/lib/thousand_island/socket.ex +++ /dev/null @@ -1,236 +0,0 @@ -defmodule ThousandIsland.Socket do - @moduledoc """ - Encapsulates a client connection's underlying socket, providing a facility to - read, write, and otherwise manipulate a connection from a client. - """ - - @enforce_keys [:socket, :transport_module, :read_timeout, :silent_terminate_on_error, :span] - defstruct @enforce_keys - - @typedoc "A reference to a socket along with metadata describing how to use it" - @type t :: %__MODULE__{ - socket: ThousandIsland.Transport.socket(), - transport_module: module(), - read_timeout: timeout(), - silent_terminate_on_error: boolean(), - span: ThousandIsland.Telemetry.t() - } - - @doc """ - Creates a new socket struct based on the passed parameters. - - This is normally called internally by `ThousandIsland.Handler` and does not need to be - called by implementations which are based on `ThousandIsland.Handler` - """ - @spec new( - ThousandIsland.Transport.socket(), - ThousandIsland.HandlerConfig.t(), - ThousandIsland.Telemetry.t() - ) :: t() - def new(raw_socket, handler_config, span) do - %__MODULE__{ - socket: raw_socket, - transport_module: handler_config.transport_module, - read_timeout: handler_config.read_timeout, - silent_terminate_on_error: handler_config.silent_terminate_on_error, - span: span - } - end - - @doc """ - Handshakes the underlying socket if it is required (as in the case of SSL sockets, for example). - - This is normally called internally by `ThousandIsland.Handler` and does not need to be - called by implementations which are based on `ThousandIsland.Handler` - """ - @spec handshake(t()) :: ThousandIsland.Transport.on_handshake() - def handshake(%__MODULE__{} = socket) do - case socket.transport_module.handshake(socket.socket) do - {:ok, inner_socket} -> - {:ok, %{socket | socket: inner_socket}} - - {:error, reason} = err -> - ThousandIsland.Telemetry.stop_span(socket.span, %{}, %{error: reason}) - err - end - end - - @doc """ - Upgrades the transport of the socket to use the specified transport module, performing any client - handshaking that may be required. The passed options are blindly passed through to the new - transport module. - - This is normally called internally by `ThousandIsland.Handler` and does not need to be - called by implementations which are based on `ThousandIsland.Handler` - """ - @spec upgrade(t(), module(), term()) :: ThousandIsland.Transport.on_upgrade() - def upgrade(%__MODULE__{} = socket, module, opts) when is_atom(module) do - case module.upgrade(socket.socket, opts) do - {:ok, updated_socket} -> - {:ok, %{socket | socket: updated_socket, transport_module: module}} - - {:error, reason} = err -> - ThousandIsland.Telemetry.stop_span(socket.span, %{}, %{error: reason}) - err - end - end - - @doc """ - Returns available bytes on the given socket. Up to `length` bytes will be - returned (0 can be passed in to get the next 'available' bytes, typically the - next packet). If insufficient bytes are available, the function can wait `timeout` - milliseconds for data to arrive. - """ - @spec recv(t(), non_neg_integer(), timeout() | nil) :: ThousandIsland.Transport.on_recv() - def recv(%__MODULE__{} = socket, length \\ 0, timeout \\ nil) do - case socket.transport_module.recv(socket.socket, length, timeout || socket.read_timeout) do - {:ok, data} = ok -> - ThousandIsland.Telemetry.untimed_span_event(socket.span, :recv, %{data: data}) - ok - - {:error, reason} = err -> - ThousandIsland.Telemetry.span_event(socket.span, :recv_error, %{error: reason}) - err - end - end - - @doc """ - Sends the given data (specified as a binary or an IO list) on the given socket. - """ - @spec send(t(), iodata()) :: ThousandIsland.Transport.on_send() - def send(%__MODULE__{} = socket, data) do - case socket.transport_module.send(socket.socket, data) do - :ok -> - ThousandIsland.Telemetry.untimed_span_event(socket.span, :send, %{data: data}) - :ok - - {:error, reason} = err -> - ThousandIsland.Telemetry.span_event(socket.span, :send_error, %{data: data, error: reason}) - - err - end - end - - @doc """ - Sends the contents of the given file based on the provided offset & length - """ - @spec sendfile(t(), String.t(), non_neg_integer(), non_neg_integer()) :: - ThousandIsland.Transport.on_sendfile() - def sendfile(%__MODULE__{} = socket, filename, offset, length) do - case socket.transport_module.sendfile(socket.socket, filename, offset, length) do - {:ok, bytes_written} = ok -> - measurements = %{filename: filename, offset: offset, bytes_written: bytes_written} - ThousandIsland.Telemetry.untimed_span_event(socket.span, :sendfile, measurements) - ok - - {:error, reason} = err -> - measurements = %{filename: filename, offset: offset, length: length, error: reason} - ThousandIsland.Telemetry.span_event(socket.span, :sendfile_error, measurements) - err - end - end - - @doc """ - Shuts down the socket in the given direction. - """ - @spec shutdown(t(), ThousandIsland.Transport.way()) :: ThousandIsland.Transport.on_shutdown() - def shutdown(%__MODULE__{} = socket, way) do - ThousandIsland.Telemetry.span_event(socket.span, :socket_shutdown, %{way: way}) - socket.transport_module.shutdown(socket.socket, way) - end - - @doc """ - Closes the given socket. Note that a socket is automatically closed when the handler - process which owns it terminates - """ - @spec close(t()) :: ThousandIsland.Transport.on_close() - def close(%__MODULE__{} = socket) do - socket.transport_module.close(socket.socket) - end - - @doc """ - Gets the given flags on the socket - - Errors are usually from :inet.posix(), however, SSL module defines return type as any() - """ - @spec getopts(t(), ThousandIsland.Transport.socket_get_options()) :: - ThousandIsland.Transport.on_getopts() - def getopts(%__MODULE__{} = socket, options) do - socket.transport_module.getopts(socket.socket, options) - end - - @doc """ - Sets the given flags on the socket - - Errors are usually from :inet.posix(), however, SSL module defines return type as any() - """ - @spec setopts(t(), ThousandIsland.Transport.socket_set_options()) :: - ThousandIsland.Transport.on_setopts() - def setopts(%__MODULE__{} = socket, options) do - socket.transport_module.setopts(socket.socket, options) - end - - @doc """ - Returns information in the form of `t:ThousandIsland.Transport.socket_info()` about the local end of the socket. - """ - @spec sockname(t()) :: ThousandIsland.Transport.on_sockname() - def sockname(%__MODULE__{} = socket) do - socket.transport_module.sockname(socket.socket) - end - - @doc """ - Returns information in the form of `t:ThousandIsland.Transport.socket_info()` about the remote end of the socket. - """ - @spec peername(t()) :: ThousandIsland.Transport.on_peername() - def peername(%__MODULE__{} = socket) do - socket.transport_module.peername(socket.socket) - end - - @doc """ - Returns information in the form of `t:public_key.der_encoded()` about the peer certificate of the socket. - """ - @spec peercert(t()) :: ThousandIsland.Transport.on_peercert() - def peercert(%__MODULE__{} = socket) do - socket.transport_module.peercert(socket.socket) - end - - @doc """ - Returns whether or not this protocol is secure. - """ - @spec secure?(t()) :: boolean() - def secure?(%__MODULE__{} = socket) do - socket.transport_module.secure?() - end - - @doc """ - Returns statistics about the connection. - """ - @spec getstat(t()) :: ThousandIsland.Transport.socket_stats() - def getstat(%__MODULE__{} = socket) do - socket.transport_module.getstat(socket.socket) - end - - @doc """ - Returns information about the protocol negotiated during transport handshaking (if any). - """ - @spec negotiated_protocol(t()) :: ThousandIsland.Transport.on_negotiated_protocol() - def negotiated_protocol(%__MODULE__{} = socket) do - socket.transport_module.negotiated_protocol(socket.socket) - end - - @doc """ - Returns information about the SSL connection info, if transport is SSL. - """ - @spec connection_information(t()) :: ThousandIsland.Transport.on_connection_information() - def connection_information(%__MODULE__{} = socket) do - socket.transport_module.connection_information(socket.socket) - end - - @doc """ - Returns the telemetry span representing the lifetime of this socket - """ - @spec telemetry_span(t()) :: ThousandIsland.Telemetry.t() - def telemetry_span(%__MODULE__{} = socket) do - socket.span - end -end diff --git a/deps/thousand_island/lib/thousand_island/telemetry.ex b/deps/thousand_island/lib/thousand_island/telemetry.ex deleted file mode 100644 index 42329a0..0000000 --- a/deps/thousand_island/lib/thousand_island/telemetry.ex +++ /dev/null @@ -1,400 +0,0 @@ -defmodule ThousandIsland.Telemetry do - @moduledoc """ - The following telemetry spans are emitted by thousand_island - - ## `[:thousand_island, :listener, *]` - - Represents a Thousand Island server listening to a port - - This span is started by the following event: - - * `[:thousand_island, :listener, :start]` - - Represents the start of the span - - This event contains the following measurements: - - * `monotonic_time`: The time of this event, in `:native` units - - This event contains the following metadata: - - * `telemetry_span_context`: A unique identifier for this span - * `local_address`: The IP address that the listener is bound to - * `local_port`: The port that the listener is bound to - * `transport_module`: The transport module in use - * `transport_options`: Options passed to the transport module at startup - - - This span is ended by the following event: - - * `[:thousand_island, :listener, :stop]` - - Represents the end of the span - - This event contains the following measurements: - - * `monotonic_time`: The time of this event, in `:native` units - * `duration`: The span duration, in `:native` units - - This event contains the following metadata: - - * `telemetry_span_context`: A unique identifier for this span - * `local_address`: The IP address that the listener is bound to - * `local_port`: The port that the listener is bound to - * `transport_module`: The transport module in use - * `transport_options`: Options passed to the transport module at startup - - ## `[:thousand_island, :acceptor, *]` - - Represents a Thousand Island acceptor process listening for connections - - This span is started by the following event: - - * `[:thousand_island, :acceptor, :start]` - - Represents the start of the span - - This event contains the following measurements: - - * `monotonic_time`: The time of this event, in `:native` units - - This event contains the following metadata: - - * `telemetry_span_context`: A unique identifier for this span - * `parent_telemetry_span_context`: The span context of the `:listener` which created this acceptor - - This span is ended by the following event: - - * `[:thousand_island, :acceptor, :stop]` - - Represents the end of the span - - This event contains the following measurements: - - * `monotonic_time`: The time of this event, in `:native` units - * `duration`: The span duration, in `:native` units - * `connections`: The number of client requests that the acceptor handled - - This event contains the following metadata: - - * `telemetry_span_context`: A unique identifier for this span - * `parent_telemetry_span_context`: The span context of the `:listener` which created this acceptor - * `error`: The error that caused the span to end, if it ended in error - - The following events may be emitted within this span: - - * `[:thousand_island, :acceptor, :spawn_error]` - - Thousand Island was unable to spawn a process to handle a connection. This occurs when too - many connections are in progress; you may want to look at increasing the `num_connections` - configuration parameter - - This event contains the following measurements: - - * `monotonic_time`: The time of this event, in `:native` units - - This event contains the following metadata: - - * `telemetry_span_context`: A unique identifier for this span - - * `[:thousand_island, :acceptor, :econnaborted]` - - Thousand Island was unable to spawn a process to handle a connection since the remote end - closed before we could accept it. This usually occurs when it takes too long for your server - to start processing a connection; you may want to look at tuning OS-level TCP parameters or - adding more server capacity. - - This event contains the following measurements: - - * `monotonic_time`: The time of this event, in `:native` units - - This event contains the following metadata: - - * `telemetry_span_context`: A unique identifier for this span - - ## `[:thousand_island, :connection, *]` - - Represents Thousand Island handling a specific client request - - This span is started by the following event: - - * `[:thousand_island, :connection, :start]` - - Represents the start of the span - - This event contains the following measurements: - - * `monotonic_time`: The time of this event, in `:native` units - - This event contains the following metadata: - - * `telemetry_span_context`: A unique identifier for this span - * `parent_telemetry_span_context`: The span context of the `:acceptor` span which accepted - this connection - * `remote_address`: The IP address of the connected client - * `remote_port`: The port of the connected client - - This span is ended by the following event: - - * `[:thousand_island, :connection, :stop]` - - Represents the end of the span - - This event contains the following measurements: - - * `monotonic_time`: The time of this event, in `:native` units - * `duration`: The span duration, in `:native` units - * `send_oct`: The number of octets sent on the connection - * `send_cnt`: The number of packets sent on the connection - * `recv_oct`: The number of octets received on the connection - * `recv_cnt`: The number of packets received on the connection - - This event contains the following metadata: - - * `telemetry_span_context`: A unique identifier for this span - * `parent_telemetry_span_context`: The span context of the `:acceptor` span which accepted - this connection - * `remote_address`: The IP address of the connected client - * `remote_port`: The port of the connected client - * `error`: The error that caused the span to end, if it ended in error - - The following events may be emitted within this span: - - * `[:thousand_island, :connection, :ready]` - - Thousand Island has completed setting up the client connection - - This event contains the following measurements: - - * `monotonic_time`: The time of this event, in `:native` units - - This event contains the following metadata: - - * `telemetry_span_context`: A unique identifier for this span - - * `[:thousand_island, :connection, :async_recv]` - - Thousand Island has asynchronously received data from the client - - This event contains the following measurements: - - * `data`: The data received from the client - - This event contains the following metadata: - - * `telemetry_span_context`: A unique identifier for this span - - * `[:thousand_island, :connection, :recv]` - - Thousand Island has synchronously received data from the client - - This event contains the following measurements: - - * `data`: The data received from the client - - This event contains the following metadata: - - * `telemetry_span_context`: A unique identifier for this span - - * `[:thousand_island, :connection, :recv_error]` - - Thousand Island encountered an error reading data from the client - - This event contains the following measurements: - - * `error`: A description of the error - - This event contains the following metadata: - - * `telemetry_span_context`: A unique identifier for this span - - * `[:thousand_island, :connection, :send]` - - Thousand Island has sent data to the client - - This event contains the following measurements: - - * `data`: The data sent to the client - - This event contains the following metadata: - - * `telemetry_span_context`: A unique identifier for this span - - * `[:thousand_island, :connection, :send_error]` - - Thousand Island encountered an error sending data to the client - - This event contains the following measurements: - - * `data`: The data that was being sent to the client - * `error`: A description of the error - - This event contains the following metadata: - - * `telemetry_span_context`: A unique identifier for this span - - * `[:thousand_island, :connection, :sendfile]` - - Thousand Island has sent a file to the client - - This event contains the following measurements: - - * `filename`: The filename containing data sent to the client - * `offset`: The offset (in bytes) within the file sending started from - * `bytes_written`: The number of bytes written - - This event contains the following metadata: - - * `telemetry_span_context`: A unique identifier for this span - - * `[:thousand_island, :connection, :sendfile_error]` - - Thousand Island encountered an error sending a file to the client - - This event contains the following measurements: - - * `filename`: The filename containing data that was being sent to the client - * `offset`: The offset (in bytes) within the file where sending started from - * `length`: The number of bytes that were attempted to send - * `error`: A description of the error - - This event contains the following metadata: - - * `telemetry_span_context`: A unique identifier for this span - - * `[:thousand_island, :connection, :socket_shutdown]` - - Thousand Island has shutdown the client connection - - This event contains the following measurements: - - * `monotonic_time`: The time of this event, in `:native` units - * `way`: The direction in which the socket was shut down - - This event contains the following metadata: - - * `telemetry_span_context`: A unique identifier for this span - """ - - @enforce_keys [ - :span_name, - :telemetry_span_context, - :start_time, - :start_metadata, - :handler, - :span_metadata - ] - defstruct @enforce_keys - - @type t :: %__MODULE__{ - span_name: span_name(), - telemetry_span_context: reference(), - start_time: integer(), - start_metadata: metadata(), - handler: module(), - span_metadata: metadata() - } - - @type span_name :: :listener | :acceptor | :connection - @type metadata :: :telemetry.event_metadata() - - @typedoc false - @type measurements :: :telemetry.event_measurements() - - @typedoc false - @type event_name :: - :ready - | :spawn_error - | :econnaborted - | :recv_error - | :send_error - | :sendfile_error - | :socket_shutdown - - @typedoc false - @type untimed_event_name :: - :async_recv - | :stop - | :recv - | :send - | :sendfile - - @app_name :thousand_island - - @doc false - @spec start_span(span_name(), measurements(), metadata()) :: t() - def start_span(span_name, measurements, metadata) do - measurements = Map.put_new_lazy(measurements, :monotonic_time, &monotonic_time/0) - telemetry_span_context = make_ref() - metadata = Map.put(metadata, :telemetry_span_context, telemetry_span_context) - _ = event([span_name, :start], measurements, metadata) - - handler = metadata.handler - - # Pre-build the metadata that will be used for all events in this span - span_metadata = %{ - telemetry_span_context: telemetry_span_context, - handler: handler - } - - %__MODULE__{ - span_name: span_name, - telemetry_span_context: telemetry_span_context, - start_time: measurements[:monotonic_time], - start_metadata: metadata, - handler: handler, - span_metadata: span_metadata - } - end - - @doc false - @spec start_child_span(t(), span_name(), measurements(), metadata()) :: t() - def start_child_span(parent_span, span_name, measurements \\ %{}, metadata \\ %{}) do - metadata = - Map.merge(metadata, %{ - parent_telemetry_span_context: parent_span.telemetry_span_context, - handler: parent_span.handler - }) - - start_span(span_name, measurements, metadata) - end - - @doc false - @spec stop_span(t(), measurements(), metadata()) :: :ok - def stop_span(span, measurements \\ %{}, metadata \\ %{}) do - monotonic_time = measurements[:monotonic_time] || monotonic_time() - - measurements = - Map.merge(measurements, %{ - monotonic_time: monotonic_time, - duration: monotonic_time - span.start_time - }) - - metadata = Map.merge(span.start_metadata, metadata) - - untimed_span_event(span, :stop, measurements, metadata) - end - - @doc false - @spec span_event(t(), event_name(), measurements(), metadata()) :: :ok - def span_event(span, name, measurements \\ %{}, metadata \\ %{}) do - measurements = Map.put_new_lazy(measurements, :monotonic_time, &monotonic_time/0) - untimed_span_event(span, name, measurements, metadata) - end - - @doc false - @spec untimed_span_event(t(), event_name() | untimed_event_name(), measurements(), metadata()) :: - :ok - def untimed_span_event(span, name, measurements \\ %{}, metadata \\ %{}) do - metadata = Map.merge(metadata, span.span_metadata) - - event([span.span_name, name], measurements, metadata) - end - - @spec monotonic_time() :: integer - defdelegate monotonic_time, to: System - - defp event(suffix, measurements, metadata) do - :telemetry.execute([@app_name | suffix], measurements, metadata) - end -end diff --git a/deps/thousand_island/lib/thousand_island/transport.ex b/deps/thousand_island/lib/thousand_island/transport.ex deleted file mode 100644 index 24ee01d..0000000 --- a/deps/thousand_island/lib/thousand_island/transport.ex +++ /dev/null @@ -1,220 +0,0 @@ -defmodule ThousandIsland.Transport do - @moduledoc """ - This module describes the behaviour required for Thousand Island to interact - with low-level sockets. It is largely internal to Thousand Island, however users - are free to implement their own versions of this behaviour backed by whatever - underlying transport they choose. Such a module can be used in Thousand Island - by passing its name as the `transport_module` option when starting up a server, - as described in `ThousandIsland`. - """ - - @typedoc "A listener socket used to wait for connections" - @type listener_socket() :: :inet.socket() | :ssl.sslsocket() - - @typedoc "A listener socket options" - @type listen_options() :: - [:inet.inet_backend() | :gen_tcp.listen_option()] | [:ssl.tls_server_option()] - - @typedoc "A socket representing a client connection" - @type socket() :: :inet.socket() | :ssl.sslsocket() - - @typedoc "Information about an endpoint, either remote ('peer') or local" - @type socket_info() :: - {:inet.ip_address(), :inet.port_number()} | :inet.returned_non_ip_address() - - @typedoc "A socket address" - @type address :: - :inet.ip_address() - | :inet.local_address() - | {:local, binary()} - | :unspec - | {:undefined, any()} - @typedoc "Connection statistics for a given socket" - @type socket_stats() :: {:ok, [{:inet.stat_option(), integer()}]} | {:error, :inet.posix()} - - @typedoc "Options which can be set on a socket via setopts/2 (or returned from getopts/1)" - @type socket_get_options() :: [:inet.socket_getopt()] - - @typedoc "Options which can be set on a socket via setopts/2 (or returned from getopts/1)" - @type socket_set_options() :: [:inet.socket_setopt()] - - @typedoc "The direction in which to shutdown a connection in advance of closing it" - @type way() :: :read | :write | :read_write - - @typedoc "The return value from a listen/2 call" - @type on_listen() :: - {:ok, listener_socket()} | {:error, :system_limit} | {:error, :inet.posix()} - - @typedoc "The return value from an accept/1 call" - @type on_accept() :: {:ok, socket()} | {:error, on_accept_tcp_error() | on_accept_ssl_error()} - - @type on_accept_tcp_error() :: :closed | :system_limit | :inet.posix() - @type on_accept_ssl_error() :: :closed | :timeout | :ssl.error_alert() - - @typedoc "The return value from a controlling_process/2 call" - @type on_controlling_process() :: :ok | {:error, :closed | :not_owner | :badarg | :inet.posix()} - - @typedoc "The return value from a handshake/1 call" - @type on_handshake() :: {:ok, socket()} | {:error, on_handshake_ssl_error()} - - @type on_handshake_ssl_error() :: :closed | :timeout | :ssl.error_alert() - - @typedoc "The return value from a upgrade/2 call" - @type on_upgrade() :: {:ok, socket()} | {:error, term()} - - @typedoc "The return value from a shutdown/2 call" - @type on_shutdown() :: :ok | {:error, :inet.posix()} - - @typedoc "The return value from a close/1 call" - @type on_close() :: :ok | {:error, any()} - - @typedoc "The return value from a recv/3 call" - @type on_recv() :: {:ok, binary()} | {:error, :closed | :timeout | :inet.posix()} - - @typedoc "The return value from a send/2 call" - @type on_send() :: :ok | {:error, :closed | {:timeout, rest_data :: binary()} | :inet.posix()} - - @typedoc "The return value from a sendfile/4 call" - @type on_sendfile() :: - {:ok, non_neg_integer()} - | {:error, :inet.posix() | :closed | :badarg | :not_owner | :eof} - - @typedoc "The return value from a getopts/2 call" - @type on_getopts() :: {:ok, [:inet.socket_optval()]} | {:error, :inet.posix()} - - @typedoc "The return value from a setopts/2 call" - @type on_setopts() :: :ok | {:error, :inet.posix()} - - @typedoc "The return value from a sockname/1 call" - @type on_sockname() :: {:ok, socket_info()} | {:error, :inet.posix()} - - @typedoc "The return value from a peername/1 call" - @type on_peername() :: {:ok, socket_info()} | {:error, :inet.posix()} - - @typedoc "The return value from a peercert/1 call" - @type on_peercert() :: {:ok, :public_key.der_encoded()} | {:error, reason :: any()} - - @typedoc "The return value from a connection_information/1 call" - @type on_connection_information() :: {:ok, :ssl.connection_info()} | {:error, reason :: any()} - - @typedoc "The return value from a negotiated_protocol/1 call" - @type on_negotiated_protocol() :: - {:ok, binary()} | {:error, :protocol_not_negotiated | :closed} - - @doc """ - Create and return a listener socket bound to the given port and configured per - the provided options. - """ - @callback listen(:inet.port_number(), listen_options()) :: - {:ok, listener_socket()} | {:error, any()} - - @doc """ - Wait for a client connection on the given listener socket. This call blocks until - such a connection arrives, or an error occurs (such as the listener socket being - closed). - """ - @callback accept(listener_socket()) :: on_accept() - - @doc """ - Performs an initial handshake on a new client connection (such as that done - when negotiating an SSL connection). Transports which do not have such a - handshake can simply pass the socket through unchanged. - """ - @callback handshake(socket()) :: on_handshake() - - @doc """ - Performs an upgrade of an existing client connection (for example upgrading - an already-established connection to SSL). Transports which do not support upgrading can return - `{:error, :unsupported_upgrade}`. - """ - @callback upgrade(socket(), term()) :: on_upgrade() - - @doc """ - Transfers ownership of the given socket to the given process. This will always - be called by the process which currently owns the socket. - """ - @callback controlling_process(socket(), pid()) :: on_controlling_process() - - @doc """ - Returns available bytes on the given socket. Up to `num_bytes` bytes will be - returned (0 can be passed in to get the next 'available' bytes, typically the - next packet). If insufficient bytes are available, the function can wait `timeout` - milliseconds for data to arrive. - """ - @callback recv(socket(), num_bytes :: non_neg_integer(), timeout :: timeout()) :: on_recv() - - @doc """ - Sends the given data (specified as a binary or an IO list) on the given socket. - """ - @callback send(socket(), data :: iodata()) :: on_send() - - @doc """ - Sends the contents of the given file based on the provided offset & length - """ - @callback sendfile( - socket(), - filename :: String.t(), - offset :: non_neg_integer(), - length :: non_neg_integer() - ) :: on_sendfile() - - @doc """ - Gets the given options on the socket. - """ - @callback getopts(socket(), socket_get_options()) :: on_getopts() - - @doc """ - Sets the given options on the socket. Should disallow setting of options which - are not compatible with Thousand Island - """ - @callback setopts(socket(), socket_set_options()) :: on_setopts() - - @doc """ - Shuts down the socket in the given direction. - """ - @callback shutdown(socket(), way()) :: on_shutdown() - - @doc """ - Closes the given socket. - """ - @callback close(socket() | listener_socket()) :: on_close() - - @doc """ - Returns information in the form of `t:socket_info()` about the local end of the socket. - """ - @callback sockname(socket() | listener_socket()) :: on_sockname() - - @doc """ - Returns information in the form of `t:socket_info()` about the remote end of the socket. - """ - @callback peername(socket()) :: on_peername() - - @doc """ - Returns the peer certificate for the given socket in the form of `t:public_key.der_encoded()`. - If the socket is not secure, `{:error, :not_secure}` is returned. - """ - @callback peercert(socket()) :: on_peercert() - - @doc """ - Returns whether or not this protocol is secure. - """ - @callback secure?() :: boolean() - - @doc """ - Returns stats about the connection on the socket. - """ - @callback getstat(socket()) :: socket_stats() - - @doc """ - Returns the protocol negotiated as part of handshaking. Most typically this is via TLS' - ALPN or NPN extensions. If the underlying transport does not support protocol negotiation - (or if one was not negotiated), `{:error, :protocol_not_negotiated}` is returned - """ - @callback negotiated_protocol(socket()) :: on_negotiated_protocol() - - @doc """ - Returns the SSL connection_info for the given socket. If the socket is not secure, - `{:error, :not_secure}` is returned. - """ - @callback connection_information(socket()) :: on_connection_information() -end diff --git a/deps/thousand_island/lib/thousand_island/transports/ssl.ex b/deps/thousand_island/lib/thousand_island/transports/ssl.ex deleted file mode 100644 index 35c81d4..0000000 --- a/deps/thousand_island/lib/thousand_island/transports/ssl.ex +++ /dev/null @@ -1,221 +0,0 @@ -defmodule ThousandIsland.Transports.SSL do - @moduledoc """ - Defines a `ThousandIsland.Transport` implementation based on TCP SSL sockets - as provided by Erlang's `:ssl` module. For the most part, users of Thousand - Island will only ever need to deal with this module via `transport_options` - passed to `ThousandIsland` at startup time. A complete list of such options - is defined via the `t::ssl.tls_server_option/0` type. This list can be somewhat - difficult to decipher; by far the most common values to pass to this transport - are the following: - - * `keyfile`: The path to a PEM encoded key to use for SSL - * `certfile`: The path to a PEM encoded cert to use for SSL - * `ip`: The IP to listen on. Can be specified as: - * `{1, 2, 3, 4}` for IPv4 addresses - * `{1, 2, 3, 4, 5, 6, 7, 8}` for IPv6 addresses - * `:loopback` for local loopback - * `:any` for all interfaces (ie: `0.0.0.0`) - * `{:local, "/path/to/socket"}` for a Unix domain socket. If this option is used, the `port` - option *must* be set to `0`. - - Unless overridden, this module uses the following default options: - - ```elixir - backlog: 1024, - nodelay: true, - send_timeout: 30_000, - send_timeout_close: true, - reuseaddr: true - ``` - - The following options are required for the proper operation of Thousand Island - and cannot be overridden: - - ```elixir - mode: :binary, - active: false - ``` - """ - - @type options() :: [:ssl.tls_server_option()] - @type listener_socket() :: :ssl.sslsocket() - @type socket() :: :ssl.sslsocket() - - @behaviour ThousandIsland.Transport - - @hardcoded_options [mode: :binary, active: false] - - # Default chunk size: 8MB - balances memory usage vs syscall overhead - @sendfile_chunk_size 8 * 1024 * 1024 - - @impl ThousandIsland.Transport - @spec listen(:inet.port_number(), [:ssl.tls_server_option()]) :: - ThousandIsland.Transport.on_listen() - def listen(port, user_options) do - default_options = [ - backlog: 1024, - nodelay: true, - send_timeout: 30_000, - send_timeout_close: true, - reuseaddr: true - ] - - # We can't use Keyword functions here because :ssl accepts non-keyword style options - resolved_options = - Enum.uniq_by( - @hardcoded_options ++ user_options ++ default_options, - fn - {key, _} when is_atom(key) -> key - key when is_atom(key) -> key - end - ) - - if not Enum.any?( - [:certs_keys, :keyfile, :key, :sni_hosts, :sni_fun], - &:proplists.is_defined(&1, resolved_options) - ) do - raise "transport_options must include one of keyfile, key, sni_hosts or sni_fun" - end - - if not Enum.any?( - [:certs_keys, :certfile, :cert, :sni_hosts, :sni_fun], - &:proplists.is_defined(&1, resolved_options) - ) do - raise "transport_options must include one of certfile, cert, sni_hosts or sni_fun" - end - - :ssl.listen(port, resolved_options) - end - - @impl ThousandIsland.Transport - @spec accept(listener_socket()) :: ThousandIsland.Transport.on_accept() - defdelegate accept(listener_socket), to: :ssl, as: :transport_accept - - @impl ThousandIsland.Transport - @spec handshake(socket()) :: ThousandIsland.Transport.on_handshake() - def handshake(socket) do - case :ssl.handshake(socket) do - {:ok, socket, _protocol_extensions} -> {:ok, socket} - other -> other - end - end - - @impl ThousandIsland.Transport - @spec upgrade(socket(), options()) :: ThousandIsland.Transport.on_upgrade() - def upgrade(socket, opts) do - case :ssl.handshake(socket, opts) do - {:ok, socket, _protocol_extensions} -> {:ok, socket} - other -> other - end - end - - @impl ThousandIsland.Transport - @spec controlling_process(socket(), pid()) :: ThousandIsland.Transport.on_controlling_process() - defdelegate controlling_process(socket, pid), to: :ssl - - @impl ThousandIsland.Transport - @spec recv(socket(), non_neg_integer(), timeout()) :: ThousandIsland.Transport.on_recv() - defdelegate recv(socket, length, timeout), to: :ssl - - @impl ThousandIsland.Transport - @spec send(socket(), iodata()) :: ThousandIsland.Transport.on_send() - defdelegate send(socket, data), to: :ssl - - @impl ThousandIsland.Transport - @spec sendfile( - socket(), - filename :: String.t(), - offset :: non_neg_integer(), - length :: non_neg_integer() - ) :: ThousandIsland.Transport.on_sendfile() - def sendfile(socket, filename, offset, length) do - # We can't use :file.sendfile here since it works on clear sockets, not ssl sockets. - # Build our own version with chunking for large files. - case :file.open(filename, [:read, :raw, :binary]) do - {:ok, fd} -> - try do - sendfile_loop(socket, fd, offset, length, 0) - after - :file.close(fd) - end - - {:error, reason} -> - {:error, reason} - end - end - - defp sendfile_loop(_socket, _fd, _offset, sent, sent) when 0 != sent do - {:ok, sent} - end - - defp sendfile_loop(socket, fd, offset, length, sent) do - with read_size <- chunk_size(length, sent, @sendfile_chunk_size), - {:ok, data} <- :file.pread(fd, offset, read_size), - :ok <- :ssl.send(socket, data) do - now_sent = byte_size(data) - sendfile_loop(socket, fd, offset + now_sent, length, sent + now_sent) - else - :eof -> - {:ok, sent} - - {:error, reason} -> - {:error, reason} - end - end - - defp chunk_size(0, _sent, chunk_size), do: chunk_size - defp chunk_size(length, sent, chunk), do: min(length - sent, chunk) - - @impl ThousandIsland.Transport - @spec getopts(socket(), ThousandIsland.Transport.socket_get_options()) :: - ThousandIsland.Transport.on_getopts() - defdelegate getopts(socket, options), to: :ssl - - @impl ThousandIsland.Transport - @spec setopts(socket(), ThousandIsland.Transport.socket_set_options()) :: - ThousandIsland.Transport.on_setopts() - defdelegate setopts(socket, options), to: :ssl - - @impl ThousandIsland.Transport - @spec shutdown(socket(), ThousandIsland.Transport.way()) :: - ThousandIsland.Transport.on_shutdown() - defdelegate shutdown(socket, way), to: :ssl - - @impl ThousandIsland.Transport - @spec close(socket() | listener_socket()) :: ThousandIsland.Transport.on_close() - defdelegate close(socket), to: :ssl - - # :ssl.sockname/1's typespec is incorrect - @dialyzer {:no_match, sockname: 1} - - @impl ThousandIsland.Transport - @spec sockname(socket() | listener_socket()) :: ThousandIsland.Transport.on_sockname() - defdelegate sockname(socket), to: :ssl - - # :ssl.peername/1's typespec is incorrect - @dialyzer {:no_match, peername: 1} - - @impl ThousandIsland.Transport - @spec peername(socket()) :: ThousandIsland.Transport.on_peername() - defdelegate peername(socket), to: :ssl - - @impl ThousandIsland.Transport - @spec peercert(socket()) :: ThousandIsland.Transport.on_peercert() - defdelegate peercert(socket), to: :ssl - - @impl ThousandIsland.Transport - @spec secure?() :: true - def secure?, do: true - - @impl ThousandIsland.Transport - @spec getstat(socket()) :: ThousandIsland.Transport.socket_stats() - defdelegate getstat(socket), to: :ssl - - @impl ThousandIsland.Transport - @spec negotiated_protocol(socket()) :: ThousandIsland.Transport.on_negotiated_protocol() - defdelegate negotiated_protocol(socket), to: :ssl - - @impl ThousandIsland.Transport - @spec connection_information(socket()) :: ThousandIsland.Transport.on_connection_information() - defdelegate connection_information(socket), to: :ssl -end diff --git a/deps/thousand_island/lib/thousand_island/transports/tcp.ex b/deps/thousand_island/lib/thousand_island/transports/tcp.ex deleted file mode 100644 index f0e9e2d..0000000 --- a/deps/thousand_island/lib/thousand_island/transports/tcp.ex +++ /dev/null @@ -1,169 +0,0 @@ -defmodule ThousandIsland.Transports.TCP do - @moduledoc """ - Defines a `ThousandIsland.Transport` implementation based on clear TCP sockets - as provided by Erlang's `:gen_tcp` module. For the most part, users of Thousand - Island will only ever need to deal with this module via `transport_options` - passed to `ThousandIsland` at startup time. A complete list of such options - is defined via the `t::gen_tcp.listen_option/0` type. This list can be somewhat - difficult to decipher; by far the most common value to pass to this transport - is the following: - - * `ip`: The IP to listen on. Can be specified as: - * `{1, 2, 3, 4}` for IPv4 addresses - * `{1, 2, 3, 4, 5, 6, 7, 8}` for IPv6 addresses - * `:loopback` for local loopback - * `:any` for all interfaces (i.e.: `0.0.0.0`) - * `{:local, "/path/to/socket"}` for a Unix domain socket. If this option is used, - the `port` option *must* be set to `0` - - Unless overridden, this module uses the following default options: - - ```elixir - backlog: 1024, - nodelay: true, - send_timeout: 30_000, - send_timeout_close: true, - reuseaddr: true - ``` - - The following options are required for the proper operation of Thousand Island - and cannot be overridden: - - ```elixir - mode: :binary, - active: false - ``` - """ - - @type options() :: [:gen_tcp.listen_option()] - @type listener_socket() :: :inet.socket() - @type socket() :: :inet.socket() - - @behaviour ThousandIsland.Transport - - @hardcoded_options [mode: :binary, active: false] - - @impl ThousandIsland.Transport - @spec listen(:inet.port_number(), [:inet.inet_backend() | :gen_tcp.listen_option()]) :: - ThousandIsland.Transport.on_listen() - def listen(port, user_options) do - default_options = [ - backlog: 1024, - nodelay: true, - send_timeout: 30_000, - send_timeout_close: true, - reuseaddr: true - ] - - # We can't use Keyword functions here because :gen_tcp accepts non-keyword style options - resolved_options = - Enum.uniq_by( - @hardcoded_options ++ user_options ++ default_options, - fn - {key, _} when is_atom(key) -> key - key when is_atom(key) -> key - end - ) - - # `inet_backend`, if present, needs to be the first option - sorted_options = - Enum.sort(resolved_options, fn - _, {:inet_backend, _} -> false - _, _ -> true - end) - - :gen_tcp.listen(port, sorted_options) - end - - @impl ThousandIsland.Transport - @spec accept(listener_socket()) :: ThousandIsland.Transport.on_accept() - defdelegate accept(listener_socket), to: :gen_tcp - - @impl ThousandIsland.Transport - @spec handshake(socket()) :: ThousandIsland.Transport.on_handshake() - def handshake(socket), do: {:ok, socket} - - @impl ThousandIsland.Transport - @spec upgrade(socket(), options()) :: ThousandIsland.Transport.on_upgrade() - def upgrade(_, _), do: {:error, :unsupported_upgrade} - - @impl ThousandIsland.Transport - @spec controlling_process(socket(), pid()) :: ThousandIsland.Transport.on_controlling_process() - defdelegate controlling_process(socket, pid), to: :gen_tcp - - @impl ThousandIsland.Transport - @spec recv(socket(), non_neg_integer(), timeout()) :: ThousandIsland.Transport.on_recv() - defdelegate recv(socket, length, timeout), to: :gen_tcp - - @impl ThousandIsland.Transport - @spec send(socket(), iodata()) :: ThousandIsland.Transport.on_send() - defdelegate send(socket, data), to: :gen_tcp - - @impl ThousandIsland.Transport - @spec sendfile( - socket(), - filename :: String.t(), - offset :: non_neg_integer(), - length :: non_neg_integer() - ) :: ThousandIsland.Transport.on_sendfile() - def sendfile(socket, filename, offset, length) do - case :file.open(filename, [:read, :raw, :binary]) do - {:ok, fd} -> - try do - :file.sendfile(fd, socket, offset, length, []) - after - :file.close(fd) - end - - {:error, reason} -> - {:error, reason} - end - end - - @impl ThousandIsland.Transport - @spec getopts(socket(), ThousandIsland.Transport.socket_get_options()) :: - ThousandIsland.Transport.on_getopts() - defdelegate getopts(socket, options), to: :inet - - @impl ThousandIsland.Transport - @spec setopts(socket(), ThousandIsland.Transport.socket_set_options()) :: - ThousandIsland.Transport.on_setopts() - defdelegate setopts(socket, options), to: :inet - - @impl ThousandIsland.Transport - @spec shutdown(socket(), ThousandIsland.Transport.way()) :: - ThousandIsland.Transport.on_shutdown() - defdelegate shutdown(socket, way), to: :gen_tcp - - @impl ThousandIsland.Transport - @spec close(socket() | listener_socket()) :: :ok - defdelegate close(socket), to: :gen_tcp - - @impl ThousandIsland.Transport - @spec sockname(socket() | listener_socket()) :: ThousandIsland.Transport.on_sockname() - defdelegate sockname(socket), to: :inet - - @impl ThousandIsland.Transport - @spec peername(socket()) :: ThousandIsland.Transport.on_peername() - defdelegate peername(socket), to: :inet - - @impl ThousandIsland.Transport - @spec peercert(socket()) :: ThousandIsland.Transport.on_peercert() - def peercert(_socket), do: {:error, :not_secure} - - @impl ThousandIsland.Transport - @spec secure?() :: false - def secure?, do: false - - @impl ThousandIsland.Transport - @spec getstat(socket()) :: ThousandIsland.Transport.socket_stats() - defdelegate getstat(socket), to: :inet - - @impl ThousandIsland.Transport - @spec negotiated_protocol(socket()) :: ThousandIsland.Transport.on_negotiated_protocol() - def negotiated_protocol(_socket), do: {:error, :protocol_not_negotiated} - - @impl ThousandIsland.Transport - @spec connection_information(socket()) :: ThousandIsland.Transport.on_connection_information() - def connection_information(_socket), do: {:error, :not_secure} -end diff --git a/deps/thousand_island/mix.exs b/deps/thousand_island/mix.exs deleted file mode 100644 index 8e51954..0000000 --- a/deps/thousand_island/mix.exs +++ /dev/null @@ -1,80 +0,0 @@ -defmodule ThousandIsland.MixProject do - use Mix.Project - - def project do - [ - app: :thousand_island, - version: "1.4.3", - elixir: "~> 1.13", - elixirc_paths: elixirc_paths(Mix.env()), - start_permanent: Mix.env() == :prod, - deps: deps(), - dialyzer: dialyzer(), - name: "Thousand Island", - description: "A simple & modern pure Elixir socket server", - source_url: "https://github.com/mtrudel/thousand_island", - package: [ - maintainers: ["Mat Trudel"], - licenses: ["MIT"], - links: %{ - "GitHub" => "https://github.com/mtrudel/thousand_island", - "Changelog" => "https://hexdocs.pm/thousand_island/changelog.html" - }, - files: ["lib", "mix.exs", "README*", "LICENSE*", "CHANGELOG*"] - ], - docs: docs() - ] - end - - def application do - [extra_applications: [:logger, :ssl]] - end - - defp elixirc_paths(:test), do: ["lib", "test/support"] - defp elixirc_paths(_), do: ["lib"] - - defp deps() do - [ - {:telemetry, "~> 0.4 or ~> 1.0"}, - {:machete, ">= 0.0.0", only: [:dev, :test]}, - {:ex_doc, "~> 0.25", only: [:dev, :test], runtime: false}, - {:dialyxir, "~> 1.0", only: [:dev, :test], runtime: false}, - {:credo, "~> 1.5", only: [:dev, :test], runtime: false} - ] - end - - defp dialyzer do - [ - plt_core_path: "priv/plts", - plt_file: {:no_warn, "priv/plts/dialyzer.plt"}, - plt_add_deps: :apps_direct, - plt_add_apps: [:public_key], - flags: [ - "-Werror_handling", - "-Wextra_return", - "-Wmissing_return", - "-Wunknown", - "-Wunmatched_returns", - "-Wunderspecs" - ] - ] - end - - defp docs do - [ - main: "ThousandIsland", - logo: "assets/ex_doc_logo.png", - extras: ["CHANGELOG.md"], - groups_for_extras: [ - Changelog: ~r/CHANGELOG\.md/ - ], - groups_for_modules: [ - Transport: [ - ThousandIsland.Transport, - ThousandIsland.Transports.TCP, - ThousandIsland.Transports.SSL - ] - ] - ] - end -end diff --git a/deps/websock/.hex b/deps/websock/.hex deleted file mode 100644 index 873bbc1..0000000 Binary files a/deps/websock/.hex and /dev/null differ diff --git a/deps/websock/LICENSE b/deps/websock/LICENSE deleted file mode 100644 index 4ab9c9a..0000000 --- a/deps/websock/LICENSE +++ /dev/null @@ -1,21 +0,0 @@ -MIT License - -Copyright (c) 2022 Mat Trudel - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. diff --git a/deps/websock/README.md b/deps/websock/README.md deleted file mode 100644 index 36b6192..0000000 --- a/deps/websock/README.md +++ /dev/null @@ -1,74 +0,0 @@ -# WebSock - -[![Build Status](https://github.com/phoenixframework/websock/workflows/Elixir%20CI/badge.svg)](https://github.com/phoenixframework/websock/actions) -[![Docs](https://img.shields.io/badge/api-docs-green.svg?style=flat)](https://hexdocs.pm/websock) -[![Hex.pm](https://img.shields.io/hexpm/v/websock.svg?style=flat&color=blue)](https://hex.pm/packages/websock) - -WebSock is a specification for apps to service WebSocket connections; you can -think of it as 'Plug for WebSockets'. WebSock abstracts WebSocket support from -servers such as [Bandit][] or [Cowboy][] and exposes a generic WebSocket API to -applications. WebSocket-aware applications such as Phoenix can then be hosted -within a supported web server simply by defining conformance to the `WebSock` -behaviour, in the same manner as how Plug conformance allows their HTTP aspects -to be hosted within an arbitrary web server. - - -Defines the `WebSock` behaviour which describes the functions that -an application such as Phoenix must implement in order to be WebSock compliant; -it is roughly the equivalent of the `Plug` interface, but for WebSocket -connections. It is commonly used in conjunction with the [websock_adapter][] -package which defines concrete adapters on top of [Bandit][] and [Cowboy][]; -the two packages are separate to allow for servers which directly expose -`WebSock` support to depend on just the behaviour. Users will almost always -want to depend on [websock_adapter][] instead of this package. - -## WebSocket Lifecycle - -WebSocket connections go through a well defined lifecycle mediated by `WebSock` -and `WebSock.Adapters`: - -* **This step is outside the scope of the WebSock API**. A client will - attempt to Upgrade an HTTP connection to a WebSocket connection by passing - a specific set of headers in an HTTP request. An application may choose to - determine the feasibility of such an upgrade request however it pleases -* An application will then signal an upgrade to be performed by calling - `WebSockAdapter.upgrade/4`, passing in the `Plug.Conn` to upgrade, along with - the `WebSock` compliant handler module which will handle the connection once - it is upgraded -* The underlying server will then attempt to upgrade the HTTP connection to a WebSocket connection -* Assuming the WebSocket connection is successfully negotiated, WebSock will - call `c:WebSock.init/1` on the configured handler to allow the application to perform any necessary - tasks now that the WebSocket connection is live -* WebSock will call the configured handler's `c:WebSock.handle_in/2` callback - whenever data is received from the client -* WebSock will call the configured handler's `c:WebSock.handle_info/2` callback - whenever other processes send messages to the handler process -* The `WebSock` implementation can send data to the client by returning - a `{:push,...}` tuple from any of the above `handle_*` callbacks -* At any time, `c:WebSock.terminate/2` (if implemented) may be called to indicate a close, error or - timeout condition - -[Cowboy]: https://github.com/ninenines/cowboy -[Bandit]: https://github.com/mtrudel/bandit/ -[websock_adapter]: https://hex.pm/packages/websock_adapter - - -For more information, consult the [docs](https://hexdocs.pm/websock). - -## Installation - -The websock package can be installed by adding `websock` to your list of dependencies in `mix.exs`: - -```elixir -def deps do - [ - {:websock, "~> 0.5"} - ] -end -``` - -Documentation can be found at . - -## License - -MIT diff --git a/deps/websock/hex_metadata.config b/deps/websock/hex_metadata.config deleted file mode 100644 index 689bd27..0000000 --- a/deps/websock/hex_metadata.config +++ /dev/null @@ -1,13 +0,0 @@ -{<<"app">>,<<"websock">>}. -{<<"build_tools">>,[<<"mix">>]}. -{<<"description">>,<<"A specification for WebSocket connections">>}. -{<<"elixir">>,<<"~> 1.9">>}. -{<<"files">>, - [<<"lib">>,<<"lib/websock.ex">>,<<"test">>,<<"test/test_helper.exs">>, - <<"mix.exs">>,<<"README.md">>,<<"LICENSE">>]}. -{<<"licenses">>,[<<"MIT">>]}. -{<<"links">>, - [{<<"GitHub">>,<<"https://github.com/phoenixframework/websock">>}]}. -{<<"name">>,<<"websock">>}. -{<<"requirements">>,[]}. -{<<"version">>,<<"0.5.3">>}. diff --git a/deps/websock/lib/websock.ex b/deps/websock/lib/websock.ex deleted file mode 100644 index 246e599..0000000 --- a/deps/websock/lib/websock.ex +++ /dev/null @@ -1,128 +0,0 @@ -defmodule WebSock do - @external_resource Path.join([__DIR__, "../README.md"]) - - @moduledoc @external_resource - |> File.read!() - |> String.split("") - |> Enum.fetch!(1) - - @typedoc "The type of an implementing module" - @type impl :: module() - - @typedoc "The type of state passed into / returned from `WebSock` callbacks" - @type state :: term() - - @typedoc "Possible data frame types" - @type data_opcode :: :text | :binary - - @typedoc "Possible control frame types" - @type control_opcode :: :ping | :pong - - @typedoc "All possible frame types" - @type opcode :: data_opcode() | control_opcode() - - @typedoc "The structure of an outbound message" - @type message :: {opcode(), iodata() | nil} - - @typedoc "Convenience type for one or many outbound messages" - @type messages :: message() | [message()] - - @typedoc "The result as returned from init, handle_in, handle_control & handle_info calls" - @type handle_result :: - {:push, messages(), state()} - | {:reply, term(), messages(), state()} - | {:ok, state()} - | {:stop, {:shutdown, :restart} | term(), state()} - | {:stop, term(), close_detail(), state()} - | {:stop, term(), close_detail(), messages(), state()} - - @typedoc "Details about why a connection was closed" - @type close_reason :: :normal | :remote | :shutdown | :timeout | {:error, term()} - - @typedoc "Describes the data to send in a connection close frame" - @type close_detail :: integer() | {integer(), iodata() | nil} - - @doc """ - Called by WebSock after a WebSocket connection has been established (that is, after the server - has accepted the connection & the WebSocket handshake has been successfully completed). - Implementations can use this callback to perform tasks such as subscribing the client to any - relevant subscriptions within the application, or any other task which should be undertaken at - the time the connection is established - - The return value from this callback is handled as described in `c:handle_in/2` - """ - @callback init(term()) :: handle_result() - - @doc """ - Called by WebSock when a frame is received from the client. WebSock will only call this function - once a complete frame has been received (that is, once any continuation frames have been - received). - - The return value from this callback are processed as follows: - - * `{:push, messages(), state()}`: The indicated message(s) are sent to the client. The - indicated state value is used to update the socket's current state - * `{:reply, term(), messages(), state()}`: The indicated message(s) are sent to the client. The - indicated state value is used to update the socket's current state. The second element of the - tuple has no semantic meaning in this context and is ignored. This return tuple is included - here solely for backwards compatibility with the `Phoenix.Socket.Transport` behaviour; it is in - all respects semantically identical to the `{:push, ...}` return value previously described - * `{:ok, state()}`: The indicated state value is used to update the socket's current state - * `{:stop, reason :: term(), state()}`: The connection will be closed based on the indicated - reason. If `reason` is `:normal`, `c:terminate/2` will be called with a `reason` value of - `:normal`. If the `reason` is `{:shutdown, :restart}`, the server is restarting and - the WebSocket adapter should close with the `1012` Service Restart code. - In all other cases, it will be called with `{:error, reason}`. Server - implementations should also use this value when determining how to close the connection with - the client - * `{:stop, reason :: term(), close_detail(), state()}`: Similar to the previous clause, but allows - for the explicit setting of either a plain close code or a close code with a body to be sent to - the client - * `{:stop, reason :: term(), close_detail(), messages(), state()}`: Similar to the previous clause, but allows - for the sending of one or more frames before sending the connection close frame to the client - """ - @callback handle_in({binary(), opcode: data_opcode()}, state()) :: handle_result() - - @doc """ - Called by WebSock when a ping or pong frame has been received from the client. Note that - implementations SHOULD NOT send a pong frame in response; this MUST be automatically done by the - web server before this callback has been called. - - Despite the name of this callback, it is not called for connection close frames even though they - are technically control frames. WebSock will handle any received connection - close frames and issue calls to `c:terminate/2` as / if appropriate - - This callback is optional - - The return value from this callback is handled as described in `c:handle_in/2` - """ - @callback handle_control({binary(), opcode: control_opcode()}, state()) :: handle_result() - - @doc """ - Called by WebSock when the socket process receives a `c:GenServer.handle_info/2` call which was - not otherwise processed by the server implementation. - - The return value from this callback is handled as described in `c:handle_in/2` - """ - @callback handle_info(term(), state()) :: handle_result() - - @doc """ - Called by WebSock when a connection is closed. `reason` may be one of the following: - - * `:normal`: The local end shut down the connection normally, by returning a `{:stop, :normal, - state()}` tuple from one of the `WebSock.handle_*` callbacks - * `:remote`: The remote end shut down the connection - * `:shutdown`: The local server is being shut down - * `:timeout`: No data has been sent or received for more than the configured timeout duration - * `{:error, reason}`: An error occurred. This may be the result of error - handling in the local server, or the result of a `WebSock.handle_*` callback returning a `{:stop, - reason, state}` tuple where reason is any value other than `:normal` - - This callback is optional - - The return value of this callback is ignored - """ - @callback terminate(reason :: close_reason(), state()) :: any() - - @optional_callbacks handle_control: 2, terminate: 2 -end diff --git a/deps/websock/mix.exs b/deps/websock/mix.exs deleted file mode 100644 index 0602071..0000000 --- a/deps/websock/mix.exs +++ /dev/null @@ -1,46 +0,0 @@ -defmodule WebSock.MixProject do - use Mix.Project - - def project do - [ - app: :websock, - version: "0.5.3", - elixir: "~> 1.9", - start_permanent: Mix.env() == :prod, - deps: deps(), - dialyzer: dialyzer(), - name: "WebSock", - description: "A specification for WebSocket connections", - source_url: "https://github.com/phoenixframework/websock", - package: [ - files: ["lib", "test", "mix.exs", "README*", "LICENSE*"], - maintainers: ["Mat Trudel"], - licenses: ["MIT"], - links: %{"GitHub" => "https://github.com/phoenixframework/websock"} - ], - docs: [ - extras: [ - "README.md": [title: "README"], - "CHANGELOG.md": [title: "Changelog"] - ], - main: "readme" - ] - ] - end - - def application do - [] - end - - defp deps do - [ - {:ex_doc, ">= 0.0.0", only: :dev, runtime: false}, - {:dialyxir, "~> 1.0", only: [:dev, :test], runtime: false}, - {:credo, "~> 1.0", only: [:dev, :test], runtime: false} - ] - end - - defp dialyzer do - [plt_core_path: "priv/plts", plt_file: {:no_warn, "priv/plts/dialyzer.plt"}] - end -end diff --git a/deps/websock/test/test_helper.exs b/deps/websock/test/test_helper.exs deleted file mode 100644 index 869559e..0000000 --- a/deps/websock/test/test_helper.exs +++ /dev/null @@ -1 +0,0 @@ -ExUnit.start()