aboutsummaryrefslogtreecommitdiff
path: root/src/net/http
diff options
context:
space:
mode:
authorDamien Neil <dneil@google.com>2022-08-11 15:56:34 -0700
committerDamien Neil <dneil@google.com>2022-08-12 17:25:47 +0000
commitebbf2b44c59e2c473ed4ed6b0e044f5daee75e54 (patch)
tree722c311ee54a67b4273004546c6401d47833cd28 /src/net/http
parentf3c39a83a3076eb560c7f687cbb35eef9b506e7d (diff)
downloadgo-ebbf2b44c59e2c473ed4ed6b0e044f5daee75e54.tar.xz
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>
Diffstat (limited to 'src/net/http')
-rw-r--r--src/net/http/serve_test.go66
1 files changed, 66 insertions, 0 deletions
diff --git a/src/net/http/serve_test.go b/src/net/http/serve_test.go
index cb6312d641..f956e66c44 100644
--- a/src/net/http/serve_test.go
+++ b/src/net/http/serve_test.go
@@ -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))
+ }
+}