Page Menu
Home
Phorge
Search
Configure Global Search
Log In
Files
F85804885
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Award Token
Flag For Later
Size
7 KB
Referenced Files
None
Subscribers
None
View Options
diff --git a/lib/pleroma/gun/connections.ex b/lib/pleroma/gun/connections.ex
index d5a9d8607..82579604a 100644
--- a/lib/pleroma/gun/connections.ex
+++ b/lib/pleroma/gun/connections.ex
@@ -1,125 +1,130 @@
# Pleroma: A lightweight social networking server
# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/>
# SPDX-License-Identifier: AGPL-3.0-only
defmodule Pleroma.Gun.Connections do
use GenServer
@type domain :: String.t()
@type conn :: Gun.Conn.t()
@type t :: %__MODULE__{
conns: %{domain() => conn()}
}
defstruct conns: %{}
def start_link(name \\ __MODULE__) do
if Application.get_env(:tesla, :adapter) == Tesla.Adapter.Gun do
GenServer.start_link(__MODULE__, [], name: name)
else
:ignore
end
end
@impl true
def init(_) do
{:ok, %__MODULE__{conns: %{}}}
end
@spec get_conn(String.t(), keyword(), atom()) :: pid()
def get_conn(url, opts \\ [], name \\ __MODULE__) do
opts = Enum.into(opts, %{})
uri = URI.parse(url)
opts = if uri.scheme == "https", do: Map.put(opts, :transport, :tls), else: opts
GenServer.call(
name,
{:conn, %{opts: opts, uri: uri}}
)
end
# TODO: only for testing, add this parameter to the config
@spec try_to_get_gun_conn(String.t(), keyword(), atom()) :: nil | pid()
def try_to_get_gun_conn(url, opts \\ [], name \\ __MODULE__),
do: try_to_get_gun_conn(url, opts, name, 0)
@spec try_to_get_gun_conn(String.t(), keyword(), atom(), pos_integer()) :: nil | pid()
def try_to_get_gun_conn(_url, _, _, 3), do: nil
def try_to_get_gun_conn(url, opts, name, acc) do
case Pleroma.Gun.Connections.get_conn(url, opts, name) do
nil -> try_to_get_gun_conn(url, acc + 1)
conn -> conn
end
end
@spec alive?(atom()) :: boolean()
def alive?(name \\ __MODULE__) do
pid = Process.whereis(name)
if pid, do: Process.alive?(pid), else: false
end
@spec get_state(atom()) :: t()
def get_state(name \\ __MODULE__) do
GenServer.call(name, {:state})
end
@impl true
def handle_call({:conn, %{opts: opts, uri: uri}}, from, state) do
key = compose_key(uri)
+ IO.inspect(state)
+
+ IO.inspect(key)
+
case state.conns[key] do
%{conn: conn, state: conn_state} when conn_state == :up ->
{:reply, conn, state}
%{state: conn_state, waiting_pids: pids} when conn_state in [:open, :down] ->
state = put_in(state.conns[key].waiting_pids, [from | pids])
{:noreply, state}
nil ->
{:ok, conn} = Pleroma.Gun.API.open(to_charlist(uri.host), uri.port, opts)
state =
put_in(state.conns[key], %Pleroma.Gun.Conn{
conn: conn,
waiting_pids: [from],
protocol: String.to_atom(uri.scheme)
})
+ IO.inspect(state)
{:noreply, state}
end
end
@impl true
def handle_call({:state}, _from, state), do: {:reply, state, state}
@impl true
def handle_info({:gun_up, conn_pid, protocol}, state) do
{key, conn} = find_conn(state.conns, conn_pid, protocol)
# Send to all waiting processes connection pid
Enum.each(conn.waiting_pids, fn waiting_pid -> GenServer.reply(waiting_pid, conn_pid) end)
# Update state of the current connection and set waiting_pids to empty list
state = put_in(state.conns[key], %{conn | state: :up, waiting_pids: []})
{:noreply, state}
end
@impl true
# Do we need to do something with killed & unprocessed references?
def handle_info({:gun_down, conn_pid, protocol, _reason, _killed, _unprocessed}, state) do
{key, conn} = find_conn(state.conns, conn_pid, protocol)
# We don't want to block requests to GenServer if gun send down message, return nil, so we can make some retries, while connection is not up
Enum.each(conn.waiting_pids, fn waiting_pid -> GenServer.reply(waiting_pid, nil) end)
state = put_in(state.conns[key].state, :down)
{:noreply, state}
end
defp compose_key(uri), do: uri.host <> ":" <> to_string(uri.port)
defp find_conn(conns, conn_pid, protocol),
do: Enum.find(conns, fn {_, conn} -> conn.conn == conn_pid and conn.protocol == protocol end)
end
diff --git a/lib/pleroma/http/http.ex b/lib/pleroma/http/http.ex
index 1846749c0..3ad891d11 100644
--- a/lib/pleroma/http/http.ex
+++ b/lib/pleroma/http/http.ex
@@ -1,109 +1,109 @@
# Pleroma: A lightweight social networking server
# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/>
# SPDX-License-Identifier: AGPL-3.0-only
defmodule Pleroma.HTTP do
@moduledoc """
"""
alias Pleroma.HTTP.Connection
alias Pleroma.HTTP.RequestBuilder, as: Builder
@type t :: __MODULE__
@doc """
Builds and perform http request.
# Arguments:
`method` - :get, :post, :put, :delete
`url`
`body`
`headers` - a keyworld list of headers, e.g. `[{"content-type", "text/plain"}]`
`options` - custom, per-request middleware or adapter options
# Returns:
`{:ok, %Tesla.Env{}}` or `{:error, error}`
"""
def request(method, url, body \\ "", headers \\ [], options \\ []) do
try do
options =
process_request_options(options)
|> process_sni_options(url)
adapter_gun? = Application.get_env(:tesla, :adapter) == Tesla.Adapter.Gun
options =
if adapter_gun? and Pleroma.Gun.Connections.alive?() do
get_conn_for_gun(url, options)
else
options
end
params = Keyword.get(options, :params, [])
%{}
|> Builder.method(method)
|> Builder.headers(headers)
|> Builder.opts(options)
|> Builder.url(url)
|> Builder.add_param(:body, :body, body)
|> Builder.add_param(:query, :query, params)
|> Enum.into([])
|> (&Tesla.request(Connection.new(options), &1)).()
rescue
e ->
{:error, e}
catch
:exit, e ->
{:error, e}
end
end
defp get_conn_for_gun(url, options) do
- case Pleroma.Gun.Connections.try_to_get_gun_conn(url) do
+ case Pleroma.Gun.Connections.get_conn(url) do
nil ->
options
conn ->
adapter_opts =
Keyword.get(options, :adapter, [])
|> Keyword.put(:conn, conn)
Keyword.put(options, :adapter, adapter_opts)
end
end
defp process_sni_options(options, nil), do: options
defp process_sni_options(options, url) do
uri = URI.parse(url)
host = uri.host |> to_charlist()
case uri.scheme do
"https" -> options ++ [ssl: [server_name_indication: host]]
_ -> options
end
end
def process_request_options(options) do
Keyword.merge(Pleroma.HTTP.Connection.options([]), options)
end
@doc """
Performs GET request.
See `Pleroma.HTTP.request/5`
"""
def get(url, headers \\ [], options \\ []),
do: request(:get, url, "", headers, options)
@doc """
Performs POST request.
See `Pleroma.HTTP.request/5`
"""
def post(url, body, headers \\ [], options \\ []),
do: request(:post, url, body, headers, options)
end
File Metadata
Details
Attached
Mime Type
text/x-diff
Expires
Sat, Oct 10, 4:43 PM (1 d, 7 h)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
1785358
Default Alt Text
(7 KB)
Attached To
Mode
rPUBE pleroma-upstream
Attached
Detach File
Event Timeline
Log In to Comment