web

package module
v0.0.0-...-ab860bf Latest Latest
Warning

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

Go to latest
Published: Mar 21, 2024 License: MIT Imports: 32 Imported by: 25

README

web

Build Status | codecov | Go Report Card | GoDoc

A simple and fast web server and client.

If i miss something or you have something interesting, please be part of this project. Let me know! My contact is at the end.

With support for

  • Common http methods
  • Single/Multiple File Upload
  • Single/Multiple File Download
  • Middlewares
  • Filters

With support for methods

  • HEAD
  • GET
  • POST
  • PUT
  • DELETE
  • PATCH
  • COPY
  • CONNECT
  • OPTIONS
  • TRACE
  • LINK
  • UNLINK
  • PURGE
  • LOCK
  • UNLOCK
  • PROPFIND
  • VIEW
  • ANY (used only on filters)

With authentication types

  • basic
  • jwt

With attachment modes

  • [default] zip files when returns more then one file
    • on client WithClientAttachmentMode(web.MultiAttachmentModeZip)
    • on server WithServerAttachmentMode(web.MultiAttachmentModeZip)
  • [experimental] returns attachmentes splited by a boundary defined on header Content-Type
    • on client WithClientAttachmentMode(web.MultiAttachmentModeBoundary)
    • on server WithServerAttachmentMode(web.MultiAttachmentModeBoundary)
Go
go get github.com/joaosoft/web

Usage

This examples are available in the project at web/examples

Server
func main() {
	// create a new server
	w, err := web.NewServer(web.WithServerMultiAttachmentMode(web.MultiAttachmentModeBoundary))
	if err != nil {
		panic(err)
	}

	claims := jwt.Claims{"name": "joao", "age": 30}

	keyFunc := func(token *jwt.Token) (interface{}, error) {
		return []byte("bananas"), nil
	}

	checkFunc := func(c jwt.Claims) (bool, error) {
		if claims["name"] == c["name"].(string) &&
			claims["age"] == int(c["age"].(float64)) {
			return true, nil
		}
		return false, fmt.Errorf("invalid jwt session token")
	}

	// add filters
	w.AddMiddlewares(MyMiddlewareOne(), MyMiddlewareTwo())
	w.AddFilter("/hello/:name", web.PositionBefore, MyFilterOne(), web.MethodPost)
	w.AddFilter("/hello/:name/upload", web.PositionBefore, MyFilterTwo(), web.MethodPost)
	w.AddFilter("*", web.PositionBefore, MyFilterThree(), web.MethodPost)

	w.AddFilter("/hello/:name", web.PositionBefore, MyFilterTwo(), web.MethodGet)

	w.AddFilter("/form-data", web.PositionAfter, MyFilterThree(), web.MethodAny)

	// add routes
	w.AddRoutes(
		web.NewRoute(web.MethodOptions, "*", HandlerHelloForOptions, web.MiddlewareOptions()),
		web.NewRoute(web.MethodGet, "/auth-basic", HandlerForGet, web.MiddlewareCheckAuthBasic("joao", "ribeiro")),
		web.NewRoute(web.MethodGet, "/auth-jwt", HandlerForGet, web.MiddlewareCheckAuthJwt(keyFunc, checkFunc)),
		web.NewRoute(web.MethodHead, "/hello/:name", HandlerHelloForHead),
		web.NewRoute(web.MethodGet, "/hello/:name", HandlerHelloForGet, MyMiddlewareThree()),
		web.NewRoute(web.MethodPost, "/hello/:name", HandlerHelloForPost),
		web.NewRoute(web.MethodPut, "/hello/:name", HandlerHelloForPut),
		web.NewRoute(web.MethodDelete, "/hello/:name", HandlerHelloForDelete),
		web.NewRoute(web.MethodPatch, "/hello/:name", HandlerHelloForPatch),
		web.NewRoute(web.MethodCopy, "/hello/:name", HandlerHelloForCopy),
		web.NewRoute(web.MethodConnect, "/hello/:name", HandlerHelloForConnect),
		web.NewRoute(web.MethodOptions, "/hello/:name", HandlerHelloForOptions, web.MiddlewareOptions()),
		web.NewRoute(web.MethodTrace, "/hello/:name", HandlerHelloForTrace),
		web.NewRoute(web.MethodLink, "/hello/:name", HandlerHelloForLink),
		web.NewRoute(web.MethodUnlink, "/hello/:name", HandlerHelloForUnlink),
		web.NewRoute(web.MethodPurge, "/hello/:name", HandlerHelloForPurge),
		web.NewRoute(web.MethodLock, "/hello/:name", HandlerHelloForLock),
		web.NewRoute(web.MethodUnlock, "/hello/:name", HandlerHelloForUnlock),
		web.NewRoute(web.MethodPropFind, "/hello/:name", HandlerHelloForPropFind),
		web.NewRoute(web.MethodView, "/hello/:name", HandlerHelloForView),
		web.NewRoute(web.MethodGet, "/hello/:name/download", HandlerHelloForDownloadFiles),
		web.NewRoute(web.MethodGet, "/hello/:name/download/one", HandlerHelloForDownloadOneFile),
		web.NewRoute(web.MethodPost, "/hello/:name/upload", HandlerHelloForUploadFiles),
		web.NewRoute(web.MethodGet, "/form-data", HandlerFormDataForGet),
		web.NewRoute(web.MethodGet, "/url-form-data", HandlerUrlFormDataForGet),
	)

	w.AddNamespace("/p").AddRoutes(
		web.NewRoute(web.MethodGet, "/hello/:name", HandlerHelloForGet, MyMiddlewareFour()),
	)

	// start the server
	if err := w.Start(); err != nil {
		panic(err)
	}
}

func MyFilterOne() web.MiddlewareFunc {
	return func(next web.HandlerFunc) web.HandlerFunc {
		return func(ctx *web.Context) error {
			fmt.Println("HELLO I'M THE FILTER ONE")
			return next(ctx)
		}
	}
}

func MyFilterTwo() web.MiddlewareFunc {
	return func(next web.HandlerFunc) web.HandlerFunc {
		return func(ctx *web.Context) error {
			fmt.Println("HELLO I'M THE FILTER TWO")
			return next(ctx)
		}
	}
}

func MyFilterThree() web.MiddlewareFunc {
	return func(next web.HandlerFunc) web.HandlerFunc {
		return func(ctx *web.Context) error {
			fmt.Println("HELLO I'M THE FILTER THREE")
			return next(ctx)
		}
	}
}

func MyMiddlewareOne() web.MiddlewareFunc {
	return func(next web.HandlerFunc) web.HandlerFunc {
		return func(ctx *web.Context) error {
			fmt.Println("HELLO I'M THE MIDDLEWARE ONE")
			return next(ctx)
		}
	}
}

func MyMiddlewareTwo() web.MiddlewareFunc {
	return func(next web.HandlerFunc) web.HandlerFunc {
		return func(ctx *web.Context) error {
			fmt.Println("HELLO I'M THE MIDDLEWARE TWO")
			return next(ctx)
		}
	}
}

func MyMiddlewareThree() web.MiddlewareFunc {
	return func(next web.HandlerFunc) web.HandlerFunc {
		return func(ctx *web.Context) error {
			fmt.Println("HELLO I'M THE MIDDLEWARE THREE")
			return next(ctx)
		}
	}
}

func MyMiddlewareFour() web.MiddlewareFunc {
	return func(next web.HandlerFunc) web.HandlerFunc {
		return func(ctx *web.Context) error {
			fmt.Println("HELLO I'M THE MIDDLEWARE FOUR")
			return next(ctx)
		}
	}
}

func HandlerForGet(ctx *web.Context) error {
	fmt.Println("HELLO I'M THE HELLO HANDER FOR GET")

	return ctx.Response.Bytes(
		web.StatusOK,
		web.ContentTypeApplicationJSON,
		[]byte("{ \"welcome\": \"guest\" }"),
	)
}

func HandlerHelloForHead(ctx *web.Context) error {
	fmt.Println("HELLO I'M THE HELLO HANDER FOR HEAD")

	return ctx.Response.NoContent(web.StatusOK)
}

func HandlerHelloForGet(ctx *web.Context) error {
	fmt.Println("HELLO I'M THE HELLO HANDER FOR GET")

	return ctx.Response.Bytes(
		web.StatusOK,
		web.ContentTypeApplicationJSON,
		[]byte("{ \"welcome\": \""+ctx.Request.UrlParams["name"][0]+"\" }"),
	)
}

func HandlerHelloForPost(ctx *web.Context) error {
	fmt.Println("HELLO I'M THE HELLO HANDER FOR POST")

	data := struct {
		Name string `json:"name"`
		Age  int    `json:"age"`
	}{}
	ctx.Request.Bind(&data)
	fmt.Printf("DATA: %+v", data)

	return ctx.Response.Bytes(
		web.StatusOK,
		web.ContentTypeApplicationJSON,
		[]byte("{ \"welcome\": \""+ctx.Request.UrlParams["name"][0]+"\" }"),
	)
}

func HandlerHelloForPut(ctx *web.Context) error {
	fmt.Println("HELLO I'M THE HELLO HANDER FOR PUT")

	return ctx.Response.Bytes(
		web.StatusOK,
		web.ContentTypeApplicationJSON,
		[]byte("{ \"welcome\": \""+ctx.Request.UrlParams["name"][0]+"\" }"),
	)
}

func HandlerHelloForDelete(ctx *web.Context) error {
	fmt.Println("HELLO I'M THE HELLO HANDER FOR DELETE")

	return ctx.Response.Bytes(
		web.StatusOK,
		web.ContentTypeApplicationJSON,
		[]byte("{ \"welcome\": \""+ctx.Request.UrlParams["name"][0]+"\" }"),
	)
}

func HandlerHelloForPatch(ctx *web.Context) error {
	fmt.Println("HELLO I'M THE HELLO HANDER FOR PATCH")

	return ctx.Response.Bytes(
		web.StatusOK,
		web.ContentTypeApplicationJSON,
		[]byte("{ \"welcome\": \""+ctx.Request.UrlParams["name"][0]+"\" }"),
	)
}

func HandlerHelloForCopy(ctx *web.Context) error {
	fmt.Println("HELLO I'M THE HELLO HANDER FOR COPY")

	return ctx.Response.NoContent(web.StatusOK)
}

func HandlerHelloForConnect(ctx *web.Context) error {
	fmt.Println("HELLO I'M THE HELLO HANDER FOR CONNECT")

	return ctx.Response.Bytes(
		web.StatusOK,
		web.ContentTypeApplicationJSON,
		[]byte("{ \"welcome\": \""+ctx.Request.UrlParams["name"][0]+"\" }"),
	)
}

func HandlerHelloForOptions(ctx *web.Context) error {
	fmt.Println("HELLO I'M THE HELLO HANDER FOR OPTIONS")

	return ctx.Response.NoContent(web.StatusNoContent)
}

func HandlerHelloForTrace(ctx *web.Context) error {
	fmt.Println("HELLO I'M THE HELLO HANDER FOR TRACE")

	return ctx.Response.Bytes(
		web.StatusOK,
		web.ContentTypeApplicationJSON,
		[]byte("{ \"welcome\": \""+ctx.Request.UrlParams["name"][0]+"\" }"),
	)
}

func HandlerHelloForLink(ctx *web.Context) error {
	fmt.Println("HELLO I'M THE HELLO HANDER FOR LINK")

	return ctx.Response.Bytes(
		web.StatusOK,
		web.ContentTypeApplicationJSON,
		[]byte("{ \"welcome\": \""+ctx.Request.UrlParams["name"][0]+"\" }"),
	)
}

func HandlerHelloForUnlink(ctx *web.Context) error {
	fmt.Println("HELLO I'M THE HELLO HANDER FOR UNLINK")

	return ctx.Response.Bytes(
		web.StatusOK,
		web.ContentTypeApplicationJSON,
		[]byte("{ \"welcome\": \""+ctx.Request.UrlParams["name"][0]+"\" }"),
	)
}

func HandlerHelloForPurge(ctx *web.Context) error {
	fmt.Println("HELLO I'M THE HELLO HANDER FOR PURGE")

	return ctx.Response.NoContent(web.StatusOK)
}

func HandlerHelloForLock(ctx *web.Context) error {
	fmt.Println("HELLO I'M THE HELLO HANDER FOR LOCK")

	return ctx.Response.Bytes(
		web.StatusOK,
		web.ContentTypeApplicationJSON,
		[]byte("{ \"welcome\": \""+ctx.Request.UrlParams["name"][0]+"\" }"),
	)
}

func HandlerHelloForUnlock(ctx *web.Context) error {
	fmt.Println("HELLO I'M THE HELLO HANDER FOR UNLOCK")

	return ctx.Response.NoContent(web.StatusOK)
}
func HandlerHelloForPropFind(ctx *web.Context) error {
	fmt.Println("HELLO I'M THE HELLO HANDER FOR PROPFIND")

	return ctx.Response.Bytes(
		web.StatusOK,
		web.ContentTypeApplicationJSON,
		[]byte("{ \"welcome\": \""+ctx.Request.UrlParams["name"][0]+"\" }"),
	)
}

func HandlerHelloForView(ctx *web.Context) error {
	fmt.Println("HELLO I'M THE HELLO HANDER FOR VIEW")

	return ctx.Response.Bytes(
		web.StatusOK,
		web.ContentTypeApplicationJSON,
		[]byte("{ \"welcome\": \""+ctx.Request.UrlParams["name"][0]+"\" }"),
	)
}

func HandlerHelloForDownloadOneFile(ctx *web.Context) error {
	fmt.Println("HELLO I'M THE HELLO HANDER FOR DOWNLOAD ONE FILE")

	dir, _ := os.Getwd()
	body, _ := web.ReadFile(fmt.Sprintf("%s%s", dir, "/examples/data/a.text"), nil)
	ctx.Response.Attachment("text_a.text", body)

	return ctx.Response.Bytes(
		web.StatusOK,
		web.ContentTypeApplicationJSON,
		[]byte("{ \"welcome\": \""+ctx.Request.UrlParams["name"][0]+"\" }"),
	)
}

func HandlerHelloForDownloadFiles(ctx *web.Context) error {
	fmt.Println("HELLO I'M THE HELLO HANDER FOR DOWNLOAD FILES")

	dir, _ := os.Getwd()
	body, _ := web.ReadFile(fmt.Sprintf("%s%s", dir, "/examples/data/a.text"), nil)
	ctx.Response.Attachment("text_a.text", body)

	body, _ = web.ReadFile(fmt.Sprintf("%s%s", dir, "/examples/data/b.text"), nil)
	ctx.Response.Attachment("text_b.text", body)

	body, _ = web.ReadFile(fmt.Sprintf("%s%s", dir, "/examples/data/c.text"), nil)
	ctx.Response.Inline("text_c.text", body)

	return ctx.Response.Bytes(
		web.StatusOK,
		web.ContentTypeApplicationJSON,
		[]byte("{ \"welcome\": \""+ctx.Request.UrlParams["name"][0]+"\" }"),
	)
}

func HandlerHelloForUploadFiles(ctx *web.Context) error {
	fmt.Println("HELLO I'M THE HELLO HANDER FOR UPLOAD FILES")

	fmt.Printf("\nAttachments: %+v\n", ctx.Request.FormData)
	return ctx.Response.Bytes(
		web.StatusOK,
		web.ContentTypeApplicationJSON,
		[]byte("{ \"welcome\": \""+ctx.Request.UrlParams["name"][0]+"\" }"),
	)
}

func HandlerFormDataForGet(ctx *web.Context) error {
	fmt.Println("HANDLING FORM DATA FOR GET")

	fmt.Printf("\nreceived")
	fmt.Printf("\nvar_one: %s", ctx.Request.GetFormDataString("var_one"))
	fmt.Printf("\nvar_two: %s", ctx.Request.GetFormDataString("var_two"))

	ctx.Response.SetFormData("var_one", "one")
	ctx.Response.SetFormData("var_two", "2")

	return ctx.Response.Bytes(
		web.StatusOK,
		web.ContentTypeApplicationJSON,
		[]byte("{ \"welcome\": \"form-data\" }"),
	)
}

func HandlerUrlFormDataForGet(ctx *web.Context) error {
	fmt.Println("HANDLING URL FORM DATA FOR GET")

	fmt.Printf("\nreceived")
	fmt.Printf("\nvar_one: %s", ctx.Request.GetFormDataString("var_one"))
	fmt.Printf("\nvar_two: %s", ctx.Request.GetFormDataString("var_two"))

	ctx.Response.SetFormData("var_one", "one")
	ctx.Response.SetFormData("var_two", "2")

	return ctx.Response.Bytes(
		web.StatusOK,
		web.ContentTypeApplicationJSON,
		[]byte("{ \"welcome\": \"form-data\" }"),
	)
}
Client
func main() {
	// create a new client
	c, err := web.NewClient(web.WithClientMultiAttachmentMode(web.MultiAttachmentModeBoundary))
	if err != nil {
		panic(err)
	}

	requestGet(c)
	requestPost(c)

	requestGetBoundary(c)

	requestAuthBasic(c)
	requestAuthJwt(c)

	requestOptionsOK(c)
	requestOptionsNotFound(c)

	bindFormData(c)
	bindUrlFormData(c)
}

func requestGet(c *web.Client) {
	request, err := c.NewRequest(web.MethodGet, "localhost:9001/hello/joao?a=1&b=2&c=1,2,3", web.ContentTypeApplicationJSON, nil)
	if err != nil {
		panic(err)
	}

	response, err := request.Send()
	if err != nil {
		panic(err)
	}

	fmt.Printf("%+v", response)
}

func requestPost(c *web.Client) {
	request, err := c.NewRequest(web.MethodPost, "localhost:9001/hello/joao?a=1&b=2&c=1,2,3", web.ContentTypeApplicationJSON, nil)
	if err != nil {
		panic(err)
	}

	data := struct {
		Name string `json:"name"`
		Age  int    `json:"age"`
	}{
		Name: "joao",
		Age:  30,
	}

	bytes, _ := json.Marshal(data)

	response, err := request.WithBody(bytes).Send()
	if err != nil {
		panic(err)
	}

	fmt.Printf("%+v\n", string(response.Body))
}

func requestGetBoundary(c *web.Client) {
	request, err := c.NewRequest(web.MethodGet, "localhost:9001/hello/joao/download", web.ContentTypeApplicationJSON, nil)
	if err != nil {
		panic(err)
	}

	response, err := request.Send()
	if err != nil {
		panic(err)
	}

	fmt.Printf("%+v", response)
}

func requestOptionsOK(c *web.Client) {
	request, err := c.NewRequest(web.MethodOptions, "localhost:9001/auth-basic", web.ContentTypeApplicationJSON, nil)
	if err != nil {
		panic(err)
	}

	_, err = request.WithAuthBasic("joao", "ribeiro")
	if err != nil {
		panic(err)
	}

	request.SetHeader(web.HeaderAccessControlRequestMethod, []string{string(web.MethodGet)})
	response, err := request.Send()
	if err != nil {
		panic(err)
	}

	fmt.Printf("\n\n%d: %s\n\n", response.Status, string(response.Body))
}

func requestOptionsNotFound(c *web.Client) {
	request, err := c.NewRequest(web.MethodOptions, "localhost:9001/auth-basic-invalid", web.ContentTypeApplicationJSON, nil)
	if err != nil {
		panic(err)
	}

	_, err = request.WithAuthBasic("joao", "ribeiro")
	if err != nil {
		panic(err)
	}

	request.SetHeader(web.HeaderAccessControlRequestMethod, []string{string(web.MethodGet)})
	response, err := request.Send()
	if err != nil {
		panic(err)
	}

	fmt.Printf("\n\n%d: %s\n\n", response.Status, string(response.Body))
}

func requestAuthBasic(c *web.Client) {
	request, err := c.NewRequest(web.MethodGet, "localhost:9001/auth-basic", web.ContentTypeApplicationJSON, nil)
	if err != nil {
		panic(err)
	}

	_, err = request.WithAuthBasic("joao", "ribeiro")
	if err != nil {
		panic(err)
	}

	response, err := request.Send()
	if err != nil {
		panic(err)
	}

	fmt.Printf("\n\n%d: %s\n\n", response.Status, string(response.Body))
}

func requestAuthJwt(c *web.Client) {
	request, err := c.NewRequest(web.MethodGet, "localhost:9001/auth-jwt", web.ContentTypeApplicationJSON, nil)
	if err != nil {
		panic(err)
	}

	_, err = request.WithAuthJwt(jwt.Claims{"name": "joao", "age": 30}, "bananas")
	if err != nil {
		panic(err)
	}

	response, err := request.Send()
	if err != nil {
		panic(err)
	}

	fmt.Printf("\n\n%d: %s\n\n", response.Status, string(response.Body))
}

func bindFormData(c *web.Client) {
	request, err := c.NewRequest(web.MethodGet, "localhost:9001/form-data", web.ContentTypeMultipartFormData, nil)
	if err != nil {
		panic(err)
	}

	request.SetFormData("var_one", "one")
	request.SetFormData("var_two", "2")

	response, err := request.Send()
	if err != nil {
		panic(err)
	}

	formData := struct {
		VarOne string `json:"var_one"`
		VarTwo int    `json:"var_two"`
	}{}

	if err := response.BindFormData(&formData); err != nil {
		fmt.Println(err)
	}

	fmt.Printf("\nvar_one: %s", response.GetFormDataString("var_one"))
	fmt.Printf("\nvar_two: %s", response.GetFormDataString("var_two"))

	fmt.Printf("\n\nFORM DATA: %+v\n", formData)
}

func bindUrlFormData(c *web.Client) {
	request, err := c.NewRequest(web.MethodGet, "localhost:9001/url-form-data", web.ContentTypeApplicationForm, nil)
	if err != nil {
		panic(err)
	}

	request.SetFormData("var_one", "one")
	request.SetFormData("var_two", "2")

	response, err := request.Send()
	if err != nil {
		panic(err)
	}

	formData := struct {
		VarOne string `json:"var_one"`
		VarTwo int    `json:"var_two"`
	}{}

	if err := response.BindFormData(&formData); err != nil {
		fmt.Println(err)
	}

	fmt.Printf("\nvar_one: %s", response.GetFormDataString("var_one"))
	fmt.Printf("\nvar_two: %s", response.GetFormDataString("var_two"))

	fmt.Printf("\n\nURL FORM DATA: %+v\n", formData)
}

Known issues

Follow me at

Facebook: https://www.facebook.com/joaosoft

LinkedIn: https://www.linkedin.com/in/jo%C3%A3o-ribeiro-b2775438/

If you have something to add, please let me know joaosoft@gmail.com

Documentation

Index

Constants

View Source
const (
	HeaderTimeFormat = "Mon, 02 Jan 2006 15:04:05 GMT"
	TimeFormat       = time.RFC3339
	RegexForURL      = "^((http|https)://)?(www)?[a-zA-Z0-9-._:/?&=,%]+$"
)
View Source
const (
	// Headers
	HeaderAccept              = "Accept"
	HeaderAcceptEncoding      = "Accept-Encoding"
	HeaderAllow               = "Allow"
	HeaderOrigin              = "Origin"
	HeaderAuthorization       = "Authorization"
	HeaderContentDisposition  = "Content-Disposition"
	HeaderContentEncoding     = "Content-Encoding"
	HeaderContentLength       = "Content-Length"
	HeaderContentType         = "Content-Type"
	HeaderCookie              = "Cookie"
	HeaderSetCookie           = "Set-Cookie"
	HeaderIfModifiedSince     = "If-Modified-Since"
	HeaderLastModified        = "Last-Modified"
	HeaderLocation            = "Location"
	HeaderUpgrade             = "Upgrade"
	HeaderVary                = "Vary"
	HeaderWWWAuthenticate     = "WWW-Authenticate"
	HeaderXForwardedFor       = "X-Forwarded-For"
	HeaderXForwardedProto     = "X-Forwarded-Proto"
	HeaderXForwardedProtocol  = "X-Forwarded-Protocol"
	HeaderXForwardedSsl       = "X-Forwarded-Ssl"
	HeaderXUrlScheme          = "X-Url-Scheme"
	HeaderXHTTPMethodOverride = "X-HTTP-Method-Override"
	HeaderXRealIP             = "X-Real-IP"
	HeaderXRequestID          = "X-Request-ID"
	HeaderXRequestedWith      = "X-Requested-With"
	HeaderServer              = "Server"
	HeaderDate                = "Date"
	HeaderHost                = "Host"
	HeaderMimeVersion         = "MIME-Version"
	HeaderUserAgent           = "User-Agent"
	HeaderTransferEncoding    = "Transfer-Encoding"

	// Access control
	HeaderAccessControlRequestMethod    = "Access-Control-Request-Method"
	HeaderAccessControlRequests         = "Access-Control-Request-s"
	HeaderAccessControlAllowOrigin      = "Access-Control-Allow-Origin"
	HeaderAccessControlAllowMethods     = "Access-Control-Allow-Methods"
	HeaderAccessControlAllows           = "Access-Control-Allow-s"
	HeaderAccessControlAllowCredentials = "Access-Control-Allow-Credentials"
	HeaderAccessControlAllowHeaders     = "Access-Control-Allow-Headers"
	HeaderAccessControlExposes          = "Access-Control-Expose-s"
	HeaderAccessControlMaxAge           = "Access-Control-Max-Age"

	// Security
	HeaderStrictTransportSecurity = "Strict-Transport-Security"
	HeaderXContentTypeOptions     = "X-Content-Type-MiddlewareOptions"
	HeaderXXSSProtection          = "X-XSS-Protection"
	HeaderXFrameOptions           = "X-Frame-MiddlewareOptions"
	HeaderContentSecurityPolicy   = "Content-Security-Policy"
	HeaderXCSRFToken              = "X-CSRF-Token"
)

Variables

View Source
var (
	ErrorNotFound     = NewError(StatusNotFound, "route not found")
	ErrorInvalidChunk = NewError(StatusNotFound, "invalid chunk length")
)
View Source
var (
	ErrorInvalidAuthorization = errors.New(errors.LevelError, http.StatusUnauthorized, "invalid authorization")
)

Functions

func ConvertPathToRegex

func ConvertPathToRegex(path string) string

func CopyDir

func CopyDir(src string, dst string) error

CopyDir copies a whole directory recursively

func CopyFile

func CopyFile(src, dst string) error

CopyFile copies a single file from src to dst

func DetectContentType

func DetectContentType(extension string, data []byte) (ContentType, Charset)

func Exists

func Exists(file string) bool

func GetEnv

func GetEnv() string

func GetFreePort

func GetFreePort() (int, error)

func GetFunctionName

func GetFunctionName(i interface{}) string

func GetMimeType

func GetMimeType(fileName string) (mimeType string)

func NewSimpleConfig

func NewSimpleConfig(file string, obj interface{}) error

func RandomBoundary

func RandomBoundary() string

func ReadFile

func ReadFile(file string, obj interface{}) ([]byte, error)

func ReadFileLines

func ReadFileLines(file string) ([]string, error)

func StatusText

func StatusText(code Status) string

StatusText returns a text for the HTTP status code. It returns the empty string if the code is unknown.

func WriteFile

func WriteFile(file string, obj interface{}) error

Types

type Address

type Address struct {
	Full      string
	Schema    Schema
	Url       string
	ParamsUrl string
	Host      string
	Params    Params
}

func NewAddress

func NewAddress(url string) *Address

type AppClientConfig

type AppClientConfig struct {
	Client ClientConfig `json:"client"`
}

func NewClientConfig

func NewClientConfig() (*AppClientConfig, error)

type AppServerConfig

type AppServerConfig struct {
	Server ServerConfig `json:"server"`
}

func NewServerConfig

func NewServerConfig() (*AppServerConfig, error)

type Attachment

type Attachment struct {
	*Data
}

type Base

type Base struct {
	IP          string
	Address     *Address
	Method      Method
	Protocol    Protocol
	Headers     Headers
	Cookies     Cookies
	ContentType ContentType
	Params      Params
	UrlParams   UrlParams
	Charset     Charset

	Server *Server
	Client *Client
	// contains filtered or unexported fields
}

func (*Base) BindHeaders

func (r *Base) BindHeaders(obj interface{}) error

func (*Base) BindParams

func (r *Base) BindParams(obj interface{}) error

func (*Base) BindUrlParams

func (r *Base) BindUrlParams(obj interface{}) error

func (*Base) GetCharset

func (r *Base) GetCharset() Charset

func (*Base) GetContentType

func (r *Base) GetContentType() *ContentType

func (*Base) GetCookie

func (r *Base) GetCookie(name string) *Cookie

func (*Base) GetHeader

func (r *Base) GetHeader(name string) string

func (*Base) GetParam

func (r *Base) GetParam(name string) string

func (*Base) GetParams

func (r *Base) GetParams(name string) []string

func (*Base) GetUrlParam

func (r *Base) GetUrlParam(name string) string

func (*Base) GetUrlParams

func (r *Base) GetUrlParams(name string) []string

func (*Base) SetCharset

func (r *Base) SetCharset(charset Charset)

func (*Base) SetContentType

func (r *Base) SetContentType(contentType ContentType)

func (*Base) SetCookie

func (r *Base) SetCookie(name string, cookie Cookie)

func (*Base) SetHeader

func (r *Base) SetHeader(name string, header []string)

func (*Base) SetParam

func (r *Base) SetParam(name string, param []string)

func (*Base) SetUrlParam

func (r *Base) SetUrlParam(name string, urlParam []string)

type Charset

type Charset string
const (
	CharsetUTF8    Charset = "utf-8"
	CharsetUTF16be Charset = "utf-16be"
	CharsetUTF16le Charset = "utf-16le"
)

type Client

type Client struct {
	// contains filtered or unexported fields
}

func NewClient

func NewClient(options ...ClientOption) (*Client, error)

func (*Client) Config

func (c *Client) Config() *ClientConfig

func (*Client) NewRequest

func (c *Client) NewRequest(method Method, url string, contentType ContentType, headers Headers) (*Request, error)

func (*Client) NewResponse

func (c *Client) NewResponse(method Method, address *Address, conn net.Conn) (*Response, error)

func (*Client) Reconfigure

func (c *Client) Reconfigure(options ...ClientOption)

Reconfigure ...

func (*Client) Send

func (c *Client) Send(request *Request) (*Response, error)

type ClientConfig

type ClientConfig struct {
	Log Log `json:"log"`
}

type ClientOption

type ClientOption func(builder *Client)

ClientOption ...

func WithClientConfiguration

func WithClientConfiguration(config *ClientConfig) ClientOption

WithClientConfiguration ...

func WithClientLogLevel

func WithClientLogLevel(level logger.Level) ClientOption

WithClientLogLevel ...

func WithClientLogger

func WithClientLogger(logger logger.ILogger) ClientOption

WithClientLogger ...

func WithClientMultiAttachmentMode

func WithClientMultiAttachmentMode(mode MultiAttachmentMode) ClientOption

WithClientMultiAttachmentMode ...

type Content

type Content struct {
	// contains filtered or unexported fields
}

type ContentDisposition

type ContentDisposition string

Mime type

const (
	ContentDispositionInline     ContentDisposition = "inline"
	ContentDispositionAttachment ContentDisposition = "attachment"
	ContentDispositionFormData   ContentDisposition = "form-data"
)

type ContentType

type ContentType string

Mime type

const (
	ContentTypeEmpty                  ContentType = ""
	ContentTypeApplicationJSON        ContentType = "application/json"
	ContentTypeApplicationJavaScript  ContentType = "application/javascript"
	ContentTypeApplicationXML         ContentType = "application/xml"
	ContentTypeTextXML                ContentType = "text/xml"
	ContentTypeTextCSV                ContentType = "text/csv"
	ContentTypeApplicationForm        ContentType = "application/x-www-form-urlencoded"
	ContentTypeApplicationProtobuf    ContentType = "application/protobuf"
	ContentTypeApplicationMsgpack     ContentType = "application/msgpack"
	ContentTypeTextHTML               ContentType = "text/html"
	ContentTypeTextPlain              ContentType = "text/plain"
	ContentTypeMultipartFormData      ContentType = "multipart/form-data"
	ContentTypeMultipartMixed         ContentType = "multipart/mixed"
	ContentTypeApplicationOctetStream ContentType = "application/octet-stream"
	ContentTypeApplicationZip         ContentType = "application/zip"
	ContentTypeApplication7z          ContentType = "application/x-7z-compressed"
	ContentTypeApplicationGzip        ContentType = "application/x-gzip"
	ContentTypeVideoMp4               ContentType = "video/mp4"
	ContentTypeApplicationPdf         ContentType = "application/pdf"
	ContentTypeApplicationPostScript  ContentType = "application/postscript"
	ContentTypeImageGif               ContentType = "image/gif"
	ContentTypeImagePng               ContentType = "image/png"
	ContentTypeImageJpeg              ContentType = "image/jpeg"
	ContentTypeImageBmp               ContentType = "image/bmp"
	ContentTypeImageWebp              ContentType = "image/webp"
	ContentTypeImageVnd               ContentType = "image/vnd.microsoft.icon"
	ContentTypeAudioWave              ContentType = "audio/wave"
	ContentTypeAudioAiff              ContentType = "audio/aiff"
	ContentTypeAudioBasic             ContentType = "audio/basic"
	ContentTypeApplicationOgg         ContentType = "application/ogg"
	ContentTypeAudioMidi              ContentType = "audio/midi"
	ContentTypeAudioMpeg              ContentType = "audio/mpeg"
	ContentTypeVideoAvi               ContentType = "video/avi"
	ContentTypeApplicationVnd         ContentType = "application/vnd.ms-fontobject"
	ContentTypeApplicationFontTtf     ContentType = "application/font-ttf"
	ContentTypeApplicationFontOff     ContentType = "application/font-off"
	ContentTypeApplicationFontCff     ContentType = "application/font-cff"
	ContentTypeApplicationFontWoff    ContentType = "application/font-woff"
	ContentTypeApplicationVideoWebm   ContentType = "video/webm"
	ContentTypeApplicationRar         ContentType = "application/x-rar-compressed"
)

type Context

type Context struct {
	StartTime time.Time
	Request   *Request
	Response  *Response
}

func NewContext

func NewContext(startTime time.Time, request *Request, response *Response) *Context

func (*Context) Redirect

func (ctx *Context) Redirect(host string) error
type Cookie struct {
	Name    string
	Value   string
	Path    string    // optional
	Domain  string    // optional
	Expires time.Time // optional
	// MaxAge=0 means no 'Max-Age' attribute specified.
	// MaxAge<0 means delete cookie now, equivalently 'Max-Age: 0'
	// MaxAge>0 means Max-Age attribute present and given in seconds
	MaxAge   int
	Secure   bool
	HttpOnly bool
}

type Cookies

type Cookies map[string]Cookie

type Data

type Data struct {
	ContentType        ContentType
	ContentDisposition ContentDisposition
	Charset            Charset
	Name               string
	FileName           string
	Body               []byte
	IsAttachment       bool
}

type Encoding

type Encoding string
const (
	EncodingNone     Encoding = "none"
	EncodingChunked  Encoding = "chunked"
	EncodingCompress Encoding = "compress"
	EncodingDeflate  Encoding = "deflate"
	EncodingGzip     Encoding = "gzip"
	EncodingIdentity Encoding = "identity"
)

type Error

type Error struct {
	Status  Status `json:"status"`
	Message string `json:"message"`
}

func NewError

func NewError(status Status, messages ...string) *Error

func (*Error) Error

func (e *Error) Error() string

type ErrorHandler

type ErrorHandler func(ctx *Context, err error) error

type Filter

type Filter struct {
	Method     Method
	Position   Position
	Pattern    string
	Regex      string
	Middleware MiddlewareFunc
}

func NewFilter

func NewFilter(method Method, pattern string, position Position, middleware MiddlewareFunc) *Filter

type Filters

type Filters map[Position]map[Method][]*Filter

func (Filters) AddFilter

func (f Filters) AddFilter(pattern string, position Position, middleware MiddlewareFunc, method Method, methods ...Method)

type FormData

type FormData struct {
	*Data
}

type HandlerFunc

type HandlerFunc func(ctx *Context) error

type Headers

type Headers map[string][]string

type Log

type Log struct {
	Level string `json:"level"`
}

type Method

type Method string
const (
	MethodConnect  Method = "CONNECT"
	MethodGet      Method = "GET"
	MethodHead     Method = "HEAD"
	MethodPost     Method = "POST"
	MethodPut      Method = "PUT"
	MethodPatch    Method = "PATCH"
	MethodDelete   Method = "DELETE"
	MethodOptions  Method = "OPTIONS"
	MethodTrace    Method = "TRACE"
	MethodCopy     Method = "COPY"
	MethodView     Method = "VIEW"
	MethodLink     Method = "LINK"
	MethodUnlink   Method = "UNLINK"
	MethodPurge    Method = "PURGE"
	MethodLock     Method = "LOCK"
	MethodUnlock   Method = "UNLOCK"
	MethodPropFind Method = "PROPFIND"
	MethodAny      Method = "ANY"
)

type MiddlewareFunc

type MiddlewareFunc func(HandlerFunc) HandlerFunc

func MiddlewareCheckAuthBasic

func MiddlewareCheckAuthBasic(user, password string) MiddlewareFunc

func MiddlewareCheckAuthJwt

func MiddlewareCheckAuthJwt(keyFunc jwt.KeyFunc, checkFunc jwt.CheckFunc) MiddlewareFunc

func MiddlewareOptions

func MiddlewareOptions() MiddlewareFunc

type MimeVersion

type MimeVersion string
const (
	MimeVersion1 MimeVersion = "1.0"
)

type MultiAttachmentMode

type MultiAttachmentMode string
const (
	MultiAttachmentModeBoundary MultiAttachmentMode = "boundary"
	MultiAttachmentModeZip      MultiAttachmentMode = "zip"
)

type Namespace

type Namespace struct {
	Path        string
	Middlewares []MiddlewareFunc
	WebServer   *Server
}

func (*Namespace) AddRoute

func (n *Namespace) AddRoute(method Method, path string, handler HandlerFunc, middleware ...MiddlewareFunc) error

func (*Namespace) AddRoutes

func (n *Namespace) AddRoutes(route ...*Route) error

type Params

type Params map[string][]string

func (Params) String

func (p Params) String() string

type Position

type Position string
const (
	PositionBefore  Position = "BEFORE"
	PositionBetween Position = "BETWEEN"
	PositionAfter   Position = "AFTER"
)

type Protocol

type Protocol string
const (
	ProtocolHttp0p9 Protocol = "HTTP/0.9"
	ProtocolHttp1p0 Protocol = "HTTP/1.0"
	ProtocolHttp1p1 Protocol = "HTTP/1.1"
	ProtocolHttp2   Protocol = "HTTP/2"
)

type Request

type Request struct {
	Base
	Body                []byte
	FormData            map[string]*FormData
	Attachments         map[string]*Attachment
	MultiAttachmentMode MultiAttachmentMode
	Boundary            string
	Reader              io.Reader
	Writer              io.Writer
}

func (*Request) Attachment

func (r *Request) Attachment(name string, body []byte) error

func (*Request) Bind

func (r *Request) Bind(obj interface{}) error

func (*Request) BindFormData

func (r *Request) BindFormData(obj interface{}) error

func (*Request) Bytes

func (r *Request) Bytes(contentType ContentType, b []byte) error

func (*Request) File

func (r *Request) File(name string, body []byte) error

func (*Request) GetFormDataBytes

func (r *Request) GetFormDataBytes(name string) []byte

func (*Request) GetFormDataString

func (r *Request) GetFormDataString(name string) string

func (*Request) HTML

func (r *Request) HTML(body string) error

func (*Request) Inline

func (r *Request) Inline(name string, body []byte) error

func (*Request) JSON

func (r *Request) JSON(i interface{}) error

func (*Request) JSONPretty

func (r *Request) JSONPretty(i interface{}, indent string) error

func (*Request) Send

func (r *Request) Send() (*Response, error)

func (*Request) Set

func (r *Request) Set(contentType ContentType, b []byte) error

func (*Request) SetFormData

func (r *Request) SetFormData(name string, value string)

func (*Request) Stream

func (r *Request) Stream(contentType ContentType, reader io.Reader) error

func (*Request) String

func (r *Request) String(s string) error

func (*Request) WithAuthBasic

func (r *Request) WithAuthBasic(username, password string) (*Request, error)

func (*Request) WithAuthJwt

func (r *Request) WithAuthJwt(claims jwt.Claims, key interface{}) (*Request, error)

func (*Request) WithBody

func (r *Request) WithBody(body []byte) *Request

func (*Request) WithContentType

func (r *Request) WithContentType(contentType ContentType) *Request

func (*Request) XML

func (r *Request) XML(i interface{}) error

func (*Request) XMLPretty

func (r *Request) XMLPretty(i interface{}, indent string) error

type RequestHandler

type RequestHandler struct {
	Conn    net.Conn
	Handler HandlerFunc
}

type Response

type Response struct {
	Base
	Body                []byte
	Status              Status
	StatusText          string
	FormData            map[string]*FormData
	Attachments         map[string]*Attachment
	MultiAttachmentMode MultiAttachmentMode
	Boundary            string
	Reader              io.Reader
	Writer              io.Writer
}

func (*Response) Attachment

func (r *Response) Attachment(name string, body []byte) error

func (*Response) Bind

func (r *Response) Bind(i interface{}) error

func (*Response) BindFormData

func (r *Response) BindFormData(obj interface{}) error

func (*Response) Bytes

func (r *Response) Bytes(status Status, contentType ContentType, b []byte) error

func (*Response) File

func (r *Response) File(status Status, name string, body []byte) error

func (*Response) GetFormDataBytes

func (r *Response) GetFormDataBytes(name string) []byte

func (*Response) GetFormDataString

func (r *Response) GetFormDataString(name string) string

func (*Response) HTML

func (r *Response) HTML(status Status, body string) error

func (*Response) Inline

func (r *Response) Inline(name string, body []byte) error

func (*Response) JSON

func (r *Response) JSON(status Status, i interface{}) error

func (*Response) JSONPretty

func (r *Response) JSONPretty(status Status, i interface{}, indent string) error

func (*Response) NoContent

func (r *Response) NoContent(status Status) error

func (*Response) Set

func (r *Response) Set(status Status, contentType ContentType, b []byte) error

func (*Response) SetFormData

func (r *Response) SetFormData(name string, value string)

func (*Response) Stream

func (r *Response) Stream(status Status, contentType ContentType, reader io.Reader) error

func (*Response) String

func (r *Response) String(status Status, s string) error

func (*Response) XML

func (r *Response) XML(status Status, i interface{}) error

func (*Response) XMLPretty

func (r *Response) XMLPretty(status Status, i interface{}, indent string) error

type Route

type Route struct {
	Method      Method
	Path        string
	Regex       string
	Name        string
	Handler     HandlerFunc
	Middlewares []MiddlewareFunc
}

func NewRoute

func NewRoute(method Method, path string, handler HandlerFunc, middleware ...MiddlewareFunc) *Route

type Routes

type Routes map[Method][]Route

type Schema

type Schema string
const (
	SchemaNone  Schema = ""
	SchemaHttp  Schema = "http"
	SchemaHttps Schema = "https"
)

type Server

type Server struct {
	// contains filtered or unexported fields
}

func NewServer

func NewServer(options ...ServerOption) (*Server, error)

func (*Server) AddFilter

func (s *Server) AddFilter(pattern string, position Position, middleware MiddlewareFunc, method Method, methods ...Method)

func (*Server) AddMiddlewares

func (s *Server) AddMiddlewares(middlewares ...MiddlewareFunc)

func (*Server) AddNamespace

func (s *Server) AddNamespace(path string, middlewares ...MiddlewareFunc) *Namespace

func (*Server) AddRoute

func (s *Server) AddRoute(method Method, path string, handler HandlerFunc, middleware ...MiddlewareFunc) error

func (*Server) AddRoutes

func (s *Server) AddRoutes(route ...*Route) error

func (*Server) Config

func (s *Server) Config() *ServerConfig

func (*Server) DefaultErrorHandler

func (s *Server) DefaultErrorHandler(ctx *Context, err error) error

func (*Server) GetMatchedFilters

func (s *Server) GetMatchedFilters(filters map[Method][]*Filter, method Method, url string) ([]*Filter, error)

func (*Server) GetRoute

func (s *Server) GetRoute(method Method, url string) (*Route, error)

func (*Server) LoadUrlParms

func (s *Server) LoadUrlParms(request *Request, route *Route) error

func (*Server) NewRequest

func (s *Server) NewRequest(conn net.Conn, server *Server) (*Request, error)

func (*Server) NewResponse

func (s *Server) NewResponse(request *Request) *Response

func (*Server) Reconfigure

func (s *Server) Reconfigure(options ...ServerOption)

Reconfigure ...

func (*Server) SetErrorHandler

func (s *Server) SetErrorHandler(handler ErrorHandler) error

func (*Server) Start

func (s *Server) Start(waitGroup ...*sync.WaitGroup) error

func (*Server) Started

func (s *Server) Started() bool

func (*Server) Stop

func (s *Server) Stop(waitGroup ...*sync.WaitGroup) error

type ServerConfig

type ServerConfig struct {
	Address string `json:"address"`
	Log     struct {
		Level string `json:"level"`
	} `json:"log"`
}

type ServerOption

type ServerOption func(builder *Server)

ServerOption ...

func WithServerAddress

func WithServerAddress(address string) ServerOption

WithServerAddress ...

func WithServerConfiguration

func WithServerConfiguration(config *ServerConfig) ServerOption

WithServerConfiguration ...

func WithServerLogLevel

func WithServerLogLevel(level logger.Level) ServerOption

WithServerLogLevel ...

func WithServerLogger

func WithServerLogger(logger logger.ILogger) ServerOption

WithServerLogger ...

func WithServerMultiAttachmentMode

func WithServerMultiAttachmentMode(mode MultiAttachmentMode) ServerOption

WithServerMultiAttachmentMode ...

func WithServerName

func WithServerName(name string) ServerOption

WithServerName ...

type Status

type Status int

HTTP status codes as registered with IANA. See: http://www.iana.org/assignments/http-status-codes/http-status-codes.xhtml

const (
	StatusContinue           Status = 100 // RFC 7231, 6.2.1
	StatusSwitchingProtocols Status = 101 // RFC 7231, 6.2.2
	StatusProcessing         Status = 102 // RFC 2518, 10.1

	StatusOK                   Status = 200 // RFC 7231, 6.3.1
	StatusCreated              Status = 201 // RFC 7231, 6.3.2
	StatusAccepted             Status = 202 // RFC 7231, 6.3.3
	StatusNonAuthoritativeInfo Status = 203 // RFC 7231, 6.3.4
	StatusNoContent            Status = 204 // RFC 7231, 6.3.5
	StatusResetContent         Status = 205 // RFC 7231, 6.3.6
	StatusPartialContent       Status = 206 // RFC 7233, 4.1
	StatusMultiStatus          Status = 207 // RFC 4918, 11.1
	StatusAlreadyReported      Status = 208 // RFC 5842, 7.1
	StatusIMUsed               Status = 226 // RFC 3229, 10.4.1

	StatusMultipleChoices  Status = 300 // RFC 7231, 6.4.1
	StatusMovedPermanently Status = 301 // RFC 7231, 6.4.2
	StatusFound            Status = 302 // RFC 7231, 6.4.3
	StatusSeeOther         Status = 303 // RFC 7231, 6.4.4
	StatusNotModified      Status = 304 // RFC 7232, 4.1
	StatusUseProxy         Status = 305 // RFC 7231, 6.4.5

	StatusTemporaryRedirect Status = 307 // RFC 7231, 6.4.7
	StatusPermanentRedirect Status = 308 // RFC 7538, 3

	StatusBadRequest                   Status = 400 // RFC 7231, 6.5.1
	StatusUnauthorized                 Status = 401 // RFC 7235, 3.1
	StatusPaymentRequired              Status = 402 // RFC 7231, 6.5.2
	StatusForbidden                    Status = 403 // RFC 7231, 6.5.3
	StatusNotFound                     Status = 404 // RFC 7231, 6.5.4
	StatusMethodNotAllowed             Status = 405 // RFC 7231, 6.5.5
	StatusNotAcceptable                Status = 406 // RFC 7231, 6.5.6
	StatusProxyAuthRequired            Status = 407 // RFC 7235, 3.2
	StatusRequestTimeout               Status = 408 // RFC 7231, 6.5.7
	StatusConflict                     Status = 409 // RFC 7231, 6.5.8
	StatusGone                         Status = 410 // RFC 7231, 6.5.9
	StatusLengthRequired               Status = 411 // RFC 7231, 6.5.10
	StatusPreconditionFailed           Status = 412 // RFC 7232, 4.2
	StatusRequestEntityTooLarge        Status = 413 // RFC 7231, 6.5.11
	StatusRequestURITooLong            Status = 414 // RFC 7231, 6.5.12
	StatusUnsupportedMediaType         Status = 415 // RFC 7231, 6.5.13
	StatusRequestedRangeNotSatisfiable Status = 416 // RFC 7233, 4.4
	StatusExpectationFailed            Status = 417 // RFC 7231, 6.5.14
	StatusTeapot                       Status = 418 // RFC 7168, 2.3.3
	StatusUnprocessableEntity          Status = 422 // RFC 4918, 11.2
	StatusLocked                       Status = 423 // RFC 4918, 11.3
	StatusFailedDependency             Status = 424 // RFC 4918, 11.4
	StatusUpgradeRequired              Status = 426 // RFC 7231, 6.5.15
	StatusPreconditionRequired         Status = 428 // RFC 6585, 3
	StatusTooManyRequests              Status = 429 // RFC 6585, 4
	StatusRequestHeaderFieldsTooLarge  Status = 431 // RFC 6585, 5
	StatusUnavailableForLegalReasons   Status = 451 // RFC 7725, 3

	StatusInternalServerError           Status = 500 // RFC 7231, 6.6.1
	StatusNotImplemented                Status = 501 // RFC 7231, 6.6.2
	StatusBadGateway                    Status = 502 // RFC 7231, 6.6.3
	StatusServiceUnavailable            Status = 503 // RFC 7231, 6.6.4
	StatusGatewayTimeout                Status = 504 // RFC 7231, 6.6.5
	StatusHTTPVersionNotSupported       Status = 505 // RFC 7231, 6.6.6
	StatusVariantAlsoNegotiates         Status = 506 // RFC 2295, 8.1
	StatusInsufficientStorage           Status = 507 // RFC 4918, 11.5
	StatusLoopDetected                  Status = 508 // RFC 5842, 7.2
	StatusNotExtended                   Status = 510 // RFC 2774, 7
	StatusNetworkAuthenticationRequired Status = 511 // RFC 6585, 6
)

type UrlParams

type UrlParams map[string][]string

Directories

Path Synopsis
examples

Jump to

Keyboard shortcuts

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