...
1 package httpbinding
2
3 import (
4 "fmt"
5 "net/http"
6 "net/url"
7 "strconv"
8 "strings"
9 )
10
11 const (
12 contentLengthHeader = "Content-Length"
13 floatNaN = "NaN"
14 floatInfinity = "Infinity"
15 floatNegInfinity = "-Infinity"
16 )
17
18
19
20
21
22 type Encoder struct {
23 path, rawPath, pathBuffer []byte
24
25 query url.Values
26 header http.Header
27 }
28
29
30
31
32 func NewEncoder(path, query string, headers http.Header) (*Encoder, error) {
33 return NewEncoderWithRawPath(path, path, query, headers)
34 }
35
36
37
38
39 func NewEncoderWithRawPath(path, rawPath, query string, headers http.Header) (*Encoder, error) {
40 parseQuery, err := url.ParseQuery(query)
41 if err != nil {
42 return nil, fmt.Errorf("failed to parse query string: %w", err)
43 }
44
45 e := &Encoder{
46 path: []byte(path),
47 rawPath: []byte(rawPath),
48 query: parseQuery,
49 header: headers.Clone(),
50 }
51
52 return e, nil
53 }
54
55
56
57
58
59
60
61 func (e *Encoder) Encode(req *http.Request) (*http.Request, error) {
62 req.URL.Path, req.URL.RawPath = string(e.path), string(e.rawPath)
63 req.URL.RawQuery = e.query.Encode()
64
65
66 if v := e.header.Get(contentLengthHeader); len(v) > 0 {
67 iv, err := strconv.ParseInt(v, 10, 64)
68 if err != nil {
69 return nil, err
70 }
71 req.ContentLength = iv
72 e.header.Del(contentLengthHeader)
73 }
74
75 req.Header = e.header
76
77 return req, nil
78 }
79
80
81 func (e *Encoder) AddHeader(key string) HeaderValue {
82 return newHeaderValue(e.header, key, true)
83 }
84
85
86 func (e *Encoder) SetHeader(key string) HeaderValue {
87 return newHeaderValue(e.header, key, false)
88 }
89
90
91 func (e *Encoder) Headers(prefix string) Headers {
92 return Headers{
93 header: e.header,
94 prefix: strings.TrimSpace(prefix),
95 }
96 }
97
98
99
100 func (e Encoder) HasHeader(key string) bool {
101 return len(e.header[key]) != 0
102 }
103
104
105 func (e *Encoder) SetURI(key string) URIValue {
106 return newURIValue(&e.path, &e.rawPath, &e.pathBuffer, key)
107 }
108
109
110 func (e *Encoder) SetQuery(key string) QueryValue {
111 return NewQueryValue(e.query, key, false)
112 }
113
114
115 func (e *Encoder) AddQuery(key string) QueryValue {
116 return NewQueryValue(e.query, key, true)
117 }
118
119
120
121 func (e *Encoder) HasQuery(key string) bool {
122 return len(e.query.Get(key)) != 0
123 }
124
View as plain text