diff --git a/frame/g/g_object.go b/frame/g/g_object.go index 99ae4019d..86fd97004 100644 --- a/frame/g/g_object.go +++ b/frame/g/g_object.go @@ -11,6 +11,7 @@ import ( "github.com/gogf/gf/v2/database/gredis" "github.com/gogf/gf/v2/frame/gins" "github.com/gogf/gf/v2/i18n/gi18n" + "github.com/gogf/gf/v2/net/gclient" "github.com/gogf/gf/v2/net/ghttp" "github.com/gogf/gf/v2/net/gtcp" "github.com/gogf/gf/v2/net/gudp" @@ -22,8 +23,8 @@ import ( ) // Client is a convenience function, which creates and returns a new HTTP client. -func Client() *ghttp.Client { - return ghttp.NewClient() +func Client() *gclient.Client { + return gclient.New() } // Server returns an instance of http server with specified name. diff --git a/frame/gins/gins_httpclient.go b/frame/gins/gins_httpclient.go index 8bf8f579c..26f784c5b 100644 --- a/frame/gins/gins_httpclient.go +++ b/frame/gins/gins_httpclient.go @@ -9,7 +9,7 @@ package gins import ( "fmt" - "github.com/gogf/gf/v2/net/ghttp" + "github.com/gogf/gf/v2/net/gclient" ) const ( @@ -17,11 +17,11 @@ const ( ) // HttpClient returns an instance of http client with specified name. -func HttpClient(name ...interface{}) *ghttp.Client { +func HttpClient(name ...interface{}) *gclient.Client { var ( instanceKey = fmt.Sprintf("%s.%v", frameCoreComponentNameHttpClient, name) ) return localInstances.GetOrSetFuncLock(instanceKey, func() interface{} { - return ghttp.NewClient() - }).(*ghttp.Client) + return gclient.New() + }).(*gclient.Client) } diff --git a/net/ghttp/internal/httputil/httputils.go b/internal/httputil/httputils.go similarity index 100% rename from net/ghttp/internal/httputil/httputils.go rename to internal/httputil/httputils.go diff --git a/net/ghttp/internal/client/client.go b/net/gclient/gclient.go similarity index 98% rename from net/ghttp/internal/client/client.go rename to net/gclient/gclient.go index d6c4ac54c..49a623253 100644 --- a/net/ghttp/internal/client/client.go +++ b/net/gclient/gclient.go @@ -4,7 +4,8 @@ // If a copy of the MIT was not distributed with this file, // You can obtain one at https://github.com/gogf/gf. -package client +// Package gclient provides convenient http client functionalities. +package gclient import ( "context" diff --git a/net/ghttp/internal/client/client_bytes.go b/net/gclient/gclient_bytes.go similarity index 99% rename from net/ghttp/internal/client/client_bytes.go rename to net/gclient/gclient_bytes.go index 5cfb5bd17..aa3f1fee6 100644 --- a/net/ghttp/internal/client/client_bytes.go +++ b/net/gclient/gclient_bytes.go @@ -4,7 +4,7 @@ // If a copy of the MIT was not distributed with this file, // You can obtain one at https://github.com/gogf/gf. -package client +package gclient import ( "context" diff --git a/net/ghttp/internal/client/client_chain.go b/net/gclient/gclient_chain.go similarity index 99% rename from net/ghttp/internal/client/client_chain.go rename to net/gclient/gclient_chain.go index 9a9474293..12cd40dee 100644 --- a/net/ghttp/internal/client/client_chain.go +++ b/net/gclient/gclient_chain.go @@ -4,7 +4,7 @@ // If a copy of the MIT was not distributed with this file, // You can obtain one at https://github.com/gogf/gf. -package client +package gclient import ( "time" diff --git a/net/ghttp/internal/client/client_content.go b/net/gclient/gclient_content.go similarity index 99% rename from net/ghttp/internal/client/client_content.go rename to net/gclient/gclient_content.go index 65d1f7120..ab7951bce 100644 --- a/net/ghttp/internal/client/client_content.go +++ b/net/gclient/gclient_content.go @@ -4,7 +4,7 @@ // If a copy of the MIT was not distributed with this file, // You can obtain one at https://github.com/gogf/gf. -package client +package gclient import "context" diff --git a/net/ghttp/internal/client/client_dump.go b/net/gclient/gclient_dump.go similarity index 99% rename from net/ghttp/internal/client/client_dump.go rename to net/gclient/gclient_dump.go index 110f3db1d..3c63e9aa7 100644 --- a/net/ghttp/internal/client/client_dump.go +++ b/net/gclient/gclient_dump.go @@ -4,7 +4,7 @@ // If a copy of the MIT was not distributed with this file, // You can obtain one at https://github.com/gogf/gf. -package client +package gclient import ( "fmt" diff --git a/net/ghttp/internal/client/client_middleware.go b/net/gclient/gclient_middleware.go similarity index 98% rename from net/ghttp/internal/client/client_middleware.go rename to net/gclient/gclient_middleware.go index cfbf8964e..95cdebfba 100644 --- a/net/ghttp/internal/client/client_middleware.go +++ b/net/gclient/gclient_middleware.go @@ -1,4 +1,4 @@ -package client +package gclient import ( "net/http" diff --git a/net/ghttp/internal/client/client_request.go b/net/gclient/gclient_request.go similarity index 99% rename from net/ghttp/internal/client/client_request.go rename to net/gclient/gclient_request.go index dac6ab42c..0c3701c29 100644 --- a/net/ghttp/internal/client/client_request.go +++ b/net/gclient/gclient_request.go @@ -4,7 +4,7 @@ // If a copy of the MIT was not distributed with this file, // You can obtain one at https://github.com/gogf/gf. -package client +package gclient import ( "bytes" @@ -20,10 +20,10 @@ import ( "github.com/gogf/gf/v2/encoding/gjson" "github.com/gogf/gf/v2/errors/gcode" "github.com/gogf/gf/v2/errors/gerror" + "github.com/gogf/gf/v2/internal/httputil" "github.com/gogf/gf/v2/internal/intlog" "github.com/gogf/gf/v2/internal/json" "github.com/gogf/gf/v2/internal/utils" - "github.com/gogf/gf/v2/net/ghttp/internal/httputil" "github.com/gogf/gf/v2/os/gfile" "github.com/gogf/gf/v2/text/gregex" "github.com/gogf/gf/v2/text/gstr" diff --git a/net/ghttp/internal/client/client_response.go b/net/gclient/gclient_response.go similarity index 99% rename from net/ghttp/internal/client/client_response.go rename to net/gclient/gclient_response.go index 3acc7c795..6f3226889 100644 --- a/net/ghttp/internal/client/client_response.go +++ b/net/gclient/gclient_response.go @@ -4,7 +4,7 @@ // If a copy of the MIT was not distributed with this file, // You can obtain one at https://github.com/gogf/gf. -package client +package gclient import ( "io/ioutil" diff --git a/net/ghttp/internal/client/client_tracing.go b/net/gclient/gclient_tracing.go similarity index 94% rename from net/ghttp/internal/client/client_tracing.go rename to net/gclient/gclient_tracing.go index 078ad4cb1..8dc3e4256 100644 --- a/net/ghttp/internal/client/client_tracing.go +++ b/net/gclient/gclient_tracing.go @@ -4,7 +4,7 @@ // If a copy of the MIT was not distributed with this file, // You can obtain one at https://github.com/gogf/gf. -package client +package gclient import ( "fmt" @@ -19,15 +19,15 @@ import ( "go.opentelemetry.io/otel/trace" "github.com/gogf/gf/v2" + "github.com/gogf/gf/v2/internal/httputil" "github.com/gogf/gf/v2/internal/utils" - "github.com/gogf/gf/v2/net/ghttp/internal/httputil" "github.com/gogf/gf/v2/net/gtrace" "github.com/gogf/gf/v2/text/gstr" "github.com/gogf/gf/v2/util/gconv" ) const ( - tracingInstrumentName = "github.com/gogf/gf/v2/net/ghttp.Client" + tracingInstrumentName = "github.com/gogf/gf/v2/net/gclient.Client" tracingAttrHttpAddressRemote = "http.address.remote" tracingAttrHttpAddressLocal = "http.address.local" tracingAttrHttpDnsStart = "http.dns.start" diff --git a/net/ghttp/internal/client/client_tracing_tracer.go b/net/gclient/gclient_tracing_tracer.go similarity index 99% rename from net/ghttp/internal/client/client_tracing_tracer.go rename to net/gclient/gclient_tracing_tracer.go index 784597c34..9044d18fe 100644 --- a/net/ghttp/internal/client/client_tracing_tracer.go +++ b/net/gclient/gclient_tracing_tracer.go @@ -4,7 +4,7 @@ // If a copy of the MIT was not distributed with this file, // You can obtain one at https://github.com/gogf/gf. -package client +package gclient import ( "context" diff --git a/net/ghttp/internal/client/client_var.go b/net/gclient/gclient_var.go similarity index 99% rename from net/ghttp/internal/client/client_var.go rename to net/gclient/gclient_var.go index 2a9a1cac2..938de94d8 100644 --- a/net/ghttp/internal/client/client_var.go +++ b/net/gclient/gclient_var.go @@ -4,7 +4,7 @@ // If a copy of the MIT was not distributed with this file, // You can obtain one at https://github.com/gogf/gf. -package client +package gclient import ( "context" diff --git a/net/ghttp/ghttp_client_websocket.go b/net/gclient/gclient_websocket.go similarity index 82% rename from net/ghttp/ghttp_client_websocket.go rename to net/gclient/gclient_websocket.go index cf99c29e1..3bdb38f02 100644 --- a/net/ghttp/ghttp_client_websocket.go +++ b/net/gclient/gclient_websocket.go @@ -4,7 +4,7 @@ // If a copy of the MIT was not distributed with this file, // You can obtain one at https://github.com/gogf/gf. -package ghttp +package gclient import ( "net/http" @@ -19,8 +19,8 @@ type WebSocketClient struct { *websocket.Dialer } -// NewWebSocketClient New creates and returns a new WebSocketClient object. -func NewWebSocketClient() *WebSocketClient { +// NewWebSocket creates and returns a new WebSocketClient object. +func NewWebSocket() *WebSocketClient { return &WebSocketClient{ &websocket.Dialer{ Proxy: http.ProxyFromEnvironment, diff --git a/net/gclient/gclient_z_example_test.go b/net/gclient/gclient_z_example_test.go new file mode 100644 index 000000000..70e7c46f5 --- /dev/null +++ b/net/gclient/gclient_z_example_test.go @@ -0,0 +1,401 @@ +// Copyright GoFrame Author(https://goframe.org). All Rights Reserved. +// +// This Source Code Form is subject to the terms of the MIT License. +// If a copy of the MIT was not distributed with this file, +// You can obtain one at https://github.com/gogf/gf. + +package gclient_test + +import ( + "context" + "fmt" + "time" + + "github.com/gogf/gf/v2/frame/g" + "github.com/gogf/gf/v2/net/ghttp" +) + +func init() { + // Default server for client. + p := 8999 + s := g.Server(p) + // HTTP method handlers. + s.Group("/", func(group *ghttp.RouterGroup) { + group.GET("/", func(r *ghttp.Request) { + r.Response.Writef( + "GET: query: %d, %s", + r.GetQuery("id").Int(), + r.GetQuery("name").String(), + ) + }) + group.PUT("/", func(r *ghttp.Request) { + r.Response.Writef( + "PUT: form: %d, %s", + r.GetForm("id").Int(), + r.GetForm("name").String(), + ) + }) + group.POST("/", func(r *ghttp.Request) { + r.Response.Writef( + "POST: form: %d, %s", + r.GetForm("id").Int(), + r.GetForm("name").String(), + ) + }) + group.DELETE("/", func(r *ghttp.Request) { + r.Response.Writef( + "DELETE: form: %d, %s", + r.GetForm("id").Int(), + r.GetForm("name").String(), + ) + }) + group.HEAD("/", func(r *ghttp.Request) { + r.Response.Write("head") + }) + group.OPTIONS("/", func(r *ghttp.Request) { + r.Response.Write("options") + }) + }) + // Client chaining operations handlers. + s.Group("/", func(group *ghttp.RouterGroup) { + group.ALL("/header", func(r *ghttp.Request) { + r.Response.Writef( + "Span-Id: %s, Trace-Id: %s", + r.Header.Get("Span-Id"), + r.Header.Get("Trace-Id"), + ) + }) + group.ALL("/cookie", func(r *ghttp.Request) { + r.Response.Writef( + "SessionId: %s", + r.Cookie.Get("SessionId"), + ) + }) + group.ALL("/json", func(r *ghttp.Request) { + r.Response.Writef( + "Content-Type: %s, id: %d", + r.Header.Get("Content-Type"), + r.Get("id").Int(), + ) + }) + }) + // Other testing handlers. + s.Group("/var", func(group *ghttp.RouterGroup) { + group.ALL("/json", func(r *ghttp.Request) { + r.Response.Write(`{"id":1,"name":"john"}`) + }) + group.ALL("/jsons", func(r *ghttp.Request) { + r.Response.Write(`[{"id":1,"name":"john"}, {"id":2,"name":"smith"}]`) + }) + }) + s.SetAccessLogEnabled(false) + s.SetDumpRouterMap(false) + s.SetPort(p) + err := s.Start() + if err != nil { + panic(err) + } + time.Sleep(time.Millisecond * 500) +} + +func ExampleClient_Header() { + var ( + url = "http://127.0.0.1:8999/header" + header = g.MapStrStr{ + "Span-Id": "0.1", + "Trace-Id": "123456789", + } + ) + content := g.Client().Header(header).PostContent(ctx, url, g.Map{ + "id": 10000, + "name": "john", + }) + fmt.Println(content) + + // Output: + // Span-Id: 0.1, Trace-Id: 123456789 +} + +func ExampleClient_HeaderRaw() { + var ( + url = "http://127.0.0.1:8999/header" + headerRaw = ` +User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3950.0 Safari/537.36 +Span-Id: 0.1 +Trace-Id: 123456789 +` + ) + content := g.Client().HeaderRaw(headerRaw).PostContent(ctx, url, g.Map{ + "id": 10000, + "name": "john", + }) + fmt.Println(content) + + // Output: + // Span-Id: 0.1, Trace-Id: 123456789 +} + +func ExampleClient_Cookie() { + var ( + url = "http://127.0.0.1:8999/cookie" + cookie = g.MapStrStr{ + "SessionId": "123", + } + ) + content := g.Client().Cookie(cookie).PostContent(ctx, url, g.Map{ + "id": 10000, + "name": "john", + }) + fmt.Println(content) + + // Output: + // SessionId: 123 +} + +func ExampleClient_ContentJson() { + var ( + url = "http://127.0.0.1:8999/json" + jsonStr = `{"id":10000,"name":"john"}` + jsonMap = g.Map{ + "id": 10000, + "name": "john", + } + ) + // Post using JSON string. + fmt.Println(g.Client().ContentJson().PostContent(ctx, url, jsonStr)) + // Post using JSON map. + fmt.Println(g.Client().ContentJson().PostContent(ctx, url, jsonMap)) + + // Output: + // Content-Type: application/json, id: 10000 + // Content-Type: application/json, id: 10000 +} + +func ExampleClient_Post() { + url := "http://127.0.0.1:8999" + // Send with string parameter in request body. + r1, err := g.Client().Post(ctx, url, "id=10000&name=john") + if err != nil { + panic(err) + } + defer r1.Close() + fmt.Println(r1.ReadAllString()) + + // Send with map parameter. + r2, err := g.Client().Post(ctx, url, g.Map{ + "id": 10000, + "name": "john", + }) + if err != nil { + panic(err) + } + defer r2.Close() + fmt.Println(r2.ReadAllString()) + + // Output: + // POST: form: 10000, john + // POST: form: 10000, john +} + +func ExampleClient_PostBytes() { + url := "http://127.0.0.1:8999" + fmt.Println(string(g.Client().PostBytes(ctx, url, g.Map{ + "id": 10000, + "name": "john", + }))) + + // Output: + // POST: form: 10000, john +} + +func ExampleClient_PostContent() { + url := "http://127.0.0.1:8999" + fmt.Println(g.Client().PostContent(ctx, url, g.Map{ + "id": 10000, + "name": "john", + })) + + // Output: + // POST: form: 10000, john +} + +func ExampleClient_PostVar() { + type User struct { + Id int + Name string + } + var ( + users []User + url = "http://127.0.0.1:8999/var/jsons" + ) + err := g.Client().PostVar(ctx, url).Scan(&users) + if err != nil { + panic(err) + } + fmt.Println(users) + + // Output: + // [{1 john} {2 smith}] +} + +func ExampleClient_Get() { + var ( + ctx = context.Background() + url = "http://127.0.0.1:8999" + ) + + // Send with string parameter along with URL. + r1, err := g.Client().Get(ctx, url+"?id=10000&name=john") + if err != nil { + panic(err) + } + defer r1.Close() + fmt.Println(r1.ReadAllString()) + + // Send with string parameter in request body. + r2, err := g.Client().Get(ctx, url, "id=10000&name=john") + if err != nil { + panic(err) + } + defer r2.Close() + fmt.Println(r2.ReadAllString()) + + // Send with map parameter. + r3, err := g.Client().Get(ctx, url, g.Map{ + "id": 10000, + "name": "john", + }) + if err != nil { + panic(err) + } + defer r3.Close() + fmt.Println(r3.ReadAllString()) + + // Output: + // GET: query: 10000, john + // GET: query: 10000, john + // GET: query: 10000, john +} + +func ExampleClient_GetBytes() { + var ( + ctx = context.Background() + url = "http://127.0.0.1:8999" + ) + fmt.Println(string(g.Client().GetBytes(ctx, url, g.Map{ + "id": 10000, + "name": "john", + }))) + + // Output: + // GET: query: 10000, john +} + +func ExampleClient_GetContent() { + url := "http://127.0.0.1:8999" + fmt.Println(g.Client().GetContent(ctx, url, g.Map{ + "id": 10000, + "name": "john", + })) + + // Output: + // GET: query: 10000, john +} + +func ExampleClient_GetVar() { + type User struct { + Id int + Name string + } + var ( + user *User + ctx = context.Background() + url = "http://127.0.0.1:8999/var/json" + ) + err := g.Client().GetVar(ctx, url).Scan(&user) + if err != nil { + panic(err) + } + fmt.Println(user) + + // Output: + // &{1 john} +} + +// ExampleClient_SetProxy a example for `gclient.Client.SetProxy` method. +// please prepare two proxy server before running this example. +// http proxy server listening on `127.0.0.1:1081` +// socks5 proxy server listening on `127.0.0.1:1080` +func ExampleClient_SetProxy() { + // connect to a http proxy server + client := g.Client() + client.SetProxy("http://127.0.0.1:1081") + client.SetTimeout(5 * time.Second) // it's suggested to set http client timeout + response, err := client.Get(ctx, "https://api.ip.sb/ip") + if err != nil { + // err is not nil when your proxy server is down. + // eg. Get "https://api.ip.sb/ip": proxyconnect tcp: dial tcp 127.0.0.1:1087: connect: connection refused + fmt.Println(err) + } + response.RawDump() + // connect to a http proxy server which needs auth + client.SetProxy("http://user:password:127.0.0.1:1081") + client.SetTimeout(5 * time.Second) // it's suggested to set http client timeout + response, err = client.Get(ctx, "https://api.ip.sb/ip") + if err != nil { + // err is not nil when your proxy server is down. + // eg. Get "https://api.ip.sb/ip": proxyconnect tcp: dial tcp 127.0.0.1:1087: connect: connection refused + fmt.Println(err) + } + response.RawDump() + + // connect to a socks5 proxy server + client.SetProxy("socks5://127.0.0.1:1080") + client.SetTimeout(5 * time.Second) // it's suggested to set http client timeout + response, err = client.Get(ctx, "https://api.ip.sb/ip") + if err != nil { + // err is not nil when your proxy server is down. + // eg. Get "https://api.ip.sb/ip": socks connect tcp 127.0.0.1:1087->api.ip.sb:443: dial tcp 127.0.0.1:1087: connect: connection refused + fmt.Println(err) + } + fmt.Println(response.RawResponse()) + + // connect to a socks5 proxy server which needs auth + client.SetProxy("socks5://user:password@127.0.0.1:1080") + client.SetTimeout(5 * time.Second) // it's suggested to set http client timeout + response, err = client.Get(ctx, "https://api.ip.sb/ip") + if err != nil { + // err is not nil when your proxy server is down. + // eg. Get "https://api.ip.sb/ip": socks connect tcp 127.0.0.1:1087->api.ip.sb:443: dial tcp 127.0.0.1:1087: connect: connection refused + fmt.Println(err) + } + fmt.Println(response.RawResponse()) +} + +// ExampleClientChain_Proxy a chain version of example for `gclient.Client.Proxy` method. +// please prepare two proxy server before running this example. +// http proxy server listening on `127.0.0.1:1081` +// socks5 proxy server listening on `127.0.0.1:1080` +// for more details, please refer to ExampleClient_SetProxy +func ExampleClient_Proxy() { + var ( + ctx = context.Background() + ) + client := g.Client() + response, err := client.Proxy("http://127.0.0.1:1081").Get(ctx, "https://api.ip.sb/ip") + if err != nil { + // err is not nil when your proxy server is down. + // eg. Get "https://api.ip.sb/ip": proxyconnect tcp: dial tcp 127.0.0.1:1087: connect: connection refused + fmt.Println(err) + } + fmt.Println(response.RawResponse()) + + client2 := g.Client() + response, err = client2.Proxy("socks5://127.0.0.1:1080").Get(ctx, "https://api.ip.sb/ip") + if err != nil { + // err is not nil when your proxy server is down. + // eg. Get "https://api.ip.sb/ip": socks connect tcp 127.0.0.1:1087->api.ip.sb:443: dial tcp 127.0.0.1:1087: connect: connection refused + fmt.Println(err) + } + fmt.Println(response.RawResponse()) +} diff --git a/net/ghttp/ghttp_z_unit_feature_client_test.go b/net/gclient/gclient_z_unit_test.go similarity index 77% rename from net/ghttp/ghttp_z_unit_feature_client_test.go rename to net/gclient/gclient_z_unit_test.go index e69b08955..a95847c7b 100644 --- a/net/ghttp/ghttp_z_unit_feature_client_test.go +++ b/net/gclient/gclient_z_unit_test.go @@ -4,7 +4,7 @@ // If a copy of the MIT was not distributed with this file, // You can obtain one at https://github.com/gogf/gf. -package ghttp_test +package gclient_test import ( "bytes" @@ -15,15 +15,30 @@ import ( "testing" "time" + "github.com/gogf/gf/v2/container/garray" "github.com/gogf/gf/v2/debug/gdebug" "github.com/gogf/gf/v2/errors/gerror" "github.com/gogf/gf/v2/frame/g" + "github.com/gogf/gf/v2/net/gclient" "github.com/gogf/gf/v2/net/ghttp" "github.com/gogf/gf/v2/os/gfile" "github.com/gogf/gf/v2/test/gtest" + "github.com/gogf/gf/v2/text/gstr" "github.com/gogf/gf/v2/util/guid" + "github.com/gorilla/websocket" ) +var ( + ctx = context.TODO() + ports = garray.NewIntArray(true) +) + +func init() { + for i := 7000; i <= 8000; i++ { + ports.Append(i) + } +} + func Test_Client_Basic(t *testing.T) { p, _ := ports.PopRand() s := g.Server(p) @@ -357,7 +372,7 @@ func Test_Client_Middleware(t *testing.T) { str2 = "resp body" ) c := g.Client().SetPrefix(fmt.Sprintf("http://127.0.0.1:%d", p)) - c.Use(func(c *ghttp.Client, r *http.Request) (resp *ghttp.ClientResponse, err error) { + c.Use(func(c *gclient.Client, r *http.Request) (resp *gclient.Response, err error) { str1 += "a" resp, err = c.Next(r) if err != nil { @@ -366,7 +381,7 @@ func Test_Client_Middleware(t *testing.T) { str1 += "b" return }) - c.Use(func(c *ghttp.Client, r *http.Request) (resp *ghttp.ClientResponse, err error) { + c.Use(func(c *gclient.Client, r *http.Request) (resp *gclient.Response, err error) { str1 += "c" resp, err = c.Next(r) if err != nil { @@ -375,7 +390,7 @@ func Test_Client_Middleware(t *testing.T) { str1 += "d" return }) - c.Use(func(c *ghttp.Client, r *http.Request) (resp *ghttp.ClientResponse, err error) { + c.Use(func(c *gclient.Client, r *http.Request) (resp *gclient.Response, err error) { str1 += "e" resp, err = c.Next(r) if err != nil { @@ -398,17 +413,17 @@ func Test_Client_Middleware(t *testing.T) { ) c = g.Client().SetPrefix(fmt.Sprintf("http://127.0.0.1:%d", p)) - c.Use(func(c *ghttp.Client, r *http.Request) (resp *ghttp.ClientResponse, err error) { + c.Use(func(c *gclient.Client, r *http.Request) (resp *gclient.Response, err error) { str3 += "a" resp, err = c.Next(r) str3 += "b" return }) - c.Use(func(c *ghttp.Client, r *http.Request) (*ghttp.ClientResponse, error) { + c.Use(func(c *gclient.Client, r *http.Request) (*gclient.Response, error) { str3 += "c" return nil, gerror.New(abortStr) }) - c.Use(func(c *ghttp.Client, r *http.Request) (resp *ghttp.ClientResponse, err error) { + c.Use(func(c *gclient.Client, r *http.Request) (resp *gclient.Response, err error) { str3 += "f" resp, err = c.Next(r) str3 += "g" @@ -440,3 +455,85 @@ func Test_Client_Agent(t *testing.T) { t.Assert(c.GetContent(ctx, "/"), "test") }) } + +func Test_Client_Request_13_Dump(t *testing.T) { + p, _ := ports.PopRand() + s := g.Server(p) + s.BindHandler("/hello", func(r *ghttp.Request) { + r.Response.WriteHeader(200) + r.Response.WriteJson(g.Map{"field": "test_for_response_body"}) + }) + s.BindHandler("/hello2", func(r *ghttp.Request) { + r.Response.WriteHeader(200) + r.Response.Writeln(g.Map{"field": "test_for_response_body"}) + }) + s.SetPort(p) + s.SetDumpRouterMap(false) + s.Start() + defer s.Shutdown() + + time.Sleep(100 * time.Millisecond) + gtest.C(t, func(t *gtest.T) { + url := fmt.Sprintf("http://127.0.0.1:%d", p) + client := g.Client().SetPrefix(url).ContentJson() + r, err := client.Post(ctx, "/hello", g.Map{"field": "test_for_request_body"}) + t.Assert(err, nil) + dumpedText := r.RawRequest() + t.Assert(gstr.Contains(dumpedText, "test_for_request_body"), true) + dumpedText2 := r.RawResponse() + fmt.Println(dumpedText2) + t.Assert(gstr.Contains(dumpedText2, "test_for_response_body"), true) + + client2 := g.Client().SetPrefix(url).ContentType("text/html") + r2, err := client2.Post(ctx, "/hello2", g.Map{"field": "test_for_request_body"}) + t.Assert(err, nil) + dumpedText3 := r2.RawRequest() + t.Assert(gstr.Contains(dumpedText3, "test_for_request_body"), true) + dumpedText4 := r2.RawResponse() + t.Assert(gstr.Contains(dumpedText4, "test_for_request_body"), false) + }) +} + +func Test_WebSocketClient(t *testing.T) { + p, _ := ports.PopRand() + s := g.Server(p) + s.BindHandler("/ws", func(r *ghttp.Request) { + ws, err := r.WebSocket() + if err != nil { + r.Exit() + } + for { + msgType, msg, err := ws.ReadMessage() + if err != nil { + return + } + if err = ws.WriteMessage(msgType, msg); err != nil { + return + } + } + }) + s.SetPort(p) + s.SetDumpRouterMap(false) + s.Start() + defer s.Shutdown() + + time.Sleep(100 * time.Millisecond) + gtest.C(t, func(t *gtest.T) { + client := gclient.NewWebSocket() + client.Proxy = http.ProxyFromEnvironment + client.HandshakeTimeout = time.Minute + + conn, _, err := client.Dial(fmt.Sprintf("ws://127.0.0.1:%d/ws", p), nil) + t.Assert(err, nil) + defer conn.Close() + + msg := []byte("hello") + err = conn.WriteMessage(websocket.TextMessage, msg) + t.Assert(err, nil) + + mt, data, err := conn.ReadMessage() + t.Assert(err, nil) + t.Assert(mt, websocket.TextMessage) + t.Assert(data, msg) + }) +} diff --git a/net/gclient/testdata/upload/file1.txt b/net/gclient/testdata/upload/file1.txt new file mode 100644 index 000000000..1885a2771 --- /dev/null +++ b/net/gclient/testdata/upload/file1.txt @@ -0,0 +1 @@ +file1.txt: This file is for uploading unit test case. \ No newline at end of file diff --git a/net/gclient/testdata/upload/file2.txt b/net/gclient/testdata/upload/file2.txt new file mode 100644 index 000000000..e3167d360 --- /dev/null +++ b/net/gclient/testdata/upload/file2.txt @@ -0,0 +1 @@ +file2.txt: This file is for uploading unit test case. \ No newline at end of file diff --git a/net/ghttp/ghttp_client.go b/net/ghttp/ghttp_client.go deleted file mode 100644 index 3c6235675..000000000 --- a/net/ghttp/ghttp_client.go +++ /dev/null @@ -1,22 +0,0 @@ -// Copyright GoFrame Author(https://goframe.org). All Rights Reserved. -// -// This Source Code Form is subject to the terms of the MIT License. -// If a copy of the MIT was not distributed with this file, -// You can obtain one at https://github.com/gogf/gf. - -package ghttp - -import ( - "github.com/gogf/gf/v2/net/ghttp/internal/client" -) - -type ( - Client = client.Client - ClientResponse = client.Response - ClientHandlerFunc = client.HandlerFunc -) - -// NewClient creates and returns a new HTTP client object. -func NewClient() *Client { - return client.New() -} diff --git a/net/ghttp/ghttp_func.go b/net/ghttp/ghttp_func.go index e40f9bed5..ed1177df0 100644 --- a/net/ghttp/ghttp_func.go +++ b/net/ghttp/ghttp_func.go @@ -9,7 +9,7 @@ package ghttp import ( "github.com/gogf/gf/v2/errors/gcode" "github.com/gogf/gf/v2/errors/gerror" - "github.com/gogf/gf/v2/net/ghttp/internal/httputil" + "github.com/gogf/gf/v2/internal/httputil" ) // BuildParams builds the request string for the http client. The `params` can be type of: diff --git a/net/ghttp/ghttp_middleware_tracing.go b/net/ghttp/ghttp_middleware_tracing.go index 8f885bf1b..d74aea77a 100644 --- a/net/ghttp/ghttp_middleware_tracing.go +++ b/net/ghttp/ghttp_middleware_tracing.go @@ -18,9 +18,9 @@ import ( "go.opentelemetry.io/otel/trace" "github.com/gogf/gf/v2" + "github.com/gogf/gf/v2/internal/httputil" "github.com/gogf/gf/v2/internal/utils" - "github.com/gogf/gf/v2/net/ghttp/internal/client" - "github.com/gogf/gf/v2/net/ghttp/internal/httputil" + "github.com/gogf/gf/v2/net/gclient" "github.com/gogf/gf/v2/net/gtrace" "github.com/gogf/gf/v2/text/gstr" "github.com/gogf/gf/v2/util/gconv" @@ -38,8 +38,8 @@ const ( ) // MiddlewareClientTracing is a client middleware that enables tracing feature using standards of OpenTelemetry. -func MiddlewareClientTracing(c *Client, r *http.Request) (*ClientResponse, error) { - return client.MiddlewareTracing(c, r) +func MiddlewareClientTracing(c *gclient.Client, r *http.Request) (*gclient.Response, error) { + return gclient.MiddlewareTracing(c, r) } // MiddlewareServerTracing is a serer middleware that enables tracing feature using standards of OpenTelemetry. diff --git a/net/ghttp/ghttp_z_example_client_test.go b/net/ghttp/ghttp_z_example_client_test.go deleted file mode 100644 index 00af6290d..000000000 --- a/net/ghttp/ghttp_z_example_client_test.go +++ /dev/null @@ -1,86 +0,0 @@ -// Copyright GoFrame Author(https://goframe.org). All Rights Reserved. -// -// This Source Code Form is subject to the terms of the MIT License. -// If a copy of the MIT was not distributed with this file, -// You can obtain one at https://github.com/gogf/gf. - -package ghttp_test - -import ( - "fmt" - - "github.com/gogf/gf/v2/frame/g" -) - -func ExampleClient_Header() { - var ( - url = "http://127.0.0.1:8999/header" - header = g.MapStrStr{ - "Span-Id": "0.1", - "Trace-Id": "123456789", - } - ) - content := g.Client().Header(header).PostContent(ctx, url, g.Map{ - "id": 10000, - "name": "john", - }) - fmt.Println(content) - - // Output: - // Span-Id: 0.1, Trace-Id: 123456789 -} - -func ExampleClient_HeaderRaw() { - var ( - url = "http://127.0.0.1:8999/header" - headerRaw = ` -User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3950.0 Safari/537.36 -Span-Id: 0.1 -Trace-Id: 123456789 -` - ) - content := g.Client().HeaderRaw(headerRaw).PostContent(ctx, url, g.Map{ - "id": 10000, - "name": "john", - }) - fmt.Println(content) - - // Output: - // Span-Id: 0.1, Trace-Id: 123456789 -} - -func ExampleClient_Cookie() { - var ( - url = "http://127.0.0.1:8999/cookie" - cookie = g.MapStrStr{ - "SessionId": "123", - } - ) - content := g.Client().Cookie(cookie).PostContent(ctx, url, g.Map{ - "id": 10000, - "name": "john", - }) - fmt.Println(content) - - // Output: - // SessionId: 123 -} - -func ExampleClient_ContentJson() { - var ( - url = "http://127.0.0.1:8999/json" - jsonStr = `{"id":10000,"name":"john"}` - jsonMap = g.Map{ - "id": 10000, - "name": "john", - } - ) - // Post using JSON string. - fmt.Println(g.Client().ContentJson().PostContent(ctx, url, jsonStr)) - // Post using JSON map. - fmt.Println(g.Client().ContentJson().PostContent(ctx, url, jsonMap)) - - // Output: - // Content-Type: application/json, id: 10000 - // Content-Type: application/json, id: 10000 -} diff --git a/net/ghttp/ghttp_z_example_get_test.go b/net/ghttp/ghttp_z_example_get_test.go deleted file mode 100644 index b839ae602..000000000 --- a/net/ghttp/ghttp_z_example_get_test.go +++ /dev/null @@ -1,98 +0,0 @@ -// Copyright GoFrame Author(https://goframe.org). All Rights Reserved. -// -// This Source Code Form is subject to the terms of the MIT License. -// If a copy of the MIT was not distributed with this file, -// You can obtain one at https://github.com/gogf/gf. - -package ghttp_test - -import ( - "context" - "fmt" - - "github.com/gogf/gf/v2/frame/g" -) - -func ExampleClient_Get() { - var ( - ctx = context.Background() - url = "http://127.0.0.1:8999" - ) - - // Send with string parameter along with URL. - r1, err := g.Client().Get(ctx, url+"?id=10000&name=john") - if err != nil { - panic(err) - } - defer r1.Close() - fmt.Println(r1.ReadAllString()) - - // Send with string parameter in request body. - r2, err := g.Client().Get(ctx, url, "id=10000&name=john") - if err != nil { - panic(err) - } - defer r2.Close() - fmt.Println(r2.ReadAllString()) - - // Send with map parameter. - r3, err := g.Client().Get(ctx, url, g.Map{ - "id": 10000, - "name": "john", - }) - if err != nil { - panic(err) - } - defer r3.Close() - fmt.Println(r3.ReadAllString()) - - // Output: - // GET: query: 10000, john - // GET: query: 10000, john - // GET: query: 10000, john -} - -func ExampleClient_GetBytes() { - var ( - ctx = context.Background() - url = "http://127.0.0.1:8999" - ) - fmt.Println(string(g.Client().GetBytes(ctx, url, g.Map{ - "id": 10000, - "name": "john", - }))) - - // Output: - // GET: query: 10000, john -} - -func ExampleClient_GetContent() { - url := "http://127.0.0.1:8999" - fmt.Println(g.Client().GetContent(ctx, url, g.Map{ - "id": 10000, - "name": "john", - })) - - // Output: - // GET: query: 10000, john -} - -func ExampleClient_GetVar() { - type User struct { - Id int - Name string - } - var ( - user *User - ctx = context.Background() - url = "http://127.0.0.1:8999/var/json" - ) - err := g.Client().GetVar(ctx, url).Scan(&user) - if err != nil { - panic(err) - } - fmt.Println(user) - - // Output: - // &{1 john} -} diff --git a/net/ghttp/ghttp_z_example_init_test.go b/net/ghttp/ghttp_z_example_init_test.go deleted file mode 100644 index 6bc446825..000000000 --- a/net/ghttp/ghttp_z_example_init_test.go +++ /dev/null @@ -1,96 +0,0 @@ -// Copyright GoFrame Author(https://goframe.org). All Rights Reserved. -// -// This Source Code Form is subject to the terms of the MIT License. -// If a copy of the MIT was not distributed with this file, -// You can obtain one at https://github.com/gogf/gf. - -package ghttp_test - -import ( - "time" - - "github.com/gogf/gf/v2/frame/g" - "github.com/gogf/gf/v2/net/ghttp" -) - -func init() { - p := 8999 - s := g.Server(p) - // HTTP method handlers. - s.Group("/", func(group *ghttp.RouterGroup) { - group.GET("/", func(r *ghttp.Request) { - r.Response.Writef( - "GET: query: %d, %s", - r.GetQuery("id").Int(), - r.GetQuery("name").String(), - ) - }) - group.PUT("/", func(r *ghttp.Request) { - r.Response.Writef( - "PUT: form: %d, %s", - r.GetForm("id").Int(), - r.GetForm("name").String(), - ) - }) - group.POST("/", func(r *ghttp.Request) { - r.Response.Writef( - "POST: form: %d, %s", - r.GetForm("id").Int(), - r.GetForm("name").String(), - ) - }) - group.DELETE("/", func(r *ghttp.Request) { - r.Response.Writef( - "DELETE: form: %d, %s", - r.GetForm("id").Int(), - r.GetForm("name").String(), - ) - }) - group.HEAD("/", func(r *ghttp.Request) { - r.Response.Write("head") - }) - group.OPTIONS("/", func(r *ghttp.Request) { - r.Response.Write("options") - }) - }) - // Client chaining operations handlers. - s.Group("/", func(group *ghttp.RouterGroup) { - group.ALL("/header", func(r *ghttp.Request) { - r.Response.Writef( - "Span-Id: %s, Trace-Id: %s", - r.Header.Get("Span-Id"), - r.Header.Get("Trace-Id"), - ) - }) - group.ALL("/cookie", func(r *ghttp.Request) { - r.Response.Writef( - "SessionId: %s", - r.Cookie.Get("SessionId"), - ) - }) - group.ALL("/json", func(r *ghttp.Request) { - r.Response.Writef( - "Content-Type: %s, id: %d", - r.Header.Get("Content-Type"), - r.Get("id").Int(), - ) - }) - }) - // Other testing handlers. - s.Group("/var", func(group *ghttp.RouterGroup) { - group.ALL("/json", func(r *ghttp.Request) { - r.Response.Write(`{"id":1,"name":"john"}`) - }) - group.ALL("/jsons", func(r *ghttp.Request) { - r.Response.Write(`[{"id":1,"name":"john"}, {"id":2,"name":"smith"}]`) - }) - }) - s.SetAccessLogEnabled(false) - s.SetDumpRouterMap(false) - s.SetPort(p) - err := s.Start() - if err != nil { - panic(err) - } - time.Sleep(time.Millisecond * 500) -} diff --git a/net/ghttp/ghttp_z_example_post_test.go b/net/ghttp/ghttp_z_example_post_test.go deleted file mode 100644 index 6c573645d..000000000 --- a/net/ghttp/ghttp_z_example_post_test.go +++ /dev/null @@ -1,80 +0,0 @@ -// Copyright GoFrame Author(https://goframe.org). All Rights Reserved. -// -// This Source Code Form is subject to the terms of the MIT License. -// If a copy of the MIT was not distributed with this file, -// You can obtain one at https://github.com/gogf/gf. - -package ghttp_test - -import ( - "fmt" - - "github.com/gogf/gf/v2/frame/g" -) - -func ExampleClient_Post() { - url := "http://127.0.0.1:8999" - // Send with string parameter in request body. - r1, err := g.Client().Post(ctx, url, "id=10000&name=john") - if err != nil { - panic(err) - } - defer r1.Close() - fmt.Println(r1.ReadAllString()) - - // Send with map parameter. - r2, err := g.Client().Post(ctx, url, g.Map{ - "id": 10000, - "name": "john", - }) - if err != nil { - panic(err) - } - defer r2.Close() - fmt.Println(r2.ReadAllString()) - - // Output: - // POST: form: 10000, john - // POST: form: 10000, john -} - -func ExampleClient_PostBytes() { - url := "http://127.0.0.1:8999" - fmt.Println(string(g.Client().PostBytes(ctx, url, g.Map{ - "id": 10000, - "name": "john", - }))) - - // Output: - // POST: form: 10000, john -} - -func ExampleClient_PostContent() { - url := "http://127.0.0.1:8999" - fmt.Println(g.Client().PostContent(ctx, url, g.Map{ - "id": 10000, - "name": "john", - })) - - // Output: - // POST: form: 10000, john -} - -func ExampleClient_PostVar() { - type User struct { - Id int - Name string - } - var ( - users []User - url = "http://127.0.0.1:8999/var/jsons" - ) - err := g.Client().PostVar(ctx, url).Scan(&users) - if err != nil { - panic(err) - } - fmt.Println(users) - - // Output: - // [{1 john} {2 smith}] -} diff --git a/net/ghttp/ghttp_z_example_test.go b/net/ghttp/ghttp_z_example_test.go index 61aeba006..ce07cda1f 100644 --- a/net/ghttp/ghttp_z_example_test.go +++ b/net/ghttp/ghttp_z_example_test.go @@ -7,16 +7,12 @@ package ghttp_test import ( - "context" - "fmt" - "time" - "github.com/gogf/gf/v2/frame/g" "github.com/gogf/gf/v2/net/ghttp" "github.com/gogf/gf/v2/os/gfile" ) -func ExampleHelloWorld() { +func ExampleServer_Run() { s := g.Server() s.BindHandler("/", func(r *ghttp.Request) { r.Response.Write("hello world") @@ -45,92 +41,3 @@ func ExampleUploadFile_Save() { s.SetPort(8999) s.Run() } - -func ExampleClientResponse_RawDump() { - var ( - ctx = context.Background() - ) - response, err := g.Client().Get(ctx, "https://goframe.org") - if err != nil { - panic(err) - } - response.RawDump() -} - -// ExampleClient_SetProxy a example for `ghttp.Client.SetProxy` method. -// please prepare two proxy server before running this example. -// http proxy server listening on `127.0.0.1:1081` -// socks5 proxy server listening on `127.0.0.1:1080` -func ExampleClient_SetProxy() { - // connect to a http proxy server - client := g.Client() - client.SetProxy("http://127.0.0.1:1081") - client.SetTimeout(5 * time.Second) // it's suggested to set http client timeout - response, err := client.Get(ctx, "https://api.ip.sb/ip") - if err != nil { - // err is not nil when your proxy server is down. - // eg. Get "https://api.ip.sb/ip": proxyconnect tcp: dial tcp 127.0.0.1:1087: connect: connection refused - fmt.Println(err) - } - response.RawDump() - // connect to a http proxy server which needs auth - client.SetProxy("http://user:password:127.0.0.1:1081") - client.SetTimeout(5 * time.Second) // it's suggested to set http client timeout - response, err = client.Get(ctx, "https://api.ip.sb/ip") - if err != nil { - // err is not nil when your proxy server is down. - // eg. Get "https://api.ip.sb/ip": proxyconnect tcp: dial tcp 127.0.0.1:1087: connect: connection refused - fmt.Println(err) - } - response.RawDump() - - // connect to a socks5 proxy server - client.SetProxy("socks5://127.0.0.1:1080") - client.SetTimeout(5 * time.Second) // it's suggested to set http client timeout - response, err = client.Get(ctx, "https://api.ip.sb/ip") - if err != nil { - // err is not nil when your proxy server is down. - // eg. Get "https://api.ip.sb/ip": socks connect tcp 127.0.0.1:1087->api.ip.sb:443: dial tcp 127.0.0.1:1087: connect: connection refused - fmt.Println(err) - } - fmt.Println(response.RawResponse()) - - // connect to a socks5 proxy server which needs auth - client.SetProxy("socks5://user:password@127.0.0.1:1080") - client.SetTimeout(5 * time.Second) // it's suggested to set http client timeout - response, err = client.Get(ctx, "https://api.ip.sb/ip") - if err != nil { - // err is not nil when your proxy server is down. - // eg. Get "https://api.ip.sb/ip": socks connect tcp 127.0.0.1:1087->api.ip.sb:443: dial tcp 127.0.0.1:1087: connect: connection refused - fmt.Println(err) - } - fmt.Println(response.RawResponse()) -} - -// ExampleClientChain_Proxy a chain version of example for `ghttp.Client.Proxy` method. -// please prepare two proxy server before running this example. -// http proxy server listening on `127.0.0.1:1081` -// socks5 proxy server listening on `127.0.0.1:1080` -// for more details, please refer to ExampleClient_SetProxy -func ExampleClientChain_Proxy() { - var ( - ctx = context.Background() - ) - client := g.Client() - response, err := client.Proxy("http://127.0.0.1:1081").Get(ctx, "https://api.ip.sb/ip") - if err != nil { - // err is not nil when your proxy server is down. - // eg. Get "https://api.ip.sb/ip": proxyconnect tcp: dial tcp 127.0.0.1:1087: connect: connection refused - fmt.Println(err) - } - fmt.Println(response.RawResponse()) - - client2 := g.Client() - response, err = client2.Proxy("socks5://127.0.0.1:1080").Get(ctx, "https://api.ip.sb/ip") - if err != nil { - // err is not nil when your proxy server is down. - // eg. Get "https://api.ip.sb/ip": socks connect tcp 127.0.0.1:1087->api.ip.sb:443: dial tcp 127.0.0.1:1087: connect: connection refused - fmt.Println(err) - } - fmt.Println(response.RawResponse()) -} diff --git a/net/ghttp/ghttp_z_unit_feature_client_dump_test.go b/net/ghttp/ghttp_z_unit_feature_client_dump_test.go deleted file mode 100644 index 28597839e..000000000 --- a/net/ghttp/ghttp_z_unit_feature_client_dump_test.go +++ /dev/null @@ -1,56 +0,0 @@ -// Copyright GoFrame Author(https://goframe.org). All Rights Reserved. -// -// This Source Code Form is subject to the terms of the MIT License. -// If a copy of the MIT was not distributed with this file, -// You can obtain one at https://github.com/gogf/gf. - -package ghttp_test - -import ( - "fmt" - "testing" - "time" - - "github.com/gogf/gf/v2/frame/g" - "github.com/gogf/gf/v2/net/ghttp" - "github.com/gogf/gf/v2/test/gtest" - "github.com/gogf/gf/v2/text/gstr" -) - -func Test_Client_Request_13_Dump(t *testing.T) { - p, _ := ports.PopRand() - s := g.Server(p) - s.BindHandler("/hello", func(r *ghttp.Request) { - r.Response.WriteHeader(200) - r.Response.WriteJson(g.Map{"field": "test_for_response_body"}) - }) - s.BindHandler("/hello2", func(r *ghttp.Request) { - r.Response.WriteHeader(200) - r.Response.Writeln(g.Map{"field": "test_for_response_body"}) - }) - s.SetPort(p) - s.SetDumpRouterMap(false) - s.Start() - defer s.Shutdown() - - time.Sleep(100 * time.Millisecond) - gtest.C(t, func(t *gtest.T) { - url := fmt.Sprintf("http://127.0.0.1:%d", p) - client := g.Client().SetPrefix(url).ContentJson() - r, err := client.Post(ctx, "/hello", g.Map{"field": "test_for_request_body"}) - t.Assert(err, nil) - dumpedText := r.RawRequest() - t.Assert(gstr.Contains(dumpedText, "test_for_request_body"), true) - dumpedText2 := r.RawResponse() - fmt.Println(dumpedText2) - t.Assert(gstr.Contains(dumpedText2, "test_for_response_body"), true) - - client2 := g.Client().SetPrefix(url).ContentType("text/html") - r2, err := client2.Post(ctx, "/hello2", g.Map{"field": "test_for_request_body"}) - t.Assert(err, nil) - dumpedText3 := r2.RawRequest() - t.Assert(gstr.Contains(dumpedText3, "test_for_request_body"), true) - dumpedText4 := r2.RawResponse() - t.Assert(gstr.Contains(dumpedText4, "test_for_request_body"), false) - }) -} diff --git a/net/ghttp/ghttp_z_unit_feature_router_group_rest_test.go b/net/ghttp/ghttp_z_unit_feature_router_group_rest_test.go index 509562fdf..52cc12578 100644 --- a/net/ghttp/ghttp_z_unit_feature_router_group_rest_test.go +++ b/net/ghttp/ghttp_z_unit_feature_router_group_rest_test.go @@ -4,7 +4,6 @@ // If a copy of the MIT was not distributed with this file, // You can obtain one at https://github.com/gogf/gf. -// 分组路由测试 package ghttp_test import ( diff --git a/net/ghttp/ghttp_z_unit_feature_websocket_client_test.go b/net/ghttp/ghttp_z_unit_feature_websocket_client_test.go deleted file mode 100644 index 56c2c794d..000000000 --- a/net/ghttp/ghttp_z_unit_feature_websocket_client_test.go +++ /dev/null @@ -1,63 +0,0 @@ -// Copyright GoFrame Author(https://goframe.org). All Rights Reserved. -// -// This Source Code Form is subject to the terms of the MIT License. -// If a copy of the MIT was not distributed with this file, -// You can obtain one at https://github.com/gogf/gf. - -package ghttp_test - -import ( - "fmt" - "net/http" - "testing" - "time" - - "github.com/gogf/gf/v2/frame/g" - "github.com/gogf/gf/v2/net/ghttp" - "github.com/gogf/gf/v2/test/gtest" - "github.com/gorilla/websocket" -) - -func Test_WebSocketClient(t *testing.T) { - p, _ := ports.PopRand() - s := g.Server(p) - s.BindHandler("/ws", func(r *ghttp.Request) { - ws, err := r.WebSocket() - if err != nil { - r.Exit() - } - for { - msgType, msg, err := ws.ReadMessage() - if err != nil { - return - } - if err = ws.WriteMessage(msgType, msg); err != nil { - return - } - } - }) - s.SetPort(p) - s.SetDumpRouterMap(false) - s.Start() - defer s.Shutdown() - - time.Sleep(100 * time.Millisecond) - gtest.C(t, func(t *gtest.T) { - client := ghttp.NewWebSocketClient() - client.Proxy = http.ProxyFromEnvironment - client.HandshakeTimeout = time.Minute - - conn, _, err := client.Dial(fmt.Sprintf("ws://127.0.0.1:%d/ws", p), nil) - t.Assert(err, nil) - defer conn.Close() - - msg := []byte("hello") - err = conn.WriteMessage(websocket.TextMessage, msg) - t.Assert(err, nil) - - mt, data, err := conn.ReadMessage() - t.Assert(err, nil) - t.Assert(mt, websocket.TextMessage) - t.Assert(data, msg) - }) -}