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.
Futures on the JVM and promises in ClojureScript behind one set of functions so that code that waits for answers is written once. The functions take a value, a future or a promise alike.
Futures on the JVM and promises in ClojureScript behind one set of functions so that code that waits for answers is written once. The functions take a value, a future or a promise alike.
Bytes on both platforms, a byte array on the JVM and a Uint8Array in JavaScript, with the encodings, hashes and randomness that requests and their signatures need.
The hashes are synchronous on both platforms. In JavaScript they come from the Closure Library rather than WebCrypto, whose digests only come as promises.
Bytes on both platforms, a byte array on the JVM and a Uint8Array in JavaScript, with the encodings, hashes and randomness that requests and their signatures need. The hashes are synchronous on both platforms. In JavaScript they come from the Closure Library rather than WebCrypto, whose digests only come as promises.
A :send over CapacitorHttp, the plugin that sends the requests of a Capacitor app from native code, where CORS doesn't stop them.
(ns my.app
(:require ["@capacitor/core" :refer [CapacitorHttp]]
[dk.simongray.wary-fetch.capacitor :as capacitor]))
(def send (capacitor/sender CapacitorHttp))
It sends a request as send! does, with the same limits, and gives the same response. It follows the redirects itself, so that :allow-pred takes each URL, and it decodes text by its charset, since the plugin reads all text as UTF-8. The plugin hands a body over whole, so the sender suits feeds and the calls of APIs rather than episodes, which the plugin's docs leave to a plugin for file transfers. Capacitor's HTTP API is at https://capacitorjs.com/docs/apis/http
A :send over CapacitorHttp, the plugin that sends the requests of a
Capacitor app from native code, where CORS doesn't stop them.
(ns my.app
(:require ["@capacitor/core" :refer [CapacitorHttp]]
[dk.simongray.wary-fetch.capacitor :as capacitor]))
(def send (capacitor/sender CapacitorHttp))
It sends a request as send! does, with the same limits, and gives the
same response. It follows the redirects itself, so that :allow-pred
takes each URL, and it decodes text by its charset, since the plugin
reads all text as UTF-8. The plugin hands a body over whole, so the
sender suits feeds and the calls of APIs rather than episodes, which
the plugin's docs leave to a plugin for file transfers. Capacitor's HTTP
API is at https://capacitorjs.com/docs/apis/httpA :send for the page of an Electron app, which sends each request through the main process, where Node sends it and CORS doesn't stop it.
The main process answers with handler, and the page sends with sender over the IPC of Electron, which the preload script gives the page:
;; main process
(.handle ipcMain "wary-fetch" (electron/handler))
;; preload script
(.exposeInMainWorld contextBridge "waryFetch"
#js {:send #(.invoke ipcRenderer "wary-fetch" %)})
;; page
(def send (electron/sender (.. js/window -waryFetch -send)))
The main process keeps its own limits, so a page can't reach what the handler doesn't allow, e.g. the app's own network. A request and its response cross the IPC as plain data, without functions, so a :sink or an :allow-pred of the page stays in the page.
A :send for the page of an Electron app, which sends each request
through the main process, where Node sends it and CORS doesn't stop it.
The main process answers with handler, and the page sends with sender
over the IPC of Electron, which the preload script gives the page:
;; main process
(.handle ipcMain "wary-fetch" (electron/handler))
;; preload script
(.exposeInMainWorld contextBridge "waryFetch"
#js {:send #(.invoke ipcRenderer "wary-fetch" %)})
;; page
(def send (electron/sender (.. js/window -waryFetch -send)))
The main process keeps its own limits, so a page can't reach what the
handler doesn't allow, e.g. the app's own network. A request and its
response cross the IPC as plain data, without functions, so a :sink or an
:allow-pred of the page stays in the page.The values of HTTP headers as data: the header maps of responses, links, byte ranges, and when to ask again.
A map of headers has lower-case names, and each value is a string or a vector of strings.
The values of HTTP headers as data: the header maps of responses, links, byte ranges, and when to ask again. A map of headers has lower-case names, and each value is a string or a vector of strings.
JSON on both platforms, without a library: a strict reader by RFC 8259 on the JVM, and the JSON of JavaScript in ClojureScript.
An object reads as a map with keyword keys, unless a :key-fn says otherwise, an array as a vector, and a number as a long when it's an integer that fits, or else as a double. In JavaScript every number is a double, so an integer past 2^53 loses its last digits there.
JSON on both platforms, without a library: a strict reader by RFC 8259 on the JVM, and the JSON of JavaScript in ClojureScript. An object reads as a map with keyword keys, unless a :key-fn says otherwise, an array as a vector, and a number as a long when it's an integer that fits, or else as a double. In JavaScript every number is a double, so an integer past 2^53 loses its last digits there.
A proxy on your own server for the requests of a web page, since most servers don't let a page of another site read their answers.
The proxy fetches any public URL for whoever can reach it, so put it behind your login. Its answers come from other sites but have the origin of yours, so it refuses to be opened as a page, and no answer runs scripts when a browser opens it anyway.
A proxy on your own server for the requests of a web page, since most servers don't let a page of another site read their answers. The proxy fetches any public URL for whoever can reach it, so put it behind your login. Its answers come from other sites but have the origin of yours, so it refuses to be opened as a page, and no answer runs scripts when a browser opens it anyway.
Texts that print as #<secret> (e.g. a password or a token) so that a log or a REPL doesn't show them.
The reader can't read #<secret>. So a map with a hidden text that goes to a file as EDN fails to read back instead of coming back without its secret. A debugger or a browser's console still shows the text because it shows the fields of an object.
Texts that print as #<secret> (e.g. a password or a token) so that a log or a REPL doesn't show them. The reader can't read #<secret>. So a map with a hidden text that goes to a file as EDN fails to read back instead of coming back without its secret. A debugger or a browser's console still shows the text because it shows the fields of an object.
URLs, and the hosts that they name, the same way on both platforms.
This covers percent-encoding and query strings, a URL made absolute against the document that it's in, as a browser does it, and the scheme and the origin of a URL. It also tells whether the host of a URL is on the public internet, which is what a request that a stranger chose must check.
URLs are parsed by whatwg-url, which implements the URL Standard, so a host is read as a browser reads it, e.g. 0x7f.1 as 127.0.0.1.
URLs, and the hosts that they name, the same way on both platforms. This covers percent-encoding and query strings, a URL made absolute against the document that it's in, as a browser does it, and the scheme and the origin of a URL. It also tells whether the host of a URL is on the public internet, which is what a request that a stranger chose must check. URLs are parsed by whatwg-url, which implements the URL Standard, so a host is read as a browser reads it, e.g. 0x7f.1 as 127.0.0.1.
cljdoc builds & hosts documentation for Clojure/Script libraries
| Ctrl+k | Jump to recent docs |
| ← | Move to previous article |
| → | Move to next article |
| Ctrl+/ | Jump to the search field |