Current section

14 Versions

Jump to

Compare versions

5 files changed
+94 additions
-5 deletions
  @@ -2,6 +2,13 @@
2 2
3 3 ## Unreleased
4 4
5 + ## v0.6.0
6 +
7 + ### `Combo.Conn`
8 +
9 + - add `put_previous_url/2`, `get_previous_url/1` for URL tracking
10 + - add `redirect_back/2`
11 +
5 12 ## v0.5.0
6 13
7 14 ### `Combo`
  @@ -1,9 +1,9 @@
1 1 {<<"links">>,
2 2 [{<<"Source">>,<<"https://github.com/combo-lab/combo">>},
3 3 {<<"Changelog">>,
4 - <<"https://github.com/combo-lab/combo/blob/v0.5.1/CHANGELOG.md">>}]}.
4 + <<"https://github.com/combo-lab/combo/blob/v0.6.0/CHANGELOG.md">>}]}.
5 5 {<<"name">>,<<"combo">>}.
6 - {<<"version">>,<<"0.5.1">>}.
6 + {<<"version">>,<<"0.6.0">>}.
7 7 {<<"description">>,
8 8 <<"A web framework, that combines the good parts of modern web development.">>}.
9 9 {<<"elixir">>,<<"~> 1.18">>}.
  @@ -11,8 +11,8 @@ defmodule Combo.Conn do
11 11 put_private: 3,
12 12 get_session: 2,
13 13 put_session: 3,
14 - get_req_header: 2,
15 14 delete_session: 2,
15 + get_req_header: 2,
16 16 get_resp_header: 2,
17 17 put_resp_header: 3,
18 18 merge_resp_headers: 2,
  @@ -662,6 +662,53 @@ defmodule Combo.Conn do
662 662 raise ArgumentError, "the :to option in redirect expects a path but was #{inspect(url)}"
663 663 end
664 664
665 + @doc """
666 + Sends redirect response to the previous location.
667 +
668 + It attempts to use path from the following sources in sequence:
669 +
670 + 1. the path retrieved from "Referer" request header
671 + 2. the path retrieved by `get_previous_url/1`. To make it work, you need
672 + to add `put_previous_url/2` to the pipeline first.
673 + 3. the path retrieved from `:fallback` option
674 + 4. the root path
675 +
676 + ## Examples
677 +
678 + iex> redirect_back(conn)
679 +
680 + iex> redirect_back(conn, fallback: ~p"/users")
681 +
682 + """
683 + def redirect_back(conn, opts \\ []) do
684 + referrer =
685 + case get_req_header(conn, "referer") do
686 + [value] -> value
687 + _ -> nil
688 + end
689 +
690 + url =
691 + referrer ||
692 + get_previous_url(conn) ||
693 + Keyword.get(opts, :fallback) ||
694 + root_url(conn)
695 +
696 + path = extract_path(url)
697 + redirect(conn, to: path)
698 + end
699 +
700 + defp root_url(conn) do
701 + endpoint = endpoint_module!(conn)
702 + endpoint.url() <> endpoint.path("/")
703 + end
704 +
705 + defp extract_path(url) do
706 + case URI.parse(url) do
707 + %URI{path: path, query: nil} -> path
708 + %URI{path: path, query: query} -> path <> "?" <> query
709 + end
710 + end
711 +
665 712 @doc """
666 713 Sends the given file or binary as a download.
667 714
  @@ -789,6 +836,11 @@ defmodule Combo.Conn do
789 836 end
790 837 end
791 838
839 + defp prefetch?(conn) do
840 + "prefetch" in get_req_header(conn, "purpose") ||
841 + "prefetch" in get_req_header(conn, "sec-purpose")
842 + end
843 +
792 844 @doc """
793 845 Sends JSON response.
794 846
  @@ -1267,6 +1319,36 @@ defmodule Combo.Conn do
1267 1319 %{conn | resp_headers: resp_headers}
1268 1320 end
1269 1321
1322 + ## URL tracking
1323 +
1324 + @doc """
1325 + Puts current url to the session before sending the response, and it will be
1326 + available as previous url for subsequence requests.
1327 +
1328 + In general, it's added to the pipeline for browser.
1329 + """
1330 + def put_previous_url(conn, _opts) do
1331 + register_before_send(conn, &put_previous_url/1)
1332 + end
1333 +
1334 + defp put_previous_url(conn) do
1335 + if conn.method == "GET" &&
1336 + conn.status in 200..299 &&
1337 + !ajax?(conn) &&
1338 + !prefetch?(conn) do
1339 + put_session(conn, :_previous_url, current_url(conn))
1340 + else
1341 + conn
1342 + end
1343 + end
1344 +
1345 + @doc """
1346 + Gets previous url.
1347 + """
1348 + def get_previous_url(conn) do
1349 + get_session(conn, :_previous_url)
1350 + end
1351 +
1270 1352 ## URL generation
1271 1353
1272 1354 @doc """
  @@ -1,7 +1,7 @@
1 1 defmodule Combo.MixProject do
2 2 use Mix.Project
3 3
4 - @version "0.5.1"
4 + @version "0.6.0"
5 5 @description "A web framework, that combines the good parts of modern web development."
6 6 @elixir_requirement "~> 1.18"
7 7 @source_url "https://github.com/combo-lab/combo"
  @@ -1,6 +1,6 @@
1 1 {
2 2 "name": "combo",
3 - "version": "0.5.1",
3 + "version": "0.6.0",
4 4 "description": "The JavaScript parts of Combo",
5 5 "type": "module",
6 6 "scripts": {