aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRunxi Yu <me@runxiyu.org>2025-02-12 11:01:52 +0800
committerRunxi Yu <me@runxiyu.org>2025-02-12 11:01:52 +0800
commit88d054811df785b92b1b76dd91265849af8f29b3 (patch)
tree522a9175290322cbe615ba98acf07a8a81888fcc
parentgit_format_patch.go: Remove garbage printf (diff)
downloadforge-88d054811df785b92b1b76dd91265849af8f29b3.tar.gz
forge-88d054811df785b92b1b76dd91265849af8f29b3.tar.zst
forge-88d054811df785b92b1b76dd91265849af8f29b3.zip
*: Migrate to the new path scheme
Diffstat (limited to '')
-rw-r--r--handle_group_index.go4
-rw-r--r--handle_repo_commit.go4
-rw-r--r--handle_repo_index.go4
-rw-r--r--handle_repo_log.go4
-rw-r--r--handle_repo_raw.go6
-rw-r--r--handle_repo_tree.go6
-rw-r--r--main.go23
-rw-r--r--resources.go26
-rw-r--r--router.go101
-rw-r--r--templates/_footer.html.tmpl2
-rw-r--r--templates/_head.html.tmpl2
-rw-r--r--templates/_repo_header.html.tmpl8
-rw-r--r--templates/index.html.tmpl2
-rw-r--r--templates/repo_tree_file.html.tmpl2
-rw-r--r--url_misc.go20
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) {
diff --git a/main.go b/main.go
index 8c06a77..ea72819 100644
--- a/main.go
+++ b/main.go
@@ -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
+}