github.com/bir3/gocompiler@v0.3.205/src/cmd/gocmd/internal/vcweb/fossil.go (about) 1 // Copyright 2017 The Go Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 package vcweb 6 7 import ( 8 "fmt" 9 "io/ioutil" 10 "log" 11 "net/http" 12 "net/http/cgi" 13 "os" 14 "os/exec" 15 "path/filepath" 16 "sync" 17 ) 18 19 type fossilHandler struct { 20 once sync.Once 21 fossilPath string 22 fossilPathErr error 23 } 24 25 func (h *fossilHandler) Available() bool { 26 h.once.Do(func() { 27 h.fossilPath, h.fossilPathErr = exec.LookPath("fossil") 28 }) 29 return h.fossilPathErr == nil 30 } 31 32 func (h *fossilHandler) Handler(dir string, env []string, logger *log.Logger) (http.Handler, error) { 33 if !h.Available() { 34 return nil, ServerNotInstalledError{name: "fossil"} 35 } 36 37 name := filepath.Base(dir) 38 db := filepath.Join(dir, name+".fossil") 39 40 cgiPath := db + ".cgi" 41 cgiScript := fmt.Sprintf("#!%s\nrepository: %s\n", h.fossilPath, db) 42 if err := ioutil.WriteFile(cgiPath, []byte(cgiScript), 0755); err != nil { 43 return nil, err 44 } 45 46 handler := http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) { 47 if _, err := os.Stat(db); err != nil { 48 http.Error(w, err.Error(), http.StatusInternalServerError) 49 return 50 } 51 ch := &cgi.Handler{ 52 Env: env, 53 Logger: logger, 54 Path: h.fossilPath, 55 Args: []string{cgiPath}, 56 Dir: dir, 57 } 58 ch.ServeHTTP(w, req) 59 }) 60 61 return handler, nil 62 }