mirror of
https://github.com/restic/rest-server.git
synced 2025-10-19 15:43:21 +00:00
Merge pull request #322 from MichaelEischer/bump-go-version
Bump minimum go version to 1.22
This commit is contained in:
commit
376392a89c
15 changed files with 162 additions and 112 deletions
55
.github/workflows/tests.yml
vendored
55
.github/workflows/tests.yml
vendored
|
@ -7,9 +7,13 @@ on:
|
||||||
|
|
||||||
# run tests for all pull requests
|
# run tests for all pull requests
|
||||||
pull_request:
|
pull_request:
|
||||||
|
merge_group:
|
||||||
|
|
||||||
|
permissions:
|
||||||
|
contents: read
|
||||||
|
|
||||||
env:
|
env:
|
||||||
latest_go: "1.21.x"
|
latest_go: "1.23.x"
|
||||||
GO111MODULE: on
|
GO111MODULE: on
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
|
@ -17,10 +21,8 @@ jobs:
|
||||||
strategy:
|
strategy:
|
||||||
matrix:
|
matrix:
|
||||||
go:
|
go:
|
||||||
- 1.18.x
|
- 1.23.x
|
||||||
- 1.19.x
|
- 1.22.x
|
||||||
- 1.20.x
|
|
||||||
- 1.21.x
|
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
name: Go ${{ matrix.go }}
|
name: Go ${{ matrix.go }}
|
||||||
|
|
||||||
|
@ -28,25 +30,21 @@ jobs:
|
||||||
GOPROXY: https://proxy.golang.org
|
GOPROXY: https://proxy.golang.org
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
|
- name: Check out code
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
|
||||||
- name: Set up Go ${{ matrix.go }}
|
- name: Set up Go ${{ matrix.go }}
|
||||||
uses: actions/setup-go@v5
|
uses: actions/setup-go@v5
|
||||||
with:
|
with:
|
||||||
go-version: ${{ matrix.go }}
|
go-version: ${{ matrix.go }}
|
||||||
|
|
||||||
- name: Check out code
|
|
||||||
uses: actions/checkout@v4
|
|
||||||
|
|
||||||
- name: Build
|
|
||||||
run: |
|
|
||||||
go build ./cmd/rest-server
|
|
||||||
|
|
||||||
- name: Build with build.go
|
- name: Build with build.go
|
||||||
run: |
|
run: |
|
||||||
go run build.go --goos linux
|
go run build.go --goos linux
|
||||||
go run build.go --goos windows
|
go run build.go --goos windows
|
||||||
go run build.go --goos darwin
|
go run build.go --goos darwin
|
||||||
|
|
||||||
- name: Run tests
|
- name: Run local Tests
|
||||||
run: |
|
run: |
|
||||||
go test ./...
|
go test ./...
|
||||||
|
|
||||||
|
@ -61,23 +59,25 @@ jobs:
|
||||||
lint:
|
lint:
|
||||||
name: lint
|
name: lint
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
|
permissions:
|
||||||
|
contents: read
|
||||||
|
# allow annotating code in the PR
|
||||||
|
checks: write
|
||||||
steps:
|
steps:
|
||||||
|
- name: Check out code
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
|
||||||
- name: Set up Go ${{ env.latest_go }}
|
- name: Set up Go ${{ env.latest_go }}
|
||||||
uses: actions/setup-go@v5
|
uses: actions/setup-go@v5
|
||||||
with:
|
with:
|
||||||
go-version: ${{ env.latest_go }}
|
go-version: ${{ env.latest_go }}
|
||||||
|
|
||||||
- name: Check out code
|
|
||||||
uses: actions/checkout@v4
|
|
||||||
|
|
||||||
- name: golangci-lint
|
- name: golangci-lint
|
||||||
uses: golangci/golangci-lint-action@v6
|
uses: golangci/golangci-lint-action@v6
|
||||||
with:
|
with:
|
||||||
# Required: the version of golangci-lint is required and must be specified without patch version: we always use the latest patch version.
|
# Required: the version of golangci-lint is required and must be specified without patch version: we always use the latest patch version.
|
||||||
version: v1.51
|
version: v1.63.4
|
||||||
# Optional: show only new issues if it's a pull request. The default value is `false`.
|
args: --verbose --timeout 5m
|
||||||
only-new-issues: true
|
|
||||||
args: --verbose --timeout 10m
|
|
||||||
|
|
||||||
# only run golangci-lint for pull requests, otherwise ALL hints get
|
# only run golangci-lint for pull requests, otherwise ALL hints get
|
||||||
# reported. We need to slowly address all issues until we can enable
|
# reported. We need to slowly address all issues until we can enable
|
||||||
|
@ -89,3 +89,18 @@ jobs:
|
||||||
echo "check if go.mod and go.sum are up to date"
|
echo "check if go.mod and go.sum are up to date"
|
||||||
go mod tidy
|
go mod tidy
|
||||||
git diff --exit-code go.mod go.sum
|
git diff --exit-code go.mod go.sum
|
||||||
|
|
||||||
|
analyze:
|
||||||
|
name: Analyze results
|
||||||
|
needs: [test, lint]
|
||||||
|
if: always()
|
||||||
|
|
||||||
|
permissions: # no need to access code
|
||||||
|
contents: none
|
||||||
|
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- name: Decide whether the needed jobs succeeded or failed
|
||||||
|
uses: re-actors/alls-green@05ac9388f0aebcb5727afa17fcccfecd6f8ec5fe
|
||||||
|
with:
|
||||||
|
jobs: ${{ toJSON(needs) }}
|
||||||
|
|
|
@ -10,13 +10,10 @@ linters:
|
||||||
# make sure all errors returned by functions are handled
|
# make sure all errors returned by functions are handled
|
||||||
- errcheck
|
- errcheck
|
||||||
|
|
||||||
# find unused code
|
|
||||||
- deadcode
|
|
||||||
|
|
||||||
# show how code can be simplified
|
# show how code can be simplified
|
||||||
- gosimple
|
- gosimple
|
||||||
|
|
||||||
# # make sure code is formatted
|
# make sure code is formatted
|
||||||
- gofmt
|
- gofmt
|
||||||
|
|
||||||
# examine code and report suspicious constructs, such as Printf calls whose
|
# examine code and report suspicious constructs, such as Printf calls whose
|
||||||
|
@ -35,15 +32,14 @@ linters:
|
||||||
# find unused variables, functions, structs, types, etc.
|
# find unused variables, functions, structs, types, etc.
|
||||||
- unused
|
- unused
|
||||||
|
|
||||||
# find unused struct fields
|
|
||||||
- structcheck
|
|
||||||
|
|
||||||
# find unused global variables
|
|
||||||
- varcheck
|
|
||||||
|
|
||||||
# parse and typecheck code
|
# parse and typecheck code
|
||||||
- typecheck
|
- typecheck
|
||||||
|
|
||||||
|
# ensure that http response bodies are closed
|
||||||
|
- bodyclose
|
||||||
|
|
||||||
|
- importas
|
||||||
|
|
||||||
issues:
|
issues:
|
||||||
# don't use the default exclude rules, this hides (among others) ignored
|
# don't use the default exclude rules, this hides (among others) ignored
|
||||||
# errors from Close() calls
|
# errors from Close() calls
|
||||||
|
@ -55,3 +51,6 @@ issues:
|
||||||
- exported (function|method|var|type|const) .* should have comment or be unexported
|
- exported (function|method|var|type|const) .* should have comment or be unexported
|
||||||
# revive: ignore constants in all caps
|
# revive: ignore constants in all caps
|
||||||
- don't use ALL_CAPS in Go names; use CamelCase
|
- don't use ALL_CAPS in Go names; use CamelCase
|
||||||
|
# revive: lots of packages don't have such a comment
|
||||||
|
- "package-comments: should have a package comment"
|
||||||
|
- "redefines-builtin-id:"
|
||||||
|
|
|
@ -11,7 +11,7 @@ Rest Server is a high performance HTTP server that implements restic's [REST bac
|
||||||
|
|
||||||
## Requirements
|
## Requirements
|
||||||
|
|
||||||
Rest Server requires Go 1.18 or higher to build. The only tested compiler is the official Go compiler. Building server with `gccgo` may work, but is not supported.
|
Rest Server requires Go 1.22 or higher to build. The only tested compiler is the official Go compiler.
|
||||||
|
|
||||||
The required version of restic backup client to use with `rest-server` is [v0.7.1](https://github.com/restic/restic/releases/tag/v0.7.1) or higher.
|
The required version of restic backup client to use with `rest-server` is [v0.7.1](https://github.com/restic/restic/releases/tag/v0.7.1) or higher.
|
||||||
|
|
||||||
|
|
2
build.go
2
build.go
|
@ -58,7 +58,7 @@ var config = Config{
|
||||||
Namespace: "github.com/restic/rest-server", // subdir of GOPATH, e.g. "github.com/foo/bar"
|
Namespace: "github.com/restic/rest-server", // subdir of GOPATH, e.g. "github.com/foo/bar"
|
||||||
Main: "github.com/restic/rest-server/cmd/rest-server", // package name for the main package
|
Main: "github.com/restic/rest-server/cmd/rest-server", // package name for the main package
|
||||||
Tests: []string{"./..."}, // tests to run
|
Tests: []string{"./..."}, // tests to run
|
||||||
MinVersion: GoVersion{Major: 1, Minor: 15, Patch: 0}, // minimum Go version supported
|
MinVersion: GoVersion{Major: 1, Minor: 22, Patch: 0}, // minimum Go version supported
|
||||||
}
|
}
|
||||||
|
|
||||||
// Config configures the build.
|
// Config configures the build.
|
||||||
|
|
9
changelog/unreleased/pull-322
Normal file
9
changelog/unreleased/pull-322
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
Change: Update dependencies and require Go 1.22 or newer
|
||||||
|
|
||||||
|
We have updated all dependencies. Since some libraries require newer Go standard
|
||||||
|
library features, support for Go 1.18 to 1.21 has been dropped, which means
|
||||||
|
that rest-server now requires at least Go 1.22 to build.
|
||||||
|
|
||||||
|
This also disables support for TLS versions older than TLS 1.2.
|
||||||
|
|
||||||
|
https://github.com/restic/rest-server/pull/322
|
|
@ -61,7 +61,10 @@ func TestUnixSocket(t *testing.T) {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
resp.Body.Close()
|
err = resp.Body.Close()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
if resp.StatusCode != test.StatusCode {
|
if resp.StatusCode != test.StatusCode {
|
||||||
return fmt.Errorf("expected %d from server, instead got %d (path %s)", test.StatusCode, resp.StatusCode, test.Path)
|
return fmt.Errorf("expected %d from server, instead got %d (path %s)", test.StatusCode, resp.StatusCode, test.Path)
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,7 +22,7 @@ import (
|
||||||
type restServerApp struct {
|
type restServerApp struct {
|
||||||
CmdRoot *cobra.Command
|
CmdRoot *cobra.Command
|
||||||
Server restserver.Server
|
Server restserver.Server
|
||||||
CpuProfile string
|
CPUProfile string
|
||||||
|
|
||||||
listenerAddressMu sync.Mutex
|
listenerAddressMu sync.Mutex
|
||||||
listenerAddress net.Addr // set after startup
|
listenerAddress net.Addr // set after startup
|
||||||
|
@ -36,7 +36,7 @@ func newRestServerApp() *restServerApp {
|
||||||
Short: "Run a REST server for use with restic",
|
Short: "Run a REST server for use with restic",
|
||||||
SilenceErrors: true,
|
SilenceErrors: true,
|
||||||
SilenceUsage: true,
|
SilenceUsage: true,
|
||||||
Args: func(cmd *cobra.Command, args []string) error {
|
Args: func(_ *cobra.Command, args []string) error {
|
||||||
if len(args) != 0 {
|
if len(args) != 0 {
|
||||||
return fmt.Errorf("rest-server expects no arguments - unknown argument: %s", args[0])
|
return fmt.Errorf("rest-server expects no arguments - unknown argument: %s", args[0])
|
||||||
}
|
}
|
||||||
|
@ -52,7 +52,7 @@ func newRestServerApp() *restServerApp {
|
||||||
rv.CmdRoot.RunE = rv.runRoot
|
rv.CmdRoot.RunE = rv.runRoot
|
||||||
flags := rv.CmdRoot.Flags()
|
flags := rv.CmdRoot.Flags()
|
||||||
|
|
||||||
flags.StringVar(&rv.CpuProfile, "cpu-profile", rv.CpuProfile, "write CPU profile to file")
|
flags.StringVar(&rv.CPUProfile, "cpu-profile", rv.CPUProfile, "write CPU profile to file")
|
||||||
flags.BoolVar(&rv.Server.Debug, "debug", rv.Server.Debug, "output debug messages")
|
flags.BoolVar(&rv.Server.Debug, "debug", rv.Server.Debug, "output debug messages")
|
||||||
flags.StringVar(&rv.Server.Listen, "listen", rv.Server.Listen, "listen address")
|
flags.StringVar(&rv.Server.Listen, "listen", rv.Server.Listen, "listen address")
|
||||||
flags.StringVar(&rv.Server.Log, "log", rv.Server.Log, "write HTTP requests in the combined log format to the specified `filename` (use \"-\" for logging to stdout)")
|
flags.StringVar(&rv.Server.Log, "log", rv.Server.Log, "write HTTP requests in the combined log format to the specified `filename` (use \"-\" for logging to stdout)")
|
||||||
|
@ -103,17 +103,19 @@ func (app *restServerApp) ListenerAddress() net.Addr {
|
||||||
return app.listenerAddress
|
return app.listenerAddress
|
||||||
}
|
}
|
||||||
|
|
||||||
func (app *restServerApp) runRoot(cmd *cobra.Command, args []string) error {
|
func (app *restServerApp) runRoot(_ *cobra.Command, _ []string) error {
|
||||||
log.SetFlags(0)
|
log.SetFlags(0)
|
||||||
|
|
||||||
log.Printf("Data directory: %s", app.Server.Path)
|
log.Printf("Data directory: %s", app.Server.Path)
|
||||||
|
|
||||||
if app.CpuProfile != "" {
|
if app.CPUProfile != "" {
|
||||||
f, err := os.Create(app.CpuProfile)
|
f, err := os.Create(app.CPUProfile)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
defer f.Close()
|
defer func() {
|
||||||
|
_ = f.Close()
|
||||||
|
}()
|
||||||
|
|
||||||
if err := pprof.StartCPUProfile(f); err != nil {
|
if err := pprof.StartCPUProfile(f); err != nil {
|
||||||
return err
|
return err
|
||||||
|
|
|
@ -4,7 +4,6 @@ import (
|
||||||
"context"
|
"context"
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io/ioutil"
|
|
||||||
"net/http"
|
"net/http"
|
||||||
"net/url"
|
"net/url"
|
||||||
"os"
|
"os"
|
||||||
|
@ -94,7 +93,7 @@ func TestTLSSettings(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestGetHandler(t *testing.T) {
|
func TestGetHandler(t *testing.T) {
|
||||||
dir, err := ioutil.TempDir("", "rest-server-test")
|
dir, err := os.MkdirTemp("", "rest-server-test")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
|
@ -120,7 +119,7 @@ func TestGetHandler(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// With NoAuth = false and custom .htpasswd
|
// With NoAuth = false and custom .htpasswd
|
||||||
htpFile, err := ioutil.TempFile(dir, "custom")
|
htpFile, err := os.CreateTemp(dir, "custom")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
|
@ -137,7 +136,7 @@ func TestGetHandler(t *testing.T) {
|
||||||
|
|
||||||
// Create .htpasswd
|
// Create .htpasswd
|
||||||
htpasswd := filepath.Join(dir, ".htpasswd")
|
htpasswd := filepath.Join(dir, ".htpasswd")
|
||||||
err = ioutil.WriteFile(htpasswd, []byte(""), 0644)
|
err = os.WriteFile(htpasswd, []byte(""), 0644)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
|
@ -262,7 +261,10 @@ func TestHttpListen(t *testing.T) {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
resp.Body.Close()
|
err = resp.Body.Close()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
if resp.StatusCode != test.StatusCode {
|
if resp.StatusCode != test.StatusCode {
|
||||||
return fmt.Errorf("expected %d from server, instead got %d (path %s)", test.StatusCode, resp.StatusCode, test.Path)
|
return fmt.Errorf("expected %d from server, instead got %d (path %s)", test.StatusCode, resp.StatusCode, test.Path)
|
||||||
}
|
}
|
||||||
|
|
27
go.mod
27
go.mod
|
@ -1,28 +1,29 @@
|
||||||
module github.com/restic/rest-server
|
module github.com/restic/rest-server
|
||||||
|
|
||||||
go 1.18
|
go 1.22
|
||||||
|
|
||||||
require (
|
require (
|
||||||
github.com/coreos/go-systemd/v22 v22.5.0
|
github.com/coreos/go-systemd/v22 v22.5.0
|
||||||
github.com/gorilla/handlers v1.5.2
|
github.com/gorilla/handlers v1.5.2
|
||||||
github.com/minio/sha256-simd v1.0.1
|
github.com/minio/sha256-simd v1.0.1
|
||||||
github.com/miolini/datacounter v1.0.3
|
github.com/miolini/datacounter v1.0.3
|
||||||
github.com/prometheus/client_golang v1.18.0
|
github.com/prometheus/client_golang v1.20.5
|
||||||
github.com/spf13/cobra v1.8.1
|
github.com/spf13/cobra v1.8.1
|
||||||
golang.org/x/crypto v0.27.0
|
golang.org/x/crypto v0.32.0
|
||||||
)
|
)
|
||||||
|
|
||||||
require (
|
require (
|
||||||
github.com/beorn7/perks v1.0.1 // indirect
|
github.com/beorn7/perks v1.0.1 // indirect
|
||||||
github.com/cespare/xxhash/v2 v2.2.0 // indirect
|
github.com/cespare/xxhash/v2 v2.3.0 // indirect
|
||||||
github.com/felixge/httpsnoop v1.0.3 // indirect
|
github.com/felixge/httpsnoop v1.0.4 // indirect
|
||||||
github.com/inconshreveable/mousetrap v1.1.0 // indirect
|
github.com/inconshreveable/mousetrap v1.1.0 // indirect
|
||||||
github.com/klauspost/cpuid/v2 v2.2.5 // indirect
|
github.com/klauspost/compress v1.17.9 // indirect
|
||||||
github.com/matttproud/golang_protobuf_extensions/v2 v2.0.0 // indirect
|
github.com/klauspost/cpuid/v2 v2.2.9 // indirect
|
||||||
github.com/prometheus/client_model v0.5.0 // indirect
|
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect
|
||||||
github.com/prometheus/common v0.45.0 // indirect
|
github.com/prometheus/client_model v0.6.1 // indirect
|
||||||
github.com/prometheus/procfs v0.12.0 // indirect
|
github.com/prometheus/common v0.62.0 // indirect
|
||||||
github.com/spf13/pflag v1.0.5 // indirect
|
github.com/prometheus/procfs v0.15.1 // indirect
|
||||||
golang.org/x/sys v0.25.0 // indirect
|
github.com/spf13/pflag v1.0.6 // indirect
|
||||||
google.golang.org/protobuf v1.33.0 // indirect
|
golang.org/x/sys v0.30.0 // indirect
|
||||||
|
google.golang.org/protobuf v1.36.5 // indirect
|
||||||
)
|
)
|
||||||
|
|
61
go.sum
61
go.sum
|
@ -1,46 +1,57 @@
|
||||||
github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM=
|
github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM=
|
||||||
github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw=
|
github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw=
|
||||||
github.com/cespare/xxhash/v2 v2.2.0 h1:DC2CZ1Ep5Y4k3ZQ899DldepgrayRUGE6BBZ/cd9Cj44=
|
github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs=
|
||||||
github.com/cespare/xxhash/v2 v2.2.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
|
github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
|
||||||
github.com/coreos/go-systemd/v22 v22.5.0 h1:RrqgGjYQKalulkV8NGVIfkXQf6YYmOyiJKk8iXXhfZs=
|
github.com/coreos/go-systemd/v22 v22.5.0 h1:RrqgGjYQKalulkV8NGVIfkXQf6YYmOyiJKk8iXXhfZs=
|
||||||
github.com/coreos/go-systemd/v22 v22.5.0/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc=
|
github.com/coreos/go-systemd/v22 v22.5.0/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc=
|
||||||
github.com/cpuguy83/go-md2man/v2 v2.0.4/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o=
|
github.com/cpuguy83/go-md2man/v2 v2.0.4/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o=
|
||||||
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
||||||
github.com/felixge/httpsnoop v1.0.3 h1:s/nj+GCswXYzN5v2DpNMuMQYe+0DDwt5WVCU6CWBdXk=
|
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||||
github.com/felixge/httpsnoop v1.0.3/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U=
|
github.com/felixge/httpsnoop v1.0.4 h1:NFTV2Zj1bL4mc9sqWACXbQFVBBg2W3GPvqp8/ESS2Wg=
|
||||||
|
github.com/felixge/httpsnoop v1.0.4/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U=
|
||||||
github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA=
|
github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA=
|
||||||
github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38=
|
github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=
|
||||||
|
github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
|
||||||
github.com/gorilla/handlers v1.5.2 h1:cLTUSsNkgcwhgRqvCNmdbRWG0A3N4F+M2nWKdScwyEE=
|
github.com/gorilla/handlers v1.5.2 h1:cLTUSsNkgcwhgRqvCNmdbRWG0A3N4F+M2nWKdScwyEE=
|
||||||
github.com/gorilla/handlers v1.5.2/go.mod h1:dX+xVpaxdSw+q0Qek8SSsl3dfMk3jNddUkMzo0GtH0w=
|
github.com/gorilla/handlers v1.5.2/go.mod h1:dX+xVpaxdSw+q0Qek8SSsl3dfMk3jNddUkMzo0GtH0w=
|
||||||
github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8=
|
github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8=
|
||||||
github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw=
|
github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw=
|
||||||
github.com/klauspost/cpuid/v2 v2.2.5 h1:0E5MSMDEoAulmXNFquVs//DdoomxaoTY1kUhbc/qbZg=
|
github.com/klauspost/compress v1.17.9 h1:6KIumPrER1LHsvBVuDa0r5xaG0Es51mhhB9BQB2qeMA=
|
||||||
github.com/klauspost/cpuid/v2 v2.2.5/go.mod h1:Lcz8mBdAVJIBVzewtcLocK12l3Y+JytZYpaMropDUws=
|
github.com/klauspost/compress v1.17.9/go.mod h1:Di0epgTjJY877eYKx5yC51cX2A2Vl2ibi7bDH9ttBbw=
|
||||||
github.com/matttproud/golang_protobuf_extensions/v2 v2.0.0 h1:jWpvCLoY8Z/e3VKvlsiIGKtc+UG6U5vzxaoagmhXfyg=
|
github.com/klauspost/cpuid/v2 v2.2.9 h1:66ze0taIn2H33fBvCkXuv9BmCwDfafmiIVpKV9kKGuY=
|
||||||
github.com/matttproud/golang_protobuf_extensions/v2 v2.0.0/go.mod h1:QUyp042oQthUoa9bqDv0ER0wrtXnBruoNd7aNjkbP+k=
|
github.com/klauspost/cpuid/v2 v2.2.9/go.mod h1:rqkxqrZ1EhYM9G+hXH7YdowN5R5RGN6NK4QwQ3WMXF8=
|
||||||
|
github.com/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0SNc=
|
||||||
|
github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw=
|
||||||
github.com/minio/sha256-simd v1.0.1 h1:6kaan5IFmwTNynnKKpDHe6FWHohJOHhCPchzK49dzMM=
|
github.com/minio/sha256-simd v1.0.1 h1:6kaan5IFmwTNynnKKpDHe6FWHohJOHhCPchzK49dzMM=
|
||||||
github.com/minio/sha256-simd v1.0.1/go.mod h1:Pz6AKMiUdngCLpeTL/RJY1M9rUuPMYujV5xJjtbRSN8=
|
github.com/minio/sha256-simd v1.0.1/go.mod h1:Pz6AKMiUdngCLpeTL/RJY1M9rUuPMYujV5xJjtbRSN8=
|
||||||
github.com/miolini/datacounter v1.0.3 h1:tanOZPVblGXQl7/bSZWoEM8l4KK83q24qwQLMrO/HOA=
|
github.com/miolini/datacounter v1.0.3 h1:tanOZPVblGXQl7/bSZWoEM8l4KK83q24qwQLMrO/HOA=
|
||||||
github.com/miolini/datacounter v1.0.3/go.mod h1:C45dc2hBumHjDpEU64IqPwR6TDyPVpzOqqRTN7zmBUA=
|
github.com/miolini/datacounter v1.0.3/go.mod h1:C45dc2hBumHjDpEU64IqPwR6TDyPVpzOqqRTN7zmBUA=
|
||||||
github.com/prometheus/client_golang v1.18.0 h1:HzFfmkOzH5Q8L8G+kSJKUx5dtG87sewO+FoDDqP5Tbk=
|
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq1c1nUAm88MOHcQC9l5mIlSMApZMrHA=
|
||||||
github.com/prometheus/client_golang v1.18.0/go.mod h1:T+GXkCk5wSJyOqMIzVgvvjFDlkOQntgjkJWKrN5txjA=
|
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ=
|
||||||
github.com/prometheus/client_model v0.5.0 h1:VQw1hfvPvk3Uv6Qf29VrPF32JB6rtbgI6cYPYQjL0Qw=
|
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||||
github.com/prometheus/client_model v0.5.0/go.mod h1:dTiFglRmd66nLR9Pv9f0mZi7B7fk5Pm3gvsjB5tr+kI=
|
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||||
github.com/prometheus/common v0.45.0 h1:2BGz0eBc2hdMDLnO/8n0jeB3oPrt2D08CekT0lneoxM=
|
github.com/prometheus/client_golang v1.20.5 h1:cxppBPuYhUnsO6yo/aoRol4L7q7UFfdm+bR9r+8l63Y=
|
||||||
github.com/prometheus/common v0.45.0/go.mod h1:YJmSTw9BoKxJplESWWxlbyttQR4uaEcGyv9MZjVOJsY=
|
github.com/prometheus/client_golang v1.20.5/go.mod h1:PIEt8X02hGcP8JWbeHyeZ53Y/jReSnHgO035n//V5WE=
|
||||||
github.com/prometheus/procfs v0.12.0 h1:jluTpSng7V9hY0O2R9DzzJHYb2xULk9VTR1V1R/k6Bo=
|
github.com/prometheus/client_model v0.6.1 h1:ZKSh/rekM+n3CeS952MLRAdFwIKqeY8b62p8ais2e9E=
|
||||||
github.com/prometheus/procfs v0.12.0/go.mod h1:pcuDEFsWDnvcgNzo4EEweacyhjeA9Zk3cnaOZAZEfOo=
|
github.com/prometheus/client_model v0.6.1/go.mod h1:OrxVMOVHjw3lKMa8+x6HeMGkHMQyHDk9E3jmP2AmGiY=
|
||||||
|
github.com/prometheus/common v0.62.0 h1:xasJaQlnWAeyHdUBeGjXmutelfJHWMRr+Fg4QszZ2Io=
|
||||||
|
github.com/prometheus/common v0.62.0/go.mod h1:vyBcEuLSvWos9B1+CyL7JZ2up+uFzXhkqml0W5zIY1I=
|
||||||
|
github.com/prometheus/procfs v0.15.1 h1:YagwOFzUgYfKKHX6Dr+sHT7km/hxC76UB0learggepc=
|
||||||
|
github.com/prometheus/procfs v0.15.1/go.mod h1:fB45yRUv8NstnjriLhBQLuOUt+WW4BsoGhij/e3PBqk=
|
||||||
github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
|
github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
|
||||||
github.com/spf13/cobra v1.8.1 h1:e5/vxKd/rZsfSJMUX1agtjeTDf+qv1/JdBF8gg5k9ZM=
|
github.com/spf13/cobra v1.8.1 h1:e5/vxKd/rZsfSJMUX1agtjeTDf+qv1/JdBF8gg5k9ZM=
|
||||||
github.com/spf13/cobra v1.8.1/go.mod h1:wHxEcudfqmLYa8iTfL+OuZPbBZkmvliBWKIezN3kD9Y=
|
github.com/spf13/cobra v1.8.1/go.mod h1:wHxEcudfqmLYa8iTfL+OuZPbBZkmvliBWKIezN3kD9Y=
|
||||||
github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA=
|
|
||||||
github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
|
github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
|
||||||
golang.org/x/crypto v0.27.0 h1:GXm2NjJrPaiv/h1tb2UH8QfgC/hOf/+z0p6PT8o1w7A=
|
github.com/spf13/pflag v1.0.6 h1:jFzHGLGAlb3ruxLB8MhbI6A8+AQX/2eW4qeyNZXNp2o=
|
||||||
golang.org/x/crypto v0.27.0/go.mod h1:1Xngt8kV6Dvbssa53Ziq6Eqn0HqbZi5Z6R0ZpwQzt70=
|
github.com/spf13/pflag v1.0.6/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
|
||||||
golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA=
|
||||||
golang.org/x/sys v0.25.0 h1:r+8e+loiHxRqhXVl6ML1nO3l1+oFoWbnlu2Ehimmi34=
|
github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
|
||||||
golang.org/x/sys v0.25.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
golang.org/x/crypto v0.32.0 h1:euUpcYgM8WcP71gNpTqQCn6rC2t6ULUPiOzfWaXVVfc=
|
||||||
google.golang.org/protobuf v1.33.0 h1:uNO2rsAINq/JlFpSdYEKIZ0uKD/R9cpdv0T+yoGwGmI=
|
golang.org/x/crypto v0.32.0/go.mod h1:ZnnJkOaASj8g0AjIduWNlq2NRxL0PlBrbKVyZ6V/Ugc=
|
||||||
google.golang.org/protobuf v1.33.0/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos=
|
golang.org/x/sys v0.30.0 h1:QjkSwP/36a20jFYWkSue1YwXzLmsV5Gfq7Eiy72C1uc=
|
||||||
|
golang.org/x/sys v0.30.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||||
|
google.golang.org/protobuf v1.36.5 h1:tPhr+woSbjfYvY6/GPufUoYizxw1cF/yFoxJ2fmpwlM=
|
||||||
|
google.golang.org/protobuf v1.36.5/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE=
|
||||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||||
|
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
||||||
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||||
|
|
|
@ -158,6 +158,7 @@ func join(base string, names ...string) (string, error) {
|
||||||
// splitURLPath splits the URL path into a folderPath of the subrepo, and
|
// splitURLPath splits the URL path into a folderPath of the subrepo, and
|
||||||
// a remainder that can be passed to repo.Handler.
|
// a remainder that can be passed to repo.Handler.
|
||||||
// Example: /foo/bar/locks/0123... will be split into:
|
// Example: /foo/bar/locks/0123... will be split into:
|
||||||
|
//
|
||||||
// ["foo", "bar"] and "/locks/0123..."
|
// ["foo", "bar"] and "/locks/0123..."
|
||||||
func splitURLPath(urlPath string, maxDepth int) (folderPath []string, remainder string) {
|
func splitURLPath(urlPath string, maxDepth int) (folderPath []string, remainder string) {
|
||||||
if !strings.HasPrefix(urlPath, "/") {
|
if !strings.HasPrefix(urlPath, "/") {
|
||||||
|
|
|
@ -6,7 +6,6 @@ import (
|
||||||
"encoding/hex"
|
"encoding/hex"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
"io/ioutil"
|
|
||||||
"net/http"
|
"net/http"
|
||||||
"net/http/httptest"
|
"net/http/httptest"
|
||||||
"os"
|
"os"
|
||||||
|
@ -165,7 +164,7 @@ func createOverwriteDeleteSeq(t testing.TB, path string, data string) []TestRequ
|
||||||
return req
|
return req
|
||||||
}
|
}
|
||||||
|
|
||||||
func createTestHandler(t *testing.T, conf Server) (http.Handler, string, string, string, func()) {
|
func createTestHandler(t *testing.T, conf *Server) (http.Handler, string, string, string, func()) {
|
||||||
buf := make([]byte, 32)
|
buf := make([]byte, 32)
|
||||||
_, err := io.ReadFull(rand.Reader, buf)
|
_, err := io.ReadFull(rand.Reader, buf)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -176,7 +175,7 @@ func createTestHandler(t *testing.T, conf Server) (http.Handler, string, string,
|
||||||
fileID := hex.EncodeToString(dataHash[:])
|
fileID := hex.EncodeToString(dataHash[:])
|
||||||
|
|
||||||
// setup the server with a local backend in a temporary directory
|
// setup the server with a local backend in a temporary directory
|
||||||
tempdir, err := ioutil.TempDir("", "rest-server-test-")
|
tempdir, err := os.MkdirTemp("", "rest-server-test-")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
|
@ -190,7 +189,7 @@ func createTestHandler(t *testing.T, conf Server) (http.Handler, string, string,
|
||||||
}
|
}
|
||||||
|
|
||||||
conf.Path = tempdir
|
conf.Path = tempdir
|
||||||
mux, err := NewHandler(&conf)
|
mux, err := NewHandler(conf)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("error from NewHandler: %v", err)
|
t.Fatalf("error from NewHandler: %v", err)
|
||||||
}
|
}
|
||||||
|
@ -199,7 +198,7 @@ func createTestHandler(t *testing.T, conf Server) (http.Handler, string, string,
|
||||||
|
|
||||||
// TestResticAppendOnlyHandler runs tests on the restic handler code, especially in append-only mode.
|
// TestResticAppendOnlyHandler runs tests on the restic handler code, especially in append-only mode.
|
||||||
func TestResticAppendOnlyHandler(t *testing.T) {
|
func TestResticAppendOnlyHandler(t *testing.T) {
|
||||||
mux, data, fileID, _, cleanup := createTestHandler(t, Server{
|
mux, data, fileID, _, cleanup := createTestHandler(t, &Server{
|
||||||
AppendOnly: true,
|
AppendOnly: true,
|
||||||
NoAuth: true,
|
NoAuth: true,
|
||||||
Debug: true,
|
Debug: true,
|
||||||
|
@ -300,7 +299,7 @@ func createIdempotentDeleteSeq(t testing.TB, path string, data string) []TestReq
|
||||||
|
|
||||||
// TestResticHandler runs tests on the restic handler code, especially in append-only mode.
|
// TestResticHandler runs tests on the restic handler code, especially in append-only mode.
|
||||||
func TestResticHandler(t *testing.T) {
|
func TestResticHandler(t *testing.T) {
|
||||||
mux, data, fileID, _, cleanup := createTestHandler(t, Server{
|
mux, data, fileID, _, cleanup := createTestHandler(t, &Server{
|
||||||
NoAuth: true,
|
NoAuth: true,
|
||||||
Debug: true,
|
Debug: true,
|
||||||
PanicOnError: true,
|
PanicOnError: true,
|
||||||
|
@ -331,7 +330,7 @@ func TestResticHandler(t *testing.T) {
|
||||||
|
|
||||||
// TestResticErrorHandler runs tests on the restic handler error handling.
|
// TestResticErrorHandler runs tests on the restic handler error handling.
|
||||||
func TestResticErrorHandler(t *testing.T) {
|
func TestResticErrorHandler(t *testing.T) {
|
||||||
mux, _, _, tempdir, cleanup := createTestHandler(t, Server{
|
mux, _, _, tempdir, cleanup := createTestHandler(t, &Server{
|
||||||
AppendOnly: true,
|
AppendOnly: true,
|
||||||
NoAuth: true,
|
NoAuth: true,
|
||||||
Debug: true,
|
Debug: true,
|
||||||
|
@ -380,7 +379,7 @@ func TestResticErrorHandler(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestEmptyList(t *testing.T) {
|
func TestEmptyList(t *testing.T) {
|
||||||
mux, _, _, _, cleanup := createTestHandler(t, Server{
|
mux, _, _, _, cleanup := createTestHandler(t, &Server{
|
||||||
AppendOnly: true,
|
AppendOnly: true,
|
||||||
NoAuth: true,
|
NoAuth: true,
|
||||||
Debug: true,
|
Debug: true,
|
||||||
|
@ -404,7 +403,7 @@ func TestEmptyList(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestListWithUnexpectedFiles(t *testing.T) {
|
func TestListWithUnexpectedFiles(t *testing.T) {
|
||||||
mux, _, _, tempdir, cleanup := createTestHandler(t, Server{
|
mux, _, _, tempdir, cleanup := createTestHandler(t, &Server{
|
||||||
AppendOnly: true,
|
AppendOnly: true,
|
||||||
NoAuth: true,
|
NoAuth: true,
|
||||||
Debug: true,
|
Debug: true,
|
||||||
|
@ -510,7 +509,7 @@ func newDelayedErrorReader(err error) *delayErrorReader {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *delayErrorReader) Read(p []byte) (int, error) {
|
func (d *delayErrorReader) Read(_ []byte) (int, error) {
|
||||||
d.firstReadOnce.Do(func() {
|
d.firstReadOnce.Do(func() {
|
||||||
// close the channel to signal that the first read has happened
|
// close the channel to signal that the first read has happened
|
||||||
close(d.FirstRead)
|
close(d.FirstRead)
|
||||||
|
@ -522,7 +521,7 @@ func (d *delayErrorReader) Read(p []byte) (int, error) {
|
||||||
// TestAbortedRequest runs tests with concurrent upload requests for the same file.
|
// TestAbortedRequest runs tests with concurrent upload requests for the same file.
|
||||||
func TestAbortedRequest(t *testing.T) {
|
func TestAbortedRequest(t *testing.T) {
|
||||||
// the race condition doesn't happen for append-only repositories
|
// the race condition doesn't happen for append-only repositories
|
||||||
mux, _, _, _, cleanup := createTestHandler(t, Server{
|
mux, _, _, _, cleanup := createTestHandler(t, &Server{
|
||||||
NoAuth: true,
|
NoAuth: true,
|
||||||
Debug: true,
|
Debug: true,
|
||||||
PanicOnError: true,
|
PanicOnError: true,
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
package restserver
|
package restserver
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"io/ioutil"
|
|
||||||
"os"
|
"os"
|
||||||
"testing"
|
"testing"
|
||||||
)
|
)
|
||||||
|
@ -12,7 +11,7 @@ func TestValidate(t *testing.T) {
|
||||||
rawPwd := "test"
|
rawPwd := "test"
|
||||||
wrongPwd := "wrong"
|
wrongPwd := "wrong"
|
||||||
|
|
||||||
tmpfile, err := ioutil.TempFile("", "rest-validate-")
|
tmpfile, err := os.CreateTemp("", "rest-validate-")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
|
|
|
@ -113,7 +113,7 @@ func tallySize(path string) (int64, error) {
|
||||||
path = "."
|
path = "."
|
||||||
}
|
}
|
||||||
var size int64
|
var size int64
|
||||||
err := filepath.Walk(path, func(path string, info os.FileInfo, err error) error {
|
err := filepath.Walk(path, func(_ string, info os.FileInfo, err error) error {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
37
repo/repo.go
37
repo/repo.go
|
@ -6,7 +6,6 @@ import (
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
"io/ioutil"
|
|
||||||
"log"
|
"log"
|
||||||
"math/rand"
|
"math/rand"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
@ -251,7 +250,7 @@ func (h *Handler) wrapFileWriter(r *http.Request, w io.Writer) (io.Writer, int,
|
||||||
}
|
}
|
||||||
|
|
||||||
// checkConfig checks whether a configuration exists.
|
// checkConfig checks whether a configuration exists.
|
||||||
func (h *Handler) checkConfig(w http.ResponseWriter, r *http.Request) {
|
func (h *Handler) checkConfig(w http.ResponseWriter, _ *http.Request) {
|
||||||
if h.opt.Debug {
|
if h.opt.Debug {
|
||||||
log.Println("checkConfig()")
|
log.Println("checkConfig()")
|
||||||
}
|
}
|
||||||
|
@ -267,13 +266,13 @@ func (h *Handler) checkConfig(w http.ResponseWriter, r *http.Request) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// getConfig allows for a config to be retrieved.
|
// getConfig allows for a config to be retrieved.
|
||||||
func (h *Handler) getConfig(w http.ResponseWriter, r *http.Request) {
|
func (h *Handler) getConfig(w http.ResponseWriter, _ *http.Request) {
|
||||||
if h.opt.Debug {
|
if h.opt.Debug {
|
||||||
log.Println("getConfig()")
|
log.Println("getConfig()")
|
||||||
}
|
}
|
||||||
cfg := h.getSubPath("config")
|
cfg := h.getSubPath("config")
|
||||||
|
|
||||||
bytes, err := ioutil.ReadFile(cfg)
|
bytes, err := os.ReadFile(cfg)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
h.fileAccessError(w, err)
|
h.fileAccessError(w, err)
|
||||||
return
|
return
|
||||||
|
@ -314,7 +313,7 @@ func (h *Handler) saveConfig(w http.ResponseWriter, r *http.Request) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// deleteConfig removes a config.
|
// deleteConfig removes a config.
|
||||||
func (h *Handler) deleteConfig(w http.ResponseWriter, r *http.Request) {
|
func (h *Handler) deleteConfig(w http.ResponseWriter, _ *http.Request) {
|
||||||
if h.opt.Debug {
|
if h.opt.Debug {
|
||||||
log.Println("deleteConfig()")
|
log.Println("deleteConfig()")
|
||||||
}
|
}
|
||||||
|
@ -369,7 +368,7 @@ func (h *Handler) listBlobsV1(w http.ResponseWriter, r *http.Request) {
|
||||||
}
|
}
|
||||||
path := h.getSubPath(objectType)
|
path := h.getSubPath(objectType)
|
||||||
|
|
||||||
items, err := ioutil.ReadDir(path)
|
items, err := os.ReadDir(path)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
h.fileAccessError(w, err)
|
h.fileAccessError(w, err)
|
||||||
return
|
return
|
||||||
|
@ -383,8 +382,8 @@ func (h *Handler) listBlobsV1(w http.ResponseWriter, r *http.Request) {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
subpath := filepath.Join(path, i.Name())
|
subpath := filepath.Join(path, i.Name())
|
||||||
var subitems []os.FileInfo
|
var subitems []os.DirEntry
|
||||||
subitems, err = ioutil.ReadDir(subpath)
|
subitems, err = os.ReadDir(subpath)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
h.fileAccessError(w, err)
|
h.fileAccessError(w, err)
|
||||||
return
|
return
|
||||||
|
@ -428,7 +427,7 @@ func (h *Handler) listBlobsV2(w http.ResponseWriter, r *http.Request) {
|
||||||
}
|
}
|
||||||
path := h.getSubPath(objectType)
|
path := h.getSubPath(objectType)
|
||||||
|
|
||||||
items, err := ioutil.ReadDir(path)
|
items, err := os.ReadDir(path)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
h.fileAccessError(w, err)
|
h.fileAccessError(w, err)
|
||||||
return
|
return
|
||||||
|
@ -442,17 +441,27 @@ func (h *Handler) listBlobsV2(w http.ResponseWriter, r *http.Request) {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
subpath := filepath.Join(path, i.Name())
|
subpath := filepath.Join(path, i.Name())
|
||||||
var subitems []os.FileInfo
|
var subitems []os.DirEntry
|
||||||
subitems, err = ioutil.ReadDir(subpath)
|
subitems, err = os.ReadDir(subpath)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
h.fileAccessError(w, err)
|
h.fileAccessError(w, err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
for _, f := range subitems {
|
for _, f := range subitems {
|
||||||
blobs = append(blobs, Blob{Name: f.Name(), Size: f.Size()})
|
fi, err := f.Info()
|
||||||
|
if err != nil {
|
||||||
|
h.fileAccessError(w, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
blobs = append(blobs, Blob{Name: f.Name(), Size: fi.Size()})
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
blobs = append(blobs, Blob{Name: i.Name(), Size: i.Size()})
|
fi, err := i.Info()
|
||||||
|
if err != nil {
|
||||||
|
h.fileAccessError(w, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
blobs = append(blobs, Blob{Name: i.Name(), Size: fi.Size()})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -652,7 +661,7 @@ func (h *Handler) saveBlob(w http.ResponseWriter, r *http.Request) {
|
||||||
h.sendMetric(objectType, BlobWrite, uint64(written))
|
h.sendMetric(objectType, BlobWrite, uint64(written))
|
||||||
}
|
}
|
||||||
|
|
||||||
// tempFile implements a custom version of ioutil.TempFile which allows modifying the file permissions
|
// tempFile implements a custom version of os.CreateTemp which allows modifying the file permissions
|
||||||
func tempFile(fn string, perm os.FileMode) (f *os.File, err error) {
|
func tempFile(fn string, perm os.FileMode) (f *os.File, err error) {
|
||||||
for i := 0; i < 10; i++ {
|
for i := 0; i < 10; i++ {
|
||||||
name := fn + strconv.FormatInt(rand.Int63(), 10)
|
name := fn + strconv.FormatInt(rand.Int63(), 10)
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue