blob: cc24f2f1b0dc2f54a72737f58eb2cc5e45cf31b2 [file] [log] [blame]
// Copyright 2017 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package vcweb
import (
"fmt"
"log"
"net/http"
"net/http/cgi"
"os"
"os/exec"
"path/filepath"
"sync"
)
type fossilHandler struct {
once sync.Once
fossilPath string
fossilPathErr error
}
func (h *fossilHandler) Available() bool {
h.once.Do(func() {
h.fossilPath, h.fossilPathErr = exec.LookPath("fossil")
})
return h.fossilPathErr == nil
}
func (h *fossilHandler) Handler(dir string, env []string, logger *log.Logger) (http.Handler, error) {
if !h.Available() {
return nil, ServerNotInstalledError{name: "fossil"}
}
name := filepath.Base(dir)
db := filepath.Join(dir, name+".fossil")
cgiPath := db + ".cgi"
cgiScript := fmt.Sprintf("#!%s\nrepository: %s\n", h.fossilPath, db)
if err := os.WriteFile(cgiPath, []byte(cgiScript), 0755); err != nil {
return nil, err
}
handler := http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) {
if _, err := os.Stat(db); err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
ch := &cgi.Handler{
Env: env,
Logger: logger,
Path: h.fossilPath,
Args: []string{cgiPath},
Dir: dir,
}
ch.ServeHTTP(w, req)
})
return handler, nil
}