+85
appview/state/git_http.go
+85
appview/state/git_http.go
···
1
+
package state
2
+
3
+
import (
4
+
"fmt"
5
+
"io"
6
+
"net/http"
7
+
8
+
"github.com/bluesky-social/indigo/atproto/identity"
9
+
"github.com/go-chi/chi/v5"
10
+
)
11
+
12
+
func (s *State) InfoRefs(w http.ResponseWriter, r *http.Request) {
13
+
user := r.Context().Value("resolvedId").(identity.Identity)
14
+
knot := r.Context().Value("knot").(string)
15
+
repo := chi.URLParam(r, "repo")
16
+
17
+
// TODO: make this https for production!
18
+
targetURL := fmt.Sprintf("http://%s/%s/%s/info/refs?%s", knot, user.DID, repo, r.URL.RawQuery)
19
+
resp, err := http.Get(targetURL)
20
+
if err != nil {
21
+
http.Error(w, err.Error(), http.StatusInternalServerError)
22
+
return
23
+
}
24
+
defer resp.Body.Close()
25
+
26
+
// Copy response headers
27
+
for k, v := range resp.Header {
28
+
w.Header()[k] = v
29
+
}
30
+
31
+
// Set response status code
32
+
w.WriteHeader(resp.StatusCode)
33
+
34
+
// Copy response body
35
+
if _, err := io.Copy(w, resp.Body); err != nil {
36
+
http.Error(w, err.Error(), http.StatusInternalServerError)
37
+
return
38
+
}
39
+
40
+
}
41
+
42
+
func (s *State) UploadPack(w http.ResponseWriter, r *http.Request) {
43
+
user, ok := r.Context().Value("resolvedId").(identity.Identity)
44
+
if !ok {
45
+
http.Error(w, "failed to resolve user", http.StatusInternalServerError)
46
+
return
47
+
}
48
+
knot := r.Context().Value("knot").(string)
49
+
repo := chi.URLParam(r, "repo")
50
+
// TODO: make this https for production!
51
+
targetURL := fmt.Sprintf("http://%s/%s/%s/git-upload-pack?%s", knot, user.DID, repo, r.URL.RawQuery)
52
+
client := &http.Client{}
53
+
54
+
// Create new request
55
+
proxyReq, err := http.NewRequest(r.Method, targetURL, r.Body)
56
+
if err != nil {
57
+
http.Error(w, err.Error(), http.StatusInternalServerError)
58
+
return
59
+
}
60
+
61
+
// Copy original headers
62
+
proxyReq.Header = r.Header
63
+
64
+
// Execute request
65
+
resp, err := client.Do(proxyReq)
66
+
if err != nil {
67
+
http.Error(w, err.Error(), http.StatusInternalServerError)
68
+
return
69
+
}
70
+
defer resp.Body.Close()
71
+
72
+
// Copy response headers
73
+
for k, v := range resp.Header {
74
+
w.Header()[k] = v
75
+
}
76
+
77
+
// Set response status code
78
+
w.WriteHeader(resp.StatusCode)
79
+
80
+
// Copy response body
81
+
if _, err := io.Copy(w, resp.Body); err != nil {
82
+
http.Error(w, err.Error(), http.StatusInternalServerError)
83
+
return
84
+
}
85
+
}
+2
-2
appview/state/middleware.go
+2
-2
appview/state/middleware.go
···
131
131
})
132
132
}
133
133
134
-
func ResolveRepoDomain(s *State) Middleware {
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
-
ctx := context.WithValue(req.Context(), "domain", repo.Knot)
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
+2
-2
appview/state/repo.go
···
14
14
ctx := r.Context()
15
15
repoName := chi.URLParam(r, "repo")
16
16
17
-
domain, ok := ctx.Value("domain").(string)
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
-
resp, err := http.Get(fmt.Sprintf("http://%s/%s/%s", domain, id.DID.String(), repoName))
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
+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
-
r.With(ResolveRepoDomain(s)).Route("/{repo}", func(r chi.Router) {
602
+
r.With(ResolveRepoKnot(s)).Route("/{repo}", func(r chi.Router) {
603
603
r.Get("/", s.RepoIndex)
604
-
// r.Get("/info/refs", s.InfoRefs)
604
+
// These routes get proxied to the knot
605
+
r.Get("/info/refs", s.InfoRefs)
606
+
r.Post("/git-upload-pack", s.UploadPack)
605
607
})
606
608
})
607
609