Skip to content

Commit

Permalink
http: implement /proxy/{id} to proxy requests to chromium
Browse files Browse the repository at this point in the history
  • Loading branch information
nadiamoe committed Jul 23, 2024
1 parent ab4a94a commit 2df8a29
Show file tree
Hide file tree
Showing 3 changed files with 47 additions and 0 deletions.
5 changes: 5 additions & 0 deletions go.mod
Original file line number Diff line number Diff line change
@@ -1,3 +1,8 @@
module github.com/grafana/crocochrome

go 1.22

require (
github.com/gorilla/websocket v1.5.3 // indirect
github.com/koding/websocketproxy v0.0.0-20181220232114-7ed82d81a28c // indirect
)
4 changes: 4 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
github.com/gorilla/websocket v1.5.3 h1:saDtZ6Pbx/0u+bgYQ3q96pZgCzfhKXGPqt7kZ72aNNg=
github.com/gorilla/websocket v1.5.3/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
github.com/koding/websocketproxy v0.0.0-20181220232114-7ed82d81a28c h1:N7A4JCA2G+j5fuFxCsJqjFU/sZe0mj8H0sSoSwbaikw=
github.com/koding/websocketproxy v0.0.0-20181220232114-7ed82d81a28c/go.mod h1:Nn5wlyECw3iJrzi0AhIWg+AJUb4PlRQVW4/3XHH1LZA=
38 changes: 38 additions & 0 deletions http/http.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import (
"net/url"

"github.com/grafana/crocochrome"
"github.com/koding/websocketproxy"
)

type Server struct {
Expand All @@ -28,6 +29,7 @@ func New(logger *slog.Logger, supervisor *crocochrome.Supervisor) *Server {
mux.HandleFunc("GET /sessions", api.List)
mux.HandleFunc("POST /sessions", api.Create)
mux.HandleFunc("DELETE /sessions/{id}", api.Delete)
mux.HandleFunc("/proxy/{id}", api.Proxy)

return api
}
Expand Down Expand Up @@ -82,6 +84,42 @@ func (s *Server) Delete(rw http.ResponseWriter, r *http.Request) {
}
}

// Proxy checks an open session for the given session ID (from path) and proxies the request to the URL present in that
// session.
// This is needed as recent versions of chromium do not support listening in addresses other than localhost, so to make
// chromium reachable from the outside we need to proxy it.
func (s *Server) Proxy(rw http.ResponseWriter, r *http.Request) {
sessionID := r.PathValue("id")
if sessionID == "" {
rw.WriteHeader(http.StatusBadRequest)
return
}

sessionInfo := s.supervisor.Session(sessionID)
if sessionInfo == nil {
s.logger.Warn("sessionID not found", "sessionID", sessionID)
rw.WriteHeader(http.StatusNotFound)
return
}

rawUrl := sessionInfo.ChromiumVersion.WebSocketDebuggerURL
chromiumURL, err := url.Parse(rawUrl)
if err != nil {
s.logger.Warn("could not parse ws URL form chromium response", "sessionID", sessionID, "url", rawUrl, "err", err)
rw.WriteHeader(http.StatusInternalServerError)
return
}

s.logger.Debug("Proxying WS connection", "sessionID", sessionID, "chromiumURL", rawUrl)

wsp := websocketproxy.WebsocketProxy{
Backend: func(r *http.Request) *url.URL {
return chromiumURL
},
}
wsp.ServeHTTP(rw, r)
}

// replaceHost returns a new url with its hostname replaced with host. The port is kept as it is.
func replaceHost(urlStr, host string) (string, error) {
parsedURL, err := url.Parse(urlStr)
Expand Down

0 comments on commit 2df8a29

Please sign in to comment.