diff options
Diffstat (limited to '')
-rw-r--r-- | handle_group_index.go | 4 | ||||
-rw-r--r-- | handle_repo_commit.go | 4 | ||||
-rw-r--r-- | handle_repo_index.go | 4 | ||||
-rw-r--r-- | handle_repo_log.go | 4 | ||||
-rw-r--r-- | handle_repo_raw.go | 6 | ||||
-rw-r--r-- | handle_repo_tree.go | 6 | ||||
-rw-r--r-- | main.go | 23 | ||||
-rw-r--r-- | resources.go | 26 | ||||
-rw-r--r-- | router.go | 101 | ||||
-rw-r--r-- | templates/_footer.html.tmpl | 2 | ||||
-rw-r--r-- | templates/_head.html.tmpl | 2 | ||||
-rw-r--r-- | templates/_repo_header.html.tmpl | 8 | ||||
-rw-r--r-- | templates/index.html.tmpl | 2 | ||||
-rw-r--r-- | templates/repo_tree_file.html.tmpl | 2 | ||||
-rw-r--r-- | url_misc.go | 20 |
15 files changed, 162 insertions, 52 deletions
diff --git a/handle_group_index.go b/handle_group_index.go index f194cee..bc7a7f4 100644 --- a/handle_group_index.go +++ b/handle_group_index.go @@ -7,9 +7,9 @@ import ( "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 58c3992..aefd58b 100644 --- a/handle_repo_commit.go +++ b/handle_repo_commit.go @@ -16,9 +16,9 @@ type usable_file_patch struct { 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 af6a625..6372b03 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 67079c8..eff5859 100644 --- a/handle_repo_log.go +++ b/handle_repo_log.go @@ -7,9 +7,9 @@ import ( ) // 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 7ed3842..d335f6a 100644 --- a/handle_repo_raw.go +++ b/handle_repo_raw.go @@ -9,10 +9,10 @@ import ( "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 7ed6f1d..f95e945 100644 --- a/handle_repo_tree.go +++ b/handle_repo_tree.go @@ -14,10 +14,10 @@ import ( "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) { @@ -26,27 +26,20 @@ func main() { 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 30b0de5..4624603 100644 --- a/resources.go +++ b/resources.go @@ -13,12 +13,12 @@ import ( //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 @@ func load_templates() (err error) { 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 0000000..ed0e9b5 --- /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 b7a9061..5b1acd2 100644 --- a/templates/_footer.html.tmpl +++ b/templates/_footer.html.tmpl @@ -1,3 +1,3 @@ {{- define "footer" -}} -<a href="https://lindenii.runxiyu.org/forge/">Lindenii Forge</a> (<a href="/source/">source</a>, <a href="https://forge.lindenii.runxiyu.org/g/lindenii/repos/forge/">upstream</a>) +<a href="https://lindenii.runxiyu.org/forge/">Lindenii Forge</a> (<a href="/:/source/">source</a>, <a href="https://forge.lindenii.runxiyu.org/g/lindenii/repos/forge/">upstream</a>) {{- end -}} diff --git a/templates/_head.html.tmpl b/templates/_head.html.tmpl index b2cd487..4641107 100644 --- a/templates/_head.html.tmpl +++ b/templates/_head.html.tmpl @@ -1,5 +1,5 @@ {{- define "head_common" -}} <meta charset="utf-8" /> <meta name="viewport" content="width=device-width, initial-scale=1" /> -<link rel="stylesheet" href="/static/style.css" /> +<link rel="stylesheet" href="/:/static/style.css" /> {{- end -}} diff --git a/templates/_repo_header.html.tmpl b/templates/_repo_header.html.tmpl index 725d97b..8e5baa8 100644 --- a/templates/_repo_header.html.tmpl +++ b/templates/_repo_header.html.tmpl @@ -1,11 +1,11 @@ {{- define "repo_header" -}} <a href="/">Lindenii Forge</a> / -g +<a href="/{{ .group_name }}/">{{ .group_name }}</a> / -<a href="/g/{{ .group_name }}/">{{ .group_name }}</a> +<a href="/{{ .group_name }}/:">:</a> / -<a href="/g/{{ .group_name }}/repos/">repos</a> +<a href="/{{ .group_name }}/:/repos/">repos</a> / -<a href="/g/{{ .group_name }}/repos/{{ .repo_name }}/">{{ .repo_name }}</a> +<a href="/{{ .group_name }}/:/repos/{{ .repo_name }}/">{{ .repo_name }}</a> {{- end -}} diff --git a/templates/index.html.tmpl b/templates/index.html.tmpl index de3a643..505ea70 100644 --- a/templates/index.html.tmpl +++ b/templates/index.html.tmpl @@ -13,7 +13,7 @@ <ul> {{- range .groups }} <li> - <a href="g/{{ . }}/repos/">{{ . }}</a> + <a href="{{ . }}/:/repos/">{{ . }}</a> </li> {{- end }} </ul> diff --git a/templates/repo_tree_file.html.tmpl b/templates/repo_tree_file.html.tmpl index 90ce5ad..d4ba1e8 100644 --- a/templates/repo_tree_file.html.tmpl +++ b/templates/repo_tree_file.html.tmpl @@ -11,7 +11,7 @@ {{ template "repo_header" . }} </header> <p> - /{{ .path_spec }} (<a href="/g/{{ .group_name }}/repos/{{ .repo_name }}/raw/{{ .path_spec }}{{ if not (eq .ref_type "head") }}?{{ .ref_type }}={{ .ref }}{{ end }}">raw</a>) + /{{ .path_spec }} (<a href="/{{ .group_name }}/:/repos/{{ .repo_name }}/raw/{{ .path_spec }}{{ if not (eq .ref_type "head") }}?{{ .ref_type }}={{ .ref }}{{ end }}">raw</a>) </p> {{ .file_contents }} <footer> diff --git a/url_misc.go b/url_misc.go index cbb30d6..e4bfd92 100644 --- a/url_misc.go +++ b/url_misc.go @@ -4,6 +4,9 @@ import ( "errors" "net/http" "net/url" + "strings" + + "go.lindenii.runxiyu.org/lindenii-common/misc" ) var ( @@ -40,3 +43,20 @@ func get_param_ref_and_type(r *http.Request) (ref_type, ref string, err error) { } return } + +func parse_request_uri(request_uri string) (segments []string, params url.Values, err error) { + path, params_string, _ := strings.Cut(request_uri, "?") + + segments = strings.Split(strings.TrimPrefix(path, "/"), "/") + + for i, segment := range segments { + segments[i], _ = url.QueryUnescape(segment) + } + + params, err = url.ParseQuery(params_string) + if err != nil { + return nil, nil, misc.Wrap_one_error(err_bad_request, err) + } + + return +} |