M main.go => main.go +11 -29
@@ 1,38 1,21 @@
+// sourcehut-vanity hosts an HTTP server that redirects HTTP requests to projects hosted on sourcehut. Example usage:
+//
+// $ sourcehut-vanity blowry 0.0.0.0:8080
+// # localhost:8080/sourcehut-vanity redirects to https://git.sr.ht/~blowry/sourcehut-vanity
+// # localhost:8080/sourcehut-vanity/README.md redirects to https://git.sr.ht/~blowry/sourcehut-vanity/tree/master/README.md
+// # localhost:8080/sourcehut-vanity?go-get=1 returns an HTML page with meta tags so go get can find the correct repository
+//
+// Compatible with go-get(1) and standard browsers.
// SPDX-License-Identifier: GPL-3.0-or-later
package main
import (
"fmt"
"net/http"
+ "ben.gmbh/sourcehut-vanity/vanityserver"
"os"
- "strings"
)
-type vanityserver struct{}
-var username string
-
-func (server vanityserver) ServeHTTP(rw http.ResponseWriter, r *http.Request) {
- fmt.Println("Hit: " + r.URL.Path)
- fmt.Println(r.Header)
- path := strings.Split(r.URL.Path, "/")
- projectname := path[1]
- baseurl := "https://git.sr.ht/~" + username + "/" + projectname
- var destination string
- r.ParseForm()
-
- if (len(path) > 2 && path[2] != "") {
- destination = baseurl + "/tree/master/" + strings.Replace(r.URL.Path, "/" + path[1] + "/", "", 1)
- } else {
- destination = baseurl
- }
- if (r.Form.Get("go-get") == "1") { // go-get(1)
- rw.Write([]byte("TODO: go-get support"))
- } else { // Standard browser
- http.Redirect(rw, r, destination, 302)
- }
- return
-}
-
func printusage() {
fmt.Fprintf(os.Stderr, "usage: sourcehut-vanity username [0.0.0.0:8080]\n")
os.Exit(1)
@@ 48,8 31,7 @@ func main() {
} else {
port = "0.0.0.0:8080"
}
- username = os.Args[1]
- fmt.Printf("Serving %v's projects on %v\n", username, port)
- fmt.Println(http.ListenAndServe(port, vanityserver{}))
+ fmt.Printf("Serving %v's projects on %v\n", os.Args[1], port)
+ fmt.Println(http.ListenAndServe(port, vanityserver.VanityServer{Username: os.Args[1]}))
}
A vanityserver/vanityserver.go => vanityserver/vanityserver.go +66 -0
@@ 0,0 1,66 @@
+// VanityServer implements an HTTP.Handler that redirects HTTP requests to projects hosted on sourcehut.
+// Example usage:
+//
+// import (
+// "net/http"
+// "ben.gmbh/sourcehut-vanity/vanityserver"
+// )
+// func main() {
+// http.ListenAndServe(port, vanityserver.VanityServer{Username: "blowry"})
+// }
+//
+// SPDX-License-Identifier: GPL-3.0-or-later
+package vanityserver
+
+import (
+ "fmt"
+ "strings"
+ "net/http"
+ "html/template"
+)
+
+type VanityServer struct {
+ Username string
+}
+
+type templatedata struct {
+ User string
+ ImportHost string
+ ProjectName string
+ Redir string
+}
+
+const page = `<!DOCTYPE html>
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
+<meta name="go-import" content="{{.ImportHost}} git https://git.sr.ht/~{{.User}}/{{.ProjectName}}">
+<meta name="go-source" content="{{.ImportHost}} https://git.sr.ht/~{{.User}}/{{.ProjectName}} https://git.sr.ht/~{{.User}}/{{.ProjectName}}/tree/master{/dir} https://git.sr.ht/~{{.User}}/{{.ProjectName}}/tree/master{/dir}/{file}#L{line}">
+<meta http-equiv="refresh" content="0; url={{.Redir}}">
+</head>
+<body>
+Nothing to see here; <a href="{{.Redir}}">move along</a>.
+</body>
+</html>`
+
+func (server VanityServer) ServeHTTP(rw http.ResponseWriter, r *http.Request) {
+ tmpl := template.Must(template.New("page").Parse(page))
+ fmt.Println("Hit: " + r.URL.Path)
+ path := strings.Split(r.URL.Path, "/")
+ projectname := path[1]
+ baseurl := "https://git.sr.ht/~" + server.Username + "/" + projectname
+ var destination string
+ r.ParseForm()
+
+ if (len(path) > 2 && path[2] != "") {
+ destination = baseurl + "/tree/master/" + strings.Replace(r.URL.Path, "/" + path[1] + "/", "", 1)
+ } else {
+ destination = baseurl
+ }
+ if (r.Form.Get("go-get") == "1") { // go-get(1)
+ tmpl.Execute(rw, templatedata{User: server.Username, ImportHost: r.Host + r.URL.Path, ProjectName: projectname, Redir: destination})
+ } else { // Standard browser
+ http.Redirect(rw, r, destination, 302)
+ }
+ return
+}