fix: avoid reading upload body when writing JSON errors (#10073)
* fix(shell): correct volume.list -writable filter unit and comparison * fix(shell): correct volume.list -writable filter unit and comparison * chore(shell): fix typo in EC shard helper param names * fix(shell): use exact match for volume.balance -racks/-nodes filter The old strings.Contains-based filter quietly included any id that was a substring of the user-supplied flag value (e.g. -racks=rack10 also matched rack1). Replace it with an exact-match set parsed from the comma-separated flag value, and add regression tests for both -racks and -nodes paths. Also fix a small typo in the "remote storage" error returned by maybeMoveOneVolume. * fix(shell): use exact match for volume.balance -racks/-nodes filter The old strings.Contains-based filter quietly included any id that was a substring of the user-supplied flag value (e.g. -racks=rack10 also matched rack1). Replace it with an exact-match set parsed from the comma-separated flag value, and add regression tests for both -racks and -nodes paths. Also fix a small typo in the "remote storage" error returned by maybeMoveOneVolume. * refactor(shell): drop nil sentinel in splitCSVSet, use len() in callers * fix: avoid reading upload body when writing JSON errors
This commit is contained in:
parent
c95401b11a
commit
18b03d5dc7
@ -95,7 +95,7 @@ func writeJson(w http.ResponseWriter, r *http.Request, httpStatus int, obj inter
|
||||
|
||||
var bytes []byte
|
||||
if obj != nil {
|
||||
if r.FormValue("pretty") != "" {
|
||||
if r.URL.Query().Get("pretty") != "" {
|
||||
bytes, err = json.MarshalIndent(obj, "", " ")
|
||||
} else {
|
||||
bytes, err = json.Marshal(obj)
|
||||
|
||||
@ -1,6 +1,9 @@
|
||||
package weed_server
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"io"
|
||||
"mime/multipart"
|
||||
"net/http"
|
||||
"net/http/httptest"
|
||||
"strings"
|
||||
@ -61,3 +64,51 @@ func TestWriteJsonNoJSONP(t *testing.T) {
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestWriteJsonPrettyDoesNotReadMultipartBody(t *testing.T) {
|
||||
var form bytes.Buffer
|
||||
mw := multipart.NewWriter(&form)
|
||||
if err := mw.WriteField("pretty", "1"); err != nil {
|
||||
t.Fatalf("write pretty field: %v", err)
|
||||
}
|
||||
part, err := mw.CreateFormFile("file", "test.txt")
|
||||
if err != nil {
|
||||
t.Fatalf("create form file: %v", err)
|
||||
}
|
||||
if _, err := part.Write([]byte("hello")); err != nil {
|
||||
t.Fatalf("write form file: %v", err)
|
||||
}
|
||||
if err := mw.Close(); err != nil {
|
||||
t.Fatalf("close multipart writer: %v", err)
|
||||
}
|
||||
|
||||
body := &countingReadCloser{Reader: bytes.NewReader(form.Bytes())}
|
||||
r := httptest.NewRequest(http.MethodPost, "/x", body)
|
||||
r.Header.Set("Content-Type", mw.FormDataContentType())
|
||||
w := httptest.NewRecorder()
|
||||
|
||||
if err := writeJson(w, r, http.StatusTooManyRequests, map[string]string{"error": "busy"}); err != nil {
|
||||
t.Fatalf("writeJson: %v", err)
|
||||
}
|
||||
|
||||
if body.reads != 0 {
|
||||
t.Fatalf("writeJson read multipart body %d times", body.reads)
|
||||
}
|
||||
if got, want := w.Body.String(), `{"error":"busy"}`; got != want {
|
||||
t.Fatalf("body: got %q want %q", got, want)
|
||||
}
|
||||
}
|
||||
|
||||
type countingReadCloser struct {
|
||||
io.Reader
|
||||
reads int
|
||||
}
|
||||
|
||||
func (c *countingReadCloser) Read(p []byte) (int, error) {
|
||||
c.reads++
|
||||
return c.Reader.Read(p)
|
||||
}
|
||||
|
||||
func (c *countingReadCloser) Close() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user