Liking cljdoc? Tell your friends :D

dk.simongray.wary-fetch

Requests and responses as maps, and the functions that send them.

The client is java.net.http on the JVM, node:http in Node and fetch in a browser. A request moves no more bytes than its purpose needs.

Requests and responses as maps, and the functions that send them.

The client is java.net.http on the JVM, node:http in Node and fetch in a
browser. A request moves no more bytes than its purpose needs.
raw docstring

aborted?clj/s

(aborted? e)

Whether the exception e of a request is ::aborted, since its :signal said to stop it.

Whether the exception `e` of a request is ::aborted, since its :signal
said to stop it.
sourceraw docstring

authorizationclj/s

(authorization credentials)

The Authorization header for credentials, or nil for no credentials.

The credentials are a map, or a function of no arguments that returns one. The map has :username and :password for basic authentication, or :token for a bearer token. Hide the password or the token with secret/hide, so that a printed map of credentials shows #<secret>.

The header holds the password or the token, so it's hidden too, and a printed request map doesn't show it.

The Authorization header for `credentials`, or nil for no credentials.

The `credentials` are a map, or a function of no arguments that returns
one. The map has :username and :password for basic authentication, or
:token for a bearer token. Hide the password or the token with
secret/hide, so that a printed map of credentials shows #<secret>.

The header holds the password or the token, so it's hidden too, and a
printed request map doesn't show it.
sourceraw docstring

digest!clj

(digest! url algorithms)
(digest! url
         algorithms
         {:keys [headers timeout-seconds allow-pred]
          :or {timeout-seconds 600}
          :as opts})

GET url with the opts below and return the digests of its body by the MessageDigest algorithms, e.g. SHA-384.

The result has the :status and the :url. For a 200, it also has the :digests, which map each algorithm to the bytes of its digest. The body streams through the digests without being kept, so it can be a large media file.

The opts are these:

  • :headers of the request
  • :allow-pred and :user-agent, as send! takes them, but with url/public? as the :allow-pred by default
  • :timeout-seconds, the limit of the whole exchange, 600 by default
GET `url` with the `opts` below and return the digests of its body by
the MessageDigest `algorithms`, e.g. SHA-384.

The result has the :status and the :url. For a 200, it also has the
:digests, which map each algorithm to the bytes of its digest. The
body streams through the digests without being kept, so it can be a
large media file.

The `opts` are these:

- :headers of the request
- :allow-pred and :user-agent, as send! takes them, but with
  url/public? as the :allow-pred by default
- :timeout-seconds, the limit of the whole exchange, 600 by default
sourceraw docstring

factsclj/s

(facts response)

The facts about its file that the response has.

The facts have these keys:

  • :status, :url and :permanent-url, as in the response
  • :redirects, each a map of its :status, the :url that answered with it and its :cors
  • :location, the Location of a redirect that wasn't followed
  • :type, the media type in lower case and without its parameters, as a browser parses the Content-Type
  • :length, the Content-Length as a number
  • :range, the Content-Range, as a map of :start, :end and :total
  • :encoding, :etag and :last-modified, from their headers
  • :cors, the origins that Access-Control-Allow-Origin allows to read the answer, with all its values joined as a browser joins them
  • :filtered?, as in the response
The facts about its file that the `response` has.

The facts have these keys:

- :status, :url and :permanent-url, as in the response
- :redirects, each a map of its :status, the :url that answered with it
  and its :cors
- :location, the Location of a redirect that wasn't followed
- :type, the media type in lower case and without its parameters, as a
  browser parses the Content-Type
- :length, the Content-Length as a number
- :range, the Content-Range, as a map of :start, :end and :total
- :encoding, :etag and :last-modified, from their headers
- :cors, the origins that Access-Control-Allow-Origin allows to read
  the answer, with all its values joined as a browser joins them
- :filtered?, as in the response
sourceraw docstring

failureclj/s

(failure e)

The exception e of a request that failed, as data: its :reason, and the :type, :url and :status that it holds. For an exception with a :type, the reason is its own message, written for a person. For any other, it's the messages of the exception and its causes.

The exception `e` of a request that failed, as data: its :reason, and
the :type, :url and :status that it holds. For an exception with a
:type, the reason is its own message, written for a person. For any
other, it's the messages of the exception and its causes.
sourceraw docstring

fetch!clj/s

(fetch! url)
(fetch! url {:keys [send] :or {send send!} :as opts})

GET the document at url with the opts below and return the response with the body as text (in ClojureScript a promise of it).

The response also has :etag and :last-modified when the server sends them, and :not-before when the server says how long to wait.

The opts are these:

  • :etag and :last-modified from an earlier response, sent as If-None-Match and If-Modified-Since, so that an unchanged document comes back as a 304 with no body
  • :credentials, as authorization takes them
  • :accept, the Accept header, / by default
  • :timeout-seconds, :max-bytes, :max-redirects, :allow-pred, :user-agent, :truncate? and :signal, as send! takes them, but with url/public? as the :allow-pred by default
  • :max-wait-seconds, as headers/not-before takes it
  • :send, the function that sends the request, send! by default
GET the document at `url` with the `opts` below and return the response
with the body as text (in ClojureScript a promise of it).

The response also has :etag and :last-modified when the server sends
them, and :not-before when the server says how long to wait.

The `opts` are these:

- :etag and :last-modified from an earlier response, sent as
  If-None-Match and If-Modified-Since, so that an unchanged document
  comes back as a 304 with no body
- :credentials, as authorization takes them
- :accept, the Accept header, */* by default
- :timeout-seconds, :max-bytes, :max-redirects, :allow-pred,
  :user-agent, :truncate? and :signal, as send! takes them, but with
  url/public? as the :allow-pred by default
- :max-wait-seconds, as headers/not-before takes it
- :send, the function that sends the request, send! by default
sourceraw docstring

fetch-requestclj/s

(fetch-request url)
(fetch-request
  url
  {:keys [etag last-modified credentials accept] :or {accept "*/*"} :as opts})

The request for the document at url with opts, the options of fetch!.

A user name and a password in url are the credentials when opts have none, and the request goes to the URL without them. The request goes only to the public internet unless opts have an :allow-pred.

The request for the document at `url` with `opts`, the options of
fetch!.

A user name and a password in `url` are the credentials when `opts`
have none, and the request goes to the URL without them. The request
goes only to the public internet unless `opts` have an :allow-pred.
sourceraw docstring

fetcherclj/s

(fetcher url)
(fetcher url {:keys [headers send] :or {send send!} :as opts})

A function that fetches the bytes of the file at url by range, with the opts below.

The function takes a start and an end (excluded) and returns a map of :bytes, :start and :total (in ClojureScript a promise of it). The total is the size of the file when the answer has it. A server that ignores ranges sends the file from its start, and the map then has :whole?. A range past the end of the file returns no bytes. Any other answer, e.g. a 404, throws ::failed with the :status.

The opts are these:

  • :headers of the requests
  • :timeout-seconds, :max-bytes, :max-redirects, :allow-pred, :user-agent, :truncate? and :signal, as send! takes them, but with url/public? as the :allow-pred by default
  • :send, the function that sends each request, send! by default
A function that fetches the bytes of the file at `url` by range, with
the `opts` below.

The function takes a start and an end (excluded) and returns a map of
:bytes, :start and :total (in ClojureScript a promise of it). The total
is the size of the file when the answer has it. A server that ignores
ranges sends the file from its start, and the map then has :whole?. A
range past the end of the file returns no bytes. Any other answer, e.g.
a 404, throws ::failed with the :status.

The `opts` are these:

- :headers of the requests
- :timeout-seconds, :max-bytes, :max-redirects, :allow-pred,
  :user-agent, :truncate? and :signal, as send! takes them, but with
  url/public? as the :allow-pred by default
- :send, the function that sends each request, send! by default
sourceraw docstring

form-requestclj/s

(form-request url fields)
(form-request url fields {:keys [headers] :as opts})

The request that posts the form fields to url with the opts below, e.g. to an OAuth token endpoint.

The fields are a map or pairs of names and values, as url/query-string takes them. The body is hidden with secret/hide, since a form often holds a secret such as an OAuth code. The opts are the :headers to add and the options of send! that with-options takes, e.g. :max-redirects 0 to keep a form from following a redirect.

The request that posts the form `fields` to `url` with the `opts`
below, e.g. to an OAuth token endpoint.

The `fields` are a map or pairs of names and values, as
url/query-string takes them. The body is hidden with secret/hide, since
a form often holds a secret such as an OAuth code. The `opts` are the
:headers to add and the options of send! that with-options takes, e.g.
:max-redirects 0 to keep a form from following a redirect.
sourceraw docstring

json-requestclj/s

(json-request url x)
(json-request url x {:keys [headers] :as opts})

The request that posts the value x to url as JSON, written by json/write-json, with the opts of form-request.

The request that posts the value `x` to `url` as JSON, written by
json/write-json, with the `opts` of form-request.
sourceraw docstring

multipart-requestclj/s

(multipart-request url parts)
(multipart-request url parts {:keys [headers] :as opts})

The request that posts the parts to url as multipart/form-data, with the opts of form-request, e.g. to upload a file.

The parts are a map or pairs of names and values, like the fields of form-request. A value is a text or a file. A file is a map of its :content (bytes or a text), its :filename (blob by default, as in a browser) and its :content-type (application/octet-stream by default).

(multipart-request "https://example.com/media"
                   [["file" {:content      jpeg-bytes
                             :filename     "sunset.jpg"
                             :content-type "image/jpeg"}]])

The body is bytes, hidden like the body of a form, and holds the files in memory.

The request that posts the `parts` to `url` as multipart/form-data, with
the `opts` of form-request, e.g. to upload a file.

The `parts` are a map or pairs of names and values, like the fields of
form-request. A value is a text or a file. A file is a map of its
:content (bytes or a text), its :filename (blob by default, as in a
browser) and its :content-type (application/octet-stream by default).

    (multipart-request "https://example.com/media"
                       [["file" {:content      jpeg-bytes
                                 :filename     "sunset.jpg"
                                 :content-type "image/jpeg"}]])

The body is bytes, hidden like the body of a form, and holds the files
in memory.
sourceraw docstring

probe!clj/s

(probe! url)
(probe! url {:keys [headers send] :or {send send!} :as opts})

Ask the server about the file at url with the opts below and return the facts (in ClojureScript a promise of them). It downloads no more than two bytes of the file.

The result is a map of :head and :get with the facts of a HEAD request and of a request for the first two bytes. For a request that failed, the facts are its exception under :error, as failure returns it.

The opts are these:

  • :headers of both requests, e.g. an Origin to learn about CORS
  • :timeout-seconds, :max-bytes, :max-redirects, :allow-pred, :user-agent, :truncate? and :signal, as send! takes them, but with url/public? as the :allow-pred by default
  • :send, the function that sends each request, send! by default
Ask the server about the file at `url` with the `opts` below and return
the facts (in ClojureScript a promise of them). It downloads no more
than two bytes of the file.

The result is a map of :head and :get with the facts of a HEAD request
and of a request for the first two bytes. For a request that failed,
the facts are its exception under :error, as failure returns it.

The `opts` are these:

- :headers of both requests, e.g. an Origin to learn about CORS
- :timeout-seconds, :max-bytes, :max-redirects, :allow-pred,
  :user-agent, :truncate? and :signal, as send! takes them, but with
  url/public? as the :allow-pred by default
- :send, the function that sends each request, send! by default
sourceraw docstring

revealedclj/s

(revealed {:keys [headers] :as request})

The request with the texts of its hidden headers and body, as a server needs them.

The Authorization header that authorization makes is hidden, and so is the body of form-request and multipart-request. Another client needs their texts, but a revealed request shows its credentials when printed.

The `request` with the texts of its hidden headers and body, as a
server needs them.

The Authorization header that authorization makes is hidden, and so is
the body of form-request and multipart-request. Another client needs
their texts, but a revealed request shows its credentials when printed.
sourceraw docstring

send!clj/s

(send! {:keys [timeout-seconds allow-pred as]
        :or {timeout-seconds 30 allow-pred (constantly true)}
        :as request})

Send the request and return the response (in ClojureScript a promise of it).

The request is a map of :method, :url, :headers and :body. It's a GET unless :method names another. The body is text or bytes. You can hide the header values and the body with secret/hide. A request can also have these keys:

  • :query-params, a map of parameters to add after the URL's own query, as url/with-query adds them
  • :as, either :bytes for a body of bytes rather than text, or :json for the value of a JSON body as json/read-json returns it (nil when it isn't JSON)
  • :timeout-seconds, the limit of the whole exchange (30 by default)
  • :max-bytes, the limit of the body (100 MB by default or nil for none)
  • :truncate?, true to cut a body that's larger than :max-bytes rather than throw (e.g. to read the start of a large page), which marks the response :truncated?
  • :range, the first and the last byte to ask for (a nil last byte asks for the rest)
  • :allow-pred, a predicate of each URL, e.g. url/public?
  • :user-agent, the User-Agent outside a browser unless the :headers name one
  • :max-redirects, how many redirects to follow (5 by default, and 0 for none)
  • :sink, to take the body of a success in pieces rather than hold it, e.g. to write a large file. It's a function of the bytes of each piece (which in ClojureScript can return a promise to wait for), an OutputStream on the JVM or a writable stream in Node.
  • :signal, to stop the exchange: an AbortSignal in ClojureScript, or on the JVM an atom, a promise or another reference that turns truthy
  • :prepare-fn, a function of the request of each hop (the first and each redirect) that returns the request to send, or a future or a promise of it, e.g. to sign each hop for its URL. It gets the request as the client sends it: with the User-Agent, with the query in its URL and with the headers and body revealed. A browser follows its own redirects, so there it gets the first hop alone.

The response is a map of :status, the final :url, :headers and :body. The body has gzip undone and text decoded by its charset. A 206 also has the :content-range as a map of :start, :end and :total. In a browser, :filtered? marks a response whose headers CORS hides. With a :sink, a response with a status from 200 to 299 has no :body but the number of bytes that the sink :received, within the same limits.

Outside a browser it follows the redirects itself and checks each URL with :allow-pred. It never follows one from https to http, and credentials stay behind when a redirect leaves the origin. The response then lists the :redirects and has a :permanent-url if the first ones were permanent. A browser follows its own redirects. With :max-redirects 0, it returns a redirect as a response with the status 0.

When it fails, it throws one of these (in ClojureScript it rejects with one):

  • ::timeout or ::too-large past a limit
  • ::refused when :allow-pred refuses a URL
  • ::aborted once the :signal says to stop. On the JVM the library checks it every few hundredths of a second, and the Capacitor and Electron senders check it only before they send.
  • ::invalid-header for a header value with a character that HTTP doesn't allow (e.g. a line break). It names the header but leaves out the value.
  • ::invalid-body for a body that's a collection, e.g. a map meant for json-request
  • ::unresolved, ::unreachable or ::tls for a request that reaches no server, when the host's name doesn't resolve, the host can't be reached or the secure connection fails (e.g. over an expired certificate)

A browser doesn't report why a request reached no server. When it reports the device as offline, the type is ::unreachable.

Send the `request` and return the response (in ClojureScript a promise
of it).

The request is a map of :method, :url, :headers and :body. It's a GET
unless :method names another. The body is text or bytes. You can hide
the header values and the body with secret/hide. A request can also
have these keys:

- :query-params, a map of parameters to add after the URL's own query,
  as url/with-query adds them
- :as, either :bytes for a body of bytes rather than text, or :json for
  the value of a JSON body as json/read-json returns it (nil when it
  isn't JSON)
- :timeout-seconds, the limit of the whole exchange (30 by default)
- :max-bytes, the limit of the body (100 MB by default or nil for none)
- :truncate?, true to cut a body that's larger than :max-bytes rather
  than throw (e.g. to read the start of a large page), which marks the
  response :truncated?
- :range, the first and the last byte to ask for (a nil last byte asks
  for the rest)
- :allow-pred, a predicate of each URL, e.g. url/public?
- :user-agent, the User-Agent outside a browser unless the :headers
  name one
- :max-redirects, how many redirects to follow (5 by default, and 0 for
  none)
- :sink, to take the body of a success in pieces rather than hold it,
  e.g. to write a large file. It's a function of the bytes of each
  piece (which in ClojureScript can return a promise to wait for), an
  OutputStream on the JVM or a writable stream in Node.
- :signal, to stop the exchange: an AbortSignal in ClojureScript, or on
  the JVM an atom, a promise or another reference that turns truthy
- :prepare-fn, a function of the request of each hop (the first and
  each redirect) that returns the request to send, or a future or a
  promise of it, e.g. to sign each hop for its URL. It gets the request
  as the client sends it: with the User-Agent, with the query in its URL
  and with the headers and body revealed. A browser follows its own
  redirects, so there it gets the first hop alone.

The response is a map of :status, the final :url, :headers and :body.
The body has gzip undone and text decoded by its charset. A 206 also
has the :content-range as a map of :start, :end and :total. In a
browser, :filtered? marks a response whose headers CORS hides. With a
:sink, a response with a status from 200 to 299 has no :body but the
number of bytes that the sink :received, within the same limits.

Outside a browser it follows the redirects itself and checks each URL
with :allow-pred. It never follows one from https to http, and
credentials stay behind when a redirect leaves the origin. The response
then lists the :redirects and has a :permanent-url if the first ones
were permanent. A browser follows its own redirects. With
:max-redirects 0, it returns a redirect as a response with the status 0.

When it fails, it throws one of these (in ClojureScript it rejects with
one):

- ::timeout or ::too-large past a limit
- ::refused when :allow-pred refuses a URL
- ::aborted once the :signal says to stop. On the JVM the library
  checks it every few hundredths of a second, and the Capacitor and
  Electron senders check it only before they send.
- ::invalid-header for a header value with a character that HTTP
  doesn't allow (e.g. a line break). It names the header but leaves out
  the value.
- ::invalid-body for a body that's a collection, e.g. a map meant for
  json-request
- ::unresolved, ::unreachable or ::tls for a request that reaches no
  server, when the host's name doesn't resolve, the host can't be
  reached or the secure connection fails (e.g. over an expired
  certificate)

A browser doesn't report why a request reached no server. When it
reports the device as offline, the type is ::unreachable.
sourceraw docstring

send-public!clj/s

(send-public! request)

Send the request, but only to a host on the public internet. On the JVM and in Node, the host of each redirect has to be public too.

It sends no request to the app's own device or network, and throws ::refused instead (in ClojureScript it rejects with that).

Send the `request`, but only to a host on the public internet. On the
JVM and in Node, the host of each redirect has to be public too.

It sends no request to the app's own device or network, and throws
::refused instead (in ClojureScript it rejects with that).
sourceraw docstring

timeout?clj/s

(timeout? e)

Whether the exception e of a request, or one of its causes, is a timeout: ::timeout, or the timeout of the platform's client.

Whether the exception `e` of a request, or one of its causes, is a
timeout: ::timeout, or the timeout of the platform's client.
sourceraw docstring

try-send!clj/s

(try-send! send request)
(try-send! send request opts)

Send the request with send (a function such as send!) and the opts, and return a map of the response as the :value, or of the exception as the :error when send throws. The opts are the options of send! that with-options puts in the request.

The map comes in a future on the JVM and in a promise in ClojureScript, so several requests can be under way at once.

Send the `request` with `send` (a function such as send!) and the
`opts`, and return a map of the response as the :value, or of the
exception as the :error when `send` throws. The `opts` are the options
of send! that with-options puts in the request.

The map comes in a future on the JVM and in a promise in ClojureScript,
so several requests can be under way at once.
sourceraw docstring

user-agentclj/s

The User-Agent of a request outside a browser, unless the request names another.

The User-Agent of a request outside a browser, unless the request names
another.
sourceraw docstring

with-optionsclj/s

(with-options request opts)

The request with the options of send! that opts have and that aren't nil: :timeout-seconds, :max-bytes, :allow-pred, :user-agent, :max-redirects, :truncate? and :signal.

The `request` with the options of send! that `opts` have and that
aren't nil: :timeout-seconds, :max-bytes, :allow-pred, :user-agent,
:max-redirects, :truncate? and :signal.
sourceraw docstring

cljdoc builds & hosts documentation for Clojure/Script libraries

Keyboard shortcuts
Ctrl+kJump to recent docs
←Move to previous article
→Move to next article
Ctrl+/Jump to the search field
× close