From 4cb89bc400ce2a2dedb9aabb89dd4c09b40d6243 Mon Sep 17 00:00:00 2001 From: Mura Li Date: Mon, 10 Oct 2016 14:51:36 +0800 Subject: [PATCH 1/2] 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. --- routers/repo/http.go | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/routers/repo/http.go b/routers/repo/http.go index 80afcec410e02..1de570633db34 100644 --- a/routers/repo/http.go +++ b/routers/repo/http.go @@ -364,14 +364,22 @@ 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()) - 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 } From a0ca633c1ad39eef3445a0601723518e0506be99 Mon Sep 17 00:00:00 2001 From: Mura Li Date: Mon, 10 Oct 2016 15:21:41 +0800 Subject: [PATCH 2/2] Must close the open file to avoid fd leaks --- routers/repo/http.go | 1 + 1 file changed, 1 insertion(+) diff --git a/routers/repo/http.go b/routers/repo/http.go index 1de570633db34..f06d39d40e6e5 100644 --- a/routers/repo/http.go +++ b/routers/repo/http.go @@ -371,6 +371,7 @@ func serviceRPC(h serviceHandler, service string) { return } defer os.Remove(tmpfile.Name()) + defer tmpfile.Close() _, err = io.Copy(tmpfile, reqBody) if err != nil {