mirror of
https://github.com/octoleo/restic.git
synced 2024-12-24 11:55:28 +00:00
Fixes for the PR
- Removed external dependencies for test - Prevent building restic-server w/ Go 1.3 Go versions 1.0, 1.1., and 1.2 are going to fail as well, but they are "excluded" by README.md already.
This commit is contained in:
parent
d86c093480
commit
51d86370a5
@ -1,3 +1,5 @@
|
|||||||
|
// +build go1.4
|
||||||
|
|
||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
@ -10,10 +12,14 @@ import (
|
|||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// Context contains repository meta-data.
|
||||||
type Context struct {
|
type Context struct {
|
||||||
path string
|
path string
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// AuthHandler wraps h with a http.HandlerFunc that performs basic
|
||||||
|
// authentication against the user/passwords pairs stored in f and returns the
|
||||||
|
// 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()
|
||||||
@ -29,6 +35,8 @@ func AuthHandler(f *HtpasswdFile, h http.Handler) http.HandlerFunc {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// CheckConfig returns a http.HandlerFunc that checks whether
|
||||||
|
// 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")
|
||||||
@ -39,6 +47,8 @@ func CheckConfig(c *Context) http.HandlerFunc {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// GetConfig returns a http.HandlerFunc that allows for a
|
||||||
|
// 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")
|
||||||
@ -51,6 +61,8 @@ func GetConfig(c *Context) http.HandlerFunc {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// SaveConfig returns a http.HandlerFunc that allows for a
|
||||||
|
// 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")
|
||||||
@ -68,6 +80,8 @@ func SaveConfig(c *Context) http.HandlerFunc {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ListBlobs returns a http.HandlerFunc that lists
|
||||||
|
// 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, "/")
|
||||||
@ -91,6 +105,8 @@ func ListBlobs(c *Context) http.HandlerFunc {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// CheckBlob reutrns a http.HandlerFunc that tests whether a blob exists
|
||||||
|
// 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, "/")
|
||||||
@ -105,6 +121,8 @@ func CheckBlob(c *Context) http.HandlerFunc {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// GetBlob returns a http.HandlerFunc that retrieves a blob
|
||||||
|
// 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, "/")
|
||||||
@ -121,6 +139,7 @@ func GetBlob(c *Context) http.HandlerFunc {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// SaveBlob returns a http.HandlerFunc that saves a blob to the repository.
|
||||||
func SaveBlob(c *Context) http.HandlerFunc {
|
func SaveBlob(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, "/")
|
||||||
@ -141,6 +160,8 @@ func SaveBlob(c *Context) http.HandlerFunc {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// DeleteBlob returns a http.HandlerFunc that deletes a blob from the
|
||||||
|
// 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, "/")
|
||||||
|
@ -1,3 +1,5 @@
|
|||||||
|
// +build go1.4
|
||||||
|
|
||||||
package main
|
package main
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -36,10 +38,14 @@ import (
|
|||||||
// 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.
|
||||||
type HtpasswdFile struct {
|
type HtpasswdFile struct {
|
||||||
Users map[string]string
|
Users map[string]string
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// NewHtpasswdFromFile reads the users and passwords from a htpasswd
|
||||||
|
// file and returns them. If an error is encountered, it is returned, together
|
||||||
|
// with a nil-Pointer for the HtpasswdFile.
|
||||||
func NewHtpasswdFromFile(path string) (*HtpasswdFile, error) {
|
func NewHtpasswdFromFile(path string) (*HtpasswdFile, error) {
|
||||||
r, err := os.Open(path)
|
r, err := os.Open(path)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -49,13 +55,16 @@ func NewHtpasswdFromFile(path string) (*HtpasswdFile, error) {
|
|||||||
return NewHtpasswd(r)
|
return NewHtpasswd(r)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// NewHtpasswd reads the users and passwords from a htpasswd
|
||||||
|
// datastream in file and returns them. If an error is encountered,
|
||||||
|
// 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) {
|
||||||
csv_reader := csv.NewReader(file)
|
cr := csv.NewReader(file)
|
||||||
csv_reader.Comma = ':'
|
cr.Comma = ':'
|
||||||
csv_reader.Comment = '#'
|
cr.Comment = '#'
|
||||||
csv_reader.TrimLeadingSpace = true
|
cr.TrimLeadingSpace = true
|
||||||
|
|
||||||
records, err := csv_reader.ReadAll()
|
records, err := cr.ReadAll()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@ -66,6 +75,9 @@ func NewHtpasswd(file io.Reader) (*HtpasswdFile, error) {
|
|||||||
return h, nil
|
return h, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Validate returns true if password matches the stored password
|
||||||
|
// for user. If no password for user is stored, or the password
|
||||||
|
// 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 {
|
||||||
|
@ -1,3 +1,5 @@
|
|||||||
|
// +build go1.4
|
||||||
|
|
||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
@ -6,83 +8,103 @@ import (
|
|||||||
"strings"
|
"strings"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// Route is a handler for a path that was already split.
|
||||||
type Route struct {
|
type Route struct {
|
||||||
path []string
|
path []string
|
||||||
handler http.Handler
|
handler http.Handler
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Router maps HTTP methods to a slice of Route handlers.
|
||||||
type Router struct {
|
type Router struct {
|
||||||
routes map[string][]Route
|
routes map[string][]Route
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// NewRouter creates a new Router and returns a pointer to it.
|
||||||
func NewRouter() *Router {
|
func NewRouter() *Router {
|
||||||
return &Router{make(map[string][]Route)}
|
return &Router{make(map[string][]Route)}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Options registers handler for path with method "OPTIONS".
|
||||||
func (router *Router) Options(path string, handler http.Handler) {
|
func (router *Router) Options(path string, handler http.Handler) {
|
||||||
router.Handle("OPTIONS", path, handler)
|
router.Handle("OPTIONS", path, handler)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// OptionsFunc registers handler for path with method "OPTIONS".
|
||||||
func (router *Router) OptionsFunc(path string, handler http.HandlerFunc) {
|
func (router *Router) OptionsFunc(path string, handler http.HandlerFunc) {
|
||||||
router.Handle("OPTIONS", path, handler)
|
router.Handle("OPTIONS", path, handler)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Get registers handler for path with method "GET".
|
||||||
func (router *Router) Get(path string, handler http.Handler) {
|
func (router *Router) Get(path string, handler http.Handler) {
|
||||||
router.Handle("GET", path, handler)
|
router.Handle("GET", path, handler)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// GetFunc registers handler for path with method "GET".
|
||||||
func (router *Router) GetFunc(path string, handler http.HandlerFunc) {
|
func (router *Router) GetFunc(path string, handler http.HandlerFunc) {
|
||||||
router.Handle("GET", path, handler)
|
router.Handle("GET", path, handler)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Head registers handler for path with method "HEAD".
|
||||||
func (router *Router) Head(path string, handler http.Handler) {
|
func (router *Router) Head(path string, handler http.Handler) {
|
||||||
router.Handle("HEAD", path, handler)
|
router.Handle("HEAD", path, handler)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// HeadFunc registers handler for path with method "HEAD".
|
||||||
func (router *Router) HeadFunc(path string, handler http.HandlerFunc) {
|
func (router *Router) HeadFunc(path string, handler http.HandlerFunc) {
|
||||||
router.Handle("HEAD", path, handler)
|
router.Handle("HEAD", path, handler)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Post registers handler for path with method "POST".
|
||||||
func (router *Router) Post(path string, handler http.Handler) {
|
func (router *Router) Post(path string, handler http.Handler) {
|
||||||
router.Handle("POST", path, handler)
|
router.Handle("POST", path, handler)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// PostFunc registers handler for path with method "POST".
|
||||||
func (router *Router) PostFunc(path string, handler http.HandlerFunc) {
|
func (router *Router) PostFunc(path string, handler http.HandlerFunc) {
|
||||||
router.Handle("POST", path, handler)
|
router.Handle("POST", path, handler)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Put registers handler for path with method "PUT".
|
||||||
func (router *Router) Put(path string, handler http.Handler) {
|
func (router *Router) Put(path string, handler http.Handler) {
|
||||||
router.Handle("PUT", path, handler)
|
router.Handle("PUT", path, handler)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// PutFunc registers handler for path with method "PUT".
|
||||||
func (router *Router) PutFunc(path string, handler http.HandlerFunc) {
|
func (router *Router) PutFunc(path string, handler http.HandlerFunc) {
|
||||||
router.Handle("PUT", path, handler)
|
router.Handle("PUT", path, handler)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Delete registers handler for path with method "DELETE".
|
||||||
func (router *Router) Delete(path string, handler http.Handler) {
|
func (router *Router) Delete(path string, handler http.Handler) {
|
||||||
router.Handle("DELETE", path, handler)
|
router.Handle("DELETE", path, handler)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// DeleteFunc registers handler for path with method "DELETE".
|
||||||
func (router *Router) DeleteFunc(path string, handler http.HandlerFunc) {
|
func (router *Router) DeleteFunc(path string, handler http.HandlerFunc) {
|
||||||
router.Handle("DELETE", path, handler)
|
router.Handle("DELETE", path, handler)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Trace registers handler for path with method "TRACE".
|
||||||
func (router *Router) Trace(path string, handler http.Handler) {
|
func (router *Router) Trace(path string, handler http.Handler) {
|
||||||
router.Handle("TRACE", path, handler)
|
router.Handle("TRACE", path, handler)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TraceFunc registers handler for path with method "TRACE".
|
||||||
func (router *Router) TraceFunc(path string, handler http.HandlerFunc) {
|
func (router *Router) TraceFunc(path string, handler http.HandlerFunc) {
|
||||||
router.Handle("TRACE", path, handler)
|
router.Handle("TRACE", path, handler)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Connect registers handler for path with method "Connect".
|
||||||
func (router *Router) Connect(path string, handler http.Handler) {
|
func (router *Router) Connect(path string, handler http.Handler) {
|
||||||
router.Handle("Connect", path, handler)
|
router.Handle("Connect", path, handler)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ConnectFunc registers handler for path with method "Connect".
|
||||||
func (router *Router) ConnectFunc(path string, handler http.HandlerFunc) {
|
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
|
||||||
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, "/")
|
||||||
|
@ -1,3 +1,5 @@
|
|||||||
|
// +build go1.4
|
||||||
|
|
||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
@ -6,8 +8,6 @@ import (
|
|||||||
"net/http/httptest"
|
"net/http/httptest"
|
||||||
"strings"
|
"strings"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/stretchr/testify/require"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestRouter(t *testing.T) {
|
func TestRouter(t *testing.T) {
|
||||||
@ -38,21 +38,37 @@ func TestRouter(t *testing.T) {
|
|||||||
|
|
||||||
getConfigResp, _ := http.Get(server.URL + "/config")
|
getConfigResp, _ := http.Get(server.URL + "/config")
|
||||||
getConfigBody, _ := ioutil.ReadAll(getConfigResp.Body)
|
getConfigBody, _ := ioutil.ReadAll(getConfigResp.Body)
|
||||||
require.Equal(t, 200, getConfigResp.StatusCode)
|
if getConfigResp.StatusCode != 200 {
|
||||||
require.Equal(t, string(getConfig), string(getConfigBody))
|
t.Fatalf("Wanted HTTP Status 200, got %d", getConfigResp.StatusCode)
|
||||||
|
}
|
||||||
|
if string(getConfig) != string(getConfigBody) {
|
||||||
|
t.Fatalf("Config wrong:\nWanted '%s'\nGot: '%s'", string(getConfig), string(getConfigBody))
|
||||||
|
}
|
||||||
|
|
||||||
postConfigResp, _ := http.Post(server.URL+"/config", "binary/octet-stream", strings.NewReader("post test"))
|
postConfigResp, _ := http.Post(server.URL+"/config", "binary/octet-stream", strings.NewReader("post test"))
|
||||||
postConfigBody, _ := ioutil.ReadAll(postConfigResp.Body)
|
postConfigBody, _ := ioutil.ReadAll(postConfigResp.Body)
|
||||||
require.Equal(t, 200, postConfigResp.StatusCode)
|
if postConfigResp.StatusCode != 200 {
|
||||||
require.Equal(t, string(postConfig), string(postConfigBody))
|
t.Fatalf("Wanted HTTP Status 200, got %d", postConfigResp.StatusCode)
|
||||||
|
}
|
||||||
|
if string(postConfig) != string(postConfigBody) {
|
||||||
|
t.Fatalf("Config wrong:\nWanted '%s'\nGot: '%s'", string(postConfig), string(postConfigBody))
|
||||||
|
}
|
||||||
|
|
||||||
getBlobsResp, _ := http.Get(server.URL + "/blobs/")
|
getBlobsResp, _ := http.Get(server.URL + "/blobs/")
|
||||||
getBlobsBody, _ := ioutil.ReadAll(getBlobsResp.Body)
|
getBlobsBody, _ := ioutil.ReadAll(getBlobsResp.Body)
|
||||||
require.Equal(t, 200, getBlobsResp.StatusCode)
|
if getBlobsResp.StatusCode != 200 {
|
||||||
require.Equal(t, string(getBlobs), string(getBlobsBody))
|
t.Fatalf("Wanted HTTP Status 200, got %d", getBlobsResp.StatusCode)
|
||||||
|
}
|
||||||
|
if string(getBlobs) != string(getBlobsBody) {
|
||||||
|
t.Fatalf("Config wrong:\nWanted '%s'\nGot: '%s'", string(getBlobs), string(getBlobsBody))
|
||||||
|
}
|
||||||
|
|
||||||
getBlobResp, _ := http.Get(server.URL + "/blobs/test")
|
getBlobResp, _ := http.Get(server.URL + "/blobs/test")
|
||||||
getBlobBody, _ := ioutil.ReadAll(getBlobResp.Body)
|
getBlobBody, _ := ioutil.ReadAll(getBlobResp.Body)
|
||||||
require.Equal(t, 200, getBlobResp.StatusCode)
|
if getBlobResp.StatusCode != 200 {
|
||||||
require.Equal(t, string(getBlob), string(getBlobBody))
|
t.Fatalf("Wanted HTTP Status 200, got %d", getBlobResp.StatusCode)
|
||||||
|
}
|
||||||
|
if string(getBlob) != string(getBlobBody) {
|
||||||
|
t.Fatalf("Config wrong:\nWanted '%s'\nGot: '%s'", string(getBlob), string(getBlobBody))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,3 +1,5 @@
|
|||||||
|
// +build go1.4
|
||||||
|
|
||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
@ -9,8 +11,8 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
HTTP = ":8000"
|
defaultHTTPPort = ":8000"
|
||||||
HTTPS = ":8443"
|
defaultHTTPSPort = ":8443"
|
||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
@ -56,15 +58,15 @@ func main() {
|
|||||||
|
|
||||||
// start the server
|
// start the server
|
||||||
if !*tls {
|
if !*tls {
|
||||||
log.Printf("start server on port %s\n", HTTP)
|
log.Printf("start server on port %s\n", defaultHTTPPort)
|
||||||
http.ListenAndServe(HTTP, handler)
|
http.ListenAndServe(defaultHTTPPort, handler)
|
||||||
} else {
|
} else {
|
||||||
privateKey := filepath.Join(*path, "private_key")
|
privateKey := filepath.Join(*path, "private_key")
|
||||||
publicKey := filepath.Join(*path, "public_key")
|
publicKey := filepath.Join(*path, "public_key")
|
||||||
log.Println("TLS enabled")
|
log.Println("TLS enabled")
|
||||||
log.Printf("private key: %s", privateKey)
|
log.Printf("private key: %s", privateKey)
|
||||||
log.Printf("public key: %s", publicKey)
|
log.Printf("public key: %s", publicKey)
|
||||||
log.Printf("start server on port %s\n", HTTPS)
|
log.Printf("start server on port %s\n", defaultHTTPSPort)
|
||||||
http.ListenAndServeTLS(HTTPS, publicKey, privateKey, handler)
|
http.ListenAndServeTLS(defaultHTTPSPort, publicKey, privateKey, handler)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user