Leveraging Chrome DevTools for HTTP middleware observability and building a HTTP reverse|forward proxy with Go.
TLDR
cdp-proxy project is 2 things:
- a reverse|forward proxy with cdp-proxy executable
- an
http.Handler
middleware to plug your Go project to Chrome DevTools
cdp-proxy is short for Chrome DevTools protocol.
cdp-proxy: a reverse|forward proxy
cdp-proxy executable is just like any other mitm style proxy: configure it as your HTTP proxy and you’ll get the requests showing up in Chrome DevTools. If you’re a developer and using Chrome you have likely used the UI before and proxy will be very familiar to you.
Running the proxy
- download:
go get github.com/gmarik/cdp-proxy/main/cdp-proxy
- install:
go install github.com/gmarik/cdp-proxy/main/cdp-proxy
- run:
cdp-proxy
- proxy is now listening on port
8080
- inspector is now listening on port
9229
$ cdp-proxy
2019/10/07 17:12:55 http.devtools: ListenAndServe.address="localhost:9229"
2019/10/07 17:12:55 http.proxy: ListenAndServe.address="localhost:8080"
Running the Chrome DevTools
- type
chrome://inspect
in Chrome’s address bar - locate
cdp-proxy
in the list of the inspect-able targets, press inspect
Proxy-ing requests
using the curl:
- for HTTP:
http_proxy=localhost:8080 curl http://www.google.com
- for HTTPS
https_proxy=localhost:8080 curl https://www.google.com
If you feel more courageous you can set it as system-wide proxy in your OSX – (TODO: details)
Inspecting requests
At this point you should be able to see the requests showing up in Chrome DevTools
cdp-proxy: a Go HTTP middleware
Using the HTTP middleware in your project is as easy as:
- adding
cdp-proxy
as a dependency - hooking up to your middleware
- exposing the inspector endpoint
here’s a hello world
snippet from an example
// ...
// an event bus to forward data to Chrome
var eb = httpcdp.NewEventBus()
go func() {
handler := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "text/plain")
fmt.Fprintf(w, "hello world")
})
log.Printf("http.proxy: ListenAndServe.address=%q", HTTP_Server_Addr)
if err := http.ListenAndServe(HTTP_Server_Addr, cdphttp.Handler(eb, handler)); err != nil {
log.Fatalf("http.proxy: ListenAndServe.error=%q", err)
}
}()
// ...
Similarly to proxy, requests made to the handler will show up in Chrome DevTools simplifying observability.
Known issues
TLDR: alpha quality!
- Chrome DevTools doesn’t reconnect automatically
- Everything is stored in memory and inspection is equally a memory leak if done for too long
- No sampling: not recommended on high traffic endpoints yet
- TLS proxy is WIP
- logs are a mess
References
- Chrome DevTools
- chromedp project
PS
Give it a try and let me know know what you think. For updates and questions follow @gmarik on twitter