### Basic Authentication Example Source: https://github.com/fukamachi/dexador/blob/master/README.markdown Use the `:basic-auth` option to provide username and password for basic authorization. The value should be a cons of username and password. ```lisp (:basic-auth '("foo" . "bar")) ``` -------------------------------- ### Simple GET Request Source: https://context7.com/fukamachi/dexador/llms.txt Make a basic HTTP GET request to retrieve content from a URL. Returns the response body, status code, headers, final URI, and an optional stream. ```common-lisp ;; Simple GET request (dex:get "http://lisp.org/") ;=> "..." ; 200 ; # ; # ; NIL ``` -------------------------------- ### dex:fetch Source: https://github.com/fukamachi/dexador/blob/master/README.markdown Sends a GET request to a URI and writes the response body directly to a destination file. ```APIDOC ## [GET] [fetch] ### Description Sends a GET request to the URI and writes the response body to the specified destination. ### Parameters #### Path Parameters - **uri** (string) - Required - The target URI. - **destination** (pathname/string) - Required - The file path to write the response. #### Query Parameters - **if-exists** (symbol) - Optional - Behavior if destination exists (default: :error). ``` -------------------------------- ### GET Request with Verbose Output Source: https://context7.com/fukamachi/dexador/llms.txt Execute a GET request with verbose output enabled for debugging. This will print the request details to standard output, aiding in troubleshooting. ```common-lisp ;; GET with verbose output for debugging (dex:get "http://example.com/" :verbose t) ;-> >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> ; GET / HTTP/1.1 ; User-Agent: Dexador/0.9.16 (SBCL 2.4.3); Linux; 6.7.0 ; Host: example.com ; Accept: */* ; ; >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> ``` -------------------------------- ### GET Request Source: https://context7.com/fukamachi/dexador/llms.txt Make a simple HTTP GET request to retrieve content from a URL. Supports custom headers, timeouts, verbose output, binary content, and streaming responses. ```APIDOC ## GET Request Make a simple HTTP GET request to retrieve content from a URL. Returns multiple values: response body, status code, headers hash table, final URI, and optionally a reusable stream. ### Method GET ### Endpoint `/` (relative to host) ### Parameters #### Query Parameters - **url** (string) - Required - The URL to fetch. - **headers** (list of pairs) - Optional - Custom headers to send with the request. - **connect-timeout** (number) - Optional - Timeout in seconds for establishing the connection. - **read-timeout** (number) - Optional - Timeout in seconds for reading the response. - **force-binary** (boolean) - Optional - If true, forces the response to be treated as binary data. - **want-stream** (boolean) - Optional - If true, returns a stream for the response body. - **verbose** (boolean) - Optional - If true, prints request and response details to standard output for debugging. ### Request Example ```common-lisp ;; Simple GET request (dex:get "http://lisp.org/") ;; GET with custom headers and timeout (dex:get "https://api.example.com/users" :headers '(("Accept" . "application/json") ("X-API-Key" . "your-api-key")) :connect-timeout 5 :read-timeout 30) ;; GET with verbose output for debugging (dex:get "http://example.com/" :verbose t) ;; GET binary content (dex:get "https://example.com/image.png" :force-binary t) ;; GET response as a stream (let ((stream (dex:get "https://example.com/large-file.zip" :want-stream t))) (unwind-protect (with-open-file (out "/tmp/file.zip" :direction :output :element-type '(unsigned-byte 8)) (alexandria:copy-stream stream out)) (close stream))) ``` ### Response #### Success Response (200) - **response-body** (string or byte-array) - The content of the response. - **status-code** (integer) - The HTTP status code. - **headers** (hash-table) - A hash table containing response headers. - **final-uri** (uri) - The final URI after following redirects. - **stream** (stream or null) - A stream to the response body if `want-stream` is true, otherwise NIL. #### Response Example ``` "..." 200 # # NIL ``` ``` -------------------------------- ### Perform Basic HTTP Requests Source: https://github.com/fukamachi/dexador/blob/master/README.markdown Use dex:get and dex:post to perform standard HTTP operations. The :content parameter accepts an association list for form data. ```common-lisp (dex:get "http://lisp.org/") (dex:post "https://example.com/login" :content '(("name" . "fukamachi") ("password" . "1ispa1ien"))) ``` -------------------------------- ### GET Binary Content Source: https://context7.com/fukamachi/dexador/llms.txt Retrieve binary content, such as an image, by setting :force-binary to true. The response will be a byte array. ```common-lisp ;; GET binary content (dex:get "https://example.com/image.png" :force-binary t) ;=> #(137 80 78 71 13 10 26 10 ...) ; raw bytes ``` -------------------------------- ### GET Request with Custom Headers and Timeout Source: https://context7.com/fukamachi/dexador/llms.txt Perform a GET request with custom HTTP headers and specify connection and read timeouts in seconds. Useful for API interactions requiring specific headers or to prevent hanging. ```common-lisp ;; GET with custom headers and timeout (dex:get "https://api.example.com/users" :headers '(("Accept" . "application/json") ("X-API-Key" . "your-api-key")) :connect-timeout 5 :read-timeout 30) ``` -------------------------------- ### Perform a GET Request with Dexador Source: https://github.com/fukamachi/dexador/blob/master/README.markdown The `dex:get` function is a convenience wrapper for making HTTP GET requests. It accepts various options for controlling the request, such as headers, timeouts, and connection pooling. ```common-lisp (dex:get uri &key version headers basic-auth cookie-jar keep-alive use-connection-pool connect-timeout read-timeout max-redirects force-binary force-string want-stream ssl-key-file ssl-cert-file ssl-key-password stream verbose proxy insecure ca-path) ``` -------------------------------- ### Simple DELETE Request Source: https://context7.com/fukamachi/dexador/llms.txt Remove a resource from the server using a simple DELETE request. This example targets a specific user ID. ```common-lisp ;; Simple DELETE request (dex:delete "https://api.example.com/users/123") ;=> "" ; 204 ``` -------------------------------- ### Fetch URL Content to a Destination Source: https://github.com/fukamachi/dexador/blob/master/README.markdown The `dex:fetch` function performs a GET request to a URI and writes the response body to a specified destination. It supports options like error handling for existing files and verbose output. ```common-lisp (dex:fetch uri destination &key (if-exists error) verbose proxy insecure) ``` -------------------------------- ### Dexador Benchmark vs Drakma Source: https://github.com/fukamachi/dexador/blob/master/README.markdown This benchmark compares the performance of Dexador's `get` function against Drakma's `http-request` for downloading a small HTML file 30 times. Dexador shows significantly better performance in terms of real time and CPU usage. ```common-lisp (time (dotimes (i 30) (drakma:http-request "http://files.8arrow.org/181B.html"))) ``` ```common-lisp (time (dotimes (i 30) (dex:get "http://files.8arrow.org/181B.html"))) ``` -------------------------------- ### GET Response as Stream Source: https://context7.com/fukamachi/dexador/llms.txt Fetch a response body as a stream, useful for large files. The stream must be explicitly closed, typically using `unwind-protect`. ```common-lisp ;; GET response as a stream (let ((stream (dex:get "https://example.com/large-file.zip" :want-stream t))) (unwind-protect (with-open-file (out "/tmp/file.zip" :direction :output :element-type '(unsigned-byte 8)) (alexandria:copy-stream stream out)) (close stream))) ``` -------------------------------- ### Make an HTTP Request with Dexador Source: https://github.com/fukamachi/dexador/blob/master/README.markdown Use `dex:request` to send an HTTP request to a given URI. It returns the response body, status, headers, last URI, and stream. Specify `:force-binary` to always get an octet vector. ```common-lisp (dex:request uri &key (method get) (version 1.1) content headers basic-auth cookie-jar (connect-timeout *default-connect-timeout*) (read-timeout *default-read-timeout*) (keep-alive t) (use-connection-pool t) (max-redirects 5) ssl-key-file ssl-cert-file ssl-key-password stream (verbose *verbose*) force-binary force-string want-stream proxy (insecure *not-verify-ssl*) ca-path) ;=> body ; status ; response-headers ; uri ; stream ``` -------------------------------- ### Handle HTTP Redirects Source: https://github.com/fukamachi/dexador/blob/master/README.markdown Dexador automatically follows redirects for GET or HEAD requests. The fourth return value indicates the final URI. ```common-lisp (dex:head "http://lisp.org") ;=> "" ; 200 ; # ; # ; NIL ``` -------------------------------- ### Configure Proxy Settings Source: https://context7.com/fukamachi/dexador/llms.txt Use HTTP or SOCKS5 proxies for requests, or set a global default proxy. ```common-lisp ;; HTTP proxy (dex:get "https://example.com/" :proxy "http://proxy.company.com:8080/") ;; SOCKS5 proxy (useful for Tor) (dex:get "https://www.facebookcorewwwi.onion/" :proxy "socks5://127.0.0.1:9150") ;; Set default proxy for all requests (setf dex:*default-proxy* "http://proxy.company.com:8080/") (dex:get "https://example.com/") ; Uses default proxy ;; Clear default proxy (setf dex:*default-proxy* nil) ``` -------------------------------- ### Configure SSL/TLS Settings Source: https://context7.com/fukamachi/dexador/llms.txt Manage HTTPS security, including client certificates, CA paths, and insecure mode. ```common-lisp ;; Standard HTTPS request (SSL verification enabled by default) (dex:get "https://secure.example.com/") ;; With client certificate authentication (dex:get "https://mutual-auth.example.com/api" :ssl-cert-file #P"/path/to/client.crt" :ssl-key-file #P"/path/to/client.key" :ssl-key-password "key-password") ;; Skip SSL verification (use with caution!) (dex:get "https://self-signed.example.com/" :insecure t) ;; Set insecure mode globally (not recommended for production) (setf dex:*not-verify-ssl* t) ;; Specify CA certificate path (dex:get "https://internal.example.com/" :ca-path #P"/path/to/ca-bundle.crt") ``` -------------------------------- ### SSL/HTTPS Configuration Source: https://github.com/fukamachi/dexador/blob/master/README.markdown For HTTPS connections, specify SSL certificate and key files using `:ssl-key-file` and `:ssl-cert-file`, along with an optional `:ssl-key-password`. ```lisp (:ssl-key-file "/path/to/key.pem" :ssl-cert-file "/path/to/cert.pem") ``` -------------------------------- ### Connection Timeout Configuration Source: https://github.com/fukamachi/dexador/blob/master/README.markdown Configure connection timeouts using `:connect-timeout` for establishing the connection and `:read-timeout` for reading the response body. Defaults are 10 seconds. ```lisp (:connect-timeout 5 :read-timeout 15) ``` -------------------------------- ### Download File with Dexador Fetch Source: https://context7.com/fukamachi/dexador/llms.txt Use `dex:fetch` to download a file from a URL and save it directly to disk. Supports specifying the destination path, handling existing files with `:if-exists`, and routing through a proxy. ```common-lisp ;; Download file to destination (dex:fetch "https://example.com/files/document.pdf" #P"/home/user/downloads/document.pdf") ;; Download with overwrite option (dex:fetch "https://example.com/files/data.csv" #P"/tmp/data.csv" :if-exists :supersede) ;; Download via proxy (dex:fetch "https://example.com/large-file.zip" #P"/tmp/large-file.zip" :proxy "http://proxy.company.com:8080/" :verbose t) ``` -------------------------------- ### Set Timeouts and Request Options Source: https://context7.com/fukamachi/dexador/llms.txt Configure connection/read timeouts, redirect limits, and response decoding behavior. ```common-lisp ;; Set timeouts for a single request (dex:get "https://slow-server.example.com/" :connect-timeout 30 ; 30 seconds to establish connection :read-timeout 120) ; 120 seconds to read response ;; Set default timeouts globally (setf dex:*default-connect-timeout* 15) (setf dex:*default-read-timeout* 60) ;; Limit redirects (dex:get "https://redirecting.example.com/" :max-redirects 3) ; Default is 5 ;; Custom User-Agent (dex:get "https://example.com/" :headers '(("User-Agent" . "MyApp/1.0 (Common Lisp)"))) ;; Force binary response (skip decoding) (dex:get "https://example.com/data" :force-binary t) ;=> #(72 101 108 108 111 ...) ; Raw bytes ;; Force string response (dex:get "https://example.com/binary-as-text" :force-string t) ``` -------------------------------- ### Proxy Configuration Source: https://github.com/fukamachi/dexador/blob/master/README.markdown Specify a proxy server for requests using the `:proxy` option. It defaults to environment variables `HTTPS_PROXY` or `HTTP_PROXY`. ```lisp (:proxy "http://my-proxy.com:8080") ``` -------------------------------- ### POST with File Upload Source: https://context7.com/fukamachi/dexador/llms.txt Perform a multipart/form-data POST request to upload a file. Include other form fields as needed. ```common-lisp ;; POST with file upload (automatically uses multipart/form-data) (dex:post "https://example.com/upload" :content '(("title" . "My Photo") ("description" . "A beautiful sunset") ("file" . #P"/home/user/photos/sunset.jpg"))) ``` -------------------------------- ### POST with Binary Data and Custom Content-Type Source: https://context7.com/fukamachi/dexador/llms.txt Send binary data as part of a multipart POST request, specifying a custom content type for the binary part. ```common-lisp ;; POST with binary data and custom content-type in multipart (dex:post "https://example.com/api/data" :content `(("metadata" . "{\"type\": \"image\"}") ("data" . (,(make-array 100 :element-type '(unsigned-byte 8)) :content-type "application/octet-stream")))) ``` -------------------------------- ### Basic Authorization Source: https://github.com/fukamachi/dexador/blob/master/README.markdown Provide credentials via the :basic-auth parameter as a cons cell containing username and password. ```common-lisp (dex:head "http://www.hatena.ne.jp/" :basic-auth '("nitro_idiot" . "password") :verbose t) ;-> >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> ; HEAD / HTTP/1.1 ; User-Agent: Dexador/0.1 (SBCL 1.2.9); Darwin; 14.1.0 ; Host: www.hatena.ne.jp ; Accept: */* ; Authorization: Basic bml0cm9faWRpb3Q6cGFzc3dvcmQ= ; ; >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> ``` -------------------------------- ### Connect via SOCKS5 Proxy Source: https://github.com/fukamachi/dexador/blob/master/README.markdown Use the `:proxy` option with a SOCKS5 URI to connect through a SOCKS5 proxy. ```common-lisp (dex:get "https://www.facebookcorewwwi.onion/" :proxy "socks5://127.0.0.1:9150") ``` -------------------------------- ### Debugging with Verbose Output Source: https://github.com/fukamachi/dexador/blob/master/README.markdown Enable debugging by setting `:verbose` to T. This option dumps the HTTP request headers to aid in troubleshooting. ```lisp (:verbose t) ``` -------------------------------- ### Connect via HTTP Proxy Source: https://github.com/fukamachi/dexador/blob/master/README.markdown Specify a proxy server for requests using the `:proxy` option. ```common-lisp (dex:get "http://lisp.org/" :proxy "http://proxy.yourcompany.com:8080/") ``` -------------------------------- ### Reusing Connections with a Stream Source: https://github.com/fukamachi/dexador/blob/master/README.markdown The `:stream` option allows providing an existing stream to reuse a connection. This is typically used for manual connection pooling, but `:use-connection-pool` is often simpler. ```lisp (:stream existing-stream) ``` -------------------------------- ### Execute Generic Requests Source: https://context7.com/fukamachi/dexador/llms.txt Use the low-level request function for full control over HTTP methods, headers, and cookies. ```common-lisp ;; Generic request with explicit method (dex:request "https://api.example.com/resource" :method :post :version 1.1 :content '(("key" . "value")) :headers '(("X-Custom-Header" . "custom-value")) :cookie-jar *cookie-jar* :connect-timeout 10 :read-timeout 30 :keep-alive t :use-connection-pool t :max-redirects 5 :verbose t) ;=> body ; status ; response-headers ; uri ; stream ;; OPTIONS request (dex:request "https://api.example.com/" :method :options) ;=> "" ; 200 ; # ; Contains Allow header with supported methods ``` -------------------------------- ### Custom Request Headers Source: https://github.com/fukamachi/dexador/blob/master/README.markdown Provide an alist to the `:headers` option to set custom request headers. If a header's value is NIL, it won't be sent. Default headers like Host, User-Agent, Accept, and Content-Type can be overwritten. ```lisp (:headers `(("User-Agent" . "MyClient/1.0") ("Accept" . "application/json"))) ``` -------------------------------- ### PUT Request to Update Resource Source: https://context7.com/fukamachi/dexador/llms.txt Update an entire resource on the server using the PUT method. Requires specifying the resource URI and the new content, typically JSON. ```common-lisp ;; PUT request to update entire resource (dex:put "https://api.example.com/users/123" :headers '(("Content-Type" . "application/json")) :content "{\"name\": \"Jane Doe\", \"email\": \"jane@example.com\", \"role\": \"admin\"}") ;=> "{\"id\": 123, \"name\": \"Jane Doe\", \"updated\": true}" ; 200 ``` -------------------------------- ### Perform a POST Request with Dexador Source: https://github.com/fukamachi/dexador/blob/master/README.markdown Use `dex:post` for sending HTTP POST requests. It allows specifying content, headers, and other request parameters. Ensure to set appropriate headers like `Content-Type` if sending a body. ```common-lisp (dex:post uri &key version content headers basic-auth cookie-jar keep-alive use-connection-pool connect-timeout read-timeout force-binary force-string want-stream ssl-key-file ssl-cert-file ssl-key-password stream verbose proxy insecure ca-path) ``` -------------------------------- ### Using a Cookie Jar Source: https://github.com/fukamachi/dexador/blob/master/README.markdown Pass a cookie jar object from the `cl-cookie` library to the `:cookie-jar` option to manage cookies across requests. ```lisp (:cookie-jar my-cookie-jar) ``` -------------------------------- ### Manage Connection Pooling Source: https://context7.com/fukamachi/dexador/llms.txt Control connection reuse behavior globally or per-request to optimize performance. ```common-lisp ;; Connection pooling is enabled by default (dex:get "https://api.example.com/endpoint1") ; Opens new connection (dex:get "https://api.example.com/endpoint2") ; Reuses connection ;; Disable connection pooling for a single request (dex:get "https://api.example.com/one-off" :use-connection-pool nil :keep-alive nil) ;; Create a custom connection pool (setf dex:*connection-pool* (dex:make-connection-pool 16)) ; Allow 16 connections ;; Clear all pooled connections (dex:clear-connection-pool) ;; Disable connection pooling globally (setf dex:*use-connection-pool* nil) ;; Re-enable with new pool (setf dex:*use-connection-pool* t) (setf dex:*connection-pool* (dex:make-connection-pool)) ``` -------------------------------- ### PUT and PATCH Requests Source: https://context7.com/fukamachi/dexador/llms.txt Update existing resources on the server. PUT typically replaces the entire resource while PATCH applies partial modifications. ```APIDOC ## PUT and PATCH Requests Update existing resources on the server. PUT typically replaces the entire resource while PATCH applies partial modifications. ### Method PUT, PATCH ### Endpoint `/` (relative to host) ### Parameters #### Query Parameters - **url** (string) - Required - The URL of the resource to update. - **content** (string or byte-array) - Required - The data to send in the request body. Typically JSON for updates. - **headers** (list of pairs) - Optional - Custom headers, including `Content-Type`. ### Request Example ```common-lisp ;; PUT request to update entire resource (dex:put "https://api.example.com/users/123" :headers '(("Content-Type" . "application/json")) :content "{\"name\": \"Jane Doe\", \"email\": \"jane@example.com\", \"role\": \"admin\"}") ;; PATCH request for partial update (dex:patch "https://api.example.com/users/123" :headers '(("Content-Type" . "application/json")) :content "{\"role\": \"moderator\"}") ``` ### Response #### Success Response (200) - **response-body** (string or byte-array) - The content of the response, often indicating the result of the update. - **status-code** (integer) - The HTTP status code. #### Response Example ``` "{\"id\": 123, \"name\": \"Jane Doe\", \"updated\": true}" 200 ``` ``` -------------------------------- ### Manage Cookies with cl-cookie Source: https://context7.com/fukamachi/dexador/llms.txt Maintain session state across multiple requests by using `cl-cookie:make-cookie-jar` with Dexador functions. Cookies are automatically sent with subsequent requests to the same domain. ```common-lisp ;; Create a cookie jar and use it across requests (defvar *cookie-jar* (cl-cookie:make-cookie-jar)) ;; First request - server sets cookies (dex:get "https://example.com/login" :cookie-jar *cookie-jar*) ;; Subsequent requests automatically include cookies (dex:get "https://example.com/dashboard" :cookie-jar *cookie-jar*) ;; Cookie header is automatically added ;; POST with cookies for authenticated session (dex:post "https://example.com/api/action" :cookie-jar *cookie-jar* :content '(("action" . "submit"))) ``` -------------------------------- ### Bearer Token Authentication Source: https://github.com/fukamachi/dexador/blob/master/README.markdown Use the `:bearer-auth` option with a string token to add a bearer auth header to the request. ```lisp (:bearer-auth "your-token-here") ``` -------------------------------- ### Handling Redirects Source: https://github.com/fukamachi/dexador/blob/master/README.markdown Control the maximum number of redirects with `:max-redirects`. If the limit is exceeded, the function returns the last response instead of raising a condition. ```lisp (:max-redirects 3) ``` -------------------------------- ### HTTP Basic and Bearer Authentication Source: https://context7.com/fukamachi/dexador/llms.txt Authenticate requests using `:basic-auth` with a username and password pair, or `:bearer-auth` with a token (e.g., JWT, OAuth). The `Authorization` header is automatically constructed. ```common-lisp ;; Basic authentication (dex:get "https://api.example.com/private/data" :basic-auth '("username" . "password")) ;; Sends: Authorization: Basic dXNlcm5hbWU6cGFzc3dvcmQ= ;; Bearer token authentication (OAuth, JWT) (dex:get "https://api.example.com/user/profile" :bearer-auth "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIn0.dozjgNryP4J3jVmNHl0w5N_XgL0n3I9PlFUP0THsR8U") ;; Sends: Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9... ;; Combined with other options (dex:post "https://api.example.com/resources" :bearer-auth "your-access-token" :headers '(("Content-Type" . "application/json")) :content "{\"name\": \"New Resource\"}") ``` -------------------------------- ### Set Custom User-Agent Header Source: https://github.com/fukamachi/dexador/blob/master/README.markdown Overwrite the default User-Agent header by specifying 'User-Agent' within the `:headers` option. ```common-lisp (dex:head "http://www.sbcl.org/" :verbose t) ``` ```common-lisp (dex:head "http://www.sbcl.org/" :headers '(("User-Agent" . "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_2) AppleWebKit/600.3.18 (KHTML, like Gecko) Version/8.0.3 Safari/600.3.18")) :verbose t) ``` -------------------------------- ### POST Request Source: https://context7.com/fukamachi/dexador/llms.txt Send data to a server using POST. Supports form-encoded data, multipart uploads with file attachments, and raw content. ```APIDOC ## POST Request Send data to a server using POST. Supports form-encoded data, multipart uploads with file attachments, and raw content. ### Method POST ### Endpoint `/` (relative to host) ### Parameters #### Query Parameters - **url** (string) - Required - The URL to send the POST request to. - **content** (list of pairs or string or byte-array) - Required - The data to send in the request body. Can be form-encoded pairs, a JSON string, or raw binary data. - **headers** (list of pairs) - Optional - Custom headers to send with the request. If sending JSON, ensure `Content-Type: application/json` is included. ### Request Example ```common-lisp ;; POST form data (application/x-www-form-urlencoded) (dex:post "https://example.com/login" :content '(("username" . "fukamachi") ("password" . "secret123"))) ;; POST JSON data (dex:post "https://api.example.com/users" :headers '(("Content-Type" . "application/json")) :content "{\"name\": \"John\", \"email\": \"john@example.com\"}") ;; POST with file upload (automatically uses multipart/form-data) (dex:post "https://example.com/upload" :content '(("title" . "My Photo") ("description" . "A beautiful sunset") ("file" . #P"/home/user/photos/sunset.jpg"))) ;; POST with binary data and custom content-type in multipart (dex:post "https://example.com/api/data" :content `(("metadata" . "{\"type\": \"image\"}") ("data" . (,(make-array 100 :element-type '(unsigned-byte 8)) :content-type "application/octet-stream")))) ``` ### Response #### Success Response (200) - **response-body** (string or byte-array) - The content of the response. - **status-code** (integer) - The HTTP status code. - **headers** (hash-table) - A hash table containing response headers. #### Response Example ``` "{\"status\": \"success\", \"token\": \"abc123\"}" 200 # ``` ``` -------------------------------- ### Request Content with Content-Type Override Source: https://github.com/fukamachi/dexador/blob/master/README.markdown The `:content` argument can be an alist. For multipart form encoding with a content-type override, specify the content as a list containing the key, value, and `:content-type`. ```lisp :content `(("key" ,(make-array 5 :element-type '(unsigned-byte 8)) :content-type "application/octets")) ``` -------------------------------- ### Bypassing SSL Verification Source: https://github.com/fukamachi/dexador/blob/master/README.markdown Use the `:insecure` option set to T to bypass SSL certificate verification. This should be used with caution. ```lisp (:insecure t) ``` -------------------------------- ### Receiving Response as Stream Source: https://github.com/fukamachi/dexador/blob/master/README.markdown Set `:want-stream` to T if you need to receive the response body as a stream, allowing for more control over reading the data. ```lisp (:want-stream t) ``` -------------------------------- ### Manage Cookies Source: https://github.com/fukamachi/dexador/blob/master/README.markdown Pass a cl-cookie cookie-jar instance to the :cookie-jar parameter to persist cookies across requests. ```common-lisp (defvar *cookie-jar* (cl-cookie:make-cookie-jar)) (dex:head "https://mixi.jp" :cookie-jar *cookie-jar* :verbose t) ;-> >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> ; HEAD / HTTP/1.1 ; User-Agent: Dexador/0.1 (SBCL 1.2.9); Darwin; 14.1.0 ; Host: mixi.jp ; Accept: */* ; ; >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> ; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< ; HTTP/1.1 200 OK ; Date: Tue, 10 Mar 2015 10:16:29 GMT ; Server: Apache ; X-Dealer: 152151 ; X-XRDS-Location: https://mixi.jp/xrds.pl ; Cache-Control: no-cache ; Pragma: no-cache ; Vary: User-Agent ; Content-Type: text/html; charset=EUC-JP ; Set-Cookie: _auid=9d47ca5a00ce4980c41511beb2626fd4; domain=.mixi.jp; path=/; expires=Thu, 09-Mar-2017 10:16:29 GMT ; Set-Cookie: _lcp=8ee4121c9866435007fff2c90dc31a4d; domain=.mixi.jp; expires=Wed, 11-Mar-2015 10:16:29 GMT ; X-Content-Type-Options: nosniff ; ; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< ;; Again (dex:head "https://mixi.jp" :cookie-jar *cookie-jar* :verbose t) ;-> >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> ; HEAD / HTTP/1.1 ; User-Agent: Dexador/0.1 (SBCL 1.2.9); Darwin; 14.1.0 ; Host: mixi.jp ; Accept: */* ; Cookie: _auid=b878756ed71a0ed5bcf527e324c78f8c; _lcp=8ee4121c9866435007fff2c90dc31a4d ; ; >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> ; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< ; HTTP/1.1 200 OK ; Date: Tue, 10 Mar 2015 10:16:59 GMT ; Server: Apache ; X-Dealer: 152146 ; X-XRDS-Location: https://mixi.jp/xrds.pl ; Cache-Control: no-cache ; Pragma: no-cache ; Vary: User-Agent ; Content-Type: text/html; charset=EUC-JP ; Set-Cookie: _auid=b878756ed71a0ed5bcf527e324c78f8c; domain=.mixi.jp; path=/; expires=Thu, 09-Mar-2017 10:16:59 GMT ; Set-Cookie: _lcp=8ee4121c9866435007fff2c90dc31a4d; domain=.mixi.jp; expires=Wed, 11-Mar-2015 10:16:59 GMT ; X-Content-Type-Options: nosniff ; ; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< ``` -------------------------------- ### Perform HEAD Request Source: https://context7.com/fukamachi/dexador/llms.txt Use `dex:head` to retrieve only the headers of a resource without downloading the body. Useful for checking resource existence or metadata. Set `:verbose t` for detailed request/response logging. ```common-lisp ;; HEAD request to check resource (dex:head "http://lisp.org") ;=> "" ; 200 ; # ; # ; NIL ;; HEAD with verbose output (dex:head "http://www.sbcl.org/" :verbose t) ;-> >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> ; HEAD / HTTP/1.1 ; User-Agent: Dexador/0.9.16 (SBCL 2.4.3) ; Host: www.sbcl.org ; Accept: */* ; ; >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> ``` -------------------------------- ### PATCH Request for Partial Update Source: https://context7.com/fukamachi/dexador/llms.txt Apply partial modifications to an existing resource using the PATCH method. Specify the resource URI and the fields to update, usually in JSON format. ```common-lisp ;; PATCH request for partial update (dex:patch "https://api.example.com/users/123" :headers '(("Content-Type" . "application/json")) :content "{\"role\": \"moderator\"}") ;=> "{\"id\": 123, \"role\": \"moderator\", \"updated\": true}" ; 200 ``` -------------------------------- ### Post Form Data Source: https://github.com/fukamachi/dexador/blob/master/README.markdown Specify form data using an association list in the :content parameter to send data as application/x-www-form-urlencoded. ```common-lisp (dex:post "http://example.com/entry/create" :content '(("title" . "The Truth About Lisp") ("body" . "In which the truth about lisp is revealed, and some alternatives are enumerated."))) ``` -------------------------------- ### Send Multipart Form Data Source: https://github.com/fukamachi/dexador/blob/master/README.markdown Including a pathname in the association list automatically triggers multipart/form-data encoding. ```common-lisp (dex:post "http://example.com/entry/create" :content '(("photo" . #P"images/2015030201.jpg"))) ``` -------------------------------- ### Perform a HEAD Request with Dexador Source: https://github.com/fukamachi/dexador/blob/master/README.markdown The `dex:head` function is used to make HTTP HEAD requests, which retrieve only the headers of a resource without the body. This is useful for checking metadata like `Content-Type` or `Last-Modified`. ```common-lisp (dex:head uri &key version headers basic-auth cookie-jar connect-timeout read-timeout max-redirects ssl-key-file ssl-cert-file ssl-key-password stream verbose proxy insecure ca-path) ``` -------------------------------- ### Perform a PUT Request with Dexador Source: https://github.com/fukamachi/dexador/blob/master/README.markdown Use `dex:put` to send HTTP PUT requests, typically used for updating resources on a server. It supports sending content and various request options. ```common-lisp (dex:put uri &key version content headers basic-auth cookie-jar keep-alive use-connection-pool connect-timeout read-timeout force-binary force-string want-stream ssl-key-file ssl-cert-file ssl-key-password stream verbose proxy insecure ca-path) ``` -------------------------------- ### dex:request Source: https://github.com/fukamachi/dexador/blob/master/README.markdown The primary function to send an HTTP request to a specified URI. ```APIDOC ## [ANY] [request] ### Description Sends an HTTP request to the provided URI. Signals http-request-failed for 4xx or 5xx status codes. ### Parameters #### Path Parameters - **uri** (string/quri) - Required - The target URI. #### Request Body - **content** (any) - Optional - The request body content. - **headers** (hash-table) - Optional - HTTP request headers. - **method** (symbol) - Optional - HTTP method (default: :get). - **version** (float) - Optional - HTTP version (default: 1.1). ### Response #### Success Response (200) - **body** (octet-vector/string) - The response body. - **status** (integer) - The HTTP status code. - **response-headers** (hash-table) - The response headers. - **uri** (quri) - The final URI requested. - **stream** (usocket-stream) - The connection stream if kept alive. ``` -------------------------------- ### Perform a PATCH Request with Dexador Source: https://github.com/fukamachi/dexador/blob/master/README.markdown The `dex:patch` function is for sending HTTP PATCH requests, used to apply partial modifications to a resource. It includes options for content, headers, and connection management. ```common-lisp (dex:patch uri &key version content headers basic-auth cookie-jar keep-alive use-connection-pool connect-timeout read-timeout force-binary force-string want-stream ssl-key-file ssl-cert-file ssl-key-password stream verbose proxy insecure ca-path) ``` -------------------------------- ### POST Form Data Source: https://context7.com/fukamachi/dexador/llms.txt Send form-encoded data using POST, suitable for submitting HTML form values. The content is provided as an association list. ```common-lisp ;; POST form data (application/x-www-form-urlencoded) (dex:post "https://example.com/login" :content '(("username" . "fukamachi") ("password" . "secret123"))) ;=> "{\"status\": \"success\", \"token\": \"abc123\"}" ; 200 ; # ``` -------------------------------- ### Send Bearer Token Authorization Source: https://github.com/fukamachi/dexador/blob/master/README.markdown Use the `:bearer-auth` option to include a Bearer token in the Authorization header for requests. ```common-lisp (dex:head "http://www.hatena.ne.jp/" :bearer-auth "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9" :verbose t) ``` -------------------------------- ### Handle HTTP Errors with Conditions Source: https://context7.com/fukamachi/dexador/llms.txt Handle HTTP errors using Common Lisp's condition system. Dexador signals specific conditions like `dex:http-request-not-found` or `dex:http-request-unauthorized`. You can also use `dex:ignore-and-continue`, `dex:retry-request`, or access error details. ```common-lisp ;; Handle specific HTTP error codes (handler-case (dex:get "https://api.example.com/missing-resource") (dex:http-request-not-found () (format t "Resource not found!~%" ) nil) (dex:http-request-unauthorized () (format t "Authentication required!~%" ) nil) (dex:http-request-failed (e) (format *error-output* "Request failed with status ~D~%Body: ~A~%" (dex:response-status e) (dex:response-body e)) nil)) ;; Ignore specific errors and continue (handler-bind ((dex:http-request-not-found #'dex:ignore-and-continue)) (dex:get "https://example.com/maybe-exists")) ;=> NIL ; instead of signaling an error ;; Retry on failure (handler-bind ((dex:http-request-failed #'dex:retry-request)) (dex:get "https://flaky-service.example.com/data")) ;; Retry with limits and interval (let ((retry-handler (dex:retry-request 5 :interval 3))) ; 5 retries, 3 second intervals (handler-bind ((dex:http-request-failed retry-handler)) (dex:get "https://sometimes-unavailable.example.com/api"))) ;; Retry with exponential backoff (let ((retry-handler (dex:retry-request 5 :interval (lambda (attempt) (sleep (expt 2 attempt))))))) (handler-bind ((dex:http-request-failed retry-handler)) (dex:get "https://rate-limited-api.example.com/"))) ;; Access error details (handler-case (dex:post "https://api.example.com/invalid" :content "{bad json") (dex:http-request-bad-request (e) (format t "Status: ~A~%" (dex:response-status e)) (format t "Headers: ~A~%" (dex:response-headers e)) (format t "Body: ~A~%" (dex:response-body e)) (format t "URI: ~A~%" (dex:request-uri e)) (format t "Method: ~A~%" (dex:request-method e)))) ``` -------------------------------- ### POST JSON Data Source: https://context7.com/fukamachi/dexador/llms.txt Send JSON data in the request body using POST. Ensure the 'Content-Type' header is set to 'application/json'. ```common-lisp ;; POST JSON data (dex:post "https://api.example.com/users" :headers '(("Content-Type" . "application/json")) :content "{\"name\": \"John\", \"email\": \"john@example.com\"}") ``` -------------------------------- ### DELETE Request with Bearer Authentication Source: https://context7.com/fukamachi/dexador/llms.txt Delete a resource using a DELETE request that includes Bearer token authentication and specifies an Accept header. ```common-lisp ;; DELETE with authentication and response body (dex:delete "https://api.example.com/posts/456" :bearer-auth "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..." :headers '(("Accept" . "application/json"))) ;=> "{\"deleted\": true, \"id\": 456}" ; 200 ``` -------------------------------- ### Keep-Alive and Connection Pooling Source: https://github.com/fukamachi/dexador/blob/master/README.markdown Set `:keep-alive` to T to maintain the connection after the request. Use `:use-connection-pool` (default T) to internally cache sockets for reuse, which is generally preferred over manual stream management. ```lisp (:keep-alive t :use-connection-pool t) ``` -------------------------------- ### Perform a DELETE Request with Dexador Source: https://github.com/fukamachi/dexador/blob/master/README.markdown Use `dex:delete` to send HTTP DELETE requests, which are used to remove a specified resource. It offers similar options to other request methods for configuration. ```common-lisp (dex:delete uri &key version headers basic-auth cookie-jar keep-alive use-connection-pool connect-timeout read-timeout force-binary force-string want-stream ssl-key-file ssl-cert-file ssl-key-password stream verbose proxy insecure ca-path) ``` -------------------------------- ### Dexador Request Parameters Source: https://github.com/fukamachi/dexador/blob/master/README.markdown Common parameters used across Dexador request functions to configure HTTP communication. ```APIDOC ## HTTP Request Configuration ### Description Dexador functions accept a standard set of parameters to configure the HTTP request lifecycle, including authentication, timeouts, and connection management. ### Parameters - **uri** (string or quri:uri) - Required - The target URI for the request. - **method** (keyword) - Optional - The HTTP method (:GET, :HEAD, :OPTIONS, :PUT, :POST, :DELETE). Default: :GET. - **version** (number) - Optional - HTTP protocol version (1.0 or 1.1). Default: 1.1. - **content** (string, alist, or pathname) - Optional - The request body. - **headers** (alist) - Optional - Request headers. - **basic-auth** (cons) - Optional - Username and password for basic auth (e.g., '("user" . "pass")). - **bearer-auth** (string) - Optional - Token for bearer authentication. - **cookie-jar** (cookie-jar) - Optional - Cookie storage object. - **connect-timeout** (fixnum) - Optional - Connection timeout in seconds. Default: 10. - **read-timeout** (fixnum) - Optional - Read timeout in seconds. Default: 10. - **keep-alive** (boolean) - Optional - Whether to keep the connection alive. Default: T. - **use-connection-pool** (boolean) - Optional - Whether to use internal connection pooling. Default: T. - **max-redirects** (fixnum) - Optional - Maximum number of redirects to follow. Default: 5. - **ssl-key-file / ssl-cert-file / ssl-key-password** (string) - Optional - Credentials for HTTPS connections. - **verbose** (boolean) - Optional - Enable debugging output for headers. - **force-binary** (boolean) - Optional - Suppress auto-decoding of the response body. - **want-stream** (boolean) - Optional - Return the response body as a stream. - **proxy** (string) - Optional - Proxy server URL. - **insecure** (boolean) - Optional - Bypass SSL certificate verification. ``` -------------------------------- ### DELETE Request Source: https://context7.com/fukamachi/dexador/llms.txt Remove a resource from the server. ```APIDOC ## DELETE Request Remove a resource from the server. ### Method DELETE ### Endpoint `/` (relative to host) ### Parameters #### Query Parameters - **url** (string) - Required - The URL of the resource to delete. - **bearer-auth** (string) - Optional - Bearer token for authentication. - **headers** (list of pairs) - Optional - Custom headers. ### Request Example ```common-lisp ;; Simple DELETE request (dex:delete "https://api.example.com/users/123") ;; DELETE with authentication and response body (dex:delete "https://api.example.com/posts/456" :bearer-auth "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..." :headers '(("Accept" . "application/json"))) ``` ### Response #### Success Response (204 or 200) - **response-body** (string or byte-array) - The content of the response, often empty for a 204 status. - **status-code** (integer) - The HTTP status code (typically 204 No Content or 200 OK). #### Response Example ``` "" 204 ``` ``` -------------------------------- ### Handle HTTP Request Failures Source: https://github.com/fukamachi/dexador/blob/master/README.markdown Dexador signals a `http-request-failed` condition for 4xx or 5xx status codes. Use `handler-case` or `handler-bind` to manage these errors. ```common-lisp ;; Handles 400 bad request (handler-case (dex:get "http://lisp.org") (dex:http-request-bad-request () ;; Runs when 400 bad request returned ) (dex:http-request-failed (e) ;; For other 4xx or 5xx (format *error-output* "The server returned ~D" (dex:response-status e)))) ``` ```common-lisp ;; Ignore 404 Not Found and continue (handler-bind ((dex:http-request-not-found #'dex:ignore-and-continue)) (dex:get "http://lisp.org")) ``` ```common-lisp ;; Retry (handler-bind ((dex:http-request-failed #'dex:retry-request)) (dex:get "http://lisp.org")) ``` ```common-lisp ;; Retry 5 times (let ((retry-request (dex:retry-request 5 :interval 3))) (handler-bind ((dex:http-request-failed retry-request)) (dex:get "http://lisp.org"))) ```