Package httpretty prints the HTTP requests you make with Go pretty on your terminal.

httpretty

GoDoc Build Status Coverage Status Go Report Card CII Best Practices

Package httpretty prints the HTTP requests of your Go programs pretty on your terminal screen. It is mostly inspired in curl's --verbose mode, and also on the httputil.DumpRequest and similar functions.

asciicast

Setting up a logger

You can define a logger with something like

logger := &httpretty.Logger{
	Time:           true,
	TLS:            true,
	RequestHeader:  true,
	RequestBody:    true,
	ResponseHeader: true,
	ResponseBody:   true,
	Colors:         true, // erase line if you don't like colors
	Formatters:     []httpretty.Formatter{&httpretty.JSONFormatter{}},
}

This code will set up a logger with sane settings. By default the logger prints nothing but the request line (and the remote address, when using it on the server-side).

Using on the client-side

You can set the transport for the *net/http.Client you are using like this:

client := &http.Client{
	Transport: logger.RoundTripper(http.DefaultTransport),
}

// from now on, you can use client.Do, client.Get, etc. to create requests.

If you don't care about setting a new client, you can safely replace your existing http.DefaultClient with this:

http.DefaultClient.Transport = logger.RoundTripper(http.DefaultClient.Transport)

Then httpretty is going to print information about regular requests to your terminal when code such as this is called:

if _, err := http.Get("https://www.google.com/"); err != nil {
        fmt.Fprintf(os.Stderr, "%+v\n", err)
        os.Exit(1)
}

However, have in mind you usually want to use a custom *http.Client to control things such as timeout.

Logging on the server-side

You can use the logger quickly to log requests on your server. For example:

logger.Middleware(mux)

The handler should by a http.Handler. Usually, you want this to be your http.ServeMux HTTP entrypoint.

For working examples, please see the example directory.

Filtering

You have two ways to filter a request so it isn't printed by the logger.

httpretty.WithHide

You can filter any request by setting a request context before the request reaches httpretty.RoundTripper:

req = req.WithContext(httpretty.WithHide(ctx))

Filter function

A second option is to implement

type Filter func(req *http.Request) (skip bool, err error)

and set it as the filter for your logger. For example:

logger.SetFilter(func filteredURIs(req *http.Request) (bool, error) {
	if req.Method != http.MethodGet {
		return true, nil
	}

	if path := req.URL.Path; path == "/debug" || strings.HasPrefix(path, "/debug/") {
		return true, nil
	}

	return false
})

Formatters

You can define a formatter for any media type by implementing the Formatter interface.

We provide a JSONFormatter for convenience (it is not enabled by default).

Owner
Henrique Vicente
Senior Software Engineer
Henrique Vicente
Comments
  • Fix tests for architectures without AES hardware support

    Fix tests for architectures without AES hardware support

    https://github.com/golang/go/blob/4aa1efed4853ea067d665a952eee77c52faac774/src/crypto/tls/cipher_suites.go#L342-L355

    Starting with Go 1.16, ChaCha (TLS_CHACHA20_POLY1305_SHA256) is picked over AES (TLS_AES_128_GCM_SHA256) for TLS 1.3 on machines that do not have AES hardware support, e.g. on armhf, 386 and ppc64le, as caught by Debian autopkgtest for golang-github-henvic-httpretty/0.0.6-2 between November 2021 and March 2022.

    The test failure can be reproduced locally with GOARCH=386 go test ./...

    Reference code for different preferred TLS 1.3 ciphers in Go 1.18: https://github.com/golang/go/blob/go1.18/src/crypto/tls/cipher_suites.go#L342-L367 https://github.com/golang/go/blob/go1.18/src/crypto/tls/handshake_client.go#L124-L129

    This commit accommodates TLS_CHACHA20_POLY1305_SHA256 in addition to TLS_AES_128_GCM_SHA256 in the TLS 1.3 tests.

  • Request path interpreted as format string

    Request path interpreted as format string

    Making a request with a query parameter with value foo & bar results in something like this being printed:

    > POST /mypath?label=foo+%!+(MISSING)bar HTTP/1.1
    

    This is because the & character gets %-encoded when in a URL, and color.Format() interprets anything passed to it as a format string. Any value that could potentially have a literal % character in it (any dynamic or user-defined value, really) should never be used a sprintf format string.

  • Response without Content-Length might not print completely

    Response without Content-Length might not print completely

    io.ReadFull should be used instead of calling *bufio.Reader.Read when getting content to print from on the logger printer, as more than one Read call might be required to fill the whole printing buffer.

  • Let user hide unwanted headers

    Let user hide unwanted headers

    On https://github.com/cli/cli/pull/306#pullrequestreview-361869659 @mislav asked me for

    a way to avoid certain request/response headers being printed; perhaps accept a func that takes a header name and returns a boolean that indicates whether to print or not?

    This might be achieved with a function similar to SetFilter and SetBodyFilter. It might take a slice and store the data in a map[string]struct{} to be checked when printing headers.

    Probably can be called FilterHeader or FilterHeaders.

  • TestOutgoingTLSBadClientCertificate seems flaky on Travis CI

    TestOutgoingTLSBadClientCertificate seems flaky on Travis CI

    From https://travis-ci.org/henvic/httpretty/jobs/645236419

    --- FAIL: TestOutgoingTLSBadClientCertificate (0.03s)
    262    client_test.go:1411: logged HTTP request * Request to https://127.0.0.1:35251
    263        * Client certificate:
    264        *  subject: CN=User,OU=User,O=Client,L=Rotterdam,ST=Zuid-Holland,C=NL
    265        *  start date: Sat Jan 25 20:12:36 UTC 2020
    266        *  expire date: Mon Jan  1 20:12:36 UTC 2120
    267        *  issuer: CN=User,OU=User,O=Client,L=Rotterdam,ST=Zuid-Holland,C=NL
    268        > GET / HTTP/1.1
    269        > Host: example.com
    270        > User-Agent: Robot/0.1 [email protected]
    271        
    272        * readLoopPeekFailLocked: remote error: tls: bad certificate
    273        ; want * Request to https://127.0.0.1:35251
    274        * Client certificate:
    275        *  subject: CN=User,OU=User,O=Client,L=Rotterdam,ST=Zuid-Holland,C=NL
    276        *  start date: Sat Jan 25 20:12:36 UTC 2020
    277        *  expire date: Mon Jan  1 20:12:36 UTC 2120
    278        *  issuer: CN=User,OU=User,O=Client,L=Rotterdam,ST=Zuid-Holland,C=NL
    279        > GET / HTTP/1.1
    280        > Host: example.com
    281        > User-Agent: Robot/0.1 [email protected]
    282        
    283        * remote error: tls: bad certificate
    
  • tests: fix tests broken due to TLS CommonName deprecation.

    tests: fix tests broken due to TLS CommonName deprecation.

    CN has been deprecated for 20 years now, but I relied on it for the certificates generated with openssl.

    Go 1.15 crypto/x509 is dropping support for it.

    The environment variable GODEBUG=x509ignoreCN=0 is required for it to work now (until Go 1.16).

    No production code was affected by this change as x509.*Certificate.VerifyHostname is used directly there to retrieve TLS hostname details.

    Related: https://github.com/golang/go/issues/39568#issuecomment-671424481 https://go-review.googlesource.com/c/go/+/243221

    See also: Extended Key Usage section of x509v3_config Let's Encrypt Making and trusting your own certificates

  • Don't try to print logs for mediatypes such as application/octet-stream, images, etc.

    Don't try to print logs for mediatypes such as application/octet-stream, images, etc.

    This can be done both by identifying Content-Type and by inspecting file magic numbers to identify if a file is "binary" or not. Decide what to use (probably both).

    Maybe we can introduce an internal Formatter implementation that identifies the file by matching mime-type and this might be good at first (and use a second step to identify other cases to avoid printing rubbish). However, we might want to identify it earlier and avoid some processing.

  • Custom header sanitization

    Custom header sanitization

    I have a module that calls an API with a custom authorization header. I would like to sanitize it rather than hide it, but currently doesn't appear I can do so. The ability to add additional headers for sanitization would be a great addition.

Related tags
gh is GitHub on the command line. It brings pull requests, issues, and other GitHub concepts to the terminal next to where you are already working with git and your code
gh is GitHub on the command line. It brings pull requests, issues, and other GitHub concepts to the terminal next to where you are already working with git and your code

gh is GitHub on the command line. It brings pull requests, issues, and other GitHub concepts to the terminal next to where you are already working with git and your code

Jan 24, 2022
🍬 Pretty Treemaps

?? Pretty Treemaps $ go install github.com/nikolaydubina/treemap/cmd/treemap@latest $ echo ' Africa/Algeria,33333216,72 Africa/Angola,12420476,42 Afr

Dec 28, 2022
Service that calls uzma24/project1 service, takes input from .txt file and prints JSON output returned from the service.

Service that calls uzma24/project1 service, takes input from .txt file and prints JSON output returned from the service. Program can take large input files.

Feb 6, 2022
An easy HTTP client for Go. Inspired by the immortal Requests.

rek An easy HTTP client for Go inspired by Requests, plus all the Go-specific goodies you'd hope for in a client. Here's an example: // GET request re

Sep 20, 2022
A tool that makes http requests and outputs the url and the content (optionally to file)

BKK Basic Crawler A tool that makes http requests and outputs the url and the content (optionally to file) How to run.. the tests go test the compiler

Nov 8, 2021
viagh.NewHTTPClient returns a *http.Client that makes API requests via the gh command.

viagh viagh.NewHTTPClient returns a *http.Client that makes API requests via the gh command. Why viagh? When writing a GitHub CLI extension, the exten

Dec 24, 2021
Application to shut down a machine using HTTP requests.

shutdownd Service to shut down a system using HTTP requests. Usage Here's a quick example of how you can use this software on Linux. Download or build

Nov 15, 2021
HTTP requests for Gophers
HTTP requests for Gophers

Requests HTTP requests for Gophers. The problem: Go's net/http is powerful and versatile, but using it correctly for client requests can be extremely

Dec 26, 2022
A http-relay server/client written in golang to forward requests to a service behind a nat router from web

http-relay This repo is WIP http-relay is a server/client application written in go(lang) to forward http(s) requests to an application behind a nat r

Dec 16, 2021
Small round tripper to avoid triggering the "attention required" status of CloudFlare for HTTP requests
Small round tripper to avoid triggering the

CloudFlare-ByPass-Go. Small round tripper to avoid triggering the "attention req

Nov 14, 2022
Mar 21, 2022
This is a tool that will proxy simple HTTPS requests to an external HTTP endpoint
 This is a tool that will proxy simple HTTPS requests to an external HTTP endpoint

AcmeShield A secured HTTP proxy that forwards requests from a remote service(Postman). This is a tool that will proxy simple HTTPS requests to an exte

Mar 21, 2022
A Caddy v2 extension to apply rate-limiting for HTTP requests

ratelimit A Caddy v2 extension to apply rate-limiting for HTTP requests. Installation $ xcaddy build --with github.com/owlwang/caddy-ratelimit Caddyfi

Jan 28, 2022
It is a proxy to improve article readability, a directory for your favorite articles, and a way to make the internet lighter and more accessible.

timoneiro It is a work in progress. Some features are unimplemented yet. The helmsman's goal is to be a way to browse articles without all the distrac

Jun 13, 2022
JPRQ Customizer is a customizer that helps to use the JPRQ server code and make it compatible with your own server with custom subdomain and domain
JPRQ Customizer is a customizer that helps to use the JPRQ server code and make it compatible with your own server with custom subdomain and domain

JPRQ Customizer is a customizer that helps to use the JPRQ server code and make it compatible with your own server with custom subdomain and domain.You can upload the generated directory to your web server and expose user localhost to public internet. You can use this to make your local machine a command center for your ethical hacking purpose ;)

Jan 19, 2022
Fast HTTP package for Go. Tuned for high performance. Zero memory allocations in hot paths. Up to 10x faster than net/http
Fast HTTP package for Go. Tuned for high performance. Zero memory allocations in hot paths. Up to 10x faster than net/http

fasthttp Fast HTTP implementation for Go. Currently fasthttp is successfully used by VertaMedia in a production serving up to 200K rps from more than

Jan 5, 2023
Send email and SMS broadcasts to your contacts. SMS are sent via your Android phone connected to your PC.

Polysender Send email and SMS broadcasts to your contacts. Polysender is a desktop application, so it does not require a complicated server setup. Ema

Aug 11, 2022
Simple application in Golang that retrieves your ip and updates your DNS entries automatically each time your IP changes.

DNS-Updater Simple application in Golang that retrieves your ip and updates your DNS entries automatically each time your IP changes. Motivation Havin

Mar 10, 2022
Use ICMP requests to check the alive subnet.

Doge-AliveCheck Use ICMP requests to check the alive subnet. Build go build -ldflags "-s -w" -trimpath Usage Doge-AliveCheck.exe

Nov 11, 2022