first implementation

This commit is contained in:
setop 2024-11-28 02:45:01 +01:00
commit e69771b09f
5 changed files with 163 additions and 0 deletions

1
.tool-versions Normal file
View File

@ -0,0 +1 @@
golang 1.21.0

9
Dockerfile Normal file
View File

@ -0,0 +1,9 @@
FROM alpine
RUN apk add curl
COPY main .
EXPOSE 5555
ENTRYPOINT ["/main", "5555"]

28
README.md Normal file
View File

@ -0,0 +1,28 @@
# Purpose
This tool allows to serve static files of a git repo hosted on a gitea instance
Files to be served must be published in a branch named "pages" and in a folder named "public"
# Usage
## standalone
set GITDOMAIN environment variable, then run `go run main.go 8081`
## Docker
Build image using docker and run a container, setting GITDOMAIN environment variable
# Limitations
* serve only public repo
* only relative links are supported
# Further
* perform security audit
* find a way to serve private repo content
* propose a standard gitea action to publish content
* custom domains

11
cmd.txt Normal file
View File

@ -0,0 +1,11 @@
CGO_ENABLED=0 go build main.go && strip main
GITDOMAIN=git.zoocoop.com ./main 8081
export VERSION=0.1.0
docker build -t giteapages:$VERSION .
docker save giteapages:$VERSION | pv | ssh kmsf2 docker load

114
main.go Normal file
View File

@ -0,0 +1,114 @@
package main
import (
"fmt"
"io/ioutil"
"net/http"
"os"
"regexp"
"strings"
)
var GITDOMAIN = os.Getenv("GITDOMAIN")
func main() {
// Get the port from command-line arguments
if len(os.Args) < 2 {
fmt.Println("Usage: go run main.go <port>")
return
}
port := os.Args[1]
http.HandleFunc("/", serveFile)
fmt.Printf("Server is running on :%s\n", port)
if err := http.ListenAndServe(":"+port, nil); err != nil {
fmt.Println("Error starting server:", err)
}
}
func serveFile(w http.ResponseWriter, r *http.Request) {
// Parse the URL path
parts := strings.Split(strings.Trim(r.URL.Path, "/"), "/")
if len(parts) < 3 {
http.Error(w, "Invalid URL format", http.StatusBadRequest)
return
}
user := parts[0]
repo := parts[1]
filePath := strings.Join(parts[2:], "/")
// Construct the raw file URL
rawURL := fmt.Sprintf("https://%s/%s/%s/raw/branch/pages/public/%s", GITDOMAIN, user, repo, filePath)
// Fetch the content from the raw URL
resp, err := http.Get(rawURL)
if err != nil || resp.StatusCode != http.StatusOK {
fmt.Println("Failed to fetch file:", err)
http.Error(w, "Failed to fetch file", http.StatusNotFound)
return
}
defer resp.Body.Close()
// Read the content
content, err := ioutil.ReadAll(resp.Body)
if err != nil {
http.Error(w, "Failed to read file content", http.StatusInternalServerError)
return
}
// Determine the content type based on the file extension
contentType := http.DetectContentType(content)
if strings.HasSuffix(filePath, ".css") {
contentType = "text/css"
} else if strings.HasSuffix(filePath, ".html") {
contentType = "text/html"
} else if strings.HasSuffix(filePath, ".js") {
contentType = "application/javascript"
} else if strings.HasSuffix(filePath, ".png") {
contentType = "image/png"
} else if strings.HasSuffix(filePath, ".jpg") || strings.HasSuffix(filePath, ".jpeg") {
contentType = "image/jpeg"
} else if strings.HasSuffix(filePath, ".gif") {
contentType = "image/gif"
}
// Rewrite links in the content
var rewrittenContent = content
if contentType == "text/html"{
rewrittenContent = []byte(rewriteLinks(string(content), user, repo))
}
// Set the content type and write the response
w.Header().Set("Content-Type", contentType)
w.Write([]byte(rewrittenContent))
}
func rewriteLinks(content, user, repo string) string {
// Regular expressions to match URLs
linkRegex := regexp.MustCompile(`(?i)(href|src)="([^"]+)"`)
replacedContent := linkRegex.ReplaceAllStringFunc(content, func(match string) string {
// Extract the URL
submatches := linkRegex.FindStringSubmatch(match)
if len(submatches) < 3 {
return match // Return the original match if it doesn't match
}
url := submatches[2]
// Rewrite the URL
rewrittenURL := rewriteURL(url, user, repo)
return fmt.Sprintf("%s=\"%s\"", submatches[1], rewrittenURL)
})
return replacedContent
}
func rewriteURL(url, user, repo string) string {
// Check if the URL is relative or absolute
if strings.HasPrefix(url, "/") {
// absolute URL, rewrite it
return fmt.Sprintf("https://%s/%s/%s/raw/branch/pages/public%s", GITDOMAIN, user, repo, url)
}
// Return the original URL if it's not relative
return url
}