diff options
Diffstat (limited to 'src/cmd/go/internal/vcweb/fossil.go')
-rw-r--r-- | src/cmd/go/internal/vcweb/fossil.go | 62 |
1 files changed, 62 insertions, 0 deletions
diff --git a/src/cmd/go/internal/vcweb/fossil.go b/src/cmd/go/internal/vcweb/fossil.go new file mode 100644 index 0000000..4b5db22 --- /dev/null +++ b/src/cmd/go/internal/vcweb/fossil.go @@ -0,0 +1,62 @@ +// 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" + "io/ioutil" + "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 := ioutil.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 +} |