diff --git a/lib/plug/adapters/test/conn.ex b/lib/plug/adapters/test/conn.ex index e396ceb3..c3315ff1 100644 --- a/lib/plug/adapters/test/conn.ex +++ b/lib/plug/adapters/test/conn.ex @@ -1,5 +1,6 @@ defmodule Plug.Adapters.Test.Conn do @behaviour Plug.Conn.Adapter + @already_sent Plug.Conn.Adapter.already_sent() @moduledoc false ## Test helpers @@ -43,7 +44,6 @@ defmodule Plug.Adapters.Test.Conn do | adapter: {__MODULE__, state}, host: uri.host || conn.host || "www.example.com", method: method, - owner: owner, path_info: split_path(uri.path), port: uri.port || conn_port, remote_ip: conn.remote_ip || {127, 0, 0, 1}, @@ -88,7 +88,10 @@ defmodule Plug.Adapters.Test.Conn do do_send(state, status, headers, data) end - def send_chunked(state, _status, _headers), do: {:ok, "", %{state | chunks: ""}} + def send_chunked(%{owner: owner} = state, _status, _headers) do + send(owner, @already_sent) + {:ok, "", %{state | chunks: ""}} + end def chunk(%{method: "HEAD"} = state, _body), do: {:ok, "", state} @@ -98,6 +101,7 @@ defmodule Plug.Adapters.Test.Conn do end defp do_send(%{owner: owner, ref: ref} = state, status, headers, body) do + send(owner, @already_sent) send(owner, {ref, {status, headers, body}}) {:ok, body, state} end diff --git a/lib/plug/conn.ex b/lib/plug/conn.ex index b163ed1a..b0f8221f 100644 --- a/lib/plug/conn.ex +++ b/lib/plug/conn.ex @@ -174,7 +174,6 @@ defmodule Plug.Conn do @type headers :: [{binary, binary}] @type host :: binary @type int_status :: non_neg_integer | nil - @type owner :: pid @type method :: binary @type query_param :: binary | %{optional(binary) => query_param} | [query_param] @type query_params :: %{optional(binary) => query_param} @@ -196,7 +195,7 @@ defmodule Plug.Conn do halted: halted, host: host, method: method, - owner: owner, + owner: pid | nil, params: params | Unfetched.t(), path_info: segments, path_params: query_params, @@ -447,7 +446,7 @@ defmodule Plug.Conn do {:ok, body, payload} = adapter.send_resp(payload, conn.status, conn.resp_headers, conn.resp_body) - send(owner, @already_sent) + owner && send(owner, @already_sent) %{conn | adapter: {adapter, payload}, resp_body: body, state: :sent} end @@ -498,7 +497,7 @@ defmodule Plug.Conn do {:ok, body, payload} = adapter.send_file(payload, conn.status, conn.resp_headers, file, offset, length) - send(owner, @already_sent) + owner && send(owner, @already_sent) %{conn | adapter: {adapter, payload}, state: :file, resp_body: body} end @@ -526,7 +525,7 @@ defmodule Plug.Conn do conn = %{conn | status: Plug.Conn.Status.code(status), resp_body: nil} conn = run_before_send(conn, :set_chunked) {:ok, body, payload} = adapter.send_chunked(payload, conn.status, conn.resp_headers) - send(owner, @already_sent) + owner && send(owner, @already_sent) %{conn | adapter: {adapter, payload}, state: :chunked, resp_body: body} end diff --git a/lib/plug/conn/adapter.ex b/lib/plug/conn/adapter.ex index bf7780aa..280f0ce8 100644 --- a/lib/plug/conn/adapter.ex +++ b/lib/plug/conn/adapter.ex @@ -1,6 +1,13 @@ defmodule Plug.Conn.Adapter do @moduledoc """ Specification of the connection adapter API implemented by webservers. + + ## Implementation recommendations + + The `owner` field of `Plug.Conn` is deprecated and no longer needs to + be set by adapters. If you don't set the `owner` field, it is the + responsibility of the adapters to track the owner and send the + `already_sent/0` message below on any of the `send_*` callbacks. """ alias Plug.Conn @@ -12,6 +19,13 @@ defmodule Plug.Conn.Adapter do ssl_cert: binary | nil } + @doc """ + The message to send to the request process on send callbacks. + """ + def already_sent do + {:plug_conn, :sent} + end + @doc """ Function used by adapters to create a new connection. """ @@ -22,7 +36,6 @@ defmodule Plug.Conn.Adapter do adapter: adapter, host: host, method: method, - owner: self(), path_info: split_path(path), port: port, remote_ip: remote_ip, diff --git a/test/plug/conn_test.exs b/test/plug/conn_test.exs index 371021ed..8b2ef7ed 100644 --- a/test/plug/conn_test.exs +++ b/test/plug/conn_test.exs @@ -1440,8 +1440,7 @@ defmodule Plug.ConnTest do end conn = %Conn{ - adapter: {RaisesOnEmptyChunkAdapter, %{chunks: ""}}, - owner: self(), + adapter: {RaisesOnEmptyChunkAdapter, %{chunks: "", owner: self()}}, state: :unset }