Structs
ScriptNotFoundError
struct
#
A ScriptNotFoundError indicates that the requested script file does not exist.
(It typically wraps a "stat" error for the script file.)
type ScriptNotFoundError struct {
err error
}
Server
struct
#
A Server serves cached, dynamically-generated version control repositories.
type Server struct {
env []string
logger *log.Logger
scriptDir string
workDir string
homeDir string
engine *script.Engine
scriptCache sync.Map
vcsHandlers map[string]vcsHandler
}
ServerNotInstalledError
struct
#
A ServerNotInstalledError indicates that the server binary required for the
indicated VCS does not exist.
type ServerNotInstalledError struct {
name string
}
accessToken
struct
#
type accessToken struct {
Username string
Password string
StatusCode int
Message string
}
authHandler
struct
#
authHandler serves requests only if the Basic Auth data sent with the request
matches the contents of a ".access" file in the requested directory.
For each request, the handler looks for a file named ".access" and parses it
as a JSON-serialized accessToken. If the credentials from the request match
the accessToken, the file is served normally; otherwise, it is rejected with
the StatusCode and Message provided by the token.
type authHandler struct {
}
bzrHandler
struct
#
type bzrHandler struct {
}
dirHandler
struct
#
dirHandler is a vcsHandler that serves the raw contents of a directory.
type dirHandler struct {
}
fossilHandler
struct
#
type fossilHandler struct {
once sync.Once
fossilPath string
fossilPathErr error
}
gitHandler
struct
#
type gitHandler struct {
once sync.Once
gitPath string
gitPathErr error
}
hgHandler
struct
#
type hgHandler struct {
once sync.Once
hgPath string
hgPathErr error
}
insecureHandler
struct
#
insecureHandler redirects requests to the same host and path but using the
"http" scheme instead of "https".
type insecureHandler struct {
}
scriptCtx
struct
#
A scriptCtx is a context.Context that stores additional state for script
commands.
type scriptCtx struct {
context.Context
server *Server
commitTime time.Time
handlerName string
handler http.Handler
}
scriptCtxKey
struct
#
scriptCtxKey is the key associating the *scriptCtx in a script's Context..
type scriptCtxKey struct {
}
scriptResult
struct
#
A scriptResult describes the cached result of executing a vcweb script.
type scriptResult struct {
mu sync.RWMutex
hash [sha256.Size]byte
hashTime time.Time
handler http.Handler
err error
}
svnHandler
struct
#
An svnHandler serves requests for Subversion repos.
Unlike the other vcweb handlers, svnHandler does not serve the Subversion
protocol directly over the HTTP connection. Instead, it opens a separate port
that serves the (non-HTTP) 'svn' protocol. The test binary can retrieve the
URL for that port by sending an HTTP request with the query parameter
"vcwebsvn=1".
We take this approach because the 'svn' protocol is implemented by a
lightweight 'svnserve' binary that is usually packaged along with the 'svn'
client binary, whereas only known implementation of the Subversion HTTP
protocol is the mod_dav_svn apache2 module. Apache2 has a lot of dependencies
and also seems to rely on global configuration via well-known file paths, so
implementing a hermetic test using apache2 would require the test to run in a
complicated container environment, which wouldn't be nearly as
straightforward for Go contributors to set up and test against on their local
machine.
type svnHandler struct {
svnRoot string
logger *log.Logger
pathOnce sync.Once
svnservePath string
svnserveErr error
listenOnce sync.Once
s chan *svnState
}
svnState
struct
#
An svnState describes the state of a port serving the 'svn://' protocol.
type svnState struct {
listener net.Listener
listenErr error
conns map[net.Conn]struct{...}
closing bool
done chan struct{...}
}
Functions
Available
method
#
func (*dirHandler) Available() bool
Available
method
#
func (h *insecureHandler) Available() bool
Available
method
#
func (h *svnHandler) Available() bool
Available
method
#
func (h *hgHandler) Available() bool
Available
method
#
func (h *authHandler) Available() bool
Available
method
#
func (h *gitHandler) Available() bool
Available
method
#
func (h *fossilHandler) Available() bool
Available
method
#
func (*bzrHandler) Available() bool
Close
method
#
func (s *Server) Close() error
Close
method
#
Close stops accepting new svn:// connections and terminates the existing
ones, then waits for the 'svnserve' subprocesses to complete.
func (h *svnHandler) Close() error
Error
method
#
func (e ScriptNotFoundError) Error() string
Error
method
#
func (v ServerNotInstalledError) Error() string
HandleScript
method
#
HandleScript ensures that the script at scriptRelPath has been evaluated
with its current contents.
If the script completed successfully, HandleScript invokes f on the handler
with the script's result still read-locked, and waits for it to return. (That
ensures that cache invalidation does not race with an in-flight handler.)
Otherwise, HandleScript returns the (cached) error from executing the script.
func (s *Server) HandleScript(scriptRelPath string, logger *log.Logger, f func(http.Handler)) error
Handler
method
#
func (*dirHandler) Handler(dir string, env []string, logger *log.Logger) (http.Handler, error)
Handler
method
#
func (h *gitHandler) Handler(dir string, env []string, logger *log.Logger) (http.Handler, error)
Handler
method
#
func (*bzrHandler) Handler(dir string, env []string, logger *log.Logger) (http.Handler, error)
Handler
method
#
func (h *fossilHandler) Handler(dir string, env []string, logger *log.Logger) (http.Handler, error)
Handler
method
#
func (h *authHandler) Handler(dir string, env []string, logger *log.Logger) (http.Handler, error)
Handler
method
#
Handler returns an http.Handler that checks for the "vcwebsvn" query
parameter and then serves the 'svn://' URL for the repository at the
requested path.
The HTTP client is expected to read that URL and pass it to the 'svn' client.
func (h *svnHandler) Handler(dir string, env []string, logger *log.Logger) (http.Handler, error)
Handler
method
#
func (h *hgHandler) Handler(dir string, env []string, logger *log.Logger) (http.Handler, error)
Handler
method
#
func (h *insecureHandler) Handler(dir string, env []string, logger *log.Logger) (http.Handler, error)
NewServer
function
#
NewServer returns a Server that generates and serves repositories in workDir
using the scripts found in scriptDir and its subdirectories.
A request for the path /foo/bar/baz will be handled by the first script along
that path that exists: $scriptDir/foo.txt, $scriptDir/foo/bar.txt, or
$scriptDir/foo/bar/baz.txt.
func NewServer(scriptDir string, workDir string, logger *log.Logger) (*Server, error)
ServeHTTP
method
#
ServeHTTP implements [http.Handler] for version-control repositories.
func (s *Server) ServeHTTP(w http.ResponseWriter, req *http.Request)
ServeHTTP
method
#
func (h *insecureHandler) ServeHTTP(w http.ResponseWriter, req *http.Request)
Unwrap
method
#
func (e ScriptNotFoundError) Unwrap() error
Value
method
#
func (sc *scriptCtx) Value(key any) any
getScriptCtx
function
#
func getScriptCtx(st *script.State) (*scriptCtx, error)
help
method
#
help serves a plain-text summary of the server's supported script language.
func (s *Server) help(w http.ResponseWriter, req *http.Request)
homeEnvName
function
#
homeEnvName returns the environment variable used by os.UserHomeDir
to locate the user's home directory.
func homeEnvName() string
loadScript
method
#
loadScript interprets the given script content using the vcweb script engine.
loadScript always returns either a non-nil handler or a non-nil error.
The script content must be a txtar archive with a comment containing a script
with exactly one "handle" command and zero or more VCS commands to prepare
the repository to be served.
func (s *Server) loadScript(ctx context.Context, logger *log.Logger, scriptPath string, scriptContent []byte, workDir string) (http.Handler, error)
newScriptEngine
function
#
newScriptEngine returns a script engine augmented with commands for
reproducing version-control repositories by replaying commits.
func newScriptEngine() *script.Engine
newState
method
#
newState returns a new script.State for executing scripts in workDir.
func (s *Server) newState(ctx context.Context, workDir string) (*script.State, error)
overview
method
#
overview serves an HTML summary of the status of the scripts in the server's
script directory.
func (s *Server) overview(w http.ResponseWriter, r *http.Request)
pathEnvName
function
#
pathEnvName returns the environment variable used by exec.LookPath to
identify directories to search for executables.
func pathEnvName() string
scriptAt
function
#
func scriptAt() script.Cmd
scriptEnviron
function
#
scriptEnviron returns a new environment that attempts to provide predictable
behavior for the supported version-control tools.
func scriptEnviron(homeDir string) []string
scriptHandle
function
#
func scriptHandle() script.Cmd
scriptModzip
function
#
func scriptModzip() script.Cmd
scriptUnquote
function
#
func scriptUnquote() script.Cmd
serve
method
#
serve serves a single 'svn://' connection on c.
func (h *svnHandler) serve(c net.Conn)
tempEnvName
function
#
tempEnvName returns the environment variable used by os.TempDir
to locate the default directory for temporary files.
func tempEnvName() string