HTTPipe v0.9.0 HTTPipe.Request

An HTTP request that will be sent to the server

Note: The functions in this module will typically take an HTTPipe.Request struct as their first parameter and return an updated struct. Under most circumstances, you will want to use the functions defined in HTTPipe.Conn which take Conn structs and update internal Request structs.

Summary

Types

The body of a request must always be given as a String.t, nil, or body_encoding

The body encoding specifies a specific way to encode the body prior to sending it to the server

Duplication options for setting headers and query params

Headers are stored in a map of header names (in lower case) to their values

A specifier for the HTTP method

Specifies a version of HTTP to use. The version should be specified as a String.t

Query params are stored as a map of keys as strings to a list of string values

t()

Encapsulates an HTTP request

Functions

Clears the existing request headers

Deletes the named header

Deletes a query string parameter

Encodes the body to a string. Accepts special forms of tuples as described by body_encoding

Inspects the structure of the Request struct passed in the same way IO.inspect/1 might, returning the Request struct so that it can be used easily with pipes

Merges a map of headers into the existing headers

Encodes the body using encode_body/1, if defer_body_processing is true, otherwise returns the body as-is

Combines the given URL with the query params

Sets an “Authorization” header with the appropriate value for Basic authentication

Sets the request body

Sets the method to be used with the request

Sets the URL for the resource to operate on

Types

body :: nil | String.t | body_encoding

The body of a request must always be given as a String.t, nil, or body_encoding.

A nil body is shorthand for an empty string ("") which will be sent when the connection is executed.

body_encoding ::
  {:file, String.t} |
  {:form, Keyword.t}

The body encoding specifies a specific way to encode the body prior to sending it to the server.

It is still the responsibility of the consumer to set the appropriate Content-Type header.

Sending Files

The {:file, filename} option will cause the file located at :file to be sent as the body of the request. Note that this is not the same as sending a file with mutlipart/form-data. In this case, the file’s contents will be the payload of the request.

Form-Encoding

The {:form, parameters} option will cause the parameters (encoded as keyword lists) to be sent to be transformed into a form-urlencoded value before being sent as the body of the request.

duplicate_options ::
  :replace_existing |
  :prefer_existing |
  :duplicates_ok

Duplication options for setting headers and query params

:duplicates_ok

If a value already exists, the new value will be merged with the current value

:prefer_existing

If a value already exists, the new value will be discarded

:replace_existing

If a value already exists, the new value will overwrite the existing value

headers :: %{required(String.t) => String.t}

Headers are stored in a map of header names (in lower case) to their values.

The names and values are always of the type String.t.

For example:

%{
  "accept" => "application/json",
  "content-type" => "application/json"
}

For more information, see the documentation for put_header/4.

http_method ::
  :get |
  :post |
  :put |
  :delete |
  :head |
  :options |
  :patch |
  atom

A specifier for the HTTP method

The standard GET, POST, PUT, DELETE, HEAD, OPTIONS, and PATCH methods should always be supported by HTTPipe adapters. The specification also allows for non-standard methods to be passed as atoms, and it is advantageous for adapters to support these non-standard methods should clients need to connect to servers that use them.

That being said, not all adapters will support non-standard methods. For example, the :httpc module which is distributed with Erlang does not support anything outside the “standard” method plus “TRACE”.

http_version :: String.t

Specifies a version of HTTP to use. The version should be specified as a String.t.

Currently, HTTPipe only knows how to support HTTP 1.1 transactions, however, HTTP 2 is a future possibility.

params :: %{required(String.t) => [String.t]}

Query params are stored as a map of keys as strings to a list of string values.

Because it is possible for query parameters to be repeated in a query string, values are stored in a list.

For example:

%{
  "q" => ["Elixir HTTPipe"],
  "tbas" => [0, 1]
}

will be encoded as:

q=Elixir+HTTPipe&tbas=0&tbas=1

Unlike headers, query parameters are stored in the case they are provided in. For more information, see the documentation for put_param/4.

t :: %HTTPipe.Request{body: body, headers: headers, http_version: http_version, method: http_method, params: params, url: url}

Encapsulates an HTTP request

:method

The HTTP method to use for the request. See the http_method type.

:http_version

The HTTP version to use for the request. See the http_version type.

:url

The URL to make the request against. By default, this is nil. See the url type.

:headers

The headers for the request. By default, this is an empty map. See the headers type.

:params

The query params for the request. By default, this is an empty map. See the params type.

:body

The body for the request. By default, this is nil. See the body type.

url :: String.t | nil

Functions

clear_headers(request)

Specs

clear_headers(t) :: t

Clears the existing request headers

This will reset the internal store of request headers to an empty map. However, certain default request headers determined by the adapter will still be sent even if the headers map is empty.

delete_header(request, header_name)

Specs

delete_header(t, String.t) :: t

Deletes the named header

delete_param(request, param_name)

Specs

delete_param(t, String.t | atom) :: t

Deletes a query string parameter

encode_body(body)

Specs

encode_body(body) ::
  {:ok, String.t} |
  {:error, Exception.t}

Encodes the body to a string. Accepts special forms of tuples as described by body_encoding.

Due to the special forms this function supports, it can encounter a wide array of error. If you call this function, make sure to match on the return value.

inspect(req, opts \\ [])

Specs

inspect(t, Keyword.t) :: t

Inspects the structure of the Request struct passed in the same way IO.inspect/1 might, returning the Request struct so that it can be used easily with pipes.

Typically, Kernel.inspect/1, IO.inspect/1, and their companions are implemented using the Inspect protocol. However, the presentation used here can get extremely intrusive when experimenting using IEx, so it’s relegated to this function. Corresponding functions can be found at HTTPipe.Conn.inspect/2 and HTTPipe.Response.inspect/2.

See HTTPipe.InspectionHelpers for more information

merge_headers(request, headers)

Specs

merge_headers(t, headers) :: t

Merges a map of headers into the existing headers

Example

headers_to_merge = %{
  "accept" => "application/json",
  "accept-encoding" => "deflate",
  "connection" => "keep-alive"
}

%Request{}
|> Request.put_header("Accept", "application/xml")
|> Request.put_header("Content-Type", "application/json")
|> Request.put_header("Accept-Encoding", "gzip")
|> Request.merge_headers(headers_to_merge)

will result in the following header list:

accept-encoding: deflate
accept: applicaiton/json
connection: keep-alive
content-type: application/json

This function will replace any existing headers with the same name (regardless of casing).

prepare_body(body, defer_body_processing)

Specs

prepare_body(body, boolean) ::
  {:ok, String.t | body} |
  {:error, Exception.t}

Encodes the body using encode_body/1, if defer_body_processing is true, otherwise returns the body as-is.

prepare_url(base_url, params)

Specs

prepare_url(url, params) ::
  {:ok, String.t} |
  {:error, Exception.t}

Combines the given URL with the query params

If the URL is nil, this will return an {:error, NilURLError}

put_authentication_basic(request, username, password)

Specs

put_authentication_basic(t, String.t, String.t) :: t

Sets an “Authorization” header with the appropriate value for Basic authentication.

put_body(request, body)

Specs

put_body(t, body) :: t

Sets the request body

The body can be any valid type detailed in the body type.

put_header(request, header_name, header_value, duplication_option \\ :duplicates_ok)

Specs

put_header(t, String.t, String.t, duplicate_options) :: t

Adds a header to the request

Casing

Header names are case-insensitive: they may be passed to this function in any case; however, in order to aid in de-duplication, header names will be stored in lower case.

Duplicate Headers

Following the guidance of RFC 2612 4.2, duplicate headers are accomodated by flattening them into a comma-separated list. This is the default behavior. For example,

%HTTPipe.Request{}
|> Request.put_header("Accept-Encoding", "gzip")
|> Request.put_header("Accept-Encoding", "deflate")

will be flattened to the following header:

accept-encoding: gzip, deflate

However, this behavior can be changed by specifying a different behavior for duplicates as the final parameter. If replace_existing is passed, the new value will always replace the existing value. If prefer_existing is passed, the header will only be updated if there is no existing value.

put_method(request, method)

Specs

put_method(t, http_method) :: t

Sets the method to be used with the request

put_param(request, param_name, value, duplication_option \\ :replace_existing)

Specs

put_param(t, String.t | atom, String.t, duplicate_options) :: t

Adds a query parameter to the request

Example

For example, this request:

%Request{}
|> Request.put_url("https://google.com/#")
|> Request.put_param(:q, "httpipe elixir")

will generate the following URL when the connection is executed:

https://google.com/#?q=httpipe+elixir
put_url(request, url)

Specs

put_url(t, String.t) :: t

Sets the URL for the resource to operate on.

The URL should include the scheme (http:// or https://) as well as the fully qualified domain name, and the request path for the resource. If necessary, also include the port.

Basic Authentication

If you need to use HTTP Basic authentication, do not include the username and password as part of the URL. Instead, please use the put_authentication_basic/3 function.