Skip to content

Commit bf078b6

Browse files
authored
Merge pull request #6 from sktan/bugfix/js_and_dotnet
Fixing issues with concurrent reads and writes + redirects to S3 pre-signed URLs
2 parents 5614e92 + 32e3864 commit bf078b6

5 files changed

Lines changed: 41 additions & 22 deletions

File tree

.devcontainer/Dockerfile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
FROM mcr.microsoft.com/vscode/devcontainers/go:1.18
1+
FROM mcr.microsoft.com/devcontainers/go:1.18
22
ENV EDITOR=vim
33

44
RUN apt-get update && export DEBIAN_FRONTEND=noninteractive && \

.devcontainer/devcontainer.json

Lines changed: 19 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,27 +1,31 @@
11
{
22
"build": {
3-
"dockerfile": "Dockerfile",
3+
"dockerfile": "Dockerfile"
44
},
5-
"extensions": [
6-
"eamodio.gitlens",
7-
"golang.Go",
8-
"ms-python.python",
9-
"ms-python.vscode-pylance",
10-
"GitHub.copilot",
11-
"mutantdino.resourcemonitor"
12-
],
13-
"settings": {
14-
"resmon.show.battery": false,
15-
"resmon.show.cpufreq": false
5+
"customizations": {
6+
"vscode": {
7+
"extensions": [
8+
"eamodio.gitlens",
9+
"golang.Go",
10+
"ms-python.python",
11+
"ms-python.vscode-pylance",
12+
"GitHub.copilot",
13+
"mutantdino.resourcemonitor"
14+
],
15+
"settings": {
16+
"resmon.show.battery": false,
17+
"resmon.show.cpufreq": false
18+
}
19+
}
1620
},
1721
"mounts": [
18-
"source=${localEnv:HOME}${localEnv:USERPROFILE}/.aws/,target=/root/.aws,type=bind,consistency=cached"
22+
"source=${localEnv:HOME}${localEnv:USERPROFILE}/.aws/,target=/home/vscode/.aws,type=bind,consistency=cached"
1923
],
2024
"remoteEnv": {
2125
"AWS_DEFAULT_REGION": "ap-southeast-2",
2226
"AWS_PROFILE": "sktansandbox",
2327
"CODEARTIFACT_DOMAIN": "sktansandbox",
24-
"CODEARTIFACT_REPO": "sandbox",
28+
"CODEARTIFACT_REPO": "sandbox"
2529
},
2630
"features": {
2731
// Used build and deploy docker containers
@@ -33,7 +37,7 @@
3337
"aws-cli": "latest",
3438
// Testing out the proxy mechanism and for deploying via CDK
3539
"python": {
36-
"version": "lts",
40+
"version": "lts"
3741
},
3842
"node": {
3943
"version": "lts",

.pre-commit-config.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,4 +11,4 @@ repos:
1111
rev: 22.3.0
1212
hooks:
1313
- id: black
14-
language_version: python3.10
14+
language_version: python3.11

src/tools/aws.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,8 @@ func Authenticate() {
6464
log.Fatalf("unable to get authorization token, %v", authErr)
6565
}
6666
log.Printf("Authorization successful")
67+
68+
mutex.Lock()
6769
CodeArtifactAuthInfo.AuthorizationToken = *authResp.AuthorizationToken
6870
CodeArtifactAuthInfo.LastAuth = time.Now()
6971

@@ -82,6 +84,7 @@ func Authenticate() {
8284
log.Fatalf("unable to get repository endpoint, %v", urlErr)
8385
}
8486
CodeArtifactAuthInfo.Url = *urlResp.RepositoryEndpoint
87+
mutex.Unlock()
8588

8689
log.Printf("Requests will now be proxied to %s", CodeArtifactAuthInfo.Url)
8790
}

src/tools/proxy.go

Lines changed: 17 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -11,13 +11,16 @@ import (
1111
"net/url"
1212
"strconv"
1313
"strings"
14+
"sync"
1415
)
1516

1617
var 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
1921
func 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

4751
func 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

Comments
 (0)