瀏覽代碼

add useragent to request header

wenzuochao 6 年之前
父節點
當前提交
03ef569c4f
共有 5 個文件被更改,包括 177 次插入47 次删除
  1. 49 2
      sdk/client.go
  2. 55 1
      sdk/client_test.go
  3. 42 42
      sdk/config_test.go
  4. 28 2
      sdk/requests/acs_request.go
  5. 3 0
      sdk/requests/acs_request_test.go

+ 49 - 2
sdk/client.go

@@ -17,6 +17,7 @@ package sdk
 import (
 	"fmt"
 	"net/http"
+	"runtime"
 	"strconv"
 	"strings"
 	"sync"
@@ -39,6 +40,8 @@ func init() {
 // Version this value will be replaced while build: -ldflags="-X sdk.version=x.x.x"
 var Version = "0.0.1"
 
+var DefaultUserAgent = fmt.Sprintf("AlibabaCloud (%s; %s) GO/%s Core/%s", runtime.GOOS, runtime.GOARCH, strings.Trim(runtime.Version(), "go"), Version)
+
 var hookDo = func(fn func(req *http.Request) (*http.Response, error)) func(req *http.Request) (*http.Response, error) {
 	return fn
 }
@@ -47,6 +50,7 @@ var hookDo = func(fn func(req *http.Request) (*http.Response, error)) func(req *
 type Client struct {
 	regionId       string
 	config         *Config
+	userAgent      map[string]string
 	signer         auth.Signer
 	httpClient     *http.Client
 	asyncTaskQueue chan func()
@@ -202,12 +206,55 @@ func (client *Client) buildRequestWithSigner(request requests.AcsRequest, signer
 		finalSigner = client.signer
 	}
 	httpRequest, err = buildHttpRequest(request, finalSigner, regionId)
-	if client.config.UserAgent != "" {
-		httpRequest.Header.Set("User-Agent", client.config.UserAgent)
+	if err == nil {
+		userAgent := DefaultUserAgent + getSendUserAgent(client.config.UserAgent, client.userAgent, request.GetUserAgent())
+		httpRequest.Header.Set("User-Agent", userAgent)
 	}
+
 	return
 }
 
+func getSendUserAgent(configUserAgent string, clientUserAgent, requestUserAgent map[string]string) string {
+	realUserAgent := ""
+	for key1, value1 := range clientUserAgent {
+		for key2, _ := range requestUserAgent {
+			if key1 == key2 {
+				key1 = ""
+			}
+		}
+		if key1 != "" {
+			realUserAgent += fmt.Sprintf(" %s/%s", key1, value1)
+
+		}
+	}
+	for key, value := range requestUserAgent {
+		realUserAgent += fmt.Sprintf(" %s/%s", key, value)
+	}
+	if configUserAgent != "" {
+		return realUserAgent + fmt.Sprintf(" Extra/%s", configUserAgent)
+	}
+	return realUserAgent
+}
+
+func (client *Client) AppendUserAgent(key, value string) {
+	newkey := true
+
+	if client.userAgent == nil {
+		client.userAgent = make(map[string]string)
+	}
+	if strings.ToLower(key) != "core" && strings.ToLower(key) != "go" {
+		for tag, _ := range client.userAgent {
+			if tag == key {
+				client.userAgent[tag] = value
+				newkey = false
+			}
+		}
+		if newkey {
+			client.userAgent[key] = value
+		}
+	}
+}
+
 func (client *Client) BuildRequestWithSigner(request requests.AcsRequest, signer auth.Signer) (err error) {
 	_, err = client.buildRequestWithSigner(request, signer)
 	return

+ 55 - 1
sdk/client_test.go

@@ -274,7 +274,6 @@ func TestClient_BuildRequestWithSigner1(t *testing.T) {
 	signer := &signertest{
 		name: "signer",
 	}
-	client.config.UserAgent = "user_agent"
 	err = client.BuildRequestWithSigner(request, signer)
 	assert.Nil(t, err)
 }
@@ -299,6 +298,61 @@ func TestClient_ProcessCommonRequestWithSigner(t *testing.T) {
 	assert.NotNil(t, err)
 }
 
+func TestClient_AppendUserAgent(t *testing.T) {
+	client, err := NewClientWithAccessKey("regionid", "acesskeyid", "accesskeysecret")
+	assert.Nil(t, err)
+	assert.NotNil(t, client)
+	assert.Equal(t, true, client.isRunning)
+	request := requests.NewCommonRequest()
+	request.Domain = "ecs.aliyuncs.com"
+	request.Version = "2014-05-26"
+	request.ApiName = "DescribeInstanceStatus"
+
+	request.RegionId = "regionid"
+	signer := &signertest{
+		name: "signer",
+	}
+	request.TransToAcsRequest()
+	httpRequest, err := client.buildRequestWithSigner(request, signer)
+	assert.Nil(t, err)
+	assert.Equal(t, DefaultUserAgent, httpRequest.Header.Get("User-Agent"))
+
+	client.AppendUserAgent("test", "1.01")
+	httpRequest, err = client.buildRequestWithSigner(request, signer)
+	assert.Equal(t, DefaultUserAgent+" test/1.01", httpRequest.Header.Get("User-Agent"))
+
+	request.AppendUserAgent("test", "2.01")
+	httpRequest, err = client.buildRequestWithSigner(request, signer)
+	assert.Equal(t, DefaultUserAgent+" test/2.01", httpRequest.Header.Get("User-Agent"))
+
+	request.AppendUserAgent("test", "2.02")
+	httpRequest, err = client.buildRequestWithSigner(request, signer)
+	assert.Equal(t, DefaultUserAgent+" test/2.02", httpRequest.Header.Get("User-Agent"))
+
+	client.AppendUserAgent("test", "2.01")
+	httpRequest, err = client.buildRequestWithSigner(request, signer)
+	assert.Equal(t, DefaultUserAgent+" test/2.02", httpRequest.Header.Get("User-Agent"))
+
+	client.AppendUserAgent("core", "1.01")
+	httpRequest, err = client.buildRequestWithSigner(request, signer)
+	assert.Equal(t, DefaultUserAgent+" test/2.02", httpRequest.Header.Get("User-Agent"))
+
+	request.AppendUserAgent("core", "1.01")
+	httpRequest, err = client.buildRequestWithSigner(request, signer)
+	assert.Equal(t, DefaultUserAgent+" test/2.02", httpRequest.Header.Get("User-Agent"))
+
+	request1 := requests.NewCommonRequest()
+	request1.Domain = "ecs.aliyuncs.com"
+	request1.Version = "2014-05-26"
+	request1.ApiName = "DescribeRegions"
+	request1.RegionId = "regionid"
+	request1.AppendUserAgent("sys", "1.01")
+	request1.TransToAcsRequest()
+	httpRequest, err = client.buildRequestWithSigner(request1, signer)
+	assert.Nil(t, err)
+	assert.Equal(t, DefaultUserAgent+" test/2.01 sys/1.01", httpRequest.Header.Get("User-Agent"))
+}
+
 func TestClient_ProcessCommonRequestWithSigner_Error(t *testing.T) {
 	client, err := NewClientWithAccessKey("regionid", "acesskeyid", "accesskeysecret")
 	assert.Nil(t, err)

+ 42 - 42
sdk/config_test.go

@@ -1,52 +1,52 @@
 package sdk
 
 import (
-  "net/http"
-  "testing"
-  "time"
+	"net/http"
+	"testing"
+	"time"
 
-  "github.com/stretchr/testify/assert"
+	"github.com/stretchr/testify/assert"
 )
 
 func Test_Config(t *testing.T) {
-  config := NewConfig()
-  assert.NotNil(t, config, "NewConfig failed")
-  assert.Equal(t, true, config.AutoRetry, "Default AutoRetry should be true")
-  assert.Equal(t, 3, config.MaxRetryTime, "Default MaxRetryTime should be 3")
-  assert.Equal(t, "", config.UserAgent, "Default UserAgent should be empty")
-  assert.Equal(t, false, config.Debug, "Default AutoRetry should be false")
-  assert.Equal(t, time.Duration(10000000000), config.Timeout, "Default Timeout should be 10000000000")
-  assert.Equal(t, (*http.Transport)(nil), config.HttpTransport, "Default HttpTransport should be nil")
-  assert.Equal(t, false, config.EnableAsync, "Default EnableAsync should be false")
-  assert.Equal(t, 1000, config.MaxTaskQueueSize, "Default MaxTaskQueueSize should be 1000")
-  assert.Equal(t, 5, config.GoRoutinePoolSize, "Default GoRoutinePoolSize should be 5")
-  assert.Equal(t, "HTTP", config.Scheme, "Default Scheme should be HTTP")
+	config := NewConfig()
+	assert.NotNil(t, config, "NewConfig failed")
+	assert.Equal(t, true, config.AutoRetry, "Default AutoRetry should be true")
+	assert.Equal(t, 3, config.MaxRetryTime, "Default MaxRetryTime should be 3")
+	assert.Equal(t, "", config.UserAgent, "Default UserAgent should be empty")
+	assert.Equal(t, false, config.Debug, "Default AutoRetry should be false")
+	assert.Equal(t, time.Duration(10000000000), config.Timeout, "Default Timeout should be 10000000000")
+	assert.Equal(t, (*http.Transport)(nil), config.HttpTransport, "Default HttpTransport should be nil")
+	assert.Equal(t, false, config.EnableAsync, "Default EnableAsync should be false")
+	assert.Equal(t, 1000, config.MaxTaskQueueSize, "Default MaxTaskQueueSize should be 1000")
+	assert.Equal(t, 5, config.GoRoutinePoolSize, "Default GoRoutinePoolSize should be 5")
+	assert.Equal(t, "HTTP", config.Scheme, "Default Scheme should be HTTP")
 
-  transport := &http.Transport{
-    MaxIdleConns:       10,
-    IdleConnTimeout:    30 * time.Second,
-    DisableCompression: true,
-  }
-  config.
-    WithAutoRetry(false).
-    WithMaxRetryTime(0).
-    WithUserAgent("new user agent").
-    WithDebug(true).
-    WithTimeout(time.Duration(500000)).
-    WithHttpTransport(transport).
-    WithEnableAsync(true).
-    WithMaxTaskQueueSize(1).
-    WithGoRoutinePoolSize(10).
-    WithScheme("HTTPS")
+	transport := &http.Transport{
+		MaxIdleConns:       10,
+		IdleConnTimeout:    30 * time.Second,
+		DisableCompression: true,
+	}
+	config.
+		WithAutoRetry(false).
+		WithMaxRetryTime(0).
+		WithUserAgent("new user agent").
+		WithDebug(true).
+		WithTimeout(time.Duration(500000)).
+		WithHttpTransport(transport).
+		WithEnableAsync(true).
+		WithMaxTaskQueueSize(1).
+		WithGoRoutinePoolSize(10).
+		WithScheme("HTTPS")
 
-  assert.Equal(t, 0, config.MaxRetryTime)
-  assert.Equal(t, false, config.AutoRetry)
-  assert.Equal(t, "new user agent", config.UserAgent)
-  assert.Equal(t, true, config.Debug)
-  assert.Equal(t, time.Duration(500000), config.Timeout)
-  assert.Equal(t, transport, config.HttpTransport)
-  assert.Equal(t, true, config.EnableAsync)
-  assert.Equal(t, 1, config.MaxTaskQueueSize)
-  assert.Equal(t, 10, config.GoRoutinePoolSize)
-  assert.Equal(t, "HTTPS", config.Scheme)
+	assert.Equal(t, 0, config.MaxRetryTime)
+	assert.Equal(t, false, config.AutoRetry)
+	assert.Equal(t, "new user agent", config.UserAgent)
+	assert.Equal(t, true, config.Debug)
+	assert.Equal(t, time.Duration(500000), config.Timeout)
+	assert.Equal(t, transport, config.HttpTransport)
+	assert.Equal(t, true, config.EnableAsync)
+	assert.Equal(t, 1, config.MaxTaskQueueSize)
+	assert.Equal(t, 10, config.GoRoutinePoolSize)
+	assert.Equal(t, "HTTPS", config.Scheme)
 }

+ 28 - 2
sdk/requests/acs_request.go

@@ -19,6 +19,7 @@ import (
 	"io"
 	"reflect"
 	"strconv"
+	"strings"
 
 	"github.com/aliyun/alibaba-cloud-sdk-go/sdk/errors"
 )
@@ -72,6 +73,8 @@ type AcsRequest interface {
 	GetLocationServiceCode() string
 	GetLocationEndpointType() string
 
+	GetUserAgent() map[string]string
+
 	SetStringToSign(stringToSign string)
 	GetStringToSign() string
 
@@ -95,8 +98,9 @@ type baseRequest struct {
 	Port     string
 	RegionId string
 
-	product string
-	version string
+	userAgent map[string]string
+	product   string
+	version   string
 
 	actionName string
 
@@ -139,6 +143,28 @@ func (request *baseRequest) SetContent(content []byte) {
 	request.Content = content
 }
 
+func (request *baseRequest) GetUserAgent() map[string]string {
+	return request.userAgent
+}
+
+func (request *baseRequest) AppendUserAgent(key, value string) {
+	newkey := true
+	if request.userAgent == nil {
+		request.userAgent = make(map[string]string)
+	}
+	if strings.ToLower(key) != "core" && strings.ToLower(key) != "go" {
+		for tag, _ := range request.userAgent {
+			if tag == key {
+				request.userAgent[tag] = value
+				newkey = false
+			}
+		}
+		if newkey {
+			request.userAgent[key] = value
+		}
+	}
+}
+
 func (request *baseRequest) addHeaderParam(key, value string) {
 	request.Headers[key] = value
 }

+ 3 - 0
sdk/requests/acs_request_test.go

@@ -88,6 +88,9 @@ func Test_AcsRequest(t *testing.T) {
 	// GetPort
 	assert.Equal(t, "", r.GetPort())
 
+	// GetUserAgent
+	r.AppendUserAgent("cli", "1.01")
+	assert.Equal(t, "1.01", r.GetUserAgent()["cli"])
 	// Content
 	assert.Equal(t, []byte(nil), r.GetContent())
 	r.SetContent([]byte("The Content"))