Skip to content

Commit

Permalink
net/http: add a test to verify form tempfiles are deleted
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
neild committed Aug 12, 2022
1 parent f3c39a8 commit ebbf2b4
Showing 1 changed file with 66 additions and 0 deletions.
66 changes: 66 additions & 0 deletions src/net/http/serve_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import (
"io"
"log"
"math/rand"
"mime/multipart"
"net"
. "net/http"
"net/http/httptest"
Expand Down Expand Up @@ -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))
}
}

0 comments on commit ebbf2b4

Please sign in to comment.