diff options
author | typeless <typeless@users.noreply.github.com> | 2016-12-24 08:50:12 +0800 |
---|---|---|
committer | 无闻 <u@gogs.io> | 2016-12-23 19:50:12 -0500 |
commit | cdedc2d188ad0e0a366c0cf9747011be2cbb2eff (patch) | |
tree | ecb9637823fc122f863891b66015b948798a83f7 /routers/repo/http.go | |
parent | 42a3bbb0f426720ac4f95a5ca7832f008156cb82 (diff) |
Use temporary file to avoid out-of-memory when receiving big chunks. (#3748)
* Use temporary file to avoid out-of-memory when receiving big chunk.
Not perfect but I think it's a reasonable solution.
For small request bodies, I suppose performance wouldn't be an issue.
For large ones, this seems to be a necessary evil.
* Must close the open file to avoid fd leaks
Diffstat (limited to 'routers/repo/http.go')
-rw-r--r-- | routers/repo/http.go | 15 |
1 files changed, 12 insertions, 3 deletions
diff --git a/routers/repo/http.go b/routers/repo/http.go index 31d8ab13..6ee0a532 100644 --- a/routers/repo/http.go +++ b/routers/repo/http.go @@ -364,14 +364,23 @@ func serviceRPC(h serviceHandler, service string) { } if h.cfg.OnSucceed != nil { - input, err = ioutil.ReadAll(reqBody) + tmpfile, err := ioutil.TempFile("", "gogs") if err != nil { - log.GitLogger.Error(2, "fail to read request body: %v", err) + log.GitLogger.Error(2, "fail to create temporary file: %v", err) h.w.WriteHeader(http.StatusInternalServerError) return } + defer os.Remove(tmpfile.Name()) + defer tmpfile.Close() - br = bytes.NewReader(input) + _, err = io.Copy(tmpfile, reqBody) + if err != nil { + log.GitLogger.Error(2, "fail to save request body: %v", err) + h.w.WriteHeader(http.StatusInternalServerError) + return + } + + br = tmpfile } else { br = reqBody } |