Skip to content

Latest commit

 

History

1 Commit

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Serv

A lightweight, flexible HTTP server for local development testing. Perfect for testing webhooks, API integrations, or any application that needs to hit HTTP endpoints during development.

Features

  • Default 200 OK: Responds to all requests with 200 OK by default
  • Custom Routes: Define specific behavior for certain endpoints
  • Wildcard Paths: Support for path patterns like /webhook/*
  • Method Matching: Optionally match specific HTTP methods (GET, POST, etc.)
  • Custom Responses: Configure status codes, headers, and body content
  • File or Inline Bodies: Response bodies can be inline strings or loaded from files
  • Request Logging: See all incoming requests with headers, body, and query parameters
  • Body Truncation: Large request bodies are automatically truncated to 1KB in logs
  • Graceful Shutdown: Server shuts down gracefully on Ctrl+C, allowing in-flight requests to complete
  • Request Timeouts: Built-in protection against slow clients with 15-second read/write timeouts
  • Port Validation: Validates port numbers are in the valid range (1-65535)

Installation

go build -o serv

Or using the Makefile:

make build

Usage

Basic Server

Start a server that responds 200 OK to all requests on port 8080:

./serv

Custom Port

./serv --port 3000

Custom Route with Inline Body

Respond to POST requests to /webhook/github with a custom status and JSON body:

./serv --method POST \
  --path "/webhook/github" \
  --status 201 \
  --headers "Content-Type:application/json,X-Webhook-Id:123" \
  --body '{"status":"received"}'

Custom Route with File Body

Load response body from a file:

./serv --method POST \
  --path "/webhook/*" \
  --status 200 \
  -f --body response.json

The -f flag tells Serv to treat --body as a file path. The Content-Type header will be automatically inferred from the file extension (.json, .html, .txt).

Wildcard Paths

Use wildcards to match multiple paths:

./serv --path "/api/*/callback"

This matches:

  • /api/users/callback
  • /api/users/v1/callback
  • /api/orders/callback

Quiet Mode

Suppress request/response logging:

./serv --quiet

Examples

Testing a Webhook Integration

# Start Serv to accept GitHub-style webhooks
./serv --method POST \
  --path "/webhook/github" \
  --status 201 \
  --headers "Content-Type:application/json" \
  --body '{"status":"success","message":"Webhook received"}'

# In another terminal, send a test webhook
curl -X POST http://localhost:8080/webhook/github \
  -H "Content-Type: application/json" \
  -d '{"event":"push","repository":"myrepo"}'

Testing API Endpoints

# Start Serv with a wildcard route
./serv --path "/api/*" \
  --status 200 \
  -f --body api-response.json

# Test different endpoints - all will use the same response
curl http://localhost:8080/api/users
curl http://localhost:8080/api/orders
curl http://localhost:8080/api/products/123

Default Fallback Behavior

If a request doesn't match your custom route, Serv returns 200 OK:

# Define custom route for /webhook/*
./serv --path "/webhook/*" --body "Webhook received"

# This matches the custom route
curl http://localhost:8080/webhook/test
# Response: Webhook received

# This doesn't match, falls back to default
curl http://localhost:8080/other/path
# Response: OK

Request Logging

When not in quiet mode, Serv logs all incoming requests:

[2025-12-14 10:30:15] POST /webhook/test?foo=bar&id=123
Headers:
  Content-Type: application/json
  User-Agent: curl/8.7.1
Body (38 bytes):
  {"event":"user.created","user_id":456}
Response: 200 OK
---

Request bodies larger than 1KB are truncated in the logs.

Graceful Shutdown

Serv handles shutdown signals (Ctrl+C, SIGTERM) gracefully:

  • When you stop the server, it will display "Shutting down server..."
  • In-flight requests are given up to 5 seconds to complete
  • New connections are rejected immediately
  • Once all requests complete (or the timeout expires), the server exits cleanly

This ensures that webhook deliveries or API requests in progress aren't interrupted abruptly.

Supported Content Types

For custom responses, only these content types are supported:

  • text/* (text/plain, text/html, text/css, etc.)
  • application/json

This is by design to keep Serv focused on API and webhook testing.

Error Handling

Serv validates configuration at startup and provides clear error messages:

# Invalid port number
./serv --port 99999
Error: configuration error: invalid port: 99999 (must be 1-65535)

# Invalid header format
./serv --headers "Content-Type"
Error: configuration error: invalid header format: "Content-Type" (expected Key:Value, got 1 parts after splitting on ':')

# Invalid status code
./serv --status 999
Error: configuration error: invalid status code: 999 (must be 100-599)

Command-Line Flags

Flag Description Default
--port Port to listen on 8080
--method HTTP method for custom route (any)
--path Path pattern for custom route (supports wildcards) (any)
--status HTTP status code for custom response 200
--headers Response headers as "Key:Value,Key2:Value2" (none)
--body Response body (inline string or file path) (none)
-f, --file Treat --body as file path false
--quiet Suppress request/response logging false

Development

Run Tests

go test -v ./...

Run Locally

make dev

Build

make build

License

MIT

About

A lightweight, flexible HTTP server for local development testing

Resources

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages