Skip to content

Commit 0312e74

Browse files
authored
Add user-agent on requesting external url (#90)
This patch will add user-agent on requesting external endpoint such as fetching envoy binary or manifest. This enables us to know which version users use and make it easier to support GetEnvoy users. The format of user-agent is `GetEnvoy/{Version}`. Signed-off-by: Kotaro Inoue [email protected]
1 parent e0f3d4c commit 0312e74

File tree

7 files changed

+160
-8
lines changed

7 files changed

+160
-8
lines changed

.goreleaser.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ before:
2020
- go mod download
2121
builds:
2222
- binary: getenvoy
23-
ldflags: "-s -w -X github.com/tetratelabs/getenvoy/pkg/cmd.cliVersion={{.Version}}"
23+
ldflags: "-s -w -X github.com/tetratelabs/getenvoy/pkg/version.version={{.Version}}"
2424
main: ./cmd/getenvoy/main.go
2525
env:
2626
- CGO_ENABLED=0

pkg/binary/envoy/fetch.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ import (
3232
"github.com/mholt/archiver"
3333
"github.com/schollz/progressbar/v2"
3434
"github.com/tetratelabs/getenvoy/pkg/manifest"
35+
"github.com/tetratelabs/getenvoy/pkg/transport"
3536
"github.com/tetratelabs/log"
3637
)
3738

@@ -91,7 +92,7 @@ func fetchEnvoy(dst, src string) error {
9192

9293
func doDownload(dst, src string) (string, error) {
9394
// #nosec -> src destination can be anywhere by design
94-
resp, err := http.Get(src)
95+
resp, err := transport.Get(src)
9596
if err != nil {
9697
return "", err
9798
}

pkg/cmd/root.go

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -17,12 +17,10 @@ package cmd
1717
import (
1818
"github.com/spf13/cobra"
1919
"github.com/tetratelabs/getenvoy/pkg/manifest"
20+
"github.com/tetratelabs/getenvoy/pkg/version"
2021
)
2122

22-
// cliVersion exposed by goreleaser
23-
var cliVersion string
24-
25-
// NewRoot create a new root command and sets the cliVersion to the passed variable
23+
// NewRoot create a new root command and sets the version to the passed variable
2624
// TODO: Add version support on the command
2725
func NewRoot() *cobra.Command {
2826
rootCmd.AddCommand(NewRunCmd())
@@ -42,7 +40,7 @@ var (
4240
Short: "Fetch, deploy and debug Envoy",
4341
Long: `Manage full lifecycle of Envoy including fetching binaries,
4442
bootstrap generation and automated collection of access logs, Envoy state and machine state.`,
45-
Version: cliVersion,
43+
Version: version.Build.Version,
4644
}
4745

4846
manifestURL string

pkg/manifest/print.go

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,8 @@ import (
2222
"sort"
2323
"text/tabwriter"
2424

25+
"github.com/tetratelabs/getenvoy/pkg/transport"
26+
2527
"net/url"
2628

2729
"strings"
@@ -61,7 +63,7 @@ func platformFromEnum(s string) string {
6163

6264
func fetch(manifestURL string) (*api.Manifest, error) {
6365
// #nosec => This is by design, users can call out to wherever they like!
64-
resp, err := http.Get(manifestURL)
66+
resp, err := transport.Get(manifestURL)
6567
if err != nil {
6668
return nil, err
6769
}

pkg/transport/client.go

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
// Copyright 2020 Tetrate
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
package transport
16+
17+
import (
18+
"fmt"
19+
"net/http"
20+
21+
"github.com/tetratelabs/getenvoy/pkg/version"
22+
)
23+
24+
var (
25+
cliUserAgent = fmt.Sprintf("GetEnvoy/%s", version.Build.Version)
26+
defaultClient = NewClient(AddUserAgent(cliUserAgent))
27+
)
28+
29+
// Option represents an argument of NewClient
30+
type Option func(http.RoundTripper) http.RoundTripper
31+
32+
// NewClient returns HTTP client for use of GetEnvoy CLI.
33+
func NewClient(opts ...Option) *http.Client {
34+
tr := http.DefaultTransport
35+
for _, opt := range opts {
36+
tr = opt(tr)
37+
}
38+
client := &http.Client{Transport: tr}
39+
return client
40+
}
41+
42+
// AddUserAgent returns Option that adds passed user-agent to every requests.
43+
// It should be passed as an argument of NewClient.
44+
func AddUserAgent(ua string) Option {
45+
return func(tr http.RoundTripper) http.RoundTripper {
46+
return &funcTripper{roundTrip: func(r *http.Request) (*http.Response, error) {
47+
r.Header.Add("User-Agent", ua)
48+
return tr.RoundTrip(r)
49+
}}
50+
}
51+
}
52+
53+
type funcTripper struct {
54+
roundTrip func(*http.Request) (*http.Response, error)
55+
}
56+
57+
func (f funcTripper) RoundTrip(r *http.Request) (*http.Response, error) {
58+
return f.roundTrip(r)
59+
}
60+
61+
// Get is thin wrapper of net/http.Get.
62+
func Get(url string) (*http.Response, error) {
63+
return defaultClient.Get(url)
64+
}

pkg/transport/client_test.go

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
// Copyright 2020 Tetrate
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
package transport
16+
17+
import (
18+
"fmt"
19+
"net/http"
20+
"net/http/httptest"
21+
"reflect"
22+
"testing"
23+
)
24+
25+
func TestClientWithoutRequest(t *testing.T) {
26+
ua := fmt.Sprintf("GetEnvoy/%s", "1.0")
27+
ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
28+
want := http.Header{
29+
"Accept-Encoding": []string{"gzip"},
30+
"User-Agent": []string{ua},
31+
}
32+
if !reflect.DeepEqual(r.Header, want) {
33+
t.Errorf("Request.Header = %#v; want %#v", r.Header, want)
34+
}
35+
if t.Failed() {
36+
w.Header().Set("Result", "got errors")
37+
} else {
38+
w.Header().Set("Result", "ok")
39+
}
40+
}))
41+
defer ts.Close()
42+
43+
client := NewClient(AddUserAgent(ua))
44+
res, err := client.Get(ts.URL)
45+
if err != nil {
46+
t.Fatal(err)
47+
}
48+
defer res.Body.Close()
49+
if res.StatusCode != 200 {
50+
t.Fatal(res.Status)
51+
}
52+
if got := res.Header.Get("Result"); got != "ok" {
53+
t.Errorf("result = %q; want ok", got)
54+
}
55+
}

pkg/version/version.go

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
// Copyright 2020 Tetrate
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
package version
16+
17+
var (
18+
// version is populated at build time via compiler options.
19+
version string
20+
)
21+
22+
// BuildInfo describes a particular build of getenvoy toolkit.
23+
type BuildInfo struct {
24+
Version string
25+
}
26+
27+
var (
28+
// Build describes a version of the enclosing binary.
29+
Build = BuildInfo{
30+
Version: version,
31+
}
32+
)

0 commit comments

Comments
 (0)