gr

package module
v0.1.13 Latest Latest
Warning

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

Go to latest
Published: Aug 31, 2023 License: Unlicense Imports: 17 Imported by: 0

README

Overview

"gr" stands for for Go Request or Go Request-Response. It also represents my reaction to many APIs in "net/http". Shortcuts for making HTTP requests and reading HTTP responses. Features:

  • Brevity!
  • No added wrappers or interfaces. Just aliases for http.Request and http.Response, freely-castable back and forth.
  • Fluent chainable builder API.
  • Most methods are nullary or unary. No syntactic overhead for features you don't use.
  • No overhead over "lower-level" uses of http.Request and http.Response. Many shortcuts are more performant than "standard" approaches.
  • Resulting requests can be passed to any code that takes http.Request.
  • Usable for http.Response responses obtained from any source.
  • Tiny and dependency-free.

API docs: https://pkg.go.dev/github.com/mitranim/gr.

Usage

Sending and receiving JSON:

package gr_test

import (
  "fmt"
  "net/url"

  "github.com/mitranim/gr"
)

func ExampleReq_jsonInputJsonOutput() {
  input := Input{`some input`}

  var output Output
  gr.To(testServer.URL).Path(`/json`).Json(input).Res().Ok().Json(&output)

  fmt.Printf("%#v\n", output)

  // Output:
  // gr_test.Output{ReqMethod:"GET", ReqUrl:"/json", ReqBody:"{\"inputVal\":\"some input\"}"}
}

type Input struct {
  InputVal string `json:"inputVal"`
}

type Output struct {
  ReqMethod string `json:"reqMethod"`
  ReqUrl    string `json:"reqUrl"`
  ReqBody   string `json:"reqBody"`
}

Sending URL-encoded form, reading plain text:

package gr_test

import (
  "fmt"
  "net/url"

  "github.com/mitranim/gr"
)

func ExampleReq_formBodyPlainResponse() {
  req := gr.To(testServer.URL).Post().FormVals(url.Values{`one`: {`two`}})
  res := req.Res().Ok()
  defer res.Done()

  fmt.Printf("\nresponse status: %v\n", res.StatusCode)
  fmt.Printf("\nresponse type: %v\n", res.Header.Get(gr.Type))
  fmt.Printf("\nresponse body:\n%v\n", res.ReadString())

  // Output:
  //
  // response status: 200
  //
  // response type: text/plain; charset=utf-8
  //
  // response body:
  //
  // request method: POST
  // request URL: /
  // request body: one=two
}

Why Pointers

Since gr uses a chainable builder-style API, we could have defined all "builder" methods on gr.Req and gr.Res (non-pointer types), rather than on *gr.Req and *gr.Res (pointer types). This would allow to store "partially built" requests, and "fork" them by simply reassigning variables. So why do we define this on pointer types?

  • In Go, request and response are inherently mutable because they contain reference types such as *url.URL, http.Header and io.ReadCloser. Copying structs such as http.Request or http.Response by reassigning variables makes a shallow copy where the inner references are still mutably shared. That would be hazardous. Explicit copying via .Clone is less error prone.

  • Emulating an "immutable" API by using copy-on-write for URL and headers is possible, but incurs a measurable performance penalty.

  • All APIs in "net/http" operate on requests and responses by pointer. By using the same pointers, we avoid the overhead of copying and reallocation.

  • Go request and response structs are rather large. The language seems to use naive call conventions that involve always copying value types, as opposed to passing them by reference when they would be constant. For large structs, always passing them by pointer rather than by value seems faster.

License

https://unlicense.org

Misc

I'm receptive to suggestions. If this library almost satisfies you but needs changes, open an issue or chat me up. Contacts: https://mitranim.com/#contacts

Documentation

Index

Examples

Constants

View Source
const (
	Type = `Content-Type`

	TypeJson     = `application/json`
	TypeJsonUtf8 = `application/json; charset=utf-8`

	TypeForm     = `application/x-www-form-urlencoded`
	TypeFormUtf8 = `application/x-www-form-urlencoded; charset=utf-8`

	TypeMulti     = `multipart/form-data`
	TypeMultiUtf8 = `multipart/form-data; charset=utf-8`
)

Variables

This section is empty.

Functions

func ForkReadCloser added in v0.1.7

func ForkReadCloser(val io.ReadCloser) (_, _ io.ReadCloser)

Fully reads the given stream via `io.ReadAll`, closing it at the end, and returns two "forks". Used internally by `(*gr.Req).CloneBody` and `(*gr.Res).CloneBody`. If reading fails, panics. If the input is nil, both outputs are nil.

func IsClientErr

func IsClientErr(val int) bool

True if given HTTP status code is between 400 and 499 inclusive.

func IsInfo

func IsInfo(val int) bool

True if given HTTP status code is between 100 and 199 inclusive.

func IsNil added in v0.1.11

func IsNil(val interface{}) bool

func IsOk

func IsOk(val int) bool

True if given HTTP status code is between 200 and 299 inclusive.

func IsReadOnly

func IsReadOnly(val string) bool

True if given HTTP method is "", "GET", "HEAD" or "OPTIONS".

func IsRedir

func IsRedir(val int) bool

True if given HTTP status code is between 300 and 399 inclusive.

func IsServerErr

func IsServerErr(val int) bool

True if given HTTP status code is between 500 and 599 inclusive.

func Str added in v0.1.1

func Str(src interface{}) string

Missing feature of the standard library: return a string representation of a primitive or "intentionally" stringable value, without allowing arbitrary non-stringable inputs. Differences from `fmt.Sprint`:

  • Allow ONLY the following inputs:

  • nil -> return ""

  • `fmt.Stringer` -> call `.String()`

  • Built-in primitive types -> use "strconv"

  • Automatically dereference pointers to supported types. Nil pointers are considered equivalent to nil.

  • Panic for all other inputs.

  • Don't swallow encoding errors.

func UrlAppend added in v0.1.1

func UrlAppend(ref *url.URL, val interface{}) *url.URL

Appends the string representation of the input to the path of the given URL, slash-separated. The input must be string-encodable following the rules of `gr.Str`, and the resulting string must be non-empty, otherwise this panics to safeguard against calling external endpoints on the wrong address. Mutates the given URL and returns it. If the input URL is nil, creates and returns a new non-nil instance. For correctness, you must reassign the output instead of relying on mutation.

func UrlJoin added in v0.1.1

func UrlJoin(ref *url.URL, vals ...interface{}) *url.URL

Appends the string representations of the input values to the path of the given URL, slash-separated. Uses `gr.UrlAppend` for each segment. Each segment must be non-empty, otherwise this panics to safeguard against calling external endpoints on the wrong address. Mutates the given URL and returns it. If the input URL is nil, creates and returns a new non-nil instance. For correctness, you must reassign the output instead of relying on mutation.

Types

type BytesReadCloser

type BytesReadCloser struct{ bytes.Reader }

Variant of `bytes.Reader` that also implements nop `io.Closer`. Used internally by `(*gr.Req).Bytes`.

func NewBytesReadCloser

func NewBytesReadCloser(val []byte) *BytesReadCloser

Equivalent to `io.NopCloser(bytes.NewReader(val))`, but avoids 1 indirection and heap allocation by returning `*gr.BytesReadCloser` which implements nop `io.Closer` by itself. Used internally by `(*gr.Req).Bytes`.

func (*BytesReadCloser) Close

func (self *BytesReadCloser) Close() error

Nop `io.Closer`.

type Cli added in v0.1.3

type Cli http.Client

Short for "client" (not "CLI"). Alias of `http.Client` with added shortcuts for better compatibility with `gr.Req` and `gr.Res`. Freely castable to and from `http.Client`.

func (*Cli) Cli added in v0.1.4

func (self *Cli) Cli() *http.Client

Free cast to `*http.Client`.

func (*Cli) Do added in v0.1.4

func (self *Cli) Do(req *Req) *Res

Similar to `(*http.Client).Do`, but with "gr" types. Panics on error. To catch the error, use `(*gr.Cli).DoCatch`.

func (*Cli) DoCatch added in v0.1.4

func (self *Cli) DoCatch(req *Req) (*Res, error)

Similar to `(*http.Client).Do`, but with "gr" types.

func (*Cli) Req added in v0.1.4

func (self *Cli) Req() *Req

Returns a new `gr.Req` with this client. Executing the request via `(*gr.Req).Res` or `(*gr.Req).ResCatch` will use this client.

type Err

type Err struct {
	Status int    `json:"status,omitempty"`
	Body   []byte `json:"body,omitempty"`
	Cause  error  `json:"cause,omitempty"`
}

Wraps another error, adding an HTTP status code and response body. Some errors returned by this package have codes obtained from `http.Response`.

func (Err) AppendTo added in v0.1.12

func (self Err) AppendTo(buf []byte) []byte

Appends the error representation. Used internally by `.Error`.

func (Err) Error

func (self Err) Error() string

Implement the `error` interface.

func (Err) HttpStatusCode

func (self Err) HttpStatusCode() int

Returns `.Status`. Implements a hidden interface supported by `github.com/mitranim/rout`.

func (Err) Unwrap

func (self Err) Unwrap() error

Implement a hidden interface in "errors".

type Head http.Header

Alias of `http.Header`. Provides additional methods. Provides a chainable builder-style API. All methods support both canonical and non-canonical versions of header keys, able to find EXISTING non-canonical entries, canonicalizing them when possible. Freely castable to and from `http.Header`.

func (Head) Add added in v0.1.1

func (self Head) Add(key, val string) Head

Similar to `http.Header.Add`, but also looks for an existing entry under this EXACT key, as well as an entry for the canonical version of the key, combining both under the canonical key. Internally calls `append`, which may mutate the backing array of any existing slices for this key. Mutates and returns the receiver. If the receiver is nil, allocates and returns a new map. For correctness, you must always reassign the returned value.

func (Head) Clone

func (self Head) Clone() Head

Same as `http.Header`. Makes a deep copy.

func (Head) Del

func (self Head) Del(key string) Head

Deletes both this exact key and its canonical version. Mutates and returns the receiver.

func (Head) Get

func (self Head) Get(key string) string

Similar to `http.Header.Get`, but also works if the key is non-canonical.

func (Head) Has

func (self Head) Has(key string) bool

True if the header contains either this exact key or its canonical version.

func (Head) Header

func (self Head) Header() http.Header

Free cast to `http.Header`.

func (Head) Init

func (self Head) Init() Head

If nil, returns a non-nil empty map. If already allocated, returns self.

func (Head) Patch

func (self Head) Patch(head map[string][]string) Head

Applies the patch, using `gr.Head.Replace` for each key-values entry. Mutates and returns the receiver. If the receiver is nil, allocates and returns a new map. For correctness, you must always reassign the returned value.

Accepts an "anonymous" type because all alias types such as `gr.Head` and `http.Header` are automatically castable into it.

func (Head) Replace

func (self Head) Replace(key string, vals ...string) Head

Replaces the given key-value, canonicalizing the key. When called with no vals, this is identical to `gr.Head.Del`, deleting the previous entry at BOTH this exact key and its canonical version. When called with some vals, this replaces the previous entry at the canonical version of this key, while deleting the entry at this exact key. The received slice is set as-is, allowing you to reuse a preallocated slice. Mutates and returns the receiver. If the receiver is nil, allocates and returns a new map. For correctness, you must always reassign the returned value.

func (Head) Set

func (self Head) Set(key, val string) Head

Similar to `http.Header.Set`, but also replaces the previous entry under this exact key, if the key is non-canonical. The resulting entry always has the canonical key. Mutates and returns the receiver. If the receiver is nil, allocates and returns a new map. For correctness, you must always reassign the returned value.

func (Head) Values

func (self Head) Values(key string) []string

Similar to `http.Header.Values`, but also works if the key is non-canonical.

type Req

type Req http.Request

Alias of `http.Request` with a fluent builder-style API. Freely castable to and from `http.Request`. All methods are defined on `*gr.Req` and may mutate the receiver or its inner references. To store and copy a "partially built" request, use `(*gr.Req).Clone`.

Example (FormBodyPlainResponse)
req := gr.To(testServer.URL).Post().FormVals(url.Values{`one`: {`two`}})
res := req.Res().Ok()
defer res.Done()

fmt.Printf("\nresponse status: %v\n", res.StatusCode)
fmt.Printf("\nresponse type: %v\n", res.Header.Get(gr.Type))
fmt.Printf("\nresponse body:\n%v\n", res.ReadString())
Output:


response status: 200

response type: text/plain; charset=utf-8

response body:

request method: POST
request URL: /
request body: one=two
Example (JsonInputJsonOutput)
input := Input{`some input`}

var output Output
gr.To(testServer.URL).Path(`/json`).Json(input).Res().Ok().Json(&output)

fmt.Printf("%#v\n", output)
Output:

gr_test.Output{ReqMethod:"GET", ReqUrl:"/json", ReqBody:"{\"inputVal\":\"some input\"}"}

func Connect added in v0.1.5

func Connect() *Req

Returns a new "CONNECT" request. Shortcut for `new(gr.Req).Connect()`.

func Ctx

func Ctx(ctx context.Context) *Req

Returns a new request with the given context. Shortcut for `new(gr.Req).Ctx(ctx)`.

func Delete

func Delete() *Req

Returns a new "DELETE" request. Shortcut for `new(gr.Req).Delete()`.

func Get

func Get() *Req

Returns a new "GET" request. Shortcut for `new(gr.Req).Get()`.

func Init

func Init() *Req

Returns a new request with pre-initialized non-zero context, method, URL, and header. Shortcut for `new(gr.Req).Init()`.

func Meth

func Meth(val string) *Req

Returns a new request with the given method. Shortcut for `new(gr.Req).Meth(val)`.

func Options

func Options() *Req

Returns a new "OPTIONS" request. Shortcut for `new(gr.Req).Options()`.

func Patch

func Patch() *Req

Returns a new "PATCH" request. Shortcut for `new(gr.Req).Patch()`.

func Path

func Path(val string, vals ...interface{}) *Req

Returns a new request with the given URL path. Shortcut for `new(gr.Req).Path(val, vals...)`.

func Post

func Post() *Req

Returns a new "POST" request. Shortcut for `new(gr.Req).Post()`.

func Put

func Put() *Req

Returns a new "PUT" request. Shortcut for `new(gr.Req).Put()`.

func To

func To(val string) *Req

Returns a new request with the given URL string. Shortcut for `new(gr.Req).To(val)`.

func Trace added in v0.1.5

func Trace() *Req

Returns a new "TRACE" request. Shortcut for `new(gr.Req).Trace()`.

func Url

func Url(val *url.URL) *Req

Returns a new request with the given URL. Shortcut for `new(gr.Req).Url(val)`.

func (*Req) Append added in v0.1.1

func (self *Req) Append(val interface{}) *Req

Uses `gr.UrlAppend` to append the input to the URL path, slash-separated. Mutates and returns the receiver.

func (*Req) Bytes

func (self *Req) Bytes(val []byte) *Req

Uses the given chunk as the request body, updating the following fields:

  • `.ContentLength` -> input length, in bytes rather than characters.
  • `.Body` -> nil or `gr.NewBytesReadCloser` from input.
  • `.GetBody` -> nil or function returning `gr.NewBytesReadCloser` from input.

If the input is empty, the listed fields are set to zero values, otherwise the fields are set to non-zero values. Mutates and returns the receiver.

func (*Req) Cli added in v0.1.3

func (self *Req) Cli(val *http.Client) *Req

Sets the given HTTP client, unsafely reusing the `.TLS` field which is normally unused in client requests. Passing nil clears the field. The client is automatically used by `(*gr.Req).Res` and `(*gr.Req).ResCatch`. The name is short for "client", not "CLI". Mutates and returns the receiver.

func (*Req) CliRes

func (self *Req) CliRes(cli *http.Client) *Res

Short for "client response" or "response using client". Performs the request using the given client, returning the response as `*gr.Res`. If the client is nil, uses `http.DefaultClient`. Panics on transport errors, but NOT in case of successful HTTP responses with non-OK HTTP status codes. To avoid panics, use `(*gr.Req).CliResCatch`.

The caller MUST close the response body by calling `*gr.Res.Done` or its other reading or closing methods.

func (*Req) CliResCatch

func (self *Req) CliResCatch(cli *http.Client) (_ *Res, err error)

Variant of `(*gr.Req).CliRes` that returns an error instead of panicking. If the response is non-nil, the caller MUST close the response body by calling `*gr.Res.Done` or its other reading or closing methods.

func (*Req) Client added in v0.1.3

func (self *Req) Client() *http.Client

Returns the HTTP client previously set by `(*gr.Req).Cli`, unsafely reusing the `.TLS` field which is normally unused in client requests. The default is nil.

func (*Req) Clone

func (self *Req) Clone() *Req

Returns a deep copy, like `(*http.Request).Clone`, but without forcing you to provide a context. Cloning allows to reuse partially built requests, like templates. This preserves everything, including the previous context and client. Inner mutable references such as `.URL` and `.Header` are deeply cloned. Unlike `(*http.Request).Clone`, this also clones the body, by calling `(*gr.Req).CloneBody` which is available separately.

func (*Req) CloneBody added in v0.1.7

func (self *Req) CloneBody() io.ReadCloser

Returns a copy of the request body. Attempts to use `.GetBody` if possible. May fully read, close, and replace the current body. If both `.Body` and `.GetBody` are nil, returns nil.

func (*Req) Connect added in v0.1.5

func (self *Req) Connect() *Req

Shortcut for `self.Meth(http.MethodConnect)`.

func (*Req) Context

func (self *Req) Context() context.Context

Returns the inner context as-is. Like `(*http.Request).Context`, but without the hidden fallback on `context.Background`. The function naming is inconsistent with `.Ctx` which sets the context; consistent name would be `.GetCtx` or `.CtxGet`; this name is used to match the existing `(*http.Request).Context`.

func (*Req) Ctx

func (self *Req) Ctx(ctx context.Context) *Req

Sets the inner context to the exact given value, without nil checks or fallbacks. Mutates and returns the receiver.

func (*Req) Delete

func (self *Req) Delete() *Req

Shortcut for `self.Meth(http.MethodDelete)`.

func (*Req) Dump added in v0.1.7

func (self *Req) Dump() *Req

Introspection tool. Shortcut for using `(*gr.Req).Write` to dump the request to standard output. Clones before dumping. Can be used in method chains without affecting the original request.

func (*Req) FormVals

func (self *Req) FormVals(val map[string][]string) *Req

URL-encodes the given vals as the request body. Also sets the header "Content-Type: application/x-www-form-urlencoded", as well as fields `.ContentLength` and `.GetBody`. Shortcut for `self.TypeForm().Vals(val)`. Accepts an "anonymous" type because all alias types such as `url.Values` are automatically castable into it. Mutates and returns the receiver.

func (*Req) Get

func (self *Req) Get() *Req

Shortcut for `self.Meth(http.MethodGet)`.

func (*Req) Head

func (self *Req) Head(val map[string][]string) *Req

Sets the given value as `.Header`. Mutates and returns the receiver. Accepts an "anonymous" type because all alias types such as `http.Header` and `gr.Head` are automatically castable into it.

func (*Req) HeadAdd added in v0.1.1

func (self *Req) HeadAdd(key, val string) *Req

Appends the given key-value to `.Header` by using `gr.Head.Add`. Allocates the header if necessary. May mutate `.Header` and an existing slice corresponding to the key. Mutates and returns the receiver.

func (*Req) HeadDel

func (self *Req) HeadDel(key string) *Req

Deletes the given entry in `.Header` by using `gr.Head.Del`. May mutate `.Header`, but not the slices contained therein. Mutates and returns the receiver.

func (*Req) HeadInit added in v0.1.12

func (self *Req) HeadInit() *Req

Makes sure `.Header` is non-nil. Mutates and returns the receiver.

func (*Req) HeadPatch

func (self *Req) HeadPatch(head map[string][]string) *Req

Patches the header by using `gr.Head.Patch`. Allocates the header if necessary. May mutate `.Header`, but not the slices contained therein. Mutates and returns the receiver. Accepts an "anonymous" type because all alias types such as `http.Header` and `gr.Head` are automatically castable into it.

func (*Req) HeadReplace

func (self *Req) HeadReplace(key string, vals ...string) *Req

Replaces the given key-values entry in `.Header` by using `gr.Head.Replace`. Allocates the header if necessary. May mutate `.Header`, but not the slices contained therein. Mutates and returns the receiver.

func (*Req) HeadSet

func (self *Req) HeadSet(key, val string) *Req

Sets the given key-value in `.Header` by using `gr.Head.Set`. Allocates the header if necessary. May mutate `.Header`, but not the slices contained therein. Mutates and returns the receiver.

func (*Req) Init

func (self *Req) Init() *Req

Initializes context, `.Method`, `.URL`, `.Header` to non-zero values, similar to how `http.NewRequest` would have done it. Mutates and returns the receiver.

func (*Req) IsReadOnly

func (self *Req) IsReadOnly() bool

True if `.Method` is "", "GET", "HEAD" or "OPTIONS".

func (*Req) Join added in v0.1.1

func (self *Req) Join(vals ...interface{}) *Req

Uses `gr.UrlJoin` to append the inputs to the URL path, slash-separated. Mutates and returns the receiver.

func (*Req) Json

func (self *Req) Json(val interface{}) *Req

JSON-encodes an arbitrary value, using it as the request body. Also sets the header "Content-Type: application/json", as well as fields `.ContentLength` and `.GetBody`. Panics if JSON encoding fails. Use `(*gr.Req).JsonCatch` to catch those panics. Mutates and returns the receiver.

func (*Req) JsonBytes

func (self *Req) JsonBytes(val []byte) *Req

Assumes that the given chunk is valid JSON, and uses it as the request body. Also sets "Content-Type: application/json". Shortcut for `self.TypeJson().Bytes(val)`. Mutates and returns the receiver.

func (*Req) JsonCatch

func (self *Req) JsonCatch(val interface{}) (err error)

Same as `(*gr.Req).Json`, but if JSON encoding fails, returns an error instead of panicking.

func (*Req) JsonString

func (self *Req) JsonString(val string) *Req

Assumes that the given string is valid JSON, and uses it as the request body. Also sets "Content-Type: application/json". Shortcut for `self.TypeJson().String(val)`. Mutates and returns the receiver.

func (*Req) Meth

func (self *Req) Meth(val string) *Req

Sets `.Method` to the given value. Mutates and returns the receiver.

func (*Req) Options

func (self *Req) Options() *Req

Shortcut for `self.Meth(http.MethodOptions)`.

func (*Req) Patch

func (self *Req) Patch() *Req

Shortcut for `self.Meth(http.MethodPatch)`.

func (*Req) Path

func (self *Req) Path(val string, vals ...interface{}) *Req

Uses `gr.UrlJoin` to make a URL path and sets the result as `.URL.Path`, creating a new URL reference if the URL was nil. Mutates and returns the receiver.

func (*Req) Post

func (self *Req) Post() *Req

Shortcut for `self.Meth(http.MethodPost)`.

func (*Req) Put

func (self *Req) Put() *Req

Shortcut for `self.Meth(http.MethodPut)`.

func (*Req) Query

func (self *Req) Query(val map[string][]string) *Req

Shortcut for `self.RawQuery(url.Values(val).Encode())`. Accepts an "anonymous" type because all alias types such as `url.Values` are automatically castable into it.

func (*Req) RawQuery

func (self *Req) RawQuery(val string) *Req

Sets the given value as `.URL.RawQuery`, creating a new URL reference if the URL was nil. Mutates and returns the receiver.

func (*Req) ReadCloser

func (self *Req) ReadCloser(val io.ReadCloser) *Req

Shortcut for setting `.Body` and returning the request. Sets the body as-is without affecting other fields. Mutates and returns the receiver.

func (*Req) Reader

func (self *Req) Reader(val io.Reader) *Req

Sets the given reader as the request body. If the reader is nil, sets nil. Otherwise wraps it in `io.NopCloser`. Mutates and returns the receiver.

func (*Req) Req

func (self *Req) Req() *http.Request

Free cast to `*http.Request`.

func (*Req) Res

func (self *Req) Res() *Res

Short for "response". Shortcut for `(*gr.Res).CliRes(self.Client())`, which uses `http.DefaultClient` if no client was given. Returns the response as `*gr.Res`. Panics on transport errors, but NOT in case of successful HTTP responses with non-OK HTTP status codes. To avoid panics, use `(*gr.Req).ResCatch`.

The caller MUST close the response body by calling `*gr.Res.Done` or its other reading or closing methods.

func (*Req) ResCatch

func (self *Req) ResCatch() (_ *Res, err error)

Variant of `(*gr.Req).Res` that returns an error instead of panicking. If the response is non-nil, the caller MUST close the response body by calling `*gr.Res.Done` or its other reading or closing methods.

func (*Req) String

func (self *Req) String(val string) *Req

Uses the given string as the request body, updating the following fields:

  • `.ContentLength` -> input length, in bytes rather than characters.
  • `.Body` -> nil or `gr.NewStringReadCloser` from input.
  • `.GetBody` -> nil or function returning `gr.NewStringReadCloser` from input.

If the input is empty, the listed fields are set to zero values, otherwise the fields are set to non-zero values. Mutates and returns the receiver.

func (*Req) To

func (self *Req) To(src string) *Req

Parses the input via `url.Parse` and sets `.URL` to the result. Panics on parsing errors. Mutates and returns the receiver.

func (*Req) Trace added in v0.1.5

func (self *Req) Trace() *Req

Shortcut for `self.Meth(http.MethodTrace)`.

func (*Req) Type

func (self *Req) Type(typ string) *Req

Shortcut for setting the "Content-Type" header. If the input is "", removes the header instead. Mutates and returns the receiver.

func (*Req) TypeForm

func (self *Req) TypeForm() *Req

Shortcut for setting the "Content-Type: application/x-www-form-urlencoded" header. Mutates and returns the receiver.

func (*Req) TypeJson

func (self *Req) TypeJson() *Req

Shortcut for setting the "Content-Type: application/json" header. Mutates and returns the receiver.

func (*Req) TypeMulti

func (self *Req) TypeMulti() *Req

Shortcut for setting the "Content-Type: multipart/form-data" header. Mutates and returns the receiver.

func (*Req) Url

func (self *Req) Url(val *url.URL) *Req

Sets the given value as `.URL`. Mutates and returns the receiver.

func (*Req) Vals

func (self *Req) Vals(val map[string][]string) *Req

URL-encodes the given vals as the request body. Shortcut for `self.String(url.Values(val).Encode())`. Also sets `.ContentLength` and `.GetBody`. Accepts an "anonymous" type because all alias types such as `url.Values` are automatically castable into it. Mutates and returns the receiver.

func (*Req) Write added in v0.1.7

func (self *Req) Write(out io.Writer)

Introspection shortcut. Uses `(*http.Request).Write`, but panics on error instead of returning an error. Follows the write with a newline. Caution: mutates the request by reading the body. If you intend to send the request, use `.Clone` or `.Dump`.

type Res

type Res http.Response

Alias of `http.Response` with many shortcuts for inspecting and decoding the response. Freely castable to and from `http.Response`.

When using `gr`, a response can be obtained by calling `(*gr.Req).Res` or `(*gr.Req).CliRes`. However, this is also usable for responses obtained from other sources. You can cast any `*http.Response` to `*gr.Res` to simplify its inspection and decoding.

The caller MUST close the response body by calling `(*gr.Res).Done` or its other reading or closing methods.

func (*Res) Clone added in v0.1.7

func (self *Res) Clone() *Res

Similar to `(*gr.Res).Clone`. Returns a deep copy whose mutations don't affect the original. Mostly useful for introspection, like dumping to standard output, which requires reading the body. Clones the body via `(*gr.Res).CloneBody` which is available separately, and other fields via their standard library counterparts.

func (*Res) CloneBody added in v0.1.7

func (self *Res) CloneBody() io.ReadCloser

Returns a copy of the response body. Mutates the receiver by fully reading, closing, and replacing the current body. If the current body is nil, this is a nop and the output is nil.

func (*Res) CloseErr

func (self *Res) CloseErr() error

Closes the response body if possible, returning a close error if any.

func (*Res) Done

func (self *Res) Done() *Res

Closes the response body if possible, returning the same response. Can be deferred or used in method chains.

func (*Res) Dump added in v0.1.7

func (self *Res) Dump() *Res

Introspection tool. Shortcut for using `(*gr.Res).Write` to dump the response to standard output. Clones before dumping. Can be used in method chains without affecting the original response.

func (*Res) Err added in v0.1.5

func (self *Res) Err(desc string) Err

Returns an error that includes the response HTTP status code and the downloaded body, as well as the provided short description. Always downloads and closes the response body, if any. The description must be non-empty, and represent a reason why the response is unsatisfactory, such as "non-OK" or "non-redirect".

func (*Res) Form

func (self *Res) Form() url.Values

Downloads the response body and parses it as URL-encoded/form-encoded content, using `url.ParseQuery`. Returns the parsed result. Panics if body can't be read, or if parsing fails. Always closes the body.

func (*Res) FormCatch

func (self *Res) FormCatch() (_ url.Values, err error)

Non-panicking version of `(*gr.Res).Form`. If body can't be read, or if parsing fails, returns an error. Always closes the body.

func (*Res) IsClientErr

func (self *Res) IsClientErr() bool

True if response status code is between 400 and 499 inclusive.

func (*Res) IsForm added in v0.1.9

func (self *Res) IsForm() bool

True if the parsed media type of `Content-Type` is `gr.TypeForm`.

func (*Res) IsInfo

func (self *Res) IsInfo() bool

True if response status code is between 100 and 199 inclusive.

func (*Res) IsJson added in v0.1.9

func (self *Res) IsJson() bool

True if the parsed media type of `Content-Type` is `gr.TypeJson`.

func (*Res) IsMulti added in v0.1.9

func (self *Res) IsMulti() bool

True if the parsed media type of `Content-Type` is `gr.TypeMulti`.

func (*Res) IsOk

func (self *Res) IsOk() bool

True if response status code is between 200 and 299 inclusive.

func (*Res) IsRedir

func (self *Res) IsRedir() bool

True if response status code is between 300 and 399 inclusive.

func (*Res) IsServerErr

func (self *Res) IsServerErr() bool

True if response status code is between 500 and 599 inclusive.

func (*Res) Json

func (self *Res) Json(out interface{}) *Res

Parses the response body into the given output, which must be either nil or a pointer. Uses `json.Decoder` to decode from a stream, without buffering the entire body. Panics on errors. If the output is nil, skips downloading or decoding. Returns the same response. Always closes the body.

func (*Res) JsonCatch

func (self *Res) JsonCatch(out interface{}) (err error)

Non-panicking version of `(*gr.Res).Json`. Returns an error if body downloading or parsing fails. Always closes the body.

func (*Res) JsonEither

func (self *Res) JsonEither(outVal, outErr interface{}) bool

If the response is "ok", decodes the response body into `outVal`. Otherwise decodes the response body into `outErr`. Both outputs are optional; if the relevant output is nil, skips downloading and decoding. Returns true if the response is "ok", and false if not. Panics on downloading or decoding errors. Always closes the body.

func (*Res) JsonEitherCatch

func (self *Res) JsonEitherCatch(outVal, outErr interface{}) (_ bool, err error)

Non-panicking version of `(*gr.Res).JsonEither`. If body can't be read, or if parsing fails, returns an error. Always closes the body.

func (*Res) Loc

func (self *Res) Loc() string

Short for "location". Returns the response header "Location". Sometimes useful when inspecting redirect responses.

func (*Res) LocUrl

func (self *Res) LocUrl() *url.URL

Short for "location URL". Parses the response header "Location" and returns it as URL. If parsing fails, panics with a descriptive error.

func (*Res) LocUrlCatch

func (self *Res) LocUrlCatch() (_ *url.URL, err error)

Non-panicking version of `(*gr.Res).LocUrl`. Returns a parsed redirect location or a descriptive parse error.

func (*Res) Media added in v0.1.9

func (self *Res) Media() (_ string, _ map[string]string)

Parses the `Content-Type` header via `mime.ParseMediaType`. Panics on error.

func (*Res) MediaType added in v0.1.9

func (self *Res) MediaType() (_ string)

Returns the media type parsed via `(*gr.Res).Media`.

func (*Res) Ok

func (self *Res) Ok() *Res

Asserts that the response is "ok". If not "ok", panics with an error that includes the response body as text, and closes the body. If "ok", returns the response unchanged without closing the body.

func (*Res) OkCatch

func (self *Res) OkCatch() (err error)

Non-panicking version of `(*gr.Res).Ok`. If not "ok", returns an error that includes the response body as text, and closes the body. Otherwise returns nil without closing the body.

func (*Res) ReadBytes

func (self *Res) ReadBytes() []byte

Uses `io.ReadAll` to read the entire response body, returning the resulting chunk. Panics if reading can't be completed. Always closes the body.

func (*Res) ReadBytesCatch

func (self *Res) ReadBytesCatch() (_ []byte, err error)

Non-panicking version of `(*gr.Res).ReadBytes`. If body reading fails, returns an error. Always closes the body.

func (*Res) ReadString

func (self *Res) ReadString() string

Similar to `(*gr.Res).ReadBytes`, but returns the entire response body as a string, without copying. Always closes the body.

func (*Res) ReadStringCatch

func (self *Res) ReadStringCatch() (_ string, err error)

Non-panicking version of `(*gr.Res).ReadString`. If body reading fails, returns an error. Always closes the body.

func (*Res) Redir

func (self *Res) Redir() *Res

Asserts that the response is a redirect. If not a redirect, panics with an error that includes the response body as text, and closes the body. If a redirect, returns the response unchanged without closing the body.

func (*Res) RedirCatch

func (self *Res) RedirCatch() (err error)

Non-panicking version of `(*gr.Res).Redir`. If not a redirect, returns an error that includes the response body as text, and closes the body. Otherwise returns nil without closing the body.

func (*Res) Res

func (self *Res) Res() *http.Response

Free cast to `*http.Response`.

func (*Res) Type added in v0.1.9

func (self *Res) Type() string

Returns the `Content-Type` header. Note that the content-type may contain additional parameters, and needs to be parsed before comparing it to a "pure" media type such as `gr.TypeJson`.

func (*Res) Write added in v0.1.7

func (self *Res) Write(out io.Writer)

Introspection shortcut. Uses `(*http.Response).Write`, but panics on error instead of returning an error. Follows the write with a newline. Caution: mutates the response by reading the body. If you intend to further read the response, use `.Clone` or `.Dump`.

func (*Res) Xml

func (self *Res) Xml(out interface{}) *Res

Shortcut for `(*gr.Res).XmlWith` with a nil func. Decodes the response body without any special XML decoder options.

func (*Res) XmlCatch

func (self *Res) XmlCatch(out interface{}) (err error)

Non-panicking version of `(*gr.Res).Xml`. Returns an error if body downloading or parsing fails. Always closes the body.

func (*Res) XmlWith added in v0.1.8

func (self *Res) XmlWith(out interface{}, fun func(*xml.Decoder)) *Res

Parses the response body into the given output, which must be either nil or a pointer. Uses `xml.Decoder` to decode from a stream, without buffering the entire body. The given function is used to customize the decoder, and may be nil. Panics on errors. If the output is nil, skips downloading or decoding. Returns the same response. Always closes the body.

func (*Res) XmlWithCatch added in v0.1.8

func (self *Res) XmlWithCatch(out interface{}, fun func(*xml.Decoder)) (err error)

Non-panicking version of `(*gr.Res).XmlWith`. Returns an error if body downloading or parsing fails. Always closes the body.

type StringReadCloser

type StringReadCloser struct{ strings.Reader }

Variant of `strings.Reader` that also implements nop `io.Closer`. Used internally by `(*gr.Req).String`.

func NewStringReadCloser

func NewStringReadCloser(val string) *StringReadCloser

Equivalent to `io.NopCloser(strings.NewReader(val))`, but avoids 1 indirection and heap allocation by returning `*gr.StringReadCloser` which implements nop `io.Closer` by itself. Used internally by `(*gr.Req).String`.

func (*StringReadCloser) Close

func (self *StringReadCloser) Close() error

Nop `io.Closer`.

type Trans added in v0.1.4

type Trans func(*http.Request) (*http.Response, error)

Short for "transport". Function type that implements `http.RoundTripper` by calling itself. Can be used as `http.Client.Transport` or `gr.Cli.Transport`.

func (Trans) RoundTrip added in v0.1.4

func (self Trans) RoundTrip(req *http.Request) (*http.Response, error)

Implement `http.RoundTripper`.

Jump to

Keyboard shortcuts

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