gclient

package
v0.0.0-...-b8c7c9f Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jun 26, 2024 License: MIT Imports: 47 Imported by: 0

Documentation

Overview

Package gclient provides convenient http client functionalities.

Index

Examples

Constants

This section is empty.

Variables

This section is empty.

Functions

func LoadKeyCrt

func LoadKeyCrt(crtFile, keyFile string) (*tls.Config, error)

LoadKeyCrt creates and returns a TLS configuration object with given certificate and key files.

Types

type Client

type Client struct {
	http.Client // Underlying HTTP Client.
	// contains filtered or unexported fields
}

Client is the HTTP client for HTTP request management.

func New

func New() *Client

New creates and returns a new HTTP client object.

Example
package main

import (
	"fmt"

	"github.com/xrcn/cg/net/gclient"
	"github.com/xrcn/cg/os/gctx"
)

func main() {
	var (
		ctx    = gctx.New()
		client = gclient.New()
	)

	if r, err := client.Get(ctx, "http://127.0.0.1:8999/var/json"); err != nil {
		panic(err)
	} else {
		defer r.Close()
		fmt.Println(r.ReadAllString())
	}

}
Output:

{"id":1,"name":"john"}

func (*Client) BasicAuth

func (c *Client) BasicAuth(user, pass string) *Client

BasicAuth is a chaining function, which sets HTTP basic authentication information for next request.

func (*Client) Clone

func (c *Client) Clone() *Client

Clone deeply clones current client and returns a new one.

Example
package main

import (
	"fmt"

	"github.com/xrcn/cg/net/gclient"
	"github.com/xrcn/cg/os/gctx"
)

func main() {
	var (
		ctx    = gctx.New()
		client = gclient.New()
	)

	client.SetCookie("key", "value")
	cloneClient := client.Clone()

	if r, err := cloneClient.Get(ctx, "http://127.0.0.1:8999/var/json"); err != nil {
		panic(err)
	} else {
		defer r.Close()
		fmt.Println(r.ReadAllString())
	}

}
Output:

{"id":1,"name":"john"}

func (*Client) Connect

func (c *Client) Connect(ctx context.Context, url string, data ...interface{}) (*Response, error)

Connect send CONNECT request and returns the response object. Note that the response object MUST be closed if it'll never be used.

Example
url := "http://127.0.0.1:8999"
r, _ := g.Client().Connect(ctx, url, g.Map{
	"id":   10000,
	"name": "john",
})
defer r.Close()
fmt.Println(r.ReadAllString())
Output:

CONNECT: form: 10000, john

func (*Client) ConnectBytes

func (c *Client) ConnectBytes(ctx context.Context, url string, data ...interface{}) []byte

ConnectBytes sends a CONNECT request, retrieves and returns the result content as bytes.

Example
url := "http://127.0.0.1:8999"
fmt.Println(string(g.Client().ConnectBytes(ctx, url, g.Map{
	"id":   10000,
	"name": "john",
})))
Output:

CONNECT: form: 10000, john

func (*Client) ConnectContent

func (c *Client) ConnectContent(ctx context.Context, url string, data ...interface{}) string

ConnectContent is a convenience method for sending CONNECT request, which retrieves and returns the result content and automatically closes response object.

Example
url := "http://127.0.0.1:8999"
fmt.Println(g.Client().ConnectContent(ctx, url, g.Map{
	"id":   10000,
	"name": "john",
}))
Output:

CONNECT: form: 10000, john

func (*Client) ConnectVar

func (c *Client) ConnectVar(ctx context.Context, url string, data ...interface{}) *gvar.Var

ConnectVar sends a CONNECT request, retrieves and converts the result content to *gvar.Var. The client reads and closes the response object internally automatically. The result *gvar.Var can be conveniently converted to any type you want.

Example
type User struct {
	Id   int
	Name string
}
var (
	users []User
	url   = "http://127.0.0.1:8999/var/jsons"
)
err := g.Client().ConnectVar(ctx, url).Scan(&users)
if err != nil {
	panic(err)
}
fmt.Println(users)
Output:

[{1 john} {2 smith}]

func (*Client) ContentJson

func (c *Client) ContentJson() *Client

ContentJson is a chaining function, which sets the HTTP content type as "application/json" for the next request.

Note that it also checks and encodes the parameter to JSON format automatically.

Example
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 (*Client) ContentType

func (c *Client) ContentType(contentType string) *Client

ContentType is a chaining function, which sets HTTP content type for the next request.

func (*Client) ContentXml

func (c *Client) ContentXml() *Client

ContentXml is a chaining function, which sets the HTTP content type as "application/xml" for the next request.

Note that it also checks and encodes the parameter to XML format automatically.

func (*Client) Cookie

func (c *Client) Cookie(m map[string]string) *Client

Cookie is a chaining function, which sets cookie items with map for next request.

Example
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 (*Client) Delete

func (c *Client) Delete(ctx context.Context, url string, data ...interface{}) (*Response, error)

Delete send DELETE request and returns the response object. Note that the response object MUST be closed if it'll never be used.

Example
url := "http://127.0.0.1:8999"
r, _ := g.Client().Delete(ctx, url, g.Map{
	"id":   10000,
	"name": "john",
})
defer r.Close()
fmt.Println(r.ReadAllString())
Output:

DELETE: form: 10000, john

func (*Client) DeleteBytes

func (c *Client) DeleteBytes(ctx context.Context, url string, data ...interface{}) []byte

DeleteBytes sends a DELETE request, retrieves and returns the result content as bytes.

Example
url := "http://127.0.0.1:8999"
fmt.Println(string(g.Client().DeleteBytes(ctx, url, g.Map{
	"id":   10000,
	"name": "john",
})))
Output:

DELETE: form: 10000, john

func (*Client) DeleteContent

func (c *Client) DeleteContent(ctx context.Context, url string, data ...interface{}) string

DeleteContent is a convenience method for sending DELETE request, which retrieves and returns the result content and automatically closes response object.

Example
url := "http://127.0.0.1:8999"
fmt.Println(g.Client().DeleteContent(ctx, url, g.Map{
	"id":   10000,
	"name": "john",
}))
Output:

DELETE: form: 10000, john

func (*Client) DeleteVar

func (c *Client) DeleteVar(ctx context.Context, url string, data ...interface{}) *gvar.Var

DeleteVar sends a DELETE request, retrieves and converts the result content to *gvar.Var. The client reads and closes the response object internally automatically. The result *gvar.Var can be conveniently converted to any type you want.

Example
type User struct {
	Id   int
	Name string
}
var (
	users []User
	url   = "http://127.0.0.1:8999/var/jsons"
)
err := g.Client().DeleteVar(ctx, url).Scan(&users)
if err != nil {
	panic(err)
}
fmt.Println(users)
Output:

[{1 john} {2 smith}]

func (*Client) Discovery

func (c *Client) Discovery(discovery gsvc.Discovery) *Client

Discovery is a chaining function, which sets the discovery for client. You can use `Discovery(nil)` to disable discovery feature for current client.

func (*Client) DoRequest

func (c *Client) DoRequest(ctx context.Context, method, url string, data ...interface{}) (resp *Response, err error)

DoRequest sends request with given HTTP method and data and returns the response object. Note that the response object MUST be closed if it'll never be used.

Note that it uses "multipart/form-data" as its Content-Type if it contains file uploading, else it uses "application/x-www-form-urlencoded". It also automatically detects the post content for JSON format, and for that it automatically sets the Content-Type as "application/json".

func (*Client) DoRequestObj

func (c *Client) DoRequestObj(ctx context.Context, req, res interface{}) error

DoRequestObj does HTTP request using standard request/response object. The request object `req` is defined like:

type UseCreateReq struct {
    g.Meta `path:"/user" method:"put"`
    // other fields....
}

The response object `res` should be a pointer type. It automatically converts result to given object `res` is success.

Example: var (

req = UseCreateReq{}
res *UseCreateRes

)

err := DoRequestObj(ctx, req, &res)

func (*Client) Get

func (c *Client) Get(ctx context.Context, url string, data ...interface{}) (*Response, error)

Get send GET request and returns the response object. Note that the response object MUST be closed if it'll never be used.

Example
package main

import (
	"context"
	"fmt"

	"github.com/xrcn/cg/frame/g"
)

func main() {
	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 (*Client) GetBytes

func (c *Client) GetBytes(ctx context.Context, url string, data ...interface{}) []byte

GetBytes sends a GET request, retrieves and returns the result content as bytes.

Example
package main

import (
	"context"
	"fmt"

	"github.com/xrcn/cg/frame/g"
)

func main() {
	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 (*Client) GetContent

func (c *Client) GetContent(ctx context.Context, url string, data ...interface{}) string

GetContent is a convenience method for sending GET request, which retrieves and returns the result content and automatically closes response object.

Example
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 (*Client) GetVar

func (c *Client) GetVar(ctx context.Context, url string, data ...interface{}) *gvar.Var

GetVar sends a GET request, retrieves and converts the result content to *gvar.Var. The client reads and closes the response object internally automatically. The result *gvar.Var can be conveniently converted to any type you want.

Example
package main

import (
	"context"
	"fmt"

	"github.com/xrcn/cg/frame/g"
)

func main() {
	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}

func (*Client) Head

func (c *Client) Head(ctx context.Context, url string, data ...interface{}) (*Response, error)

Head send HEAD request and returns the response object. Note that the response object MUST be closed if it'll never be used.

Example
url := "http://127.0.0.1:8999"
r, _ := g.Client().Head(ctx, url, g.Map{
	"id":   10000,
	"name": "john",
})
defer r.Close()
fmt.Println(r.ReadAllString())
Output:

func (*Client) HeadBytes

func (c *Client) HeadBytes(ctx context.Context, url string, data ...interface{}) []byte

HeadBytes sends a HEAD request, retrieves and returns the result content as bytes.

Example
url := "http://127.0.0.1:8999"
fmt.Println(string(g.Client().HeadBytes(ctx, url, g.Map{
	"id":   10000,
	"name": "john",
})))
Output:

func (*Client) HeadContent

func (c *Client) HeadContent(ctx context.Context, url string, data ...interface{}) string

HeadContent is a convenience method for sending HEAD request, which retrieves and returns the result content and automatically closes response object.

Example
url := "http://127.0.0.1:8999"
fmt.Println(g.Client().HeadContent(ctx, url, g.Map{
	"id":   10000,
	"name": "john",
}))
Output:

func (*Client) HeadVar

func (c *Client) HeadVar(ctx context.Context, url string, data ...interface{}) *gvar.Var

HeadVar sends a HEAD request, retrieves and converts the result content to *gvar.Var. The client reads and closes the response object internally automatically. The result *gvar.Var can be conveniently converted to any type you want.

Example
type User struct {
	Id   int
	Name string
}
var (
	users []User
	url   = "http://127.0.0.1:8999/var/jsons"
)
err := g.Client().HeadVar(ctx, url).Scan(&users)
if err != nil {
	panic(err)
}
fmt.Println(users)
Output:

[]

func (*Client) Header

func (c *Client) Header(m map[string]string) *Client

Header is a chaining function, which sets custom HTTP headers with map for next request.

Example
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 (*Client) HeaderRaw

func (c *Client) HeaderRaw(headers string) *Client

HeaderRaw is a chaining function, which sets custom HTTP header using raw string for next request.

Example
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 (*Client) Next

func (c *Client) Next(req *http.Request) (*Response, error)

Next calls the next middleware. This should only be call in HandlerFunc.

func (*Client) NoUrlEncode

func (c *Client) NoUrlEncode() *Client

NoUrlEncode sets the mark that do not encode the parameters before sending request.

func (*Client) Options

func (c *Client) Options(ctx context.Context, url string, data ...interface{}) (*Response, error)

Options send OPTIONS request and returns the response object. Note that the response object MUST be closed if it'll never be used.

Example
url := "http://127.0.0.1:8999"
r, _ := g.Client().Options(ctx, url, g.Map{
	"id":   10000,
	"name": "john",
})
defer r.Close()
fmt.Println(r.ReadAllString())
Output:

OPTIONS: form: 10000, john

func (*Client) OptionsBytes

func (c *Client) OptionsBytes(ctx context.Context, url string, data ...interface{}) []byte

OptionsBytes sends an OPTIONS request, retrieves and returns the result content as bytes.

Example
url := "http://127.0.0.1:8999"
fmt.Println(string(g.Client().OptionsBytes(ctx, url, g.Map{
	"id":   10000,
	"name": "john",
})))
Output:

OPTIONS: form: 10000, john

func (*Client) OptionsContent

func (c *Client) OptionsContent(ctx context.Context, url string, data ...interface{}) string

OptionsContent is a convenience method for sending OPTIONS request, which retrieves and returns the result content and automatically closes response object.

Example
url := "http://127.0.0.1:8999"
fmt.Println(g.Client().OptionsContent(ctx, url, g.Map{
	"id":   10000,
	"name": "john",
}))
Output:

OPTIONS: form: 10000, john

func (*Client) OptionsVar

func (c *Client) OptionsVar(ctx context.Context, url string, data ...interface{}) *gvar.Var

OptionsVar sends an OPTIONS request, retrieves and converts the result content to *gvar.Var. The client reads and closes the response object internally automatically. The result *gvar.Var can be conveniently converted to any type you want.

Example
type User struct {
	Id   int
	Name string
}
var (
	users []User
	url   = "http://127.0.0.1:8999/var/jsons"
)
err := g.Client().OptionsVar(ctx, url).Scan(&users)
if err != nil {
	panic(err)
}
fmt.Println(users)
Output:

[{1 john} {2 smith}]

func (*Client) Patch

func (c *Client) Patch(ctx context.Context, url string, data ...interface{}) (*Response, error)

Patch send PATCH request and returns the response object. Note that the response object MUST be closed if it'll never be used.

Example
url := "http://127.0.0.1:8999"
r, _ := g.Client().Patch(ctx, url, g.Map{
	"id":   10000,
	"name": "john",
})
defer r.Close()
fmt.Println(r.ReadAllString())
Output:

PATCH: form: 10000, john

func (*Client) PatchBytes

func (c *Client) PatchBytes(ctx context.Context, url string, data ...interface{}) []byte

PatchBytes sends a PATCH request, retrieves and returns the result content as bytes.

Example
url := "http://127.0.0.1:8999"
fmt.Println(string(g.Client().PatchBytes(ctx, url, g.Map{
	"id":   10000,
	"name": "john",
})))
Output:

PATCH: form: 10000, john

func (*Client) PatchContent

func (c *Client) PatchContent(ctx context.Context, url string, data ...interface{}) string

PatchContent is a convenience method for sending PATCH request, which retrieves and returns the result content and automatically closes response object.

Example
url := "http://127.0.0.1:8999"
fmt.Println(g.Client().PatchContent(ctx, url, g.Map{
	"id":   10000,
	"name": "john",
}))
Output:

PATCH: form: 10000, john

func (*Client) PatchVar

func (c *Client) PatchVar(ctx context.Context, url string, data ...interface{}) *gvar.Var

PatchVar sends a PATCH request, retrieves and converts the result content to *gvar.Var. The client reads and closes the response object internally automatically. The result *gvar.Var can be conveniently converted to any type you want.

Example
type User struct {
	Id   int
	Name string
}
var (
	users []User
	url   = "http://127.0.0.1:8999/var/jsons"
)
err := g.Client().PatchVar(ctx, url).Scan(&users)
if err != nil {
	panic(err)
}
fmt.Println(users)
Output:

[{1 john} {2 smith}]

func (*Client) Post

func (c *Client) Post(ctx context.Context, url string, data ...interface{}) (*Response, error)

Post sends request using HTTP method POST and returns the response object. Note that the response object MUST be closed if it'll never be used.

Example
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 (*Client) PostBytes

func (c *Client) PostBytes(ctx context.Context, url string, data ...interface{}) []byte

PostBytes sends a POST request, retrieves and returns the result content as bytes.

Example
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 (*Client) PostContent

func (c *Client) PostContent(ctx context.Context, url string, data ...interface{}) string

PostContent is a convenience method for sending POST request, which retrieves and returns the result content and automatically closes response object.

Example
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 (*Client) PostForm

func (c *Client) PostForm(ctx context.Context, url string, data map[string]string) (resp *Response, err error)

PostForm is different from net/http.PostForm. It's a wrapper of Post method, which sets the Content-Type as "multipart/form-data;". and It will automatically set boundary characters for the request body and Content-Type.

It's Seem like the following case:

Content-Type: multipart/form-data; boundary=----Boundarye4Ghaog6giyQ9ncN

And form data is like: ------Boundarye4Ghaog6giyQ9ncN Content-Disposition: form-data; name="checkType"

none

It's used for sending form data. Note that the response object MUST be closed if it'll never be used.

func (*Client) PostVar

func (c *Client) PostVar(ctx context.Context, url string, data ...interface{}) *gvar.Var

PostVar sends a POST request, retrieves and converts the result content to *gvar.Var. The client reads and closes the response object internally automatically. The result *gvar.Var can be conveniently converted to any type you want.

Example
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 (*Client) Prefix

func (c *Client) Prefix(prefix string) *Client

Prefix is a chaining function, which sets the URL prefix for next request of this client. Eg: Prefix("http://127.0.0.1:8199/api/v1") Prefix("http://127.0.0.1:8199/api/v2")

Example
package main

import (
	"fmt"
	"time"

	"github.com/xrcn/cg/frame/g"
	"github.com/xrcn/cg/net/ghttp"
	"github.com/xrcn/cg/os/gctx"
	"github.com/xrcn/cg/util/guid"
)

func main() {
	var (
		ctx = gctx.New()
	)

	s := g.Server(guid.S())
	// HTTP method handlers.
	s.Group("/api", func(group *ghttp.RouterGroup) {
		group.GET("/v1/prefix", func(r *ghttp.Request) {
			r.Response.Write("this is v1 prefix")
		})
		group.GET("/v1/hello", func(r *ghttp.Request) {
			r.Response.Write("this is v1 hello")
		})
	})
	s.SetAccessLogEnabled(false)
	s.SetDumpRouterMap(false)
	s.Start()
	time.Sleep(time.Millisecond * 100)

	// Add Client URI Prefix
	client := g.Client().Prefix(fmt.Sprintf(
		"http://127.0.0.1:%d/api/v1/", s.GetListenedPort(),
	))

	fmt.Println(string(client.GetBytes(ctx, "prefix")))
	fmt.Println(string(client.GetBytes(ctx, "hello")))

}
Output:

this is v1 prefix
this is v1 hello

func (*Client) Proxy

func (c *Client) Proxy(proxyURL string) *Client

Proxy is a chaining function, which sets proxy for next request. Make sure you pass the correct `proxyURL`. The correct pattern is like `http://USER:PASSWORD@IP:PORT` or `socks5://USER:PASSWORD@IP:PORT`. Only `http` and `socks5` proxies are supported currently.

Example

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

package main

import (
	"context"
	"fmt"
	"time"

	"github.com/xrcn/cg/frame/g"
	"github.com/xrcn/cg/net/ghttp"
)

func init() {

	p := 8999
	s := g.Server(p)

	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.Writef(
				"HEAD: form: %d, %s",
				r.GetForm("id").Int(),
				r.GetForm("name").String(),
			)
		})
		group.PATCH("/", func(r *ghttp.Request) {
			r.Response.Writef(
				"PATCH: form: %d, %s",
				r.GetForm("id").Int(),
				r.GetForm("name").String(),
			)
		})
		group.CONNECT("/", func(r *ghttp.Request) {
			r.Response.Writef(
				"CONNECT: form: %d, %s",
				r.GetForm("id").Int(),
				r.GetForm("name").String(),
			)
		})
		group.OPTIONS("/", func(r *ghttp.Request) {
			r.Response.Writef(
				"OPTIONS: form: %d, %s",
				r.GetForm("id").Int(),
				r.GetForm("name").String(),
			)
		})
		group.TRACE("/", func(r *ghttp.Request) {
			r.Response.Writef(
				"TRACE: form: %d, %s",
				r.GetForm("id").Int(),
				r.GetForm("name").String(),
			)
		})
	})

	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(),
			)
		})
	})

	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 main() {
	var (
		ctx = context.Background()
	)
	client := g.Client()
	_, err := client.Proxy("http://127.0.0.1:1081").Get(ctx, "http://127.0.0.1:8999")
	fmt.Println(err != nil)

	client2 := g.Client()
	_, err = client2.Proxy("socks5://127.0.0.1:1080").Get(ctx, "http://127.0.0.1:8999")
	fmt.Println(err != nil)

	client3 := g.Client()
	_, err = client3.Proxy("").Get(ctx, "http://127.0.0.1:8999")
	fmt.Println(err != nil)

	client4 := g.Client()
	url := "http://127.0.0.1:1081" + string([]byte{0x7f})
	_, err = client4.Proxy(url).Get(ctx, "http://127.0.0.1:8999")
	fmt.Println(err != nil)

}
Output:

true
true
false
false

func (*Client) Put

func (c *Client) Put(ctx context.Context, url string, data ...interface{}) (*Response, error)

Put send PUT request and returns the response object. Note that the response object MUST be closed if it'll never be used.

Example
url := "http://127.0.0.1:8999"
r, _ := g.Client().Put(ctx, url, g.Map{
	"id":   10000,
	"name": "john",
})
defer r.Close()
fmt.Println(r.ReadAllString())
Output:

PUT: form: 10000, john

func (*Client) PutBytes

func (c *Client) PutBytes(ctx context.Context, url string, data ...interface{}) []byte

PutBytes sends a PUT request, retrieves and returns the result content as bytes.

Example
package main

import (
	"context"
	"fmt"

	"github.com/xrcn/cg/frame/g"
)

func main() {
	var (
		ctx = context.Background()
		url = "http://127.0.0.1:8999"
	)
	fmt.Println(string(g.Client().PutBytes(ctx, url, g.Map{
		"id":   10000,
		"name": "john",
	})))

}
Output:

PUT: form: 10000, john

func (*Client) PutContent

func (c *Client) PutContent(ctx context.Context, url string, data ...interface{}) string

PutContent is a convenience method for sending PUT request, which retrieves and returns the result content and automatically closes response object.

Example
url := "http://127.0.0.1:8999"
fmt.Println(g.Client().PutContent(ctx, url, g.Map{
	"id":   10000,
	"name": "john",
}))
Output:

PUT: form: 10000, john

func (*Client) PutVar

func (c *Client) PutVar(ctx context.Context, url string, data ...interface{}) *gvar.Var

PutVar sends a PUT request, retrieves and converts the result content to *gvar.Var. The client reads and closes the response object internally automatically. The result *gvar.Var can be conveniently converted to any type you want.

Example
package main

import (
	"context"
	"fmt"

	"github.com/xrcn/cg/frame/g"
)

func main() {
	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().PutVar(ctx, url).Scan(&user)
	if err != nil {
		panic(err)
	}
	fmt.Println(user)

}
Output:

&{1 john}

func (*Client) RedirectLimit

func (c *Client) RedirectLimit(redirectLimit int) *Client

RedirectLimit is a chaining function, which sets the redirect limit the number of jumps for the request.

Example
package main

import (
	"fmt"

	"github.com/xrcn/cg/frame/g"
	"github.com/xrcn/cg/os/gctx"
)

func main() {
	var (
		ctx = gctx.New()
		url = "http://127.0.0.1:8999"
	)
	client := g.Client().RedirectLimit(1)

	fmt.Println(string(client.GetBytes(ctx, url, g.Map{
		"id":   10000,
		"name": "john",
	})))

}
Output:

GET: query: 10000, john

func (*Client) RequestBytes

func (c *Client) RequestBytes(ctx context.Context, method string, url string, data ...interface{}) []byte

RequestBytes sends request using given HTTP method and data, retrieves returns the result as bytes. It reads and closes the response object internally automatically.

func (*Client) RequestContent

func (c *Client) RequestContent(ctx context.Context, method string, url string, data ...interface{}) string

RequestContent is a convenience method for sending custom http method request, which retrieves and returns the result content and automatically closes response object.

Example
url := "http://127.0.0.1:8999"
fmt.Println(g.Client().RequestContent(ctx, http.MethodGet, url, g.Map{
	"id":   10000,
	"name": "john",
}))
Output:

GET: query: 10000, john

func (*Client) RequestVar

func (c *Client) RequestVar(ctx context.Context, method string, url string, data ...interface{}) *gvar.Var

RequestVar sends request using given HTTP method and data, retrieves converts the result to *gvar.Var. The client reads and closes the response object internally automatically. The result *gvar.Var can be conveniently converted to any type you want.

func (*Client) Retry

func (c *Client) Retry(retryCount int, retryInterval time.Duration) *Client

Retry is a chaining function, which sets retry count and interval when failure for next request.

Example
package main

import (
	"fmt"
	"time"

	"github.com/xrcn/cg/frame/g"
	"github.com/xrcn/cg/os/gctx"
)

func main() {
	var (
		ctx = gctx.New()
		url = "http://127.0.0.1:8999"
	)
	client := g.Client().Retry(2, time.Second)

	fmt.Println(string(client.GetBytes(ctx, url, g.Map{
		"id":   10000,
		"name": "john",
	})))

}
Output:

GET: query: 10000, john

func (*Client) SetAgent

func (c *Client) SetAgent(agent string) *Client

SetAgent sets the User-Agent header for client.

func (*Client) SetBasicAuth

func (c *Client) SetBasicAuth(user, pass string) *Client

SetBasicAuth sets HTTP basic authentication information for the client.

func (*Client) SetBrowserMode

func (c *Client) SetBrowserMode(enabled bool) *Client

SetBrowserMode enables browser mode of the client. When browser mode is enabled, it automatically saves and sends cookie content from and to server.

Example
package main

import (
	"fmt"

	"github.com/xrcn/cg/frame/g"
	"github.com/xrcn/cg/os/gctx"
)

func main() {
	var (
		ctx = gctx.New()
		url = "http://127.0.0.1:8999"
	)
	client := g.Client().SetBrowserMode(true)

	fmt.Println(string(client.GetBytes(ctx, url, g.Map{
		"id":   10000,
		"name": "john",
	})))

}
Output:

GET: query: 10000, john

func (*Client) SetBuilder

func (c *Client) SetBuilder(builder gsel.Builder)

SetBuilder sets the load balance builder for client.

func (*Client) SetContentType

func (c *Client) SetContentType(contentType string) *Client

SetContentType sets HTTP content type for the client.

func (*Client) SetCookie

func (c *Client) SetCookie(key, value string) *Client

SetCookie sets a cookie pair for the client.

func (*Client) SetCookieMap

func (c *Client) SetCookieMap(m map[string]string) *Client

SetCookieMap sets cookie items with map.

func (*Client) SetDiscovery

func (c *Client) SetDiscovery(discovery gsvc.Discovery)

SetDiscovery sets the load balance builder for client.

func (*Client) SetHeader

func (c *Client) SetHeader(key, value string) *Client

SetHeader sets a custom HTTP header pair for the client.

Example
package main

import (
	"fmt"

	"github.com/xrcn/cg/frame/g"
	"github.com/xrcn/cg/os/gctx"
)

func main() {
	var (
		ctx = gctx.New()
		url = "http://127.0.0.1:8999"
	)
	client := g.Client()
	client.SetHeader("Server", "GoXrcServer")
	client.SetHeader("Client", "g.Client()")

	fmt.Println(string(client.GetBytes(ctx, url, g.Map{
		"id":   10000,
		"name": "john",
	})))

}
Output:

GET: query: 10000, john

func (*Client) SetHeaderMap

func (c *Client) SetHeaderMap(m map[string]string) *Client

SetHeaderMap sets custom HTTP headers with map.

func (*Client) SetHeaderRaw

func (c *Client) SetHeaderRaw(headers string) *Client

SetHeaderRaw sets custom HTTP header using raw string.

func (*Client) SetNoUrlEncode

func (c *Client) SetNoUrlEncode(noUrlEncode bool) *Client

SetNoUrlEncode sets the mark that do not encode the parameters before sending request.

func (*Client) SetPrefix

func (c *Client) SetPrefix(prefix string) *Client

SetPrefix sets the request server URL prefix.

func (*Client) SetProxy

func (c *Client) SetProxy(proxyURL string)

SetProxy set proxy for the client. This func will do nothing when the parameter `proxyURL` is empty or in wrong pattern. The correct pattern is like `http://USER:PASSWORD@IP:PORT` or `socks5://USER:PASSWORD@IP:PORT`. Only `http` and `socks5` proxies are supported currently.

Example

ExampleClient_SetProxy an 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`

// connect to an 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
resp, err := client.Get(ctx, "http://127.0.0.1:8999")
if err != nil {
	// err is not nil when your proxy server is down.
	// eg. Get "http://127.0.0.1:8999": proxyconnect tcp: dial tcp 127.0.0.1:1087: connect: connection refused
}
fmt.Println(err != nil)
resp.Close()

// connect to an 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
resp, err = client.Get(ctx, "http://127.0.0.1:8999")
if err != nil {
	// err is not nil when your proxy server is down.
	// eg. Get "http://127.0.0.1:8999": proxyconnect tcp: dial tcp 127.0.0.1:1087: connect: connection refused
}
fmt.Println(err != nil)
resp.Close()

// 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
resp, err = client.Get(ctx, "http://127.0.0.1:8999")
if err != nil {
	// err is not nil when your proxy server is down.
	// eg. Get "http://127.0.0.1:8999": 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 != nil)
resp.Close()

// 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
resp, err = client.Get(ctx, "http://127.0.0.1:8999")
if err != nil {
	// err is not nil when your proxy server is down.
	// eg. Get "http://127.0.0.1:8999": 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 != nil)
resp.Close()
Output:

true
true
true
true

func (*Client) SetRedirectLimit

func (c *Client) SetRedirectLimit(redirectLimit int) *Client

SetRedirectLimit limits the number of jumps.

Example
package main

import (
	"fmt"
	"net/http"
	"time"

	"github.com/xrcn/cg/frame/g"
	"github.com/xrcn/cg/net/ghttp"
	"github.com/xrcn/cg/os/gctx"
)

func main() {
	go func() {
		s := g.Server()
		s.BindHandler("/hello", func(r *ghttp.Request) {
			r.Response.Writeln("hello world")
		})
		s.BindHandler("/back", func(r *ghttp.Request) {
			r.Response.RedirectBack()
		})
		s.SetDumpRouterMap(false)
		s.SetPort(8199)
		s.Run()
	}()

	time.Sleep(time.Second)

	var (
		ctx      = gctx.New()
		urlHello = "http://127.0.0.1:8199/hello"
		urlBack  = "http://127.0.0.1:8199/back"
	)
	client := g.Client().SetRedirectLimit(1)
	client.SetHeader("Referer", urlHello)

	resp, err := client.DoRequest(ctx, http.MethodGet, urlBack, g.Map{
		"id":   10000,
		"name": "john",
	})
	if err == nil {
		fmt.Println(resp.ReadAllString())
		resp.Close()
	}

	client.SetRedirectLimit(2)
	resp, err = client.DoRequest(ctx, http.MethodGet, urlBack, g.Map{
		"id":   10000,
		"name": "john",
	})
	if err == nil {
		fmt.Println(resp.ReadAllString())
		resp.Close()
	}

}
Output:

Found
hello world

func (*Client) SetRetry

func (c *Client) SetRetry(retryCount int, retryInterval time.Duration) *Client

SetRetry sets retry count and interval.

func (*Client) SetTLSConfig

func (c *Client) SetTLSConfig(tlsConfig *tls.Config) error

SetTLSConfig sets the TLS configuration of client.

Example
package main

import (
	"crypto/tls"
	"fmt"

	"github.com/xrcn/cg/frame/g"
	"github.com/xrcn/cg/os/gctx"
)

func main() {
	var (
		ctx       = gctx.New()
		url       = "http://127.0.0.1:8999"
		tlsConfig = &tls.Config{}
	)
	client := g.Client()
	client.SetTLSConfig(tlsConfig)
	fmt.Println(string(client.GetBytes(ctx, url, g.Map{
		"id":   10000,
		"name": "john",
	})))

}
Output:

GET: query: 10000, john

func (*Client) SetTLSKeyCrt

func (c *Client) SetTLSKeyCrt(crtFile, keyFile string) error

SetTLSKeyCrt sets the certificate and key file for TLS configuration of client.

Example
package main

import (
	"fmt"

	"github.com/xrcn/cg/debug/gdebug"
	"github.com/xrcn/cg/frame/g"
	"github.com/xrcn/cg/os/gctx"
	"github.com/xrcn/cg/os/gfile"
)

var (
	crtFile = gfile.Dir(gdebug.CallerFilePath()) + gfile.Separator + "testdata/server.crt"
	keyFile = gfile.Dir(gdebug.CallerFilePath()) + gfile.Separator + "testdata/server.key"
)

func main() {
	var (
		ctx         = gctx.New()
		url         = "http://127.0.0.1:8999"
		testCrtFile = gfile.Dir(gdebug.CallerFilePath()) + gfile.Separator + "testdata/upload/file1.txt"
		testKeyFile = gfile.Dir(gdebug.CallerFilePath()) + gfile.Separator + "testdata/upload/file2.txt"
	)
	client := g.Client()
	client.SetTLSKeyCrt(testCrtFile, testKeyFile)
	client.SetTLSKeyCrt(crtFile, keyFile)
	fmt.Println(string(client.GetBytes(ctx, url, g.Map{
		"id":   10000,
		"name": "john",
	})))

}
Output:

GET: query: 10000, john

func (*Client) SetTimeout

func (c *Client) SetTimeout(t time.Duration) *Client

SetTimeout sets the request timeout for the client.

func (*Client) Timeout

func (c *Client) Timeout(t time.Duration) *Client

Timeout is a chaining function, which sets the timeout for next request.

func (*Client) Trace

func (c *Client) Trace(ctx context.Context, url string, data ...interface{}) (*Response, error)

Trace send TRACE request and returns the response object. Note that the response object MUST be closed if it'll never be used.

Example
url := "http://127.0.0.1:8999"
r, _ := g.Client().Trace(ctx, url, g.Map{
	"id":   10000,
	"name": "john",
})
defer r.Close()
fmt.Println(r.ReadAllString())
Output:

TRACE: form: 10000, john

func (*Client) TraceBytes

func (c *Client) TraceBytes(ctx context.Context, url string, data ...interface{}) []byte

TraceBytes sends a TRACE request, retrieves and returns the result content as bytes.

Example
url := "http://127.0.0.1:8999"
fmt.Println(string(g.Client().TraceBytes(ctx, url, g.Map{
	"id":   10000,
	"name": "john",
})))
Output:

TRACE: form: 10000, john

func (*Client) TraceContent

func (c *Client) TraceContent(ctx context.Context, url string, data ...interface{}) string

TraceContent is a convenience method for sending TRACE request, which retrieves and returns the result content and automatically closes response object.

Example
url := "http://127.0.0.1:8999"
fmt.Println(g.Client().TraceContent(ctx, url, g.Map{
	"id":   10000,
	"name": "john",
}))
Output:

TRACE: form: 10000, john

func (*Client) TraceVar

func (c *Client) TraceVar(ctx context.Context, url string, data ...interface{}) *gvar.Var

TraceVar sends a TRACE request, retrieves and converts the result content to *gvar.Var. The client reads and closes the response object internally automatically. The result *gvar.Var can be conveniently converted to any type you want.

Example
type User struct {
	Id   int
	Name string
}
var (
	users []User
	url   = "http://127.0.0.1:8999/var/jsons"
)
err := g.Client().TraceVar(ctx, url).Scan(&users)
if err != nil {
	panic(err)
}
fmt.Println(users)
Output:

[{1 john} {2 smith}]

func (*Client) Use

func (c *Client) Use(handlers ...HandlerFunc) *Client

Use adds one or more middleware handlers to client.

type HandlerFunc

type HandlerFunc = func(c *Client, r *http.Request) (*Response, error)

HandlerFunc middleware handler func

type Response

type Response struct {
	*http.Response // Response is the underlying http.Response object of certain request.
	// contains filtered or unexported fields
}

Response is the struct for client request response.

func (*Response) Close

func (r *Response) Close() error

Close closes the response when it will never be used.

func (*Response) GetCookie

func (r *Response) GetCookie(key string) string

GetCookie retrieves and returns the cookie value of specified `key`.

func (*Response) GetCookieMap

func (r *Response) GetCookieMap() map[string]string

GetCookieMap retrieves and returns a copy of current cookie values map.

func (*Response) Raw

func (r *Response) Raw() string

Raw returns the raw text of the request and the response.

func (*Response) RawDump

func (r *Response) RawDump()

RawDump outputs the raw text of the request and the response to stdout.

func (*Response) RawRequest

func (r *Response) RawRequest() string

RawRequest returns the raw content of the request.

func (*Response) RawResponse

func (r *Response) RawResponse() string

RawResponse returns the raw content of the response.

func (*Response) ReadAll

func (r *Response) ReadAll() []byte

ReadAll retrieves and returns the response content as []byte.

func (*Response) ReadAllString

func (r *Response) ReadAllString() string

ReadAllString retrieves and returns the response content as string.

func (*Response) SetBodyContent

func (r *Response) SetBodyContent(content []byte)

SetBodyContent overwrites response content with custom one.

type WebSocketClient

type WebSocketClient struct {
	*websocket.Dialer
}

WebSocketClient wraps the underlying websocket client connection and provides convenient functions.

func NewWebSocket

func NewWebSocket() *WebSocketClient

NewWebSocket creates and returns a new WebSocketClient object.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL