diff --git a/README.md b/README.md index aefc2a3..f0c8218 100644 --- a/README.md +++ b/README.md @@ -28,6 +28,7 @@ gout 是go写的http 客户端,为提高工作效率而开发 * 支持导出curl命令 * 传入自定义*http.Client * 支持请求中间件(https://github.com/antlabs/gout-middleware) +* 支持设置chunked数据格式发送 * 等等更多 ## 演示 @@ -85,6 +86,7 @@ gout 是go写的http 客户端,为提高工作效率而开发 - [export](#export) - [generate curl command](#generate-curl-command) - [Incoming custom * http.Client](#Incoming-custom-*http.Client) + - [Using chunked data format](#Using-chunked-data-format) - [Global configuration](#Global-configuration) - [Null values are also serialized](#Null-values-are-also-serialized) - [Global set timeout](#global-set-timeout) @@ -1587,6 +1589,30 @@ func main() { } ``` +# Using chunked data format +使用Chunked接口, 设置为"Transfer-Encoding: chunked"的数据编码方式 +``` go +package main + +import ( + "time" + + "github.com/guonaihong/gout" +) + +func main() { + err := gout.POST(":8080"). + Chunked(). + SetBody("11111111111"). + Do() + if err != nil { + fmt.Printf("err :%v\n", err) + } +} +// 使用nc 起一个tcp服务, 使用上面的代码发起数据观察下结果 +// nc -l 8080 +``` + # Global configuration ## Null values are also serialized ```go diff --git a/dataflow/dataflow.go b/dataflow/dataflow.go index 6104533..14781a2 100644 --- a/dataflow/dataflow.go +++ b/dataflow/dataflow.go @@ -336,6 +336,12 @@ func (df *DataFlow) Callback(cb func(*Context) error) *DataFlow { return df } +// Chunked +func (df *DataFlow) Chunked() *DataFlow { + df.Req.Chunked() + return df +} + // SetTimeout set timeout, and WithContext are mutually exclusive functions func (df *DataFlow) SetTimeout(d time.Duration) *DataFlow { df.Req.SetTimeout(d) diff --git a/dataflow/req.go b/dataflow/req.go index 0fff141..fc270b9 100644 --- a/dataflow/req.go +++ b/dataflow/req.go @@ -449,6 +449,13 @@ func (r *Req) canTrace() bool { return opt.Trace } +// 使用chunked方式 +func (r *Req) maybeUseChunked(req *http.Request) { + if r.UseChunked { + req.ContentLength = -1 + } +} + // Do Send function func (r *Req) Do() (err error) { if r.Err != nil { @@ -465,6 +472,9 @@ func (r *Req) Do() (err error) { opt := r.getDebugOpt() + // 如果调用Chunked()接口, 就使用chunked的数据包 + r.maybeUseChunked(req) + //resp, err := r.Client().Do(req) //TODO r.Client() 返回Do接口 resp, err := opt.startTrace(opt, r.canTrace(), req, r.Client()) diff --git a/gout_chunked_test.go b/gout_chunked_test.go new file mode 100644 index 0000000..5fd196d --- /dev/null +++ b/gout_chunked_test.go @@ -0,0 +1,53 @@ +package gout + +import ( + "bytes" + "io" + "net" + "testing" + "time" + + "github.com/guonaihong/gout/core" + "github.com/stretchr/testify/assert" +) + +func testTcpSocket(out *bytes.Buffer, quit chan bool, t *testing.T) (addr string) { + addr = core.GetNoPortExists() + + addr = ":" + addr + go func() { + defer close(quit) + listener, err := net.Listen("tcp", addr) + if err != nil { + t.Errorf("%v\n", err) + return + } + defer listener.Close() + + conn, err := listener.Accept() + if err != nil { + t.Errorf("%v\n", err) + return + } + + io.Copy(out, conn) + conn.Close() + }() + + return addr + +} + +func Test_Use_Chunked(t *testing.T) { + var out bytes.Buffer + quit := make(chan bool) + + addr := testTcpSocket(&out, quit, t) + time.Sleep(time.Second / 100) //等待服务起好 + + POST(addr).SetTimeout(time.Second / 100).Chunked().SetBody("11111111111").Do() + <-quit + //time.Sleep(time.Second) + + assert.NotEqual(t, bytes.Index(out.Bytes(), []byte("Transfer-Encoding: chunked")), -1) +} diff --git a/setting/setting.go b/setting/setting.go index 5ba1e2d..8aada2b 100644 --- a/setting/setting.go +++ b/setting/setting.go @@ -20,6 +20,13 @@ type Setting struct { //当前time 的index TimeoutIndex int + + UseChunked bool +} + +// 使用chunked数据 +func (s *Setting) Chunked() { + s.UseChunked = true } func (s *Setting) SetTimeout(d time.Duration) {