aboutsummaryrefslogtreecommitdiff
path: root/internal/modules/handler.go
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--internal/modules/handler.go107
1 files changed, 81 insertions, 26 deletions
diff --git a/internal/modules/handler.go b/internal/modules/handler.go
index 9fa1094..c01f716 100644
--- a/internal/modules/handler.go
+++ b/internal/modules/handler.go
@@ -5,6 +5,7 @@ import (
"fmt"
"log/slog"
"net/http"
+ "net/url"
"path/filepath"
"strings"
@@ -18,6 +19,74 @@ type ModuleHandler struct {
serverHost string
}
+// normalizeImportPath creates a properly formatted full import path
+func (h *ModuleHandler) normalizeImportPath(modulePath string) (string, error) {
+ if h.serverHost == "" {
+ return "", fmt.Errorf("serverHost cannot be empty")
+ }
+ if modulePath == "" {
+ return "", fmt.Errorf("modulePath cannot be empty")
+ }
+ if strings.Contains(modulePath, "..") {
+ return "", fmt.Errorf("modulePath cannot contain '..'")
+ }
+
+ // Clean the inputs
+ host := strings.TrimRight(h.serverHost, "/")
+ module := strings.Trim(modulePath, "/")
+
+ // Validate that module path doesn't contain invalid characters
+ if strings.ContainsAny(module, " \t\n\r") {
+ return "", fmt.Errorf("modulePath cannot contain whitespace characters")
+ }
+
+ return host + "/" + module, nil
+}
+
+// buildRepoURL creates a proper repository URL
+func (h *ModuleHandler) buildRepoURL(modulePath string) (string, error) {
+ _, err := h.normalizeImportPath(modulePath)
+ if err != nil {
+ return "", err
+ }
+
+ // Use proper URL building to ensure valid URLs
+ repoURL := &url.URL{
+ Scheme: "https",
+ Host: h.serverHost,
+ Path: "/" + strings.Trim(modulePath, "/"),
+ }
+
+ return repoURL.String(), nil
+}
+
+// generateGoImportHTML creates the HTML response for go-import requests
+func (h *ModuleHandler) generateGoImportHTML(modulePath string) (string, error) {
+ fullImportPath, err := h.normalizeImportPath(modulePath)
+ if err != nil {
+ return "", fmt.Errorf("failed to normalize import path: %w", err)
+ }
+
+ repoURL, err := h.buildRepoURL(modulePath)
+ if err != nil {
+ return "", fmt.Errorf("failed to build repository URL: %w", err)
+ }
+
+ return fmt.Sprintf(`<!DOCTYPE html>
+<html>
+<head>
+ <meta name="go-import" content="%s git %s">
+ <meta name="go-source" content="%s %s %s/tree/{/dir} %s/blob/{/dir}/{file}#L{line}">
+</head>
+<body>
+ go get %s
+</body>
+</html>`,
+ fullImportPath, repoURL,
+ fullImportPath, repoURL, repoURL, repoURL,
+ fullImportPath), nil
+}
+
// NewModuleHandler creates a new module handler with explicit routes for known repos
func NewModuleHandler(reposDir, serverHost string, config *admin.ServerRepos) http.Handler {
handler := &ModuleHandler{
@@ -266,19 +335,12 @@ func (h *ModuleHandler) handleGoImportForModule(w http.ResponseWriter, r *http.R
}
// Generate HTML with go-import meta tag
- html := fmt.Sprintf(`<!DOCTYPE html>
-<html>
-<head>
- <meta name="go-import" content="%s git https://%s/%s">
- <meta name="go-source" content="%s https://%s/%s https://%s/%s/tree/{/dir} https://%s/%s/blob/{/dir}/{file}#L{line}">
-</head>
-<body>
- go get %s
-</body>
-</html>`,
- modulePath, h.serverHost, modulePath,
- modulePath, h.serverHost, modulePath, h.serverHost, modulePath, h.serverHost, modulePath,
- modulePath)
+ html, err := h.generateGoImportHTML(modulePath)
+ if err != nil {
+ slog.Error("failed to generate go-import HTML", "module", modulePath, "error", err)
+ http.Error(w, "Internal Server Error", http.StatusInternalServerError)
+ return
+ }
w.Header().Set("Content-Type", "text/html; charset=utf-8")
w.WriteHeader(http.StatusOK)
@@ -300,19 +362,12 @@ func (h *ModuleHandler) handleGoImport(w http.ResponseWriter, r *http.Request) {
modulePath := ExtractModulePath(r.URL.Path)
// Generate HTML with go-import meta tag
- html := fmt.Sprintf(`<!DOCTYPE html>
-<html>
-<head>
- <meta name="go-import" content="%s git https://%s/%s">
- <meta name="go-source" content="%s https://%s/%s https://%s/%s/tree/{/dir} https://%s/%s/blob/{/dir}/{file}#L{line}">
-</head>
-<body>
- go get %s
-</body>
-</html>`,
- modulePath, h.serverHost, modulePath,
- modulePath, h.serverHost, modulePath, h.serverHost, modulePath, h.serverHost, modulePath,
- modulePath)
+ html, err := h.generateGoImportHTML(modulePath)
+ if err != nil {
+ slog.Error("failed to generate go-import HTML", "module", modulePath, "error", err)
+ http.Error(w, "Internal Server Error", http.StatusInternalServerError)
+ return
+ }
w.Header().Set("Content-Type", "text/html; charset=utf-8")
w.WriteHeader(http.StatusOK)