diff --git a/cmd/rest-server/listener_unix_test.go b/cmd/rest-server/listener_unix_test.go index a4f32f4..2143135 100644 --- a/cmd/rest-server/listener_unix_test.go +++ b/cmd/rest-server/listener_unix_test.go @@ -61,7 +61,10 @@ func TestUnixSocket(t *testing.T) { if err != nil { return err } - resp.Body.Close() + err = resp.Body.Close() + if err != nil { + return err + } if resp.StatusCode != test.StatusCode { return fmt.Errorf("expected %d from server, instead got %d (path %s)", test.StatusCode, resp.StatusCode, test.Path) } diff --git a/cmd/rest-server/main.go b/cmd/rest-server/main.go index 0bdd1eb..aa921c9 100644 --- a/cmd/rest-server/main.go +++ b/cmd/rest-server/main.go @@ -22,7 +22,7 @@ import ( type restServerApp struct { CmdRoot *cobra.Command Server restserver.Server - CpuProfile string + CPUProfile string listenerAddressMu sync.Mutex listenerAddress net.Addr // set after startup @@ -36,7 +36,7 @@ func newRestServerApp() *restServerApp { Short: "Run a REST server for use with restic", SilenceErrors: true, SilenceUsage: true, - Args: func(cmd *cobra.Command, args []string) error { + Args: func(_ *cobra.Command, args []string) error { if len(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 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.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)") @@ -103,17 +103,19 @@ func (app *restServerApp) ListenerAddress() net.Addr { 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.Printf("Data directory: %s", app.Server.Path) - if app.CpuProfile != "" { - f, err := os.Create(app.CpuProfile) + if app.CPUProfile != "" { + f, err := os.Create(app.CPUProfile) if err != nil { return err } - defer f.Close() + defer func() { + _ = f.Close() + }() if err := pprof.StartCPUProfile(f); err != nil { return err diff --git a/cmd/rest-server/main_test.go b/cmd/rest-server/main_test.go index 7366981..1171530 100644 --- a/cmd/rest-server/main_test.go +++ b/cmd/rest-server/main_test.go @@ -4,7 +4,6 @@ import ( "context" "errors" "fmt" - "io/ioutil" "net/http" "net/url" "os" @@ -94,7 +93,7 @@ func TestTLSSettings(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 { t.Fatal(err) } @@ -120,7 +119,7 @@ func TestGetHandler(t *testing.T) { } // With NoAuth = false and custom .htpasswd - htpFile, err := ioutil.TempFile(dir, "custom") + htpFile, err := os.CreateTemp(dir, "custom") if err != nil { t.Fatal(err) } @@ -137,7 +136,7 @@ func TestGetHandler(t *testing.T) { // Create .htpasswd htpasswd := filepath.Join(dir, ".htpasswd") - err = ioutil.WriteFile(htpasswd, []byte(""), 0644) + err = os.WriteFile(htpasswd, []byte(""), 0644) if err != nil { t.Fatal(err) } @@ -262,7 +261,10 @@ func TestHttpListen(t *testing.T) { if err != nil { return err } - resp.Body.Close() + err = resp.Body.Close() + if err != nil { + return err + } if resp.StatusCode != test.StatusCode { return fmt.Errorf("expected %d from server, instead got %d (path %s)", test.StatusCode, resp.StatusCode, test.Path) } diff --git a/handlers.go b/handlers.go index 8163ccf..1bccc60 100644 --- a/handlers.go +++ b/handlers.go @@ -158,7 +158,8 @@ func join(base string, names ...string) (string, error) { // splitURLPath splits the URL path into a folderPath of the subrepo, and // a remainder that can be passed to repo.Handler. // 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) { if !strings.HasPrefix(urlPath, "/") { // Really should start with "/" diff --git a/handlers_test.go b/handlers_test.go index 279951f..38773a2 100644 --- a/handlers_test.go +++ b/handlers_test.go @@ -6,7 +6,6 @@ import ( "encoding/hex" "fmt" "io" - "io/ioutil" "net/http" "net/http/httptest" "os" @@ -165,7 +164,7 @@ func createOverwriteDeleteSeq(t testing.TB, path string, data string) []TestRequ 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) _, err := io.ReadFull(rand.Reader, buf) if err != nil { @@ -176,7 +175,7 @@ func createTestHandler(t *testing.T, conf Server) (http.Handler, string, string, fileID := hex.EncodeToString(dataHash[:]) // 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 { t.Fatal(err) } @@ -190,7 +189,7 @@ func createTestHandler(t *testing.T, conf Server) (http.Handler, string, string, } conf.Path = tempdir - mux, err := NewHandler(&conf) + mux, err := NewHandler(conf) if err != nil { 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. func TestResticAppendOnlyHandler(t *testing.T) { - mux, data, fileID, _, cleanup := createTestHandler(t, Server{ + mux, data, fileID, _, cleanup := createTestHandler(t, &Server{ AppendOnly: true, NoAuth: 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. func TestResticHandler(t *testing.T) { - mux, data, fileID, _, cleanup := createTestHandler(t, Server{ + mux, data, fileID, _, cleanup := createTestHandler(t, &Server{ NoAuth: true, Debug: true, PanicOnError: true, @@ -331,7 +330,7 @@ func TestResticHandler(t *testing.T) { // TestResticErrorHandler runs tests on the restic handler error handling. func TestResticErrorHandler(t *testing.T) { - mux, _, _, tempdir, cleanup := createTestHandler(t, Server{ + mux, _, _, tempdir, cleanup := createTestHandler(t, &Server{ AppendOnly: true, NoAuth: true, Debug: true, @@ -380,7 +379,7 @@ func TestResticErrorHandler(t *testing.T) { } func TestEmptyList(t *testing.T) { - mux, _, _, _, cleanup := createTestHandler(t, Server{ + mux, _, _, _, cleanup := createTestHandler(t, &Server{ AppendOnly: true, NoAuth: true, Debug: true, @@ -404,7 +403,7 @@ func TestEmptyList(t *testing.T) { } func TestListWithUnexpectedFiles(t *testing.T) { - mux, _, _, tempdir, cleanup := createTestHandler(t, Server{ + mux, _, _, tempdir, cleanup := createTestHandler(t, &Server{ AppendOnly: true, NoAuth: 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() { // close the channel to signal that the first read has happened 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. func TestAbortedRequest(t *testing.T) { // the race condition doesn't happen for append-only repositories - mux, _, _, _, cleanup := createTestHandler(t, Server{ + mux, _, _, _, cleanup := createTestHandler(t, &Server{ NoAuth: true, Debug: true, PanicOnError: true, diff --git a/htpasswd_test.go b/htpasswd_test.go index 869883b..fe3a46e 100644 --- a/htpasswd_test.go +++ b/htpasswd_test.go @@ -1,7 +1,6 @@ package restserver import ( - "io/ioutil" "os" "testing" ) @@ -12,7 +11,7 @@ func TestValidate(t *testing.T) { rawPwd := "test" wrongPwd := "wrong" - tmpfile, err := ioutil.TempFile("", "rest-validate-") + tmpfile, err := os.CreateTemp("", "rest-validate-") if err != nil { t.Fatal(err) } diff --git a/quota/quota.go b/quota/quota.go index 0b1020e..8437f65 100644 --- a/quota/quota.go +++ b/quota/quota.go @@ -113,7 +113,7 @@ func tallySize(path string) (int64, error) { path = "." } 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 { return err } diff --git a/repo/repo.go b/repo/repo.go index d04879a..cd84929 100644 --- a/repo/repo.go +++ b/repo/repo.go @@ -6,7 +6,6 @@ import ( "errors" "fmt" "io" - "io/ioutil" "log" "math/rand" "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. -func (h *Handler) checkConfig(w http.ResponseWriter, r *http.Request) { +func (h *Handler) checkConfig(w http.ResponseWriter, _ *http.Request) { if h.opt.Debug { 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. -func (h *Handler) getConfig(w http.ResponseWriter, r *http.Request) { +func (h *Handler) getConfig(w http.ResponseWriter, _ *http.Request) { if h.opt.Debug { log.Println("getConfig()") } cfg := h.getSubPath("config") - bytes, err := ioutil.ReadFile(cfg) + bytes, err := os.ReadFile(cfg) if err != nil { h.fileAccessError(w, err) return @@ -314,7 +313,7 @@ func (h *Handler) saveConfig(w http.ResponseWriter, r *http.Request) { } // 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 { log.Println("deleteConfig()") } @@ -369,7 +368,7 @@ func (h *Handler) listBlobsV1(w http.ResponseWriter, r *http.Request) { } path := h.getSubPath(objectType) - items, err := ioutil.ReadDir(path) + items, err := os.ReadDir(path) if err != nil { h.fileAccessError(w, err) return @@ -383,8 +382,8 @@ func (h *Handler) listBlobsV1(w http.ResponseWriter, r *http.Request) { continue } subpath := filepath.Join(path, i.Name()) - var subitems []os.FileInfo - subitems, err = ioutil.ReadDir(subpath) + var subitems []os.DirEntry + subitems, err = os.ReadDir(subpath) if err != nil { h.fileAccessError(w, err) return @@ -428,7 +427,7 @@ func (h *Handler) listBlobsV2(w http.ResponseWriter, r *http.Request) { } path := h.getSubPath(objectType) - items, err := ioutil.ReadDir(path) + items, err := os.ReadDir(path) if err != nil { h.fileAccessError(w, err) return @@ -442,17 +441,27 @@ func (h *Handler) listBlobsV2(w http.ResponseWriter, r *http.Request) { continue } subpath := filepath.Join(path, i.Name()) - var subitems []os.FileInfo - subitems, err = ioutil.ReadDir(subpath) + var subitems []os.DirEntry + subitems, err = os.ReadDir(subpath) if err != nil { h.fileAccessError(w, err) return } 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 { - 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)) } -// 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) { for i := 0; i < 10; i++ { name := fn + strconv.FormatInt(rand.Int63(), 10)