Skip to content

Commit 0d99a2c

Browse files
authoredMar 6, 2023
新增SetHeaderRaw (#362)
1 parent 894382a commit 0d99a2c

9 files changed

+139
-16
lines changed
 

‎.gitignore

+1
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
*.dll
77
*.so
88
*.dylib
9+
/cover.cov
910
.DS_Store
1011
.idea
1112

‎README.md

+51-1
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@ gout 是go写的http 客户端,为提高工作效率而开发
5050
- [GET POST PUT DELETE PATH HEAD OPTIONS template](#get-post-put-delete-path-head-options-template)
5151
- [Query Parameters](#Query-Parameters)
5252
- [http header](#http-header)
53+
- [Do not convert http headers](#do-not-convert-http-headers)
5354
- [Set request header](#set-request-header)
5455
- [Parsing the response header](#parsing-the-response-header)
5556
- [get all header](#get-all-header)
@@ -348,7 +349,6 @@ func main() {
348349

349350
```
350351
### SetQuery支持的更多数据类型
351-
<details>
352352

353353
```go
354354
package main
@@ -412,6 +412,56 @@ SetQuery([]string{"active", "enable", "action", "drop"})`
412412
</details>
413413

414414
## http header
415+
#### Do not convert http headers
416+
与SetHeader API唯一的区别就是不修改header名. 大部分情况用SetHeader,如果有不修改header的需求再使用SetHeaderRaw。
417+
```go
418+
package main
419+
420+
import (
421+
"fmt"
422+
"github.com/guonaihong/gout"
423+
"time"
424+
)
425+
426+
func main() {
427+
err := gout.
428+
//设置GET请求和url,:8080/test.header是127.0.0.1:8080/test.header的简写
429+
GET(":8080/test.header").
430+
//设置debug模式
431+
Debug(true).
432+
//设置请求http header
433+
SetHeaderRaw(gout.H{
434+
"h1": "v1",
435+
"h2": 2,
436+
"h3": float32(3.14),
437+
"h4": 4.56,
438+
"h5": time.Now().Unix(),
439+
"h6": time.Now().UnixNano(),
440+
"h7": time.Now().Format("2006-01-02")}).
441+
Do()
442+
if err != nil {
443+
fmt.Printf("%s\n", err)
444+
return
445+
}
446+
447+
}
448+
449+
/*
450+
> GET /test.header HTTP/1.1
451+
> h2: 2
452+
> h3: 3.14
453+
> h4: 4.56
454+
> h5: 1574081686
455+
> h6: 1574081686471347098
456+
> h7: 2019-11-18
457+
> h1: v1
458+
>
459+
460+
461+
< HTTP/1.1 200 OK
462+
< Content-Length: 0
463+
*/
464+
```
415465
#### Set request header
416466
```go
417467
package main

‎dataflow/dataflow.go

+7
Original file line numberDiff line numberDiff line change
@@ -180,6 +180,13 @@ func (df *DataFlow) SetHeader(obj ...interface{}) *DataFlow {
180180
return df
181181
}
182182

183+
// SetHeader send http header, Support struct/map/slice types
184+
func (df *DataFlow) SetHeaderRaw(obj ...interface{}) *DataFlow {
185+
df.Req.headerEncode = append([]interface{}{}, obj...)
186+
df.Req.rawHeader = true
187+
return df
188+
}
189+
183190
// SetJSON send json to the http body, Support raw json(string, []byte)/struct/map types
184191
func (df *DataFlow) SetJSON(obj interface{}) *DataFlow {
185192
df.ReqBodyType = "json"

‎dataflow/dataflow_header_test.go

+37-3
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,14 @@
11
package dataflow
22

33
import (
4-
"github.com/gin-gonic/gin"
5-
"github.com/guonaihong/gout/core"
6-
"github.com/stretchr/testify/assert"
74
"net/http"
85
"net/http/httptest"
96
"testing"
107
"time"
8+
9+
"github.com/gin-gonic/gin"
10+
"github.com/guonaihong/gout/core"
11+
"github.com/stretchr/testify/assert"
1112
)
1213

1314
type testHeader2 struct {
@@ -177,3 +178,36 @@ func Test_BindHeader_empty(t *testing.T) {
177178
assert.Equal(t, tHeader.Sid, "sid-ok")
178179
}
179180
}
181+
182+
// 测试直接发送raw http header。
183+
func Test_HeaderRaw(t *testing.T) {
184+
router := func() *gin.Engine {
185+
router := gin.New()
186+
187+
router.GET("/test.header", func(c *gin.Context) {
188+
h := map[string][]string(c.Request.Header)
189+
c.Writer.Header().Add("sid", h["Sid"][0])
190+
})
191+
192+
return router
193+
}()
194+
195+
ts := httptest.NewServer(http.HandlerFunc(router.ServeHTTP))
196+
197+
g := New()
198+
199+
type testHeader2 struct {
200+
Sid string `header:"sid"`
201+
Code int
202+
}
203+
204+
var tHeader testHeader2
205+
for _, v := range []interface{}{
206+
core.A{"sid", "hello"},
207+
} {
208+
err := g.GET(ts.URL + "/test.header").Debug(true).SetHeaderRaw(v).BindHeader(&tHeader).Code(&tHeader.Code).Do()
209+
assert.NoError(t, err)
210+
assert.Equal(t, tHeader.Code, 200)
211+
assert.Equal(t, tHeader.Sid, "hello")
212+
}
213+
}

‎dataflow/req.go

+4-1
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,9 @@ type Req struct {
3838

3939
// http header
4040
headerEncode []interface{}
41+
// raw header
42+
rawHeader bool
43+
4144
headerDecode interface{}
4245

4346
// query
@@ -349,7 +352,7 @@ func (r *Req) encodeHeader(req *http.Request) (err error) {
349352
continue
350353
}
351354

352-
err = encode.Encode(h, encode.NewHeaderEncode(req))
355+
err = encode.Encode(h, encode.NewHeaderEncode(req, r.rawHeader))
353356
if err != nil {
354357
return err
355358
}

‎encode/encode_core_test.go

+3-3
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ func testEncodeCore_Encode(t *testing.T) {
3535
assert.NoError(t, err)
3636

3737
for _, v := range testPtr {
38-
err := Encode(v.set, NewHeaderEncode(req))
38+
err := Encode(v.set, NewHeaderEncode(req, false))
3939
assert.NoError(t, err)
4040
}
4141
}
@@ -60,7 +60,7 @@ func testEncodeCore_Encode_Fail(t *testing.T) {
6060
assert.NoError(t, err)
6161

6262
for _, v := range testFail {
63-
err := Encode(v.set, NewHeaderEncode(req))
63+
err := Encode(v.set, NewHeaderEncode(req, false))
6464
assert.Error(t, err)
6565
}
6666

@@ -143,7 +143,7 @@ func TestEncodeCore_parseTagAndSet(t *testing.T) {
143143

144144
for _, v := range test {
145145
val := reflect.ValueOf(v.set)
146-
err := parseTagAndSet(val.Field(0), val.Type().Field(0), NewHeaderEncode(&http.Request{}))
146+
err := parseTagAndSet(val.Field(0), val.Type().Field(0), NewHeaderEncode(&http.Request{}, false))
147147
assert.NoError(t, err)
148148
}
149149
}

‎encode/header.go

+11-4
Original file line numberDiff line numberDiff line change
@@ -9,17 +9,24 @@ var _ Adder = (*HeaderEncode)(nil)
99

1010
// HeaderEncode http header encoder structure
1111
type HeaderEncode struct {
12-
r *http.Request
12+
r *http.Request
13+
rawHeader bool
1314
}
1415

1516
// NewHeaderEncode create a new http header encoder
16-
func NewHeaderEncode(req *http.Request) *HeaderEncode {
17-
return &HeaderEncode{r: req}
17+
func NewHeaderEncode(req *http.Request, rawHeader bool) *HeaderEncode {
18+
return &HeaderEncode{r: req, rawHeader: rawHeader}
1819
}
1920

2021
// Add Encoder core function, used to set each key / value into the http header
2122
func (h *HeaderEncode) Add(key string, v reflect.Value, sf reflect.StructField) error {
22-
h.r.Header.Add(key, valToStr(v, sf))
23+
value := valToStr(v, sf)
24+
if !h.rawHeader {
25+
h.r.Header.Add(key, value)
26+
} else {
27+
28+
h.r.Header[key] = append(h.r.Header[key], value)
29+
}
2330
return nil
2431
}
2532

‎encode/header_test.go

+5-4
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,10 @@ package encode
22

33
import (
44
"fmt"
5-
"github.com/stretchr/testify/assert"
65
"net/http"
76
"testing"
7+
8+
"github.com/stretchr/testify/assert"
89
)
910

1011
type testH map[string]interface{}
@@ -16,7 +17,7 @@ func TestHeaderStringSlice(t *testing.T) {
1617
"header1", "value1",
1718
"header2", "value2",
1819
"header3", "value3",
19-
}, NewHeaderEncode(req))
20+
}, NewHeaderEncode(req, false))
2021

2122
assert.NoError(t, err)
2223

@@ -36,7 +37,7 @@ func TestHeaderMap(t *testing.T) {
3637
"header1": 1,
3738
"header2": "value2",
3839
"header3": 3.14,
39-
}, NewHeaderEncode(req))
40+
}, NewHeaderEncode(req, false))
4041

4142
assert.NoError(t, err)
4243

@@ -83,7 +84,7 @@ func TestHeaderStruct(t *testing.T) {
8384
},
8485
H: &p,
8586
},
86-
NewHeaderEncode(req),
87+
NewHeaderEncode(req, false),
8788
)
8889

8990
assert.NoError(t, err)

‎encode/www_form_test.go

+20
Original file line numberDiff line numberDiff line change
@@ -35,3 +35,23 @@ func Test_WWWForm_Encode(t *testing.T) {
3535
func Test_WWWForm_Name(t *testing.T) {
3636
assert.Equal(t, NewWWWFormEncode(setting.Setting{}).Name(), "www-form")
3737
}
38+
39+
type CreateUserMetadataReqBody struct {
40+
Avatarurl string `www-form:"avatarurl"`
41+
Nickname string `www-form:"nickname"`
42+
}
43+
44+
func Test_WWWForm_Struct(t *testing.T) {
45+
46+
data := CreateUserMetadataReqBody{Avatarurl: "www.hh.com", Nickname: "good"}
47+
enc := NewWWWFormEncode(setting.Setting{})
48+
err := enc.Encode(&data)
49+
assert.NoError(t, err)
50+
51+
var out bytes.Buffer
52+
assert.NoError(t, enc.End(&out))
53+
pos := bytes.Index(out.Bytes(), []byte("avatarurl"))
54+
pos1 := bytes.Index(out.Bytes(), []byte("nickname"))
55+
assert.NotEqual(t, pos, -1)
56+
assert.NotEqual(t, pos1, -1)
57+
}

0 commit comments

Comments
 (0)
Please sign in to comment.