Skip to content

Basic https server for debug incoming http requests

License

Notifications You must be signed in to change notification settings

vbyazilim/basichttpdebugger

Version Go Golang CI Lint Docker Pulls Docker Size Docker Build Status Build and push to GitHub CR Powered by Rake Go Report Card codecov

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;

go install github.com/vbyazilim/basichttpdebugger@latest

or; from brew;

brew install vbyazilim/basichttpdebugger/basichttpdebugger

Then run:

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;

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:

basichttpdebugger -listen ":8000"    # listens at :8000

If you want to test HMAC validation;

basichttpdebugger -listen ":8000" -hmac-secret "<secret>" -hmac-header-name "<X-HEADER-NAME>"
basichttpdebugger -color -listen ":8000" -hmac-secret "<secret>" -hmac-header-name "<X-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:

basichttpdebugger -listen ":8000" -secret-token-header-name "X-Gitlab-Token" -secret-token "test"

Instead of standard output, pipe everything to file!

basichttpdebugger -listen ":8000" -hmac-secret "<secret>" -hmac-header-name "<X-HEADER-NAME>" -output "/tmp/foo"

Now, tail /tmp/foo:

tail -f /tmp/foo

Well, add some colors :)

basichttpdebugger -listen ":8000" -color

Web Dashboard

Webui Light Webui Dark

A browser-based dashboard is available for real-time request monitoring, similar to ngrok’s web interface. The web dashboard starts automatically when you run the server.

By default, the web dashboard runs on debug port + 1:

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:

basichttpdebugger -listen ":9002" -web-listen ":4040"    # Web dashboard at http://localhost:4040

Or use environment variable:

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:

basichttpdebugger -save-raw-http-request     # will create something like:
                                             # 2024-12-26-163253-localhost_9002-_.raw
                                             # slashes become _

If you make:

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:

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:

nc localhost 9002 < /Users/vigo/Desktop/2024-12-localhost_9002.raw

You can also clone the source repo and run it locally;

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="<secret>" HMAC_HEADER_NAME="<X-HEADER-NAME>" rake
LISTEN=":8000" HMAC_SECRET="<secret>" HMAC_HEADER_NAME="<X-HEADER-NAME>" COLOR=1 rake
LISTEN=":8000" HMAC_SECRET="<secret>" HMAC_HEADER_NAME="<X-HEADER-NAME>" OUTPUT="/tmp/foo" rake

LISTEN=":8000" SECRET_TOKEN="<secret>" SECRET_TOKEN_HEADER_NAME="<X-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!

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                                                                | <version>                                                               |
| Build                                                                  | <build-sha>                                                             |
| 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:

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:

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:

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:

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:

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:

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).

docker build -t <your-image> .

# run with both debug and web dashboard ports
docker run -p 9002:9002 -p 9003:9003 <your-image>

# run from custom port (web dashboard will be at 8401)
docker run -p 8400:8400 -p 8401:8401 <your-image> -listen ":8400"

# run with custom web dashboard port
docker run -p 8400:8400 -p 4040:4040 <your-image> -listen ":8400" -web-listen ":4040"

# with hmac support
docker run -p 8400:8400 -p 8401:8401 <your-image> -listen ":8400" -hmac-secret "<secret>" -hmac-header-name "<X-HEADER-NAME>"

# with secret token support
docker run -p 8400:8400 -p 8401:8401 <your-image> -listen ":8400" -secret-token "<secret>" -secret-token-header-name "<X-HEADER-NAME>"

You can download/use from docker hub or ghcr:

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 "<secret>" -hmac-header-name "<X-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>" -secret-token-header-name "<X-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 "<secret>" -hmac-header-name "<X-HEADER-NAME>"

Rake Tasks

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

$ 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.

About

Basic https server for debug incoming http requests

Topics

Resources

License

Code of conduct

Contributing

Security policy

Stars

Watchers

Forks

Sponsor this project

  •  

Packages

 
 
 

Contributors 3

  •  
  •  
  •