diff --git a/README.md b/README.md index 2cfb83c..d74f6e1 100644 --- a/README.md +++ b/README.md @@ -58,21 +58,21 @@ command menu. ## Output -Response bodies go to stdout; status, headers, timing, warnings, and errors go -to stderr. This keeps pipelines clean: +Response bodies go to stdout. Status, headers, timing, warnings, and errors go +to stderr. This separation keeps pipelines clean: ```sh fetch example.com/api | jq . ``` -Terminal output is formatted automatically. Redirected output is unformatted by -default, and binary responses are protected from accidental terminal output. +By default, `fetch` formats terminal output and does not format redirected +output. It blocks accidental binary output to a terminal. See [Output Formatting](docs/output-formatting.md) for pager, color, binary, clipboard, and file behavior. Use `--har request.har` to record the final HTTP exchange as a HAR 1.2 sidecar without changing normal response output. HAR files can contain credentials, -cookies, and bodies and should be treated as sensitive data. +cookies, and bodies. Treat HAR files as sensitive data. ## Documentation diff --git a/docs/advanced-features.md b/docs/advanced-features.md index cf7074c..74aa1e2 100644 --- a/docs/advanced-features.md +++ b/docs/advanced-features.md @@ -28,8 +28,8 @@ UDP DNS queries advertise EDNS(0) and retry truncated responses over TCP. ### DNS over TCP -Use the `tcp://` scheme for plain DNS over TCP. This avoids UDP truncation -entirely because responses are streamed with a 2-byte length prefix. +Use the `tcp://` scheme for plain DNS over TCP. TCP uses a 2-byte length prefix +and prevents UDP truncation. ```sh fetch --dns-server tcp://1.1.1.1 example.com @@ -39,8 +39,8 @@ fetch --dns-server tcp://1.1.1.1:53 example.com ### DNS over TLS (DoT) Use the `tls://` or `dot://` scheme for DNS over TLS. The default port is 853. -Both IP addresses and hostnames are accepted; hostnames are resolved with the -system resolver and used for TLS server name verification. +You can specify an IP address or a hostname. The system resolver resolves +hostnames. `fetch` uses the hostname to verify the TLS server name. ```sh fetch --dns-server tls://1.1.1.1 example.com @@ -50,7 +50,8 @@ fetch --dns-server tls://dns.google:853 example.com ### DNS over QUIC (DoQ) -Use the `quic://` or `doq://` scheme for DNS over QUIC. The default port is 853. Both IP addresses and hostnames are accepted. +Use the `quic://` or `doq://` scheme for DNS over QUIC. The default port is 853. +You can specify an IP address or a hostname. ```sh fetch --dns-server quic://1.1.1.1 example.com @@ -83,9 +84,17 @@ fetch --inspect-dns example.com fetch --inspect-dns --dns-server https://1.1.1.1/dns-query example.com ``` -Request-only CLI flags warn that no HTTP request will be sent and those flags have no effect when used with `--inspect-dns`; config-file defaults do not trigger this warning. +Request-only CLI flags have no effect with `--inspect-dns`. They cause a warning +that `fetch` does not send an HTTP request. Configuration-file defaults do not +cause this warning. -The output shows the resolver backend, A, AAAA, CNAME, TXT, MX, NS, SOA, SRV, CAA, SVCB, and HTTPS records when present, address count, record count, lookup duration, and per-record TTLs. UDP DNS inspection advertises EDNS(0) and retries truncated UDP responses over TCP; if TCP fallback cannot complete the lookup, `fetch` warns that the results are incomplete and exits with a non-zero status. +The output identifies the resolver and shows available A, AAAA, CNAME, TXT, MX, +NS, SOA, SRV, CAA, SVCB, and HTTPS records. It also shows each record TTL, the +address and record counts, and the lookup duration. + +UDP inspection advertises EDNS(0). It retries a truncated UDP response with TCP. +If the TCP retry fails, `fetch` warns that the results are incomplete and exits +with a nonzero status. ### Configuration File @@ -116,8 +125,8 @@ fetch --proxy http://proxy.example.com:8080 example.com fetch --proxy https://secure-proxy.example.com:8443 example.com ``` -HTTPS proxy TLS is configured separately from origin TLS. The proxy handshake -uses platform verification, and origin `--ca-cert`, `--cert`/`--key`, and +`fetch` configures HTTPS proxy TLS separately from origin TLS. The proxy +handshake uses platform verification. Origin `--ca-cert`, `--cert`/`--key`, and `--insecure` settings do not apply to the proxy. ### SOCKS5 Proxy @@ -145,10 +154,9 @@ export NO_PROXY="localhost,127.0.0.1,192.168.0.0/16,.internal.com" fetch example.com # Uses proxy from environment ``` -Proxy variables also support lowercase forms: `http_proxy`, `https_proxy`, -`all_proxy`, and `no_proxy`. Uppercase names are checked before lowercase names -for each variable, except uppercase `HTTP_PROXY` is ignored when -`REQUEST_METHOD` is set. +Proxy variables also have lowercase forms: `http_proxy`, `https_proxy`, +`all_proxy`, and `no_proxy`. `fetch` checks each uppercase name before its +lowercase name. It ignores uppercase `HTTP_PROXY` if `REQUEST_METHOD` is set. Proxy precedence is: an explicit `--proxy` or configured `proxy = ...` value, then scheme-specific environment variables (`HTTP_PROXY` for HTTP requests and @@ -171,7 +179,8 @@ proxy = socks5://internal-proxy:1080 ### `--unix` -Connect via Unix domain socket instead of TCP. Available on Unix-like systems only. +Connect through a Unix domain socket instead of TCP. This option is available +only on Unix-like systems. ### Docker API @@ -187,7 +196,8 @@ fetch --unix /var/run/myservice.sock http://localhost/api/status fetch --unix ~/myapp.sock http://localhost/health ``` -**Note**: The hostname in the URL is ignored when using Unix sockets; the socket path determines the destination. +With a Unix socket, the socket path sets the destination. `fetch` ignores the +hostname in the URL. ## HTTP Versions @@ -216,7 +226,7 @@ the same automatic direct HTTPS path. Prompt fresh HTTPS/SVCB results are tried before cached entries, while cached entries can race slower HTTPS-record discovery so a learned `Alt-Svc` alternative can be used on later requests. -Setting `--http 1`, `--http 2`, or `--http 3` forces that protocol; it does not +Setting `--http 1`, `--http 2`, or `--http 3` forces that protocol. It does not set a version cap. Use `--http 1` or `--http 2` to opt out of automatic HTTP/3. ### HTTP/1.1 @@ -267,7 +277,7 @@ By default, `fetch` negotiates the best available version: usable 4. Races QUIC setup against TCP/TLS when a usable `h3` candidate is discovered before TCP/TLS wins -5. Otherwise offers HTTP/2 via ALPN +5. Otherwise, offers HTTP/2 with ALPN 6. Falls back to HTTP/1.1 if needed ## TLS Configuration @@ -335,7 +345,9 @@ Output includes: Expiry is color-coded: red if expired or less than 7 days remaining, yellow if less than 30 days, green otherwise. -Request-only CLI flags (e.g. `--data`, `--timing`, `--grpc`) warn that no HTTP request will be sent and those flags have no effect when used with `--inspect-tls`; config-file defaults do not trigger this warning. +Request-only CLI flags, such as `--data`, `--timing`, and `--grpc`, have no +effect with `--inspect-tls`. They cause a warning that `fetch` does not send an +HTTP request. Configuration-file defaults do not cause this warning. `--dns-server` applies to TLS inspection too, so certificate diagnostics can use the same UDP or DNS-over-HTTPS resolver override as normal requests. When @@ -401,9 +413,10 @@ Compression modes: Output files receive decoded/decompressed bodies by default too. Use `--compress off` for byte-for-byte downloads of `.gz`, `.br`, or `.zst` assets. -For SSE (`text/event-stream`) responses in `auto` mode, `fetch` retries without -`Accept-Encoding` when the server replies with compressed content. This avoids -common buffering behavior that prevents events from appearing as they arrive. +For SSE (`text/event-stream`) responses in `auto` mode, `fetch` retries +compressed responses to `GET` and `HEAD` requests without `Accept-Encoding`. +For other methods, it keeps the compressed response and gives a warning. For +immediate SSE streaming with another method, use `--compress off`. Using `off` is useful when: @@ -495,14 +508,17 @@ streams. ### `--connect-timeout SECONDS` -Set a timeout for just the connection phase (DNS resolution, TCP connect, TLS handshake): +Set a timeout for the connection phase. This phase includes DNS resolution, the +TCP connection, and the TLS handshake: ```sh fetch --connect-timeout 5 example.com fetch --connect-timeout 5 --timeout 30 example.com # Both timeouts ``` -This is useful for fast-failing on unreachable hosts while allowing large responses to transfer slowly. The connect timeout is independent of `--timeout` — both can be set simultaneously, and `--timeout` still caps the entire request. +Use this option to stop connection attempts to unreachable hosts quickly. A +large response can continue to transfer after the connect timeout. You can set +both timeout options. The `--timeout` value still limits the complete request. ### Configuration File @@ -585,7 +601,7 @@ fetch --session staging https://staging.example.com/login ### Configuration File -Set session names per-host so you don't need `--session` every time: +Set session names for each host to omit `--session` from subsequent commands: ```ini # Global default session @@ -611,7 +627,8 @@ Sessions are stored as JSON in the user's cache directory: - **Expired cookies**: Cookies with an explicit expiry in the past are filtered out on load. - **Session cookies** (no explicit expiry): Persist across invocations since the session is explicitly named. - **Cookie domain matching**: Delegated to the Rust cookie store, which implements RFC 6265 behavior. -- **Atomic writes**: Session files are written atomically (temp file + rename) to avoid corruption. +- **Atomic writes**: `fetch` writes a temporary file and then renames it. This + operation prevents file corruption. - **Name validation**: Only `[a-zA-Z0-9_-]` characters are allowed to prevent path traversal. ## Debugging Network Issues @@ -626,25 +643,31 @@ fetch --har request.har https://api.example.com/users fetch -o response.json --har request.har https://api.example.com/users ``` -The destination is reserved before network I/O and atomically installed after -the response completes. It honors `--clobber`. Redirect, retry, and -authentication challenge exchanges are not included; only the final exchange -is recorded. Captures larger than 16 MiB are counted but omitted from the HAR. +`fetch` reserves the destination before network I/O. It installs the file +atomically after the response. The operation obeys `--clobber`. The HAR records +only the final exchange. It does not include redirect, retry, or authentication +challenge exchanges. For captures larger than 16 MiB, it records the size but +omits the content. HAR files may contain authorization headers, cookies, request bodies, and response bodies. Store and share them as sensitive data. ### Timing Waterfall -`--timing` (or `-T`) displays a timing waterfall chart after the response, showing how time was spent across DNS resolution, TCP connection setup, TLS handshake, time to first byte, and body download: +`--timing` (or `-T`) displays a timing waterfall chart after the response. The +chart shows DNS resolution, TCP connection, TLS handshake, time to first byte, +and body-download phases: ```sh fetch --timing https://example.com ``` -The chart adapts to the request: TLS is omitted for plaintext HTTP, HTTP/3 reports connection setup as QUIC, and connection phases are omitted when an existing pooled connection is reused. Combine with `-vvv` for both inline debug text and the waterfall summary. +The chart omits TLS for plaintext HTTP. It shows the HTTP/3 connection phase as +QUIC. If `fetch` reuses a pooled connection, the chart omits the connection +phases. Combine this option with `-vvv` to show debug text and the waterfall +summary. -Can also be configured in the [configuration file](configuration.md): +You can also enable the chart in the [configuration file](configuration.md): ```ini timing = true diff --git a/docs/agent-skill.md b/docs/agent-skill.md index b861c2f..5e41d09 100644 --- a/docs/agent-skill.md +++ b/docs/agent-skill.md @@ -45,7 +45,7 @@ fetch --install-skill pi --scope project | `gemini` | `~/.gemini/skills/fetch` | `.gemini/skills/fetch` | | `pi` | `~/.pi/agent/skills/fetch` | `.pi/skills/fetch` | -`all` means the five locations in the table; it does not probe for or write to +`all` means the five locations in the table. It does not probe for or write to other agent directories. ## Preview Changes @@ -91,11 +91,11 @@ when you intend to remove a locally changed copy. The skill workflow: -- operates only on the selected user or project destinations; -- does not download files; -- does not edit agent configuration files; -- detects modified installations before replacement or removal; and -- uses locked, atomic filesystem operations. +- Operates only on the selected user or project destinations. +- Does not download files. +- Does not edit agent configuration files. +- Detects modified installations before replacement or removal. +- Uses locked, atomic file operations. ## See Also diff --git a/docs/authentication.md b/docs/authentication.md index cb93c30..a113975 100644 --- a/docs/authentication.md +++ b/docs/authentication.md @@ -173,7 +173,7 @@ ca-cert = /path/to/api-ca.crt - Certificates and keys must be in PEM format - TLS requests reject a private key without a client certificate, including values from config files or `--from-curl` - Encrypted private keys are not supported -- Combined PEM files should have the certificate before the key +- In a combined PEM file, put the certificate before the key. ### Example: Self-Signed Certificates @@ -232,10 +232,13 @@ If you need multiple authentication headers, use `-H` for additional headers. ## Security Considerations -1. **Avoid embedding secrets in scripts** - Use environment variables or secure vaults -2. **Protect configuration files** - Set appropriate file permissions (`chmod 600`) -3. **Use HTTPS** - Never send credentials over unencrypted HTTP -4. **Rotate credentials regularly** - Especially API keys and tokens +1. **Do not put secrets in scripts.** Use environment variables or secure + vaults. +2. **Protect configuration files.** Set applicable file permissions, such as + `chmod 600`. +3. **Use HTTPS.** Do not send credentials over unencrypted HTTP. +4. **Replace credentials regularly.** This is especially important for API keys + and tokens. ### Secure Credential Handling @@ -257,7 +260,7 @@ fetch --bearer "$(cat /run/secrets/api-token)" example.com - Verify credentials are correct - Check if the authentication method matches what the server expects -- Ensure tokens haven't expired +- Make sure that the tokens are not expired. ### 403 Forbidden @@ -266,15 +269,18 @@ fetch --bearer "$(cat /run/secrets/api-token)" example.com ### Certificate Errors with mTLS -- Verify certificate and key match: `openssl x509 -noout -modulus -in cert.crt | openssl md5` should match `openssl rsa -noout -modulus -in key.key | openssl md5` -- Check certificate expiration: `openssl x509 -noout -dates -in cert.crt` -- Ensure the CA certificate is correct for the server +- Make sure that the certificate and key match. The output of + `openssl x509 -noout -modulus -in cert.crt | openssl md5` must match the + output of `openssl rsa -noout -modulus -in key.key | openssl md5`. +- Check the certificate expiration: + `openssl x509 -noout -dates -in cert.crt`. +- Make sure that the CA certificate is correct for the server. ### AWS SigV4 Errors - Verify `AWS_ACCESS_KEY_ID` and `AWS_SECRET_ACCESS_KEY` are set - Check the region and service name are correct -- Ensure your credentials have the required IAM permissions +- Make sure that your credentials have the necessary IAM permissions. - Verify system clock is accurate (signatures are time-sensitive) ## See Also diff --git a/docs/cli-reference.md b/docs/cli-reference.md index 5beb8e1..c658d68 100644 --- a/docs/cli-reference.md +++ b/docs/cli-reference.md @@ -41,7 +41,7 @@ fetch -X DELETE example.com/resource/123 ### `-H, --header NAME:VALUE` -Set custom headers. Can be used multiple times. +Set custom headers. Repeat this option to set multiple headers. ```sh fetch -H "Authorization: Bearer token" example.com @@ -50,7 +50,8 @@ fetch -H "X-Custom: value" -H "Accept: application/json" example.com ### `-q, --query KEY=VALUE` -Append query parameters to the URL. Can be used multiple times. +Append query parameters to the URL. Repeat this option to append multiple +parameters. ```sh fetch -q page=1 -q limit=50 example.com @@ -58,10 +59,10 @@ fetch -q page=1 -q limit=50 example.com ## Request Body Options -Payload source options are mutually exclusive - only one of `--data`, `--json`, -`--xml`, `--form`, or `--multipart` can be used per request. These options, and -`--edit`, default the request method to `POST` when `--method` is omitted; use -`-m`/`--method` to send the body with another method. +Payload source options are mutually exclusive. Use only one of `--data`, +`--json`, `--xml`, `--form`, or `--multipart` in a request. These options and +`--edit` set the default request method to `POST`. Use `-m` or `--method` to +send the body with another method. ### `-d, --data [@]VALUE` @@ -93,7 +94,7 @@ fetch -x @data.xml -m PUT example.com ### `-f, --form KEY=VALUE` -Send a URL-encoded form body. Can be used multiple times. +Send a URL-encoded form body. Repeat this option to send multiple fields. ```sh fetch -f username=john -f password=secret example.com/login @@ -101,7 +102,8 @@ fetch -f username=john -f password=secret example.com/login ### `-F, --multipart NAME=[@]VALUE` -Send a multipart form body. Use `@` prefix for file uploads. Can be used multiple times. +Send a multipart form body. Use the `@` prefix for file uploads. Repeat this +option to send multiple fields. ```sh fetch -F hello=world -F file=@document.pdf example.com/upload @@ -109,7 +111,8 @@ fetch -F hello=world -F file=@document.pdf example.com/upload ### `-e, --edit` -Open an editor to modify the request body before sending. Uses `VISUAL` or `EDITOR` environment variables. +Open an editor to modify the request body before you send it. `fetch` uses the +`VISUAL` or `EDITOR` environment variable. ```sh fetch --edit example.com @@ -129,8 +132,9 @@ fetch --basic username:password example.com ### `--digest USER:PASS` -HTTP Digest Authentication. Uses a challenge-response handshake to avoid sending credentials in plain text. -Supports challenges without `qop` and challenges with `qop=auth`; unsupported digest parameters are reported as diagnostics. +Use HTTP Digest Authentication. A challenge-response handshake prevents the +transmission of credentials in plain text. `fetch` supports challenges without +`qop` and challenges with `qop=auth`. It reports unsupported digest parameters. ```sh fetch --digest username:password example.com @@ -146,7 +150,9 @@ fetch --bearer mysecrettoken example.com ### `--aws-sigv4 REGION/SERVICE` -Sign requests with AWS Signature V4. Requires `AWS_ACCESS_KEY_ID` and `AWS_SECRET_ACCESS_KEY` environment variables. Temporary credentials can also set `AWS_SESSION_TOKEN`. +Sign requests with AWS Signature V4. Set the `AWS_ACCESS_KEY_ID` and +`AWS_SECRET_ACCESS_KEY` environment variables. For temporary credentials, also +set `AWS_SESSION_TOKEN`. ```sh fetch --aws-sigv4 us-east-1/s3 s3.amazonaws.com/bucket/key @@ -217,22 +223,24 @@ fetch -o output.json --clobber example.com/data Write a HAR 1.2 sidecar containing the final HTTP exchange while preserving the normal response output. The capture includes the effective request, finalized headers and streamed request body, decoded response body, remote IP, and timing -information. Unary gRPC is supported; protobuf frames are stored as base64. +information. Unary gRPC is supported. `fetch` stores protobuf frames as base64. ```sh fetch --har request.har https://api.example.com/users fetch -o response.json --har request.har https://api.example.com/users ``` -The destination is reserved before the request, is installed atomically after -the response completes, and follows `--clobber`. `PATH` cannot be `-` or match +`fetch` reserves the destination before the request and installs the file +atomically after the response. The operation obeys `--clobber`. `PATH` cannot +be `-` or match `--output`. WebSocket, inspection, gRPC discovery, and `--dry-run` modes are not supported. The initial HAR contains only the final exchange after redirects, retries, or authentication challenges. -HAR files may contain credentials, cookies, request bodies, and response bodies. -Treat them as sensitive data. Body capture is bounded at 16 MiB; larger bodies -are counted completely but their text is omitted with a truncation comment. +HAR files can contain credentials, cookies, request bodies, and response bodies. +Treat HAR files as sensitive data. Body capture has a limit of 16 MiB. For a +larger body, `fetch` records its size and replaces its text with a truncation +comment. ### `--copy` @@ -258,7 +266,7 @@ Do not print the response body. Useful for checking status codes, viewing header `--discard` still reads the response body to completion. Use `-m HEAD` when you want to ask the server to avoid transferring a response body. -Cannot be combined with `--output`, `--remote-name`, or `--copy`. +Do not use this option with `--output`, `--remote-name`, or `--copy`. ```sh fetch --discard example.com @@ -293,7 +301,7 @@ to 16 MiB. The flag cannot be combined with gRPC, WebSocket, `--discard`, mode's HTML-oriented default. `--format`, `--color`, and `--pager` control terminal presentation of the -generated Markdown; they do not disable article extraction. Output files and +generated Markdown. They do not disable article extraction. Output files and non-formatted pipes receive raw, uncolored Markdown. ### `--format OPTION` @@ -342,7 +350,7 @@ fetch --pager off example.com When paging is enabled, fetch uses `$PAGER` if it is set. Set `NO_PAGER` to disable the default `auto` pager. If `$PAGER` is unset, fetch falls back to -`less -FIRX`; when `$LESS` is set, fetch runs `less` without adding its default +`less -FIRX`. When `$LESS` is set, `fetch` runs `less` without adding its default flags so your `LESS` options apply. `$PAGER` is split with POSIX shell-style quoting, but fetch launches the pager directly and does not interpret shell operators such as pipes or redirects. @@ -351,9 +359,12 @@ operators such as pipes or redirects. ### `-S, --session NAME` -Use a named session for persistent cookie storage across invocations. Cookies set by servers are saved to disk and automatically sent on subsequent requests using the same session name. +Use a named session to keep cookies for subsequent commands. `fetch` saves +server cookies to disk. It sends the cookies in subsequent requests that use +the same session name. -Session names must contain only alphanumeric characters, hyphens, and underscores (`[a-zA-Z0-9_-]`). +Use only alphanumeric characters, hyphens, and underscores in session names +(`[a-zA-Z0-9_-]`). ```sh # First request — server sets cookies, they get saved @@ -368,7 +379,8 @@ Session files are stored in the user's cache directory: - **Linux**: `~/.cache/fetch/sessions/.json` - **macOS**: `~/Library/Caches/fetch/sessions/.json` -Can also be configured per-host in the [configuration file](configuration.md). +You can also configure sessions for each host in the [configuration +file](configuration.md). ## Network Options @@ -384,7 +396,7 @@ fetch --connect-timeout 5 --timeout 30 example.com ### `-t, --timeout SECONDS` Request timeout in seconds. Accepts decimal values. The timeout covers the full -request, including response body streaming; it is also enforced for SSE, NDJSON, +request, including response body streaming. It also applies to SSE, NDJSON, and gRPC streams. ```sh @@ -397,7 +409,7 @@ fetch --timeout 2.5 example.com Maximum automatic redirects. Default: `10`. Use `0` to disable. ```sh -fetch --redirects 0 example.com # Don't follow redirects +fetch --redirects 0 example.com # Do not follow redirects fetch --redirects 10 example.com ``` @@ -405,9 +417,12 @@ fetch --redirects 10 example.com Maximum number of retries for transient failures. Default: `0` (no retries). -Retries occur on connection errors and retryable status codes (429, 502, 503, 504). Non-retryable errors (4xx, TLS certificate errors) are not retried. Uses exponential backoff with jitter between attempts. +`fetch` retries connection errors and status codes 429, 502, 503, and 504. It +does not retry other 4xx errors or TLS certificate errors. Between attempts, it +uses exponential backoff with jitter. -Only the final attempt's response body is written to stdout. Retry notifications are printed to stderr (suppressed with `--silent`). +`fetch` writes only the final response body to stdout. It writes retry +notifications to stderr. Use `--silent` to hide these notifications. ```sh fetch --retry 3 example.com @@ -418,7 +433,11 @@ fetch --retry 2 --retry-delay 0.5 example.com Initial delay between retries in seconds. Default: `1`. Accepts decimal values. -The actual delay uses exponential backoff (delay doubles each attempt) with ±25% jitter. The effective delay is capped at 30 seconds. If the server sends a `Retry-After` header, that value is used when it exceeds the computed delay, but it is also capped at 30 seconds. A warning is emitted when `Retry-After` is clamped unless `--silent` is enabled. An overall `--timeout` remains the final upper bound. +The delay doubles after each attempt and includes ±25% jitter. The maximum delay +is 30 seconds. If the server sends a larger `Retry-After` value, `fetch` uses +that value up to 30 seconds. It gives a warning if it reduces `Retry-After` to +30 seconds. Use `--silent` to hide this warning. The overall `--timeout` value +continues to limit all attempts. ```sh fetch --retry 3 --retry-delay 2 example.com @@ -448,7 +467,18 @@ fetch --dns-server https://1.1.1.1/dns-query example.com ### `--inspect-dns` -Inspect DNS resolution for the URL hostname only (no HTTP request is made). Displays the resolver backend, A, AAAA, CNAME, TXT, MX, NS, SOA, SRV, CAA, SVCB, and HTTPS records when present, along with per-record TTLs, address count, record count, and lookup duration. Supports all `--dns-server` transports. UDP DNS inspection advertises EDNS(0) and retries truncated UDP responses over TCP; if TCP fallback cannot complete the lookup, `fetch` warns that the results are incomplete and exits with a non-zero status. Request-only CLI flags warn that no HTTP request will be sent and those flags have no effect; config-file defaults do not trigger this warning. +Inspect DNS resolution for the URL hostname. This operation does not make an +HTTP request. The output identifies the resolver and shows available A, AAAA, +CNAME, TXT, MX, NS, SOA, SRV, CAA, SVCB, and HTTPS records. It also shows each +record TTL, the address and record counts, and the lookup duration. + +All `--dns-server` transports are supported. UDP inspection advertises EDNS(0). +It retries a truncated UDP response with TCP. If the TCP retry fails, `fetch` +warns that the results are incomplete and exits with a nonzero status. + +Request-only CLI flags have no effect with `--inspect-dns`. They cause a warning +that `fetch` does not send an HTTP request. Configuration-file defaults do not +cause this warning. ```sh fetch --inspect-dns example.com @@ -508,11 +538,11 @@ fetch --min-tls 1.2 --max-tls 1.2 example.com Encrypted Client Hello mode. Values: `auto`, `on`, `off`. Default: `off`. -- **`auto`** — Use ECH if the server advertises it via DNS HTTPS/SVCB records. +- **`auto`** — Use ECH if the server advertises it in DNS HTTPS/SVCB records. Falls back to GREASE ECH when no real config is found. If the server rejects the offer, the connection proceeds gracefully. -- **`on`** — Require ECH. Errors if the server doesn't advertise ECH in DNS, - and fails if the server rejects the offer. +- **`on`** — Require ECH. `fetch` reports an error if the server does not + advertise ECH in DNS or rejects the offer. - **`off`** — Never use ECH. ECH requires TLS 1.3 and is incompatible with `--min-tls 1.2`. @@ -526,7 +556,15 @@ See [Encrypted Client Hello](ech.md) for details. ### `--inspect-tls` -Inspect the TLS certificate chain by performing a TLS handshake only (no HTTP request is made). Displays the TLS version, cipher suite, ALPN protocol, full certificate chain with expiry status, Subject Alternative Names (SANs), and OCSP staple status. Requires an HTTPS URL. With `--http 3`, inspection uses a QUIC handshake and offers `h3` ALPN. Request-only CLI flags (e.g. `--data`, `--timing`, `--grpc`) warn that no HTTP request will be sent and those flags have no effect; config-file defaults do not trigger this warning. +Inspect the TLS certificate chain with a TLS handshake. This operation does not +make an HTTP request. The output shows the TLS version, cipher suite, ALPN +protocol, certificate chain and expiry status, Subject Alternative Names +(SANs), and OCSP staple status. Use an HTTPS URL. With `--http 3`, inspection +uses a QUIC handshake and offers `h3` ALPN. + +Request-only CLI flags have no effect with `--inspect-tls`. They cause a warning +that `fetch` does not send an HTTP request. Configuration-file defaults do not +cause this warning. ```sh fetch --inspect-tls example.com @@ -578,7 +616,7 @@ also use the normal ALPN path. a maximum version. `--http 2` with a plain `http://` URL is only supported for gRPC requests, where `fetch` uses h2c (HTTP/2 over cleartext) for local plaintext servers. Use `--http 1` or `--http 2` to opt out of automatic -HTTP/3; forced `--http 3` remains strict and does not fall back to TCP. +HTTP/3. Forced `--http 3` remains strict and does not fall back to TCP. ```sh fetch --http 1 example.com @@ -602,9 +640,10 @@ Control response compression negotiation. Values: `auto`, `br`/`brotli`, `gzip`, Output files also receive decoded/decompressed bodies by default. Use `--compress off` for byte-for-byte downloads of `.gz`, `.br`, or `.zst` assets. -In `auto` mode, compressed SSE (`text/event-stream`) responses are retried -without `Accept-Encoding` so streaming events can be delivered promptly instead -of being buffered by compression. +In `auto` mode, `fetch` retries compressed SSE (`text/event-stream`) responses +to `GET` and `HEAD` requests without `Accept-Encoding`. For other methods, it +keeps the compressed response and gives a warning. For immediate SSE streaming +with another method, use `--compress off`. ```sh fetch --compress br example.com @@ -616,7 +655,7 @@ fetch --compress off example.com ### `-r, --range RANGE` -Request specific byte ranges. Can be used multiple times. +Request specific byte ranges. Repeat this option to request multiple ranges. ```sh fetch -r 0-1023 example.com/file.bin @@ -627,7 +666,7 @@ fetch -r 0-499 -r 1000-1499 example.com/file.bin ### `-v, --verbose` -Increase output verbosity. Can be stacked. +Increase output verbosity. Repeat `v` to increase the level. - `-v` - Show response headers - `-vv` - Show request and response headers with `> ` / `< ` prefixes @@ -642,7 +681,10 @@ fetch -vvv example.com ### `-T, --timing` -Display a timing waterfall chart after the response. Shows DNS, TCP, TLS, TTFB, and body download phases as a proportional bar chart. HTTP/3 reports connection setup as QUIC. Works independently of verbosity. Phases that don't apply (e.g., TLS for plaintext HTTP or connection phases for reused connections) are omitted. +Display a timing waterfall chart after the response. The proportional bars show +DNS, TCP, TLS, time to first byte (TTFB), and body-download phases. HTTP/3 shows +the connection phase as QUIC. The chart does not depend on the verbosity level. +It omits phases that do not apply, such as TLS for plaintext HTTP. ```sh fetch --timing https://example.com @@ -660,7 +702,7 @@ fetch -s example.com ### `--ignore-status` -HTTP 4xx/5xx responses exit nonzero by default; use `--ignore-status` to keep +HTTP 4xx/5xx responses exit nonzero by default. Use `--ignore-status` to keep the exit code at 0 when the request completes. ```sh @@ -683,8 +725,8 @@ Use `--ws-interactive auto|on|off` to control the terminal prompt. Use `--ws-message-mode auto|text|binary` to control whether outgoing messages are sent as text or binary WebSocket frames. -Piped text/auto input is line-delimited and capped at 16 MiB per line; use -`--ws-message-mode binary` for larger raw streams. +Piped text or auto input uses line delimiters and has a limit of 16 MiB for each +line. Use `--ws-message-mode binary` for larger raw streams. Incoming WebSocket server frames and assembled messages are capped at 16 MiB. @@ -746,7 +788,9 @@ Add import paths for proto compilation. Use with `--proto-file`. fetch --grpc --proto-file service.proto --proto-import ./proto localhost:50051/pkg.Svc/Method ``` -Plaintext servers are supported via `h2c` (HTTP/2 over cleartext) when using an `http://` URL with HTTP/2. This works for `--grpc` and reflection-based discovery (`--grpc-list`, `--grpc-describe`). +For plaintext servers, use `h2c` (HTTP/2 over cleartext) with an `http://` URL +and HTTP/2. You can use this configuration for `--grpc` and reflection-based +discovery (`--grpc-list`, `--grpc-describe`). ## Configuration @@ -764,7 +808,9 @@ fetch --config ~/.config/fetch/custom.conf example.com Execute a curl command using fetch. Parses a curl command string and translates its flags into the equivalent fetch options. The `curl` prefix is optional. -Cannot be combined with other request-specifying flags (URL, `--method`, `--header`, `--data`, auth flags, etc.). Meta flags like `--dry-run`, `--color`, `--format`, `--pager`, and `--timing` can still be used. +Do not use this option with other request options, such as a URL, `--method`, +`--header`, `--data`, or authentication options. You can use it with metadata +options such as `--dry-run`, `--color`, `--format`, `--pager`, and `--timing`. ```sh # Basic GET @@ -804,7 +850,8 @@ fetch --from-curl 'https://example.com' **Notes:** -- `-b`/`--cookie` only supports inline cookie strings (e.g., `-b 'name=value'`). Cookie jar files are not supported and will return an error. +- `-b` and `--cookie` support only inline cookie strings, such as + `-b 'name=value'`. Cookie jar files cause an error. - A single `-d @filename` or `-d @-` body streams through fetch's native request body path. Composite data bodies and `--data-urlencode @filename` are materialized for curl compatibility and are capped at 16 MiB. - `--data-urlencode` supports `@filename` and `name@filename` forms for reading and URL-encoding file contents. - `-n`/`--netrc` is not supported. Use `--basic`, `--bearer`, or an explicit `Authorization` header instead. @@ -817,7 +864,7 @@ Unknown curl flags return an error. ### `-h, --help` Print help information. Use `-v --help` or `--verbose --help` for the detailed, -colorized CLI reference. Detailed help follows `--pager`; use `--pager off` to +colorized CLI reference. Detailed help obeys `--pager`. Use `--pager off` to print directly and `--color off` to disable color. ### `-V, --version` @@ -844,7 +891,7 @@ fetch --install-skill [agents|codex|claude|gemini|pi|all] fetch --uninstall-skill [agents|codex|claude|gemini|pi|all] ``` -`agents` is the default target. User scope is the default; use +`agents` is the default target. User scope is the default. Use `--scope user|project` to select the destination scope. `--dry-run` previews changes, and `--force` permits replacing or removing a locally modified installation. diff --git a/docs/configuration.md b/docs/configuration.md index 466d5e6..16b85d9 100644 --- a/docs/configuration.md +++ b/docs/configuration.md @@ -29,13 +29,15 @@ lowest): 3. **Global configuration** - Global settings in config file 4. **Default values** - Built-in application defaults -In short: scalar options override; list options merge global -> host -> CLI. +In summary, scalar options override other scalar options. List options merge in +this order: global, host, and CLI. Repeatable options such as `header`, `query`, and `ca-cert` are applied in this order: global config first, then the matched host section, then command-line flags. -This allows you to set global defaults, override scalar values per-domain or -per-command, and add shared list values without losing more specific entries. +As a result, you can set global defaults and override scalar values for each domain or +command. You can also add shared list values without removing more specific +entries. ### File Structure @@ -158,9 +160,9 @@ image = off Control piping response body output through a pager. `auto` uses the pager when stdout is a terminal, `on` forces pager use, and `off` disables the pager. When paging is enabled, fetch uses `$PAGER` if it is set. Set `NO_PAGER` to disable -the default `auto` pager. If `$PAGER` is unset, fetch falls back to `less -FIRX`; -when `$LESS` is set, fetch runs `less` without adding its default flags so your -`LESS` options apply. `$PAGER` is split with POSIX shell-style quoting, but +the default `auto` pager. If `$PAGER` is unset, `fetch` uses `less -FIRX`. +If `$LESS` is set, `fetch` runs `less` without its default flags. Your `LESS` +options still apply. `$PAGER` is split with POSIX shell-style quoting, but fetch launches the pager directly and does not interpret shell operators such as pipes or redirects. @@ -230,7 +232,7 @@ verbosity = 3 **Default**: `false` Sort displayed request and response headers alphabetically by name. This only -changes verbose output; request headers are still sent in their normal order. +changes verbose output. `fetch` sends request headers in their normal order. ```ini sort-headers = true @@ -403,7 +405,7 @@ HTTPS-record discovery is too slow, fails, is unsupported by the OS resolver, or returns no usable `h3` record, HTTPS offers `h2` then `http/1.1` through ALPN. Proxy and Unix socket requests also use the normal ALPN path. -Setting this option to `1`, `2`, or `3` forces that protocol; it does not set a +Setting this option to `1`, `2`, or `3` forces that protocol. It does not set a version cap. Set `http = 1` or `http = 2` to opt out of automatic HTTP/3. Forced HTTP/2 with a plain `http://` URL is only supported for gRPC requests, where `fetch` uses h2c (HTTP/2 over cleartext). @@ -499,7 +501,9 @@ insecure = false **Type**: File path **Default**: None -Path to a client certificate file for mTLS authentication. The file should be in PEM format. If the file contains both the certificate and private key, no separate `key` option is needed. +Specify the path to a client certificate file for mTLS authentication. Use PEM +format. If the file contains the certificate and private key, you do not need a +separate `key` option. ```ini # Client certificate for mTLS @@ -514,7 +518,8 @@ cert = /path/to/client.pem **Type**: File path **Default**: None -Path to a client private key file for mTLS authentication. The file should be in PEM format. Required if `cert` points to a certificate-only file. +Specify the path to a client private key file for mTLS authentication. Use PEM +format. This option is required if `cert` points to a certificate-only file. ```ini # Client private key for mTLS @@ -535,12 +540,13 @@ key = /path/to/api-client.key ca-cert = /path/to/api-ca.crt ``` -**Notes:** +**Operation:** -- If `cert` is provided without `key`, the tool will attempt to read the private key from the certificate file (combined PEM format) -- If the private key cannot be found, an error will be displayed -- TLS requests reject `key` without `cert` -- Encrypted private keys are not supported +- If you specify `cert` without `key`, `fetch` reads the private key from the + certificate file. +- If `fetch` does not find the private key, it reports an error. +- TLS requests reject `key` without `cert`. +- `fetch` does not support encrypted private keys. #### `compress` @@ -568,8 +574,10 @@ Output files receive decoded/decompressed bodies by default too. Use `compress = off` or `--compress off` for byte-for-byte downloads of `.gz`, `.br`, or `.zst` assets. -When `compress = auto`, compressed SSE (`text/event-stream`) responses are -retried without `Accept-Encoding` so events can be displayed as they arrive. +With `compress = auto`, `fetch` retries compressed SSE (`text/event-stream`) +responses to `GET` and `HEAD` requests without `Accept-Encoding`. For other +methods, it keeps the compressed response and gives a warning. For immediate +SSE streaming with another method, set `compress = off`. ### Session Options @@ -578,7 +586,10 @@ retried without `Accept-Encoding` so events can be displayed as they arrive. **Type**: String **Default**: None -Set a named session for persistent cookie storage. Cookies set by servers are saved to disk and automatically sent on subsequent requests using the same session name. The name must contain only alphanumeric characters, hyphens, and underscores. +Set a named session to keep cookies for subsequent commands. `fetch` saves +server cookies to disk. It sends the cookies in subsequent requests that use +the same session name. Use only alphanumeric characters, hyphens, and +underscores in the name. ```ini # Global default session @@ -601,7 +612,7 @@ CLI `--session` flag overrides the config value. See [CLI Reference](cli-referen **Type**: String (name:value format) **Repeatable**: Yes -Set custom HTTP headers. Can be specified multiple times. +Set custom HTTP headers. Repeat this option to set multiple headers. ```ini # Single header @@ -618,7 +629,8 @@ header = User-Agent: MyApp/1.0 **Type**: String (key=value format) **Repeatable**: Yes -Append query parameters to requests. Can be specified multiple times. +Append query parameters to requests. Repeat this option to append multiple +parameters. ```ini # Single query parameter @@ -648,7 +660,7 @@ ignore-status = false ## Host-Specific Configuration -You can configure different settings for specific hosts or domains using sections: +Use sections to configure different settings for specified hosts or domains: ```ini # Global settings apply to all requests @@ -675,7 +687,7 @@ redirects = 0 ### Wildcard Subdomain Matching -You can use `[*.domain.com]` syntax to match any subdomain of a domain: +Use the `[*.domain.com]` syntax to match all subdomains of a domain: ```ini # Match any subdomain of example.com @@ -693,7 +705,7 @@ header = X-API-Key: admin-key **Matching rules:** -- `*.example.com` matches `api.example.com`, `a.b.example.com`, etc. +- `*.example.com` matches `api.example.com` and `a.b.example.com`. - `*.example.com` does **not** match `example.com` itself - Exact matches always take priority over wildcard matches - When multiple wildcards match, the most specific (longest suffix) wins @@ -701,7 +713,8 @@ header = X-API-Key: admin-key ### Host Section Rules -- Section names should be the exact hostname (without protocol or path), or a wildcard pattern like `*.domain.com` +- Use the exact hostname, without the protocol or path, as the section name. + Alternatively, use a wildcard pattern such as `*.domain.com`. - Duplicate host section names are rejected. Names are compared case-insensitively after trimming, so `[API.example.com]` and `[api.example.com]` are duplicates. - Scalar host-specific settings override global settings - Scalar command-line flags override both global and host-specific settings @@ -767,28 +780,29 @@ header = X-Company-ID: company-identifier ## Configuration File Validation -`fetch` validates configuration files when loading them and will report errors: +`fetch` validates configuration files when it loads them. It reports errors in +this format: ``` config file '/home/user/.config/fetch/config': line 15: invalid option: 'invalid-option' ``` -Validation errors may include: +The tool reports these types of validation error: - Invalid option names -- Invalid values for specific options (e.g., `color = invalid`) +- Invalid values for specified options, such as `color = invalid` - Malformed key=value pairs - Empty host section names `[]` ## Best Practices -1. **Use host-specific sections** for API keys and service-specific settings -2. **Set reasonable timeouts** to avoid hanging requests -3. **Use global settings** for common preferences like colors and formatting -4. **Keep sensitive data secure** - configuration files may contain API keys -5. **Test configurations** with dry-run mode: `fetch --dry-run example.com` -6. **Use comments** to document complex configurations -7. **Enable auto-update** for security and feature updates +1. **Use host-specific sections** for API keys and service-specific settings. +2. **Set applicable timeouts** to prevent requests from running too long. +3. **Use global settings** for common preferences such as color and formatting. +4. **Keep configuration files secure.** They can contain API keys. +5. **Test configurations** with dry-run mode: `fetch --dry-run example.com`. +6. **Use comments** to document complex configurations. +7. **Enable automatic updates** to get security and feature updates. ## See Also diff --git a/docs/ech.md b/docs/ech.md index f874084..0908e6f 100644 --- a/docs/ech.md +++ b/docs/ech.md @@ -31,7 +31,7 @@ fetch --ech off https://example.com ECH defaults to `off` rather than `auto` because `auto` requires an extra DNS SVCB query on every HTTPS request, which adds latency with no benefit - when the server doesn't support ECH. Use `--ech auto` or set `ech = auto` + if the server does not support ECH. Use `--ech auto` or set `ech = auto` in your config to enable opportunistic ECH. ## GREASE ECH diff --git a/docs/getting-started.md b/docs/getting-started.md index b9297d2..9368e3f 100644 --- a/docs/getting-started.md +++ b/docs/getting-started.md @@ -1,6 +1,6 @@ # Getting Started -This guide will help you install `fetch` and make your first HTTP request. +Use this guide to install `fetch` and make your first HTTP request. ## Installation @@ -46,7 +46,7 @@ Make a GET request by providing a URL: fetch httpbin.org/json ``` -The response body is automatically formatted and syntax-highlighted: +`fetch` automatically formats and highlights the response body: ``` HTTP/2.0 200 OK @@ -59,7 +59,7 @@ HTTP/2.0 200 OK } ``` -When no scheme is provided, `fetch` defaults to HTTPS: +If you do not specify a scheme, `fetch` uses HTTPS: ```sh fetch example.com # Uses https://example.com @@ -74,7 +74,7 @@ fetch 192.168.1.1:8080 # Uses http://192.168.1.1:8080 fetch 1.1.1.1 # Uses http://1.1.1.1 ``` -You can always specify the scheme explicitly: +Specify the scheme to override the default: ```sh fetch http://example.com # Force HTTP @@ -92,7 +92,8 @@ equivalent `http://` URL. 1. **Status line** (stderr) - The HTTP version, status code, and status text 2. **Response body** (stdout) - The response content, automatically formatted -This separation means you can pipe the body to other tools or redirect it to a file without the status line getting in the way: +As a result, you can pipe the body to other tools or redirect it to a file. The status +line does not go to the pipe or file: ```sh # Save just the response body to a file @@ -104,7 +105,8 @@ fetch httpbin.org/json | jq '.slideshow.title' ### Auto-formatting -`fetch` automatically detects the content type and formats the response with syntax highlighting. Supported formats include: +`fetch` detects the content type and formats the response. It supports these +formats: - **JSON** - Pretty-printed with syntax highlighting - **XML / HTML** - Indented and highlighted @@ -217,13 +219,18 @@ fetch -vvv httpbin.org/json < ... ``` -The `> `, `< `, and `* ` prefixes make the direction of data instantly clear: outgoing request lines, incoming response lines, and informational/connection details. +The prefixes identify each type of output: -This is useful for diagnosing latency issues, verifying TLS configuration, and understanding connection behavior. +- `> ` identifies outgoing request lines. +- `< ` identifies incoming response lines. +- `* ` identifies connection information. + +Use this output to diagnose latency, verify the TLS configuration, and examine +the connection. ### `--dry-run` - Preview Without Sending -Preview the exact request that would be sent without actually making the HTTP call: +Preview the request without sending it: ```sh fetch --dry-run -vv -j '{"hello":"world"}' httpbin.org/post @@ -269,7 +276,7 @@ fetch -H "X-Custom: value" httpbin.org/get fetch -q name=test -q page=1 httpbin.org/get ``` -Query parameters are URL-encoded and appended to the URL automatically. +`fetch` encodes the query parameters and appends them to the URL. ### Sending Form Data @@ -311,12 +318,13 @@ output: fetch --har request.har httpbin.org/json ``` -HAR files can contain credentials, cookies, and bodies, so handle them as +HAR files can contain credentials, cookies, and bodies. Treat HAR files as sensitive data. ### Viewing Images -`fetch` can render images directly in terminals that support inline images (Kitty, iTerm2), with a block-character fallback for other terminals. +`fetch` renders images directly in terminals that support inline images, such +as Kitty and iTerm2. For other terminals, it uses block characters. ```sh fetch httpbin.org/image/png @@ -326,7 +334,8 @@ See [Image Rendering](image-rendering.md) for details. ## Sessions -Sessions let you persist cookies across multiple requests. This is useful for interacting with APIs that use cookie-based authentication: +Sessions keep cookies for subsequent requests. Use sessions for APIs that use +cookie authentication: ```sh # Log in - cookies are saved to the "myapi" session diff --git a/docs/grpc.md b/docs/grpc.md index 2b9ea20..5705a93 100644 --- a/docs/grpc.md +++ b/docs/grpc.md @@ -98,7 +98,7 @@ fetch --grpc --proto-file common.proto,service.proto \ Use a pre-compiled descriptor set file. Useful when: -- `protoc` isn't available at runtime +- `protoc` is not available at run time - You want faster startup (no compilation) - Building CI/CD pipelines @@ -380,17 +380,18 @@ apt install protobuf-compiler - Verify the URL path matches `package.Service/Method` exactly - Check that your proto file defines the service and method -- Ensure all required imports are included via `--proto-import` +- Include all necessary imports with `--proto-import`. ### "failed to parse JSON" - Verify JSON syntax is correct - Check field names match proto definitions (use snake_case) -- Ensure types match (strings quoted, numbers not quoted) +- Make sure that the types match. Put quotation marks around strings, but not + around numbers. ### Connection Errors -- gRPC requires HTTP/2 - ensure server supports it +- gRPC requires HTTP/2. Make sure that the server supports it. - Check port number (gRPC typically uses different ports than REST) - For TLS issues, try `--insecure` for testing @@ -402,7 +403,9 @@ apt install protobuf-compiler ## Server Streaming -`fetch` supports server-side streaming gRPC responses. Each response message is formatted and displayed as it arrives, following the same real-time streaming pattern used for SSE and NDJSON responses. +`fetch` supports server-streaming gRPC responses. It formats and displays each +response message when the message arrives. SSE and NDJSON responses use the +same streaming pattern. ```sh fetch --grpc --proto-file service.proto \ @@ -422,7 +425,8 @@ If a server compresses individual response messages, `fetch` decompresses gzip-f `fetch` supports client-side streaming gRPC calls. When the proto schema indicates a method is client-streaming, multiple JSON objects in the request body are each converted to a separate protobuf message and sent as individual gRPC frames. -Detection is automatic via the method descriptor in the proto schema — no additional flags are needed. +`fetch` uses the method descriptor in the proto schema to detect client +streaming. You do not need additional flags. ### Inline Data @@ -444,7 +448,8 @@ fetch --grpc --proto-file service.proto \ ### Streaming from Stdin -Pipe data from stdin for real-time streaming — each JSON object is sent as soon as it is parsed: +Pipe data from stdin for real-time streaming. `fetch` sends each JSON object +when it completes parsing the object: ```sh cat messages.ndjson | fetch --grpc --proto-file service.proto \ @@ -453,18 +458,23 @@ cat messages.ndjson | fetch --grpc --proto-file service.proto \ ## Bidirectional Streaming -Bidirectional streaming is supported with the same mechanism as client streaming. When piping from stdin, request frames are sent incrementally while response frames are received and displayed concurrently: +Bidirectional streaming uses the same mechanism as client streaming. When you +pipe data from stdin, `fetch` sends request frames incrementally. At the same +time, it receives and displays response frames: ```sh cat messages.ndjson | fetch --grpc --proto-file service.proto \ -d @- https://localhost:50051/pkg.Service/BidiStream ``` -Both directions flow on the same HTTP/2 stream. The response is formatted and displayed as messages arrive, just like server streaming. +Both directions use the same HTTP/2 stream. `fetch` formats and displays each +response message when it arrives. ## Limitations -- **Client/bidi streaming requires a proto schema**: The `--proto-file` or `--proto-desc` flag must be provided so `fetch` can detect that a method is client-streaming +- **Client and bidirectional streaming require a proto schema**: Specify + `--proto-file` or `--proto-desc`. `fetch` uses the schema to identify a + client-streaming method. - **gRPC-Web**: Standard gRPC protocol only, not gRPC-Web ## See Also diff --git a/docs/image-rendering.md b/docs/image-rendering.md index e6e15f2..7048f94 100644 --- a/docs/image-rendering.md +++ b/docs/image-rendering.md @@ -1,6 +1,6 @@ # Image Rendering -`fetch` can render images directly in your terminal when fetching image URLs. +`fetch` renders images directly in the terminal. ## Image Control @@ -32,17 +32,19 @@ These formats are decoded without external tools: ### With External Adapters -When `--image external` is set, these additional formats are supported if you have the required tools installed: +If you set `--image external`, `fetch` supports these additional formats when +the necessary tools are installed: - **AVIF** - `.avif` - **HEIF/HEIC** - `.heif`, `.heic` - **GIF** - `.gif` (static frame) - **BMP** - `.bmp` -- **And many more...** + +The installed adapters can support other formats. ## Terminal Protocols -`fetch` automatically detects your terminal and uses the best available image protocol. +`fetch` detects the terminal and selects the first applicable image protocol. ### Kitty Graphics Protocol @@ -84,7 +86,8 @@ Fallback rendering using Unicode block characters (▀▄█). Works everywhere ## External Adapters -When `--image external` is enabled and built-in decoders can't handle an image format, `fetch` tries external tools in this order: +If the built-in decoders do not support an image format, set `--image +external`. `fetch` tries these external tools in the specified order: ### 1. VIPS (`vips`) @@ -139,7 +142,8 @@ image = external ## Image Sizing -Images are automatically resized to fit within 80% of the terminal height while maintaining aspect ratio. This ensures images don't overwhelm the terminal display. +`fetch` resizes images to a maximum of 80% of the terminal height. It keeps the +image aspect ratio. ## Examples @@ -168,30 +172,34 @@ fetch --image off example.com/image.jpg 1. **Check terminal support**: Not all terminals support inline images 2. **Verify format**: Built-in decoders handle JPEG, PNG, TIFF, and WebP by default 3. **Install adapters**: Install VIPS, ImageMagick, or FFmpeg and use `--image external` for more formats -4. **Check terminal size**: Very small terminals may not render properly +4. **Check the terminal size**: Increase the size if the image does not render. ### Poor Quality -1. **Use a native protocol terminal**: Kitty, Ghostty, or iTerm2 provide best quality -2. **Check image dimensions**: Very large images are resized +1. **Use a native-protocol terminal**: Kitty, Ghostty, and iTerm2 give the + highest quality. +2. **Check image dimensions**: `fetch` resizes large images. 3. **Block character fallback**: Quality is limited with Unicode blocks ### Colors Look Wrong -1. **Terminal color support**: Ensure your terminal supports 24-bit color -2. **tmux/screen**: May reduce color depth +1. **Terminal color support**: Make sure that the terminal supports 24-bit + color. +2. **tmux or screen**: Test without the terminal multiplexer because it can + reduce the color depth. 3. **Try default decoding**: `--image auto` ### Image Dimensions Too Large -`fetch` limits images to 8192x8192 pixels maximum to prevent memory issues. Larger images will fail to decode with a "dimensions are too large" error. +`fetch` limits images to 8192 x 8192 pixels to prevent memory problems. It +reports a `dimensions are too large` error for larger images. ## Limitations -- **Animated GIFs**: Only the first frame is displayed -- **Maximum size**: 8192x8192 pixels -- **Memory limit**: Images are loaded into memory for processing -- **Terminal multiplexers**: tmux and screen may interfere with image protocols +- **Animated GIFs**: `fetch` displays only the first frame. +- **Maximum size**: The limit is 8192 x 8192 pixels. +- **Memory limit**: `fetch` loads images into memory for processing. +- **Terminal multiplexers**: tmux and screen can interfere with image protocols. ## See Also diff --git a/docs/output-formatting.md b/docs/output-formatting.md index ac77dca..ac9ea46 100644 --- a/docs/output-formatting.md +++ b/docs/output-formatting.md @@ -141,7 +141,7 @@ available article metadata such as `title`, `byline`, `site_name`, resolved against that URL. If the response is already `text/markdown` or `text/x-markdown`, its Markdown -body is used directly and only `url` is added as frontmatter. +`fetch` uses the body directly and adds only `url` as frontmatter. Article extraction is a body transformation rather than terminal presentation: `--format`, `--color`, and `--pager` only control how the resulting Markdown is @@ -183,7 +183,7 @@ fetch example.com/README.md Features: - Column alignment for readability -- Vertical "record view" for wide data that doesn't fit terminal width +- Vertical "record view" for data that does not fit the terminal width ```sh fetch example.com/data.csv @@ -242,7 +242,7 @@ Without schema (generic parsing): 3: "john@example.com" ``` -With schema (via `--proto-file` or `--proto-desc`): +With a schema (with `--proto-file` or `--proto-desc`): ```json { @@ -262,7 +262,7 @@ Features: - Streaming output as events arrive - SSE-shaped `event:` and `data:` output -- JSON `data:` payloads are formatted and syntax-highlighted +- `fetch` formats and highlights JSON `data:` payloads - Request timeouts still apply to long-running event streams ```sh @@ -279,10 +279,12 @@ event: message data: { "text": "Hi there!", "user": "jane" } ``` -When color is enabled, `event` and `data` labels are highlighted, and JSON values -inside `data:` use the same syntax highlighting as JSON responses. In automatic -compression mode, compressed SSE responses are retried without `Accept-Encoding` -so proxies and servers are less likely to buffer events before delivery. +When color is enabled, `fetch` highlights `event` and `data` labels. It applies +the JSON theme to JSON values inside `data:`. In automatic compression mode, +`fetch` retries compressed SSE responses to `GET` and `HEAD` requests without +`Accept-Encoding`. For other methods, it keeps the compressed response and gives +a warning. For immediate SSE streaming with another method, use +`--compress off`. ### NDJSON / JSON Lines @@ -309,7 +311,8 @@ Output: **Content-Type**: `image/*` -Images are rendered directly in the terminal. See [Image Rendering](image-rendering.md) for details. +`fetch` renders images directly in the terminal. See [Image +Rendering](image-rendering.md) for details. ## Output to File @@ -321,9 +324,9 @@ Write response body to a file: fetch -o response.json example.com/api/data ``` -Formatting is disabled when writing to a file, but compression decoding is still -enabled by default. If the response uses `Content-Encoding` for a `.gz`, `.br`, -or `.zst` asset, use `--compress off` for byte-for-byte downloads. +When writing to a file, `fetch` disables formatting. By default, it continues to +decode compression. If the response uses `Content-Encoding` for a `.gz`, `.br`, +or `.zst` asset, use `--compress off` for a byte-for-byte download. ### `-o -` (Stdout) @@ -362,7 +365,9 @@ fetch -o output.json --clobber example.com/data ## Pager -By default, when stdout is a terminal, `fetch` pipes response body output through a pager for easier navigation. Image responses bypass the pager so native terminal image protocols are interpreted by the terminal. +By default, `fetch` sends response bodies to a pager when stdout is a terminal. +Image responses bypass the pager. As a result, the terminal can interpret its native +image protocols. ### Pager Mode @@ -374,7 +379,7 @@ fetch --pager off example.com/large-response ### Pager Environment -When paging is enabled, fetch uses `$PAGER` if it is set. Set `NO_PAGER` to +When paging is enabled, `fetch` uses `$PAGER` if it is set. Set `NO_PAGER` to disable the default `auto` pager. If `$PAGER` is unset, fetch falls back to `less -FIRX`. When `$LESS` is set, fetch runs `less` without adding its default flags so your `LESS` options apply. `$PAGER` is split with POSIX shell-style @@ -386,7 +391,7 @@ The fallback `less -FIRX` flags are: - `-F` - Quit if output fits on screen - `-I` - Case-insensitive search - `-R` - Handle ANSI colors -- `-X` - Don't clear screen on exit +- `-X` - Do not clear the screen on exit ## Binary Detection diff --git a/docs/request-bodies.md b/docs/request-bodies.md index 1a2e97b..fa7ad1d 100644 --- a/docs/request-bodies.md +++ b/docs/request-bodies.md @@ -1,10 +1,11 @@ # Request Bodies -`fetch` provides multiple options for sending request bodies with different content types. +`fetch` provides options to send request bodies with different content types. ## Overview -Payload source options are **mutually exclusive** - you can only use one per request: +Payload source options are **mutually exclusive**. Use only one source option in +each request: | Option | Content-Type | Use Case | | ----------------- | ----------------------------------- | ---------------------- | @@ -20,7 +21,8 @@ send a body with another method, such as `PUT`. ## Raw Data -The `-d` or `--data` flag sends raw request body data. Content-Type is auto-detected when reading from files. +The `-d` or `--data` option sends raw request body data. When it reads a file, +`fetch` detects the Content-Type. ### Inline Data @@ -44,8 +46,8 @@ cat data.json | fetch -d @- example.com/api ### Content-Type Detection -When using `@filename`, the Content-Type is detected from the file extension. -Multipart file parts use the same policy. Some examples are: +With `@filename`, `fetch` detects the Content-Type from the file extension. +Multipart file parts use the same policy. The table shows examples: | Extension | Content-Type | | ---------------- | -------------------------- | @@ -148,7 +150,7 @@ fetch -f username=john -f password=secret example.com/login ### With Special Characters -Values are automatically URL-encoded: +`fetch` automatically URL-encodes the values: ```sh fetch -f "message=Hello World!" -f "email=user@example.com" example.com/contact @@ -168,7 +170,8 @@ username=john&password=secret ## Multipart Forms -The `-F` or `--multipart` flag sends multipart form data, typically used for file uploads. +The `-F` or `--multipart` option sends multipart form data. Use this option for +file uploads. ### Text Fields @@ -185,7 +188,8 @@ fetch -F file=@document.pdf example.com/upload fetch -F avatar=@photo.jpg -F name=John example.com/profile ``` -When uploading a file by path, only the file's base name is sent in the multipart `filename` parameter. +When you upload a file by path, `fetch` sends only the base name in the +multipart `filename` parameter. ### Multiple Files @@ -206,7 +210,7 @@ fetch \ ### Home Directory Expansion -The `~` is expanded to your home directory: +`fetch` expands `~` to your home directory: ```sh fetch -F config=@~/config.json example.com/settings @@ -233,7 +237,7 @@ fetch -j '{"name": "template"}' --edit example.com/api ### Editor Selection -The editor is selected in this order: +`fetch` selects the editor in this order: 1. `VISUAL` environment variable 2. `EDITOR` environment variable @@ -272,9 +276,9 @@ fetch -d @~/Documents/data.txt -m PUT example.com ## Method Inference -When a request body flag is provided without `--method`, `fetch` uses `POST`. -An explicit method always wins, so use `-m PUT`, `-m PATCH`, or even `-m GET` -when a body must be sent with a different method. +If you do not specify `--method`, a request-body option sets the method to +`POST`. An explicit method takes precedence. Use `-m PUT`, `-m PATCH`, or +`-m GET` to send the body with a different method. ```sh # Inferred POST @@ -286,7 +290,7 @@ fetch -m PUT -j '{"data": true}' example.com ## Large Files -For large file uploads, consider: +For large file uploads, use these settings: 1. **Streaming**: `fetch` streams file content rather than loading it all into memory 2. **Timeout**: Set appropriate timeouts with `--timeout` diff --git a/docs/troubleshooting.md b/docs/troubleshooting.md index 48c1cd8..3933367 100644 --- a/docs/troubleshooting.md +++ b/docs/troubleshooting.md @@ -16,7 +16,7 @@ This guide helps diagnose and fix common issues with `fetch`. | 130 | Interrupted by Ctrl-C/SIGINT | Unlike curl's default behavior, HTTP 4xx/5xx and other non-2xx/3xx responses -exit nonzero; use `--ignore-status` to ignore HTTP status when choosing the +exit nonzero. Use `--ignore-status` to ignore HTTP status when choosing the exit code. Interrupted requests exit 130. gRPC status errors always exit 1. ### Ignore HTTP Status @@ -259,7 +259,7 @@ fetch --grpc --proto-file service.proto \ ### Image Rendering Not Working -**Symptom**: Images show as raw bytes or don't display +**Symptom**: Images appear as raw bytes or do not display **Solutions**: diff --git a/docs/updates.md b/docs/updates.md index 031ee77..3ca7c71 100644 --- a/docs/updates.md +++ b/docs/updates.md @@ -1,8 +1,8 @@ # Updates -`fetch` can update its own binary from the project's GitHub releases. Use -`fetch --update` for an explicit update check, or set `auto-update` in the -configuration file to run update checks in the background. +`fetch` updates its binary from the project GitHub releases. Use +`fetch --update` for an update check. To run update checks in the background, +set `auto-update` in the configuration file. ## Manual Updates @@ -64,9 +64,9 @@ Before replacing the executable, `fetch` downloads the matching downloaded artifact as it streams, and compares the two digests. A mismatch aborts the update before installation. -The updater also bounds the release metadata, checksum file, artifact download, -archive entry count, and unpacked data size, and refuses archive paths that -would escape the temporary unpack directory. +The updater limits the size of the release metadata, checksum file, artifact, +and unpacked data. It also limits the number of archive entries. It rejects an +archive path that is outside the temporary unpack directory. ## Permissions @@ -103,8 +103,8 @@ auto-update = false values such as `30m`, `1.5h`, `4h`, and `1d`. `false`, `off`, `no`, `never`, and `0` disable automatic updates. -Automatic updates run after configuration has been loaded and validated, and -only for normal request/inspection commands. Metadata commands such as +Automatic updates run after `fetch` loads and validates the configuration. They +run only for normal request and inspection commands. Metadata commands such as `fetch --help`, `fetch --version`, and `fetch --buildinfo` do not start background updates. @@ -114,10 +114,10 @@ When an automatic update is due, `fetch` starts a detached child process with: --update --timeout=300 --silent ``` -The parent command continues without waiting, and the child process has stdin, -stdout, and stderr detached. The explicit config path from `--config` is passed -to the child; otherwise the child uses normal config discovery. Background -update failures are not reported by the parent command. +The parent command continues without waiting. The child process has detached +stdin, stdout, and stderr. If you specify `--config`, the child uses that +configuration path. Otherwise, the child uses normal configuration discovery. +The parent command does not report background update failures. ## Cache and Lock Files @@ -140,9 +140,10 @@ Files in this directory include: Manual and automatic update attempts both refresh `metadata.json`, including `fetch --update --dry-run`. -Explicit `fetch --update` waits for the update lock, up to the shorter of the -request timeout and 30 seconds. Background auto-update checks use a nonblocking -lock attempt; if another update is running, the background check is skipped. +Explicit `fetch --update` waits for the update lock. The wait limit is the +shorter of the request timeout and 30 seconds. Background update checks do not +wait for the lock. If another update is in progress, `fetch` skips the +background check. ## Proxy and Timeout Behavior diff --git a/docs/websocket.md b/docs/websocket.md index 556cfcc..0cc0be5 100644 --- a/docs/websocket.md +++ b/docs/websocket.md @@ -32,16 +32,16 @@ fetch ws://api.example.com/upload -d @payload.bin --ws-message-mode binary ### Piped Input -Pipe lines from stdin — each line is sent as a separate text message, including -empty lines: +Pipe lines from stdin. `fetch` sends each line as a separate text message. It +also sends empty lines: ```sh echo "hello" | fetch ws://echo.websocket.events printf "msg1\nmsg2\n" | fetch ws://echo.websocket.events ``` -`fetch` connects before reading piped input, streams each line as it arrives, and -continues printing server messages after stdin reaches EOF until the server +`fetch` connects before it reads piped input. It streams each line as the line +arrives. After stdin reaches EOF, it prints server messages until the server closes the connection. With `--ws-message-mode auto`, piped input is still line-delimited, but a line @@ -50,10 +50,11 @@ binary`, piped input is streamed as raw byte chunks and newline bytes are preserved. Text and auto stdin modes cap each line at 16 MiB before a newline. Use -`--ws-message-mode binary` for larger messages or raw byte streams that should -not be line-delimited. +`--ws-message-mode binary` for larger messages or raw byte streams without line +delimiters. -When stdin/stdout/stderr are terminals, `fetch` opens an interactive prompt. Type a message and press Enter to send it. Use Ctrl+C or Ctrl+D to exit. +If stdin, stdout, and stderr are terminals, `fetch` opens an interactive prompt. +Type a message and press Enter to send it. Press Ctrl+C or Ctrl+D to exit. Control this behavior with `--ws-interactive`: @@ -70,8 +71,11 @@ fetch ws://api.example.com/stream --ws-interactive off ## Output -- **Text messages**: Written to stdout. JSON messages are automatically formatted when connected to a terminal. -- **Binary messages**: Written as raw bytes to stdout when stdout is redirected or piped. When stdout is a terminal, binary-looking payloads are guarded with a warning instead of being printed. +- **Text messages**: `fetch` writes text messages to stdout. On a terminal, it + automatically formats JSON messages. +- **Binary messages**: `fetch` writes raw bytes if stdout is redirected or + piped. On a terminal, it gives a warning and does not print binary-looking + data. - **Formatting**: Use `--format on` to force JSON formatting, or `--format off` to disable it. Incoming server frames and assembled messages are capped at 16 MiB. Larger @@ -99,7 +103,13 @@ fetch -vv ws://echo.websocket.events -d "hello" ## Authentication -Header-based authentication options work with WebSocket connections; headers are sent during the HTTP upgrade handshake. URL credentials are converted to a Basic `Authorization` header and stripped from the handshake request, matching normal HTTP requests. Digest authentication (`--digest`) is not supported for WebSocket requests because it requires a challenge/response retry flow before the upgrade completes. +Header-based authentication options work with WebSocket connections. `fetch` +sends the headers during the HTTP upgrade handshake. It converts URL +credentials to a Basic `Authorization` header and removes them from the +handshake URL. + +WebSocket requests do not support Digest authentication (`--digest`). Digest +authentication requires a challenge and a retry before the upgrade completes. ```sh fetch --bearer mytoken ws://api.example.com/ws @@ -110,7 +120,7 @@ fetch -H "Authorization: Bearer mytoken" ws://api.example.com/ws ## Subprotocols -Specify WebSocket subprotocols via the `Sec-WebSocket-Protocol` header: +Specify WebSocket subprotocols with the `Sec-WebSocket-Protocol` header: ```sh fetch -H "Sec-WebSocket-Protocol: graphql-ws" wss://api.example.com/graphql @@ -119,8 +129,8 @@ fetch -H "Sec-WebSocket-Protocol: graphql-ws" wss://api.example.com/graphql ## Network Options WebSocket connections honor `--dns-server` for direct TCP connections and for -local target resolution through plain `socks5://` proxies. Use `socks5h://` when -the SOCKS proxy should resolve the target hostname remotely. +local target resolution through plain `socks5://` proxies. Use `socks5h://` to +make the SOCKS proxy resolve the target hostname. ## Timeout @@ -130,7 +140,10 @@ The `--timeout` flag applies to the WebSocket handshake only. The connection sta fetch --timeout 5 ws://api.example.com/ws ``` -Use `--connect-timeout` to bound WebSocket connection setup phases such as custom DNS resolution, TCP connect, proxy CONNECT or SOCKS negotiation, and TLS handshakes. When both timeout flags are set, the connect timeout is capped by the remaining `--timeout` budget: +Use `--connect-timeout` to limit WebSocket connection setup. The limit applies +to custom DNS resolution, the TCP connection, proxy CONNECT or SOCKS +negotiation, and TLS handshakes. If both timeout flags are set, the remaining +`--timeout` value limits the connect timeout: ```sh fetch --connect-timeout 2 --timeout 10 wss://api.example.com/ws