|
| 1 | +--- |
| 2 | +llms_description: "HTTP forward proxy on port 8080 with MITM for HTTPS. Captures full request+response pairs (method, URL, headers, body, status code, timing) as http-dump events. Clients set proxy URL and disable SSL verification. Works with any language: PHP Guzzle (proxy+verify), Go (http.Transport Proxy+InsecureSkipVerify), JavaScript fetch/axios (https-proxy-agent), Python requests (proxies+verify), curl (-x -k), env vars (HTTP_PROXY/HTTPS_PROXY). UI shows response body with JSON tree view, HTML preview, syntax highlighting." |
| 3 | +--- |
| 4 | + |
| 5 | +# HTTP Proxy — Request & Response Capture |
| 6 | + |
| 7 | +Your app calls external APIs — payment gateways, webhooks, third-party services — and you need to see both what |
| 8 | +you send **and** what you get back. Buggregator's HTTP proxy sits between your app and the internet, capturing |
| 9 | +full request/response pairs without changing your application code. Just point your HTTP client at the proxy. |
| 10 | + |
| 11 | +> **Looking for one-way request capture?** See [HTTP Dumps](/config/http-dumps) — it captures incoming requests |
| 12 | +> without proxying to a real server. |
| 13 | +
|
| 14 | +## Use cases |
| 15 | + |
| 16 | +- **API debugging** — see exactly what your app sends to Stripe, Twilio, or any external API, and what comes back. |
| 17 | +- **Webhook testing** — send webhooks through the proxy to inspect both the outgoing payload and the remote server's response. |
| 18 | +- **Response inspection** — view response bodies with syntax highlighting (JSON, HTML, XML) and an interactive JSON tree view. |
| 19 | +- **Performance monitoring** — see response times for every external call your app makes. |
| 20 | +- **No code changes** — configure the proxy at the HTTP client level; your application logic stays untouched. |
| 21 | + |
| 22 | +## What you see in the UI |
| 23 | + |
| 24 | +Proxied requests appear as HTTP dump events with additional data: |
| 25 | + |
| 26 | +- **Full URL** — the complete destination URL including host and port. |
| 27 | +- **Request and response** — headers, body, and status code for both directions. |
| 28 | +- **Status code** — color-coded badge (green for 2xx, amber for 4xx, red for 5xx). |
| 29 | +- **Response time** — duration in milliseconds. |
| 30 | +- **Proxy label** — purple badge to distinguish proxied requests from regular HTTP dumps. |
| 31 | +- **Response body viewer** — JSON tree view with collapsible nodes, HTML preview in a sandboxed iframe, syntax highlighting for XML/CSS/JS. |
| 32 | +- **Tab navigation** — Response, Request, and Raw tabs on the detail page. |
| 33 | + |
| 34 | +## Configuration |
| 35 | + |
| 36 | +The proxy listens on port **8080** by default. Configure it via environment variable or config file: |
| 37 | + |
| 38 | +```dotenv |
| 39 | +PROXY_ADDR=:8080 |
| 40 | +``` |
| 41 | + |
| 42 | +```yaml |
| 43 | +# buggregator.yaml |
| 44 | +tcp: |
| 45 | + proxy: |
| 46 | + addr: ":8080" |
| 47 | +``` |
| 48 | +
|
| 49 | +In Docker Compose, expose the port: |
| 50 | +
|
| 51 | +```yaml |
| 52 | +services: |
| 53 | + buggregator: |
| 54 | + image: ghcr.io/buggregator/server:latest |
| 55 | + ports: |
| 56 | + - "8000:8000" # UI + API |
| 57 | + - "8080:8080" # HTTP Proxy |
| 58 | +``` |
| 59 | +
|
| 60 | +## Client setup |
| 61 | +
|
| 62 | +Point your HTTP client at `http://<buggregator-host>:8080` as a proxy. For HTTPS traffic, disable SSL certificate |
| 63 | +verification — the proxy uses an in-memory CA to intercept TLS connections. This is safe for development. |
| 64 | + |
| 65 | +> In Docker Compose, replace `127.0.0.1` with the Buggregator service name (e.g., `buggregator`). |
| 66 | + |
| 67 | +### PHP — Guzzle |
| 68 | + |
| 69 | +```php |
| 70 | +use GuzzleHttp\Client; |
| 71 | +
|
| 72 | +$client = new Client([ |
| 73 | + 'proxy' => 'http://127.0.0.1:8080', |
| 74 | + 'verify' => false, |
| 75 | +]); |
| 76 | +
|
| 77 | +$response = $client->get('https://api.example.com/users'); |
| 78 | +``` |
| 79 | + |
| 80 | +### PHP — Laravel HTTP Client |
| 81 | + |
| 82 | +```php |
| 83 | +use Illuminate\Support\Facades\Http; |
| 84 | +
|
| 85 | +$response = Http::withOptions([ |
| 86 | + 'proxy' => 'http://127.0.0.1:8080', |
| 87 | + 'verify' => false, |
| 88 | +])->get('https://api.example.com/users'); |
| 89 | +``` |
| 90 | + |
| 91 | +To configure globally for all HTTP calls in development, add a macro in `AppServiceProvider`: |
| 92 | + |
| 93 | +```php |
| 94 | +// app/Providers/AppServiceProvider.php |
| 95 | +use Illuminate\Support\Facades\Http; |
| 96 | +
|
| 97 | +public function boot(): void |
| 98 | +{ |
| 99 | + if ($this->app->isLocal()) { |
| 100 | + Http::globalOptions([ |
| 101 | + 'proxy' => env('BUGGREGATOR_PROXY_URL', 'http://127.0.0.1:8080'), |
| 102 | + 'verify' => false, |
| 103 | + ]); |
| 104 | + } |
| 105 | +} |
| 106 | +``` |
| 107 | + |
| 108 | +```dotenv |
| 109 | +BUGGREGATOR_PROXY_URL=http://buggregator:8080 |
| 110 | +``` |
| 111 | + |
| 112 | +### PHP — Symfony HttpClient |
| 113 | + |
| 114 | +```php |
| 115 | +use Symfony\Component\HttpClient\HttpClient; |
| 116 | +
|
| 117 | +$client = HttpClient::create([ |
| 118 | + 'proxy' => 'http://127.0.0.1:8080', |
| 119 | + 'verify_peer' => false, |
| 120 | + 'verify_host' => false, |
| 121 | +]); |
| 122 | +
|
| 123 | +$response = $client->request('GET', 'https://api.example.com/users'); |
| 124 | +``` |
| 125 | + |
| 126 | +### Go |
| 127 | + |
| 128 | +```go |
| 129 | +import ( |
| 130 | + "crypto/tls" |
| 131 | + "net/http" |
| 132 | + "net/url" |
| 133 | +) |
| 134 | +
|
| 135 | +proxyURL, _ := url.Parse("http://127.0.0.1:8080") |
| 136 | +
|
| 137 | +client := &http.Client{ |
| 138 | + Transport: &http.Transport{ |
| 139 | + Proxy: http.ProxyURL(proxyURL), |
| 140 | + TLSClientConfig: &tls.Config{InsecureSkipVerify: true}, |
| 141 | + }, |
| 142 | +} |
| 143 | +
|
| 144 | +resp, err := client.Get("https://api.example.com/users") |
| 145 | +``` |
| 146 | + |
| 147 | +### JavaScript / Node.js — fetch |
| 148 | + |
| 149 | +```js |
| 150 | +import { ProxyAgent } from 'undici' |
| 151 | +
|
| 152 | +const agent = new ProxyAgent({ |
| 153 | + uri: 'http://127.0.0.1:8080', |
| 154 | + requestTls: { rejectUnauthorized: false }, |
| 155 | +}) |
| 156 | +
|
| 157 | +const response = await fetch('https://api.example.com/users', { |
| 158 | + dispatcher: agent, |
| 159 | +}) |
| 160 | +``` |
| 161 | + |
| 162 | +### JavaScript / Node.js — axios |
| 163 | + |
| 164 | +```js |
| 165 | +import axios from 'axios' |
| 166 | +import { HttpsProxyAgent } from 'https-proxy-agent' |
| 167 | +
|
| 168 | +const agent = new HttpsProxyAgent('http://127.0.0.1:8080', { |
| 169 | + rejectUnauthorized: false, |
| 170 | +}) |
| 171 | +
|
| 172 | +const response = await axios.get('https://api.example.com/users', { |
| 173 | + httpsAgent: agent, |
| 174 | +}) |
| 175 | +``` |
| 176 | + |
| 177 | +### Python — requests |
| 178 | + |
| 179 | +```python |
| 180 | +import requests |
| 181 | +
|
| 182 | +response = requests.get( |
| 183 | + 'https://api.example.com/users', |
| 184 | + proxies={'https': 'http://127.0.0.1:8080'}, |
| 185 | + verify=False, |
| 186 | +) |
| 187 | +``` |
| 188 | + |
| 189 | +### Python — httpx |
| 190 | + |
| 191 | +```python |
| 192 | +import httpx |
| 193 | +
|
| 194 | +client = httpx.Client( |
| 195 | + proxy='http://127.0.0.1:8080', |
| 196 | + verify=False, |
| 197 | +) |
| 198 | +
|
| 199 | +response = client.get('https://api.example.com/users') |
| 200 | +``` |
| 201 | + |
| 202 | +### curl |
| 203 | + |
| 204 | +```bash |
| 205 | +curl -x http://127.0.0.1:8080 -k https://api.example.com/users |
| 206 | +``` |
| 207 | + |
| 208 | +### Environment variables (any language) |
| 209 | + |
| 210 | +Most HTTP clients respect standard proxy environment variables: |
| 211 | + |
| 212 | +```bash |
| 213 | +export HTTP_PROXY=http://127.0.0.1:8080 |
| 214 | +export HTTPS_PROXY=http://127.0.0.1:8080 |
| 215 | +export NODE_TLS_REJECT_UNAUTHORIZED=0 # Node.js only |
| 216 | +
|
| 217 | +# Then run your app normally |
| 218 | +node app.js |
| 219 | +python main.py |
| 220 | +go run . |
| 221 | +``` |
| 222 | + |
| 223 | +> **Note:** `NODE_TLS_REJECT_UNAUTHORIZED=0` disables TLS verification globally for Node.js processes. |
| 224 | +> Use it only in development. |
| 225 | + |
| 226 | +## How it works |
| 227 | + |
| 228 | +1. Your app sends a request to the proxy (`http://127.0.0.1:8080`). |
| 229 | +2. For HTTPS, the proxy performs a CONNECT handshake, generates a TLS certificate for the target host on the fly |
| 230 | + (signed by an in-memory CA), and establishes a TLS connection with your app. |
| 231 | +3. The proxy forwards the request to the real destination server. |
| 232 | +4. The full request and response are captured and stored as an `http-dump` event with a `proxy: true` flag, |
| 233 | + response data, and timing information. |
| 234 | +5. The event appears in the Buggregator UI in real time via WebSocket. |
| 235 | + |
| 236 | +The in-memory CA is generated at server startup and never written to disk. Your client skips certificate |
| 237 | +verification (`InsecureSkipVerify`, `verify: false`, `-k`), so no CA installation is required. |
| 238 | + |
| 239 | +## Docker Compose example |
| 240 | + |
| 241 | +```yaml |
| 242 | +services: |
| 243 | + buggregator: |
| 244 | + image: ghcr.io/buggregator/server:latest |
| 245 | + ports: |
| 246 | + - "8000:8000" |
| 247 | + - "8080:8080" |
| 248 | +
|
| 249 | + app: |
| 250 | + build: . |
| 251 | + environment: |
| 252 | + BUGGREGATOR_PROXY_URL: http://buggregator:8080 |
| 253 | + depends_on: |
| 254 | + - buggregator |
| 255 | +``` |
0 commit comments