cdp-proxy: Chrome DevTools proxy and middleware for Go

Leveraging Chrome DevTools for HTTP middleware observability and building a HTTP reverse|forward proxy with Go.

TLDR

cdp-proxy project is 2 things:

  1. a reverse|forward proxy with cdp-proxy executable
  2. 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

  1. download: go get github.com/gmarik/cdp-proxy/main/cdp-proxy
  2. install: go install github.com/gmarik/cdp-proxy/main/cdp-proxy
  3. run: cdp-proxy
  4. proxy is now listening on port 8080
  5. 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

  1. type chrome://inspect in Chrome’s address bar
  2. locate cdp-proxy in the list of the inspect-able targets, press inspect

inspector

Proxy-ing requests

using the curl:

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

cdp-proxy: a Go HTTP middleware

Using the HTTP middleware in your project is as easy as:

  1. adding cdp-proxy as a dependency
  2. hooking up to your middleware
  3. 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!

  1. Chrome DevTools doesn’t reconnect automatically
  2. Everything is stored in memory and inspection is equally a memory leak if done for too long
  3. No sampling: not recommended on high traffic endpoints yet
  4. TLS proxy is WIP
  5. logs are a mess

References

PS

Give it a try and let me know know what you think. For updates and questions follow @gmarik on twitter

Related Posts
Read More
12 factor configuration with Go's `flag` package
Comments
read or add one↓