summaryrefslogtreecommitdiff
path: root/lib/pleroma/web/fed_sockets.ex
diff options
context:
space:
mode:
Diffstat (limited to 'lib/pleroma/web/fed_sockets.ex')
-rw-r--r--lib/pleroma/web/fed_sockets.ex185
1 files changed, 0 insertions, 185 deletions
diff --git a/lib/pleroma/web/fed_sockets.ex b/lib/pleroma/web/fed_sockets.ex
deleted file mode 100644
index 1fd5899c8..000000000
--- a/lib/pleroma/web/fed_sockets.ex
+++ /dev/null
@@ -1,185 +0,0 @@
-# Pleroma: A lightweight social networking server
-# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
-# SPDX-License-Identifier: AGPL-3.0-only
-
-defmodule Pleroma.Web.FedSockets do
- @moduledoc """
- This documents the FedSockets framework. A framework for federating
- ActivityPub objects between servers via persistant WebSocket connections.
-
- FedSockets allow servers to authenticate on first contact and maintain that
- connection, eliminating the need to authenticate every time data needs to be shared.
-
- ## Protocol
- FedSockets currently support 2 types of data transfer:
- * `publish` method which doesn't require a response
- * `fetch` method requires a response be sent
-
- ### Publish
- The publish operation sends a json encoded map of the shape:
- %{action: :publish, data: json}
- and accepts (but does not require) a reply of form:
- %{"action" => "publish_reply"}
-
- The outgoing params represent
- * data: ActivityPub object encoded into json
-
-
- ### Fetch
- The fetch operation sends a json encoded map of the shape:
- %{action: :fetch, data: id, uuid: fetch_uuid}
- and requires a reply of form:
- %{"action" => "fetch_reply", "uuid" => uuid, "data" => data}
-
- The outgoing params represent
- * id: an ActivityPub object URI
- * uuid: a unique uuid generated by the sender
-
- The reply params represent
- * data: an ActivityPub object encoded into json
- * uuid: the uuid sent along with the fetch request
-
- ## Examples
- Clients of FedSocket transfers shouldn't need to use any of the functions outside of this module.
-
- A typical publish operation can be performed through the following code, and a fetch operation in a similar manner.
-
- case FedSockets.get_or_create_fed_socket(inbox) do
- {:ok, fedsocket} ->
- FedSockets.publish(fedsocket, json)
-
- _ ->
- alternative_publish(inbox, actor, json, params)
- end
-
- ## Configuration
- FedSockets have the following config settings
-
- config :pleroma, :fed_sockets,
- enabled: true,
- ping_interval: :timer.seconds(15),
- connection_duration: :timer.hours(1),
- rejection_duration: :timer.hours(1),
- fed_socket_fetches: [
- default: 12_000,
- interval: 3_000,
- lazy: false
- ]
- * enabled - turn FedSockets on or off with this flag. Can be toggled at runtime.
- * connection_duration - How long a FedSocket can sit idle before it's culled.
- * rejection_duration - After failing to make a FedSocket connection a host will be excluded
- from further connections for this amount of time
- * fed_socket_fetches - Use these parameters to pass options to the Cachex queue backing the FetchRegistry
- * fed_socket_rejections - Use these parameters to pass options to the Cachex queue backing the FedRegistry
-
- Cachex options are
- * default: the minimum amount of time a fetch can wait before it times out.
- * interval: the interval between checks for timed out entries. This plus the default represent the maximum time allowed
- * lazy: leave at false for consistant and fast lookups, set to true for stricter timeout enforcement
-
- """
- require Logger
-
- alias Pleroma.Web.FedSockets.FedRegistry
- alias Pleroma.Web.FedSockets.FedSocket
- alias Pleroma.Web.FedSockets.SocketInfo
-
- @doc """
- returns a FedSocket for the given origin. Will reuse an existing one or create a new one.
-
- address is expected to be a fully formed URL such as:
- "http://www.example.com" or "http://www.example.com:8080"
-
- It can and usually does include additional path parameters,
- but these are ignored as the FedSockets are organized by host and port info alone.
- """
- def get_or_create_fed_socket(address) do
- with {:cache, {:error, :missing}} <- {:cache, get_fed_socket(address)},
- {:connect, {:ok, _pid}} <- {:connect, FedSocket.connect_to_host(address)},
- {:cache, {:ok, fed_socket}} <- {:cache, get_fed_socket(address)} do
- Logger.debug("fedsocket created for - #{inspect(address)}")
- {:ok, fed_socket}
- else
- {:cache, {:ok, socket}} ->
- Logger.debug("fedsocket found in cache - #{inspect(address)}")
- {:ok, socket}
-
- {:cache, {:error, :rejected} = e} ->
- e
-
- {:connect, {:error, _host}} ->
- Logger.debug("set host rejected for - #{inspect(address)}")
- FedRegistry.set_host_rejected(address)
- {:error, :rejected}
-
- {_, {:error, :disabled}} ->
- {:error, :disabled}
-
- {_, {:error, reason}} ->
- Logger.warn("get_or_create_fed_socket error - #{inspect(reason)}")
- {:error, reason}
- end
- end
-
- @doc """
- returns a FedSocket for the given origin. Will not create a new FedSocket if one does not exist.
-
- address is expected to be a fully formed URL such as:
- "http://www.example.com" or "http://www.example.com:8080"
- """
- def get_fed_socket(address) do
- origin = SocketInfo.origin(address)
-
- with {:config, true} <- {:config, Pleroma.Config.get([:fed_sockets, :enabled], false)},
- {:ok, socket} <- FedRegistry.get_fed_socket(origin) do
- {:ok, socket}
- else
- {:config, _} ->
- {:error, :disabled}
-
- {:error, :rejected} ->
- Logger.debug("FedSocket previously rejected - #{inspect(origin)}")
- {:error, :rejected}
-
- {:error, reason} ->
- {:error, reason}
- end
- end
-
- @doc """
- Sends the supplied data via the publish protocol.
- It will not block waiting for a reply.
- Returns :ok but this is not an indication of a successful transfer.
-
- the data is expected to be JSON encoded binary data.
- """
- def publish(%SocketInfo{} = fed_socket, json) do
- FedSocket.publish(fed_socket, json)
- end
-
- @doc """
- Sends the supplied data via the fetch protocol.
- It will block waiting for a reply or timeout.
-
- Returns {:ok, object} where object is the requested object (or nil)
- {:error, :timeout} in the event the message was not responded to
-
- the id is expected to be the URI of an ActivityPub object.
- """
- def fetch(%SocketInfo{} = fed_socket, id) do
- FedSocket.fetch(fed_socket, id)
- end
-
- @doc """
- Disconnect all and restart FedSockets.
- This is mainly used in development and testing but could be useful in production.
- """
- def reset do
- FedRegistry
- |> Process.whereis()
- |> Process.exit(:testing)
- end
-
- def uri_for_origin(origin),
- do: "ws://#{origin}/api/fedsocket/v1"
-end