README

Flamingo web features

This package mainly contains the framework web support for:

Expand ▾ Collapse ▴

Documentation

Index

Examples

Constants

const (
	// CacheVisibilityPrivate is used as visibility in CacheDirective to indiate no store in intermediate caches
	CacheVisibilityPrivate = "private"
	// CacheVisibilityPublic is used as visibility in CacheDirective to indicate that response can be stored also in intermediate caches
	CacheVisibilityPublic = "public"
)

const (
	// FlamingoError is the Controller name for errors
	FlamingoError = "flamingo.error"
	// FlamingoNotfound is the Controller name for 404 notfound
	FlamingoNotfound = "flamingo.notfound"
)

Variables

var (

	// ControllerKey exposes the current controller/handler key
	ControllerKey, _ = tag.NewKey("controller")

	// RouterError defines error value for issues appearing during routing process
	RouterError contextKeyType = "error"
)

var (
	// ErrFormNotFound is returned for unknown form values
	ErrFormNotFound = errors.New("form value not found")

	// ErrQueryNotFound is returned for unknown URL query parameters
	ErrQueryNotFound = errors.New("query value not found")
)

Functions

func AddHTTPHeader

func AddHTTPHeader(target, source http.Header)

AddHTTPHeader adds the sources http.Header to the target.

func BindRoutes

func BindRoutes(injector *dingo.Injector, m RoutesModule)

BindRoutes is a convenience helper to multi-bind router modules

func ContextWithRequest

func ContextWithRequest(ctx context.Context, r *Request) context.Context

ContextWithRequest stores the request in a new context

func ContextWithSession

func ContextWithSession(ctx context.Context, session *Session) context.Context

ContextWithSession returns a new Context with an attached session

func HandlerCmd

func HandlerCmd(router *Router, area *config.Area) *cobra.Command

HandlerCmd for debugging the router/handler configuration

func RoutesCmd

func RoutesCmd(router *Router, area *config.Area) *cobra.Command

RoutesCmd for debugging the router configuration

func RunWithDetachedContext

func RunWithDetachedContext(origCtx context.Context, fnc func(ctx context.Context))

RunWithDetachedContext returns a context which is detached from the original deadlines, timeouts & co

func URLTitle

func URLTitle(title string) string

URLTitle normalizes a title for nice usage in URLs

Example

Example usage of the URLTitle helper function

Code:

fmt.Println(URLTitle("test/a 123 name % / _ - _ test"))
test_a-123-name-test

Types

type Action

type Action func(ctx context.Context, req *Request) Result

Action defines an explicit http action

func WrapDataAction

func WrapDataAction(da DataAction) Action

WrapDataAction allows to register a data action for a HTTP method

func WrapHTTPHandler

func WrapHTTPHandler(handler http.Handler) Action

WrapHTTPHandler wraps an http.Handler to be used in the flamingo http package

func (Action) ServeHTTP

func (a Action) ServeHTTP(rw http.ResponseWriter, r *http.Request)

type AreaRoutedEvent

type AreaRoutedEvent struct {
	ConfigArea *config.Area
}

AreaRoutedEvent is dispatched when the router initializes the Handler

type CacheDirective

type CacheDirective struct {
	// Visibility: private or public
	// a response marked “private” can be cached (by the browser) but such responses are typically intended for single users hence they aren’t cacheable by intermediate caches
	// A response that is marked “public” can be cached even in cases where it is associated with a HTTP authentication or the HTTP response status code is not cacheable normally. In most cases, a response marked “public” isn’t necessary, since explicit caching information (i.e. “max-age”) shows that a response is cacheable anyway.
	Visibility string
	// NoCache directive to tell this response can’t be used for subsequent requests to the same URL (browser might revalidate or not cache at all)
	NoCache bool
	// NoStore directive: disallows browsers and all intermediate caches from storing any versions of returned responses i.e. responses containing private/personal information or banking data. Every time users request this asset, requests are sent to the server. The assets are downloaded every time.
	NoStore bool
	// tells intermediate caches to not modify headers - especialle The Content-Encoding, Content-Range, and Content-Type headers must remain unchanged
	NoTransform bool
	// MustRevalidate directive is used to tell a cache that it must first revalidate an asset with the origin after it becomes stale
	MustRevalidate bool
	// ProxyRevalidate is the same as MustRevalidate for shared caches
	ProxyRevalidate bool
	// MaxAge defines the max-age directive states the maximum amount of time in seconds that fetched responses are allowed to be used again
	MaxAge int
	// SMaxAge defines the maxAge for shared caches. Supposed to override max-age for CDN for example
	SMaxAge int
	// ETag the key for the Response
	ETag string
	// LastModifiedSince indicates the time a document last changed
	LastModifiedSince *time.Time
}

CacheDirective holds the possible directives for Cache Control Headers and other Http Caching

func (*CacheDirective) ApplyHeaders

func (c *CacheDirective) ApplyHeaders(header http.Header)

ApplyHeaders sets the correct cache control headers

type CacheDirectiveBuilder

type CacheDirectiveBuilder struct {
	IsReusable              bool
	RevalidateEachTime      bool
	AllowIntermediateCaches bool
	MaxCacheLifetime        int
	ETag                    string
}

CacheDirectiveBuilder constructs a CacheDirective with the most commonly used options

func (CacheDirectiveBuilder) Build

func (c CacheDirectiveBuilder) Build() *CacheDirective

Build returns the CacheDirective based on the settings

type CanonicalDomainFunc

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

CanonicalDomainFunc is exported as a template function

func (*CanonicalDomainFunc) Func

func (c *CanonicalDomainFunc) Func(ctx context.Context) interface{}

Func returns the canonicalDomain func

func (*CanonicalDomainFunc) Inject

func (c *CanonicalDomainFunc) Inject(router ReverseRouter) *CanonicalDomainFunc

Inject dependencies

type DataAction

type DataAction func(ctx context.Context, req *Request, callParams RequestParams) interface{}

DataAction is a method called which does not return the web response itself, but data instead

type DataResponse

type DataResponse struct {
	Response
	Data interface{}
}

DataResponse returns a response containing data, e.g. as JSON

func (*DataResponse) Apply

func (r *DataResponse) Apply(c context.Context, w http.ResponseWriter) error

Apply response todo: support more than json

func (*DataResponse) SetNoCache

func (r *DataResponse) SetNoCache() *DataResponse

SetNoCache helper

func (*DataResponse) Status

func (r *DataResponse) Status(status uint) *DataResponse

Status changes response status code

type Filter

type Filter interface {
	Filter(ctx context.Context, req *Request, w http.ResponseWriter, fc *FilterChain) Result
}

Filter is an interface which can filter requests

type FilterChain

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

FilterChain defines the chain which contains all filters which will be worked off

func NewFilterChain

func NewFilterChain(final lastFilter, filters ...Filter) *FilterChain

NewFilterChain constructs and sets the final filter and optional filters

func (*FilterChain) AddPostApply

func (fc *FilterChain) AddPostApply(callback func(err error, result Result))

AddPostApply adds a callback to be called after the response has been applied to the responsewriter

func (*FilterChain) Next

func (fc *FilterChain) Next(ctx context.Context, req *Request, w http.ResponseWriter) Result

Next calls the next filter and deletes it of the chain

type GetPartialDataFunc

type GetPartialDataFunc struct{}

GetPartialDataFunc allows to get partial data

func (*GetPartialDataFunc) Func

func (*GetPartialDataFunc) Func(c context.Context) interface{}

Func getter to bind the context

type Handler

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

Handler defines a concrete Controller

func MustRoute

func MustRoute(handler *Handler, err error) *Handler

MustRoute checks the result of a `Route` call

func (*Handler) GetHandlerName

func (handler *Handler) GetHandlerName() string

GetHandlerName getter

func (*Handler) GetPath

func (handler *Handler) GetPath() string

GetPath getter

func (*Handler) Normalize

func (handler *Handler) Normalize(params ...string) *Handler

Normalize enforces a normalization of passed parameters

type IsExternalURL

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

IsExternalURL is exported as a template function

func (*IsExternalURL) Func

func (c *IsExternalURL) Func(ctx context.Context) interface{}

Func returns a boolean if a given URL is external

func (*IsExternalURL) Inject

func (c *IsExternalURL) Inject(router ReverseRouter) *IsExternalURL

Inject dependencies

type Match

type Match struct {
	Values map[string]string
}

Match is the result of matching a path

type OnFinishEvent

type OnFinishEvent struct {
	OnRequestEvent
	Error error
}

OnFinishEvent is the event object associated to OnFinish

type OnRequestEvent

type OnRequestEvent struct {
	Request        *Request
	ResponseWriter http.ResponseWriter
}

OnRequestEvent contains the bare request

type OnResponseEvent

type OnResponseEvent struct {
	OnRequestEvent
	Result Result
}

OnResponseEvent is the event associated to OnResponse

type Path

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

Path is a matchable routing path

func NewPath

func NewPath(path string) (*Path, error)

NewPath returns a new path

func (*Path) Match

func (p *Path) Match(path string) *Match

Match matches a given path

func (*Path) Render

func (p *Path) Render(values map[string]string, usedValues map[string]struct{}) (string, error)

Render a path for a given list of values

type RenderResponse

type RenderResponse struct {
	DataResponse
	Template string
	// contains filtered or unexported fields
}

RenderResponse renders data

func (*RenderResponse) Apply

func (r *RenderResponse) Apply(c context.Context, w http.ResponseWriter) error

Apply response

func (*RenderResponse) SetNoCache

func (r *RenderResponse) SetNoCache() *RenderResponse

SetNoCache helper

type Request

type Request struct {
	Params RequestParams
	Values sync.Map
	// contains filtered or unexported fields
}

Request object stores the actual HTTP Request, Session, Params and attached Values

func CreateRequest

func CreateRequest(r *http.Request, s *Session) *Request

CreateRequest creates a new request, with optional http.Request and Session. If any variable is nil it is ignored, otherwise it is copied into the new Request.

func RequestFromContext

func RequestFromContext(ctx context.Context) *Request

RequestFromContext retrieves the request from the context, if available

func (*Request) Form

func (r *Request) Form(name string) ([]string, error)

Form get POST value

func (*Request) Form1

func (r *Request) Form1(name string) (string, error)

Form1 get first POST value

func (*Request) FormAll

func (r *Request) FormAll() (map[string][]string, error)

FormAll get all POST values

func (*Request) Query

func (r *Request) Query(name string) ([]string, error)

Query looks up Raw Query map for Param

func (*Request) Query1

func (r *Request) Query1(name string) (string, error)

Query1 looks up Raw Query map for First Param

func (*Request) QueryAll

func (r *Request) QueryAll() url.Values

QueryAll returns a Map of the Raw Query

func (*Request) RemoteAddress

func (r *Request) RemoteAddress() []string

RemoteAddress get the requests real remote address

func (*Request) Request

func (r *Request) Request() *http.Request

Request getter

func (*Request) Session

func (r *Request) Session() *Session

Session getter

type RequestParams

type RequestParams map[string]string

RequestParams store string->string values for request data

type Responder

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

Responder generates responses

func (*Responder) Data

func (r *Responder) Data(data interface{}) *DataResponse

Data returns a data response which can be serialized

func (*Responder) Download

func (r *Responder) Download(data io.Reader, contentType string, fileName string, forceDownload bool) *Response

Download returns a download response to handle file downloads

func (*Responder) Forbidden

func (r *Responder) Forbidden(err error) *ServerErrorResponse

Forbidden creates a 403 error response

func (*Responder) HTTP

func (r *Responder) HTTP(status uint, body io.Reader) *Response

HTTP Response generator

func (*Responder) Inject

func (r *Responder) Inject(router *Router, logger flamingo.Logger, cfg *struct {
	Engine                flamingo.TemplateEngine `inject:",optional"`
	Debug                 bool                    `inject:"config:flamingo.debug.mode"`
	TemplateForbidden     string                  `inject:"config:flamingo.template.err403"`
	TemplateNotFound      string                  `inject:"config:flamingo.template.err404"`
	TemplateUnavailable   string                  `inject:"config:flamingo.template.err503"`
	TemplateErrorWithCode string                  `inject:"config:flamingo.template.errWithCode"`
}) *Responder

Inject Responder dependencies

func (*Responder) NotFound

func (r *Responder) NotFound(err error) *ServerErrorResponse

NotFound creates a 404 error response

func (*Responder) Render

func (r *Responder) Render(tpl string, data interface{}) *RenderResponse

Render creates a render response, with the supplied template and data

func (*Responder) RouteRedirect

func (r *Responder) RouteRedirect(to string, data map[string]string) *RouteRedirectResponse

RouteRedirect generator

func (*Responder) ServerError

func (r *Responder) ServerError(err error) *ServerErrorResponse

ServerError creates a 500 error response

func (*Responder) ServerErrorWithCodeAndTemplate

func (r *Responder) ServerErrorWithCodeAndTemplate(err error, tpl string, status uint) *ServerErrorResponse

ServerErrorWithCodeAndTemplate error response with template and http status code

func (*Responder) TODO

func (r *Responder) TODO() *Response

TODO creates a 501 Not Implemented response

func (*Responder) URLRedirect

func (r *Responder) URLRedirect(url *url.URL) *URLRedirectResponse

URLRedirect returns a 303 redirect to a given URL

func (*Responder) Unavailable

func (r *Responder) Unavailable(err error) *ServerErrorResponse

Unavailable creates a 503 error response

type Response

type Response struct {
	Status         uint
	Body           io.Reader
	Header         http.Header
	CacheDirective *CacheDirective
}

Response contains a status and a body

func (*Response) Apply

func (r *Response) Apply(c context.Context, w http.ResponseWriter) error

Apply response

func (*Response) SetNoCache

func (r *Response) SetNoCache() *Response

SetNoCache helper deprecated: use CacheControlHeader instead

type Result

type Result interface {
	// Apply executes the response on the http.ResponseWriter
	Apply(ctx context.Context, rw http.ResponseWriter) error
}

Result defines the generic web response

type ReverseRouter

type ReverseRouter interface {
	// Relative returns a root-relative URL, starting with `/`
	// if to starts with "/" it will be used as the target, instead of resolving the URL
	Relative(to string, params map[string]string) (*url.URL, error)
	// Absolute returns an absolute URL, with scheme and host.
	// It takes the request to construct as many information as possible
	// if to starts with "/" it will be used as the target, instead of resolving the URL
	Absolute(r *Request, to string, params map[string]string) (*url.URL, error)
}

ReverseRouter allows to retrieve urls for controller

type RouteRedirectResponse

type RouteRedirectResponse struct {
	Response
	To string

	Data map[string]string
	// contains filtered or unexported fields
}

RouteRedirectResponse redirects to a certain route

func (*RouteRedirectResponse) Apply

func (r *RouteRedirectResponse) Apply(c context.Context, w http.ResponseWriter) error

Apply response

func (*RouteRedirectResponse) Fragment

func (r *RouteRedirectResponse) Fragment(fragment string) *RouteRedirectResponse

Fragment adds a fragment to the resulting URL, argument must be given without '#'

func (*RouteRedirectResponse) Permanent

func (r *RouteRedirectResponse) Permanent() *RouteRedirectResponse

Permanent marks a redirect as being permanent (http 301)

func (*RouteRedirectResponse) SetNoCache

func (r *RouteRedirectResponse) SetNoCache() *RouteRedirectResponse

SetNoCache helper

type Router

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

Router represents actual implementation of ReverseRouter interface

func (*Router) Absolute

func (r *Router) Absolute(req *Request, to string, params map[string]string) (*url.URL, error)

Absolute returns an absolute URL, with scheme and host. It takes the request to construct as many information as possible

func (*Router) Base

func (r *Router) Base() *url.URL

Base returns full base urls, containing scheme, domain and base path

func (*Router) Data

func (r *Router) Data(ctx context.Context, handler string, params map[interface{}]interface{}) interface{}

Data calls a flamingo data controller

func (*Router) Handler

func (r *Router) Handler() http.Handler

Handler creates and returns new instance of http.Handler interface

func (*Router) Inject

func (r *Router) Inject(
	cfg *struct {
		// base url configuration
		Scheme      string `inject:"config:flamingo.router.scheme,optional"`
		Host        string `inject:"config:flamingo.router.host,optional"`
		Path        string `inject:"config:flamingo.router.path,optional"`
		External    string `inject:"config:flamingo.router.external,optional"`
		SessionName string `inject:"config:flamingo.session.name,optional"`
	},
	sessionStore *SessionStore,
	eventRouter flamingo.EventRouter,
	filterProvider filterProvider,
	routesProvider routesProvider,
	logger flamingo.Logger,
	configArea *config.Area,
	responderProvider responderProvider,
)

Inject dependencies

func (*Router) ListenAndServe

func (r *Router) ListenAndServe(addr string) error

ListenAndServe starts flamingo server

func (*Router) Relative

func (r *Router) Relative(to string, params map[string]string) (*url.URL, error)

Relative returns a root-relative URL, starting with `/`

func (*Router) URL

func (r *Router) URL(to string, params map[string]string) (*url.URL, error)

URL returns returns a root-relative URL, starting with `/` Deprecated: use Relative instead

type RouterRegistry

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

RouterRegistry holds a list of all routes and handlers to be registered in modules.

We have: routes: key-params -> path, for reverse routes

path: url-pattern -> key+params

Handler: key -> Controller

func NewRegistry

func NewRegistry() *RouterRegistry

NewRegistry creates a new RouterRegistry

func (*RouterRegistry) Alias

func (registry *RouterRegistry) Alias(name, to string)

Alias for an existing router definition

func (*RouterRegistry) GetRoutes

func (registry *RouterRegistry) GetRoutes() []*Handler

GetRoutes returns registered Routes

func (*RouterRegistry) HandleAny

func (registry *RouterRegistry) HandleAny(name string, action Action)

HandleAny serves as a fallback to handle HTTP requests which are not taken care of by other handlers

func (*RouterRegistry) HandleData

func (registry *RouterRegistry) HandleData(name string, action DataAction)

HandleData sets the controllers data action

func (*RouterRegistry) HandleDelete

func (registry *RouterRegistry) HandleDelete(name string, action Action)

HandleDelete handles HTTP DELETE requests

func (*RouterRegistry) HandleGet

func (registry *RouterRegistry) HandleGet(name string, action Action)

HandleGet handles a HTTP GET request

func (*RouterRegistry) HandleHead

func (registry *RouterRegistry) HandleHead(name string, action Action)

HandleHead handles HTTP HEAD requests

func (*RouterRegistry) HandleMethod

func (registry *RouterRegistry) HandleMethod(method, name string, action Action)

HandleMethod handles requests for the specified HTTP Method

func (*RouterRegistry) HandleOptions

func (registry *RouterRegistry) HandleOptions(name string, action Action)

HandleOptions handles HTTP OPTIONS requests

func (*RouterRegistry) HandlePost

func (registry *RouterRegistry) HandlePost(name string, action Action)

HandlePost handles HTTP POST requests

func (*RouterRegistry) HandlePut

func (registry *RouterRegistry) HandlePut(name string, action Action)

HandlePut handles HTTP PUT requests

func (*RouterRegistry) Has

func (registry *RouterRegistry) Has(method, name string) bool

Has checks if a method is set for a given handler name

func (*RouterRegistry) HasAny

func (registry *RouterRegistry) HasAny(name string) bool

HasAny checks if an any handler is set for a given name

func (*RouterRegistry) HasData

func (registry *RouterRegistry) HasData(name string) bool

HasData checks if a data handler is set for a given name

func (*RouterRegistry) MustRoute

func (registry *RouterRegistry) MustRoute(path, handler string) *Handler

MustRoute makes a checked Route call

func (*RouterRegistry) Reverse

func (registry *RouterRegistry) Reverse(name string, params map[string]string) (string, error)

Reverse builds the path from a named route with params

func (*RouterRegistry) Route

func (registry *RouterRegistry) Route(path, handler string) (*Handler, error)

Route assigns a route to a Handler

type RoutesModule

type RoutesModule interface {
	Routes(registry *RouterRegistry)
}

RoutesModule defines a router RoutesModule, which is able to register routes

type ServerErrorResponse

type ServerErrorResponse struct {
	RenderResponse
	Error     error
	ErrString string
}

ServerErrorResponse returns a server error, by default http 500

func (*ServerErrorResponse) Apply

func (r *ServerErrorResponse) Apply(c context.Context, w http.ResponseWriter) error

Apply response

func (*ServerErrorResponse) SetNoCache

func (r *ServerErrorResponse) SetNoCache() *ServerErrorResponse

SetNoCache helper

type Session

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

Session holds the data connected to the current user session

func EmptySession

func EmptySession() *Session

EmptySession creates an empty session instance for testing etc.

func SessionFromContext

func SessionFromContext(ctx context.Context) *Session

SessionFromContext allows to retrieve the stored session. Please note: this is dangerous and should never be used to implicitly pass the session. If your code required the request or session make it clear. Implicit passing of dependencies is dangerous and should be avoided at all costs.

func (*Session) AddFlash

func (s *Session) AddFlash(value interface{}, vars ...string)

AddFlash adds a flash message to the session. todo change?

func (*Session) ClearAll

func (s *Session) ClearAll() *Session

ClearAll removes all values from the session Deprecated: do not use ClearAll

func (*Session) Delete

func (s *Session) Delete(key interface{})

Delete a given key from the session

func (*Session) Flashes

func (s *Session) Flashes(vars ...string) []interface{}

Flashes returns a slice of flash messages from the session todo change?

func (*Session) ID

func (s *Session) ID() (id string)

ID returns the Session id

func (*Session) IDHash

func (s *Session) IDHash() string

IDHash - returns the Hashed session id - useful for logs

func (*Session) Keys

func (s *Session) Keys() []interface{}

Keys returns an unordered list of session keys Deprecated: please know what you will need

func (*Session) Load

func (s *Session) Load(key interface{}) (data interface{}, ok bool)

Load data by a key

func (*Session) Store

func (s *Session) Store(key interface{}, data interface{}) *Session

Store data with a key in the Session

func (*Session) Try

func (s *Session) Try(key interface{}) (data interface{})

Try to load data by a key

type SessionStore

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

SessionStore handles flamingo's session loading and storing. It currently uses gorilla as a backend.

func (*SessionStore) Inject

func (s *SessionStore) Inject(logger flamingo.Logger, cfg *struct {
	SessionStore sessions.Store `inject:",optional"`
	SessionName  string         `inject:"config:flamingo.session.name,optional"`
	SaveMode     string         `inject:"config:flamingo.session.saveMode"`
}) *SessionStore

Inject dependencies.

func (*SessionStore) LoadByID

func (s *SessionStore) LoadByID(ctx context.Context, id string) (*Session, error)

LoadByID loads a Session from a provided session id

func (*SessionStore) LoadByRequest

func (s *SessionStore) LoadByRequest(ctx context.Context, req *http.Request) (*Session, error)

LoadByRequest loads a Session from an http.Request (it is expected to find the session cookie there)

func (*SessionStore) Save

func (s *SessionStore) Save(ctx context.Context, session *Session) (http.Header, error)

Save stores a session back in the session storage. The returned headers should be applied, they usually contain SetCookie headers.

type SetPartialDataFunc

type SetPartialDataFunc struct{}

SetPartialDataFunc allows to set partial data

func (*SetPartialDataFunc) Func

func (*SetPartialDataFunc) Func(c context.Context) interface{}

Func getter to bind the context

type URLRedirectResponse

type URLRedirectResponse struct {
	Response
	URL *url.URL
}

URLRedirectResponse redirects to a certain URL

func (*URLRedirectResponse) Apply

func (r *URLRedirectResponse) Apply(c context.Context, w http.ResponseWriter) error

Apply response

func (*URLRedirectResponse) Permanent

func (r *URLRedirectResponse) Permanent() *URLRedirectResponse

Permanent marks a redirect as being permanent (http 301)

func (*URLRedirectResponse) SetNoCache

func (r *URLRedirectResponse) SetNoCache() *URLRedirectResponse

SetNoCache helper

Directories

Path Synopsis
filter