From e10ca35b3de0ca1b32ab5fd57f559a1cec1e5c3e Mon Sep 17 00:00:00 2001 From: William Pitcock Date: Thu, 28 Feb 2019 14:53:54 +0000 Subject: [PATCH 1/7] mix: update dependencies for cowboy 2.0 --- mix.exs | 5 ++--- mix.lock | 10 +++++----- 2 files changed, 7 insertions(+), 8 deletions(-) diff --git a/mix.exs b/mix.exs index 5392d94d1..0fe9c6ec3 100644 --- a/mix.exs +++ b/mix.exs @@ -55,9 +55,8 @@ defp elixirc_paths(_), do: ["lib"] # Type `mix help deps` for examples and options. defp deps do [ - # Until Phoenix 1.4.1 is released - {:phoenix, github: "phoenixframework/phoenix", branch: "v1.4"}, - {:plug_cowboy, "~> 1.0"}, + {:phoenix, "~> 1.4.1"}, + {:plug_cowboy, "~> 2.0"}, {:phoenix_pubsub, "~> 1.1"}, {:phoenix_ecto, "~> 3.3"}, {:postgrex, ">= 0.13.5"}, diff --git a/mix.lock b/mix.lock index 918702444..50e742fbd 100644 --- a/mix.lock +++ b/mix.lock @@ -9,8 +9,8 @@ "comeonin": {:hex, :comeonin, "4.1.1", "c7304fc29b45b897b34142a91122bc72757bc0c295e9e824999d5179ffc08416", [:mix], [{:argon2_elixir, "~> 1.2", [hex: :argon2_elixir, repo: "hexpm", optional: true]}, {:bcrypt_elixir, "~> 0.12.1 or ~> 1.0", [hex: :bcrypt_elixir, repo: "hexpm", optional: true]}, {:pbkdf2_elixir, "~> 0.12", [hex: :pbkdf2_elixir, repo: "hexpm", optional: true]}], "hexpm"}, "connection": {:hex, :connection, "1.0.4", "a1cae72211f0eef17705aaededacac3eb30e6625b04a6117c1b2db6ace7d5976", [:mix], [], "hexpm"}, "cors_plug": {:hex, :cors_plug, "1.5.2", "72df63c87e4f94112f458ce9d25800900cc88608c1078f0e4faddf20933eda6e", [:mix], [{:plug, "~> 1.3 or ~> 1.4 or ~> 1.5", [hex: :plug, repo: "hexpm", optional: false]}], "hexpm"}, - "cowboy": {:hex, :cowboy, "1.1.2", "61ac29ea970389a88eca5a65601460162d370a70018afe6f949a29dca91f3bb0", [:rebar3], [{:cowlib, "~> 1.0.2", [hex: :cowlib, repo: "hexpm", optional: false]}, {:ranch, "~> 1.3.2", [hex: :ranch, repo: "hexpm", optional: false]}], "hexpm"}, - "cowlib": {:hex, :cowlib, "1.0.2", "9d769a1d062c9c3ac753096f868ca121e2730b9a377de23dec0f7e08b1df84ee", [:make], [], "hexpm"}, + "cowboy": {:hex, :cowboy, "2.6.1", "f2e06f757c337b3b311f9437e6e072b678fcd71545a7b2865bdaa154d078593f", [:rebar3], [{:cowlib, "~> 2.7.0", [hex: :cowlib, repo: "hexpm", optional: false]}, {:ranch, "~> 1.7.1", [hex: :ranch, repo: "hexpm", optional: false]}], "hexpm"}, + "cowlib": {:hex, :cowlib, "2.7.0", "3ef16e77562f9855a2605900cedb15c1462d76fb1be6a32fc3ae91973ee543d2", [:rebar3], [], "hexpm"}, "credo": {:hex, :credo, "0.9.3", "76fa3e9e497ab282e0cf64b98a624aa11da702854c52c82db1bf24e54ab7c97a", [:mix], [{:bunt, "~> 0.2.0", [hex: :bunt, repo: "hexpm", optional: false]}, {:poison, ">= 0.0.0", [hex: :poison, repo: "hexpm", optional: false]}], "hexpm"}, "crypt": {:git, "https://github.com/msantos/crypt", "1f2b58927ab57e72910191a7ebaeff984382a1d3", [ref: "1f2b58927ab57e72910191a7ebaeff984382a1d3"]}, "db_connection": {:hex, :db_connection, "1.1.3", "89b30ca1ef0a3b469b1c779579590688561d586694a3ce8792985d4d7e575a61", [:mix], [{:connection, "~> 1.0.2", [hex: :connection, repo: "hexpm", optional: false]}, {:poolboy, "~> 1.5", [hex: :poolboy, repo: "hexpm", optional: true]}, {:sbroker, "~> 1.0", [hex: :sbroker, repo: "hexpm", optional: true]}], "hexpm"}, @@ -45,17 +45,17 @@ "nimble_parsec": {:hex, :nimble_parsec, "0.4.0", "ee261bb53214943679422be70f1658fff573c5d0b0a1ecd0f18738944f818efe", [:mix], [], "hexpm"}, "parse_trans": {:hex, :parse_trans, "3.3.0", "09765507a3c7590a784615cfd421d101aec25098d50b89d7aa1d66646bc571c1", [:rebar3], [], "hexpm"}, "pbkdf2_elixir": {:hex, :pbkdf2_elixir, "0.12.3", "6706a148809a29c306062862c803406e88f048277f6e85b68faf73291e820b84", [:mix], [], "hexpm"}, - "phoenix": {:git, "https://github.com/phoenixframework/phoenix.git", "ea22dc50b574178a300ecd19253443960407df93", [branch: "v1.4"]}, + "phoenix": {:hex, :phoenix, "1.4.1", "801f9d632808657f1f7c657c8bbe624caaf2ba91429123ebe3801598aea4c3d9", [:mix], [{:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: true]}, {:phoenix_pubsub, "~> 1.1", [hex: :phoenix_pubsub, repo: "hexpm", optional: false]}, {:plug, "~> 1.7", [hex: :plug, repo: "hexpm", optional: false]}, {:plug_cowboy, "~> 1.0 or ~> 2.0", [hex: :plug_cowboy, repo: "hexpm", optional: true]}], "hexpm"}, "phoenix_ecto": {:hex, :phoenix_ecto, "3.3.0", "702f6e164512853d29f9d20763493f2b3bcfcb44f118af2bc37bb95d0801b480", [:mix], [{:ecto, "~> 2.1", [hex: :ecto, repo: "hexpm", optional: false]}, {:phoenix_html, "~> 2.9", [hex: :phoenix_html, repo: "hexpm", optional: true]}, {:plug, "~> 1.0", [hex: :plug, repo: "hexpm", optional: false]}], "hexpm"}, "phoenix_html": {:hex, :phoenix_html, "2.13.1", "fa8f034b5328e2dfa0e4131b5569379003f34bc1fafdaa84985b0b9d2f12e68b", [:mix], [{:plug, "~> 1.5", [hex: :plug, repo: "hexpm", optional: false]}], "hexpm"}, "phoenix_pubsub": {:hex, :phoenix_pubsub, "1.1.1", "6668d787e602981f24f17a5fbb69cc98f8ab085114ebfac6cc36e10a90c8e93c", [:mix], [], "hexpm"}, "plug": {:hex, :plug, "1.7.2", "d7b7db7fbd755e8283b6c0a50be71ec0a3d67d9213d74422d9372effc8e87fd1", [:mix], [{:mime, "~> 1.0", [hex: :mime, repo: "hexpm", optional: false]}, {:plug_crypto, "~> 1.0", [hex: :plug_crypto, repo: "hexpm", optional: false]}], "hexpm"}, - "plug_cowboy": {:hex, :plug_cowboy, "1.0.0", "2e2a7d3409746d335f451218b8bb0858301c3de6d668c3052716c909936eb57a", [:mix], [{:cowboy, "~> 1.0", [hex: :cowboy, repo: "hexpm", optional: false]}, {:plug, "~> 1.7", [hex: :plug, repo: "hexpm", optional: false]}], "hexpm"}, + "plug_cowboy": {:hex, :plug_cowboy, "2.0.1", "d798f8ee5acc86b7d42dbe4450b8b0dadf665ce588236eb0a751a132417a980e", [:mix], [{:cowboy, "~> 2.5", [hex: :cowboy, repo: "hexpm", optional: false]}, {:plug, "~> 1.7", [hex: :plug, repo: "hexpm", optional: false]}], "hexpm"}, "plug_crypto": {:hex, :plug_crypto, "1.0.0", "18e49317d3fa343f24620ed22795ec29d4a5e602d52d1513ccea0b07d8ea7d4d", [:mix], [], "hexpm"}, "poison": {:hex, :poison, "3.1.0", "d9eb636610e096f86f25d9a46f35a9facac35609a7591b3be3326e99a0484665", [:mix], [], "hexpm"}, "poolboy": {:hex, :poolboy, "1.5.1", "6b46163901cfd0a1b43d692657ed9d7e599853b3b21b95ae5ae0a777cf9b6ca8", [:rebar], [], "hexpm"}, "postgrex": {:hex, :postgrex, "0.13.5", "3d931aba29363e1443da167a4b12f06dcd171103c424de15e5f3fc2ba3e6d9c5", [:mix], [{:connection, "~> 1.0", [hex: :connection, repo: "hexpm", optional: false]}, {:db_connection, "~> 1.1", [hex: :db_connection, repo: "hexpm", optional: false]}, {:decimal, "~> 1.0", [hex: :decimal, repo: "hexpm", optional: false]}], "hexpm"}, - "ranch": {:hex, :ranch, "1.3.2", "e4965a144dc9fbe70e5c077c65e73c57165416a901bd02ea899cfd95aa890986", [:rebar3], [], "hexpm"}, + "ranch": {:hex, :ranch, "1.7.1", "6b1fab51b49196860b733a49c07604465a47bdb78aa10c1c16a3d199f7f8c881", [:rebar3], [], "hexpm"}, "ssl_verify_fun": {:hex, :ssl_verify_fun, "1.1.4", "f0eafff810d2041e93f915ef59899c923f4568f4585904d010387ed74988e77b", [:make, :mix, :rebar3], [], "hexpm"}, "swoosh": {:hex, :swoosh, "0.20.0", "9a6c13822c9815993c03b6f8fccc370fcffb3c158d9754f67b1fdee6b3a5d928", [:mix], [{:cowboy, "~> 1.0.1 or ~> 1.1 or ~> 2.4", [hex: :cowboy, repo: "hexpm", optional: true]}, {:gen_smtp, "~> 0.12", [hex: :gen_smtp, repo: "hexpm", optional: true]}, {:hackney, "~> 1.9", [hex: :hackney, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}, {:mime, "~> 1.1", [hex: :mime, repo: "hexpm", optional: false]}, {:plug, "~> 1.4", [hex: :plug, repo: "hexpm", optional: true]}], "hexpm"}, "syslog": {:git, "https://github.com/Vagabond/erlang-syslog.git", "4a6c6f2c996483e86c1320e9553f91d337bcb6aa", [tag: "1.0.5"]}, From bc53dff5b6c7814a1cfeca43fc2a843e1e306501 Mon Sep 17 00:00:00 2001 From: William Pitcock Date: Thu, 28 Feb 2019 15:17:01 +0000 Subject: [PATCH 2/7] mastodon api: websocket: update code for cowboy 2.x --- .../web/mastodon_api/websocket_handler.ex | 39 +++++++++---------- 1 file changed, 18 insertions(+), 21 deletions(-) diff --git a/lib/pleroma/web/mastodon_api/websocket_handler.ex b/lib/pleroma/web/mastodon_api/websocket_handler.ex index ea75070c4..f19f26b9a 100644 --- a/lib/pleroma/web/mastodon_api/websocket_handler.ex +++ b/lib/pleroma/web/mastodon_api/websocket_handler.ex @@ -9,7 +9,7 @@ defmodule Pleroma.Web.MastodonAPI.WebsocketHandler do alias Pleroma.Repo alias Pleroma.User - @behaviour :cowboy_websocket_handler + @behaviour :cowboy_websocket @streams [ "public", @@ -23,40 +23,37 @@ defmodule Pleroma.Web.MastodonAPI.WebsocketHandler do ] @anonymous_streams ["public", "public:local", "hashtag"] - # Handled by periodic keepalive in Pleroma.Web.Streamer. - @timeout :infinity - - def init(_type, _req, _opts) do - {:upgrade, :protocol, :cowboy_websocket} - end - - def websocket_init(_type, req, _opts) do + def init(req, _state) do with {qs, req} <- :cowboy_req.qs(req), params <- :cow_qs.parse_qs(qs), access_token <- List.keyfind(params, "access_token", 0), {_, stream} <- List.keyfind(params, "stream", 0), {:ok, user} <- allow_request(stream, access_token), topic when is_binary(topic) <- expand_topic(stream, params) do - send(self(), :subscribe) - {:ok, req, %{user: user, topic: topic}, @timeout} + {:cowboy_websocket, req, %{user: user, topic: topic}} else {:error, code} -> Logger.debug("#{__MODULE__} denied connection: #{inspect(code)} - #{inspect(req)}") {:ok, req} = :cowboy_req.reply(code, req) - {:shutdown, req} + {:stop, req} error -> Logger.debug("#{__MODULE__} denied connection: #{inspect(error)} - #{inspect(req)}") - {:shutdown, req} + {:stop, req} end end - # We never receive messages. - def websocket_handle(_frame, req, state) do - {:ok, req, state} + def websocket_init(state) do + send(self(), :subscribe) + {:ok, state} end - def websocket_info(:subscribe, req, state) do + # We never receive messages. + def websocket_handle(_frame, state) do + {:ok, state} + end + + def websocket_info(:subscribe, state) do Logger.debug( "#{__MODULE__} accepted websocket connection for user #{ (state.user || %{id: "anonymous"}).id @@ -64,14 +61,14 @@ def websocket_info(:subscribe, req, state) do ) Pleroma.Web.Streamer.add_socket(state.topic, streamer_socket(state)) - {:ok, req, state} + {:ok, state} end - def websocket_info({:text, message}, req, state) do - {:reply, {:text, message}, req, state} + def websocket_info({:text, message}, state) do + {:reply, {:text, message}, state} end - def websocket_terminate(reason, _req, state) do + def terminate(reason, _req, state) do Logger.debug( "#{__MODULE__} terminating websocket connection for user #{ (state.user || %{id: "anonymous"}).id From 9aec00d71101b848aab6b61ad6c5335284fb339b Mon Sep 17 00:00:00 2001 From: William Pitcock Date: Thu, 28 Feb 2019 15:43:38 +0000 Subject: [PATCH 3/7] config: update config for cowboy 2 endpoints --- config/config.exs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/config/config.exs b/config/config.exs index 7e4ac1100..374b4d86b 100644 --- a/config/config.exs +++ b/config/config.exs @@ -93,10 +93,10 @@ dispatch: [ {:_, [ - {"/api/v1/streaming", Elixir.Pleroma.Web.MastodonAPI.WebsocketHandler, []}, - {"/socket/websocket", Phoenix.Endpoint.CowboyWebSocket, + {"/api/v1/streaming", Pleroma.Web.MastodonAPI.WebsocketHandler, []}, + {"/socket/websocket", Phoenix.Endpoint.CowboyWebsocket, {nil, {Pleroma.Web.Endpoint, Pleroma.Web.UserSocket, websocket_config}}}, - {:_, Plug.Adapters.Cowboy.Handler, {Pleroma.Web.Endpoint, []}} + {:_, Phoenix.Endpoint.Cowboy2Handler, {Pleroma.Web.Endpoint, []}} ]} ] ], From f1d37a5e2399d06c8a2178c98825e77e5b381460 Mon Sep 17 00:00:00 2001 From: William Pitcock Date: Thu, 28 Feb 2019 16:02:48 +0000 Subject: [PATCH 4/7] mastodon websocket: use pattern match to get query data, robustly handle errors --- lib/pleroma/web/mastodon_api/websocket_handler.ex | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/lib/pleroma/web/mastodon_api/websocket_handler.ex b/lib/pleroma/web/mastodon_api/websocket_handler.ex index f19f26b9a..edab961f0 100644 --- a/lib/pleroma/web/mastodon_api/websocket_handler.ex +++ b/lib/pleroma/web/mastodon_api/websocket_handler.ex @@ -23,9 +23,8 @@ defmodule Pleroma.Web.MastodonAPI.WebsocketHandler do ] @anonymous_streams ["public", "public:local", "hashtag"] - def init(req, _state) do - with {qs, req} <- :cowboy_req.qs(req), - params <- :cow_qs.parse_qs(qs), + def init(%{qs: qs} = req, _state) do + with params <- :cow_qs.parse_qs(qs), access_token <- List.keyfind(params, "access_token", 0), {_, stream} <- List.keyfind(params, "stream", 0), {:ok, user} <- allow_request(stream, access_token), @@ -39,6 +38,7 @@ def init(req, _state) do error -> Logger.debug("#{__MODULE__} denied connection: #{inspect(error)} - #{inspect(req)}") + {:ok, req} = :cowboy_req.reply(400, req) {:stop, req} end end From 388a3f4ca2299faca366f6dc19485dc03c307aa5 Mon Sep 17 00:00:00 2001 From: William Pitcock Date: Thu, 28 Feb 2019 16:23:24 +0000 Subject: [PATCH 5/7] mastodon websocket: bring back infinity timeout --- lib/pleroma/web/mastodon_api/websocket_handler.ex | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/lib/pleroma/web/mastodon_api/websocket_handler.ex b/lib/pleroma/web/mastodon_api/websocket_handler.ex index edab961f0..bb7ecad69 100644 --- a/lib/pleroma/web/mastodon_api/websocket_handler.ex +++ b/lib/pleroma/web/mastodon_api/websocket_handler.ex @@ -23,13 +23,16 @@ defmodule Pleroma.Web.MastodonAPI.WebsocketHandler do ] @anonymous_streams ["public", "public:local", "hashtag"] - def init(%{qs: qs} = req, _state) do + # Handled by periodic keepalive in Pleroma.Web.Streamer. + @timeout :infinity + + def init(%{qs: qs} = req, state) do with params <- :cow_qs.parse_qs(qs), access_token <- List.keyfind(params, "access_token", 0), {_, stream} <- List.keyfind(params, "stream", 0), {:ok, user} <- allow_request(stream, access_token), topic when is_binary(topic) <- expand_topic(stream, params) do - {:cowboy_websocket, req, %{user: user, topic: topic}} + {:cowboy_websocket, req, %{user: user, topic: topic}, %{idle_timeout: @timeout}} else {:error, code} -> Logger.debug("#{__MODULE__} denied connection: #{inspect(code)} - #{inspect(req)}") From 28b40932335e1b31a240f51740ace415ab558f43 Mon Sep 17 00:00:00 2001 From: William Pitcock Date: Thu, 28 Feb 2019 16:23:55 +0000 Subject: [PATCH 6/7] mastodon websocket: return errors using ok, not stop --- lib/pleroma/web/mastodon_api/websocket_handler.ex | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/pleroma/web/mastodon_api/websocket_handler.ex b/lib/pleroma/web/mastodon_api/websocket_handler.ex index bb7ecad69..8efe2efd5 100644 --- a/lib/pleroma/web/mastodon_api/websocket_handler.ex +++ b/lib/pleroma/web/mastodon_api/websocket_handler.ex @@ -37,12 +37,12 @@ def init(%{qs: qs} = req, state) do {:error, code} -> Logger.debug("#{__MODULE__} denied connection: #{inspect(code)} - #{inspect(req)}") {:ok, req} = :cowboy_req.reply(code, req) - {:stop, req} + {:ok, req, state} error -> Logger.debug("#{__MODULE__} denied connection: #{inspect(error)} - #{inspect(req)}") {:ok, req} = :cowboy_req.reply(400, req) - {:stop, req} + {:ok, req, state} end end From 6b2a1ad1c84b7ef350b0d0be76d6b2e03c633260 Mon Sep 17 00:00:00 2001 From: William Pitcock Date: Thu, 28 Feb 2019 16:58:00 +0000 Subject: [PATCH 7/7] config: fix chat endpoint path --- config/config.exs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/config/config.exs b/config/config.exs index 374b4d86b..a620e7451 100644 --- a/config/config.exs +++ b/config/config.exs @@ -94,8 +94,9 @@ {:_, [ {"/api/v1/streaming", Pleroma.Web.MastodonAPI.WebsocketHandler, []}, - {"/socket/websocket", Phoenix.Endpoint.CowboyWebsocket, - {nil, {Pleroma.Web.Endpoint, Pleroma.Web.UserSocket, websocket_config}}}, + {"/websocket", Phoenix.Endpoint.CowboyWebSocket, + {Phoenix.Transports.WebSocket, + {Pleroma.Web.Endpoint, Pleroma.Web.UserSocket, websocket_config}}}, {:_, Phoenix.Endpoint.Cowboy2Handler, {Pleroma.Web.Endpoint, []}} ]} ]