The HTTP transport of Tspex.stamp/2: one POST of a time-stamp request
to a TSA (RFC 3161, section 3.4), written on :gen_tcp and :ssl.
It is small on purpose, because it only has to do one thing and put
limits on it that :httpc does not offer. For anything else (a proxy, a
client certificate with an agent, HTTP/2, your own retries) pass your own
:transport function to Tspex.stamp/2, a function of the URL, the
request in DER and the options that returns {:ok, response_der} or
{:error, reason}, and use Req, Finch or Mint inside it.
What it does:
POSTwithContent-Type: application/timestamp-query,Accept: application/timestamp-reply,User-Agent: tspex/<version>andConnection: close; one connection for each request.httpsverifies the server:verify_peer, the system CA certificates (:public_key.cacerts_get/0) and the name of the URL against the certificate.httpis accepted, because the token authenticates itself and many TSAs speak onlyhttp; the cost is that the hash of your data travels in the clear (a matter of privacy, not of integrity).- Only the status 200 is a success. Any other status ends the
request at once, without reading its body, and is
{:http_status, n}. - The body is limited by
:max_response_bytes. AContent-Lengthabove it is refused before a byte of the body is read, and a chunked or close-delimited body is cut at the limit, so a server cannot make you allocate what it wants. - No redirect unless you raise
:max_redirects, and then only 307 and 308 (which keep the method and the body), never fromhttpstohttp, and the:headersyou gave are not sent to another host. - The type of the body is not required: some TSAs answer with
text/plain. What decides is that the bytes are a valid DER response, whichTspex.verify/3checks. - The time of
:timeoutis for the whole exchange.
Options:
:headers- extra headers as{name, value}strings, for authentication. They replaceContent-Type,AcceptandUser-Agentof the same name;Host,Content-Length,ConnectionandTransfer-Encodingare refused. A name with anything that is not a token, or a value with a line break, raisesArgumentError.:timeout- milliseconds for the whole exchange, 30 000.:max_redirects- 0.:max_response_bytes- 1 MiB.:ssl- options for:ssl.connect/4that replace the defaults: acacerts:orcacertfile:for a private CA, orcertfile:andkeyfile:for a client certificate.verify: :verify_noneis yours to choose, and the token is still verified, but then anyone on the path can read your request.
The reasons of {:error, reason}, which Tspex.stamp/2 turns into the
detail of a :transport error: {:http_status, n}, :timeout,
:too_large, {:connect, reason} (no address, connection refused),
{:tls, reason} (the handshake, the certificate or the name) and
{:other, reason} (a response that is not HTTP, a connection closed
before the end of the body).
Needs the :ssl application only for https URLs.
Summary
Functions
Sends body to url and returns the body of the answer.
Types
@type reason() :: {:http_status, pos_integer()} | :timeout | :too_large | {:connect, term()} | {:tls, term()} | {:other, term()}
Why the request failed.
Functions
Sends body to url and returns the body of the answer.
{:ok, response_der} = Tspex.HTTP.post("http://tsa.example.com/tsp", request.der)See the module documentation for the options. A url that is not http
or https with a host, or a bad option, raises ArgumentError.