Merge branch 'fix/debian-install-libmagic-typo' into 'develop'
[akkoma] / lib / pleroma / web / fed_sockets / incoming_handler.ex
1 # Pleroma: A lightweight social networking server
2 # Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
3 # SPDX-License-Identifier: AGPL-3.0-only
4
5 defmodule Pleroma.Web.FedSockets.IncomingHandler do
6 require Logger
7
8 alias Pleroma.Web.FedSockets.FedRegistry
9 alias Pleroma.Web.FedSockets.FedSocket
10 alias Pleroma.Web.FedSockets.SocketInfo
11
12 import HTTPSignatures, only: [validate_conn: 1, split_signature: 1]
13
14 @behaviour :cowboy_websocket
15
16 def init(req, state) do
17 shake = FedSocket.shake()
18
19 with true <- Pleroma.Config.get([:fed_sockets, :enabled]),
20 sec_protocol <- :cowboy_req.header("sec-websocket-protocol", req, nil),
21 headers = %{"(request-target)" => ^shake} <- :cowboy_req.headers(req),
22 true <- validate_conn(%{req_headers: headers}),
23 %{"keyId" => origin} <- split_signature(headers["signature"]) do
24 req =
25 if is_nil(sec_protocol) do
26 req
27 else
28 :cowboy_req.set_resp_header("sec-websocket-protocol", sec_protocol, req)
29 end
30
31 {:cowboy_websocket, req, %{origin: origin}, %{}}
32 else
33 _ ->
34 {:ok, req, state}
35 end
36 end
37
38 def websocket_init(%{origin: origin}) do
39 case FedRegistry.add_fed_socket(origin) do
40 {:ok, socket_info} ->
41 {:ok, socket_info}
42
43 e ->
44 Logger.error("FedSocket websocket_init failed - #{inspect(e)}")
45 {:error, inspect(e)}
46 end
47 end
48
49 # Use the ping to check if the connection should be expired
50 def websocket_handle(:ping, socket_info) do
51 if SocketInfo.expired?(socket_info) do
52 {:stop, socket_info}
53 else
54 {:ok, socket_info, :hibernate}
55 end
56 end
57
58 def websocket_handle({:text, data}, socket_info) do
59 socket_info = SocketInfo.touch(socket_info)
60
61 case FedSocket.receive_package(socket_info, data) do
62 {:noreply, _} ->
63 {:ok, socket_info}
64
65 {:reply, reply} ->
66 {:reply, {:text, Jason.encode!(reply)}, socket_info}
67
68 {:error, reason} ->
69 Logger.error("incoming error - receive_package: #{inspect(reason)}")
70 {:ok, socket_info}
71 end
72 end
73
74 def websocket_info({:send, message}, socket_info) do
75 socket_info = SocketInfo.touch(socket_info)
76
77 {:reply, {:text, message}, socket_info}
78 end
79
80 def websocket_info(:close, state) do
81 {:stop, state}
82 end
83
84 def websocket_info(message, state) do
85 Logger.debug("#{__MODULE__} unknown message #{inspect(message)}")
86 {:ok, state}
87 end
88 end