func RelativeURL(paths ...string) Option {
	return OptionFunc(func(r *Requester) error {
		for _, p := range paths {
			u, err := url.Parse(p)
			if err != nil {
				return merry.Prepend(err, "invalid url")
			}
			if r.URL == nil {
				r.URL = u
			} else {
				r.URL = r.URL.ResolveReference(u)
			}
		}
		return nil
	})
}
RelativeURL resolves the arg as a relative URL references against
the current URL, using the standard lib's url.URL.ResolveReference() method.
package requester
import (
	"encoding/base64"
	"net/http"
	"net/url"
	"strings"
	"unicode"
	"github.com/ansel1/merry"
	"github.com/gemalto/requester/httpclient"
	goquery "github.com/google/go-querystring/query"
)
const (
	HeaderAccept        = "Accept"
	HeaderContentType   = "Content-Type"
	HeaderAuthorization = "Authorization"
	HeaderRange         = "Range"
	MediaTypeJSON          = "application/json"
	MediaTypeXML           = "application/xml"
	MediaTypeForm          = "application/x-www-form-urlencoded"
	MediaTypeOctetStream   = "application/octet-stream"
	MediaTypeTextPlain     = "text/plain"
	MediaTypeMultipart     = "multipart/mixed"
	MediaTypeMultipartForm = "multipart/form-data"
)
type Option interface {
	Apply(*Requester) error
}
type OptionFunc func(*Requester) error
func (f OptionFunc) Apply(r *Requester) error {
	return f(r)
}
func (r *Requester) With(opts ...Option) (*Requester, error) {
	r2 := r.Clone()
	err := r2.Apply(opts...)
	if err != nil {
		return nil, err
	}
	return r2, nil
}
func (r *Requester) MustWith(opts ...Option) *Requester {
	if r2, err := r.With(opts...); err != nil {
		panic(err)
	} else {
		return r2
	}
}
func (r *Requester) Apply(opts ...Option) error {
	for _, o := range opts {
		err := o.Apply(r)
		if err != nil {
			return merry.Prepend(err, "applying options")
		}
	}
	return nil
}
func (r *Requester) MustApply(opts ...Option) {
	if err := r.Apply(opts...); err != nil {
		panic(err)
	}
}
func Method(m string, paths ...string) Option {
	return OptionFunc(func(r *Requester) error {
		r.Method = m
		if len(paths) > 0 {
			err := RelativeURL(paths...).Apply(r)
			if err != nil {
				return err
			}
		}
		return nil
	})
}
func Head(paths ...string) Option {
	return Method(http.MethodHead, paths...)
}
func Get(paths ...string) Option {
	return Method(http.MethodGet, paths...)
}
func Post(paths ...string) Option {
	return Method(http.MethodPost, paths...)
}
func Put(paths ...string) Option {
	return Method(http.MethodPut, paths...)
}
func Patch(paths ...string) Option {
	return Method(http.MethodPatch, paths...)
}
func Delete(paths ...string) Option {
	return Method(http.MethodDelete, paths...)
}
func AddHeader(key, value string) Option {
	return OptionFunc(func(b *Requester) error {
		if b.Header == nil {
			b.Header = make(http.Header)
		}
		b.Header.Add(key, value)
		return nil
	})
}
func Header(key, value string) Option {
	return OptionFunc(func(b *Requester) error {
		if b.Header == nil {
			b.Header = make(http.Header)
		}
		b.Header.Set(key, value)
		return nil
	})
}
func DeleteHeader(key string) Option {
	return OptionFunc(func(b *Requester) error {
		b.Header.Del(key)
		return nil
	})
}
func BasicAuth(username, password string) Option {
	if username == "" && password == "" {
		return DeleteHeader(HeaderAuthorization)
	}
	return Header(HeaderAuthorization, "Basic "+basicAuth(username, password))
}
func basicAuth(username, password string) string {
	auth := username + ":" + password
	return base64.StdEncoding.EncodeToString([]byte(auth))
}
func BearerAuth(token string) Option {
	if token == "" {
		return DeleteHeader(HeaderAuthorization)
	}
	return Header(HeaderAuthorization, "Bearer "+token)
}
func URL(rawurl string) Option {
	return OptionFunc(func(b *Requester) error {
		u, err := url.Parse(rawurl)
		if err != nil {
			return merry.Prepend(err, "invalid url")
		}
		b.URL = u
		return nil
	})
}