mirror of
https://github.com/restic/rest-server.git
synced 2025-10-19 07:33:21 +00:00
Reformat comments
This commit is contained in:
parent
d74e19b13d
commit
5de6d4fd00
11 changed files with 67 additions and 107 deletions
|
@ -2,8 +2,7 @@ package errors
|
||||||
|
|
||||||
import "fmt"
|
import "fmt"
|
||||||
|
|
||||||
// fatalError is an error that should be printed to the user, then the program
|
// fatalError is an error that should be printed to the user, then the program should exit with an error code.
|
||||||
// should exit with an error code.
|
|
||||||
type fatalError string
|
type fatalError string
|
||||||
|
|
||||||
func (e fatalError) Error() string {
|
func (e fatalError) Error() string {
|
||||||
|
@ -14,14 +13,12 @@ func (e fatalError) Fatal() bool {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
// Fataler is an error which should be printed to the user directly.
|
// Fataler is an error which should be printed to the user directly. Afterwards, the program should exit with an error.
|
||||||
// Afterwards, the program should exit with an error.
|
|
||||||
type Fataler interface {
|
type Fataler interface {
|
||||||
Fatal() bool
|
Fatal() bool
|
||||||
}
|
}
|
||||||
|
|
||||||
// IsFatal returns true if err is a fatal message that should be printed to the
|
// IsFatal returns true if err is a fatal message that should be printed to the user. Then, the program should exit.
|
||||||
// user. Then, the program should exit.
|
|
||||||
func IsFatal(err error) bool {
|
func IsFatal(err error) bool {
|
||||||
e, ok := err.(Fataler)
|
e, ok := err.(Fataler)
|
||||||
return ok && e.Fatal()
|
return ok && e.Fatal()
|
||||||
|
|
|
@ -7,14 +7,13 @@ func Cause(err error) error {
|
||||||
return errors.Cause(err)
|
return errors.Cause(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
// New creates a new error based on message. Wrapped so that this package does
|
// New creates a new error based on message. Wrapped so that this package does not appear in the stack trace.
|
||||||
// not appear in the stack trace.
|
|
||||||
var New = errors.New
|
var New = errors.New
|
||||||
|
|
||||||
// Errorf creates an error based on a format string and values. Wrapped so that
|
// Errorf creates an error based on a format string and values. Wrapped so that this package does not appear in the
|
||||||
// this package does not appear in the stack trace.
|
// stack trace.
|
||||||
var Errorf = errors.Errorf
|
var Errorf = errors.Errorf
|
||||||
|
|
||||||
// Wrap wraps an error retrieved from outside of restic. Wrapped so that this
|
// Wrap wraps an error retrieved from outside of restic. Wrapped so that this package does not appear in the stack
|
||||||
// package does not appear in the stack trace.
|
// trace.
|
||||||
var Wrap = errors.Wrap
|
var Wrap = errors.Wrap
|
||||||
|
|
|
@ -9,8 +9,7 @@ import (
|
||||||
"github.com/zcalusic/restic-server/errors"
|
"github.com/zcalusic/restic-server/errors"
|
||||||
)
|
)
|
||||||
|
|
||||||
// DeviceID extracts the device ID from an os.FileInfo object by casting it
|
// DeviceID extracts the device ID from an os.FileInfo object by casting it to syscall.Stat_t
|
||||||
// to syscall.Stat_t
|
|
||||||
func DeviceID(fi os.FileInfo) (deviceID uint64, err error) {
|
func DeviceID(fi os.FileInfo) (deviceID uint64, err error) {
|
||||||
if fi == nil {
|
if fi == nil {
|
||||||
return 0, errors.New("unable to determine device: fi is nil")
|
return 0, errors.New("unable to determine device: fi is nil")
|
||||||
|
@ -21,8 +20,7 @@ func DeviceID(fi os.FileInfo) (deviceID uint64, err error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if st, ok := fi.Sys().(*syscall.Stat_t); ok {
|
if st, ok := fi.Sys().(*syscall.Stat_t); ok {
|
||||||
// st.Dev is uint32 on Darwin and uint64 on Linux. Just cast
|
// st.Dev is uint32 on Darwin and uint64 on Linux. Just cast everything to uint64.
|
||||||
// everything to uint64.
|
|
||||||
return uint64(st.Dev), nil
|
return uint64(st.Dev), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -8,8 +8,7 @@ import (
|
||||||
"github.com/zcalusic/restic-server/errors"
|
"github.com/zcalusic/restic-server/errors"
|
||||||
)
|
)
|
||||||
|
|
||||||
// DeviceID extracts the device ID from an os.FileInfo object by casting it
|
// DeviceID extracts the device ID from an os.FileInfo object by casting it to syscall.Stat_t.
|
||||||
// to syscall.Stat_t
|
|
||||||
func DeviceID(fi os.FileInfo) (deviceID uint64, err error) {
|
func DeviceID(fi os.FileInfo) (deviceID uint64, err error) {
|
||||||
return 0, errors.New("Device IDs are not supported on Windows")
|
return 0, errors.New("Device IDs are not supported on Windows")
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,3 +1,2 @@
|
||||||
// Package fs implements an OS independend abstraction of a file system
|
// Package fs implements an OS independent abstraction of a file system suitable for backup purposes.
|
||||||
// suitable for backup purposes.
|
|
||||||
package fs
|
package fs
|
||||||
|
|
83
fs/file.go
83
fs/file.go
|
@ -21,25 +21,24 @@ type File interface {
|
||||||
Stat() (os.FileInfo, error)
|
Stat() (os.FileInfo, error)
|
||||||
}
|
}
|
||||||
|
|
||||||
// fixpath returns an absolute path on windows, so restic can open long file
|
// fixpath returns an absolute path on windows, so restic can open long file names.
|
||||||
// names.
|
|
||||||
func fixpath(name string) string {
|
func fixpath(name string) string {
|
||||||
if runtime.GOOS == "windows" {
|
if runtime.GOOS == "windows" {
|
||||||
abspath, err := filepath.Abs(name)
|
abspath, err := filepath.Abs(name)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
// Check if \\?\UNC\ already exist
|
// Check if \\?\UNC\ already exists.
|
||||||
if strings.HasPrefix(abspath, `\\?\UNC\`) {
|
if strings.HasPrefix(abspath, `\\?\UNC\`) {
|
||||||
return abspath
|
return abspath
|
||||||
}
|
}
|
||||||
// Check if \\?\ already exist
|
// Check if \\?\ already exists.
|
||||||
if strings.HasPrefix(abspath, `\\?\`) {
|
if strings.HasPrefix(abspath, `\\?\`) {
|
||||||
return abspath
|
return abspath
|
||||||
}
|
}
|
||||||
// Check if path starts with \\
|
// Check if path starts with \\.
|
||||||
if strings.HasPrefix(abspath, `\\`) {
|
if strings.HasPrefix(abspath, `\\`) {
|
||||||
return strings.Replace(abspath, `\\`, `\\?\UNC\`, 1)
|
return strings.Replace(abspath, `\\`, `\\?\UNC\`, 1)
|
||||||
}
|
}
|
||||||
// Normal path
|
// Normal path.
|
||||||
return `\\?\` + abspath
|
return `\\?\` + abspath
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -51,95 +50,77 @@ func Chmod(name string, mode os.FileMode) error {
|
||||||
return os.Chmod(fixpath(name), mode)
|
return os.Chmod(fixpath(name), mode)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Mkdir creates a new directory with the specified name and permission bits.
|
// Mkdir creates a new directory with the specified name and permission bits. If there is an error, it will be of type
|
||||||
// If there is an error, it will be of type *PathError.
|
// *PathError.
|
||||||
func Mkdir(name string, perm os.FileMode) error {
|
func Mkdir(name string, perm os.FileMode) error {
|
||||||
return os.Mkdir(fixpath(name), perm)
|
return os.Mkdir(fixpath(name), perm)
|
||||||
}
|
}
|
||||||
|
|
||||||
// MkdirAll creates a directory named path,
|
// MkdirAll creates a directory named path, along with any necessary parents, and returns nil, or else returns an error.
|
||||||
// along with any necessary parents, and returns nil,
|
// The permission bits perm are used for all directories that MkdirAll creates. If path is already a directory,
|
||||||
// or else returns an error.
|
// MkdirAll does nothing and returns nil.
|
||||||
// The permission bits perm are used for all
|
|
||||||
// directories that MkdirAll creates.
|
|
||||||
// If path is already a directory, MkdirAll does nothing
|
|
||||||
// and returns nil.
|
|
||||||
func MkdirAll(path string, perm os.FileMode) error {
|
func MkdirAll(path string, perm os.FileMode) error {
|
||||||
return os.MkdirAll(fixpath(path), perm)
|
return os.MkdirAll(fixpath(path), perm)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Readlink returns the destination of the named symbolic link.
|
// Readlink returns the destination of the named symbolic link. If there is an error, it will be of type *PathError.
|
||||||
// If there is an error, it will be of type *PathError.
|
|
||||||
func Readlink(name string) (string, error) {
|
func Readlink(name string) (string, error) {
|
||||||
return os.Readlink(fixpath(name))
|
return os.Readlink(fixpath(name))
|
||||||
}
|
}
|
||||||
|
|
||||||
// Remove removes the named file or directory.
|
// Remove removes the named file or directory. If there is an error, it will be of type *PathError.
|
||||||
// If there is an error, it will be of type *PathError.
|
|
||||||
func Remove(name string) error {
|
func Remove(name string) error {
|
||||||
return os.Remove(fixpath(name))
|
return os.Remove(fixpath(name))
|
||||||
}
|
}
|
||||||
|
|
||||||
// RemoveAll removes path and any children it contains.
|
// RemoveAll removes path and any children it contains. It removes everything it can but returns the first error it
|
||||||
// It removes everything it can but returns the first error
|
// encounters. If the path does not exist, RemoveAll returns nil (no error).
|
||||||
// it encounters. If the path does not exist, RemoveAll
|
|
||||||
// returns nil (no error).
|
|
||||||
func RemoveAll(path string) error {
|
func RemoveAll(path string) error {
|
||||||
return os.RemoveAll(fixpath(path))
|
return os.RemoveAll(fixpath(path))
|
||||||
}
|
}
|
||||||
|
|
||||||
// Rename renames (moves) oldpath to newpath.
|
// Rename renames (moves) oldpath to newpath. If newpath already exists, Rename replaces it. OS-specific restrictions
|
||||||
// If newpath already exists, Rename replaces it.
|
// may apply when oldpath and newpath are in different directories. If there is an error, it will be of type
|
||||||
// OS-specific restrictions may apply when oldpath and newpath are in different directories.
|
// *LinkError.
|
||||||
// If there is an error, it will be of type *LinkError.
|
|
||||||
func Rename(oldpath, newpath string) error {
|
func Rename(oldpath, newpath string) error {
|
||||||
return os.Rename(fixpath(oldpath), fixpath(newpath))
|
return os.Rename(fixpath(oldpath), fixpath(newpath))
|
||||||
}
|
}
|
||||||
|
|
||||||
// Symlink creates newname as a symbolic link to oldname.
|
// Symlink creates newname as a symbolic link to oldname. If there is an error, it will be of type *LinkError.
|
||||||
// If there is an error, it will be of type *LinkError.
|
|
||||||
func Symlink(oldname, newname string) error {
|
func Symlink(oldname, newname string) error {
|
||||||
return os.Symlink(fixpath(oldname), fixpath(newname))
|
return os.Symlink(fixpath(oldname), fixpath(newname))
|
||||||
}
|
}
|
||||||
|
|
||||||
// Stat returns a FileInfo structure describing the named file.
|
// Stat returns a FileInfo structure describing the named file. If there is an error, it will be of type *PathError.
|
||||||
// If there is an error, it will be of type *PathError.
|
|
||||||
func Stat(name string) (os.FileInfo, error) {
|
func Stat(name string) (os.FileInfo, error) {
|
||||||
return os.Stat(fixpath(name))
|
return os.Stat(fixpath(name))
|
||||||
}
|
}
|
||||||
|
|
||||||
// Lstat returns the FileInfo structure describing the named file.
|
// Lstat returns the FileInfo structure describing the named file. If the file is a symbolic link, the returned
|
||||||
// If the file is a symbolic link, the returned FileInfo
|
// FileInfo describes the symbolic link. Lstat makes no attempt to follow the link. If there is an error, it will be
|
||||||
// describes the symbolic link. Lstat makes no attempt to follow the link.
|
// of type *PathError.
|
||||||
// If there is an error, it will be of type *PathError.
|
|
||||||
func Lstat(name string) (os.FileInfo, error) {
|
func Lstat(name string) (os.FileInfo, error) {
|
||||||
return os.Lstat(fixpath(name))
|
return os.Lstat(fixpath(name))
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create creates the named file with mode 0666 (before umask), truncating
|
// Create creates the named file with mode 0666 (before umask), truncating it if it already exists. If successful,
|
||||||
// it if it already exists. If successful, methods on the returned
|
// methods on the returned File can be used for I/O; the associated file descriptor has mode O_RDWR. If there is an
|
||||||
// File can be used for I/O; the associated file descriptor has mode
|
// error, it will be of type *PathError.
|
||||||
// O_RDWR.
|
|
||||||
// If there is an error, it will be of type *PathError.
|
|
||||||
func Create(name string) (*os.File, error) {
|
func Create(name string) (*os.File, error) {
|
||||||
return os.Create(fixpath(name))
|
return os.Create(fixpath(name))
|
||||||
}
|
}
|
||||||
|
|
||||||
// OpenFile is the generalized open call; most users will use Open
|
// OpenFile is the generalized open call; most users will use Open or Create instead. It opens the named file with
|
||||||
// or Create instead. It opens the named file with specified flag
|
// specified flag (O_RDONLY etc.) and perm, (0666 etc.) if applicable. If successful, methods on the returned File can
|
||||||
// (O_RDONLY etc.) and perm, (0666 etc.) if applicable. If successful,
|
// be used for I/O. If there is an error, it will be of type *PathError.
|
||||||
// methods on the returned File can be used for I/O.
|
|
||||||
// If there is an error, it will be of type *PathError.
|
|
||||||
func OpenFile(name string, flag int, perm os.FileMode) (*os.File, error) {
|
func OpenFile(name string, flag int, perm os.FileMode) (*os.File, error) {
|
||||||
return os.OpenFile(fixpath(name), flag, perm)
|
return os.OpenFile(fixpath(name), flag, perm)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Walk walks the file tree rooted at root, calling walkFn for each file or
|
// Walk walks the file tree rooted at root, calling walkFn for each file or directory in the tree, including root. All
|
||||||
// directory in the tree, including root. All errors that arise visiting files
|
// errors that arise visiting files and directories are filtered by walkFn. The files are walked in lexical order, which
|
||||||
// and directories are filtered by walkFn. The files are walked in lexical
|
// makes the output deterministic but means that for very large directories Walk can be inefficient. Walk does not
|
||||||
// order, which makes the output deterministic but means that for very
|
// follow symbolic links.
|
||||||
// large directories Walk can be inefficient.
|
|
||||||
// Walk does not follow symbolic links.
|
|
||||||
func Walk(root string, walkFn filepath.WalkFunc) error {
|
func Walk(root string, walkFn filepath.WalkFunc) error {
|
||||||
return filepath.Walk(fixpath(root), walkFn)
|
return filepath.Walk(fixpath(root), walkFn)
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,8 +19,7 @@ func Open(name string) (File, error) {
|
||||||
return &nonCachingFile{File: file}, err
|
return &nonCachingFile{File: file}, err
|
||||||
}
|
}
|
||||||
|
|
||||||
// nonCachingFile wraps an *os.File and calls fadvise() to instantly forget
|
// nonCachingFile wraps an *os.File and calls fadvise() to instantly forget data that has been read or written.
|
||||||
// data that has been read or written.
|
|
||||||
type nonCachingFile struct {
|
type nonCachingFile struct {
|
||||||
*os.File
|
*os.File
|
||||||
readOffset int64
|
readOffset int64
|
||||||
|
|
26
handlers.go
26
handlers.go
|
@ -21,9 +21,8 @@ type Context struct {
|
||||||
path string
|
path string
|
||||||
}
|
}
|
||||||
|
|
||||||
// AuthHandler wraps h with a http.HandlerFunc that performs basic
|
// AuthHandler wraps h with a http.HandlerFunc that performs basic authentication against the user/passwords pairs
|
||||||
// authentication against the user/passwords pairs stored in f and returns the
|
// stored in f and returns the http.HandlerFunc.
|
||||||
// http.HandlerFunc.
|
|
||||||
func AuthHandler(f *HtpasswdFile, h http.Handler) http.HandlerFunc {
|
func AuthHandler(f *HtpasswdFile, h http.Handler) http.HandlerFunc {
|
||||||
return func(w http.ResponseWriter, r *http.Request) {
|
return func(w http.ResponseWriter, r *http.Request) {
|
||||||
username, password, ok := r.BasicAuth()
|
username, password, ok := r.BasicAuth()
|
||||||
|
@ -39,8 +38,7 @@ func AuthHandler(f *HtpasswdFile, h http.Handler) http.HandlerFunc {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// CheckConfig returns a http.HandlerFunc that checks whether
|
// CheckConfig returns a http.HandlerFunc that checks whether a configuration exists.
|
||||||
// a configuration exists.
|
|
||||||
func CheckConfig(c *Context) http.HandlerFunc {
|
func CheckConfig(c *Context) http.HandlerFunc {
|
||||||
return func(w http.ResponseWriter, r *http.Request) {
|
return func(w http.ResponseWriter, r *http.Request) {
|
||||||
config := filepath.Join(c.path, "config")
|
config := filepath.Join(c.path, "config")
|
||||||
|
@ -53,8 +51,7 @@ func CheckConfig(c *Context) http.HandlerFunc {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetConfig returns a http.HandlerFunc that allows for a
|
// GetConfig returns a http.HandlerFunc that allows for a config to be retrieved.
|
||||||
// config to be retrieved.
|
|
||||||
func GetConfig(c *Context) http.HandlerFunc {
|
func GetConfig(c *Context) http.HandlerFunc {
|
||||||
return func(w http.ResponseWriter, r *http.Request) {
|
return func(w http.ResponseWriter, r *http.Request) {
|
||||||
config := filepath.Join(c.path, "config")
|
config := filepath.Join(c.path, "config")
|
||||||
|
@ -67,8 +64,7 @@ func GetConfig(c *Context) http.HandlerFunc {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// SaveConfig returns a http.HandlerFunc that allows for a
|
// SaveConfig returns a http.HandlerFunc that allows for a config to be saved.
|
||||||
// config to be saved.
|
|
||||||
func SaveConfig(c *Context) http.HandlerFunc {
|
func SaveConfig(c *Context) http.HandlerFunc {
|
||||||
return func(w http.ResponseWriter, r *http.Request) {
|
return func(w http.ResponseWriter, r *http.Request) {
|
||||||
config := filepath.Join(c.path, "config")
|
config := filepath.Join(c.path, "config")
|
||||||
|
@ -86,8 +82,7 @@ func SaveConfig(c *Context) http.HandlerFunc {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// ListBlobs returns a http.HandlerFunc that lists
|
// ListBlobs returns a http.HandlerFunc that lists all blobs of a given type in an arbitrary order.
|
||||||
// all blobs of a given type in an arbitrary order.
|
|
||||||
func ListBlobs(c *Context) http.HandlerFunc {
|
func ListBlobs(c *Context) http.HandlerFunc {
|
||||||
return func(w http.ResponseWriter, r *http.Request) {
|
return func(w http.ResponseWriter, r *http.Request) {
|
||||||
vars := strings.Split(r.RequestURI, "/")
|
vars := strings.Split(r.RequestURI, "/")
|
||||||
|
@ -111,8 +106,7 @@ func ListBlobs(c *Context) http.HandlerFunc {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// CheckBlob reutrns a http.HandlerFunc that tests whether a blob exists
|
// CheckBlob returns a http.HandlerFunc that tests whether a blob exists and returns 200, if it does, or 404 otherwise.
|
||||||
// and returns 200, if it does, or 404 otherwise.
|
|
||||||
func CheckBlob(c *Context) http.HandlerFunc {
|
func CheckBlob(c *Context) http.HandlerFunc {
|
||||||
return func(w http.ResponseWriter, r *http.Request) {
|
return func(w http.ResponseWriter, r *http.Request) {
|
||||||
vars := strings.Split(r.RequestURI, "/")
|
vars := strings.Split(r.RequestURI, "/")
|
||||||
|
@ -128,8 +122,7 @@ func CheckBlob(c *Context) http.HandlerFunc {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetBlob returns a http.HandlerFunc that retrieves a blob
|
// GetBlob returns a http.HandlerFunc that retrieves a blob from the repository.
|
||||||
// from the repository.
|
|
||||||
func GetBlob(c *Context) http.HandlerFunc {
|
func GetBlob(c *Context) http.HandlerFunc {
|
||||||
return func(w http.ResponseWriter, r *http.Request) {
|
return func(w http.ResponseWriter, r *http.Request) {
|
||||||
vars := strings.Split(r.RequestURI, "/")
|
vars := strings.Split(r.RequestURI, "/")
|
||||||
|
@ -176,8 +169,7 @@ func SaveBlob(c *Context) http.HandlerFunc {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// DeleteBlob returns a http.HandlerFunc that deletes a blob from the
|
// DeleteBlob returns a http.HandlerFunc that deletes a blob from the repository.
|
||||||
// repository.
|
|
||||||
func DeleteBlob(c *Context) http.HandlerFunc {
|
func DeleteBlob(c *Context) http.HandlerFunc {
|
||||||
return func(w http.ResponseWriter, r *http.Request) {
|
return func(w http.ResponseWriter, r *http.Request) {
|
||||||
vars := strings.Split(r.RequestURI, "/")
|
vars := strings.Split(r.RequestURI, "/")
|
||||||
|
|
18
htpasswd.go
18
htpasswd.go
|
@ -36,17 +36,15 @@ import (
|
||||||
"github.com/zcalusic/restic-server/fs"
|
"github.com/zcalusic/restic-server/fs"
|
||||||
)
|
)
|
||||||
|
|
||||||
// lookup passwords in a htpasswd file
|
// Lookup passwords in a htpasswd file. The entries must have been created with -s for SHA encryption.
|
||||||
// The entries must have been created with -s for SHA encryption
|
|
||||||
|
|
||||||
// HtpasswdFile is a map for usernames to passwords.
|
// HtpasswdFile is a map for usernames to passwords.
|
||||||
type HtpasswdFile struct {
|
type HtpasswdFile struct {
|
||||||
Users map[string]string
|
Users map[string]string
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewHtpasswdFromFile reads the users and passwords from a htpasswd
|
// NewHtpasswdFromFile reads the users and passwords from a htpasswd file and returns them. If an error is encountered,
|
||||||
// file and returns them. If an error is encountered, it is returned, together
|
// it is returned, together with a nil-Pointer for the HtpasswdFile.
|
||||||
// with a nil-Pointer for the HtpasswdFile.
|
|
||||||
func NewHtpasswdFromFile(path string) (*HtpasswdFile, error) {
|
func NewHtpasswdFromFile(path string) (*HtpasswdFile, error) {
|
||||||
r, err := fs.Open(path)
|
r, err := fs.Open(path)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -56,9 +54,8 @@ func NewHtpasswdFromFile(path string) (*HtpasswdFile, error) {
|
||||||
return NewHtpasswd(r)
|
return NewHtpasswd(r)
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewHtpasswd reads the users and passwords from a htpasswd
|
// NewHtpasswd reads the users and passwords from a htpasswd datastream in file and returns them. If an error is
|
||||||
// datastream in file and returns them. If an error is encountered,
|
// encountered, it is returned, together with a nil-Pointer for the HtpasswdFile.
|
||||||
// it is returned, together with a nil-Pointer for the HtpasswdFile.
|
|
||||||
func NewHtpasswd(file io.Reader) (*HtpasswdFile, error) {
|
func NewHtpasswd(file io.Reader) (*HtpasswdFile, error) {
|
||||||
cr := csv.NewReader(file)
|
cr := csv.NewReader(file)
|
||||||
cr.Comma = ':'
|
cr.Comma = ':'
|
||||||
|
@ -76,9 +73,8 @@ func NewHtpasswd(file io.Reader) (*HtpasswdFile, error) {
|
||||||
return h, nil
|
return h, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Validate returns true if password matches the stored password
|
// Validate returns true if password matches the stored password for user. If no password for user is stored, or the
|
||||||
// for user. If no password for user is stored, or the password
|
// password is wrong, false is returned.
|
||||||
// is wrong, false is returned.
|
|
||||||
func (h *HtpasswdFile) Validate(user string, password string) bool {
|
func (h *HtpasswdFile) Validate(user string, password string) bool {
|
||||||
realPassword, exists := h.Users[user]
|
realPassword, exists := h.Users[user]
|
||||||
if !exists {
|
if !exists {
|
||||||
|
|
|
@ -104,7 +104,7 @@ func (router *Router) ConnectFunc(path string, handler http.HandlerFunc) {
|
||||||
router.Handle("Connect", path, handler)
|
router.Handle("Connect", path, handler)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Handle registers a http.Handler for method and uri
|
// Handle registers a http.Handler for method and uri.
|
||||||
func (router *Router) Handle(method string, uri string, handler http.Handler) {
|
func (router *Router) Handle(method string, uri string, handler http.Handler) {
|
||||||
routes := router.routes[method]
|
routes := router.routes[method]
|
||||||
path := strings.Split(uri, "/")
|
path := strings.Split(uri, "/")
|
||||||
|
|
10
server.go
10
server.go
|
@ -16,12 +16,12 @@ const (
|
||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
// Parse command-line args
|
// Parse command-line args.
|
||||||
var path = flag.String("path", "/tmp/restic", "specifies the path of the data directory")
|
var path = flag.String("path", "/tmp/restic", "specifies the path of the data directory")
|
||||||
var tls = flag.Bool("tls", false, "turns on tls support")
|
var tls = flag.Bool("tls", false, "turns on tls support")
|
||||||
flag.Parse()
|
flag.Parse()
|
||||||
|
|
||||||
// Create the missing directories
|
// Create the missing directories.
|
||||||
dirs := []string{
|
dirs := []string{
|
||||||
"data",
|
"data",
|
||||||
"index",
|
"index",
|
||||||
|
@ -34,7 +34,7 @@ func main() {
|
||||||
os.MkdirAll(filepath.Join(*path, d), 0700)
|
os.MkdirAll(filepath.Join(*path, d), 0700)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Define the routes
|
// Define the routes.
|
||||||
context := &Context{*path}
|
context := &Context{*path}
|
||||||
router := NewRouter()
|
router := NewRouter()
|
||||||
router.HeadFunc("/config", CheckConfig(context))
|
router.HeadFunc("/config", CheckConfig(context))
|
||||||
|
@ -46,7 +46,7 @@ func main() {
|
||||||
router.PostFunc("/:type/:name", SaveBlob(context))
|
router.PostFunc("/:type/:name", SaveBlob(context))
|
||||||
router.DeleteFunc("/:type/:name", DeleteBlob(context))
|
router.DeleteFunc("/:type/:name", DeleteBlob(context))
|
||||||
|
|
||||||
// Check for a password file
|
// Check for a password file.
|
||||||
var handler http.Handler
|
var handler http.Handler
|
||||||
htpasswdFile, err := NewHtpasswdFromFile(filepath.Join(*path, ".htpasswd"))
|
htpasswdFile, err := NewHtpasswdFromFile(filepath.Join(*path, ".htpasswd"))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -57,7 +57,7 @@ func main() {
|
||||||
handler = AuthHandler(htpasswdFile, router)
|
handler = AuthHandler(htpasswdFile, router)
|
||||||
}
|
}
|
||||||
|
|
||||||
// start the server
|
// Start the server.
|
||||||
if !*tls {
|
if !*tls {
|
||||||
log.Printf("start server on port %s\n", defaultHTTPPort)
|
log.Printf("start server on port %s\n", defaultHTTPPort)
|
||||||
http.ListenAndServe(defaultHTTPPort, handler)
|
http.ListenAndServe(defaultHTTPPort, handler)
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue