Monorepo for Tangled
at master 101 lines 2.6 kB view raw
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}