ConnectionPool middleware: Fix connection leak on ReverseProxy redirects
authorrinpatch <rinpatch@sdf.org>
Fri, 4 Sep 2020 19:10:40 +0000 (22:10 +0300)
committerrinpatch <rinpatch@sdf.org>
Fri, 4 Sep 2020 19:10:40 +0000 (22:10 +0300)
Requires a patched Tesla due to upstream not saving opts between
redirects, patch submitted at https://github.com/teamon/tesla/pull/414

lib/pleroma/tesla/middleware/connection_pool.ex
mix.exs
mix.lock

index a435ab4cc5232ab39646fa73687eb7e862a29a35..5909e98d69faba3e88f14a7e25383277b3eb7605 100644 (file)
@@ -15,21 +15,32 @@ defmodule Pleroma.Tesla.Middleware.ConnectionPool do
   def call(%Tesla.Env{url: url, opts: opts} = env, next, _) do
     uri = URI.parse(url)
 
+    # Avoid leaking connections when the middleware is called twice
+    # with body_as: :chunks. We assume only the middleware can set
+    # opts[:adapter][:conn]
+    if opts[:adapter][:conn] do
+      ConnectionPool.release_conn(opts[:adapter][:conn])
+    end
+
     case ConnectionPool.get_conn(uri, opts[:adapter]) do
       {:ok, conn_pid} ->
         adapter_opts = Keyword.merge(opts[:adapter], conn: conn_pid, close_conn: false)
         opts = Keyword.put(opts, :adapter, adapter_opts)
         env = %{env | opts: opts}
-        res = Tesla.run(env, next)
 
-        unless opts[:adapter][:body_as] == :chunks do
-          ConnectionPool.release_conn(conn_pid)
+        case Tesla.run(env, next) do
+          {:ok, env} ->
+            unless opts[:adapter][:body_as] == :chunks do
+              ConnectionPool.release_conn(conn_pid)
+              {:ok, pop_in(env[:opts][:adapter][:conn])}
+            else
+              {:ok, env}
+            end
+
+          err ->
+            ConnectionPool.release_conn(conn_pid)
+            err
         end
-
-        res
-
-      err ->
-        err
     end
   end
 end
diff --git a/mix.exs b/mix.exs
index 4de0c78db6d74c6680a44e8c4f51851ddc8cd415..c324960c5d5307f307de5acec8358e7de3f27ef3 100644 (file)
--- a/mix.exs
+++ b/mix.exs
@@ -134,7 +134,9 @@ defmodule Pleroma.Mixfile do
       {:cachex, "~> 3.2"},
       {:poison, "~> 3.0", override: true},
       {:tesla,
-       github: "teamon/tesla", ref: "af3707078b10793f6a534938e56b963aff82fe3c", override: true},
+       git: "https://git.pleroma.social/pleroma/elixir-libraries/tesla.git",
+       ref: "3a2789d8535f7b520ebbadc4494227e5ba0e5365",
+       override: true},
       {:castore, "~> 0.1"},
       {:cowlib, "~> 2.9", override: true},
       {:gun,
index 874ea9215d4b87389debcc3c1467936a33dde3c7..deb07eb68ee8a138bfc31f1e66d2db6c14ca05a3 100644 (file)
--- a/mix.lock
+++ b/mix.lock
   "swoosh": {:hex, :swoosh, "1.0.0", "c547cfc83f30e12d5d1fdcb623d7de2c2e29a5becfc68bf8f42ba4d23d2c2756", [:mix], [{:cowboy, "~> 1.0.1 or ~> 1.1 or ~> 2.4", [hex: :cowboy, repo: "hexpm", optional: true]}, {:gen_smtp, "~> 0.13", [hex: :gen_smtp, repo: "hexpm", optional: true]}, {:hackney, "~> 1.9", [hex: :hackney, repo: "hexpm", optional: true]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}, {:mail, "~> 0.2", [hex: :mail, repo: "hexpm", optional: true]}, {:mime, "~> 1.1", [hex: :mime, repo: "hexpm", optional: false]}, {:plug_cowboy, ">= 1.0.0", [hex: :plug_cowboy, repo: "hexpm", optional: true]}], "hexpm", "b3b08e463f876cb6167f7168e9ad99a069a724e124bcee61847e0e1ed13f4a0d"},
   "syslog": {:hex, :syslog, "1.1.0", "6419a232bea84f07b56dc575225007ffe34d9fdc91abe6f1b2f254fd71d8efc2", [:rebar3], [], "hexpm", "4c6a41373c7e20587be33ef841d3de6f3beba08519809329ecc4d27b15b659e1"},
   "telemetry": {:hex, :telemetry, "0.4.2", "2808c992455e08d6177322f14d3bdb6b625fbcfd233a73505870d8738a2f4599", [:rebar3], [], "hexpm", "2d1419bd9dda6a206d7b5852179511722e2b18812310d304620c7bd92a13fcef"},
-  "tesla": {:git, "https://github.com/teamon/tesla.git", "af3707078b10793f6a534938e56b963aff82fe3c", [ref: "af3707078b10793f6a534938e56b963aff82fe3c"]},
+  "tesla": {:git, "https://git.pleroma.social/pleroma/elixir-libraries/tesla.git", "3a2789d8535f7b520ebbadc4494227e5ba0e5365", [ref: "3a2789d8535f7b520ebbadc4494227e5ba0e5365"]},
   "timex": {:hex, :timex, "3.6.2", "845cdeb6119e2fef10751c0b247b6c59d86d78554c83f78db612e3290f819bc2", [:mix], [{:combine, "~> 0.10", [hex: :combine, repo: "hexpm", optional: false]}, {:gettext, "~> 0.10", [hex: :gettext, repo: "hexpm", optional: false]}, {:tzdata, "~> 0.1.8 or ~> 0.5 or ~> 1.0.0", [hex: :tzdata, repo: "hexpm", optional: false]}], "hexpm", "26030b46199d02a590be61c2394b37ea25a3664c02fafbeca0b24c972025d47a"},
   "trailing_format_plug": {:hex, :trailing_format_plug, "0.0.7", "64b877f912cf7273bed03379936df39894149e35137ac9509117e59866e10e45", [:mix], [{:plug, "> 0.12.0", [hex: :plug, repo: "hexpm", optional: false]}], "hexpm", "bd4fde4c15f3e993a999e019d64347489b91b7a9096af68b2bdadd192afa693f"},
   "tzdata": {:hex, :tzdata, "1.0.3", "73470ad29dde46e350c60a66e6b360d3b99d2d18b74c4c349dbebbc27a09a3eb", [:mix], [{:hackney, "~> 1.0", [hex: :hackney, repo: "hexpm", optional: false]}], "hexpm", "a6e1ee7003c4d04ecbd21dd3ec690d4c6662db5d3bbdd7262d53cdf5e7c746c1"},