Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 9 additions & 3 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ This file provides guidance to AI agents when working with code in this reposito

## Project Overview

`fetch` is a modern HTTP(S) client CLI written in Go. It features automatic response formatting (JSON, XML, YAML, HTML, CSS, CSV, protobuf, msgpack), image rendering in terminals, gRPC support with JSON-to-protobuf conversion, and authentication (Basic, Bearer, AWS SigV4).
`fetch` is a modern HTTP(S) client CLI written in Go. It features automatic response formatting (JSON, XML, YAML, HTML, CSS, CSV, protobuf, msgpack), image rendering in terminals, gRPC support with reflection/discovery and JSON-to-protobuf conversion, and authentication (Basic, Bearer, AWS SigV4).

The repository currently targets Go 1.26.1 in `go.mod` and GitHub Actions.

Expand Down Expand Up @@ -52,7 +52,7 @@ prettier -w .
- **internal/config** - INI-format config file parsing with host-specific overrides.
- **internal/core** - Shared types (`Printer`, `Color`, `Format`, `HTTPVersion`) and utilities.
- **internal/curl** - Curl command parser for `--from-curl` flag. Tokenizes and parses curl command strings into an intermediate `Result` struct.
- **internal/fetch** - Core HTTP request execution. `fetch.go:Fetch()` is the main entry point that builds requests, handles gRPC framing, and routes to formatters.
- **internal/fetch** - Core HTTP request execution. `fetch.go:Fetch()` is the main entry point that builds requests, handles gRPC framing/reflection/discovery, and routes to formatters.
- **internal/fileutil** - Shared file helpers, including cross-platform atomic replacement for temp-file write flows.
- **internal/format** - Response body formatters (JSON, XML, YAML, HTML, CSS, CSV, msgpack, protobuf, SSE, NDJSON). Each formatter writes colored output to a `Printer`.
- **internal/grpc** - gRPC framing, headers, and status code handling.
Expand All @@ -68,7 +68,13 @@ prettier -w .
1. CLI args parsed (`cli.Parse`) → `App` struct
2. Config file merged (`config.GetFile`)
3. `fetch.Request` built from merged config
4. If gRPC: load proto schema, setup descriptors, convert JSON→protobuf, frame message
4. If gRPC: load local proto schema or resolve it via reflection, setup descriptors, convert JSON→protobuf, frame message

## Recent Notes

- `--grpc-list` and `--grpc-describe` provide grpcurl-style discovery using reflection or local descriptor files.
- `--grpc` now automatically tries gRPC reflection when no local schema is supplied.
- Plaintext loopback gRPC servers are supported via `h2c` for both calls and discovery.
5. HTTP client executes request
6. Response formatted based on Content-Type and output to stdout (optionally via pager)

Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ A modern HTTP(S) client for the command line.
- **Response formatting** - Automatic formatting and syntax highlighting for JSON, XML, YAML, HTML, CSS, CSV, Markdown, MessagePack, Protocol Buffers, and more
- **Image rendering** - Display images directly in your terminal
- **WebSocket support** - Bidirectional WebSocket connections with automatic JSON formatting
- **gRPC support** - Make gRPC calls with automatic JSON-to-protobuf conversion
- **gRPC support** - Make gRPC calls with automatic reflection, discovery, and 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
- **TLS inspection** - Inspect TLS certificate chains, expiry, SANs, and OCSP status
Expand Down
1 change: 1 addition & 0 deletions docs/advanced-features.md
Original file line number Diff line number Diff line change
Expand Up @@ -151,6 +151,7 @@ fetch --http 2 example.com
- Multiplexed streams
- Header compression (HPACK)
- Required for gRPC
- Automatically uses h2c (HTTP/2 over cleartext) for gRPC requests with `http://` URLs, enabling plaintext HTTP/2 connections to local development servers without TLS

### HTTP/3 (QUIC)

Expand Down
29 changes: 26 additions & 3 deletions docs/cli-reference.md
Original file line number Diff line number Diff line change
Expand Up @@ -407,9 +407,12 @@ Force specific HTTP version. Values: `1`, `2`, `3`.
- `2` - HTTP/2 (default preference)
- `3` - HTTP/3 (QUIC)

When `--http 2` is used with an `http://` URL for gRPC requests, `fetch` automatically uses h2c (HTTP/2 over cleartext) to connect without TLS.

```sh
fetch --http 1 example.com
fetch --http 3 example.com
fetch --grpc --http 2 http://localhost:50051/pkg.Svc/Method # uses h2c
```

## Compression
Expand Down Expand Up @@ -489,23 +492,41 @@ See [WebSocket documentation](websocket.md) for details.

### `--grpc`

Enable gRPC mode. Automatically sets HTTP/2, POST method, and gRPC headers.
Enable gRPC mode. Automatically sets HTTP/2, POST method, and gRPC headers. When no local proto schema is provided, `fetch` automatically tries gRPC reflection before falling back to generic protobuf handling.

```sh
fetch --grpc https://localhost:50051/package.Service/Method
```

### `--grpc-list`

List available gRPC services. Uses reflection when a URL is provided, or runs offline when `--proto-file` / `--proto-desc` is provided.

```sh
fetch --grpc-list https://localhost:50051
fetch --grpc-list --proto-desc service.pb
```

### `--grpc-describe NAME`

Describe a gRPC service, method, or message. Accepts `package.Service`, `package.Service/Method`, `package.Service.Method`, and full message names.

```sh
fetch --grpc-describe grpc.health.v1.Health https://localhost:50051
fetch --grpc-describe grpc.health.v1.Health/Check --proto-desc service.pb
```

### `--proto-file PATH`

Compile `.proto` file(s) for JSON-to-protobuf conversion. Requires `protoc`. Can specify multiple comma-separated paths.
Compile `.proto` file(s) for gRPC requests or offline discovery. 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`.
Use a pre-compiled descriptor set file instead of `--proto-file`.

```sh
# Generate descriptor:
Expand All @@ -523,6 +544,8 @@ 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`).

## Configuration

### `-c, --config PATH`
Expand Down
59 changes: 53 additions & 6 deletions docs/grpc.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# gRPC Support

`fetch` supports making gRPC calls with automatic protocol handling, JSON-to-protobuf conversion, and formatted responses.
`fetch` supports making gRPC calls with automatic protocol handling, reflection-backed schema discovery, JSON-to-protobuf conversion, and formatted responses.

## Overview

Expand All @@ -22,6 +22,41 @@ Enable gRPC mode. This flag:
fetch --grpc https://localhost:50051/package.Service/Method
```

When `--proto-file` or `--proto-desc` is not provided, `fetch` automatically tries gRPC reflection for schema-aware request conversion and response formatting.

## Reflection and Discovery

### `--grpc-list`

List available services from a reflection-enabled server:

```sh
fetch --grpc-list https://localhost:50051
```

Or run the same lookup offline with a local descriptor set:

```sh
fetch --grpc-list --proto-desc service.pb
```

### `--grpc-describe NAME`

Describe a service, method, or message:

```sh
fetch --grpc-describe grpc.health.v1.Health https://localhost:50051
fetch --grpc-describe grpc.health.v1.Health/Check https://localhost:50051
fetch --grpc-describe grpc.health.v1.HealthCheckRequest --proto-desc service.pb
```

`NAME` accepts:

- `package.Service`
- `package.Service/Method`
- `package.Service.Method`
- full message names

### URL Format

The service and method are specified in the URL path:
Expand All @@ -39,7 +74,7 @@ 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.
To enable offline discovery, guaranteed JSON-to-protobuf conversion, or to bypass reflection entirely, provide a local proto schema.

### `--proto-file PATH`

Expand Down Expand Up @@ -106,11 +141,14 @@ fetch --grpc \

### Without Proto Schema

When no schema is provided:
When no local 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
- `fetch` first tries gRPC reflection
- If reflection is available, request/response descriptors are resolved automatically
- If reflection is unavailable, schema-less requests still work for raw/empty protobuf bodies and responses fall back to generic protobuf formatting
- JSON request bodies fail with an actionable error because descriptors are required for conversion

If reflection is unavailable and you need schema-aware behavior, pass `--proto-file` or `--proto-desc`.

## Request Bodies

Expand Down Expand Up @@ -217,6 +255,15 @@ fetch --grpc --insecure \
https://localhost:50051/pkg.Service/Method
```

### Plaintext Local Servers (`h2c`)

For local development servers that use plaintext HTTP/2, use an `http://` URL:

```sh
fetch --grpc -j '{"service":""}' http://127.0.0.1:50051/grpc.health.v1.Health/Check
fetch --grpc-list http://127.0.0.1:50051
```

### Custom CA Certificate

```sh
Expand Down
Loading
Loading