Documentation
¶
Overview ¶
Package httpspy provides utilities for capturing and inspecting HTTP request and response messages.
This package offers configurable capture functions that can snapshot HTTP messages with support for selective header censoring and body collection. It is designed for debugging, logging, and testing scenarios where you need to capture HTTP traffic without permanently modifying the original message headers.
Key Features ¶
- Capture incoming HTTP requests (http.Request) using RequestCaptureWithHeaderCensorshipFunction
- Capture outgoing HTTP requests with RequestOutCaptureWithHeaderCensorshipFunction
- Capture HTTP responses (http.Response) using ResponseCaptureWithHeaderCensorshipFunction
- Selectively censor sensitive headers (e.g., Authorization, Set-Cookie)
- Optionally capture message bodies
- Non-destructive: headers are temporarily modified during capture then restored
Basic Usage ¶
Generate capture functions with the desired options:
// For incoming requests (e.g., in HTTP handlers)
captureRequest := httpspy.RequestCaptureWithHeaderCensorshipFunction(
true, // attemptCollectBody
[]string{"Authorization", "Cookie"}, // headersToCensor
"*** REDACTED ***", // censorText
)
snapshot, err := captureRequest(req)
// For outgoing requests (e.g., in HTTP clients)
captureRequestOut := httpspy.RequestOutCaptureWithHeaderCensorshipFunction(
true, // attemptCollectBody
[]string{"Authorization", "Cookie"}, // headersToCensor
"*** REDACTED ***", // censorText
)
snapshot, err := captureRequestOut(req)
// For responses
captureResponse := httpspy.ResponseCaptureWithHeaderCensorshipFunction(
true, // attemptCollectBody
[]string{"Set-Cookie"}, // headersToCensor
"*** REDACTED ***", // censorText
)
snapshot, err := captureResponse(resp)
Header Censoring ¶
When headersToCensor is specified, the capture functions will temporarily replace the values of specified headers with censorText during the snapshot operation, then restore the original values. This ensures sensitive data in the headers is not included in captured snapshots while keeping the actual HTTP message intact.
Header names are case-insensitive (following HTTP standards).
Index ¶
- func RequestCaptureWithHeaderCensorshipFunction(attemptCollectBody bool, headersToCensor []string, censorText string) func(*http.Request) ([]byte, error)
- func RequestOutCaptureWithHeaderCensorshipFunction(attemptCollectBody bool, headersToCensor []string, censorText string) func(*http.Request) ([]byte, error)
- func ResponseCaptureWithHeaderCensorshipFunction(attemptCollectBody bool, headersToCensor []string, censorText string) func(*http.Response) ([]byte, error)
Examples ¶
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func RequestCaptureWithHeaderCensorshipFunction ¶
func RequestCaptureWithHeaderCensorshipFunction(attemptCollectBody bool, headersToCensor []string, censorText string) func(*http.Request) ([]byte, error)
RequestCaptureWithHeaderCensorshipFunction creates a function that captures incoming HTTP requests. If headersToCensor is specified, the returned function will temporarily replace those header values with censorText during capture.
Example ¶
package main
import (
"fmt"
"net/http"
"net/http/httptest"
"strings"
"github.com/angrifel/unapologetic/httpspy"
)
func main() {
capture := httpspy.RequestCaptureWithHeaderCensorshipFunction(false, []string{"authorization"}, "[REDACTED]")
req := httptest.NewRequest(http.MethodGet, "https://example.com", nil)
req.Header.Set("Authorization", "Bearer secret-token")
data, _ := capture(req)
fmt.Println(strings.Contains(string(data), "[REDACTED]"))
fmt.Println(!strings.Contains(string(data), "secret-token"))
}
Output: true true
func RequestOutCaptureWithHeaderCensorshipFunction ¶
func RequestOutCaptureWithHeaderCensorshipFunction(attemptCollectBody bool, headersToCensor []string, censorText string) func(*http.Request) ([]byte, error)
RequestOutCaptureWithHeaderCensorshipFunction creates a function that captures outgoing HTTP requests. If headersToCensor is specified, the returned function will temporarily replace those header values with censorText during capture.
Example ¶
package main
import (
"fmt"
"net/http"
"net/http/httptest"
"strings"
"github.com/angrifel/unapologetic/httpspy"
)
func main() {
capture := httpspy.RequestOutCaptureWithHeaderCensorshipFunction(true, nil, "")
req := httptest.NewRequest(http.MethodPost, "https://example.com", strings.NewReader("request body"))
req.Header.Set("Content-Type", "text/plain")
data, _ := capture(req)
fmt.Println(len(data) > 0)
}
Output: true
func ResponseCaptureWithHeaderCensorshipFunction ¶
func ResponseCaptureWithHeaderCensorshipFunction(attemptCollectBody bool, headersToCensor []string, censorText string) func(*http.Response) ([]byte, error)
ResponseCaptureWithHeaderCensorshipFunction creates a function that captures HTTP responses. If headersToCensor is specified, the returned function will temporarily replace those header values with censorText during capture.
Example ¶
package main
import (
"fmt"
"io"
"net/http"
"net/http/httptest"
"strings"
"github.com/angrifel/unapologetic/httpspy"
)
func main() {
capture := httpspy.ResponseCaptureWithHeaderCensorshipFunction(true, []string{"set-cookie"}, "[REDACTED]")
resp := &http.Response{
StatusCode: 200,
Status: "200 OK",
Proto: "HTTP/1.1",
ProtoMajor: 1,
ProtoMinor: 1,
ContentLength: 13,
Header: http.Header{
"Content-Type": []string{"text/plain"},
"Set-Cookie": []string{"session=abc123"},
},
Body: io.NopCloser(strings.NewReader("response body")),
Request: httptest.NewRequest("GET", "https://example.com", nil),
}
data, _ := capture(resp)
fmt.Println(strings.Contains(string(data), "[REDACTED]"))
fmt.Println(!strings.Contains(string(data), "session=abc123"))
fmt.Println(strings.Contains(string(data), "response body"))
}
Output: true true true
Types ¶
This section is empty.