1package state
2
3import (
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
12func (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 scheme := "https"
18 if s.config.Core.Dev {
19 scheme = "http"
20 }
21
22 targetURL := fmt.Sprintf("%s://%s/%s/%s/info/refs?%s", scheme, knot, user.DID, repo, r.URL.RawQuery)
23 s.proxyRequest(w, r, targetURL)
24
25}
26
27func (s *State) UploadPack(w http.ResponseWriter, r *http.Request) {
28 user, ok := r.Context().Value("resolvedId").(identity.Identity)
29 if !ok {
30 http.Error(w, "failed to resolve user", http.StatusInternalServerError)
31 return
32 }
33 knot := r.Context().Value("knot").(string)
34 repo := chi.URLParam(r, "repo")
35
36 scheme := "https"
37 if s.config.Core.Dev {
38 scheme = "http"
39 }
40
41 targetURL := fmt.Sprintf("%s://%s/%s/%s/git-upload-pack?%s", scheme, knot, user.DID, repo, r.URL.RawQuery)
42 s.proxyRequest(w, r, targetURL)
43}
44
45func (s *State) ReceivePack(w http.ResponseWriter, r *http.Request) {
46 user, ok := r.Context().Value("resolvedId").(identity.Identity)
47 if !ok {
48 http.Error(w, "failed to resolve user", http.StatusInternalServerError)
49 return
50 }
51 knot := r.Context().Value("knot").(string)
52 repo := chi.URLParam(r, "repo")
53
54 scheme := "https"
55 if s.config.Core.Dev {
56 scheme = "http"
57 }
58
59 targetURL := fmt.Sprintf("%s://%s/%s/%s/git-receive-pack?%s", scheme, knot, user.DID, repo, r.URL.RawQuery)
60 s.proxyRequest(w, r, targetURL)
61}
62
63func (s *State) proxyRequest(w http.ResponseWriter, r *http.Request, targetURL string) {
64 client := &http.Client{}
65
66 // Create new request
67 proxyReq, err := http.NewRequest(r.Method, targetURL, r.Body)
68 if err != nil {
69 http.Error(w, err.Error(), http.StatusInternalServerError)
70 return
71 }
72
73 // Copy original headers
74 proxyReq.Header = r.Header
75
76 repoOwnerHandle := chi.URLParam(r, "user")
77 proxyReq.Header.Add("x-tangled-repo-owner-handle", repoOwnerHandle)
78
79 // Execute request
80 resp, err := client.Do(proxyReq)
81 if err != nil {
82 http.Error(w, err.Error(), http.StatusInternalServerError)
83 return
84 }
85 defer resp.Body.Close()
86
87 // Copy response headers
88 for k, v := range resp.Header {
89 w.Header()[k] = v
90 }
91
92 // Set response status code
93 w.WriteHeader(resp.StatusCode)
94
95 // Copy response body
96 if _, err := io.Copy(w, resp.Body); err != nil {
97 http.Error(w, err.Error(), http.StatusInternalServerError)
98 return
99 }
100}