net/http: add a test to verify form tempfiles are deleted

The HTTP/1 server deletes multipart form tempfiles after ServeHTTP
returns, but the HTTP/2 server does not. Add a test to verify
cleanup happens in both cases, temporarily disabled for the
HTTP/2 path.

For #20253
Updates #25965

Change-Id: Ib753f2761fe73b29321d9d4337dbb5090fd193c2
Reviewed-on: https://go-review.googlesource.com/c/go/+/423194
TryBot-Result: Gopher Robot <gobot@golang.org>
Run-TryBot: Damien Neil <dneil@google.com>
Reviewed-by: Robert Griesemer <gri@google.com>
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
This commit is contained in:
Damien Neil 2022-08-11 15:56:34 -07:00
parent f3c39a83a3
commit ebbf2b44c5

View file

@ -20,6 +20,7 @@ import (
"io"
"log"
"math/rand"
"mime/multipart"
"net"
. "net/http"
"net/http/httptest"
@ -6758,3 +6759,68 @@ func TestProcessing(t *testing.T) {
t.Errorf("unexpected response; got %q; should start by %q", got, expected)
}
}
func TestParseFormCleanup_h1(t *testing.T) { testParseFormCleanup(t, h1Mode) }
func TestParseFormCleanup_h2(t *testing.T) {
t.Skip("https://go.dev/issue/20253")
testParseFormCleanup(t, h2Mode)
}
func testParseFormCleanup(t *testing.T, h2 bool) {
const maxMemory = 1024
const key = "file"
if runtime.GOOS == "windows" {
// Windows sometimes refuses to remove a file that was just closed.
t.Skip("https://go.dev/issue/25965")
}
setParallel(t)
defer afterTest(t)
cst := newClientServerTest(t, h2, HandlerFunc(func(w ResponseWriter, r *Request) {
r.ParseMultipartForm(maxMemory)
f, _, err := r.FormFile(key)
if err != nil {
t.Errorf("r.FormFile(%q) = %v", key, err)
return
}
of, ok := f.(*os.File)
if !ok {
t.Errorf("r.FormFile(%q) returned type %T, want *os.File", key, f)
return
}
w.Write([]byte(of.Name()))
}))
defer cst.close()
fBuf := new(bytes.Buffer)
mw := multipart.NewWriter(fBuf)
mf, err := mw.CreateFormFile(key, "myfile.txt")
if err != nil {
t.Fatal(err)
}
if _, err := mf.Write(bytes.Repeat([]byte("A"), maxMemory*2)); err != nil {
t.Fatal(err)
}
if err := mw.Close(); err != nil {
t.Fatal(err)
}
req, err := NewRequest("POST", cst.ts.URL, fBuf)
if err != nil {
t.Fatal(err)
}
req.Header.Set("Content-Type", mw.FormDataContentType())
res, err := cst.c.Do(req)
if err != nil {
t.Fatal(err)
}
defer res.Body.Close()
fname, err := io.ReadAll(res.Body)
if err != nil {
t.Fatal(err)
}
cst.close()
if _, err := os.Stat(string(fname)); !errors.Is(err, os.ErrNotExist) {
t.Errorf("file %q exists after HTTP handler returned", string(fname))
}
}