Welcome to mirror list, hosted at ThFree Co, Russian Federation.

gitlab.com/gitlab-org/gitlab-pages.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGrzegorz Bizon <grzesiek.bizon@gmail.com>2020-04-29 17:36:20 +0300
committerGrzegorz Bizon <grzesiek.bizon@gmail.com>2020-05-12 12:32:12 +0300
commit9f582c2a1c7a2438f32fb870bc7ad7d9fa6addeb (patch)
treea88507a3602eeadd5a22d84b97703a6e5032ab03 /internal/source
parentef580296e32c973655791371443175d1aa3c8f9d (diff)
Ensure that we always close GitLab API response body
This change is important because in case of receiving a JSON payload from GitLab API that is invalid, and is larger than 512, deserializer will stop reading it after 512 bytes and will not close the reader. This will result in HTTP connection not being reused. This commit ensures that we always read reasponse body until EOF and that we close the reader afterwards.
Diffstat (limited to 'internal/source')
-rw-r--r--internal/source/gitlab/client/client.go9
-rw-r--r--internal/source/gitlab/client/client_test.go36
2 files changed, 45 insertions, 0 deletions
diff --git a/internal/source/gitlab/client/client.go b/internal/source/gitlab/client/client.go
index afe9da6f..ea7a6cf8 100644
--- a/internal/source/gitlab/client/client.go
+++ b/internal/source/gitlab/client/client.go
@@ -85,6 +85,15 @@ func (gc *Client) GetLookup(ctx context.Context, host string) api.Lookup {
return api.Lookup{Name: host}
}
+ // ensure that entire response body has been read and close it, to make it
+ // possible to reuse HTTP connection. In case of a JSON being invalid and
+ // larger than 512 bytes, the response body will not be closed properly, thus
+ // we need to close it manually in every case.
+ defer func() {
+ io.Copy(ioutil.Discard, resp.Body)
+ resp.Body.Close()
+ }()
+
lookup := api.Lookup{Name: host}
lookup.Error = json.NewDecoder(resp.Body).Decode(&lookup.Domain)
diff --git a/internal/source/gitlab/client/client_test.go b/internal/source/gitlab/client/client_test.go
index 58729153..02684860 100644
--- a/internal/source/gitlab/client/client_test.go
+++ b/internal/source/gitlab/client/client_test.go
@@ -6,6 +6,7 @@ import (
"fmt"
"net/http"
"net/http/httptest"
+ "net/http/httptrace"
"testing"
"time"
@@ -20,6 +21,41 @@ const (
defaultJWTTokenExpiry = 30 * time.Second
)
+func TestConnectionReuse(t *testing.T) {
+ mux := http.NewServeMux()
+
+ mux.HandleFunc("/api/v4/internal/pages", func(w http.ResponseWriter, r *http.Request) {
+ w.WriteHeader(http.StatusOK)
+
+ // we want to test for an invalid JSON that is larger than 512 bytes
+ b := make([]byte, 513)
+ for i := range b {
+ b[i] = 'x'
+ }
+
+ w.Write(b)
+ })
+
+ server := httptest.NewServer(mux)
+ defer server.Close()
+
+ client := defaultClient(t, server.URL)
+ reused := make(chan bool, 2)
+
+ trace := &httptrace.ClientTrace{
+ GotConn: func(connInfo httptrace.GotConnInfo) {
+ reused <- connInfo.Reused
+ },
+ }
+
+ ctx := httptrace.WithClientTrace(context.Background(), trace)
+ client.GetLookup(ctx, "group.gitlab.io")
+ client.GetLookup(ctx, "group.gitlab.io")
+
+ require.False(t, <-reused)
+ require.True(t, <-reused)
+}
+
func TestNewValidBaseURL(t *testing.T) {
_, err := NewClient("https://gitlab.com", secretKey(t), defaultClientConnTimeout, defaultJWTTokenExpiry)
require.NoError(t, err)