tangled
alpha
login
or
join now
tjh.dev
/
core
forked from
tangled.org/core
0
fork
atom
this repo has no description
0
fork
atom
overview
issues
pulls
pipelines
appview: proxy clones to knot
anirudh.fi
1 year ago
6a3761d7
f61b8874
+93
-6
4 changed files
expand all
collapse all
unified
split
appview
state
git_http.go
middleware.go
repo.go
state.go
+85
appview/state/git_http.go
···
1
1
+
package state
2
2
+
3
3
+
import (
4
4
+
"fmt"
5
5
+
"io"
6
6
+
"net/http"
7
7
+
8
8
+
"github.com/bluesky-social/indigo/atproto/identity"
9
9
+
"github.com/go-chi/chi/v5"
10
10
+
)
11
11
+
12
12
+
func (s *State) InfoRefs(w http.ResponseWriter, r *http.Request) {
13
13
+
user := r.Context().Value("resolvedId").(identity.Identity)
14
14
+
knot := r.Context().Value("knot").(string)
15
15
+
repo := chi.URLParam(r, "repo")
16
16
+
17
17
+
// TODO: make this https for production!
18
18
+
targetURL := fmt.Sprintf("http://%s/%s/%s/info/refs?%s", knot, user.DID, repo, r.URL.RawQuery)
19
19
+
resp, err := http.Get(targetURL)
20
20
+
if err != nil {
21
21
+
http.Error(w, err.Error(), http.StatusInternalServerError)
22
22
+
return
23
23
+
}
24
24
+
defer resp.Body.Close()
25
25
+
26
26
+
// Copy response headers
27
27
+
for k, v := range resp.Header {
28
28
+
w.Header()[k] = v
29
29
+
}
30
30
+
31
31
+
// Set response status code
32
32
+
w.WriteHeader(resp.StatusCode)
33
33
+
34
34
+
// Copy response body
35
35
+
if _, err := io.Copy(w, resp.Body); err != nil {
36
36
+
http.Error(w, err.Error(), http.StatusInternalServerError)
37
37
+
return
38
38
+
}
39
39
+
40
40
+
}
41
41
+
42
42
+
func (s *State) UploadPack(w http.ResponseWriter, r *http.Request) {
43
43
+
user, ok := r.Context().Value("resolvedId").(identity.Identity)
44
44
+
if !ok {
45
45
+
http.Error(w, "failed to resolve user", http.StatusInternalServerError)
46
46
+
return
47
47
+
}
48
48
+
knot := r.Context().Value("knot").(string)
49
49
+
repo := chi.URLParam(r, "repo")
50
50
+
// TODO: make this https for production!
51
51
+
targetURL := fmt.Sprintf("http://%s/%s/%s/git-upload-pack?%s", knot, user.DID, repo, r.URL.RawQuery)
52
52
+
client := &http.Client{}
53
53
+
54
54
+
// Create new request
55
55
+
proxyReq, err := http.NewRequest(r.Method, targetURL, r.Body)
56
56
+
if err != nil {
57
57
+
http.Error(w, err.Error(), http.StatusInternalServerError)
58
58
+
return
59
59
+
}
60
60
+
61
61
+
// Copy original headers
62
62
+
proxyReq.Header = r.Header
63
63
+
64
64
+
// Execute request
65
65
+
resp, err := client.Do(proxyReq)
66
66
+
if err != nil {
67
67
+
http.Error(w, err.Error(), http.StatusInternalServerError)
68
68
+
return
69
69
+
}
70
70
+
defer resp.Body.Close()
71
71
+
72
72
+
// Copy response headers
73
73
+
for k, v := range resp.Header {
74
74
+
w.Header()[k] = v
75
75
+
}
76
76
+
77
77
+
// Set response status code
78
78
+
w.WriteHeader(resp.StatusCode)
79
79
+
80
80
+
// Copy response body
81
81
+
if _, err := io.Copy(w, resp.Body); err != nil {
82
82
+
http.Error(w, err.Error(), http.StatusInternalServerError)
83
83
+
return
84
84
+
}
85
85
+
}
+2
-2
appview/state/middleware.go
···
131
131
})
132
132
}
133
133
134
134
-
func ResolveRepoDomain(s *State) Middleware {
134
134
+
func ResolveRepoKnot(s *State) Middleware {
135
135
return func(next http.Handler) http.Handler {
136
136
return http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) {
137
137
repoName := chi.URLParam(req, "repo")
···
150
150
return
151
151
}
152
152
153
153
-
ctx := context.WithValue(req.Context(), "domain", repo.Knot)
153
153
+
ctx := context.WithValue(req.Context(), "knot", repo.Knot)
154
154
next.ServeHTTP(w, req.WithContext(ctx))
155
155
})
156
156
}
+2
-2
appview/state/repo.go
···
14
14
ctx := r.Context()
15
15
repoName := chi.URLParam(r, "repo")
16
16
17
17
-
domain, ok := ctx.Value("domain").(string)
17
17
+
knot, ok := ctx.Value("knot").(string)
18
18
if !ok {
19
19
log.Println("malformed middleware")
20
20
w.WriteHeader(http.StatusInternalServerError)
···
28
28
return
29
29
}
30
30
31
31
-
resp, err := http.Get(fmt.Sprintf("http://%s/%s/%s", domain, id.DID.String(), repoName))
31
31
+
resp, err := http.Get(fmt.Sprintf("http://%s/%s/%s", knot, id.DID.String(), repoName))
32
32
if err != nil {
33
33
log.Println("failed to reach knotserver", err)
34
34
return
+4
-2
appview/state/state.go
···
599
599
600
600
r.With(ResolveIdent).Route("/{user}", func(r chi.Router) {
601
601
r.Get("/", s.ProfilePage)
602
602
-
r.With(ResolveRepoDomain(s)).Route("/{repo}", func(r chi.Router) {
602
602
+
r.With(ResolveRepoKnot(s)).Route("/{repo}", func(r chi.Router) {
603
603
r.Get("/", s.RepoIndex)
604
604
-
// r.Get("/info/refs", s.InfoRefs)
604
604
+
// These routes get proxied to the knot
605
605
+
r.Get("/info/refs", s.InfoRefs)
606
606
+
r.Post("/git-upload-pack", s.UploadPack)
605
607
})
606
608
})
607
609