Skip to content

Commit

Permalink
fix(otelgin): remove multipartform temporary file
Browse files Browse the repository at this point in the history
  • Loading branch information
Yiling-J committed Jan 13, 2025
1 parent 9640704 commit 6875165
Show file tree
Hide file tree
Showing 2 changed files with 55 additions and 0 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,17 @@ func Middleware(service string, opts ...Option) gin.HandlerFunc {

// pass the span through the request context
c.Request = c.Request.WithContext(ctx)
defer func() {
// as we have created new http.Request object we need to make sure that temporary files created to hold MultipartForm
// files are cleaned up. This is done by http.Server at the end of request lifecycle but Server does not
// have reference to our new Request instance therefore it is our responsibility to fix the mess we caused.
//
// This means that when we are on returning path from handler middlewares up in chain from this middleware
// can not access these temporary files anymore because we deleted them here.
if c.Request.MultipartForm != nil {
c.Request.MultipartForm.RemoveAll()
}
}()

// serve the request to the next middleware
c.Next()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,11 @@
package test

import (
"bytes"
"errors"
"html/template"
"io/fs"
"mime/multipart"
"net/http"
"net/http/httptest"
"strconv"
Expand Down Expand Up @@ -430,3 +433,44 @@ func TestWithGinFilter(t *testing.T) {
assert.Len(t, sr.Ended(), 1)
})
}

func TestTemporaryFormFileRemove(t *testing.T) {
sr := tracetest.NewSpanRecorder()
provider := sdktrace.NewTracerProvider(sdktrace.WithSpanProcessor(sr))

router := gin.New()
router.MaxMultipartMemory = 1
router.Use(otelgin.Middleware("foobar", otelgin.WithTracerProvider(provider)))
var fileHeader *multipart.FileHeader
router.POST("/upload", func(c *gin.Context) {
ff, err := c.FormFile("file")
if err != nil {
_ = c.AbortWithError(http.StatusInternalServerError, err)
return
}
_ = ff
fileHeader = c.Request.MultipartForm.File["file"][0]
c.JSON(http.StatusOK, nil)
})

var body bytes.Buffer

mw := multipart.NewWriter(&body)
fw, err := mw.CreateFormFile("file", "file")
require.NoError(t, err)

_, err = fw.Write([]byte("hello world"))
require.NoError(t, err)
err = mw.Close()
require.NoError(t, err)
r := httptest.NewRequest("POST", "/upload", &body)
r.Header.Add("Content-Type", mw.FormDataContentType())
w := httptest.NewRecorder()

router.ServeHTTP(w, r)
assert.Len(t, sr.Ended(), 1)
require.Equal(t, http.StatusOK, w.Code)
_, err = fileHeader.Open()
require.ErrorIs(t, err, fs.ErrNotExist)

}

0 comments on commit 6875165

Please sign in to comment.