1 package http_test
2
3 import (
4 "bytes"
5 "context"
6 "fmt"
7 "io"
8 "io/ioutil"
9 "net/http"
10 "net/url"
11 "testing"
12
13 "github.com/aws/smithy-go/logging"
14 "github.com/aws/smithy-go/middleware"
15 smithyhttp "github.com/aws/smithy-go/transport/http"
16 )
17
18 type mockLogger struct {
19 bytes.Buffer
20 }
21
22 func (m *mockLogger) Logf(_ logging.Classification, format string, v ...interface{}) {
23 m.Buffer.WriteString(fmt.Sprintf(format, v...))
24 m.Buffer.WriteRune('\n')
25 }
26
27 func TestRequestResponseLogger(t *testing.T) {
28 cases := map[string]struct {
29 Middleware smithyhttp.RequestResponseLogger
30 Input *smithyhttp.Request
31 InputBody io.ReadCloser
32 Output *smithyhttp.Response
33 ExpectedLog string
34 }{
35 "no logging": {},
36 "request": {
37 Middleware: smithyhttp.RequestResponseLogger{
38 LogRequest: true,
39 },
40 Input: &smithyhttp.Request{
41 Request: &http.Request{
42 URL: &url.URL{
43 Scheme: "https",
44 Path: "/foo",
45 Host: "example.amazonaws.com",
46 },
47 Header: map[string][]string{
48 "Foo": {"bar"},
49 },
50 },
51 },
52 InputBody: ioutil.NopCloser(bytes.NewReader([]byte(`this is the body`))),
53 ExpectedLog: "Request\n" +
54 "GET /foo HTTP/1.1\r\n" +
55 "Host: example.amazonaws.com\r\n" +
56 "User-Agent: Go-http-client/1.1\r\n" +
57 "Foo: bar\r\n" +
58 "Accept-Encoding: gzip\r\n" +
59 "\r\n\n",
60 },
61 "request with body": {
62 Middleware: smithyhttp.RequestResponseLogger{
63 LogRequestWithBody: true,
64 },
65 Input: &smithyhttp.Request{
66 Request: &http.Request{
67 URL: &url.URL{
68 Scheme: "https",
69 Path: "/foo",
70 Host: "example.amazonaws.com",
71 },
72 Header: map[string][]string{
73 "Foo": {"bar"},
74 },
75 ContentLength: 16,
76 },
77 },
78 InputBody: ioutil.NopCloser(bytes.NewReader([]byte(`this is the body`))),
79 ExpectedLog: "Request\n" +
80 "GET /foo HTTP/1.1\r\n" +
81 "Host: example.amazonaws.com\r\n" +
82 "User-Agent: Go-http-client/1.1\r\n" +
83 "Content-Length: 16\r\n" +
84 "Foo: bar\r\n" +
85 "Accept-Encoding: gzip\r\n" +
86 "\r\n" +
87 "this is the body\n",
88 },
89 "response": {
90 Middleware: smithyhttp.RequestResponseLogger{
91 LogResponse: true,
92 },
93 Output: &smithyhttp.Response{
94 Response: &http.Response{
95 StatusCode: 200,
96 Proto: "HTTP/1.1",
97 ContentLength: 16,
98 Header: map[string][]string{
99 "Foo": {"Bar"},
100 },
101 Body: ioutil.NopCloser(bytes.NewReader([]byte(`this is the body`))),
102 },
103 },
104 ExpectedLog: "Response\n" +
105 "HTTP/0.0 200 OK\r\n" +
106 "Content-Length: 16\r\n" +
107 "Foo: Bar\r\n" +
108 "\r\n\n",
109 },
110 "response with body": {
111 Middleware: smithyhttp.RequestResponseLogger{
112 LogResponseWithBody: true,
113 },
114 Output: &smithyhttp.Response{
115 Response: &http.Response{
116 StatusCode: 200,
117 Proto: "HTTP/1.1",
118 ContentLength: 16,
119 Header: map[string][]string{
120 "Foo": {"Bar"},
121 },
122 Body: ioutil.NopCloser(bytes.NewReader([]byte(`this is the body`))),
123 },
124 },
125 ExpectedLog: "Response\n" +
126 "HTTP/0.0 200 OK\r\n" +
127 "Content-Length: 16\r\n" +
128 "Foo: Bar\r\n" +
129 "\r\n" +
130 "this is the body\n",
131 },
132 }
133
134 for name, tt := range cases {
135 t.Run(name, func(t *testing.T) {
136 logger := mockLogger{}
137 ctx := middleware.SetLogger(context.Background(), &logger)
138
139 var err error
140 if tt.InputBody != nil {
141 tt.Input, err = tt.Input.SetStream(tt.InputBody)
142 if err != nil {
143 t.Errorf("expect no error, got %v", err)
144 }
145 }
146
147 _, _, err = tt.Middleware.HandleDeserialize(ctx, middleware.DeserializeInput{Request: tt.Input}, middleware.DeserializeHandlerFunc(func(ctx context.Context, input middleware.DeserializeInput) (
148 middleware.DeserializeOutput, middleware.Metadata, error,
149 ) {
150 return middleware.DeserializeOutput{RawResponse: tt.Output}, middleware.Metadata{}, nil
151 }))
152 if err != nil {
153 t.Fatal("expect error, got nil")
154 }
155
156 actual := string(logger.Bytes())
157 if tt.ExpectedLog != actual {
158 t.Errorf("%v != %v", tt.ExpectedLog, actual)
159 }
160 })
161 }
162 }
163
View as plain text