forked from tangled.org/core
Monorepo for Tangled — https://tangled.org
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 user := r.Context().Value("resolvedId").(identity.Identity) 16 repo := r.Context().Value("repo").(*models.Repo) 17 18 scheme := "https" 19 if s.config.Core.Dev { 20 scheme = "http" 21 } 22 23 targetURL := fmt.Sprintf("%s://%s/%s/%s/info/refs?%s", scheme, repo.Knot, user.DID, repo.Name, r.URL.RawQuery) 24 s.proxyRequest(w, r, targetURL) 25 26} 27 28func (s *State) UploadPack(w http.ResponseWriter, r *http.Request) { 29 user, ok := r.Context().Value("resolvedId").(identity.Identity) 30 if !ok { 31 http.Error(w, "failed to resolve user", http.StatusInternalServerError) 32 return 33 } 34 repo := r.Context().Value("repo").(*models.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, repo.Knot, user.DID, repo.Name, 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 repo := r.Context().Value("repo").(*models.Repo) 52 53 scheme := "https" 54 if s.config.Core.Dev { 55 scheme = "http" 56 } 57 58 targetURL := fmt.Sprintf("%s://%s/%s/%s/git-receive-pack?%s", scheme, repo.Knot, user.DID, repo.Name, r.URL.RawQuery) 59 s.proxyRequest(w, r, targetURL) 60} 61 62func (s *State) proxyRequest(w http.ResponseWriter, r *http.Request, targetURL string) { 63 client := &http.Client{} 64 65 // Create new request 66 proxyReq, err := http.NewRequest(r.Method, targetURL, r.Body) 67 if err != nil { 68 http.Error(w, err.Error(), http.StatusInternalServerError) 69 return 70 } 71 72 // Copy original headers 73 proxyReq.Header = r.Header 74 75 repoOwnerHandle := chi.URLParam(r, "user") 76 proxyReq.Header.Add("x-tangled-repo-owner-handle", repoOwnerHandle) 77 78 // Execute request 79 resp, err := client.Do(proxyReq) 80 if err != nil { 81 http.Error(w, err.Error(), http.StatusInternalServerError) 82 return 83 } 84 defer resp.Body.Close() 85 86 // Copy response headers 87 maps.Copy(w.Header(), resp.Header) 88 89 // Set response status code 90 w.WriteHeader(resp.StatusCode) 91 92 // Copy response body 93 if _, err := io.Copy(w, resp.Body); err != nil { 94 http.Error(w, err.Error(), http.StatusInternalServerError) 95 return 96 } 97}