https://github.com/vbyazilim/basichttpdebugger
Basic https server for debug incoming http requests
https://github.com/vbyazilim/basichttpdebugger
golang http-debugging http-server webhook-receiver webhooks-catcher
Last synced: 14 days ago
JSON representation
Basic https server for debug incoming http requests
- Host: GitHub
- URL: https://github.com/vbyazilim/basichttpdebugger
- Owner: vbyazilim
- License: mit
- Created: 2024-01-04T10:08:57.000Z (about 2 years ago)
- Default Branch: main
- Last Pushed: 2026-01-23T19:18:06.000Z (about 1 month ago)
- Last Synced: 2026-01-24T00:45:01.283Z (about 1 month ago)
- Topics: golang, http-debugging, http-server, webhook-receiver, webhooks-catcher
- Language: Go
- Homepage:
- Size: 236 KB
- Stars: 2
- Watchers: 1
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- Contributing: CONTRIBUTING.md
- Funding: .github/FUNDING.yml
- License: LICENSE
- Code of conduct: CODE_OF_CONDUCT.md
- Codeowners: .github/CODEOWNERS
- Security: SECURITY.md
Awesome Lists containing this project
README


[](https://github.com/vbyazilim/basichttpdebugger/actions/workflows/go-lint.yml)



[](https://github.com/vbyazilim/basichttpdebugger/actions/workflows/push-to-github-cr.yml)

[](https://goreportcard.com/report/github.com/vbyazilim/basichttpdebugger)
[](https://codecov.io/gh/vbyazilim/basichttpdebugger)
# Basic HTTP Debugger
This basic http server helps you to debug incoming http requests. It helps you to
debug 3rd party webhooks etc...
---
## Usage
You can install directly the latest version if you have go installation;
```bash
go install github.com/vbyazilim/basichttpdebugger@latest
```
or; from brew;
```bash
brew install vbyazilim/basichttpdebugger/basichttpdebugger
```
Then run:
```bash
basichttpdebugger -h
Usage of basichttpdebugger:
-color
enable color
-hmac-header-name string
name of your signature header, e.g. X-Hub-Signature-256
-hmac-secret string
your HMAC secret value
-listen string
listen addr (default ":9002")
-output string
output/write responses to (default "stdout")
-save-format string
save filename format of raw http (default "%Y-%m-%d-%H%i%s-{hostname}-{url}.raw")
-save-raw-http-request
enable saving of raw http request
-secret-token string
your secret token value
-secret-token-header-name string
name of your secret token header, e.g. X-Gitlab-Token
-version
display version information
-web-listen string
web dashboard listen addr (default: debug port + 1)
```
Start the server;
```bash
basichttpdebugger # listens at :9002
```
> **Note:** The URL path doesn't matter. The server captures **all** incoming
> requests regardless of the path. `http://localhost:9002/`,
> `http://localhost:9002/webhook`, `http://localhost:9002/api/v1/users` - they
> all work the same way. The paths used in examples below (`/login`, `/upload`,
> etc.) are just for illustration purposes.
Listen different port:
```bash
basichttpdebugger -listen ":8000" # listens at :8000
```
If you want to test HMAC validation;
```bash
basichttpdebugger -listen ":8000" -hmac-secret "" -hmac-header-name ""
basichttpdebugger -color -listen ":8000" -hmac-secret "" -hmac-header-name ""
```
Instead of HMAC validation, you can check against secret token/secret token
header name. Consider you are testing GitLab webhooks and you’ll receive
`X-Gitlab-Token` with a value `test`:
```bash
basichttpdebugger -listen ":8000" -secret-token-header-name "X-Gitlab-Token" -secret-token "test"
```
Instead of standard output, pipe everything to file!
```bash
basichttpdebugger -listen ":8000" -hmac-secret "" -hmac-header-name "" -output "/tmp/foo"
```
Now, tail `/tmp/foo`:
```bash
tail -f /tmp/foo
```
Well, add some colors :)
```bash
basichttpdebugger -listen ":8000" -color
```
---
## Web Dashboard
A browser-based dashboard is available for real-time request monitoring,
similar to [ngrok][ngrok]’s web interface. The web dashboard starts
automatically when you run the server.
By default, the web dashboard runs on **debug port + 1**:
```bash
basichttpdebugger -listen ":9002" # Web dashboard at http://localhost:9003
basichttpdebugger -listen ":8000" # Web dashboard at http://localhost:8001
```
You can specify a custom port for the web dashboard:
```bash
basichttpdebugger -listen ":9002" -web-listen ":4040" # Web dashboard at http://localhost:4040
```
Or use environment variable:
```bash
WEB_LISTEN=":4040" basichttpdebugger
```
**Features:**
- Real-time updates via Server-Sent Events (SSE)
- Two-panel layout: request list on left, detail view on right
- Last 50 requests stored in memory
- JSON pretty-printing for request bodies
- Auto-reconnect on connection loss
---
Color output is **disabled** if the output is set to file! You can also
save/capture Raw HTTP Request for later use too:
```bash
basichttpdebugger -save-raw-http-request # will create something like:
# 2024-12-26-163253-localhost_9002-_.raw
# slashes become _
```
If you make:
```bash
curl localhost:9002/test/post/data -d '{"foo": "bar"}'
OK
Raw HTTP Request is saved to: 2024-12-26-163406-localhost_9002-_test_post_data.raw
```
Set custom filename format:
```bash
basichttpdebugger -save-raw-http-request -save-format="~/Desktop/%Y-%m-{hostname}.raw"
OK
Raw HTTP Request is saved to: /Users/vigo/Desktop/2024-12-localhost_9002.raw
```
You can replicate the same http request with using `nc`:
```bash
nc localhost 9002 < /Users/vigo/Desktop/2024-12-localhost_9002.raw
```
You can also clone the source repo and run it locally;
```bash
cd /path/to/go/develompent/
git clone github.com/vbyazilim/basichttpdebugger
cd basichttpdebugger/
go run . -h # help
go run . -version # display version information
go run . # starts server, listens at :9002
go run . -listen ":8000" # listens at :8000
# or if you have ruby installed, use rake tasks!
rake # listens at :9002
LISTEN=":8000" rake # listens at :8000
LISTEN=":8000" HMAC_SECRET="" HMAC_HEADER_NAME="" rake
LISTEN=":8000" HMAC_SECRET="" HMAC_HEADER_NAME="" COLOR=1 rake
LISTEN=":8000" HMAC_SECRET="" HMAC_HEADER_NAME="" OUTPUT="/tmp/foo" rake
LISTEN=":8000" SECRET_TOKEN="" SECRET_TOKEN_HEADER_NAME="" rake
SAVE_RAW_HTTP_REQUEST=t rake
SAVE_RAW_HTTP_REQUEST=t SAVE_FORMAT="~/Desktop/%Y-%m-%d-%H%i%s-test.raw" rake
```
---
## Flags / Environment Variable Map
| Flag | Environment Variable | Default Value |
|:-----|:---------------------|---------------|
| `-hmac-header-name` | `HMAC_HEADER_NAME` | Not set |
| `-hmac-secret` | `HMAC_SECRET` | Not set |
| `-secret-token` | `SECRET_TOKEN` | Not set |
| `-secret-token-header-name` | `SECRET_TOKEN_HEADER_NAME` | Not set |
| `-color` | `COLOR` | `false` |
| `-listen` | `LISTEN` | `:9002` |
| `-output` | `OUTPUT` | `stdout` |
| `-save-raw-http-request` | `SAVE_RAW_HTTP_REQUEST` | `false` |
| `-save-format` | `SAVE_FORMAT` | `%Y-%m-%d-%H%i%s-{hostname}.raw` |
| `-web-listen` | `WEB_LISTEN` | debug port + 1 |
---
## Save Format Placeholders
Most of the format is taken from [Django](https://docs.djangoproject.com/en/5.1/ref/templates/builtins/#date)!
| Placeholder | Description | Example |
|:------------|:------------|---------|
| `{hostname}` | Host name :) | `localhost_9002` |
| `{url}` | URL path | `/test/post/data` => `_test_post_data` |
| `%d` | Day of the month, 2 digits with leading zeros. | `01` to `31` |
| `%j` | Day of the month without leading zeros. | `1` to `31` |
| `%D` | Day of the week, textual, 3 letters. | `Fri` |
| `%l` | Day of the week, textual, long. | `Friday` |
| `%w` | Day of the week, digits without leading zeros. | `0` (Sunday) |
| `%z` | Day of the year. | `1` to `366` |
| `%W` | ISO-8601 week number of year, with weeks starting on Monday. | `1` to `53` |
| `%m` | Month, 2 digits with leading zeros. | `01` to `12` |
| `%n` | Month without leading zeros. | `1` to `12` |
| `%M` | Month, textual, 3 letters. | `Jan` |
| `%b` | Month, textual, 3 letters, lowercase. | `jan` |
| `%F` | Month, textual, long. | `January` |
| `%t` | Number of days in the given month. | `28` to `31` |
| `%y` | Year, 2 digits with leading zeros. | `00` to `99` |
| `%Y` | Year, 4 digits with leading zeros. | `0001` to `9999` |
| `%g` | Hour, 12-hour format without leading zeros. | `1` to `12` |
| `%G` | Hour, 24-hour format without leading zeros. | `0` to `23` |
| `%h` | Hour, 12-hour format. | `01` to `12` |
| `%H` | Hour, 24-hour format. | `00` to `23` |
| `%i` | Minutes. | `00` to `59` |
| `%s` | Seconds, 2 digits with leading zeros. | `00` to `59` |
| `%u` | Microseconds. | `000000` to `999999` |
| `%A` | Meridiem system. | `AM` or `PM` |
---
## Output
Here is how it looks, a GitHub webhook (trimmed, masked due to it’s huge/private data):
----------------------------------------------------------------------------------------------------
+--------------------------------------------------------------------------------------------------------------------------------------------------+
| Basic HTTP Debugger |
+------------------------------------------------------------------------+-------------------------------------------------------------------------+
| Version | |
| Build | |
| Request Time | 2024-12-26 07:37:29.704382 +0000 UTC |
| HTTP Method | POST |
+------------------------------------------------------------------------+-------------------------------------------------------------------------+
| Request Headers |
+------------------------------------------------------------------------+-------------------------------------------------------------------------+
| Accept | */* |
| Accept-Encoding | gzip |
| Content-Length | 11453 |
| Content-Type | application/json |
| User-Agent | GitHub-Hookshot/******* |
| X-Forwarded-For | 140.82.115.54 |
| X-Forwarded-Host | ****.ngrok-free.app |
| X-Forwarded-Proto | https |
| X-Github-Delivery | 0d27de20-****-11ef-****-78dbc150f59f |
| X-Github-Event | issue_comment |
| X-Github-Hook-Id | ****02493 |
| X-Github-Hook-Installation-Target-Id | 90642**** |
| X-Github-Hook-Installation-Target-Type | repository |
| X-Hub-Signature | sha1=****************60a5a88092f5c4678b06fd1e |
| X-Hub-Signature-256 | sha256=****************bebf86cbf7bc1c69a93ff8a3d1ff0cf20ee31ff57ed85ab2 |
+------------------------------------------------------------------------+-------------------------------------------------------------------------+
| Payload |
+------------------------------------------------------------------------+-------------------------------------------------------------------------+
| HMAC Secret | ******************* |
| HMAC Header Name | X-Hub-Signature-256 |
| Incoming Signature | sha256=****************bebf86cbf7bc1c69a93ff8a3d1ff0cf20ee31ff57ed85ab2 |
| Expected Signature | sha256=****************bebf86cbf7bc1c69a93ff8a3d1ff0cf20ee31ff57ed85ab2 |
| Is Valid? | true |
+------------------------------------------------------------------------+-------------------------------------------------------------------------+
| Incoming | application/json |
+------------------------------------------------------------------------+-------------------------------------------------------------------------+
| { |
| "action": "created", |
| "comment": { |
| : |
| : |
| "reactions": { |
| : |
| : |
| }, |
| : |
| "user": { |
| : |
| : |
| : |
| } |
| }, |
| "issue": { |
| : |
| "reactions": { |
| : |
| : |
| : |
| }, |
| : |
| "user": { |
| : |
| } |
| }, |
| "organization": { |
| : |
| : |
| : |
| }, |
| "repository": { |
| : |
| : |
| : |
| "owner": { |
| : |
| }, |
| : |
| : |
| }, |
| "sender": { |
| : |
| : |
| } |
| } |
+--------------------------------------------------------------------------------------------------------------------------------------------------+
----------------------------------------------------------------------------------------------------
Raw Http Request
----------------------------------------------------------------------------------------------------
POST /webhook/github HTTP/1.1
Host: ****.ngrok-free.app
Accept: */*
Accept-Encoding: gzip
Content-Length: 11453
Content-Type: application/json
User-Agent: GitHub-Hookshot/*******
X-Forwarded-For: 140.82.115.54
X-Forwarded-Host: ****.ngrok-free.app
X-Forwarded-Proto: https
X-Github-Delivery: 0d27de20-****-11ef-****-78dbc150f59f
X-Github-Event: issue_comment
X-Github-Hook-Id: 51990****
X-Github-Hook-Installation-Target-Id: 90642****
X-Github-Hook-Installation-Target-Type: repository
X-Hub-Signature: sha1=************a68b60a5a88092f5c4678b06fd1e
X-Hub-Signature-256: sha256=************3d61bebf86cbf7bc1c69a93ff8a3d1ff0cf20ee31ff57ed85ab2
{"action":"created","issue":{"url": ...} ... }
----------------------------------------------------------------------------------------------------
If you are checking secret token/secret token header (`test`, `X-Gitlab-Token`),
you'll see something like this in Payload section:
+-----------------------------------+-----------------------------+
| Payload | |
+-----------------------------------+-----------------------------+
| Secret Token | test |
| Secret Token Header Name | X-Gitlab-Token |
| Secret Token Matches? | true |
+-----------------------------------+-----------------------------+
---
## Form Data Support
The debugger supports `application/x-www-form-urlencoded` content type. Form
data is parsed and displayed in a table format:
```bash
curl -X POST http://localhost:9002/login \
-H "Content-Type: application/x-www-form-urlencoded" \
-d "username=john&password=secret123&remember=true"
```
Output:
+-----------------------------------------------------+
| Payload |
+--------------+--------------------------------------+
| Incoming | application/x-www-form-urlencoded |
+--------------+--------------------------------------+
| Form Data |
+--------------+--------------------------------------+
| password | secret123 |
| remember | true |
| username | john |
+--------------+--------------------------------------+
Form fields are sorted alphabetically. Multiple values for the same key are
displayed comma-separated:
```bash
curl -X POST http://localhost:9002/colors \
-H "Content-Type: application/x-www-form-urlencoded" \
-d "color=red&color=green&color=blue"
```
Output:
+--------------+--------------------------------------+
| Form Data |
+--------------+--------------------------------------+
| color | red, green, blue |
+--------------+--------------------------------------+
URL-encoded special characters are automatically decoded:
```bash
curl -X POST http://localhost:9002/search \
-H "Content-Type: application/x-www-form-urlencoded" \
-d "email=user%40example.com&query=hello+world"
```
Output:
+--------------+--------------------------------------+
| Form Data |
+--------------+--------------------------------------+
| email | user@example.com |
| query | hello world |
+--------------+--------------------------------------+
---
## File Upload Support
The debugger supports `multipart/form-data` content type for file uploads.
Both form fields and files are parsed and displayed:
```bash
curl -X POST http://localhost:9002/upload \
-F "username=vigo" \
-F "description=Test upload" \
-F "config=@config.json"
```
Output:
+-----------------------------------------------------+
| Payload |
+--------------+--------------------------------------+
| Incoming | multipart/form-data; boundary=... |
+--------------+--------------------------------------+
| Form Data |
+--------------+--------------------------------------+
| description | Test upload |
| username | vigo |
+--------------+--------------------------------------+
| Files |
+--------------+--------------------------------------+
| config.json | 18 B | application/json |
| {"theme": "dark"} |
+-----------------------------------------------------+
File metadata is displayed for all uploaded files:
```bash
curl -X POST http://localhost:9002/upload \
-F "avatar=@photo.png"
```
Output:
+-----------------------------------------------------+
| Files |
+-----------------------------------------------------+
| photo.png | 2.5 KB | application/octet-stream |
+-----------------------------------------------------+
For small text files (under 1KB), the content is displayed. For larger files
or binary files, only metadata (filename, size, content-type) is shown.
**Image Preview in Web Dashboard:** When you upload image files (JPEG, PNG, GIF,
etc.), the web dashboard displays a preview of the image alongside the file
metadata.
Multiple files can be uploaded at once:
```bash
curl -X POST http://localhost:9002/upload \
-F "file1=@readme.txt" \
-F "file2=@data.json" \
-F "image=@logo.png"
```
Form fields and files are displayed in separate sections, both in the terminal
and in the web dashboard.
---
## Docker
For local docker usage, default expose port is: `9002` (debug) and `9003` (web dashboard).
```bash
docker build -t .
# run with both debug and web dashboard ports
docker run -p 9002:9002 -p 9003:9003
# run from custom port (web dashboard will be at 8401)
docker run -p 8400:8400 -p 8401:8401 -listen ":8400"
# run with custom web dashboard port
docker run -p 8400:8400 -p 4040:4040 -listen ":8400" -web-listen ":4040"
# with hmac support
docker run -p 8400:8400 -p 8401:8401 -listen ":8400" -hmac-secret "" -hmac-header-name ""
# with secret token support
docker run -p 8400:8400 -p 8401:8401 -listen ":8400" -secret-token "" -secret-token-header-name ""
```
You can download/use from docker hub or ghcr:
- https://hub.docker.com/r/vigo/basichttpdebugger/
- https://github.com/vbyazilim/basichttpdebugger/pkgs/container/basichttpdebugger%2Fbasichttpdebugger
```bash
docker run vigo/basichttpdebugger
docker run -p 9002:9002 vigo/basichttpdebugger # run from default port
docker run -p 8400:8400 vigo/basichttpdebugger -listen ":8400" # run from 8400
# run from docker hub on port 9100 with hmac support
docker run -p 9100:9100 vigo/basichttpdebugger -listen ":9100" -hmac-secret "" -hmac-header-name ""
# run from docker hub on port 9100 with secret token/secret token header name support
docker run -p 9100:9100 vigo/basichttpdebugger -listen ":9100" -secret-token "" -secret-token-header-name ""
# run from ghcr on default port
docker run -p 9002:9002 ghcr.io/vbyazilim/basichttpdebugger/basichttpdebugger:latest
# run from ghcr on 9100
docker run -p 9100:9100 ghcr.io/vbyazilim/basichttpdebugger/basichttpdebugger:latest -listen ":9100"
# run from ghcr on 9100 with hmac support
docker run -p 9100:9100 ghcr.io/vbyazilim/basichttpdebugger/basichttpdebugger:latest -listen ":9100" -hmac-secret "" -hmac-header-name ""
```
---
## Rake Tasks
```bash
rake -T
rake coverage # show test coverage
rake docker:build # build docker image locally
rake docker:run # run docker image locally
rake release[revision] # release new version major,minor,patch, default: patch
rake run # run server (default port 9002)
rake test # run test
```
---
## Change Log
**2026-01-23**
- add `application/x-www-form-urlencoded` content type support
- add `multipart/form-data` content type support for file uploads
- form data is parsed and displayed in table format
- file uploads show metadata (filename, size, content-type)
- small text files (under 1KB) display content inline
- multiple values for the same key are comma-separated
- URL-encoded characters are automatically decoded
- web dashboard supports form data and file upload display
- web dashboard shows image preview for uploaded images (JPEG, PNG, GIF, etc.)
- binary file content is sanitized in terminal output (`[binary data: X KB]`)
- add homebrew-tap
**2025-01-23**
- add web dashboard for real-time request monitoring (similar to ngrok)
- add `-web-listen` flag and `WEB_LISTEN` environment variable
**2025-02-02**
- improve `stringutils` tests
- add secret token/secret token header name support
**2024-12-24**
- refactor from scratch
- disable color when output is file (due to ansi codes, output looks glitchy)
- auto detect terminal and column width
- add raw http request for response
**2024-12-23**
- many improvements, pretty output with colors!
- now you can pipe to file too!
**2024-09-17**
- change default host port to `9002`
- add github actions for docker hub and ghcr
**2024-06-22**
- remove environment variables from source. only `rake` task requires
environment variables
- add command-line flags: `-listen`, `-hmac-secret`, `-hmac-header-name`,
`-h`, `--help`
- add HMAC validation indicator
---
## TODO
- Add brew tap installation support
---
## Rake Tasks
```bash
$ rake -T
rake coverage # show test coverage
rake docker:build # build docker image locally
rake docker:run # run docker image locally
rake release[revision] # release new version major,minor,patch, default: patch
rake run # run server (default port 9002)
rake test # run test
```
---
## License
This project is licensed under MIT
---
This project is intended to be a safe, welcoming space for collaboration, and
contributors are expected to adhere to the [code of conduct][coc].
[coc]: https://github.com/vbyazilim/basichttpdebugger/blob/main/CODE_OF_CONDUCT.md
[ngrok]: https://ngrok.com/