Skip to content
This repository has been archived by the owner on Dec 29, 2023. It is now read-only.

Commit

Permalink
Added /storage Endpoint to proxy to storage.googleapis.com
Browse files Browse the repository at this point in the history
  • Loading branch information
tobias-kuendig committed Sep 29, 2021
1 parent 414f63a commit 517b495
Showing 1 changed file with 38 additions and 8 deletions.
46 changes: 38 additions & 8 deletions main.go
Original file line number Diff line number Diff line change
Expand Up @@ -45,10 +45,40 @@ type registryConfig struct {
repoPrefix string
}

// CDNHost is used to rewrite redirects for storage.googleapis.com to a custom CDN domain.
var CDNHost = os.Getenv("CDN_HOST")
type StorageProxy struct {
p *httputil.ReverseProxy
}

func (ph *StorageProxy) ServeHTTP(w http.ResponseWriter, r *http.Request) {
log.Println(r.URL)
log.Println(r.Header)
log.Println(r.Host)
log.Println(r.Method)


ph.p.ServeHTTP(w, r)
}

func main() {
remote, err := url.Parse("https://storage.googleapis.com")
if err != nil {
panic(err)
}

// Proxy /storage to storage.googleapis.com for image downlaods.
proxy := httputil.NewSingleHostReverseProxy(remote)
originalDirector := proxy.Director
proxy.Director = func(req *http.Request) {
originalDirector(req)
req.Host = "storage.googleapis.com"
req.URL.Path = strings.TrimPrefix(req.URL.Path, "/storage")
}
proxy.ModifyResponse = func(r *http.Response) error {
// Ensure "transfer-encoding: chunked" as Google Cloud Run only allows 32 MB responses if they are not chunked.
r.Header.Del("content-length")
return nil
}

port := os.Getenv("PORT")
if port == "" {
log.Fatal("PORT environment variable not specified")
Expand Down Expand Up @@ -95,6 +125,7 @@ func main() {
mux.Handle("/_token", tokenProxyHandler(tokenEndpoint, repoPrefix))
}
mux.Handle("/v2/", registryAPIProxy(reg, auth))
mux.Handle("/storage/", &StorageProxy{proxy})

addr := ":" + port
handler := captureHostHeader(mux)
Expand Down Expand Up @@ -247,23 +278,22 @@ func (rrt *registryRoundtripper) RoundTrip(req *http.Request) (*http.Response, e
}

updateTokenEndpoint(resp, origHost)
if CDNHost != "" {
updateLocationHeader(resp)
}
updateLocationHeader(resp, origHost)
return resp, nil
}

// updateLocationHeader modifies the response header like:
// Location: https://storage.googleapis.com/xyz
// to point to a custom CDN location.
func updateLocationHeader(resp *http.Response) {
// to point to the internal Google Cloud Storage proxy under /storage
func updateLocationHeader(resp *http.Response, host string) {
replace := "https://storage.googleapis.com"
v := resp.Header.Get("Location")
if v == "" {
return
}
if strings.HasPrefix(v, replace) {
resp.Header.Set("Location", strings.Replace(v, replace, CDNHost, 1))
newHost := fmt.Sprintf("https://%s/storage", host)
resp.Header.Set("Location", strings.Replace(v, replace, newHost, 1))
}
}

Expand Down

0 comments on commit 517b495

Please sign in to comment.