Documentation ¶
Overview ¶
Package ctxclient offers utilities for handling the selection and creation of http.Clients based on the context. This borrows from ideas found in golang.org/x/oauth2.
Usage example:
import ( "github.com/jfcote87/ctxclient" ) ... var clf *ctxclient.Func req, _ := http.NewRequest("GET","http://example.com",nil) res, err := clf.Do(req) ...
Example (Func) ¶
package main import ( "context" "errors" "log" "net/http" "github.com/jfcote87/ctxclient" ) func main() { var clfunc ctxclient.Func = func(ctx context.Context) (*http.Client, error) { k, _ := ctx.Value(UserKey).(string) if k == "" { return nil, errors.New("no user key provided in context") // or to use the default client instead: // return nil, ctxclient.ErrUseDefault } return &http.Client{Transport: &UserKeyTransport{UserKey: k}}, nil } ctx := context.WithValue(context.Background(), UserKey, "USER_GUID") req, _ := http.NewRequest("GET", "http://example.com", nil) res, err := clfunc.Do(ctx, req) switch ex := err.(type) { case *ctxclient.NotSuccess: log.Printf("server returned %s status: %s", ex.StatusMessage, ex.Body) case nil: log.Printf("successful server response %s", res.Status) default: log.Printf("Transport error: %v", err) } } var UserKey userKey type userKey struct{} type UserKeyTransport struct { UserKey string } func (t *UserKeyTransport) RoundTrip(r *http.Request) (*http.Response, error) { h := make(http.Header) for k, v := range r.Header { h[k] = v } newReq := *r h.Set("X-USERKEY", t.UserKey) newReq.Header = h return http.DefaultTransport.RoundTrip(&newReq) }
Output:
Example (Func_nil) ¶
package main import ( "context" "log" "net/http" "github.com/jfcote87/ctxclient" ) func main() { ctx := context.Background() var clfunc ctxclient.Func req, _ := http.NewRequest("GET", "http://example.com", nil) res, err := clfunc.Do(ctx, req) switch ex := err.(type) { case *ctxclient.NotSuccess: log.Printf("server returned %s status: %s", ex.StatusMessage, ex.Body) case nil: log.Printf("successful server response %s", res.Status) default: log.Printf("transport error: %v", err) } }
Output:
Example (Register) ¶
package main import ( "context" "net/http" "github.com/jfcote87/ctxclient" ) func main() { // should be done during a package init() var clfunc ctxclient.Func = func(ctx context.Context) (*http.Client, error) { k, _ := ctx.Value(UserKey).(string) if k == "" { return nil, ctxclient.ErrUseDefault // use default instead } return &http.Client{Transport: &UserKeyTransport{UserKey: k}}, nil } ctxclient.RegisterFunc(clfunc) } var UserKey userKey type userKey struct{} type UserKeyTransport struct { UserKey string } func (t *UserKeyTransport) RoundTrip(r *http.Request) (*http.Response, error) { h := make(http.Header) for k, v := range r.Header { h[k] = v } newReq := *r h.Set("X-USERKEY", t.UserKey) newReq.Header = h return http.DefaultTransport.RoundTrip(&newReq) }
Output:
Index ¶
- Variables
- func Client(ctx context.Context) *http.Client
- func Do(ctx context.Context, req *http.Request) (*http.Response, error)
- func Error(cl *http.Client) error
- func PostForm(ctx context.Context, url string, payload url.Values) (*http.Response, error)
- func RegisterFunc(f Func)
- func RequestError(req *http.Request, err error) (*http.Response, error)
- func Transport(ctx context.Context) http.RoundTripper
- type ErrorTransport
- type Func
- func (f Func) Client(ctx context.Context) *http.Client
- func (f Func) Do(ctx context.Context, req *http.Request) (*http.Response, error)
- func (f Func) Get(ctx context.Context, url string) (*http.Response, error)
- func (f Func) PostForm(ctx context.Context, url string, payload url.Values) (*http.Response, error)
- type NotSuccess
Examples ¶
Constants ¶
This section is empty.
Variables ¶
var ErrUseDefault *useDefault
ErrUseDefault should be returned as the error from a ctxclient.Func when wishing to use the default client determined by the ctxclient package.
Functions ¶
func Client ¶
Client retrieves the default client. If an error occurs, the error will be stored as an ErrorTransport in the client. The error will be returned on all calls the client makes.
func Do ¶
Do sends the request using the default client and checks for timeout/cancellation. Returns *NotSuccess error if response status is not 2xx. ctx must be non-nil
func RegisterFunc ¶
func RegisterFunc(f Func)
RegisterFunc adds f to the list of Funcs checked by the Default Func. This should only be called during init as it is not thread safe.
func RequestError ¶
RequestError is a helper func to use in RoundTripper interfaces. Closes request body, checking for nils to you don't have to.
Types ¶
type ErrorTransport ¶
type ErrorTransport struct{ Err error }
ErrorTransport returns the pass error on RoundTrip call. This RoundTripper should be used in cases where error handling can be postponed due to short response handling time.
type Func ¶
Func returns an http.Client pointer.
func (Func) Client ¶
Client retrieves the Func's client. If an error occurs, the error will be stored as an ErrorTransport in the client. The error will be returned on all calls the client makes.
func (Func) Do ¶
Do sends the request using the calculated client and checks for timeout/cancellation. Returns *NotSuccess if response status is not 2xx. ctx must be non-nil