DEV Community

Carlo Colombo
Carlo Colombo

Posted on • Originally published at

Elixir - Simple Req Cookie Jar

A simple req cookie jar plugin. It can be used when automating or scraping websites that implement cookie based sessions. The cookies are set using set-cookie header and are sent back to the server in the headers of each following request. The implementation is naive and probably misses advanced and corner cases.

# create the cookie jar

# attach the plugin to the req
req = "")
|> CookieJar.attach()

# when the response includes the set-cookie header, it store its value in the jar
%{body: "Ok."} = req
         url: "/api/v2/auth/login",
         form: [username: "admin", password: "password"])

# all subsequent requests have the cookie set in the headers
%{status: 200} = req
|> Req.get!(url: "/api/v2/info?filter=foo")
Enter fullscreen mode Exit fullscreen mode

The cookie is stored in an Agent. Req response and request steps are respectively used to collect the cookie string and to add to the cookie header when requests are performed.

defmodule ReqCookieJar do
  use Agent

  def new() do
    Agent.start_link(fn -> "" end, name: __MODULE__)

  defp get_cookie do
    Agent.get(__MODULE__, & &1)

  defp set_cookie([]), do: nil
  defp set_cookie(val) do
    Agent.update(__MODULE__, fn (_) -> val end)

  def attach(%Req.Request{} = request) do
    |> Req.Request.append_response_steps(
      cookie_jar: fn({req, res})->
        Req.Response.get_header(res, "set-cookie")
        |> set_cookie()

    |> Req.Request.append_request_steps(
      cookie_jar: &Req.Request.put_header(&1, "cookie", get_cookie())
Enter fullscreen mode Exit fullscreen mode

Top comments (0)