From 88d054811df785b92b1b76dd91265849af8f29b3 Mon Sep 17 00:00:00 2001 From: Runxi Yu Date: Wed, 12 Feb 2025 11:01:52 +0800 Subject: [PATCH] *: Migrate to the new path scheme --- handle_group_index.go | 4 ++-- handle_repo_commit.go | 4 ++-- handle_repo_index.go | 4 ++-- handle_repo_log.go | 4 ++-- handle_repo_raw.go | 6 +++--- handle_repo_tree.go | 6 +++--- main.go | 23 ++++++++--------------- resources.go | 26 +++++++++++--------------- router.go | 101 +++++++++++++++++++++++++++++++++++++++++++++++++++++ templates/_footer.html.tmpl | 2 +- templates/_head.html.tmpl | 2 +- templates/_repo_header.html.tmpl | 8 ++++---- templates/index.html.tmpl | 2 +- templates/repo_tree_file.html.tmpl | 2 +- url_misc.go | 20 ++++++++++++++++++++ diff --git a/handle_group_index.go b/handle_group_index.go index f194cee095835e9c76d77711a7e2904d800915f6..bc7a7f45d04ff701d81975e4a90d99ec85b83f38 100644 --- a/handle_group_index.go +++ b/handle_group_index.go @@ -7,9 +7,9 @@ "path/filepath" "strings" ) -func handle_group_repos(w http.ResponseWriter, r *http.Request) { +func handle_group_repos(w http.ResponseWriter, r *http.Request, params map[string]string) { data := make(map[string]any) - group_name := r.PathValue("group_name") + group_name := params["group_name"] data["group_name"] = group_name entries, err := os.ReadDir(filepath.Join(config.Git.Root, group_name)) if err != nil { diff --git a/handle_repo_commit.go b/handle_repo_commit.go index 58c399223dec899bf77948b2787f2514c3dcde69..aefd58beab7c0c709da52f8b5d19da5f933f7754 100644 --- a/handle_repo_commit.go +++ b/handle_repo_commit.go @@ -16,9 +16,9 @@ To diff.File Chunks []diff.Chunk } -func handle_repo_commit(w http.ResponseWriter, r *http.Request) { +func handle_repo_commit(w http.ResponseWriter, r *http.Request, params map[string]string) { data := make(map[string]any) - group_name, repo_name, commit_id_specified_string := r.PathValue("group_name"), r.PathValue("repo_name"), r.PathValue("commit_id") + group_name, repo_name, commit_id_specified_string := params["group_name"], params["repo_name"], params["commit_id"] data["group_name"], data["repo_name"] = group_name, repo_name repo, err := open_git_repo(group_name, repo_name) if err != nil { diff --git a/handle_repo_index.go b/handle_repo_index.go index af6a62517a27edf24ad3f2b19112fed663cc955f..6372b03c40d492f8ce7f7f0ce89f964adf4d85c8 100644 --- a/handle_repo_index.go +++ b/handle_repo_index.go @@ -4,9 +4,9 @@ import ( "net/http" ) -func handle_repo_index(w http.ResponseWriter, r *http.Request) { +func handle_repo_index(w http.ResponseWriter, r *http.Request, params map[string]string) { data := make(map[string]any) - group_name, repo_name := r.PathValue("group_name"), r.PathValue("repo_name") + group_name, repo_name := params["group_name"], params["repo_name"] data["group_name"], data["repo_name"] = group_name, repo_name repo, err := open_git_repo(group_name, repo_name) if err != nil { diff --git a/handle_repo_log.go b/handle_repo_log.go index 67079c87c737a6f357034c581c60f650cfaa24b7..eff58590c7622078e2aff2f5f1b75e582dce163f 100644 --- a/handle_repo_log.go +++ b/handle_repo_log.go @@ -7,9 +7,9 @@ "github.com/go-git/go-git/v5/plumbing" ) // TODO: I probably shouldn't include *all* commits here... -func handle_repo_log(w http.ResponseWriter, r *http.Request) { +func handle_repo_log(w http.ResponseWriter, r *http.Request, params map[string]string) { data := make(map[string]any) - group_name, repo_name, ref_name := r.PathValue("group_name"), r.PathValue("repo_name"), r.PathValue("ref") + group_name, repo_name, ref_name := params["group_name"], params["repo_name"], params["ref"] data["group_name"], data["repo_name"], data["ref"] = group_name, repo_name, ref_name repo, err := open_git_repo(group_name, repo_name) if err != nil { diff --git a/handle_repo_raw.go b/handle_repo_raw.go index 7ed384281b622fd4257edc6d67c310514aa0dc34..d335f6a770a19800a74e6eba03ad7ca07c1b4120 100644 --- a/handle_repo_raw.go +++ b/handle_repo_raw.go @@ -9,10 +9,10 @@ "github.com/go-git/go-git/v5/plumbing/object" ) -func handle_repo_raw(w http.ResponseWriter, r *http.Request) { +func handle_repo_raw(w http.ResponseWriter, r *http.Request, params map[string]string) { data := make(map[string]any) - raw_path_spec := r.PathValue("rest") - group_name, repo_name, path_spec := r.PathValue("group_name"), r.PathValue("repo_name"), strings.TrimSuffix(raw_path_spec, "/") + raw_path_spec := params["rest"] + group_name, repo_name, path_spec := params["group_name"], params["repo_name"], strings.TrimSuffix(raw_path_spec, "/") ref_type, ref_name, err := get_param_ref_and_type(r) if err != nil { diff --git a/handle_repo_tree.go b/handle_repo_tree.go index 7ed6f1d0fb5f15708ef54219284a37f6bc35da3a..f95e9452f213a6beed3a6cdf1ec135e59cb36d0a 100644 --- a/handle_repo_tree.go +++ b/handle_repo_tree.go @@ -14,10 +14,10 @@ chroma_styles "github.com/alecthomas/chroma/v2/styles" "github.com/go-git/go-git/v5/plumbing/object" ) -func handle_repo_tree(w http.ResponseWriter, r *http.Request) { +func handle_repo_tree(w http.ResponseWriter, r *http.Request, params map[string]string) { data := make(map[string]any) - raw_path_spec := r.PathValue("rest") - group_name, repo_name, path_spec := r.PathValue("group_name"), r.PathValue("repo_name"), strings.TrimSuffix(raw_path_spec, "/") + raw_path_spec := params["rest"] + group_name, repo_name, path_spec := params["group_name"], params["repo_name"], strings.TrimSuffix(raw_path_spec, "/") ref_type, ref_name, err := get_param_ref_and_type(r) if err != nil { if errors.Is(err, err_no_ref_spec) { diff --git a/main.go b/main.go index 8c06a77fa121bfd3ad0567173c015a48ac193537..ea72819b45d23f5f59a0453f4cdf9695f19dc010 100644 --- a/main.go +++ b/main.go @@ -26,27 +26,20 @@ if err != nil { clog.Fatal(1, "Loading templates: "+err.Error()) } - err = serve_static() - if err != nil { - clog.Fatal(1, "Serving static: "+err.Error()) - } - - serve_source() - - http.HandleFunc("/{$}", handle_index) - http.HandleFunc("/g/{group_name}/repos/{$}", handle_group_repos) - http.HandleFunc("/g/{group_name}/repos/{repo_name}/{$}", handle_repo_index) - http.HandleFunc("/g/{group_name}/repos/{repo_name}/tree/{rest...}", handle_repo_tree) - http.HandleFunc("/g/{group_name}/repos/{repo_name}/raw/{rest...}", handle_repo_raw) - http.HandleFunc("/g/{group_name}/repos/{repo_name}/log/{ref}/", handle_repo_log) - http.HandleFunc("/g/{group_name}/repos/{repo_name}/commit/{commit_id}", handle_repo_commit) +// http.HandleFunc("/{$}", handle_index) +// http.HandleFunc("/g/{group_name}/repos/{$}", handle_group_repos) +// http.HandleFunc("/g/{group_name}/repos/{repo_name}/{$}", handle_repo_index) +// http.HandleFunc("/g/{group_name}/repos/{repo_name}/tree/{rest...}", handle_repo_tree) +// http.HandleFunc("/g/{group_name}/repos/{repo_name}/raw/{rest...}", handle_repo_raw) +// http.HandleFunc("/g/{group_name}/repos/{repo_name}/log/{ref}/", handle_repo_log) +// http.HandleFunc("/g/{group_name}/repos/{repo_name}/commit/{commit_id}", handle_repo_commit) listener, err := net.Listen(config.HTTP.Net, config.HTTP.Addr) if err != nil { clog.Fatal(1, "Listening: "+err.Error()) } - err = http.Serve(listener, nil) + err = http.Serve(listener, &http_router_t{}) if err != nil { clog.Fatal(1, "Serving: "+err.Error()) } diff --git a/resources.go b/resources.go index 30b0de5b4222042a1ae6ef10da06b1698f64618f..462460344d0446e9d462e04d1021db061bf92bb3 100644 --- a/resources.go +++ b/resources.go @@ -13,12 +13,12 @@ //go:embed *.scfg //go:embed static/* templates/* var source_fs embed.FS -func serve_source() { - http.Handle("/source/", - http.StripPrefix( - "/source/", - http.FileServer(http.FS(source_fs)), - ), +var source_handler http.Handler + +func init() { + source_handler = http.StripPrefix( + "/:/source/", + http.FileServer(http.FS(source_fs)), ) } @@ -35,16 +35,12 @@ }).ParseFS(resources_fs, "templates/*") return err } -func serve_static() (err error) { +var static_handler http.Handler +func init() { static_fs, err := fs.Sub(resources_fs, "static") if err != nil { - return err + panic(err) } - http.Handle("/static/", - http.StripPrefix( - "/static/", - http.FileServer(http.FS(static_fs)), - ), - ) - return nil + static_handler = http.StripPrefix("/:/static/", http.FileServer(http.FS(static_fs))) } + diff --git a/router.go b/router.go new file mode 100644 index 0000000000000000000000000000000000000000..ed0e9b5de53f4eb7744edf480261df007e08d98f --- /dev/null +++ b/router.go @@ -0,0 +1,101 @@ +package main + +import ( + "errors" + "fmt" + "net/http" + "strings" +) + +type http_router_t struct{} + +func (router *http_router_t) ServeHTTP(w http.ResponseWriter, r *http.Request) { + segments, _, err := parse_request_uri(r.RequestURI) + if err != nil { + http.Error(w, err.Error(), http.StatusBadRequest) + return + } + + if segments[0] == ":" { + switch segments[1] { + case "static": + static_handler.ServeHTTP(w, r) + case "source": + source_handler.ServeHTTP(w, r) + default: + fmt.Fprintln(w, "Unknown system module type:", segments[1]) + } + return + } + + separator_index := -1 + for i, part := range segments { + if part == ":" { + separator_index = i + break + } + } + non_empty_last_segments_len := len(segments) + dir_mode := false + if segments[len(segments)-1] == "" { + non_empty_last_segments_len-- + dir_mode = true + } + + params := make(map[string]string) + _ = params + switch { + case non_empty_last_segments_len == 0: + handle_index(w, r) + case separator_index == -1: + fmt.Fprintln(w, "Group indexing hasn't been implemented yet") + case non_empty_last_segments_len == separator_index+1: + fmt.Fprintln(w, "Group root hasn't been implemented yet") + case non_empty_last_segments_len == separator_index+2: + module_type := segments[separator_index+1] + params["group_name"] = segments[0] + switch module_type { + case "repos": + handle_group_repos(w, r, params) + default: + fmt.Fprintln(w, "Unknown module type:", module_type) + } + default: + module_type := segments[separator_index+1] + module_name := segments[separator_index+2] + params["group_name"] = segments[0] + switch module_type { + case "repos": + params["repo_name"] = module_name + // TODO: subgroups + if non_empty_last_segments_len == separator_index+3 { + if !dir_mode { + http.Redirect(w, r, r.URL.Path+"/", http.StatusSeeOther) + return + } + handle_repo_index(w, r, params) + return + } + repo_feature := segments[separator_index+3] + switch repo_feature { + case "tree": + params["rest"] = strings.Join(segments[separator_index+4:], "/") + handle_repo_tree(w, r, params) + case "raw": + params["rest"] = strings.Join(segments[separator_index+4:], "/") + handle_repo_raw(w, r, params) + case "log": + params["ref"] = segments[separator_index+4] + handle_repo_log(w, r, params) + case "commit": + params["commit_id"] = segments[separator_index+4] + handle_repo_commit(w, r, params) + } + default: + fmt.Fprintln(w, "Unknown module type:", module_type) + } + } +} + +var err_bad_request = errors.New("Bad Request") + diff --git a/templates/_footer.html.tmpl b/templates/_footer.html.tmpl index b7a9061d37ef4bcc692ad14d42d6abab8cce48b3..5b1acd23e1cd8bec16a0354af1c01a6a420b9afc 100644 --- a/templates/_footer.html.tmpl +++ b/templates/_footer.html.tmpl @@ -1,3 +1,3 @@ {{- define "footer" -}} -Lindenii Forge (source, upstream) +Lindenii Forge (source, upstream) {{- end -}} diff --git a/templates/_head.html.tmpl b/templates/_head.html.tmpl index b2cd48718a770fa736bd7d2d9024b9a9c250ea21..4641107d441df4fc3c3f41c8f7a7ac357fb5da57 100644 --- a/templates/_head.html.tmpl +++ b/templates/_head.html.tmpl @@ -1,5 +1,5 @@ {{- define "head_common" -}} - + {{- end -}} diff --git a/templates/_repo_header.html.tmpl b/templates/_repo_header.html.tmpl index 725d97b8a74b97cca10eaa3be568034a52e0dcaa..8e5baa87619bfe12dae451cb99ca32fe5b099401 100644 --- a/templates/_repo_header.html.tmpl +++ b/templates/_repo_header.html.tmpl @@ -1,11 +1,11 @@ {{- define "repo_header" -}} Lindenii Forge / -g +{{ .group_name }} / -{{ .group_name }} +: / -repos +repos / -{{ .repo_name }} +{{ .repo_name }} {{- end -}} diff --git a/templates/index.html.tmpl b/templates/index.html.tmpl index de3a643d242901651ede8c44a8015ae9c98030fa..505ea70b6b22a0de21b7e3c03e98c62dbf85a661 100644 --- a/templates/index.html.tmpl +++ b/templates/index.html.tmpl @@ -13,7 +13,7 @@ diff --git a/templates/repo_tree_file.html.tmpl b/templates/repo_tree_file.html.tmpl index 90ce5adb1ed78aca878e376a57d70b0a2905ec20..d4ba1e88dbe803dcd1492799afb62e10444abc71 100644 --- a/templates/repo_tree_file.html.tmpl +++ b/templates/repo_tree_file.html.tmpl @@ -11,7 +11,7 @@
{{ template "repo_header" . }}

- /{{ .path_spec }} (raw) + /{{ .path_spec }} (raw)

{{ .file_contents }}