From e98bd36d2501edfdae77c2650041eb914e2baf6b Mon Sep 17 00:00:00 2001 From: Paulo Gomes Date: Tue, 15 Mar 2022 14:42:54 +0000 Subject: [PATCH] Fix race condition on httpSmartSubTransport Signed-off-by: Paulo Gomes --- pkg/git/libgit2/managed/http.go | 57 ++++++++++++++++++--------------- 1 file changed, 31 insertions(+), 26 deletions(-) diff --git a/pkg/git/libgit2/managed/http.go b/pkg/git/libgit2/managed/http.go index 5c71f9a34..b9607280f 100644 --- a/pkg/git/libgit2/managed/http.go +++ b/pkg/git/libgit2/managed/http.go @@ -217,6 +217,7 @@ type httpSmartSubtransportStream struct { sentRequest bool recvReply sync.WaitGroup httpError error + m sync.RWMutex } func newManagedHttpStream(owner *httpSmartSubtransport, req *http.Request, client *http.Client) *httpSmartSubtransportStream { @@ -244,6 +245,8 @@ func (self *httpSmartSubtransportStream) Read(buf []byte) (int, error) { self.recvReply.Wait() + self.m.RLock() + defer self.m.RUnlock() if self.httpError != nil { return 0, self.httpError } @@ -252,6 +255,8 @@ func (self *httpSmartSubtransportStream) Read(buf []byte) (int, error) { } func (self *httpSmartSubtransportStream) Write(buf []byte) (int, error) { + self.m.RLock() + defer self.m.RUnlock() if self.httpError != nil { return 0, self.httpError } @@ -266,7 +271,11 @@ func (self *httpSmartSubtransportStream) Free() { func (self *httpSmartSubtransportStream) sendRequestBackground() { go func() { - self.httpError = self.sendRequest() + err := self.sendRequest() + + self.m.Lock() + self.httpError = err + self.m.Unlock() }() self.sentRequest = true } @@ -299,33 +308,29 @@ func (self *httpSmartSubtransportStream) sendRequest() error { } } - for { - req := &http.Request{ - Method: self.req.Method, - URL: self.req.URL, - Header: self.req.Header, - } - if req.Method == "POST" { - req.Body = self.reader - req.ContentLength = -1 - } - - req.SetBasicAuth(userName, password) - resp, err = self.client.Do(req) - if err != nil { - return err - } + req := &http.Request{ + Method: self.req.Method, + URL: self.req.URL, + Header: self.req.Header, + } + if req.Method == "POST" { + req.Body = self.reader + req.ContentLength = -1 + } - if resp.StatusCode == http.StatusOK { - break - } + req.SetBasicAuth(userName, password) + resp, err = self.client.Do(req) + if err != nil { + return err + } - io.Copy(ioutil.Discard, resp.Body) - resp.Body.Close() - return fmt.Errorf("Unhandled HTTP error %s", resp.Status) + if resp.StatusCode == http.StatusOK { + self.resp = resp + self.sentRequest = true + return nil } - self.sentRequest = true - self.resp = resp - return nil + io.Copy(ioutil.Discard, resp.Body) + defer resp.Body.Close() + return fmt.Errorf("Unhandled HTTP error %s", resp.Status) }