@@ -13,6 +13,7 @@ import (
1313 "time"
1414
1515 "github.com/eko/gocache/cache"
16+ "github.com/gitpod-io/gitpod/common-go/experiments"
1617 "github.com/gitpod-io/gitpod/common-go/log"
1718 "github.com/sirupsen/logrus"
1819 "golang.org/x/xerrors"
@@ -21,20 +22,49 @@ import (
2122const (
2223 REQUEST_CACHE_KEY_CTX = "gitpod-cache-key"
2324 REQUEST_ID_CTX = "gitpod-request-id"
25+ UPSTREAM_CTX = "gitpod-upstream"
2426 LOG_FIELD_REQUEST_ID = "request_id"
2527 LOG_FIELD_REQUEST = "request"
2628 LOG_FIELD_FUNC = "func"
2729 LOG_FIELD_STATUS = "status"
2830)
2931
3032type OpenVSXProxy struct {
31- Config * Config
32- upstreamURL * url.URL
33- cacheManager * cache.Cache
34- metrics * Prometheus
33+ Config * Config
34+ defaultUpstreamURL * url.URL
35+ cacheManager * cache.Cache
36+ metrics * Prometheus
37+ experiments experiments.Client
38+ }
39+
40+ func (o * OpenVSXProxy ) GetUpstreamUrl (r * http.Request ) * url.URL {
41+ reqid := r .Context ().Value (REQUEST_ID_CTX ).(string )
42+
43+ clientID := r .Header .Get ("x-market-client-id" )
44+ ctx , cancel := context .WithTimeout (context .Background (), time .Second )
45+ defer cancel ()
46+ upstream := o .experiments .GetStringValue (ctx , "openvsx_proxy_upstream" , o .Config .URLUpstream , experiments.Attributes {
47+ UserID : reqid ,
48+ VSCodeClientID : clientID ,
49+ })
50+ upstreamUrl , err := url .Parse (upstream )
51+ if err != nil {
52+ return o .defaultUpstreamURL
53+ }
54+ return upstreamUrl
55+ }
56+
57+ func (o * OpenVSXProxy ) IsDisabledCache (u * url.URL ) bool {
58+ for _ , v := range o .Config .AllowCacheDomain {
59+ if strings .ToLower (u .Host ) == v {
60+ return false
61+ }
62+ }
63+ return true
3564}
3665
3766func (o * OpenVSXProxy ) Setup () error {
67+ o .experiments = experiments .NewClient ()
3868 o .metrics = & Prometheus {}
3969 o .metrics .Start (o .Config )
4070
@@ -43,7 +73,7 @@ func (o *OpenVSXProxy) Setup() error {
4373 return xerrors .Errorf ("error setting up cache: %v" , err )
4474 }
4575
46- o .upstreamURL , err = url .Parse (o .Config .URLUpstream )
76+ o .defaultUpstreamURL , err = url .Parse (o .Config .URLUpstream )
4777 if err != nil {
4878 return xerrors .Errorf ("error parsing upstream URL: %v" , err )
4979 }
@@ -54,12 +84,12 @@ func (o *OpenVSXProxy) Setup() error {
5484}
5585
5686func (o * OpenVSXProxy ) Start () (shutdown func (context.Context ) error , err error ) {
57- if o .upstreamURL == nil {
87+ if o .defaultUpstreamURL == nil {
5888 if err := o .Setup (); err != nil {
5989 return nil , err
6090 }
6191 }
62- proxy := newSingleHostReverseProxy (o . upstreamURL )
92+ proxy := newSingleHostReverseProxy ()
6393 proxy .ErrorHandler = o .ErrorHandler
6494 proxy .ModifyResponse = o .ModifyResponse
6595 proxy .Transport = & DurationTrackingTransport {o : o }
@@ -94,7 +124,7 @@ type DurationTrackingTransport struct {
94124
95125func (t * DurationTrackingTransport ) RoundTrip (r * http.Request ) (* http.Response , error ) {
96126 reqid := r .Context ().Value (REQUEST_ID_CTX ).(string )
97- key := r .Context ().Value (REQUEST_CACHE_KEY_CTX ).(string )
127+ key , _ := r .Context ().Value (REQUEST_CACHE_KEY_CTX ).(string )
98128
99129 logFields := logrus.Fields {
100130 LOG_FIELD_FUNC : "transport_roundtrip" ,
@@ -149,9 +179,11 @@ func joinURLPath(a, b *url.URL) (path, rawpath string) {
149179 return a .Path + b .Path , apath + bpath
150180}
151181
152- func newSingleHostReverseProxy (target * url.URL ) * httputil.ReverseProxy {
153- targetQuery := target .RawQuery
182+ func newSingleHostReverseProxy () * httputil.ReverseProxy {
154183 director := func (req * http.Request ) {
184+ target := req .Context ().Value (UPSTREAM_CTX ).(* url.URL )
185+ targetQuery := target .RawQuery
186+
155187 originalHost := req .Host
156188
157189 req .URL .Scheme = target .Scheme
0 commit comments