# localproxy — Guide & Tips

> localproxy is a lightweight local HTTP proxy for browser-based tools — download, start, configuration and endpoints to fetch URLs without CORS.

Source: https://www.jpkc.com/db/en/guides/proxy-jpkcom-dev-tools/

localproxy is a lightweight, secure local HTTP proxy for browser-based online tools. It binds exclusively to `127.0.0.1` and lets your web applications fetch external URLs — safely bypassing the browser's CORS restrictions.

## Guide

### Requirements

- A pre-built binary for your platform (Linux, macOS, Windows, FreeBSD, OpenBSD, NetBSD — common architectures each)
- Alternatively, to build from source: [Go 1.26+](https://go.dev/dl/)

### Download the binary

Pre-built binaries for all platforms are available under **Releases** in the repository (e.g. `localproxy-linux-amd64`, `localproxy-macos-apple-silicon`, `localproxy-windows-amd64.exe`).

### Make it executable (macOS / Linux)

```bash
chmod +x ./localproxy-macos-apple-silicon
# macOS: clear the Gatekeeper warning for the unsigned binary:
xattr -dr com.apple.quarantine ./localproxy-macos-apple-silicon
```

### Start it

In the simplest case, with no further configuration:

```bash
./localproxy
```

On startup a banner shows the key values: the **address** (`http://127.0.0.1:PORT` — a random free port without `--port`), the **token** regenerated on every start, the **DNS servers** in use and the allowed **origins**.

### Configuration

```
--port      int     TCP port to listen on (0 = random free port)          [default: 0]
--origin    string  Allowed origins, comma-separated
--timeout   int     Upstream request timeout in seconds                    [default: 30]
--max-mb    int64   Maximum upstream response size in MB (0 = unlimited)   [default: 50]
--dns       string  DNS servers, comma-separated, or "system" for OS DNS   [default: "1.1.1.1,8.8.8.8"]
--version           Print version information and exit
```

Examples:

```bash
# Production: allow only one specific tool
./localproxy --origin https://yourtool.example.com

# Custom DNS servers (Quad9 + Cloudflare)
./localproxy --dns "9.9.9.9,1.1.1.1"

# Use the operating system's DNS resolver
./localproxy --dns system
```

By default localproxy resolves names via **Cloudflare (1.1.1.1)** and **Google (8.8.8.8)** — independent of the host's DNS configuration, which keeps results consistent across machines. If the `--dns` value omits a port, `:53` is appended automatically.

### Endpoints

| Endpoint | Auth | Description |
|---|---|---|
| `GET/POST/HEAD /proxy?url=...` | yes (`X-Proxy-Token`) | Forward the request to the target URL (body streaming, metadata headers) |
| `GET /inspect?url=...` | yes | Connection metadata as JSON (SSL, timing, IP, headers); `&body=1` includes the body |
| `GET /page?url=...` | yes | Full page analysis: redirect chain + body + SSL + timing in one JSON |
| `OPTIONS /proxy|/inspect|/page` | no | CORS preflight (204 with CORS and PNA headers) |
| `GET /ping` | no | Health check (returns `localproxy ok`) |
| `GET /version` | no | Version info as JSON |

### Integrating it in a tool

1. The user enters the **address** (`http://127.0.0.1:PORT`) and **token** in the online tool.
2. The tool verifies the connection via `/ping`.
3. All further requests go through `/proxy?url=...` with the `X-Proxy-Token` header. Example:

```javascript
const response = await fetch(
  `${PROXY_BASE}/proxy?url=${encodeURIComponent(targetUrl)}`,
  { headers: { "X-Proxy-Token": PROXY_TOKEN } }
);
```

Every `/proxy` response also carries upstream metadata as headers: `X-Upstream-Protocol`, `X-Upstream-IP`, `X-Upstream-Timing` (e.g. `dns=12;tcp=45;ssl=23;ttfb=156;total=234`), `X-Upstream-Content-Encoding` and `X-Upstream-Content-Length`. All upstream headers are readable from JavaScript.

## Tips & Tricks

- **Restrict origins in production:** Without `--origin` all origins are allowed. For production use, always allow the specific tool via `--origin https://yourtool.example.com`.
- **HTTPS page calling HTTP localhost — no problem:** Browsers treat `http://127.0.0.1` as a "potentially trustworthy origin" (W3C Secure Contexts). Requests from an HTTPS page to the local proxy are **not** blocked as mixed content; Chrome's Private Network Access preflight is answered automatically.
- **`/page` saves round-trips:** The endpoint traces the redirect chain (up to 20 hops), downloads the body, inspects SSL and measures timing in a single JSON — replacing multiple `/proxy` and `/inspect` calls.
- **SSL details the browser won't give you:** `/inspect` returns certificate information (version, issuer, validity, SANs, chain) that the Fetch API can't access. Without `body=1` it sends only a HEAD request upstream (faster, no body download).
- **Security defaults:** 48-character session token regenerated on each start, SSRF protection (target hosts are resolved and checked against private/loopback CIDRs), upstream TLS verification always on, redirects are **not** followed automatically (the client decides), response size capped via `--max-mb`.
- **Concurrency & compression:** The proxy handles requests concurrently (one goroutine per connection); each upstream request uses a fresh connection for accurate timing. Brotli, gzip and deflate pass through transparently on `/proxy` — the browser handles decompression.
- **Build from source:** With Go 1.26+ via `go build -o localproxy .`; cross-compile with `GOOS`/`GOARCH` (e.g. `GOOS=windows GOARCH=amd64 CGO_ENABLED=0 go build -ldflags="-s -w" -trimpath -o localproxy.exe .`). A Git tag (`git tag v1.0.5 && git push origin v1.0.5`) triggers cross-platform release builds automatically via GitHub Actions.
- **Tests & linting:** `go test -race ./...` for the race detector; the project is linted with [staticcheck](https://staticcheck.dev/) (CI blocks the release on any finding). staticcheck is dev tooling only and never ships with the binary.

## Further reading

- Source code on GitHub: <https://github.com/JPKCom/proxy-jpkcom-dev-tools>
- [Go (download & installation)](https://go.dev/dl/)
- [staticcheck](https://staticcheck.dev/)
- [This project's changelog](https://www.jpkc.com/db/en/changelog/proxy-jpkcom-dev-tools/)

