forked from badboyd/lura
/
http_response.go
68 lines (57 loc) · 2.11 KB
/
http_response.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
// SPDX-License-Identifier: Apache-2.0
package proxy
import (
"compress/gzip"
"context"
"io"
"net/http"
"github.com/betprophet1/lura/encoding"
)
// HTTPResponseParser defines how the response is parsed from http.Response to Response object
type HTTPResponseParser func(context.Context, *http.Response) (*Response, error)
// DefaultHTTPResponseParserConfig defines a default HTTPResponseParserConfig
var DefaultHTTPResponseParserConfig = HTTPResponseParserConfig{
func(_ io.Reader, _ *map[string]interface{}) error { return nil },
EntityFormatterFunc(func(r Response) Response { return r }),
}
// HTTPResponseParserConfig contains the config for a given HttpResponseParser
type HTTPResponseParserConfig struct {
Decoder encoding.Decoder
EntityFormatter EntityFormatter
}
// HTTPResponseParserFactory creates HTTPResponseParser from a given HTTPResponseParserConfig
type HTTPResponseParserFactory func(HTTPResponseParserConfig) HTTPResponseParser
// DefaultHTTPResponseParserFactory is the default implementation of HTTPResponseParserFactory
func DefaultHTTPResponseParserFactory(cfg HTTPResponseParserConfig) HTTPResponseParser {
return func(ctx context.Context, resp *http.Response) (*Response, error) {
defer resp.Body.Close()
var reader io.ReadCloser
switch resp.Header.Get("Content-Encoding") {
case "gzip":
reader, _ = gzip.NewReader(resp.Body)
defer reader.Close()
default:
reader = resp.Body
}
var data map[string]interface{}
if err := cfg.Decoder(reader, &data); err != nil {
return nil, err
}
newResponse := Response{Data: data, IsComplete: true}
newResponse = cfg.EntityFormatter.Format(newResponse)
return &newResponse, nil
}
}
// NoOpHTTPResponseParser is a HTTPResponseParser implementation that just copies the
// http response body into the proxy response IO
func NoOpHTTPResponseParser(ctx context.Context, resp *http.Response) (*Response, error) {
return &Response{
Data: map[string]interface{}{},
IsComplete: true,
Io: NewReadCloserWrapper(ctx, resp.Body),
Metadata: Metadata{
StatusCode: resp.StatusCode,
Headers: resp.Header,
},
}, nil
}