logo

pleroma

My custom branche(s) on git.pleroma.social/pleroma/pleroma

incoming_handler.ex (2470B)


  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. defmodule Pleroma.Web.FedSockets.IncomingHandler do
  5. require Logger
  6. alias Pleroma.Web.FedSockets.FedRegistry
  7. alias Pleroma.Web.FedSockets.FedSocket
  8. alias Pleroma.Web.FedSockets.SocketInfo
  9. import HTTPSignatures, only: [validate_conn: 1, split_signature: 1]
  10. @behaviour :cowboy_websocket
  11. def init(req, state) do
  12. shake = FedSocket.shake()
  13. with true <- Pleroma.Config.get([:fed_sockets, :enabled]),
  14. sec_protocol <- :cowboy_req.header("sec-websocket-protocol", req, nil),
  15. headers = %{"(request-target)" => ^shake} <- :cowboy_req.headers(req),
  16. true <- validate_conn(%{req_headers: headers}),
  17. %{"keyId" => origin} <- split_signature(headers["signature"]) do
  18. req =
  19. if is_nil(sec_protocol) do
  20. req
  21. else
  22. :cowboy_req.set_resp_header("sec-websocket-protocol", sec_protocol, req)
  23. end
  24. {:cowboy_websocket, req, %{origin: origin}, %{}}
  25. else
  26. _ ->
  27. {:ok, req, state}
  28. end
  29. end
  30. def websocket_init(%{origin: origin}) do
  31. case FedRegistry.add_fed_socket(origin) do
  32. {:ok, socket_info} ->
  33. {:ok, socket_info}
  34. e ->
  35. Logger.error("FedSocket websocket_init failed - #{inspect(e)}")
  36. {:error, inspect(e)}
  37. end
  38. end
  39. # Use the ping to check if the connection should be expired
  40. def websocket_handle(:ping, socket_info) do
  41. if SocketInfo.expired?(socket_info) do
  42. {:stop, socket_info}
  43. else
  44. {:ok, socket_info, :hibernate}
  45. end
  46. end
  47. def websocket_handle({:text, data}, socket_info) do
  48. socket_info = SocketInfo.touch(socket_info)
  49. case FedSocket.receive_package(socket_info, data) do
  50. {:noreply, _} ->
  51. {:ok, socket_info}
  52. {:reply, reply} ->
  53. {:reply, {:text, Jason.encode!(reply)}, socket_info}
  54. {:error, reason} ->
  55. Logger.error("incoming error - receive_package: #{inspect(reason)}")
  56. {:ok, socket_info}
  57. end
  58. end
  59. def websocket_info({:send, message}, socket_info) do
  60. socket_info = SocketInfo.touch(socket_info)
  61. {:reply, {:text, message}, socket_info}
  62. end
  63. def websocket_info(:close, state) do
  64. {:stop, state}
  65. end
  66. def websocket_info(message, state) do
  67. Logger.debug("#{__MODULE__} unknown message #{inspect(message)}")
  68. {:ok, state}
  69. end
  70. end