mirror of
https://github.com/valyala/fasthttp.git
synced 2026-06-14 15:56:44 +03:00
Added Post() method to client
This commit is contained in:
@@ -30,13 +30,17 @@ func Do(req *Request, resp *Response) error {
|
||||
}
|
||||
|
||||
// Get fetches url contents into dst.
|
||||
//
|
||||
// Use Do for request customization.
|
||||
func Get(dst []byte, url string) (statusCode int, body []byte, err error) {
|
||||
return defaultClient.Get(dst, url)
|
||||
}
|
||||
|
||||
// GetBytes fetches url contents into dst.
|
||||
func GetBytes(dst, url []byte) (statusCode int, body []byte, err error) {
|
||||
return defaultClient.GetBytes(dst, url)
|
||||
// Post sends POST request to the given url with the given POST arguments.
|
||||
//
|
||||
// Use Do for request customization.
|
||||
func Post(dst []byte, url string, postArgs *Args) (statusCode int, body []byte, err error) {
|
||||
return defaultClient.Post(dst, url, postArgs)
|
||||
}
|
||||
|
||||
var defaultClient Client
|
||||
@@ -75,37 +79,17 @@ type Client struct {
|
||||
}
|
||||
|
||||
// Get fetches url contents into dst.
|
||||
//
|
||||
// Use Do for request customization.
|
||||
func (c *Client) Get(dst []byte, url string) (statusCode int, body []byte, err error) {
|
||||
v := urlBufPool.Get()
|
||||
if v == nil {
|
||||
v = make([]byte, 1024)
|
||||
}
|
||||
buf := v.([]byte)
|
||||
buf = AppendBytesStr(buf[:0], url)
|
||||
statusCode, body, err = c.GetBytes(dst, buf)
|
||||
urlBufPool.Put(v)
|
||||
return statusCode, body, err
|
||||
return clientGetURL(dst, url, c)
|
||||
}
|
||||
|
||||
// GetBytes fetches url contents into dst.
|
||||
func (c *Client) GetBytes(dst, url []byte) (statusCode int, body []byte, err error) {
|
||||
req := acquireRequest()
|
||||
req.Header.RequestURI = url
|
||||
req.ParseURI()
|
||||
|
||||
resp := acquireResponse()
|
||||
resp.Body = dst
|
||||
if err = c.Do(req, resp); err != nil {
|
||||
return 0, nil, err
|
||||
}
|
||||
statusCode = resp.Header.StatusCode
|
||||
body = resp.Body
|
||||
resp.Body = nil
|
||||
releaseResponse(resp)
|
||||
|
||||
req.Header.RequestURI = nil
|
||||
releaseRequest(req)
|
||||
return statusCode, body, err
|
||||
// Post sends POST request to the given url with the given POST arguments.
|
||||
//
|
||||
// Use Do for request customization.
|
||||
func (c *Client) Post(dst []byte, url string, postArgs *Args) (statusCode int, body []byte, err error) {
|
||||
return clientPostURL(dst, url, postArgs, c)
|
||||
}
|
||||
|
||||
// Do performs the given http request and fills the given http response.
|
||||
@@ -277,25 +261,55 @@ func (c *HostClient) LastUseTime() time.Time {
|
||||
}
|
||||
|
||||
// Get fetches url contents into dst.
|
||||
//
|
||||
// Use Do for request customization.
|
||||
func (c *HostClient) Get(dst []byte, url string) (statusCode int, body []byte, err error) {
|
||||
return clientGetURL(dst, url, c)
|
||||
}
|
||||
|
||||
// Post sends POST request to the given url with the given POST arguments.
|
||||
//
|
||||
// Use Do for request customization.
|
||||
func (c *HostClient) Post(dst []byte, url string, postArgs *Args) (statusCode int, body []byte, err error) {
|
||||
return clientPostURL(dst, url, postArgs, c)
|
||||
}
|
||||
|
||||
type clientDoer interface {
|
||||
Do(req *Request, resp *Response) error
|
||||
}
|
||||
|
||||
func clientGetURL(dst []byte, url string, c clientDoer) (statusCode int, body []byte, err error) {
|
||||
req := acquireRequest()
|
||||
|
||||
statusCode, body, err = doRequest(req, dst, url, c)
|
||||
|
||||
releaseRequest(req)
|
||||
return statusCode, body, err
|
||||
}
|
||||
|
||||
func clientPostURL(dst []byte, url string, postArgs *Args, c clientDoer) (statusCode int, body []byte, err error) {
|
||||
req := acquireRequest()
|
||||
req.Header.Method = strPost
|
||||
req.Header.contentType = strPostArgsContentType
|
||||
req.Body = postArgs.AppendBytes(req.Body[:0])
|
||||
|
||||
statusCode, body, err = doRequest(req, dst, url, c)
|
||||
|
||||
req.Header.Method = nil
|
||||
req.Header.contentType = nil
|
||||
// there is no need in req.Body = nil, since Body belongs to req.
|
||||
releaseRequest(req)
|
||||
return statusCode, body, err
|
||||
}
|
||||
|
||||
func doRequest(req *Request, dst []byte, url string, c clientDoer) (statusCode int, body []byte, err error) {
|
||||
v := urlBufPool.Get()
|
||||
if v == nil {
|
||||
v = make([]byte, 1024)
|
||||
}
|
||||
buf := v.([]byte)
|
||||
buf = AppendBytesStr(buf[:0], url)
|
||||
statusCode, body, err = c.GetBytes(dst, buf)
|
||||
urlBufPool.Put(v)
|
||||
return statusCode, body, err
|
||||
}
|
||||
|
||||
var urlBufPool sync.Pool
|
||||
|
||||
// GetBytes fetches url contents into dst.
|
||||
func (c *HostClient) GetBytes(dst, url []byte) (statusCode int, body []byte, err error) {
|
||||
req := acquireRequest()
|
||||
req.Header.RequestURI = url
|
||||
req.ParseURI()
|
||||
req.Header.RequestURI = buf
|
||||
|
||||
resp := acquireResponse()
|
||||
resp.Body = dst
|
||||
@@ -308,11 +322,14 @@ func (c *HostClient) GetBytes(dst, url []byte) (statusCode int, body []byte, err
|
||||
releaseResponse(resp)
|
||||
|
||||
req.Header.RequestURI = nil
|
||||
releaseRequest(req)
|
||||
urlBufPool.Put(v)
|
||||
|
||||
return statusCode, body, err
|
||||
}
|
||||
|
||||
var (
|
||||
urlBufPool sync.Pool
|
||||
|
||||
requestPool sync.Pool
|
||||
responsePool sync.Pool
|
||||
)
|
||||
|
||||
+64
-4
@@ -30,6 +30,7 @@ func TestClientHTTPSConcurrent(t *testing.T) {
|
||||
go func() {
|
||||
defer wg.Done()
|
||||
testClientGet(t, &defaultClient, addr, 3000)
|
||||
testClientPost(t, &defaultClient, addr, 1000)
|
||||
}()
|
||||
}
|
||||
wg.Wait()
|
||||
@@ -51,6 +52,7 @@ func TestClientManyServers(t *testing.T) {
|
||||
go func() {
|
||||
defer wg.Done()
|
||||
testClientGet(t, &defaultClient, addr, 3000)
|
||||
testClientPost(t, &defaultClient, addr, 1000)
|
||||
}()
|
||||
}
|
||||
wg.Wait()
|
||||
@@ -65,7 +67,16 @@ func TestClientGet(t *testing.T) {
|
||||
testClientGet(t, &defaultClient, addr, 100)
|
||||
}
|
||||
|
||||
func TestClientGetConcurrent(t *testing.T) {
|
||||
func TestClientPost(t *testing.T) {
|
||||
addr := "127.0.0.1:56798"
|
||||
s := startEchoServer(t, "tcp", addr)
|
||||
defer s.Stop()
|
||||
|
||||
addr = "http://" + addr
|
||||
testClientPost(t, &defaultClient, addr, 100)
|
||||
}
|
||||
|
||||
func TestClientConcurrent(t *testing.T) {
|
||||
addr := "127.0.0.1:56780"
|
||||
s := startEchoServer(t, "tcp", addr)
|
||||
defer s.Stop()
|
||||
@@ -77,6 +88,7 @@ func TestClientGetConcurrent(t *testing.T) {
|
||||
go func() {
|
||||
defer wg.Done()
|
||||
testClientGet(t, &defaultClient, addr, 3000)
|
||||
testClientPost(t, &defaultClient, addr, 1000)
|
||||
}()
|
||||
}
|
||||
wg.Wait()
|
||||
@@ -91,8 +103,17 @@ func TestHostClientGet(t *testing.T) {
|
||||
testHostClientGet(t, c, 100)
|
||||
}
|
||||
|
||||
func TestHostClientGetConcurrent(t *testing.T) {
|
||||
addr := "./TestHostClientGetConcurrent.unix"
|
||||
func TestHostClientPost(t *testing.T) {
|
||||
addr := "./TestHostClientPost.unix"
|
||||
s := startEchoServer(t, "unix", addr)
|
||||
defer s.Stop()
|
||||
c := createEchoClient(t, "unix", addr)
|
||||
|
||||
testHostClientPost(t, c, 100)
|
||||
}
|
||||
|
||||
func TestHostClientConcurrent(t *testing.T) {
|
||||
addr := "./TestHostClientConcurrent.unix"
|
||||
s := startEchoServer(t, "unix", addr)
|
||||
defer s.Stop()
|
||||
c := createEchoClient(t, "unix", addr)
|
||||
@@ -103,6 +124,7 @@ func TestHostClientGetConcurrent(t *testing.T) {
|
||||
go func() {
|
||||
defer wg.Done()
|
||||
testHostClientGet(t, c, 3000)
|
||||
testHostClientPost(t, c, 1000)
|
||||
}()
|
||||
}
|
||||
wg.Wait()
|
||||
@@ -130,10 +152,41 @@ func testClientGet(t *testing.T, c clientGetter, addr string, n int) {
|
||||
}
|
||||
}
|
||||
|
||||
func testClientPost(t *testing.T, c clientPoster, addr string, n int) {
|
||||
var buf []byte
|
||||
var args Args
|
||||
for i := 0; i < n; i++ {
|
||||
uri := fmt.Sprintf("%s/foo/%d?bar=baz", addr, i)
|
||||
args.Set("xx", fmt.Sprintf("yy%d", i))
|
||||
args.Set("zzz", fmt.Sprintf("qwe_%d", i))
|
||||
argsS := args.String()
|
||||
statusCode, body, err := c.Post(buf, uri, &args)
|
||||
buf = body
|
||||
if err != nil {
|
||||
t.Fatalf("unexpected error when doing http request: %s", err)
|
||||
}
|
||||
if statusCode != StatusOK {
|
||||
t.Fatalf("unexpected status code: %d. Expecting %d", statusCode, StatusOK)
|
||||
}
|
||||
s := string(body)
|
||||
if s != argsS {
|
||||
t.Fatalf("unexpected response %q. Expecting %q", s, argsS)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func testHostClientGet(t *testing.T, c *HostClient, n int) {
|
||||
testClientGet(t, c, "http://google.com", n)
|
||||
}
|
||||
|
||||
func testHostClientPost(t *testing.T, c *HostClient, n int) {
|
||||
testClientPost(t, c, "http://post-host.com", n)
|
||||
}
|
||||
|
||||
type clientPoster interface {
|
||||
Post(dst []byte, uri string, postArgs *Args) (int, []byte, error)
|
||||
}
|
||||
|
||||
type clientGetter interface {
|
||||
Get(dst []byte, uri string) (int, []byte, error)
|
||||
}
|
||||
@@ -198,7 +251,14 @@ func startEchoServerExt(t *testing.T, network, addr string, isTLS bool) *testEch
|
||||
s := &Server{
|
||||
Handler: func(ctx *RequestCtx) {
|
||||
ctx.Request.ParseURI()
|
||||
ctx.Success("text/plain", ctx.Request.URI.URI)
|
||||
if ctx.IsGet() {
|
||||
ctx.Success("text/plain", ctx.Request.URI.URI)
|
||||
} else if ctx.IsPost() {
|
||||
if err := ctx.Request.ParsePostArgs(); err != nil {
|
||||
t.Fatalf("cannot parse post arguments: %s", err)
|
||||
}
|
||||
ctx.SetResponseBody(ctx.Request.Body)
|
||||
}
|
||||
},
|
||||
}
|
||||
ch := make(chan struct{})
|
||||
|
||||
Reference in New Issue
Block a user