urest

package
v0.0.0-...-969647d Latest Latest
Warning

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

Go to latest
Published: Dec 23, 2024 License: MIT Imports: 23 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 CloneHttpClient

func CloneHttpClient(prototype *http.Client) (rv *http.Client)

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 CondF

type CondF func(*Requestor) 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

type Part

type Part struct {
	FileField   string    // field name for filename to use in multipart mime part
	FileName    string    // filename (basename) to use in multipart mime part
	ContentType string    // if blank, application/octet-stream
	ContentR    io.Reader // where the bytes are
	Len         int64     // bytes to read from ContentR
}

Use with UploadMultiparts. See RFC 2045, 2046.

type Requestor

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

a fluent wrapper to deal with http interactions

Example:

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

var client *http.Client
...
c, err := urest.NewRequestor(client).
   SetUrlString("http://...").
   SetBody(body).
   Post().
   IsOK().
   Done()

var pMyStruct *MyStruct
c, err := urest.NewRequestor(client).
   SetUrlString("http://...").
   SetBodyJson(thing).
   Post().
   IsOK().
   BodyJson(&pMyStruct). // address of ptr
   Done()

c, err := urest.NewRequestor(client).
   SetUrlString("http://...").
   PostMultipart(file,fileParm, ...).
   IsOK().
   Done()

var reqW, respW bytes.Buffer
_, err := urest.NewRequestor(client).Dump(&reqW,&respW).PostJson(...

func NewRequestor

func NewRequestor(client *http.Client) (this *Requestor)

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

func (*Requestor) BeforeRequest

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

Perform specialized adjustment of req before making the request

func (*Requestor) Body

func (this *Requestor) Body(body *io.Reader) *Requestor

in a call chain, get the body of the response

func (*Requestor) BodyBytes

func (this *Requestor) BodyBytes(body *[]byte) *Requestor

get the body of the response as []byte

func (*Requestor) BodyBytesIf

func (this *Requestor) BodyBytesIf(cond CondF, body *[]byte) *Requestor

get the body of the response as []byte if cond met

func (*Requestor) BodyCopy

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

Copy response body to dst

func (*Requestor) BodyJson

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

decode response body JSON into result. result should be a ptr to the struct to fill in, or a ptr to ptr.

func (*Requestor) BodyJsonIf

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

decode response body JSON into result if condition met. result should be a ptr to the struct to fill in, or a ptr to ptr.

func (*Requestor) BodyLen

func (this *Requestor) BodyLen(length *int64) *Requestor

in a call chain, get the size of the response body

func (*Requestor) BodyText

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

decode response body text into result if condition met

func (*Requestor) BodyTextIf

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

decode response body text into result if condition met

func (*Requestor) Delete

func (this *Requestor) Delete() *Requestor

perform a DELETE - use in place of SetMethod("DELETE").Do()

func (*Requestor) Do

func (this *Requestor) Do() *Requestor

perform the request

func (*Requestor) DoRetriably

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

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 (*Requestor) Done

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

complete the invocation chain, returning any error encountered

func (*Requestor) Dump

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

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

func (*Requestor) Get

func (this *Requestor) Get() *Requestor

perform a GET - use in place of SetMethod("GET").Do()

func (*Requestor) GetBody

func (this *Requestor) GetBody() (bodyLength int64, body io.Reader, err error)

get the body of the response and the length of it (if known. if not known, then length will be negative

func (*Requestor) GetError

func (this *Requestor) GetError() error

get the recorded error, if any

func (*Requestor) GetResponseHeaders

func (this *Requestor) GetResponseHeaders(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 (*Requestor) GetStatus

func (this *Requestor) GetStatus() (status int, err error)

get status (only valid after response)

func (*Requestor) Head

func (this *Requestor) Head() *Requestor

perform a HEAD - use in place of SetMethod("HEAD").Do()

func (*Requestor) IfStatusIn

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

if return status is one of specified, then invoke func

func (*Requestor) IfStatusIs

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

if return status is as specified, then invoke method

func (*Requestor) IsOK

func (this *Requestor) IsOK() *Requestor

error unless response status OK

func (*Requestor) IsOk

func (this *Requestor) IsOk() *Requestor

error unless response status OK

func (*Requestor) IsStatus

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

func (*Requestor) IsStatusIn

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

func (*Requestor) LinkResponseHeaders

func (this *Requestor) 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 (*Requestor) Log

func (this *Requestor) Log() *Requestor

dump out request and response to log

func (*Requestor) LogIf

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

func (*Requestor) Patch

func (this *Requestor) Patch() *Requestor

perform a PATCH - use in place of SetMethod("PATCH").Do()

func (*Requestor) Post

func (this *Requestor) Post() *Requestor

perform a POST - use in place of SetMethod("POST").Do()

func (*Requestor) PostFileMultipart

func (this *Requestor) PostFileMultipart(
	fileName, fileField, fileFieldValue string,
	fields map[string]string,
) *Requestor

Upload the named file using the multipart/form_data method.

The file will be openned and streamed to the server.

If ContentLength is not set, this will fill in the correct value.

If fileFieldValue is not set, then it will be set to filepath.Base(fileName)

func (*Requestor) PostForm

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

Post URL encoded form (application/x-www-form-urlencoded)

func (*Requestor) PostMultipart

func (this *Requestor) PostMultipart(
	contentR io.Reader,
	fileField, fileName string,
	fields map[string]string,
) (rv *Requestor)

Upload content by posting multipart/form-data.

See RFC 2045, 2046.

A direct post is preferred as it is more efficient and simpler, 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.

If you SetContentLength ahead of this, then this will adjust the Content-Length to account for the form data. otherwise, Content-Length will be -1.

fileName should be the basename of the file.

func (*Requestor) PostMultiparts

func (this *Requestor) PostMultiparts(
	fields map[string]string,
	parts ...Part,
) (rv *Requestor)

Upload content from multiple io.Readers in one multipart/form-data POST

See RFC 2045, 2046.

A direct post is preferred as it is more efficient and simpler, 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 (*Requestor) Put

func (this *Requestor) Put() *Requestor

perform a PUT - use in place of SetMethod("PUT").Do()

func (*Requestor) Reset

func (this *Requestor) Reset() *Requestor

reset for reuse - only safe after Done() called.

func (*Requestor) SetBasicAuth

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

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

func (*Requestor) SetBody

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

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

func (*Requestor) SetBodyBytes

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

set the body and content length.

func (*Requestor) SetBodyFile

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

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

func (*Requestor) SetBodyJson

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

set a JSON body

func (*Requestor) SetContentLength

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

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 (*Requestor) SetContentType

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

Set the Content-Type HTTP request header

func (*Requestor) SetHeader

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

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

func (*Requestor) SetHeaders

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

set the HTTP request headers

func (*Requestor) SetMethod

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

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

func (*Requestor) SetRawHeader

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

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

func (*Requestor) SetRawHeaders

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

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

func (*Requestor) SetTimeout

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

set a timeout to this request

since we create the context, we handle cancelation/cleanup

func (*Requestor) SetUrl

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

set the URL to use for the request

func (*Requestor) SetUrlString

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

set the URL to use for the request, parsing the provided string into a URL

func (*Requestor) Status

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

get status as part of a call chain, if there is a response

func (*Requestor) StatusIn

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

error unless response status is one of the indicated ones

func (*Requestor) StatusIs

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

error unless response status specified one

func (*Requestor) Then

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

invoke the function (only valid after response)

func (*Requestor) WithContext

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

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...

Jump to

Keyboard shortcuts

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