urest

package
v0.0.0-...-cc23fee Latest Latest
Warning

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

Go to latest
Published: Mar 1, 2024 License: MIT Imports: 24 Imported by: 0

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func BuildHttpClient

func BuildHttpClient(c *uconfig.Chain) (rv any, err error)

build a http.Client using uconfig

if c is nil, then build default http.Client

func BuildHttpServer

func BuildHttpServer(c *uconfig.Chain) (rv any, err error)

build a http.Server using uconfig

if c is nil, then build default http.Server

func DefaultHttpClient

func DefaultHttpClient() (rv *http.Client)

func DefaultHttpTransport

func DefaultHttpTransport() (rv *http.Transport)

func IsTlsServer

func IsTlsServer(s *http.Server) bool

is the httpServer configured for TLS?

func ShowHttpClient

func ShowHttpClient(name, descr string, help *uconfig.Help) *uconfig.Help

show params available for building http.Client

func ShowHttpServer

func ShowHttpServer(name, descr string, help *uconfig.Help) *uconfig.Help

show params available for building http.Server

func StartServer

func StartServer(svr *http.Server, onDone func(err error))

start listening on a server

func StopServer

func StopServer(svr *http.Server, grace time.Duration)

Types

type Chained

type Chained struct {
	Client   *http.Client
	Request  *http.Request
	Response *http.Response
	Error    error
	// contains filtered or unexported fields
}

a fluent wrapper to deal with http interactions

Example:

_, err := urest.NewChain(nil).Get("http://google.com").IsOK().Done()

var client *http.Client
...
c, err := urest.NewChain(client).
   SetMethod("POST").
   SetUrlString("http://...").
   SetBody(body).
   Do().
   IsOK().
   Done()

c, err := urest.NewChain(client).
   PostAsJson("http://...",thing).
   IsOK().
   BodyJson(&resp).
   Done()

c, err := urest.NewChain(client).
   UploadMultipart("http://...",file,fileParm, ...).
   IsOK().
   Done()

var reqW, respW bytes.Buffer
_, err := urest.NewChain(client).Dump(&reqW,&respW).PostAsJson(url,...

func NewChain

func NewChain(client *http.Client) (rv *Chained)

create a new request chain. if client is nil (not recommended), then use default client.

func (*Chained) BeforeRequest

func (this *Chained) BeforeRequest(f func(req *http.Request) error) *Chained

Perform specialized adjustment of req before making the request

func (*Chained) Body

func (this *Chained) Body(body *[]byte) *Chained

get the body of the response

func (*Chained) BodyCopy

func (this *Chained) BodyCopy(dst io.Writer) *Chained

Copy response body to dst

func (*Chained) BodyIf

func (this *Chained) BodyIf(cond CondF, body *[]byte) *Chained

get the body of the response if cond met

func (*Chained) BodyJson

func (this *Chained) BodyJson(result any) *Chained

decode response body JSON into result

func (*Chained) BodyJsonIf

func (this *Chained) BodyJsonIf(cond CondF, result any) *Chained

decode response body JSON into result if condition met

func (*Chained) BodyText

func (this *Chained) BodyText(result *string) *Chained

decode response body text into result if condition met

func (*Chained) BodyTextIf

func (this *Chained) BodyTextIf(cond CondF, result *string) *Chained

decode response body text into result if condition met

func (*Chained) BodyWrite

func (this *Chained) BodyWrite(dst io.Writer, nwrote *int64) *Chained

Write response body to dst

func (*Chained) Do

func (this *Chained) Do() *Chained

perform the request

func (*Chained) DoRetriably

func (this *Chained) DoRetriably(
	times int,
	delay time.Duration,
	onResp func(*Chained, int) (retry bool, err error),
) (rv *Chained)

Repeatedly perform request until onResp returns false or an error

if times is less than or equal to 0 (zero), then retry indefinitely as long as onResp returns true

onResp gets a ref to this, so must check for Error, Response, etc.

Error will be set if there is a connection problem (see http.Client.Do)

Error will not be set, but Response may indicate a retriable problem with the server (502, 503, 504, ...)

Error will be set to the returned error (if any) of onResp

NOTE: This is primarily for requests that can be replayed, such as GET. or POST/PUT with no Body. The onResp method must perform any required reset.

func (*Chained) Done

func (this *Chained) Done() (rv *Chained, err error)

complete the invocation chain, returning any error encountered

func (*Chained) Dump

func (this *Chained) Dump(reqW, respW io.Writer) *Chained

dump out request and/or response to specified writers. put nil in if you don't want one or the other

func (*Chained) Get

func (this *Chained) Get(url string) *Chained

perform a simple GET

func (*Chained) GetChain

func (this *Chained) GetChain(c **Chained) *Chained

retrieve a reference to the chain

func (*Chained) IfStatusIn

func (this *Chained) IfStatusIn(
	status []int,
	then func(c *Chained) error,
) (rv *Chained)

if return status is one of specified, then invoke func

func (*Chained) IfStatusIs

func (this *Chained) IfStatusIs(
	status int,
	then func(c *Chained) error,
) (rv *Chained)

if return status is as specified, then invoke method

func (*Chained) IsOK

func (this *Chained) IsOK() *Chained

error unless response status OK

func (*Chained) IsOk

func (this *Chained) IsOk() *Chained

error unless response status OK

func (*Chained) IsStatus

func (this *Chained) IsStatus(status int) (rv bool)

func (*Chained) IsStatusIn

func (this *Chained) IsStatusIn(status []int) (rv bool)

func (*Chained) LinkResponseHeaders

func (this *Chained) LinkResponseHeaders(key string) (rv map[string]string)

get Link headers for pagination, returning map of links per rel type.

if key is not set, it will default to "Link"

Link: <https://api.github.com/search/code?q=addClass+user%3Amozilla&page=15>; rel="next",

<https://api.github.com/search/code?q=addClass+user%3Amozilla&page=34>; rel="last",
<https://api.github.com/search/code?q=addClass+user%3Amozilla&page=1>; rel="first",
<https://api.github.com/search/code?q=addClass+user%3Amozilla&page=13>; rel="prev"

func (*Chained) Log

func (this *Chained) Log() *Chained

dump out request and response to log

func (*Chained) LogIf

func (this *Chained) LogIf(on bool) *Chained

func (*Chained) Post

func (this *Chained) Post(url, bodyType string, body io.Reader) *Chained

perform a simple POST

func (*Chained) PostAsJson

func (this *Chained) PostAsJson(url string, body any) *Chained

perform a simple JSON POST

func (*Chained) PostForm

func (this *Chained) PostForm(url string, values *nurl.Values) *Chained

Post URL encoded form data

func (*Chained) ResponseHeaders

func (this *Chained) ResponseHeaders(key string) (rv []string)

Get response header values. There may be multiple header values for the key, and the values may be CSV separated. The spec says that CSV separated values should be treated the same as multiple header/value pairs. Normalize all of that to an array of values.

func (*Chained) SetBasicAuth

func (this *Chained) SetBasicAuth(user, pass string) *Chained

set basic auth info. if user is "", then do not actually set the info

func (*Chained) SetBody

func (this *Chained) SetBody(body io.Reader) *Chained

set the body. setting nil indicates no data in body. the body will be automatically closed

func (*Chained) SetBodyBytes

func (this *Chained) SetBodyBytes(body []byte) *Chained

set the body and content length.

func (*Chained) SetBodyFile

func (this *Chained) SetBodyFile(filename string) *Chained

set the body to the contents (and length) of the specified file

func (*Chained) SetBodyJson

func (this *Chained) SetBodyJson(body any) *Chained

set a JSON body

func (*Chained) SetContentLength

func (this *Chained) SetContentLength(length int64) *Chained

Set the Content-Length HTTP request header

if content length is set to a positive number, then go http will use a LimitReader, which will prevent ReaderFrom/WriterTo optimization

func (*Chained) SetContentType

func (this *Chained) SetContentType(ctype string) *Chained

Set the Content-Type HTTP request header

func (*Chained) SetHeader

func (this *Chained) SetHeader(key, value string, values ...string) *Chained

set the named HTTP request header to the specified value(s)

func (*Chained) SetHeaders

func (this *Chained) SetHeaders(headers map[string]string) *Chained

set the HTTP request headers

func (*Chained) SetMethod

func (this *Chained) SetMethod(method string) *Chained

set the HTTP verb (GET, PUT, POST, DELETE, ...) to use

func (*Chained) SetRawHeader

func (this *Chained) SetRawHeader(key, value string) *Chained

set a header without allowing Go to make the header HTTP compliant, such as capitalizing the header key, etc.

func (*Chained) SetRawHeaders

func (this *Chained) SetRawHeaders(headers map[string]string) *Chained

set headers without allowing Go to make them HTTP compliant, such as capitalizing the header key, etc. Some services are broken and require this.

func (*Chained) SetTimeout

func (this *Chained) SetTimeout(d time.Duration) *Chained

set a timeout to this request

since we create the context, we handle cancelation/cleanup

func (*Chained) SetUrl

func (this *Chained) SetUrl(url *nurl.URL) *Chained

set the URL to use for the request

func (*Chained) SetUrlString

func (this *Chained) SetUrlString(url string) *Chained

set the URL to use for the request

func (*Chained) Status

func (this *Chained) Status(status *int) *Chained

get status if there is a response

func (*Chained) StatusIn

func (this *Chained) StatusIn(status ...int) *Chained

error unless response status is one of the indicated ones

func (*Chained) StatusIs

func (this *Chained) StatusIs(status int) *Chained

error unless response status specified one

func (*Chained) Then

func (this *Chained) Then(f func(c *Chained) error) *Chained

invoke the function after response

func (*Chained) UploadFileMultipart

func (this *Chained) UploadFileMultipart(
	url, fileName, fileField, fileFieldValue string,
	fields map[string]string,
) *Chained

upload a file by posting as a multipart form

a direct post is preferred as it is much more efficient and much easier, but some things require the form based way of doing things.

we stream the file contents to the server instead of assembling the whole multipart message in memory.

func (*Chained) UploadMultipart

func (this *Chained) UploadMultipart(
	url string,
	contentR io.Reader,
	fileField, fileFieldValue string,
	fields map[string]string,
) (rv *Chained)

upload content by posting as a multipart form

a direct post is preferred as it is much more efficient and much easier, but some things require the form based way of doing things.

we stream the content to the server instead of assembling the whole multipart message in memory.

func (*Chained) WithContext

func (this *Chained) WithContext(ctx context.Context) *Chained

add a cancelation context to the request

since the context is provided by caller, it is caller's responsibility to check the context and cancel it, etc...

func (*Chained) WriteTo

func (this *Chained) WriteTo(dst io.Writer) (nwrote int64, err error)

Write response body to dst

implement io.WriterTo

type CondF

type CondF func(*Chained) bool

a function that computes a condition

func StatusIn

func StatusIn(statusen ...int) CondF

produce a CondF to check statusen

func StatusIs

func StatusIs(status int) CondF

produce a CondF to check status

func StatusNot

func StatusNot(status int) CondF

produce a CondF to check !status

func StatusNotIn

func StatusNotIn(statusen ...int) CondF

produce a CondF to check !statusen

Jump to

Keyboard shortcuts

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