From 1c42f41569b77516e62d6c84a07da79747ef1367 Mon Sep 17 00:00:00 2001 From: Ryan Fowler Date: Tue, 27 Jan 2026 20:35:38 -0800 Subject: [PATCH] Improve documentation --- README.md | 131 +---- docs/USAGE.md | 701 --------------------------- docs/advanced-features.md | 414 ++++++++++++++++ docs/authentication.md | 247 ++++++++++ docs/cli-reference.md | 477 ++++++++++++++++++ docs/{CONFIG.md => configuration.md} | 11 +- docs/getting-started.md | 141 ++++++ docs/grpc.md | 366 ++++++++++++++ docs/image-rendering.md | 206 ++++++++ docs/output-formatting.md | 368 ++++++++++++++ docs/request-bodies.md | 333 +++++++++++++ docs/troubleshooting.md | 384 +++++++++++++++ 12 files changed, 2971 insertions(+), 808 deletions(-) delete mode 100644 docs/USAGE.md create mode 100644 docs/advanced-features.md create mode 100644 docs/authentication.md create mode 100644 docs/cli-reference.md rename docs/{CONFIG.md => configuration.md} (97%) create mode 100644 docs/getting-started.md create mode 100644 docs/grpc.md create mode 100644 docs/image-rendering.md create mode 100644 docs/output-formatting.md create mode 100644 docs/request-bodies.md create mode 100644 docs/troubleshooting.md diff --git a/README.md b/README.md index ee849fd..00a41c5 100644 --- a/README.md +++ b/README.md @@ -1,124 +1,45 @@ # fetch -`fetch` is a modern, high-level HTTP(S) client for the command line. +A modern, high-level HTTP(S) client for the command line. ![Example of fetch with an image and JSON responses](./assets/example.jpg) -### Features include: +## Features -- **Response formatting**: automatically formats and colors output (json, html, xml, css, csv, msgpack, protobuf, etc.) -- **Image rendering**: render images directly in your terminal -- **Compression**: automatic gzip and zstd response body decompression -- **Authentication**: support for Basic Auth, Bearer Token, and AWS Signature V4 -- **Form body**: send multipart or urlencoded form bodies -- **gRPC support**: make gRPC calls with automatic JSON-to-protobuf conversion -- **Editor integration**: use an editor to modify the request body -- **Configuration**: global and per-host configuration -- _and more!_ +- **Response formatting** - Automatic formatting and syntax highlighting for JSON, XML, HTML, CSS, CSV, MessagePack, Protocol Buffers, and more +- **Image rendering** - Display images directly in your terminal +- **gRPC support** - Make gRPC calls with automatic JSON-to-protobuf conversion +- **Authentication** - Built-in support for Basic Auth, Bearer Token, AWS Signature V4, and mTLS +- **Compression** - Automatic gzip and zstd response body decompression +- **Configuration** - Global and per-host configuration file support ---- +## Quick Start -## Installation - -You can install `fetch` using an installation script, by compiling from source, -or from pre-built binaries. - -### Installation Script - -For macOS or Linux, download and run the [install.sh](./install.sh) script: +#### Install ```sh +# Install fetch from shell script curl -fsSL https://raw.githubusercontent.com/ryanfowler/fetch/main/install.sh | bash -``` - -### Building from Source -Ensure you have Go installed, then run: - -```sh +# Or install fetch with Go go install github.com/ryanfowler/fetch@latest -``` - -### Pre-built Binaries - -Visit the [GitHub releases page](https://github.com/ryanfowler/fetch/releases) -to download the binary for your operating system. -### Updating - -Once installed, you can update the fetch binary in-place by running: - -```sh -fetch --update -``` - -Or you can let the application auto-update by including the following setting in -your [configuration file](#Configuration): - -```ini -auto-update = true +# Make a request +fetch httpbin.org/json ``` ---- - -## Usage - -To make a GET request to a URL and print the status code to stderr and the response body to stdout: - -```sh -fetch example.com -``` - -
HTTP/1.1 200 OK
-
-{
-  "name": "example",
-  "value": 42
-}
-
- -For complete usage documentation including all available options and advanced features, see [USAGE.md](docs/USAGE.md). - ---- - -## Configuration - -`fetch` can be configured using a file with an ini-like format. Configuration files support both global settings and host-specific configurations. - -### File Locations - -`fetch` searches for configuration files in the following order: - -- the file location specified with the `-c` or `--config` flag -- on Windows at `%AppData%\fetch\config` -- on Unix-like systems at `$XDG_CONFIG_HOME/fetch/config` or `$HOME/.config/fetch/config` - -### Configuration Precedence - -Settings are applied in the following order of precedence: - -- CLI flags (highest priority) -- domain-specific configuration -- global configuration -- default values (lowest priority) - -### Basic Example - -```ini -# Global settings -color = on -format = on -timeout = 30 - -# Domain-specific settings -[api.example.com] -header = X-API-Key: your-api-key -timeout = 10 -``` - -For complete configuration documentation including all available options, file format details, and advanced examples, see [CONFIG.md](docs/CONFIG.md). - ---- +## Documentation + +- **[Getting Started](docs/getting-started.md)** - Installation, first steps, and basic concepts +- **[CLI Reference](docs/cli-reference.md)** - Complete reference for all command-line options +- **[Configuration](docs/configuration.md)** - Configuration file format and options +- **[Authentication](docs/authentication.md)** - Basic, Bearer, AWS SigV4, and mTLS +- **[Request Bodies](docs/request-bodies.md)** - JSON, XML, forms, multipart, and file uploads +- **[Output Formatting](docs/output-formatting.md)** - Supported content types and formatting options +- **[Image Rendering](docs/image-rendering.md)** - Terminal image protocols and formats +- **[gRPC](docs/grpc.md)** - Making gRPC requests with Protocol Buffers +- **[Advanced Features](docs/advanced-features.md)** - DNS, proxies, TLS, HTTP versions, and more +- **[Troubleshooting](docs/troubleshooting.md)** - Common issues, debugging, and exit codes ## License diff --git a/docs/USAGE.md b/docs/USAGE.md deleted file mode 100644 index fbbd1e8..0000000 --- a/docs/USAGE.md +++ /dev/null @@ -1,701 +0,0 @@ -# Usage Guide - -This guide provides comprehensive documentation for using `fetch`, a modern HTTP client for the command line. - -## Basic Usage - -To make a GET request to a URL: - -```sh -fetch example.com -``` - -### URL Schemes - -When no scheme is provided, `fetch` defaults to HTTPS: - -```sh -fetch example.com # Uses https://example.com -fetch 192.168.1.1:8080 # Uses https://192.168.1.1:8080 -``` - -Loopback addresses default to HTTP for local development convenience: - -```sh -fetch localhost:3000 # Uses http://localhost:3000 -fetch 127.0.0.1:8080 # Uses http://127.0.0.1:8080 -``` - -You can always specify the scheme explicitly: - -```sh -fetch http://example.com # Force HTTP -fetch https://localhost # Force HTTPS for localhost -``` - -## Authentication Options - -### AWS Signature V4 - -**Flag**: `--aws-sigv4 REGION/SERVICE` - -Sign the request using [AWS Signature V4](https://docs.aws.amazon.com/AmazonS3/latest/API/sig-v4-authenticating-requests.html). - -Requires: `AWS_ACCESS_KEY_ID` and `AWS_SECRET_ACCESS_KEY` environment variables. - -```sh -fetch --aws-sigv4 us-east-1/s3 example.com -``` - -### Basic Authentication - -**Flag**: `--basic USER:PASS` - -Enable HTTP Basic Authentication. - -```sh -fetch --basic username:password example.com -``` - -### Bearer Token - -**Flag**: `--bearer TOKEN` - -Enable HTTP Bearer Token Authentication. - -```sh -fetch --bearer mysecrettoken example.com -``` - -## Request Body Options - -Body options generally accept values in the format: `[@]VALUE` - -- A value without `@` prefix is sent directly -- A value prefixed with `@` sends a file at the given path -- A value of `@-` sends data read from stdin - -### Raw Request Body - -**Flag**: `-d, --data [@]VALUE` - -Send a raw request body. - -```sh -fetch -d 'Hello, world!' -m PUT example.com -fetch -d @data.txt -m PUT example.com -fetch -d @- -m PUT example.com < data.txt -``` - -### JSON Request Body - -**Flag**: `-j, --json [@]VALUE` - -Send a JSON request body. Automatically sets the `Content-Type` header to `application/json`. - -```sh -fetch -j '{"hello":"world"}' -m PUT example.com -fetch -j @data.json -m PUT example.com -``` - -### XML Request Body - -**Flag**: `-x, --xml [@]VALUE` - -Send an XML request body. Automatically sets the `Content-Type` header to `application/xml`. - -```sh -fetch -x 'value' -m PUT example.com -fetch -x @data.xml -m PUT example.com -``` - -### URL-Encoded Form Body - -**Flag**: `-f, --form KEY=VALUE` - -Send a URL-encoded form body. Can be used multiple times to add multiple fields. - -```sh -fetch -f hello=world -f name=value -m POST example.com -``` - -### Multipart Form Body - -**Flag**: `-F, --multipart NAME=[@]VALUE` - -Send a multipart form body. Can be used multiple times to add multiple fields. - -```sh -fetch -F hello=world -F data=@/path/to/file.txt -m POST example.com -fetch -F "file=@image.png" -F "description=My image" -m POST example.com -``` - -### Editor Integration - -**Flag**: `-e, --edit` - -Edit the request body with an editor before sending. Uses `VISUAL` or `EDITOR` environment variables, or falls back to well-known editors. - -```sh -fetch --edit -m PUT example.com -``` - -## General Request Options - -### HTTP Method - -**Flag**: `-m, --method METHOD` (alias: `-X`) - -Specify the HTTP method to use. Default is GET. - -```sh -fetch -m POST example.com -fetch -X DELETE example.com -``` - -### Custom Headers - -**Flag**: `-H, --header NAME:VALUE` - -Set custom headers on the request. Can be used multiple times. - -```sh -fetch -H "x-custom-header: value" -H "Authorization: Bearer token" example.com -``` - -### Query Parameters - -**Flag**: `-q, --query KEY=VALUE` - -Append query parameters to the URL. Can be used multiple times. - -```sh -fetch -q hello=world -q page=2 example.com -``` - -### Range Requests - -**Flag**: `-r, --range RANGE` - -Set the [Range](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Range) request header. Can be used multiple times for multiple ranges. - -```sh -fetch -r 0-1023 example.com -fetch -r 0-499 -r 1000-1499 example.com -``` - -### Redirects - -**Flag**: `--redirects NUM` - -Set the maximum allowed automatic redirects. Use `0` to disable redirects. - -```sh -fetch --redirects 0 example.com -fetch --redirects 10 example.com -``` - -### Timeout - -**Flag**: `-t, --timeout SECONDS` - -Set a timeout for the entire request in seconds. Accepts decimal values. - -```sh -fetch --timeout 30 example.com -fetch --timeout 2.5 example.com -``` - -### Custom DNS Server - -**Flag**: `--dns-server IP[:PORT]|URL` - -Use a custom DNS server. Can be either: - -- IP address with optional port for UDP DNS -- HTTPS URL for DNS-over-HTTPS - -```sh -fetch --dns-server 8.8.8.8 example.com -fetch --dns-server 1.1.1.1:53 example.com -fetch --dns-server https://1.1.1.1/dns-query example.com -``` - -### Proxy - -**Flag**: `--proxy PROXY` - -Route the request through the specified proxy. - -```sh -fetch --proxy http://localhost:8080 example.com -fetch --proxy socks5://localhost:1080 example.com -``` - -### Unix Socket - -**Flag**: `--unix PATH` - -Make the request over a Unix domain socket. Only available on Unix-like systems. - -```sh -fetch --unix /var/run/docker.sock http://unix/containers/json -fetch --unix /var/run/service.sock http://unix/api/status -``` - -### TLS Options - -**Flag**: `--insecure` - -Allow for invalid TLS certificates from the server. - -```sh -fetch --insecure https://self-signed.example.com -``` - -**Flag**: `--tls VERSION` - -Specify the minimum TLS version to use. Must be one of: `1.0`, `1.1`, `1.2`, `1.3`. - -```sh -fetch --tls 1.3 example.com -``` - -### HTTP Version - -**Flag**: `--http VERSION` - -Specify the exact HTTP version to use. Must be `1`, `2`, or `3`. -By default, HTTP/2 is preferred but will fallback to using HTTP/1.1. - -```sh -fetch --http 1 example.com -``` - -### Compression - -**Flag**: `--no-encode` - -Disable automatic gzip and zstd request/response compression. - -```sh -fetch --no-encode example.com -``` - -### Custom CA Certificate - -**Flag**: `--ca-cert` - -Use a custom CA certificate. - -```sh -fetch --ca-cert ca-cert.pem example.com -``` - -## Output Options - -### Output to File - -**Flag**: `-o, --output PATH` - -Write the response body to the specified file. Truncates existing files. - -```sh -fetch -o response.json example.com/api/data -fetch -o ~/downloads/file.zip example.com/file.zip -``` - -### Output to Current Directory - -**Flag**: `-O, --output-current-dir` - -Write the response body to the current directory using the filename from the URL. - -```sh -fetch -O example.com/path/to/file.txt -# Creates ./file.txt -``` - -### Colored Output - -**Flag**: `--color OPTION` (alias: `--colour`) - -Set whether output should be colored. Options: `auto`, `off`, `on`. - -```sh -fetch --color off example.com -fetch --colour on example.com -``` - -### Formatted Output - -**Flag**: `--format OPTION` - -Set whether output should be formatted. Options: `auto`, `off`, `on`. - -Supported formats for automatic formatting and syntax highlighting: - -- JSON (`application/json`) -- HTML (`text/html`) -- XML (`application/xml`, `text/xml`) -- CSS (`text/css`) -- CSV (`text/csv`) -- MessagePack (`application/msgpack`) -- NDJSON/JSONLines (`application/x-ndjson`) -- Protobuf (`application/x-protobuf`, `application/protobuf`) -- Server-Sent Events (`text/event-stream`) - -CSV output is automatically column-aligned. When output is too wide for the terminal, it switches to a vertical "record view" format where each row is displayed with field names as labels. - -```sh -fetch --format off example.com -fetch --format on example.com -``` - -### Image Rendering - -**Flag**: `--image OPTION` - -Set how images should be rendered in the terminal. Options: `auto`, `native`, `off`. - -- `auto`: Try optimal protocol, fallback to external tools -- `native`: Use only built-in decoders (jpeg, png, tiff, webp) -- `off`: Disable image rendering - -```sh -fetch --image native example.com/image.png -fetch --image off example.com/image.jpg -``` - -### Pager Control - -**Flag**: `--no-pager` - -Disable piping output to a pager like `less`. - -```sh -fetch --no-pager example.com -``` - -## Verbosity Options - -### Verbose Output - -**Flag**: `-v, --verbose` - -Increase verbosity of output to stderr. Can be used multiple times: - -- `-v`: Show response headers -- `-vv`: Show request and response headers -- `-vvv`: Show DNS and TLS details - -```sh -fetch -v example.com -fetch -vv example.com -fetch -vvv example.com -``` - -### Silent Mode - -**Flag**: `-s, --silent` - -Suppress verbose output. Only warnings and errors are written to stderr. - -```sh -fetch -s example.com -``` - -### Ignore HTTP Status - -**Flag**: `--ignore-status` - -Don't determine exit code from HTTP status. Always exit with code 0 instead of using 4xx/5xx status codes. - -```sh -fetch --ignore-status example.com -``` - -## Configuration Options - -### Config File - -**Flag**: `-c, --config PATH` - -Specify a custom configuration file path. - -```sh -fetch --config ~/.config/fetch/custom.conf example.com -``` - -## Utility Options - -### Help - -**Flag**: `-h, --help` - -Print help information. - -```sh -fetch --help -``` - -### Version Information - -**Flag**: `-V, --version` - -Print version information. - -```sh -fetch --version -``` - -### Build Information - -**Flag**: `--buildinfo` - -Print detailed build information including version, commit, and build date. - -```sh -fetch --buildinfo -``` - -### Update - -**Flag**: `--update` - -Update the fetch binary in place. - -```sh -fetch --update -``` - -### Shell Completion - -**Flag**: `--complete SHELL` - -Output shell completion scripts. Supported shells: `fish`, `zsh`. - -```sh -fetch --complete zsh > ~/.zshrc.d/fetch-completion.zsh -fetch --complete fish > ~/.config/fish/completions/fetch.fish -``` - -### Dry Run - -**Flag**: `--dry-run` - -Print request information without actually sending the request. - -```sh -fetch --dry-run -m POST -j '{"test": true}' example.com -``` - -## Value Formats - -### File References - -Many options support file references with the `@` prefix: - -- `@filename` - Read content from file -- `@-` - Read content from stdin -- `@~/path` - Home directory expansion supported - -### Environment Variables - -The following environment variables are recognized: - -- `AWS_ACCESS_KEY_ID` - For AWS Signature V4 authentication -- `AWS_SECRET_ACCESS_KEY` - For AWS Signature V4 authentication -- `VISUAL` or `EDITOR` - For editor integration -- `HTTPS_PROXY`, `HTTP_PROXY`, `NO_PROXY` - For proxy configuration - -### Special Characters - -When using special characters in values, proper shell escaping may be required: - -```sh -# Escape quotes in JSON -fetch -j '{"message": "Hello \"World\""}' example.com - -# Use single quotes to avoid shell interpretation -fetch -H 'Authorization: Bearer token-with-$pecial-chars' example.com -``` - -## gRPC Support - -`fetch` supports making gRPC calls with automatic protocol handling, JSON-to-protobuf conversion, and response formatting. - -### Basic gRPC Request - -**Flag**: `--grpc` - -Enable gRPC mode. This flag: - -- Uses the HTTP/2 protocol -- Sets the method to `POST` -- Adds gRPC headers (`Content-Type: application/grpc+proto`, `TE: trailers`, etc.) -- Applies gRPC framing to the request body -- Handles gRPC framing on the response - -The service and method are specified in the URL path in the format `/package.Service/Method`: - -```sh -fetch https://localhost:50051/mypackage.MyService/MyMethod --grpc --insecure -``` - -### Proto Schema Options - -To enable JSON-to-protobuf conversion for request bodies and rich protobuf formatting for responses, provide a proto schema using one of these options: - -**Flag**: `--proto-file PATH` - -Compile `.proto` file(s) using `protoc`. Requires `protoc` to be installed. Can be specified multiple times or with comma-separated paths. - -```sh -fetch https://localhost:50051/echo.EchoService/Echo \ - --grpc \ - --proto-file service.proto \ - -j '{"message": "hello", "count": 42}' \ - --insecure -``` - -**Flag**: `--proto-desc PATH` - -Use a pre-compiled descriptor set file. This is useful when `protoc` isn't available at runtime or to avoid recompilation. - -Generate a descriptor set with: - -```sh -protoc --descriptor_set_out=service.pb --include_imports service.proto -``` - -Then use it: - -```sh -fetch https://localhost:50051/echo.EchoService/Echo \ - --grpc \ - --proto-desc service.pb \ - -j '{"message": "hello", "count": 42}' \ - --insecure -``` - -**Flag**: `--proto-import PATH` - -Add import paths for proto compilation. Use with `--proto-file` when your proto files have imports. - -```sh -fetch https://localhost:50051/mypackage.MyService/MyMethod \ - --grpc \ - --proto-file service.proto \ - --proto-import ./proto \ - --proto-import /usr/local/include \ - -j '{"field": "value"}' \ - --insecure -``` - -### How It Works - -When `--grpc` is used with a proto schema (`--proto-file` or `--proto-desc`): - -1. The service and method are extracted from the URL path -2. The method's input/output message types are looked up in the schema -3. JSON request bodies are automatically converted to protobuf -4. Protobuf responses are formatted with field names from the schema - -Without a proto schema, `fetch` still handles gRPC framing but: - -- Request bodies must be raw protobuf (not JSON) -- Responses are formatted using generic protobuf parsing (field numbers instead of names) - -### Examples - -**Simple gRPC call with JSON body:** - -```sh -fetch https://api.example.com/package.Service/Method \ - --grpc \ - --proto-file service.proto \ - -j '{"name": "test", "value": 123}' -``` - -**gRPC call with verbose output:** - -```sh -fetch https://api.example.com/package.Service/Method \ - --grpc \ - --proto-file service.proto \ - -j '{"request": "data"}' \ - -vv -``` - -**gRPC call to local server with self-signed certificate:** - -```sh -fetch https://localhost:50051/echo.EchoService/Echo \ - --grpc \ - --proto-desc echo.pb \ - -j '{"message": "hello"}' \ - --insecure -``` - -**Dry run to inspect the request:** - -```sh -fetch https://api.example.com/package.Service/Method \ - --grpc \ - --proto-file service.proto \ - -j '{"field": "value"}' \ - --dry-run -``` - -**Use an editor to modify the request body:** - -```sh -fetch https://api.example.com/package.Service/Method \ - --grpc \ - --proto-file service.proto \ - -j '{"field": "value"}' \ - --edit -``` - -## Advanced Usage - -### Combining Options - -Options can be combined for complex requests: - -```sh -fetch \ - --method POST \ - --header "Content-Type: application/json" \ - --header "Authorization: Bearer token" \ - --json '{"user": "john", "action": "login"}' \ - --query "version=2" \ - --timeout 30 \ - --verbose \ - example.com/api/auth -``` - -### Using with Pipes - -```sh -# Send stdin as request body -echo '{"hello": "world"}' | fetch -j @- -m POST example.com - -# Save response to file and view -fetch example.com/large-response.json | jq . > formatted.json - -# Chain requests -fetch example.com/auth | jq -r '.token' | fetch --bearer @- example.com/protected -``` - -### Configuration Precedence - -Options are applied in the following order (highest to lowest precedence): - -1. Command line flags -2. Domain-specific configuration -3. Global configuration -4. Default values - -This allows for flexible configuration where you can set defaults globally and override them per-domain or per-command. diff --git a/docs/advanced-features.md b/docs/advanced-features.md new file mode 100644 index 0000000..2fbfe32 --- /dev/null +++ b/docs/advanced-features.md @@ -0,0 +1,414 @@ +# Advanced Features + +This guide covers advanced networking, protocol, and TLS options in `fetch`. + +## Custom DNS Resolution + +### `--dns-server` + +Use a custom DNS server instead of the system resolver. + +### UDP DNS + +Specify an IP address with optional port: + +```sh +# Google DNS +fetch --dns-server 8.8.8.8 example.com + +# Cloudflare DNS with custom port +fetch --dns-server 1.1.1.1:53 example.com + +# IPv6 DNS server +fetch --dns-server "[2001:4860:4860::8888]:53" example.com +``` + +### DNS-over-HTTPS (DoH) + +Use HTTPS URL for encrypted DNS queries: + +```sh +# Cloudflare DoH +fetch --dns-server https://1.1.1.1/dns-query example.com + +# Google DoH +fetch --dns-server https://dns.google/dns-query example.com + +# Quad9 DoH +fetch --dns-server https://dns.quad9.net/dns-query example.com +``` + +### Configuration File + +```ini +# Use Cloudflare DNS globally +dns-server = 1.1.1.1 + +# Use DoH for specific hosts +[secure.example.com] +dns-server = https://1.1.1.1/dns-query +``` + +## Proxy Configuration + +### `--proxy` + +Route requests through a proxy server. + +### HTTP Proxy + +```sh +fetch --proxy http://proxy.example.com:8080 example.com +``` + +### HTTPS Proxy + +```sh +fetch --proxy https://secure-proxy.example.com:8443 example.com +``` + +### SOCKS5 Proxy + +```sh +fetch --proxy socks5://localhost:1080 example.com +``` + +### Authenticated Proxy + +```sh +fetch --proxy http://user:password@proxy.example.com:8080 example.com +``` + +### Environment Variables + +`fetch` respects standard proxy environment variables: + +```sh +export HTTP_PROXY="http://proxy.example.com:8080" +export HTTPS_PROXY="http://proxy.example.com:8080" +export NO_PROXY="localhost,127.0.0.1,.internal.com" + +fetch example.com # Uses proxy from environment +``` + +### Configuration File + +```ini +# Global proxy +proxy = http://proxy.example.com:8080 + +# Host-specific proxy +[internal.example.com] +proxy = socks5://internal-proxy:1080 +``` + +## Unix Domain Sockets + +### `--unix` + +Connect via Unix domain socket instead of TCP. Available on Unix-like systems only. + +### Docker API + +```sh +fetch --unix /var/run/docker.sock http://localhost/containers/json +fetch --unix /var/run/docker.sock http://localhost/images/json +``` + +### Custom Services + +```sh +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. + +## HTTP Versions + +### `--http VERSION` + +Force a specific HTTP version. + +### HTTP/1.1 + +```sh +fetch --http 1 example.com +``` + +- Uses HTTP/1.1 protocol +- Single request per connection +- No header compression +- Useful for debugging or legacy servers + +### HTTP/2 + +```sh +fetch --http 2 example.com +``` + +- Default behavior (HTTP/2 preferred with fallback) +- Multiplexed streams +- Header compression (HPACK) +- Required for gRPC + +### HTTP/3 (QUIC) + +```sh +fetch --http 3 example.com +``` + +- Uses QUIC transport (UDP-based) +- Reduced latency +- Better handling of packet loss +- Not all servers support HTTP/3 + +### Version Detection + +By default, `fetch` negotiates the best available version: + +1. Attempts HTTP/2 via ALPN +2. Falls back to HTTP/1.1 if needed + +## TLS Configuration + +### Minimum TLS Version + +`--tls VERSION` sets the minimum acceptable TLS version: + +```sh +fetch --tls 1.2 example.com # Require TLS 1.2+ +fetch --tls 1.3 example.com # Require TLS 1.3 +``` + +| Value | Protocol | +| ----- | ----------------------------- | +| `1.0` | TLS 1.0 (legacy) | +| `1.1` | TLS 1.1 (deprecated) | +| `1.2` | TLS 1.2 (recommended minimum) | +| `1.3` | TLS 1.3 (most secure) | + +### Insecure Mode + +`--insecure` accepts invalid TLS certificates: + +```sh +fetch --insecure https://self-signed.example.com +``` + +**Warning**: Only use for development/testing. Never in production. + +### Custom CA Certificate + +`--ca-cert` specifies a custom CA certificate: + +```sh +fetch --ca-cert /path/to/ca.crt https://internal.example.com +``` + +Use cases: + +- Internal PKI with private CA +- Development with self-signed certificates +- Corporate environments with SSL inspection + +### Configuration File + +```ini +# Require TLS 1.2 minimum +tls = 1.2 + +# Internal server with private CA +[internal.company.com] +ca-cert = /etc/pki/internal-ca.crt + +# Development server (insecure) +[dev.localhost] +insecure = true +``` + +## Compression + +### `--no-encode` + +Disable automatic compression negotiation: + +```sh +fetch --no-encode example.com +``` + +By default, `fetch`: + +- Sends `Accept-Encoding: gzip, zstd` header +- Automatically decompresses responses + +Disabling is useful when: + +- Testing compression behavior +- Server has compression bugs +- You want to see raw compressed data + +## Range Requests + +### `-r, --range RANGE` + +Request specific byte ranges (partial content): + +```sh +# First 1KB +fetch -r 0-1023 example.com/file.bin + +# Last 500 bytes +fetch -r -500 example.com/file.bin + +# Skip first 1000 bytes +fetch -r 1000- example.com/file.bin +``` + +### Multiple Ranges + +```sh +fetch -r 0-499 -r 1000-1499 example.com/file.bin +``` + +This sets the header: + +``` +Range: bytes=0-499, 1000-1499 +``` + +### Use Cases + +- Resume interrupted downloads +- Download specific portions of large files +- Video seeking +- Parallel downloads + +## Redirect Control + +### `--redirects NUM` + +Set maximum number of automatic redirects: + +```sh +# Disable redirects +fetch --redirects 0 example.com + +# Allow up to 10 redirects +fetch --redirects 10 example.com +``` + +### Verbose Redirect Tracking + +```sh +fetch -v --redirects 5 example.com +``` + +Shows each redirect hop with status codes. + +## Request Timeout + +### `-t, --timeout SECONDS` + +Set a timeout for the entire request: + +```sh +fetch --timeout 30 example.com +fetch --timeout 2.5 example.com # Decimal seconds +``` + +The timeout covers: + +- DNS resolution +- Connection establishment +- TLS handshake +- Request/response transfer + +### Configuration File + +```ini +# Global timeout +timeout = 30 + +# Longer timeout for slow API +[slow-api.example.com] +timeout = 120 +``` + +## Combining Options + +Complex requests often combine multiple advanced options: + +```sh +fetch \ + --dns-server https://1.1.1.1/dns-query \ + --proxy socks5://localhost:9050 \ + --tls 1.3 \ + --timeout 60 \ + --http 2 \ + -v \ + https://example.onion/api +``` + +### Configuration File Example + +```ini +# Global settings +timeout = 30 +tls = 1.2 +dns-server = 8.8.8.8 + +# Internal services +[internal.company.com] +proxy = http://internal-proxy:8080 +ca-cert = /etc/pki/internal-ca.crt +insecure = false + +# Development environment +[localhost] +insecure = true +timeout = 5 + +# High-security API +[secure-api.example.com] +tls = 1.3 +timeout = 60 +``` + +## Debugging Network Issues + +### Verbose Output + +```sh +fetch -v example.com # Response headers +fetch -vv example.com # Request + response headers +fetch -vvv example.com # DNS + TLS details +``` + +### Dry Run + +Preview the request without sending: + +```sh +fetch --dry-run -m POST -j '{"test": true}' example.com +``` + +### Testing Connectivity + +```sh +# Test with specific DNS +fetch --dns-server 8.8.8.8 -v example.com + +# Test with explicit HTTP version +fetch --http 1 -v example.com + +# Test TLS configuration +fetch --tls 1.3 -vvv example.com +``` + +## See Also + +- [CLI Reference](cli-reference.md) - Complete option reference +- [Authentication](authentication.md) - mTLS and other auth methods +- [Configuration](configuration.md) - Configuration file options +- [Troubleshooting](troubleshooting.md) - Network debugging diff --git a/docs/authentication.md b/docs/authentication.md new file mode 100644 index 0000000..a937c7b --- /dev/null +++ b/docs/authentication.md @@ -0,0 +1,247 @@ +# Authentication + +`fetch` supports multiple authentication methods for accessing protected resources. + +## HTTP Basic Authentication + +Basic Authentication sends credentials as a base64-encoded `Authorization` header. + +### Command Line + +```sh +fetch --basic username:password example.com +``` + +### How It Works + +The `--basic` flag sets the `Authorization` header: + +``` +Authorization: Basic base64(username:password) +``` + +## Bearer Token Authentication + +Bearer tokens are commonly used with OAuth 2.0 and JWT-based authentication. + +### Command Line + +```sh +fetch --bearer mytoken123 example.com +``` + +### How It Works + +The `--bearer` flag sets the `Authorization` header: + +``` +Authorization: Bearer mytoken123 +``` + +### Using Environment Variables + +For security, avoid putting tokens directly in commands: + +```sh +fetch --bearer "$API_TOKEN" example.com +``` + +Or read from a file: + +```sh +fetch -H "Authorization: Bearer $(cat ~/.api-token)" example.com +``` + +## AWS Signature V4 + +Sign requests for AWS services using [AWS Signature V4](https://docs.aws.amazon.com/AmazonS3/latest/API/sig-v4-authenticating-requests.html). + +### Prerequisites + +Set the required environment variables: + +```sh +export AWS_ACCESS_KEY_ID="your-access-key" +export AWS_SECRET_ACCESS_KEY="your-secret-key" +``` + +### Command Line + +```sh +fetch --aws-sigv4 REGION/SERVICE url +``` + +### Examples + +```sh +# S3 request +fetch --aws-sigv4 us-east-1/s3 https://my-bucket.s3.amazonaws.com/key + +# API Gateway +fetch --aws-sigv4 us-west-2/execute-api https://abc123.execute-api.us-west-2.amazonaws.com/prod/resource + +# Lambda function URL +fetch --aws-sigv4 eu-west-1/lambda https://xyz.lambda-url.eu-west-1.on.aws/ +``` + +### How It Works + +AWS SigV4 signs the request by: + +1. Creating a canonical request from the HTTP method, path, query string, headers, and body +2. Generating a signing key from your secret key, date, region, and service +3. Computing an HMAC-SHA256 signature +4. Adding the signature to the `Authorization` header + +## Mutual TLS (mTLS) + +mTLS provides two-way authentication where both client and server present certificates. + +### Basic Usage + +```sh +fetch --cert client.crt --key client.key example.com +``` + +### Combined Certificate and Key + +If your PEM file contains both the certificate and private key: + +```sh +fetch --cert client.pem example.com +``` + +### With Custom CA Certificate + +When the server uses a private CA: + +```sh +fetch --cert client.crt --key client.key --ca-cert ca.crt example.com +``` + +### Configuration File + +```ini +# Global mTLS settings +cert = /path/to/client.crt +key = /path/to/client.key + +# Host-specific mTLS +[api.secure.example.com] +cert = /path/to/api-client.crt +key = /path/to/api-client.key +ca-cert = /path/to/api-ca.crt +``` + +### Certificate Formats + +- Certificates and keys must be in PEM format +- Encrypted private keys are not supported +- Combined PEM files should have the certificate before the key + +### Example: Self-Signed Certificates + +Generate test certificates: + +```sh +# Generate CA +openssl genrsa -out ca.key 4096 +openssl req -new -x509 -days 365 -key ca.key -out ca.crt -subj "/CN=Test CA" + +# Generate client certificate +openssl genrsa -out client.key 4096 +openssl req -new -key client.key -out client.csr -subj "/CN=client" +openssl x509 -req -days 365 -in client.csr -CA ca.crt -CAkey ca.key -CAcreateserial -out client.crt +``` + +Use with fetch: + +```sh +fetch --cert client.crt --key client.key --ca-cert ca.crt https://mtls.example.com +``` + +## Custom Headers + +For authentication methods not directly supported, use custom headers: + +```sh +# API Key in header +fetch -H "X-API-Key: your-api-key" example.com + +# Custom token format +fetch -H "X-Auth-Token: custom-token" example.com + +# Multiple auth headers +fetch -H "X-API-Key: key" -H "X-Signature: sig" example.com +``` + +### Configuration File + +```ini +[api.example.com] +header = X-API-Key: your-api-key +header = X-Client-ID: client123 +``` + +## Authentication Precedence + +Authentication options are mutually exclusive. You cannot combine: + +- `--basic` +- `--bearer` +- `--aws-sigv4` + +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 + +### Secure Credential Handling + +```sh +# Using environment variables +export API_TOKEN="$(vault read -field=token secret/api)" +fetch --bearer "$API_TOKEN" example.com + +# Using password manager +fetch --basic "$(pass show api/credentials)" example.com + +# Reading from secure file +fetch --bearer "$(cat /run/secrets/api-token)" example.com +``` + +## Troubleshooting + +### 401 Unauthorized + +- Verify credentials are correct +- Check if the authentication method matches what the server expects +- Ensure tokens haven't expired + +### 403 Forbidden + +- Authentication succeeded but authorization failed +- Check if your credentials have the required permissions + +### 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 + +### 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 +- Verify system clock is accurate (signatures are time-sensitive) + +## See Also + +- [CLI Reference](cli-reference.md) - All authentication flags +- [Configuration](configuration.md) - Setting up authentication in config files +- [Troubleshooting](troubleshooting.md) - Common issues and solutions diff --git a/docs/cli-reference.md b/docs/cli-reference.md new file mode 100644 index 0000000..5dd3775 --- /dev/null +++ b/docs/cli-reference.md @@ -0,0 +1,477 @@ +# CLI Reference + +Complete reference for all `fetch` command-line options. + +## Usage + +``` +fetch [OPTIONS] [URL] +``` + +## URL Handling + +When no scheme is provided, `fetch` defaults to HTTPS. Loopback addresses (`localhost`, `127.0.0.1`) default to HTTP. + +```sh +fetch example.com # https://example.com +fetch localhost:3000 # http://localhost:3000 +fetch http://example.com # Force HTTP +``` + +## HTTP Method + +### `-m, --method METHOD` + +Specify the HTTP method. Default: `GET`. + +**Alias**: `-X` + +```sh +fetch -m POST example.com +fetch -X DELETE example.com/resource/123 +``` + +## Headers and Query Parameters + +### `-H, --header NAME:VALUE` + +Set custom headers. Can be used multiple times. + +```sh +fetch -H "Authorization: Bearer token" example.com +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. + +```sh +fetch -q page=1 -q limit=50 example.com +``` + +## Request Body Options + +Body options are mutually exclusive - only one can be used per request. + +### `-d, --data [@]VALUE` + +Send a raw request body. Content-Type is auto-detected when using file references. + +```sh +fetch -d 'Hello, world!' -m PUT example.com +fetch -d @data.txt -m PUT example.com +fetch -d @- -m PUT example.com < data.txt +``` + +### `-j, --json [@]VALUE` + +Send a JSON request body. Sets `Content-Type: application/json`. + +```sh +fetch -j '{"hello": "world"}' -m POST example.com +fetch -j @data.json -m POST example.com +``` + +### `-x, --xml [@]VALUE` + +Send an XML request body. Sets `Content-Type: application/xml`. + +```sh +fetch -x 'value' -m PUT example.com +fetch -x @data.xml -m PUT example.com +``` + +### `-f, --form KEY=VALUE` + +Send a URL-encoded form body. Can be used multiple times. + +```sh +fetch -f username=john -f password=secret -m POST example.com/login +``` + +### `-F, --multipart NAME=[@]VALUE` + +Send a multipart form body. Use `@` prefix for file uploads. Can be used multiple times. + +```sh +fetch -F hello=world -F file=@document.pdf -m POST example.com/upload +``` + +### `-e, --edit` + +Open an editor to modify the request body before sending. Uses `VISUAL` or `EDITOR` environment variables. + +```sh +fetch --edit -m PUT example.com +``` + +## Authentication + +Authentication options are mutually exclusive. + +### `--basic USER:PASS` + +HTTP Basic Authentication. + +```sh +fetch --basic username:password example.com +``` + +### `--bearer TOKEN` + +HTTP Bearer Token Authentication. + +```sh +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. + +```sh +fetch --aws-sigv4 us-east-1/s3 s3.amazonaws.com/bucket/key +``` + +### `--cert PATH` + +Client certificate file for mTLS. PEM format. + +```sh +fetch --cert client.crt --key client.key example.com +``` + +### `--key PATH` + +Client private key file for mTLS. Required if `--cert` is a certificate-only file. + +```sh +fetch --cert client.crt --key client.key example.com +``` + +## Output Options + +### `-o, --output PATH` + +Write response body to a file. Use `-` for stdout (bypasses binary detection). + +```sh +fetch -o response.json example.com/api/data +fetch -o - example.com/file.bin > output.bin +``` + +### `-O, --remote-name` + +Write response body to current directory using the filename from the URL. + +**Alias**: `--output-current-dir` + +```sh +fetch -O example.com/path/to/file.txt # Creates ./file.txt +``` + +### `-J, --remote-header-name` + +Use filename from `Content-Disposition` header. Requires `-O`. + +```sh +fetch -O -J example.com/download +``` + +### `--clobber` + +Overwrite existing output file (default behavior is to fail if file exists). + +```sh +fetch -o output.json --clobber example.com/data +``` + +## Formatting Options + +### `--format OPTION` + +Control response formatting. Values: `auto`, `on`, `off`. + +```sh +fetch --format off example.com # Disable formatting +fetch --format on example.com # Force formatting +``` + +### `--color OPTION` + +Control colored output. Values: `auto`, `on`, `off`. + +**Alias**: `--colour` + +```sh +fetch --color off example.com +``` + +### `--image OPTION` + +Control image rendering. Values: `auto`, `native`, `off`. + +- `auto` - Try optimal protocol, fallback to external tools +- `native` - Use only built-in decoders (JPEG, PNG, TIFF, WebP) +- `off` - Disable image rendering + +```sh +fetch --image native example.com/image.png +fetch --image off example.com/photo.jpg +``` + +### `--no-pager` + +Disable piping output to a pager (`less`). + +```sh +fetch --no-pager example.com +``` + +## Network Options + +### `-t, --timeout SECONDS` + +Request timeout in seconds. Accepts decimal values. + +```sh +fetch --timeout 30 example.com +fetch --timeout 2.5 example.com +``` + +### `--redirects NUM` + +Maximum automatic redirects. Use `0` to disable. + +```sh +fetch --redirects 0 example.com # Don't follow redirects +fetch --redirects 10 example.com +``` + +### `--dns-server IP[:PORT]|URL` + +Use custom DNS server. Supports UDP DNS and DNS-over-HTTPS. + +```sh +fetch --dns-server 8.8.8.8 example.com +fetch --dns-server 1.1.1.1:53 example.com +fetch --dns-server https://1.1.1.1/dns-query example.com +``` + +### `--proxy PROXY` + +Route request through a proxy. + +```sh +fetch --proxy http://localhost:8080 example.com +fetch --proxy socks5://localhost:1080 example.com +``` + +### `--unix PATH` + +Make request over a Unix domain socket. Unix-like systems only. + +```sh +fetch --unix /var/run/docker.sock http://unix/containers/json +``` + +## TLS Options + +### `--tls VERSION` + +Minimum TLS version. Values: `1.0`, `1.1`, `1.2`, `1.3`. + +```sh +fetch --tls 1.3 example.com +``` + +### `--insecure` + +Accept invalid TLS certificates. Use with caution. + +```sh +fetch --insecure https://self-signed.example.com +``` + +### `--ca-cert PATH` + +Custom CA certificate file. + +```sh +fetch --ca-cert ca-cert.pem example.com +``` + +## HTTP Version + +### `--http VERSION` + +Force specific HTTP version. Values: `1`, `2`, `3`. + +- `1` - HTTP/1.1 +- `2` - HTTP/2 (default preference) +- `3` - HTTP/3 (QUIC) + +```sh +fetch --http 1 example.com +fetch --http 3 example.com +``` + +## Compression + +### `--no-encode` + +Disable automatic gzip/zstd compression. + +```sh +fetch --no-encode example.com +``` + +## Range Requests + +### `-r, --range RANGE` + +Request specific byte ranges. Can be used multiple times. + +```sh +fetch -r 0-1023 example.com/file.bin +fetch -r 0-499 -r 1000-1499 example.com/file.bin +``` + +## Verbosity + +### `-v, --verbose` + +Increase output verbosity. Can be stacked. + +- `-v` - Show response headers +- `-vv` - Show request and response headers +- `-vvv` - Show DNS and TLS details + +```sh +fetch -v example.com +fetch -vvv example.com +``` + +### `-s, --silent` + +Suppress verbose output. Only errors shown on stderr. + +```sh +fetch -s example.com +``` + +### `--ignore-status` + +Don't use HTTP status code for exit code. Always exit 0 on successful request. + +```sh +fetch --ignore-status example.com/not-found +``` + +## gRPC Options + +### `--grpc` + +Enable gRPC mode. Automatically sets HTTP/2, POST method, and gRPC headers. + +```sh +fetch --grpc https://localhost:50051/package.Service/Method +``` + +### `--proto-file PATH` + +Compile `.proto` file(s) for JSON-to-protobuf conversion. Requires `protoc`. Can specify multiple comma-separated paths. + +```sh +fetch --grpc --proto-file service.proto -j '{"field": "value"}' localhost:50051/pkg.Svc/Method +``` + +### `--proto-desc PATH` + +Use pre-compiled descriptor set file instead of `--proto-file`. + +```sh +# Generate descriptor: +protoc --descriptor_set_out=service.pb --include_imports service.proto + +# Use descriptor: +fetch --grpc --proto-desc service.pb -j '{"field": "value"}' localhost:50051/pkg.Svc/Method +``` + +### `--proto-import PATH` + +Add import paths for proto compilation. Use with `--proto-file`. + +```sh +fetch --grpc --proto-file service.proto --proto-import ./proto localhost:50051/pkg.Svc/Method +``` + +## Configuration + +### `-c, --config PATH` + +Specify configuration file path. + +```sh +fetch --config ~/.config/fetch/custom.conf example.com +``` + +## Utility Options + +### `-h, --help` + +Print help information. + +### `-V, --version` + +Print version. + +### `--buildinfo` + +Print detailed build information. + +### `--update` + +Update fetch binary in place. + +### `--complete SHELL` + +Output shell completion scripts. Values: `fish`, `zsh`. + +```sh +fetch --complete zsh > ~/.zshrc.d/_fetch +fetch --complete fish > ~/.config/fish/completions/fetch.fish +``` + +### `--dry-run` + +Print request information without sending. + +```sh +fetch --dry-run -m POST -j '{"test": true}' example.com +``` + +## Environment Variables + +| Variable | Description | +| ----------------------- | -------------------------------- | +| `AWS_ACCESS_KEY_ID` | AWS access key for `--aws-sigv4` | +| `AWS_SECRET_ACCESS_KEY` | AWS secret key for `--aws-sigv4` | +| `VISUAL` / `EDITOR` | Editor for `--edit` option | +| `HTTPS_PROXY` | HTTPS proxy URL | +| `HTTP_PROXY` | HTTP proxy URL | +| `NO_PROXY` | Hosts to bypass proxy | + +## File References + +Many options support file references with the `@` prefix: + +- `@filename` - Read content from file +- `@-` - Read content from stdin +- `@~/path` - Home directory expansion + +```sh +fetch -j @data.json -m POST example.com +echo '{"test": true}' | fetch -j @- -m POST example.com +``` diff --git a/docs/CONFIG.md b/docs/configuration.md similarity index 97% rename from docs/CONFIG.md rename to docs/configuration.md index 790a690..6ff4228 100644 --- a/docs/CONFIG.md +++ b/docs/configuration.md @@ -349,6 +349,7 @@ ca-cert = /path/to/api-ca.crt ``` **Notes:** + - 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 - Encrypted private keys are not supported @@ -513,13 +514,13 @@ header = X-Company-ID: company-identifier ## Configuration File Validation -`fetch` validates configuration files when loading them and will report errors with specific line numbers: +`fetch` validates configuration files when loading them and will report errors: ``` config file '/home/user/.config/fetch/config': line 15: invalid option: 'invalid-option' ``` -Common validation errors include: +Validation errors may include: - Invalid option names - Invalid values for specific options (e.g., `color = invalid`) @@ -535,3 +536,9 @@ Common validation errors include: 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 + +## See Also + +- [CLI Reference](cli-reference.md) - All command-line options +- [Authentication](authentication.md) - Detailed authentication setup +- [Advanced Features](advanced-features.md) - DNS, proxies, and TLS configuration diff --git a/docs/getting-started.md b/docs/getting-started.md new file mode 100644 index 0000000..33543f5 --- /dev/null +++ b/docs/getting-started.md @@ -0,0 +1,141 @@ +# Getting Started + +This guide will help you install `fetch` and make your first HTTP request. + +## Installation + +### Installation Script (Recommended) + +For macOS or Linux, use the installation script: + +```sh +curl -fsSL https://raw.githubusercontent.com/ryanfowler/fetch/main/install.sh | bash +``` + +### Building from Source + +If you have Go installed: + +```sh +go install github.com/ryanfowler/fetch@latest +``` + +### Pre-built Binaries + +Download binaries for your operating system from the [GitHub releases page](https://github.com/ryanfowler/fetch/releases). + +### Verify Installation + +```sh +fetch --version +``` + +## Making Your First Request + +Make a GET request by providing a URL: + +```sh +fetch example.com +``` + +When no scheme is provided, `fetch` defaults to HTTPS: + +```sh +fetch example.com # Uses https://example.com +fetch 192.168.1.1:8080 # Uses https://192.168.1.1:8080 +``` + +Loopback addresses default to HTTP for local development: + +```sh +fetch localhost:3000 # Uses http://localhost:3000 +fetch 127.0.0.1:8080 # Uses http://127.0.0.1:8080 +``` + +You can always specify the scheme explicitly: + +```sh +fetch http://example.com # Force HTTP +fetch https://localhost # Force HTTPS for localhost +``` + +## Understanding the Output + +When you make a request, `fetch` displays: + +1. **Status line** (to stderr) - Shows the HTTP version, status code, and status text +2. **Response body** (to stdout) - Automatically formatted based on content type + +``` +HTTP/1.1 200 OK + +{ + "name": "example", + "value": 42 +} +``` + +The response body is automatically formatted and syntax-highlighted for supported content types like JSON, XML, HTML, and more. + +## Common Options + +### Change HTTP Method + +```sh +fetch -m POST example.com +fetch -X DELETE example.com/resource/123 +``` + +### Add Headers + +```sh +fetch -H "Authorization: Bearer token" example.com +fetch -H "X-Custom: value" -H "Accept: application/json" example.com +``` + +### Send JSON Data + +```sh +fetch -j '{"name": "test"}' -m POST example.com/api +``` + +### View Request and Response Headers + +```sh +fetch -v example.com # Show response headers +fetch -vv example.com # Show request and response headers +fetch -vvv example.com # Show DNS and TLS details +``` + +## Updating + +Update `fetch` to the latest version: + +```sh +fetch --update +``` + +Or enable automatic updates in your [configuration file](configuration.md): + +```ini +auto-update = true +``` + +## Shell Completions + +Generate shell completion scripts: + +```sh +# Zsh +fetch --complete zsh > ~/.zshrc.d/fetch-completion.zsh + +# Fish +fetch --complete fish > ~/.config/fish/completions/fetch.fish +``` + +## Next Steps + +- **[CLI Reference](cli-reference.md)** - Complete list of all command-line options +- **[Configuration](configuration.md)** - Set up a configuration file for persistent settings +- **[Authentication](authentication.md)** - Learn about authentication options +- **[Request Bodies](request-bodies.md)** - Send JSON, XML, forms, and files diff --git a/docs/grpc.md b/docs/grpc.md new file mode 100644 index 0000000..9c8e5dc --- /dev/null +++ b/docs/grpc.md @@ -0,0 +1,366 @@ +# gRPC Support + +`fetch` supports making gRPC calls with automatic protocol handling, JSON-to-protobuf conversion, and formatted responses. + +## Overview + +gRPC (gRPC Remote Procedure Calls) is a high-performance RPC framework that uses Protocol Buffers for serialization and HTTP/2 for transport. + +## Basic gRPC Request + +### `--grpc` + +Enable gRPC mode. This flag: + +- Forces HTTP/2 protocol +- Sets method to POST +- Adds gRPC headers (`Content-Type: application/grpc+proto`, `TE: trailers`) +- Applies gRPC message framing +- Handles gRPC response framing + +```sh +fetch --grpc https://localhost:50051/package.Service/Method +``` + +### URL Format + +The service and method are specified in the URL path: + +``` +https://host:port/package.ServiceName/MethodName +``` + +Example: + +```sh +# Call Echo method on EchoService in the echo package +fetch --grpc https://localhost:50051/echo.EchoService/Echo +``` + +## Proto Schema Options + +To enable JSON-to-protobuf conversion and rich response formatting, provide a proto schema. + +### `--proto-file PATH` + +Compile `.proto` files using `protoc` (must be installed). Supports multiple comma-separated paths. + +```sh +fetch --grpc --proto-file service.proto \ + -j '{"message": "hello"}' \ + https://localhost:50051/echo.EchoService/Echo +``` + +Multiple files: + +```sh +fetch --grpc --proto-file common.proto,service.proto \ + -j '{"request": "data"}' \ + https://localhost:50051/pkg.Service/Method +``` + +### `--proto-desc PATH` + +Use a pre-compiled descriptor set file. Useful when: + +- `protoc` isn't available at runtime +- You want faster startup (no compilation) +- Building CI/CD pipelines + +Generate a descriptor set: + +```sh +protoc --descriptor_set_out=service.pb --include_imports service.proto +``` + +Use the descriptor: + +```sh +fetch --grpc --proto-desc service.pb \ + -j '{"message": "hello"}' \ + https://localhost:50051/echo.EchoService/Echo +``` + +### `--proto-import PATH` + +Add import paths for proto compilation. Use with `--proto-file` when your protos have imports. + +```sh +fetch --grpc \ + --proto-file service.proto \ + --proto-import ./proto \ + --proto-import /usr/local/include \ + -j '{"field": "value"}' \ + https://localhost:50051/pkg.Service/Method +``` + +## How It Works + +### With Proto Schema + +1. The service and method are extracted from the URL path +2. `fetch` looks up the method's input/output message types in the schema +3. JSON request bodies are converted to protobuf wire format +4. The request is framed with gRPC length-prefix +5. Response protobuf is formatted as JSON with field names from the schema + +### Without Proto Schema + +When no schema is provided: + +- Request bodies must be raw protobuf (not JSON) +- Responses are formatted using generic protobuf parsing +- Field numbers are shown instead of names + +## Request Bodies + +### JSON to Protobuf + +With a proto schema, send JSON that matches your message structure: + +```sh +fetch --grpc --proto-file user.proto \ + -j '{ + "name": "John Doe", + "age": 30, + "email": "john@example.com" + }' \ + https://localhost:50051/users.UserService/CreateUser +``` + +The JSON is automatically converted to protobuf wire format. + +### Nested Messages + +```sh +fetch --grpc --proto-file order.proto \ + -j '{ + "customer": { + "id": 123, + "name": "Jane" + }, + "items": [ + {"product_id": 1, "quantity": 2}, + {"product_id": 5, "quantity": 1} + ] + }' \ + https://localhost:50051/orders.OrderService/CreateOrder +``` + +### Empty Requests + +For methods that take empty messages: + +```sh +fetch --grpc --proto-file service.proto \ + https://localhost:50051/health.HealthService/Check +``` + +Or with an empty JSON object: + +```sh +fetch --grpc --proto-file service.proto \ + -j '{}' \ + https://localhost:50051/health.HealthService/Check +``` + +### File-based JSON + +```sh +fetch --grpc --proto-file service.proto \ + -j @request.json \ + https://localhost:50051/pkg.Service/Method +``` + +## Response Formatting + +### With Schema + +Responses are formatted as JSON with field names: + +```json +{ + "name": "John Doe", + "age": 30, + "email": "john@example.com", + "created_at": { + "seconds": 1704067200, + "nanos": 0 + } +} +``` + +### Without Schema + +Generic protobuf parsing shows field numbers: + +``` +1: "John Doe" +2: 30 +3: "john@example.com" +4 { + 1: 1704067200 + 2: 0 +} +``` + +## TLS and Security + +### Self-Signed Certificates + +For development servers with self-signed certificates: + +```sh +fetch --grpc --insecure \ + --proto-file service.proto \ + -j '{"request": "data"}' \ + https://localhost:50051/pkg.Service/Method +``` + +### Custom CA Certificate + +```sh +fetch --grpc \ + --ca-cert ca.crt \ + --proto-file service.proto \ + -j '{"request": "data"}' \ + https://server.example.com:50051/pkg.Service/Method +``` + +### mTLS + +```sh +fetch --grpc \ + --cert client.crt \ + --key client.key \ + --ca-cert ca.crt \ + --proto-file service.proto \ + -j '{"request": "data"}' \ + https://secure.example.com:50051/pkg.Service/Method +``` + +## Debugging + +### Verbose Output + +See request and response headers: + +```sh +fetch --grpc --proto-file service.proto \ + -j '{"field": "value"}' \ + -vv \ + https://localhost:50051/pkg.Service/Method +``` + +### Dry Run + +Inspect the request without sending: + +```sh +fetch --grpc --proto-file service.proto \ + -j '{"field": "value"}' \ + --dry-run \ + https://localhost:50051/pkg.Service/Method +``` + +### Edit Before Sending + +Modify the JSON request body in an editor: + +```sh +fetch --grpc --proto-file service.proto \ + -j '{"template": "value"}' \ + --edit \ + https://localhost:50051/pkg.Service/Method +``` + +## Examples + +### Health Check + +```sh +fetch --grpc https://localhost:50051/grpc.health.v1.Health/Check +``` + +### Create Resource + +```sh +fetch --grpc --proto-file api.proto \ + -j '{ + "resource": { + "name": "my-resource", + "type": "TYPE_A", + "config": {"key": "value"} + } + }' \ + https://api.example.com/resources.ResourceService/Create +``` + +### List with Pagination + +```sh +fetch --grpc --proto-file api.proto \ + -j '{"page_size": 10, "page_token": ""}' \ + https://api.example.com/users.UserService/ListUsers +``` + +### With Authentication + +```sh +fetch --grpc --proto-file api.proto \ + -H "Authorization: Bearer $TOKEN" \ + -j '{"id": "123"}' \ + https://api.example.com/users.UserService/GetUser +``` + +## Troubleshooting + +### "protoc not found" + +Install Protocol Buffers compiler: + +```sh +# macOS +brew install protobuf + +# Ubuntu/Debian +apt install protobuf-compiler + +# Or use --proto-desc with pre-compiled descriptors +``` + +### "method not found in schema" + +- 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` + +### "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) + +### Connection Errors + +- gRPC requires HTTP/2 - ensure server supports it +- Check port number (gRPC typically uses different ports than REST) +- For TLS issues, try `--insecure` for testing + +### Response Parsing Errors + +- If response is empty, check gRPC status in headers (`-vv`) +- Verify proto schema matches server's actual message format +- Try without schema to see raw wire format + +## Limitations + +- **Unary calls only**: Streaming RPCs are not supported +- **Single message**: Cannot send multiple messages in one request +- **gRPC-Web**: Standard gRPC protocol only, not gRPC-Web + +## See Also + +- [CLI Reference](cli-reference.md) - All gRPC options +- [Authentication](authentication.md) - mTLS setup +- [Troubleshooting](troubleshooting.md) - Common issues diff --git a/docs/image-rendering.md b/docs/image-rendering.md new file mode 100644 index 0000000..ee64327 --- /dev/null +++ b/docs/image-rendering.md @@ -0,0 +1,206 @@ +# Image Rendering + +`fetch` can render images directly in your terminal when fetching image URLs. + +## Image Control + +### `--image OPTION` + +Control how images are rendered: + +| Value | Description | +| -------- | ---------------------------------------------------------- | +| `auto` | Try optimal protocol, fallback to external tools (default) | +| `native` | Use only built-in decoders | +| `off` | Disable image rendering | + +```sh +fetch --image native example.com/photo.jpg +fetch --image off example.com/image.png +``` + +## Supported Image Formats + +### Built-in Decoders (Native) + +These formats are decoded without external tools: + +- **JPEG** - `.jpg`, `.jpeg` +- **PNG** - `.png` +- **TIFF** - `.tiff`, `.tif` +- **WebP** - `.webp` + +### With External Adapters + +When `--image auto` (default), these additional formats are supported if you have the required tools installed: + +- **AVIF** - `.avif` +- **HEIF/HEIC** - `.heif`, `.heic` +- **GIF** - `.gif` (static frame) +- **BMP** - `.bmp` +- **And many more...** + +## Terminal Protocols + +`fetch` automatically detects your terminal and uses the best available image protocol. + +### Kitty Graphics Protocol + +**Supported terminals**: Kitty, Ghostty, Konsole + +The highest quality protocol with full color support and efficient transmission. + +### iTerm2 Inline Images + +**Supported terminals**: iTerm2, WezTerm, Hyper, Mintty + +Base64-encoded PNG images displayed inline. + +### Unicode Block Characters + +**Supported terminals**: All terminals + +Fallback rendering using Unicode block characters (▀▄█). Works everywhere but with reduced resolution. + +## Terminal Detection + +`fetch` detects your terminal emulator through environment variables: + +| Terminal | Detection Method | +| ---------------- | ---------------------------------------------- | +| Kitty | `KITTY_PID` or `TERM=xterm-kitty` | +| Ghostty | `GHOSTTY_BIN_DIR` or `TERM=xterm-ghostty` | +| iTerm2 | `ITERM_SESSION_ID` or `TERM_PROGRAM=iTerm.app` | +| WezTerm | `WEZTERM_EXECUTABLE` or `TERM_PROGRAM=WezTerm` | +| Konsole | `KONSOLE_VERSION` | +| Hyper | `TERM_PROGRAM=Hyper` | +| Mintty | `TERM_PROGRAM=mintty` | +| VS Code | `TERM_PROGRAM=vscode` or `VSCODE_INJECTION` | +| Windows Terminal | `WT_SESSION` | +| Apple Terminal | `TERM_PROGRAM=Apple_Terminal` | +| Alacritty | `TERM=alacritty` | +| Zellij | `ZELLIJ` | +| tmux | `TERM_PROGRAM=tmux` | + +## External Adapters + +When native decoders can't handle an image format, `fetch` tries external tools in this order: + +### 1. VIPS (`vips`) + +Fast image processing library. + +```sh +# Install on macOS +brew install vips + +# Install on Ubuntu/Debian +apt install libvips-tools +``` + +### 2. ImageMagick (`magick`) + +Comprehensive image manipulation tool. + +```sh +# Install on macOS +brew install imagemagick + +# Install on Ubuntu/Debian +apt install imagemagick +``` + +### 3. FFmpeg (`ffmpeg`) + +Multimedia framework with image support. + +```sh +# Install on macOS +brew install ffmpeg + +# Install on Ubuntu/Debian +apt install ffmpeg +``` + +## Configuration + +Set image rendering preferences in your [configuration file](configuration.md): + +```ini +# Disable image rendering +image = off + +# Use only native decoders +image = native + +# Auto-detect (default) +image = auto +``` + +## 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. + +## Examples + +### View an Image + +```sh +fetch example.com/photo.jpg +``` + +### Download Instead of Display + +```sh +fetch -o photo.jpg example.com/photo.jpg +``` + +### Force Native Decoding + +```sh +fetch --image native example.com/image.png +``` + +### Disable Image Rendering + +```sh +fetch --image off example.com/image.jpg +``` + +## Troubleshooting + +### Image Not Displaying + +1. **Check terminal support**: Not all terminals support inline images +2. **Verify format**: Use `--image native` to test if it's a format issue +3. **Install adapters**: Install VIPS, ImageMagick, or FFmpeg for more formats +4. **Check terminal size**: Very small terminals may not render properly + +### Poor Quality + +1. **Use a native protocol terminal**: Kitty, Ghostty, or iTerm2 provide best quality +2. **Check image dimensions**: Very large images are resized +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 +3. **Try native decoding**: `--image native` + +### 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. + +## 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 + +## See Also + +- [CLI Reference](cli-reference.md) - Image option details +- [Output Formatting](output-formatting.md) - Other content type handling +- [Configuration](configuration.md) - Default image settings diff --git a/docs/output-formatting.md b/docs/output-formatting.md new file mode 100644 index 0000000..94a7f59 --- /dev/null +++ b/docs/output-formatting.md @@ -0,0 +1,368 @@ +# Output Formatting + +`fetch` automatically formats and syntax-highlights response bodies based on content type. + +## Format Control + +### `--format OPTION` + +Control response body formatting: + +| Value | Description | +| ------ | ------------------------------------------ | +| `auto` | Format when stdout is a terminal (default) | +| `on` | Always format output | +| `off` | Never format output | + +```sh +fetch --format off example.com/api # Raw output +fetch --format on example.com/api # Force formatting +``` + +### `--color OPTION` + +Control syntax highlighting: + +| Value | Description | +| ------ | ----------------------------------------- | +| `auto` | Color when stdout is a terminal (default) | +| `on` | Always use colors | +| `off` | Never use colors | + +```sh +fetch --color off example.com/api # No colors +fetch --color on example.com/api | less -R # Colors piped to less +``` + +## Supported Content Types + +### JSON + +**Content-Types**: `application/json`, `*/*+json`, `*/*-json` + +Features: + +- Pretty-printing with proper indentation +- Syntax highlighting for keys, strings, numbers, booleans, null + +```sh +fetch example.com/api/users +``` + +Output: + +```json +{ + "id": 1, + "name": "John Doe", + "email": "john@example.com", + "active": true +} +``` + +### XML + +**Content-Types**: `application/xml`, `text/xml`, `*/*+xml` + +Features: + +- Proper indentation +- Color-coded elements, attributes, and content + +```sh +fetch example.com/api/data.xml +``` + +Output: + +```xml + + + + John Doe + john@example.com + + +``` + +### HTML + +**Content-Type**: `text/html` + +Features: + +- Proper indentation of nested elements +- Syntax highlighting +- Embedded CSS handling + +```sh +fetch example.com +``` + +### CSS + +**Content-Type**: `text/css` + +Features: + +- Selector highlighting +- Property and value coloring +- Proper indentation + +```sh +fetch example.com/styles.css +``` + +### CSV + +**Content-Types**: `text/csv`, `application/csv` + +Features: + +- Column alignment for readability +- Vertical "record view" for wide data that doesn't fit terminal width + +```sh +fetch example.com/data.csv +``` + +Standard output (fits terminal): + +``` +name email age +John Doe john@example.com 30 +Jane Smith jane@example.com 25 +``` + +Vertical mode (wide data): + +``` +--- Record 1 --- +name: John Doe +email: john@example.com +age: 30 + +--- Record 2 --- +name: Jane Smith +email: jane@example.com +age: 25 +``` + +### MessagePack + +**Content-Types**: `application/msgpack`, `application/x-msgpack`, `application/vnd.msgpack` + +Features: + +- Automatic conversion to JSON format +- Same formatting as JSON responses + +```sh +fetch example.com/api/data.msgpack +``` + +### Protocol Buffers + +**Content-Types**: `application/protobuf`, `application/x-protobuf`, `application/x-google-protobuf`, `application/vnd.google.protobuf`, `*/*+proto` + +Features: + +- Wire format parsing (without schema) +- Field number display +- With gRPC schema: field names and proper types + +Without schema (generic parsing): + +``` +1: "John Doe" +2: 30 +3: "john@example.com" +``` + +With schema (via `--proto-file` or `--proto-desc`): + +```json +{ + "name": "John Doe", + "age": 30, + "email": "john@example.com" +} +``` + +See [gRPC documentation](grpc.md) for schema-aware formatting. + +### Server-Sent Events (SSE) + +**Content-Type**: `text/event-stream` + +Features: + +- Streaming output as events arrive +- Event type and data parsing + +```sh +fetch example.com/events +``` + +Output: + +``` +event: message +data: {"user": "john", "text": "Hello!"} + +event: message +data: {"user": "jane", "text": "Hi there!"} +``` + +### NDJSON / JSON Lines + +**Content-Types**: `application/x-ndjson`, `application/ndjson`, `application/x-jsonl`, `application/jsonl`, `application/x-jsonlines` + +Features: + +- Streaming output line by line +- Each line formatted as JSON + +```sh +fetch example.com/stream.ndjson +``` + +Output: + +```json +{"id": 1, "event": "start"} +{"id": 2, "event": "data", "value": 42} +{"id": 3, "event": "end"} +``` + +### Images + +**Content-Type**: `image/*` + +Images are rendered directly in the terminal. See [Image Rendering](image-rendering.md) for details. + +## Output to File + +### `-o, --output PATH` + +Write response body to a file: + +```sh +fetch -o response.json example.com/api/data +``` + +Formatting is disabled when writing to a file. + +### `-o -` (Stdout) + +Force output to stdout, bypassing binary detection: + +```sh +fetch -o - example.com/file.bin > output.bin +``` + +### `-O, --remote-name` + +Save to current directory using filename from URL: + +```sh +fetch -O example.com/files/document.pdf +# Creates ./document.pdf +``` + +### `-J, --remote-header-name` + +Use filename from `Content-Disposition` header: + +```sh +fetch -O -J example.com/download +# Uses server-provided filename +``` + +### `--clobber` + +Overwrite existing files: + +```sh +fetch -o output.json --clobber example.com/data +``` + +## Pager + +When stdout is a terminal and output is large, `fetch` pipes output through `less` for easier navigation. + +### Disable Pager + +```sh +fetch --no-pager example.com/large-response +``` + +### Pager Environment + +The pager uses these flags: `less -FIRX` + +- `-F` - Quit if output fits on screen +- `-I` - Case-insensitive search +- `-R` - Handle ANSI colors +- `-X` - Don't clear screen on exit + +## Binary Detection + +When stdout is a terminal, `fetch` checks if the response appears to be binary data. If so, it displays a warning instead of corrupting your terminal: + +``` +warning: the response body appears to be binary +``` + +To force output: + +```sh +fetch -o - example.com/binary.dat > file.dat +``` + +## Configuration + +Set defaults in your [configuration file](configuration.md): + +```ini +# Always format output +format = on + +# Disable colors +color = off + +# Disable pager +no-pager = true +``` + +## Examples + +### Pipe to jq + +```sh +fetch --format off example.com/api | jq '.users[0]' +``` + +### Save Pretty JSON + +```sh +fetch example.com/api | tee response.json +``` + +### Force Colors in Pipe + +```sh +fetch --color on example.com/api | less -R +``` + +### Raw Binary Download + +```sh +fetch -o archive.zip example.com/download.zip +``` + +## See Also + +- [CLI Reference](cli-reference.md) - All formatting options +- [Image Rendering](image-rendering.md) - Terminal image display +- [Configuration](configuration.md) - Default settings diff --git a/docs/request-bodies.md b/docs/request-bodies.md new file mode 100644 index 0000000..ae0c653 --- /dev/null +++ b/docs/request-bodies.md @@ -0,0 +1,333 @@ +# Request Bodies + +`fetch` provides multiple options for sending request bodies with different content types. + +## Overview + +Request body options are **mutually exclusive** - you can only use one per request: + +| Option | Content-Type | Use Case | +| ----------------- | ----------------------------------- | ---------------------- | +| `-d, --data` | Auto-detected | Raw data, binary files | +| `-j, --json` | `application/json` | JSON APIs | +| `-x, --xml` | `application/xml` | XML/SOAP APIs | +| `-f, --form` | `application/x-www-form-urlencoded` | Simple forms | +| `-F, --multipart` | `multipart/form-data` | File uploads | + +## Raw Data + +The `-d` or `--data` flag sends raw request body data. Content-Type is auto-detected when reading from files. + +### Inline Data + +```sh +fetch -d 'Hello, world!' -m PUT example.com/resource +``` + +### From File + +```sh +fetch -d @data.txt -m PUT example.com/resource +fetch -d @payload.bin -m POST example.com/upload +``` + +### From Stdin + +```sh +echo 'Request body' | fetch -d @- -m PUT example.com/resource +cat data.json | fetch -d @- -m POST example.com/api +``` + +### Content-Type Detection + +When using `@filename`, the Content-Type is detected from the file extension. +Some examples are: + +| Extension | Content-Type | +| --------- | -------------------------- | +| `.json` | `application/json` | +| `.xml` | `application/xml` | +| `.html` | `text/html` | +| `.txt` | `text/plain` | +| `.csv` | `text/csv` | +| Unknown | `application/octet-stream` | + +Override with a header: + +```sh +fetch -d @data.bin -H "Content-Type: application/custom" -m POST example.com +``` + +## JSON Bodies + +The `-j` or `--json` flag sends JSON data and sets `Content-Type: application/json`. + +### Inline JSON + +```sh +fetch -j '{"name": "test", "value": 42}' -m POST example.com/api +``` + +### From File + +```sh +fetch -j @payload.json -m POST example.com/api +``` + +### From Stdin + +```sh +echo '{"key": "value"}' | fetch -j @- -m POST example.com/api + +# Build JSON dynamically +jq -n '{name: "test", time: now}' | fetch -j @- -m POST example.com/api +``` + +### Nested JSON + +```sh +fetch -j '{ + "user": { + "name": "John", + "email": "john@example.com" + }, + "settings": { + "theme": "dark", + "notifications": true + } +}' -m POST example.com/api/users +``` + +## XML Bodies + +The `-x` or `--xml` flag sends XML data and sets `Content-Type: application/xml`. + +### Inline XML + +```sh +fetch -x 'John' -m POST example.com/api +``` + +### From File + +```sh +fetch -x @request.xml -m POST example.com/soap/endpoint +``` + +### SOAP Example + +```sh +fetch -x ' + + + + 123 + + +' -m POST example.com/soap +``` + +## URL-Encoded Forms + +The `-f` or `--form` flag sends URL-encoded form data. Use multiple times for multiple fields. + +### Basic Form + +```sh +fetch -f username=john -f password=secret -m POST example.com/login +``` + +### With Special Characters + +Values are automatically URL-encoded: + +```sh +fetch -f "message=Hello World!" -f "email=user@example.com" -m POST example.com/contact +``` + +### Generated Content-Type + +``` +Content-Type: application/x-www-form-urlencoded +``` + +Request body: + +``` +username=john&password=secret +``` + +## Multipart Forms + +The `-F` or `--multipart` flag sends multipart form data, typically used for file uploads. + +### Text Fields + +```sh +fetch -F name=John -F email=john@example.com -m POST example.com/users +``` + +### File Uploads + +Use `@` prefix to upload files: + +```sh +fetch -F file=@document.pdf -m POST example.com/upload +fetch -F avatar=@photo.jpg -F name=John -m POST example.com/profile +``` + +### Multiple Files + +```sh +fetch -F "files=@doc1.pdf" -F "files=@doc2.pdf" -m POST example.com/upload +``` + +### Mixed Content + +```sh +fetch \ + -F "title=My Document" \ + -F "description=A sample upload" \ + -F "file=@document.pdf" \ + -F "thumbnail=@preview.png" \ + -m POST example.com/documents +``` + +### Home Directory Expansion + +The `~` is expanded to your home directory: + +```sh +fetch -F config=@~/config.json -m POST example.com/settings +``` + +## Editor Integration + +The `-e` or `--edit` flag opens an editor to compose or modify the request body before sending. + +### Basic Usage + +```sh +fetch --edit -m PUT example.com/resource +``` + +### With Initial Content + +Combine with other body options to edit before sending: + +```sh +fetch -j '{"name": "template"}' --edit -m POST example.com/api +``` + +### Editor Selection + +The editor is selected in this order: + +1. `VISUAL` environment variable +2. `EDITOR` environment variable +3. Well-known editors (`vim`, `nano`, etc.) + +```sh +EDITOR=code fetch --edit -m POST example.com/api +``` + +## File Reference Syntax + +Body options that accept `[@]VALUE` support these formats: + +| Format | Description | +| ----------- | ------------------------ | +| `value` | Use the literal value | +| `@filename` | Read content from file | +| `@-` | Read content from stdin | +| `@~/path` | Read from home directory | + +### Examples + +```sh +# Literal value +fetch -j '{"inline": true}' -m POST example.com + +# From file +fetch -j @data.json -m POST example.com + +# From stdin +cat data.json | fetch -j @- -m POST example.com + +# Home directory +fetch -d @~/Documents/data.txt -m PUT example.com +``` + +## Method Inference + +When a request body is provided without specifying a method, the default is still GET. Always specify the method explicitly for clarity: + +```sh +# Explicit POST +fetch -j '{"data": true}' -m POST example.com + +# Don't rely on implicit behavior +fetch -j '{"data": true}' example.com # Still uses GET! +``` + +## Large Files + +For large file uploads, consider: + +1. **Streaming**: `fetch` streams file content rather than loading it all into memory +2. **Timeout**: Set appropriate timeouts with `--timeout` +3. **Progress**: Use `-v` to see request/response headers + +```sh +fetch -F "large=@bigfile.zip" --timeout 300 -v -m POST example.com/upload +``` + +## Examples + +### REST API Create + +```sh +fetch -j '{ + "title": "New Post", + "content": "Hello, World!", + "published": true +}' -m POST example.com/api/posts +``` + +### Form Login + +```sh +fetch -f username=admin -f password=secret -m POST example.com/login +``` + +### File Upload with Metadata + +```sh +fetch \ + -F "file=@report.pdf" \ + -F "title=Monthly Report" \ + -F "tags=finance,monthly" \ + -m POST example.com/documents +``` + +### GraphQL Query + +```sh +fetch -j '{ + "query": "{ user(id: 1) { name email } }" +}' -m POST example.com/graphql +``` + +### Webhook Payload + +```sh +fetch -j @webhook-payload.json \ + -H "X-Webhook-Secret: $WEBHOOK_SECRET" \ + -m POST example.com/webhooks/receive +``` + +## See Also + +- [CLI Reference](cli-reference.md) - All request body options +- [gRPC](grpc.md) - Sending Protocol Buffer messages +- [Output Formatting](output-formatting.md) - Response formatting diff --git a/docs/troubleshooting.md b/docs/troubleshooting.md new file mode 100644 index 0000000..ace996b --- /dev/null +++ b/docs/troubleshooting.md @@ -0,0 +1,384 @@ +# Troubleshooting + +This guide helps diagnose and fix common issues with `fetch`. + +## Exit Codes + +`fetch` uses exit codes to indicate the result of a request: + +| Exit Code | Meaning | +| --------- | ---------------------------------- | +| 0 | Success (HTTP 2xx-3xx) | +| 4 | Client error (HTTP 4xx) | +| 5 | Server error (HTTP 5xx) | +| 6 | Other HTTP status or request error | + +### Ignore HTTP Status + +To always exit 0 regardless of HTTP status: + +```sh +fetch --ignore-status example.com/not-found +echo $? # Always 0 if request completed +``` + +## Debugging with Verbosity + +### `-v` - Response Headers + +```sh +fetch -v example.com +``` + +Shows: + +- HTTP version and status +- Response headers + +### `-vv` - Request and Response Headers + +```sh +fetch -vv example.com +``` + +Shows: + +- Request method and URL +- Request headers +- Response headers + +### `-vvv` - Full Debug Output + +```sh +fetch -vvv example.com +``` + +Shows: + +- DNS resolution details +- TLS handshake information +- All headers + +## Dry Run Mode + +Preview the request without sending: + +```sh +fetch --dry-run -m POST -j '{"test": true}' example.com +``` + +Shows: + +- Complete request that would be sent +- Headers and body +- Useful for debugging authentication and body formatting + +## Common Issues + +### TLS Certificate Errors + +**Symptom**: "certificate signed by unknown authority" or similar + +**Causes**: + +- Self-signed certificate +- Expired certificate +- Wrong hostname +- Missing intermediate certificates +- Corporate SSL inspection + +**Solutions**: + +1. **For development/testing only**: + + ```sh + fetch --insecure https://self-signed.example.com + ``` + +2. **Add custom CA certificate**: + + ```sh + fetch --ca-cert /path/to/ca.crt https://internal.example.com + ``` + +3. **Check certificate details**: + + ```sh + fetch -vvv https://example.com 2>&1 | grep -i tls + ``` + +4. **Verify certificate externally**: + ```sh + openssl s_client -connect example.com:443 -showcerts + ``` + +### Connection Timeouts + +**Symptom**: Request hangs or "context deadline exceeded" + +**Causes**: + +- Server unreachable +- Firewall blocking connection +- DNS resolution failure +- Slow server response + +**Solutions**: + +1. **Set explicit timeout**: + + ```sh + fetch --timeout 10 example.com + ``` + +2. **Test DNS resolution**: + + ```sh + fetch --dns-server 8.8.8.8 -vvv example.com + ``` + +3. **Test network connectivity**: + ```sh + ping example.com + curl -v example.com + ``` + +### Connection Refused + +**Symptom**: "connection refused" + +**Causes**: + +- Server not running +- Wrong port +- Firewall blocking + +**Solutions**: + +1. **Verify the URL and port** +2. **Check if service is running**: + ```sh + nc -zv example.com 443 + ``` + +### DNS Resolution Failures + +**Symptom**: "no such host" or DNS errors + +**Solutions**: + +1. **Try alternative DNS**: + + ```sh + fetch --dns-server 8.8.8.8 example.com + fetch --dns-server https://1.1.1.1/dns-query example.com + ``` + +2. **Verify hostname**: + ```sh + nslookup example.com + dig example.com + ``` + +### Proxy Issues + +**Symptom**: Connection errors when using proxy + +**Solutions**: + +1. **Verify proxy URL format**: + + ```sh + fetch --proxy http://proxy:8080 example.com + fetch --proxy socks5://proxy:1080 example.com + ``` + +2. **Test without proxy**: + + ```sh + unset HTTP_PROXY HTTPS_PROXY + fetch example.com + ``` + +3. **Check proxy authentication**: + ```sh + fetch --proxy http://user:pass@proxy:8080 example.com + ``` + +### HTTP/2 Issues + +**Symptom**: "http2: server sent GOAWAY" or protocol errors + +**Solutions**: + +1. **Force HTTP/1.1**: + + ```sh + fetch --http 1 example.com + ``` + +2. **Check server HTTP/2 support**: + ```sh + curl --http2 -v example.com 2>&1 | grep -i alpn + ``` + +### gRPC Errors + +**Symptom**: gRPC calls failing + +**Common issues**: + +1. **Method not found**: + - Check URL path format: `/package.Service/Method` + - Verify proto schema includes the method + +2. **Proto compilation fails**: + - Install `protoc`: `brew install protobuf` + - Check import paths: `--proto-import` + +3. **JSON conversion errors**: + - Verify JSON field names match proto (use snake_case) + - Check types: strings must be quoted + +```sh +# Debug gRPC request +fetch --grpc --proto-file service.proto \ + -j '{"field": "value"}' \ + --dry-run \ + https://localhost:50051/pkg.Service/Method +``` + +### Image Rendering Not Working + +**Symptom**: Images show as raw bytes or don't display + +**Solutions**: + +1. **Check terminal support**: + - Use Kitty, iTerm2, WezTerm, or Ghostty for best results + +2. **Force native decoding**: + + ```sh + fetch --image native example.com/image.png + ``` + +3. **Install image adapters**: + + ```sh + brew install vips imagemagick ffmpeg + ``` + +4. **Disable image rendering**: + ```sh + fetch --image off example.com/image.jpg + ``` + +### Binary Data Warning + +**Symptom**: "the response body appears to be binary" + +**Solutions**: + +1. **Save to file**: + + ```sh + fetch -o output.bin example.com/file.bin + ``` + +2. **Force output to stdout**: + ```sh + fetch -o - example.com/file.bin > output.bin + ``` + +### Large Response Truncated + +**Symptom**: Response appears cut off + +**Info**: Formatting is limited to 16MB of data + +**Solutions**: + +1. **Save to file** (no size limit): + + ```sh + fetch -o large-response.json example.com/large + ``` + +2. **Disable formatting**: + ```sh + fetch --format off example.com/large + ``` + +## Configuration Issues + +### Config File Not Loading + +1. **Check location**: + - Windows: `%AppData%\fetch\config` + - macOS/Linux: `~/.config/fetch/config` + +2. **Specify explicitly**: + + ```sh + fetch --config /path/to/config example.com + ``` + +3. **Validate syntax**: + - Check for error messages on stderr + - Verify INI format + +### Settings Not Applied + +**Precedence** (highest to lowest): + +1. Command-line flags +2. Host-specific config +3. Global config +4. Defaults + +Use dry-run to verify: + +```sh +fetch --dry-run example.com +``` + +## Getting More Help + +### Version and Build Info + +```sh +fetch --version +fetch --buildinfo +``` + +### Help Text + +```sh +fetch --help +``` + +### Report Issues + +If you encounter a bug: + +1. Gather debug output: + + ```sh + fetch -vvv example.com 2>&1 + ``` + +2. Note your environment: + + ```sh + fetch --buildinfo + uname -a + ``` + +3. Report at: https://github.com/ryanfowler/fetch/issues + +## See Also + +- [CLI Reference](cli-reference.md) - All options and flags +- [Configuration](configuration.md) - Config file format +- [Advanced Features](advanced-features.md) - Network options