minor changes
This commit is contained in:
parent
d61374b9e2
commit
0e18e4202b
3 changed files with 111 additions and 111 deletions
|
|
@ -68,6 +68,6 @@ Environment="PORT=<port>"
|
|||
WantedBy=multi-user.target
|
||||
</code></pre><p>Then start the service:</p><pre><code>sudo systemctl enable docs.brut
|
||||
sudo systemctl start docs.brut
|
||||
</code></pre><h2>Usage Within Git.Brut.Systems</h2><p>Those with repositories on <a href="https://git.brut.systems">git.brut.systems</a> can serve websites by creating a <code>docs/</code> folder (on the default branch). While any file from the repository can be accessed, files within <code>docs/</code> are accessible from <code>/</code>. If a file within <code>docs/</code> conflicts with another file in the repository, the file in <code>docs/</code> take precedence.</p>
|
||||
</code></pre><h2>Usage Within Git.Brut.Systems</h2><p>Those with repositories on <a href="https://git.brut.systems">git.brut.systems</a> can serve websites by creating a <code>docs/</code> folder (on the default branch). While any file from the repository can be accessed, files within <code>docs/</code> are accessible from <code>/</code>. If a <a href="/main.go">file</a> within <code>docs/</code> conflicts with another file in the repository, the file in <code>docs/</code> take precedence.</p>
|
||||
</body>
|
||||
</html>
|
||||
|
|
@ -46,4 +46,4 @@ Then start the service:
|
|||
|
||||
USAGE WITHIN GIT.BRUT.SYSTEMS
|
||||
|
||||
Those with repositories on [https://git.brut.systems git.brut.systems] can serve websites by creating a `docs/` folder (on the default branch). While any file from the repository can be accessed, files within `docs/` are accessible from `/`. If a file within `docs/` conflicts with another file in the repository, the file in `docs/` take precedence.
|
||||
Those with repositories on [https://git.brut.systems git.brut.systems] can serve websites by creating a `docs/` folder (on the default branch). While any file from the repository can be accessed, files within `docs/` are accessible from `/`. If a [/main.go file] within `docs/` conflicts with another file in the repository, the file in `docs/` take precedence.
|
||||
|
|
|
|||
222
main.go
222
main.go
|
|
@ -21,38 +21,104 @@ var (
|
|||
PORT string
|
||||
)
|
||||
|
||||
type Server struct {
|
||||
http.ServeMux
|
||||
func main() {
|
||||
var err error
|
||||
if API_URL, err = GetEnvironmentVariable("API_URL"); err != nil {
|
||||
log.Fatal(err)
|
||||
} else {
|
||||
if _, err := url.Parse(API_URL); err != nil {
|
||||
log.Fatalf("invalid API_URL %q", err)
|
||||
}
|
||||
|
||||
if !strings.HasPrefix(API_URL, "http") {
|
||||
log.Fatalf("invalid API_URL %q - must being with http(s)://", API_URL)
|
||||
}
|
||||
}
|
||||
|
||||
if REDIRECT_URL, err = GetEnvironmentVariable("REDIRECT_URL"); err != nil {
|
||||
log.Fatal(err)
|
||||
} else {
|
||||
if _, err := url.Parse(REDIRECT_URL); err != nil {
|
||||
log.Fatalf("invalid REDIRECT_URL %q", err)
|
||||
}
|
||||
|
||||
if !strings.HasPrefix(REDIRECT_URL, "http") {
|
||||
log.Fatalf("invalid REDIRECT_URL %q - must begin with \"http(s)://\"", REDIRECT_URL)
|
||||
}
|
||||
}
|
||||
|
||||
if token, err := GetEnvironmentVariable("API_TOKEN"); err != nil {
|
||||
log.Fatal(err)
|
||||
} else {
|
||||
API_TOKEN = "token " + token
|
||||
}
|
||||
|
||||
if PORT, err = GetEnvironmentVariable("PORT"); err != nil {
|
||||
log.Fatal(err)
|
||||
} else {
|
||||
if _, err = strconv.ParseInt(PORT, 10, 64); err != nil {
|
||||
log.Fatalf("invalid port number %q", PORT)
|
||||
}
|
||||
}
|
||||
|
||||
redirect := func(w http.ResponseWriter, r *http.Request) {
|
||||
http.Redirect(w, r, REDIRECT_URL, http.StatusTemporaryRedirect)
|
||||
}
|
||||
|
||||
sv := new(http.ServeMux)
|
||||
sv.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
|
||||
redirect(w, r)
|
||||
})
|
||||
sv.HandleFunc("/{user}/{repo}/", func(w http.ResponseWriter, r *http.Request) {
|
||||
user := strings.TrimSpace(r.PathValue("user"))
|
||||
repo := strings.TrimSpace(r.PathValue("repo"))
|
||||
|
||||
if len(user) == 0 || len(repo) == 0 {
|
||||
redirect(w, r)
|
||||
return
|
||||
}
|
||||
|
||||
path := r.URL.Path
|
||||
path = strings.TrimSpace(path[strings.Index(path, repo)+len(repo):])
|
||||
path = strings.TrimPrefix(path, "/")
|
||||
|
||||
if len(path) == 0 {
|
||||
path = "docs/index.html"
|
||||
}
|
||||
|
||||
log.Printf("fetching file content %s:%s - %q", user, repo, path)
|
||||
|
||||
content, err := FetchFile(user, repo, path)
|
||||
if err != nil {
|
||||
log.Println(err)
|
||||
redirect(w, r)
|
||||
return
|
||||
}
|
||||
|
||||
if _, err := w.Write(content); err != nil {
|
||||
log.Println(err)
|
||||
redirect(w, r)
|
||||
return
|
||||
}
|
||||
})
|
||||
|
||||
addr := fmt.Sprintf(":%s", PORT)
|
||||
log.Printf("Listening at %s", addr)
|
||||
|
||||
if err := http.ListenAndServe(addr, sv); err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
}
|
||||
|
||||
func (sv *Server) getfile(user, repo, path string) ([]byte, error) {
|
||||
var (
|
||||
endpoint = endpoint("/repos/%s/%s/contents/%s", user, repo, url.PathEscape(path))
|
||||
)
|
||||
|
||||
req, err := http.NewRequest("GET", endpoint, nil)
|
||||
func FetchFile(user, repo, path string) ([]byte, error) {
|
||||
api_endpoint := FormatEndpoint("/repos/%s/%s/contents/%s", user, repo, url.PathEscape(path))
|
||||
body, status, err := ApiGet(api_endpoint)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
req.Header.Add("accept", "application/json")
|
||||
req.Header.Add("Authorization", API_TOKEN)
|
||||
|
||||
log.Printf("GET %q", endpoint)
|
||||
|
||||
var client http.Client
|
||||
res, err := client.Do(req)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
body, err := io.ReadAll(res.Body)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if res.StatusCode != http.StatusOK {
|
||||
return nil, fmt.Errorf("response had unexpected status %d - %s", res.StatusCode, string(body))
|
||||
if status != http.StatusOK {
|
||||
return nil, fmt.Errorf("response had unexpected status %d - %s", status, string(body))
|
||||
}
|
||||
|
||||
var response struct {
|
||||
|
|
@ -77,97 +143,31 @@ func (sv *Server) getfile(user, repo, path string) ([]byte, error) {
|
|||
return file, nil
|
||||
}
|
||||
|
||||
func main() {
|
||||
var err error
|
||||
if API_URL, err = getvar("API_URL"); err != nil {
|
||||
log.Fatal(err)
|
||||
} else {
|
||||
if _, err := url.Parse(API_URL); err != nil {
|
||||
log.Fatalf("invalid API_URL %q", err)
|
||||
}
|
||||
|
||||
if !strings.HasPrefix(API_URL, "http") {
|
||||
log.Fatalf("invalid API_URL %q - must being with http(s)://", API_URL)
|
||||
}
|
||||
}
|
||||
|
||||
if REDIRECT_URL, err = getvar("REDIRECT_URL"); err != nil {
|
||||
log.Fatal(err)
|
||||
} else {
|
||||
if _, err := url.Parse(REDIRECT_URL); err != nil {
|
||||
log.Fatalf("invalid REDIRECT_URL %q", err)
|
||||
}
|
||||
|
||||
if !strings.HasPrefix(REDIRECT_URL, "http") {
|
||||
log.Fatalf("invalid REDIRECT_URL %q - must begin with \"http(s)://\"", REDIRECT_URL)
|
||||
}
|
||||
}
|
||||
|
||||
if token, err := getvar("API_TOKEN"); err != nil {
|
||||
log.Fatal(err)
|
||||
} else {
|
||||
API_TOKEN = "token " + token
|
||||
}
|
||||
|
||||
if PORT, err = getvar("PORT"); err != nil {
|
||||
log.Fatal(err)
|
||||
} else {
|
||||
if _, err = strconv.ParseInt(PORT, 10, 64); err != nil {
|
||||
log.Fatalf("invalid port number %q", PORT)
|
||||
}
|
||||
}
|
||||
|
||||
redirect := func(w http.ResponseWriter, r *http.Request) {
|
||||
http.Redirect(w, r, REDIRECT_URL, http.StatusTemporaryRedirect)
|
||||
}
|
||||
|
||||
sv := new(Server)
|
||||
sv.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
|
||||
redirect(w, r)
|
||||
})
|
||||
|
||||
sv.HandleFunc("/{user}/{repo}/", func(w http.ResponseWriter, r *http.Request) {
|
||||
user := strings.TrimSpace(r.PathValue("user"))
|
||||
repo := strings.TrimSpace(r.PathValue("repo"))
|
||||
|
||||
if len(user) == 0 || len(repo) == 0 {
|
||||
redirect(w, r)
|
||||
return
|
||||
}
|
||||
|
||||
path := r.URL.Path
|
||||
path = strings.TrimSpace(path[strings.Index(path, repo)+len(repo):])
|
||||
path = strings.TrimPrefix(path, "/")
|
||||
|
||||
if len(path) == 0 {
|
||||
path = "docs/index.html"
|
||||
}
|
||||
|
||||
log.Printf("fetching file content %s:%s - %q", user, repo, path)
|
||||
|
||||
content, err := sv.getfile(user, repo, path)
|
||||
func ApiGet(endpoint string) ([]byte, int, error) {
|
||||
req, err := http.NewRequest("GET", endpoint, nil)
|
||||
if err != nil {
|
||||
log.Println(err)
|
||||
redirect(w, r)
|
||||
return
|
||||
return nil, -1, err
|
||||
}
|
||||
|
||||
if _, err := w.Write(content); err != nil {
|
||||
log.Println(err)
|
||||
redirect(w, r)
|
||||
return
|
||||
}
|
||||
})
|
||||
req.Header.Add("accept", "application/json")
|
||||
req.Header.Add("Authorization", API_TOKEN)
|
||||
|
||||
addr := fmt.Sprintf(":%s", PORT)
|
||||
log.Printf("Listening at %s", addr)
|
||||
|
||||
if err := http.ListenAndServe(addr, sv); err != nil {
|
||||
log.Fatal(err)
|
||||
var client http.Client
|
||||
log.Printf("GET %q", endpoint)
|
||||
res, err := client.Do(req)
|
||||
if err != nil {
|
||||
return nil, -1, err
|
||||
}
|
||||
|
||||
body, err := io.ReadAll(res.Body)
|
||||
if err != nil {
|
||||
return nil, -1, err
|
||||
}
|
||||
|
||||
return body, res.StatusCode, nil
|
||||
}
|
||||
|
||||
func getvar(name string) (string, error) {
|
||||
func GetEnvironmentVariable(name string) (string, error) {
|
||||
envvar := strings.TrimSpace(os.Getenv(name))
|
||||
if len(envvar) == 0 {
|
||||
return "", fmt.Errorf("required environment variable %q was not set", name)
|
||||
|
|
@ -175,7 +175,7 @@ func getvar(name string) (string, error) {
|
|||
return envvar, nil
|
||||
}
|
||||
|
||||
func endpoint(endpoint string, args ...any) string {
|
||||
func FormatEndpoint(endpoint string, args ...any) string {
|
||||
url, _ := url.JoinPath(API_URL, "api/v1", fmt.Sprintf(endpoint, args...))
|
||||
return url
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue