@@ -11,13 +11,16 @@ import (
1111 "net/url"
1212 "strconv"
1313 "strings"
14+ "sync"
1415)
1516
1617var originalUrlResolver = make (map [string ]* url.URL )
18+ var mutex = & sync.Mutex {}
1719
1820// ProxyRequestHandler intercepts requests to CodeArtifact and add the Authorization header + correct Host header
1921func ProxyRequestHandler (p * httputil.ReverseProxy ) func (http.ResponseWriter , * http.Request ) {
2022 return func (w http.ResponseWriter , r * http.Request ) {
23+ mutex .Lock ()
2124 // Store the original host header for each request
2225 originalUrlResolver [r .RemoteAddr ] = r .URL
2326 originalUrlResolver [r .RemoteAddr ].Host = r .Host
@@ -39,33 +42,40 @@ func ProxyRequestHandler(p *httputil.ReverseProxy) func(http.ResponseWriter, *ht
3942 log .Printf ("REQ: %s %s \" %s\" \" %s\" " , r .RemoteAddr , r .Method , r .URL .RequestURI (), r .UserAgent ())
4043
4144 log .Printf ("Sending request to %s%s" , strings .Trim (CodeArtifactAuthInfo .Url , "/" ), r .URL .RequestURI ())
45+ mutex .Unlock ()
4246
4347 p .ServeHTTP (w , r )
4448 }
4549}
4650
4751func ProxyResponseHandler () func (* http.Response ) error {
4852 return func (r * http.Response ) error {
49- log .Printf ("Received response from %s" , r .Request .URL .String ())
53+ log .Printf ("Received %d response from %s" , r . StatusCode , r .Request .URL .String ())
5054 log .Printf ("RES: %s \" %s\" %d \" %s\" \" %s\" " , r .Request .RemoteAddr , r .Request .Method , r .StatusCode , r .Request .RequestURI , r .Request .UserAgent ())
5155
5256 contentType := r .Header .Get ("Content-Type" )
5357
58+ mutex .Lock ()
5459 originalUrl := originalUrlResolver [r .Request .RemoteAddr ]
5560 delete (originalUrlResolver , r .Request .RemoteAddr )
5661
5762 u , _ := url .Parse (CodeArtifactAuthInfo .Url )
5863 hostname := u .Host + ":443"
64+ mutex .Unlock ()
5965
6066 // Rewrite the 301 to point from CodeArtifact URL to the proxy instead..
6167 if r .StatusCode == 301 || r .StatusCode == 302 {
6268 location , _ := r .Location ()
6369
64- location .Host = originalUrl .Host
65- location .Scheme = originalUrl .Scheme
66- location .Path = strings .Replace (location .Path , u .Path , "" , 1 )
70+ // Only attempt to rewrite the location if the host matches the CodeArtifact host
71+ // Otherwise leave the original location intact (e.g a redirect to a S3 presigned URL)
72+ if location .Host == u .Host {
73+ location .Host = originalUrl .Host
74+ location .Scheme = originalUrl .Scheme
75+ location .Path = strings .Replace (location .Path , u .Path , "" , 1 )
6776
68- r .Header .Set ("Location" , location .String ())
77+ r .Header .Set ("Location" , location .String ())
78+ }
6979 }
7080
7181 // Do some quick fixes to the HTTP response for NPM install requests
@@ -90,11 +100,13 @@ func ProxyResponseHandler() func(*http.Response) error {
90100 oldContentResponse , _ := ioutil .ReadAll (body )
91101 oldContentResponseStr := string (oldContentResponse )
92102
103+ mutex .Lock ()
93104 resolvedHostname := strings .Replace (CodeArtifactAuthInfo .Url , u .Host , hostname , - 1 )
94105 newUrl := fmt .Sprintf ("%s://%s/" , originalUrl .Scheme , originalUrl .Host )
95106
96107 newResponseContent := strings .Replace (oldContentResponseStr , resolvedHostname , newUrl , - 1 )
97108 newResponseContent = strings .Replace (newResponseContent , CodeArtifactAuthInfo .Url , newUrl , - 1 )
109+ mutex .Unlock ()
98110
99111 r .Body = ioutil .NopCloser (strings .NewReader (newResponseContent ))
100112 r .ContentLength = int64 (len (newResponseContent ))
0 commit comments