{"id":13508129,"url":"https://github.com/DevL/plug_require_header","last_synced_at":"2025-03-30T09:33:23.770Z","repository":{"id":29535556,"uuid":"33074375","full_name":"DevL/plug_require_header","owner":"DevL","description":"An Elixir Plug for requiring and extracting a given header.","archived":true,"fork":false,"pushed_at":"2025-03-10T12:33:04.000Z","size":39,"stargazers_count":27,"open_issues_count":2,"forks_count":3,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-03-10T13:33:50.463Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"Elixir","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/DevL.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE.txt","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2015-03-29T13:42:19.000Z","updated_at":"2025-03-10T12:33:19.000Z","dependencies_parsed_at":"2022-09-26T18:21:43.006Z","dependency_job_id":null,"html_url":"https://github.com/DevL/plug_require_header","commit_stats":null,"previous_names":[],"tags_count":14,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/DevL%2Fplug_require_header","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/DevL%2Fplug_require_header/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/DevL%2Fplug_require_header/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/DevL%2Fplug_require_header/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/DevL","download_url":"https://codeload.github.com/DevL/plug_require_header/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":246301963,"owners_count":20755512,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-08-01T02:00:48.585Z","updated_at":"2025-03-30T09:33:23.764Z","avatar_url":"https://github.com/DevL.png","language":"Elixir","funding_links":[],"categories":["Framework Components"],"sub_categories":[],"readme":"# PlugRequireHeader\n\n**NB:** This repository has been moved to [https://codeberg.org/DevL/plug_require_header](https://codeberg.org/DevL/plug_require_header).\n\n[![Build Status](https://travis-ci.org/DevL/plug_require_header.svg?branch=master)](https://travis-ci.org/DevL/plug_require_header)\n[![Inline docs](http://inch-ci.org/github/DevL/plug_require_header.svg?branch=master)](http://inch-ci.org/github/DevL/plug_require_header)\n[![Hex.pm](https://img.shields.io/hexpm/v/plug_require_header.svg)](https://hex.pm/packages/plug_require_header)\n[![Documentation](https://img.shields.io/badge/Documentation-online-c800c8.svg)](http://hexdocs.pm/plug_require_header)\n\nAn Elixir Plug for requiring and extracting a given header.\n\n## Usage\n\nUpdate your `mix.exs` file and run `mix deps.get`.\n```elixir\ndefp deps do\n  [{:plug_require_header, \"~\u003e 0.8\"}]\nend\n```\n\nAdd the plug to e.g. a pipeline in a [Phoenix](http://www.phoenixframework.org/)\ncontroller. In this case we will require the request header `x-api-key` to be set,\nextract its first value and assign it the connection (a `Plug.Conn`) for later use\nin another plug or action.\n```elixir\ndefmodule MyPhoenixApp.MyController do\n  use MyPhoenixApp.Web, :controller\n  alias Plug.Conn.Status\n\n  plug PlugRequireHeader, headers: [api_key: \"x-api-key\"]\n  plug :action\n\n  def index(conn, _params) do\n    conn\n    |\u003e put_status(Status.code :ok)\n    |\u003e text \"The API key used is: #{conn.assigns[:api_key]}\"\n  end\nend\n```\nNotice how the first value required header `\"x-api-key\"` has been extracted\nand can be retrieved using `conn.assigns[:api_key]`. An alternative is to use\n`Plug.Conn.get_req_header/2` to get all the values associated with a given header.\n\nBy default, a missing header will return a status code of 403 (forbidden) and halt\nthe plug pipeline, i.e. no subsequent plugs will be executed. The same is true if\nthe required header is explicitly set to `nil` as the underlying HTTP server will\nnot include the header. This behaviour however is configurable.\n```elixir\ndefmodule MyPhoenixApp.MyOtherController do\n  use MyPhoenixApp.Web, :controller\n  alias Plug.Conn.Status\n\n  plug PlugRequireHeader, headers: [api_key: \"x-api-key\"],\n    on_missing: [status: 418, message: %{error: \"I'm a teapot!\"}, as: :json]\n  plug :action\n\n  def index(conn, _params) do\n    conn\n    |\u003e put_status(Status.code :ok)\n    |\u003e text \"The API key used is: #{conn.assigns[:api_key]}\"\n  end\n```\nThe `:on_missing` handling can be given a keyword list of options on how to handle\na missing header.\n\n* `:status` - an `integer` or `atom` to specify the status code. If it's an atom,\nit'll be looked up using the `Plug.Status.code` function. Default is `:forbidden`.\n* `:message` - a `binary` sent as the response body. Default is an empty string.\n* `:as` - an `atom` describing the content type and encoding. Currently supported\nalternatives are `:text` for plain text and `:json` for JSON. Default is `:text`.\n\nYou can also provide a function that handles the missing header by specifying a\nmodule/function pair in a tuple as the `:on_missing` value.\n```elixir\ndefmodule MyPhoenixApp.MyOtherController do\n  use MyPhoenixApp.Web, :controller\n  alias Plug.Conn.Status\n\n  plug PlugRequireHeader, headers: [api_key: \"x-api-key\"],\n    on_missing: {__MODULE__, :handle_missing_header}\n  plug :action\n\n  def index(conn, _params) do\n    conn\n    |\u003e put_status(Status.code :ok)\n    |\u003e text(\"The API key used is: #{conn.assigns[:api_key]}\")\n  end\n\n  def handle_missing_header(conn, {_connection_assignment_key, missing_header_key}) do\n    conn\n    |\u003e send_resp(Status.code(:bad_request), \"Missing header: #{missing_header_key}\")\n    |\u003e halt\n  end\nend\n```\nIf the header is missing or set to `nil` the status code, a status code of 400\n(bad request) will be returned before the plug pipeline is halted. Notice that\nthe function specified as a callback needs to be a public function as it'll be\ninvoked from another module. Also notice that the callback must return a `Plug.Conn` struct.\n\nLastly, it's possible to extract multiple headers at the same time.\n```elixir\n  plug PlugRequireHeader, headers: [api_key: \"x-api-key\", magic: \"x-magic\"]\n```\n\nIf extracting multiple headers _and_ specifying an `:on_missing` callback, be aware\nthat the callback will be invoked once for each missing header. Be careful to not send\na response as you can easily run into raising a `Plug.Conn.AlreadySentError`. A way of\navoiding this is to have your callback function pattern match on the state of the `conn`.\n```elixir\n  plug PlugRequireHeader, headers: [api_key: \"x-api-key\", secret: \"x-secret\"],\n    on_missing: {__MODULE__, :handle_missing_header}\n\n  def handle_missing_header(%Plug.Conn{state: :sent} = conn, _), do: conn\n  def handle_missing_header(conn, {_connection_assignment_key, missing_header_key}) do\n    conn\n    |\u003e send_resp(Status.code(:bad_request), \"Missing header: #{missing_header_key}\")\n    |\u003e halt\n  end\n```\nThis example will only send a response for the first missing header.\n\n## Online documentation\n\nFor more information, see [the full documentation](http://hexdocs.pm/plug_require_header).\n\n## Contributing\n\n1. Fork this repository\n2. Create your feature branch (`git checkout -b I-say-we-take-off-and-nuke-it-from-orbit`)\n3. Commit your changes (`git commit -am 'It is the only way to be sure!'`)\n4. Push to the branch (`git push origin I-say-we-take-off-and-nuke-it-from-orbit`)\n5. Create a new Pull Request\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FDevL%2Fplug_require_header","html_url":"https://awesome.ecosyste.ms/projects/github.com%2FDevL%2Fplug_require_header","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FDevL%2Fplug_require_header/lists"}