| 1 | // SPDX-License-Identifier: AGPL-3.0-or-later |
| 2 | |
| 3 | package repo |
| 4 | |
| 5 | import ( |
| 6 | "net/http" |
| 7 | "strings" |
| 8 | |
| 9 | "github.com/jackc/pgx/v5/pgtype" |
| 10 | |
| 11 | reposdb "github.com/tenseleyFlow/shithub/internal/repos/sqlc" |
| 12 | ) |
| 13 | |
| 14 | // tryRedirect resolves a (stale_owner, stale_name) URL to its current |
| 15 | // canonical form via repo_redirects. Returns "" when no redirect row |
| 16 | // matches, in which case the caller should 404. The returned URL |
| 17 | // preserves the request's RemainingPath so e.g. /old/repo/blob/x |
| 18 | // becomes /new/repo/blob/x — handy when more granular routes ship. |
| 19 | func (h *Handlers) tryRedirect(r *http.Request, ownerName, repoName string) string { |
| 20 | owner, err := h.uq.GetUserByUsername(r.Context(), h.d.Pool, ownerName) |
| 21 | if err != nil { |
| 22 | return "" |
| 23 | } |
| 24 | repoID, err := h.rq.LookupRedirectByUserOwner(r.Context(), h.d.Pool, reposdb.LookupRedirectByUserOwnerParams{ |
| 25 | OldOwnerUserID: pgtype.Int8{Int64: owner.ID, Valid: true}, |
| 26 | OldName: repoName, |
| 27 | }) |
| 28 | if err != nil { |
| 29 | return "" |
| 30 | } |
| 31 | row, err := h.rq.GetRepoByID(r.Context(), h.d.Pool, repoID) |
| 32 | if err != nil || row.DeletedAt.Valid { |
| 33 | // Repo gone for real; let the caller serve a clean 404 instead |
| 34 | // of redirecting into a 404. This keeps user agents from |
| 35 | // chasing dead links via a 301. |
| 36 | return "" |
| 37 | } |
| 38 | currentOwner := "" |
| 39 | if row.OwnerUserID.Valid { |
| 40 | if u, err := h.uq.GetUserByID(r.Context(), h.d.Pool, row.OwnerUserID.Int64); err == nil { |
| 41 | currentOwner = u.Username |
| 42 | } |
| 43 | } |
| 44 | if currentOwner == "" || row.Name == "" { |
| 45 | return "" |
| 46 | } |
| 47 | // Preserve any path tail beyond /{owner}/{repo} (rare today; will |
| 48 | // matter when blob/tree/issues subpaths land). |
| 49 | tail := strings.TrimPrefix(r.URL.Path, "/"+ownerName+"/"+repoName) |
| 50 | return "/" + currentOwner + "/" + row.Name + tail |
| 51 | } |
| 52 |