github.com/aliyun/credentials-go@v1.4.7/credentials/internal/http/http_test.go (about)

     1  package http
     2  
     3  import (
     4  	"encoding/json"
     5  	"errors"
     6  	"io"
     7  	"io/ioutil"
     8  	"net/http"
     9  	"testing"
    10  	"time"
    11  
    12  	"github.com/stretchr/testify/assert"
    13  )
    14  
    15  func TestRequest(t *testing.T) {
    16  	req := &Request{
    17  		Method:   "GET",
    18  		Protocol: "http",
    19  		Host:     "www.aliyun.com",
    20  		Path:     "/",
    21  	}
    22  	assert.Equal(t, "GET http://www.aliyun.com/", req.BuildRequestURL())
    23  
    24  	req = &Request{
    25  		Method: "GET",
    26  		URL:    "http://www.aliyun.com",
    27  		Path:   "/",
    28  	}
    29  	assert.Equal(t, "GET http://www.aliyun.com", req.BuildRequestURL())
    30  
    31  	// With query
    32  	req = &Request{
    33  		Method:   "GET",
    34  		Protocol: "http",
    35  		Host:     "www.aliyun.com",
    36  		Path:     "/",
    37  		Queries: map[string]string{
    38  			"spm": "test",
    39  		},
    40  	}
    41  	assert.Equal(t, "GET http://www.aliyun.com/?spm=test", req.BuildRequestURL())
    42  }
    43  
    44  func TestDoGet(t *testing.T) {
    45  	req := &Request{
    46  		Method:   "GET",
    47  		Protocol: "http",
    48  		Host:     "www.aliyun.com",
    49  		Path:     "/",
    50  	}
    51  	res, err := Do(req)
    52  	assert.Nil(t, err)
    53  	assert.NotNil(t, res)
    54  	assert.Equal(t, 200, res.StatusCode)
    55  	assert.Equal(t, "text/html; charset=utf-8", res.Headers["Content-Type"])
    56  
    57  	req = &Request{
    58  		Method: "GET",
    59  		URL:    "http://www.aliyun.com",
    60  	}
    61  	res, err = Do(req)
    62  	assert.Nil(t, err)
    63  	assert.NotNil(t, res)
    64  	assert.Equal(t, 200, res.StatusCode)
    65  	assert.Equal(t, "text/html; charset=utf-8", res.Headers["Content-Type"])
    66  }
    67  
    68  func TestDoPost(t *testing.T) {
    69  	req := &Request{
    70  		Method:   "POST",
    71  		Protocol: "http",
    72  		Host:     "www.aliyun.com",
    73  		Path:     "/",
    74  		Form: map[string]string{
    75  			"URL": "HI",
    76  		},
    77  		Headers: map[string]string{
    78  			"Accept-Language": "zh",
    79  		},
    80  	}
    81  	res, err := Do(req)
    82  	assert.Nil(t, err)
    83  	assert.NotNil(t, res)
    84  	assert.Equal(t, 200, res.StatusCode)
    85  	assert.Equal(t, "text/html; charset=utf-8", res.Headers["Content-Type"])
    86  	req.Body, err = json.Marshal(map[string]string{
    87  		"URL": "HI",
    88  	})
    89  	assert.Nil(t, err)
    90  	res, err = Do(req)
    91  	assert.Nil(t, err)
    92  	assert.NotNil(t, res)
    93  	assert.Equal(t, 200, res.StatusCode)
    94  	assert.Equal(t, "text/html; charset=utf-8", res.Headers["Content-Type"])
    95  }
    96  
    97  type errorReader struct {
    98  }
    99  
   100  func (r *errorReader) Read(p []byte) (n int, err error) {
   101  	err = errors.New("read failed")
   102  	return
   103  }
   104  
   105  func TestDoWithError(t *testing.T) {
   106  	originNewRequest := newRequest
   107  	defer func() { newRequest = originNewRequest }()
   108  
   109  	// case 1: mock new http request failed
   110  	newRequest = func(method, url string, body io.Reader) (*http.Request, error) {
   111  		return nil, errors.New("new http request failed")
   112  	}
   113  
   114  	req := &Request{
   115  		Method:   "POST",
   116  		Protocol: "http",
   117  		Host:     "www.aliyun.com",
   118  		Path:     "/",
   119  		Form: map[string]string{
   120  			"URL": "HI",
   121  		},
   122  		Headers: map[string]string{
   123  			"Accept-Language": "zh",
   124  		},
   125  	}
   126  	_, err := Do(req)
   127  	assert.EqualError(t, err, "new http request failed")
   128  
   129  	// reset new request
   130  	newRequest = originNewRequest
   131  
   132  	// case 2: server error
   133  	originDo := hookDo
   134  	defer func() { hookDo = originDo }()
   135  	hookDo = func(fn do) do {
   136  		return func(req *http.Request) (res *http.Response, err error) {
   137  			err = errors.New("mock server error")
   138  			return
   139  		}
   140  	}
   141  	_, err = Do(req)
   142  	assert.EqualError(t, err, "mock server error")
   143  
   144  	// case 4: mock read response error
   145  	hookDo = func(fn do) do {
   146  		return func(req *http.Request) (res *http.Response, err error) {
   147  			res = &http.Response{
   148  				Proto:      "HTTP/1.1",
   149  				ProtoMajor: 1,
   150  				ProtoMinor: 1,
   151  				Header:     map[string][]string{},
   152  				StatusCode: 200,
   153  				Status:     "200 " + http.StatusText(200),
   154  			}
   155  			res.Body = ioutil.NopCloser(&errorReader{})
   156  			return
   157  		}
   158  	}
   159  
   160  	_, err = Do(req)
   161  	assert.EqualError(t, err, "read failed")
   162  }
   163  
   164  func TestDoWithProxy(t *testing.T) {
   165  	req := &Request{
   166  		Method:   "POST",
   167  		Protocol: "http",
   168  		Host:     "www.aliyun.com",
   169  		Path:     "/",
   170  		Form: map[string]string{
   171  			"URL": "HI",
   172  		},
   173  		Headers: map[string]string{
   174  			"Accept-Language": "zh",
   175  		},
   176  		Proxy: "http://localhost:9999/",
   177  	}
   178  	_, err := Do(req)
   179  	assert.Contains(t, err.Error(), "proxyconnect tcp: dial tcp")
   180  	assert.Contains(t, err.Error(), "connect: connection refused")
   181  
   182  	// invalid proxy url
   183  	req.Proxy = string([]byte{0x7f})
   184  	_, err = Do(req)
   185  	assert.Contains(t, err.Error(), "net/url: invalid control character in URL")
   186  }
   187  
   188  func TestDoWithConnectTimeout(t *testing.T) {
   189  	req := &Request{
   190  		Method:   "POST",
   191  		Protocol: "http",
   192  		Host:     "www.aliyun.com",
   193  		Path:     "/",
   194  		Form: map[string]string{
   195  			"URL": "HI",
   196  		},
   197  		Headers: map[string]string{
   198  			"Accept-Language": "zh",
   199  		},
   200  		ConnectTimeout: 1 * time.Nanosecond,
   201  	}
   202  	_, err := Do(req)
   203  	assert.Contains(t, err.Error(), "dial tcp: ")
   204  	assert.Contains(t, err.Error(), "i/o timeout")
   205  }
   206  
   207  func TestDoWithReadTimeout(t *testing.T) {
   208  	req := &Request{
   209  		Method:      "POST",
   210  		Protocol:    "http",
   211  		Host:        "www.aliyun.com",
   212  		Path:        "/",
   213  		ReadTimeout: 1 * time.Nanosecond,
   214  	}
   215  	_, err := Do(req)
   216  	assert.Contains(t, err.Error(), "(Client.Timeout exceeded while awaiting headers)")
   217  }