Skip to content

Commit

Permalink
FFM-11006 Add Connection close header (#141)
Browse files Browse the repository at this point in the history
* FFM-11006 Add Connection close header

**What**

- Adds a connection close header to the http requests to prevent
  connections being re-used

**Why**

- We were seeing every other POST /metrics request fail with an EOF
  error but when we ran with the debugger this didn't happen. After some
research it seems like this can happen due to the way the http client
tries to re-use connections. Adding this header means we'll close the
connection once the request has completed

**Testing**

- Tested this fix out locally

Co-authored-by: Erdi Rowlands <erdirowlands@gmail.com>
  • Loading branch information
jcox250 and erdirowlands committed Mar 22, 2024
1 parent 7d99c9a commit 5546ef7
Show file tree
Hide file tree
Showing 3 changed files with 18 additions and 11 deletions.
4 changes: 2 additions & 2 deletions .harness/ffgolangserversdk.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ pipeline:
identifier: Submodule_Init
spec:
connectorRef: DockerHub
image: golang:1.18.6
image: golang:1.19.9
shell: Sh
command: "mkdir -p ~/.ssh\nssh-keyscan -t rsa github.com >> ~/.ssh/known_hosts\n\ncat <<EOF >> .gitmodules\n[submodule \"tests/ff-test-cases\"]\n\tpath = tests/ff-test-cases\n\turl = https://github.com/drone/ff-test-cases.git\nEOF\n\ngit submodule update --init --recursive"
- parallel:
Expand All @@ -46,7 +46,7 @@ pipeline:
identifier: Build_and_Test
spec:
connectorRef: DockerHub
image: golang:1.18.6
image: golang:1.19.9
shell: Sh
command: |-
go install github.com/jstemmer/go-junit-report@latest
Expand Down
21 changes: 14 additions & 7 deletions client/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,16 +5,17 @@ import (
"encoding/json"
"errors"
"fmt"
"github.com/cenkalti/backoff/v4"
"github.com/harness/ff-golang-server-sdk/sdk_codes"
"golang.org/x/sync/errgroup"
"log"
"net/http"
"strings"
"sync"
"sync/atomic"
"time"

"github.com/cenkalti/backoff/v4"
"github.com/harness/ff-golang-server-sdk/sdk_codes"
"golang.org/x/sync/errgroup"

"github.com/harness/ff-golang-server-sdk/evaluation"
"github.com/harness/ff-golang-server-sdk/logger"

Expand Down Expand Up @@ -393,14 +394,20 @@ func (c *CfClient) authenticate(ctx context.Context) error {
// Use a custom transport which adds headers for tracking usage
// The `WithRequestEditorFn` cannot be used for SSE requests, so we need to provide a custom transport to the
// http client so that these headers can be added to all requests.
getHeadersFn := func() (map[string]string, error) {
return map[string]string{
getHeadersFn := func(r *http.Request) (map[string]string, error) {
headers := map[string]string{
"User-Agent": "GoSDK/" + analyticsservice.SdkVersion,
"Harness-SDK-Info": fmt.Sprintf("Go %s Server", analyticsservice.SdkVersion),
"Harness-EnvironmentID": c.environmentID,
}, nil
}

if strings.Contains(r.URL.Path, "/metrics") && r.Method == http.MethodPost {
headers["Connection"] = "close"
}

return headers, nil
}

// Wrap the httpClient's transport with our own custom transport, which currently just adds extra headers
// for analytics purposes.
// If the httpClient doesn't have a Transport we can honour, then just use a default transport.
Expand Down
4 changes: 2 additions & 2 deletions client/transport.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ package client
import "net/http"

// HeadersFn is a function type that provides headers dynamically.
type HeadersFn func() (map[string]string, error)
type HeadersFn func(r *http.Request) (map[string]string, error)

// customTransport wraps an http.RoundTripper and allows adding headers dynamically. This means we can still use
// the goretryable-http client's transport, or a user's transport if they've provided their own http client.
Expand All @@ -22,7 +22,7 @@ func NewCustomTransport(baseTransport http.RoundTripper, getHeaderFn HeadersFn)

func (t *customTransport) RoundTrip(req *http.Request) (*http.Response, error) {
// Retrieve the headers using the provided function.
headers, err := t.getHeaders()
headers, err := t.getHeaders(req)
if err != nil {
return nil, err
}
Expand Down

0 comments on commit 5546ef7

Please sign in to comment.