Monorepo for Tangled
1package state
2
3import (
4 "fmt"
5 "io"
6 "maps"
7 "net/http"
8
9 "github.com/bluesky-social/indigo/atproto/identity"
10 "github.com/go-chi/chi/v5"
11 "tangled.org/core/appview/models"
12)
13
14func (s *State) InfoRefs(w http.ResponseWriter, r *http.Request) {
15 repo := r.Context().Value("repo").(*models.Repo)
16
17 scheme := "https"
18 if s.config.Core.Dev {
19 scheme = "http"
20 }
21
22 targetURL := fmt.Sprintf("%s://%s/%s/info/refs?%s", scheme, repo.Knot, repo.RepoIdentifier(), r.URL.RawQuery)
23 s.proxyRequest(w, r, targetURL)
24
25}
26
27func (s *State) UploadArchive(w http.ResponseWriter, r *http.Request) {
28 repo := r.Context().Value("repo").(*models.Repo)
29
30 scheme := "https"
31 if s.config.Core.Dev {
32 scheme = "http"
33 }
34
35 targetURL := fmt.Sprintf("%s://%s/%s/git-upload-archive?%s", scheme, repo.Knot, repo.RepoIdentifier(), r.URL.RawQuery)
36 s.proxyRequest(w, r, targetURL)
37}
38
39func (s *State) UploadPack(w http.ResponseWriter, r *http.Request) {
40 repo := r.Context().Value("repo").(*models.Repo)
41
42 scheme := "https"
43 if s.config.Core.Dev {
44 scheme = "http"
45 }
46
47 targetURL := fmt.Sprintf("%s://%s/%s/git-upload-pack?%s", scheme, repo.Knot, repo.RepoIdentifier(), r.URL.RawQuery)
48 s.proxyRequest(w, r, targetURL)
49}
50
51func (s *State) ReceivePack(w http.ResponseWriter, r *http.Request) {
52 repo := r.Context().Value("repo").(*models.Repo)
53
54 scheme := "https"
55 if s.config.Core.Dev {
56 scheme = "http"
57 }
58
59 targetURL := fmt.Sprintf("%s://%s/%s/git-receive-pack?%s", scheme, repo.Knot, repo.RepoIdentifier(), 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 if id, ok := r.Context().Value("resolvedId").(identity.Identity); ok && !id.Handle.IsInvalidHandle() {
78 repoOwnerHandle = id.Handle.String()
79 }
80 proxyReq.Header.Add("x-tangled-repo-owner-handle", repoOwnerHandle)
81
82 // Execute request
83 resp, err := client.Do(proxyReq)
84 if err != nil {
85 http.Error(w, err.Error(), http.StatusInternalServerError)
86 return
87 }
88 defer resp.Body.Close()
89
90 // Copy response headers
91 maps.Copy(w.Header(), resp.Header)
92
93 // Set response status code
94 w.WriteHeader(resp.StatusCode)
95
96 // Copy response body
97 if _, err := io.Copy(w, resp.Body); err != nil {
98 http.Error(w, err.Error(), http.StatusInternalServerError)
99 return
100 }
101}