package main import ( "os" "fmt" "net" "net/http" "strings" "time" "code.gitea.io/sdk/gitea" "github.com/urfave/cli/v2" log "github.com/sirupsen/logrus" ) const ( //PagesBranch "pages" // TODO: Change back for testing PagesBranch = "main" ) func handleSubdomain(domain string, cname string, path string, giteaClient *gitea.Client, w http.ResponseWriter) { hostParts := strings.Split(domain, ".") username := hostParts[0] // Strip the leading / if path[:1] == "/" { path = path[1:] } _, path, err := RepoFromPath( username, domain, cname, path, giteaClient, ) if err != nil { log.Errorf("Failed to get repo: %s", err) w.WriteHeader(404) return } serveFile(username, path, giteaClient, w) } func Handler(pagesDomain string, giteaClient *gitea.Client) http.HandlerFunc { return func(w http.ResponseWriter, req *http.Request) { w.Header().Set("Server", "rio") if strings.HasSuffix(req.Host, pagesDomain){ log.Debug("Domain can be directly handled") handleSubdomain(req.Host, "", req.URL.Path, giteaClient, w) return } cname, err := lookupCNAME(req.Host) if err != nil { log.Warningf("CNAME request failed, we don't handle %s", req.Host) w.WriteHeader(400) return } log.Debugf("Got CNAME %s", cname) if strings.HasSuffix(cname, pagesDomain) { log.Debugf("%s is alias of %s", req.Host, cname) handleSubdomain(cname, cname, req.URL.Path, giteaClient, w) return } log.Errorf("Not handling %s", req.Host) w.WriteHeader(404) } } func runServer(ctx *cli.Context) error { giteaUrl := ctx.String("gitea-url") addr := ctx.String("listen-host") + ":" + ctx.String("listen-port") domain := ctx.String("pages-domain") log.SetLevel(log.DebugLevel) httpClient := http.Client{Timeout: 10 * time.Second} client, err := gitea.NewClient( giteaUrl, gitea.SetHTTPClient(&httpClient), gitea.SetToken(""), gitea.SetUserAgent("rio"), ) listener, err := net.Listen("tcp", addr) if err != nil { fmt.Errorf("Failed to create listener: %v", err) return err } if err := http.Serve(listener, Handler(domain, client)); err != nil { fmt.Printf("Listening failed") return err } return nil } func main() { app := &cli.App{ Action: runServer, Flags: []cli.Flag{ &cli.StringFlag{ Name: "gitea-url", Usage: "The (HTTPS) URL to the serving Gitea instance", EnvVars: []string{"GITEA_URL"}, Required: true, }, &cli.StringFlag{ Name: "listen-host", Usage: "The host to listen on", EnvVars: []string{"HOST"}, Value: "127.0.0.1", }, &cli.StringFlag{ Name: "listen-port", Usage: "The port to listen on", EnvVars: []string{"PORT"}, Value: "8888", }, &cli.StringFlag{ Name: "pages-domain", Usage: "The domain on which the server is reachable", EnvVars: []string{"PAGES_DOMAIN"}, Required: true, }, }, } if err := app.Run(os.Args); err != nil { log.Fatalf("Failed to run app: %s", err) } }