router

package
v5.9.0 Latest Latest
Warning

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

Go to latest
Published: Apr 23, 2020 License: AGPL-3.0 Imports: 21 Imported by: 0

Documentation

Overview

The router package implements an HTTP request router for charm store HTTP requests.

Index

Constants

This section is empty.

Variables

View Source
var WriteError = errorToResp.WriteError

WriteError can be used to write an error response.

Functions

func HandleErrors

func HandleErrors(h ErrorHandler) http.Handler

HandleJSON converts from a ErrorHandler function to an http.Handler.

func HandleJSON

func HandleJSON(h JSONHandler) http.Handler

HandleJSON converts from a JSONHandler function to an http.Handler.

func NotFoundHandler

func NotFoundHandler() http.Handler

NotFoundHandler is like http.NotFoundHandler except it returns a JSON error response.

func ParseBool

func ParseBool(value string) (bool, error)

ParseBool returns the boolean value represented by the string. It accepts "1" or "0". Any other value returns an error.

func RelativeURLPath

func RelativeURLPath(basePath, targPath string) (string, error)

RelativeURLPath returns a relative URL path that is lexically equivalent to targpath when interpreted by url.URL.ResolveReference. On success, the returned path will always be non-empty and relative to basePath, even if basePath and targPath share no elements.

An error is returned if basePath or targPath are not absolute paths.

func UnmarshalJSONResponse

func UnmarshalJSONResponse(resp *http.Response, v interface{}, errorF func(*http.Response) error) error

UnmarshalJSONResponse unmarshals resp.Body into v. If errorF is not nil and resp.StatusCode indicates an error has occured (>= 400) then the result of calling errorF with resp is returned.

Types

type BulkIncludeHandler

type BulkIncludeHandler interface {
	// Key returns a value that will be used to group handlers
	// together in preparation for a call to HandleGet or HandlePut.
	// The key should be comparable for equality.
	// Please do not return NaN. That would be silly, OK?
	Key() interface{}

	// HandleGet returns the results of invoking all the given handlers
	// on the given charm or bundle id. Each result is held in
	// the respective element of the returned slice.
	//
	// All of the handlers' Keys will be equal to the receiving handler's
	// Key.
	//
	// Each item in paths holds the remaining metadata path
	// for the handler in the corresponding position
	// in hs after the prefix in Handlers.Meta has been stripped,
	// and flags holds all the URL query values.
	//
	// TODO(rog) document indexed errors.
	HandleGet(hs []BulkIncludeHandler, id *ResolvedURL, paths []string, flags url.Values, req *http.Request) ([]interface{}, error)

	// HandlePut invokes a PUT request on all the given handlers on
	// the given charm or bundle id. If there is an error, the
	// returned errors slice should contain one element for each element
	// in paths. The error for handler hs[i] should be returned in errors[i].
	// If there is no error, an empty slice should be returned.
	//
	// Each item in paths holds the remaining metadata path
	// for the handler in the corresponding position
	// in hs after the prefix in Handlers.Meta has been stripped,
	// and flags holds all the url query values.
	HandlePut(hs []BulkIncludeHandler, id *ResolvedURL, paths []string, values []*json.RawMessage, req *http.Request) []error
}

BulkIncludeHandler represents a metadata handler that can handle multiple metadata "include" requests in a single batch.

For simple metadata handlers that cannot be efficiently combined, see SingleIncludeHandler.

All handlers may assume that http.Request.ParseForm has been called to parse the URL form values.

type Context

type Context interface {
	// ResolveURL will be called to resolve ids in
	// router paths - it should return the fully
	// resolved URL corresponding to the given id.
	// If the entity referred to by the URL does not
	// exist, it should return an error with a params.ErrNotFound
	// cause.
	ResolveURL(id *charm.URL) (*ResolvedURL, error)

	// ResolveURLs is like ResolveURL but resolves multiple URLs
	// at the same time. The length of the returned slice should
	// be len(ids); any entities that are not found should be represented
	// by nil elements.
	ResolveURLs(ids []*charm.URL) ([]*ResolvedURL, error)

	// AuthorizeEntity will be called to authorize requests
	// to any BulkIncludeHandlers. All other handlers are expected
	// to handle their own authorization.
	AuthorizeEntity(id *ResolvedURL, req *http.Request) error

	// WillIncludeMetadata informs the context that the given metadata
	// includes will be required in the request. This allows the context
	// to prime any cache fetches to fetch this data when early
	// fetches which may not require the metadata are made.
	// This method should ignore any unrecognized names.
	WillIncludeMetadata(includes []string)
}

Context provides contextual information for a router.

type ErrorHandler

type ErrorHandler func(http.ResponseWriter, *http.Request) error

ErrorHandler represents a handler that can return an error.

type FieldGetFunc

type FieldGetFunc func(doc interface{}, id *ResolvedURL, path string, flags url.Values, req *http.Request) (interface{}, error)

A FieldGetFunc returns some data from the given document. The document will have been returned from an earlier call to the associated QueryFunc.

type FieldIncludeHandler

type FieldIncludeHandler struct {
	P FieldIncludeHandlerParams
}

FieldIncludeHandler implements BulkIncludeHandler by making a single request with a number of aggregated fields.

func NewFieldIncludeHandler

func NewFieldIncludeHandler(p FieldIncludeHandlerParams) *FieldIncludeHandler

NewFieldIncludeHandler returns a BulkIncludeHandler that will perform only a single database query for several requests. See FieldIncludeHandlerParams for more detail.

See in ../v4/api.go for an example of its use.

func (*FieldIncludeHandler) HandleGet

func (h *FieldIncludeHandler) HandleGet(hs []BulkIncludeHandler, id *ResolvedURL, paths []string, flags url.Values, req *http.Request) ([]interface{}, error)

HandleGet implements BulkIncludeHandler.HandleGet.

func (*FieldIncludeHandler) HandlePut

func (h *FieldIncludeHandler) HandlePut(hs []BulkIncludeHandler, id *ResolvedURL, paths []string, values []*json.RawMessage, req *http.Request) []error

HandlePut implements BulkIncludeHandler.HandlePut.

func (*FieldIncludeHandler) Key

func (h *FieldIncludeHandler) Key() interface{}

Key implements BulkIncludeHandler.Key.

type FieldIncludeHandlerParams

type FieldIncludeHandlerParams struct {
	// Key is used to group together similar FieldIncludeHandlers
	// (the same query should be generated for any given key).
	Key interface{}

	// Query is used to retrieve the document from the database for
	// GET requests. The fields passed to the query will be the
	// union of all fields found in all the handlers in the bulk
	// request.
	Query FieldQueryFunc

	// Fields specifies which fields are required by the given handler.
	Fields []string

	// Handle actually returns the data from the document retrieved
	// by Query, for GET requests.
	HandleGet FieldGetFunc

	// HandlePut generates update operations for a PUT
	// operation.
	HandlePut FieldPutFunc

	// Update is used to update the document in the database for
	// PUT requests.
	Update FieldUpdateFunc

	// UpdateSearch is used to update the document in the search
	// database for PUT requests.
	UpdateSearch FieldUpdateSearchFunc
}

FieldIncludeHandlerParams specifies the parameters for NewFieldIncludeHandler.

type FieldPutFunc

type FieldPutFunc func(id *ResolvedURL, path string, val *json.RawMessage, updater *FieldUpdater, req *http.Request) error

FieldPutFunc sets using the given FieldUpdater corresponding to fields to be set in the metadata document for the given id. The path holds the metadata path after the initial prefix has been removed.

type FieldQueryFunc

type FieldQueryFunc func(id *ResolvedURL, selector map[string]int, req *http.Request) (interface{}, error)

A FieldQueryFunc is used to retrieve a metadata document for the given URL, selecting only those fields specified in keys of the given selector.

type FieldUpdateFunc

type FieldUpdateFunc func(id *ResolvedURL, fields map[string]interface{}, entries []audit.Entry) error

A FieldUpdateFunc is used to update a metadata document for the given id. For each field in fields, it should set that field to its corresponding value in the metadata document.

type FieldUpdateSearchFunc

type FieldUpdateSearchFunc func(id *ResolvedURL, fields map[string]interface{}) error

A FieldUpdateSearchFunc is used to update a search document for the given id. For each field in fields, it should set that field to its corresponding value in the search document.

type FieldUpdater

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

FieldUpdater records field changes made by a FieldUpdateFunc.

func (*FieldUpdater) UpdateField

func (u *FieldUpdater) UpdateField(fieldName string, val interface{}, entry *audit.Entry)

UpdateField requests that the provided field is updated with the given value.

func (*FieldUpdater) UpdateSearch

func (u *FieldUpdater) UpdateSearch()

UpdateSearch requests that search records are updated.

type Handlers

type Handlers struct {
	// Global holds handlers for paths not matched by Meta or Id.
	// The map key is the path; the value is the handler that will
	// be used to handle that path.
	//
	// Path matching is by matched by longest-prefix - the same as
	// http.ServeMux.
	//
	// Note that, unlike http.ServeMux, the prefix is stripped
	// from the URL path before the hander is invoked,
	// matching the behaviour of the other handlers.
	Global map[string]http.Handler

	// Id holds handlers for paths which correspond to a single
	// charm or bundle id other than the meta path. The map key
	// holds the first element of the path, which may end in a
	// trailing slash (/) to indicate that longer paths are allowed
	// too.
	Id map[string]IdHandler

	// Meta holds metadata handlers for paths under the meta
	// endpoint. The map key holds the first element of the path,
	// which may end in a trailing slash (/) to indicate that longer
	// paths are allowed too.
	Meta map[string]BulkIncludeHandler
}

Handlers specifies how HTTP requests will be routed by the router. All errors returned by the handlers will be processed by WriteError with their Cause left intact. This means that, for example, if they return an error with a Cause that is params.ErrNotFound, the HTTP status code will reflect that (assuming the error has not been absorbed by the bulk metadata logic).

type IdHandler

type IdHandler func(charmId *charm.URL, w http.ResponseWriter, req *http.Request) error

IdHandler handles a charm store request rooted at the given id. The request path (req.URL.Path) holds the URL path after the id has been stripped off.

type JSONHandler

type JSONHandler func(http.Header, *http.Request) (interface{}, error)

JSONHandler represents a handler that returns a JSON value. The provided header can be used to set response headers.

type ResolvedURL

type ResolvedURL struct {
	// URL holds the canonical URL for the entity, as used as a key into
	// the Entities collection. URL.User should always be non-empty
	// and URL.Revision should never be -1. URL.Series will only be non-empty
	// if the URL refers to a multi-series charm.
	URL charm.URL

	// PreferredSeries holds the series to return in PreferredURL
	// if URL itself contains no series.
	PreferredSeries string

	// PromulgatedRevision holds the revision of the promulgated version of the
	// charm or -1 if the corresponding entity is not promulgated.
	PromulgatedRevision int
}

ResolvedURL represents a URL that has been resolved by resolveURL.

func MustNewResolvedURL

func MustNewResolvedURL(urlStr string, promulgatedRev int) *ResolvedURL

MustNewResolvedURL returns a new ResolvedURL by parsing the entity URL in urlStr. The promulgatedRev parameter specifies the value of PromulgatedRevision in the returned value.

This function panics if urlStr cannot be parsed as a charm.URL or if it is not fully specified, including user and revision.

func (*ResolvedURL) GoString

func (id *ResolvedURL) GoString() string

func (*ResolvedURL) PreferredURL

func (id *ResolvedURL) PreferredURL() *charm.URL

PreferredURL returns the promulgated URL for the given id if there is one, otherwise it returns the non-promulgated URL. The returned *charm.URL may be modified freely.

If id.PreferredSeries is non-empty, the returns charm URL will always have a non-empty series.

func (*ResolvedURL) PromulgatedURL

func (id *ResolvedURL) PromulgatedURL() *charm.URL

PromulgatedURL returns the promulgated URL for id if there is one, or nil otherwise.

func (*ResolvedURL) String

func (u *ResolvedURL) String() string

String returns the preferred string representation of u. It prefers to use the promulgated URL when there is one.

type Router

type Router struct {
	// Context holds context that the router was created with.
	Context Context

	// monitor holds a metric monitor to time a request.
	Monitor monitoring.Request
	// contains filtered or unexported fields
}

Router represents a charm store HTTP request router.

func New

func New(
	handlers *Handlers,
	ctxt Context,
) *Router

New returns a charm store router that will route requests to the given handlers and retrieve metadata from the given database.

The Context argument provides additional context to the router. Any errors returned by the context methods will have their cause preserved when creating the error return as for the handlers.

func (*Router) GetMetadata

func (r *Router) GetMetadata(id *ResolvedURL, includes []string, req *http.Request) (map[string]interface{}, error)

GetMetadata retrieves metadata for the given charm or bundle id, including information as specified by the includes slice.

func (*Router) Handlers

func (r *Router) Handlers() *Handlers

Handlers returns the set of handlers that the router was created with. This should not be changed.

func (*Router) MetaHandler

func (r *Router) MetaHandler(metaPath string) BulkIncludeHandler

MetaHandler returns the meta handler for the given meta path by looking it up in the Meta map.

func (*Router) PutMetadata

func (r *Router) PutMetadata(id *ResolvedURL, data map[string]*json.RawMessage, req *http.Request) error

PutMetadata puts metadata for the given id. Each key in data holds the name of a metadata endpoint; its associated value holds the value to be written.

func (*Router) ServeHTTP

func (r *Router) ServeHTTP(w http.ResponseWriter, req *http.Request)

ServeHTTP implements http.Handler.ServeHTTP.

type ServeMux

type ServeMux struct {
	*http.ServeMux
}

ServeMux is like http.ServeMux but returns JSON errors when pages are not found.

func NewServeMux

func NewServeMux() *ServeMux

func (*ServeMux) ServeHTTP

func (mux *ServeMux) ServeHTTP(w http.ResponseWriter, req *http.Request)

type SingleIncludeHandler

type SingleIncludeHandler func(id *ResolvedURL, path string, flags url.Values, req *http.Request) (interface{}, error)

SingleIncludeHandler implements BulkMetaHander for a non-batching metadata retrieval function that can perform a GET only.

func (SingleIncludeHandler) HandleGet

func (h SingleIncludeHandler) HandleGet(hs []BulkIncludeHandler, id *ResolvedURL, paths []string, flags url.Values, req *http.Request) ([]interface{}, error)

HandleGet implements BulkMetadataHander.HandleGet.

func (SingleIncludeHandler) HandlePut

func (h SingleIncludeHandler) HandlePut(hs []BulkIncludeHandler, id *ResolvedURL, paths []string, values []*json.RawMessage, req *http.Request) []error

HandlePut implements BulkMetadataHander.HandlePut.

func (SingleIncludeHandler) Key

func (h SingleIncludeHandler) Key() interface{}

Key implements BulkMetadataHander.Key.

Jump to

Keyboard shortcuts

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