Documentation
¶
Overview ¶
Package prefab provides a library to streamline the initialization and configuration of a typical hybrid web server, which can handle GRPC, JSON RPC, and regular HTTP handlers.
Index ¶
- Constants
- Variables
- func RegisterMetaServiceHandler(ctx context.Context, mux *runtime.ServeMux, conn *grpc.ClientConn) error
- func RegisterMetaServiceHandlerClient(ctx context.Context, mux *runtime.ServeMux, client MetaServiceClient) error
- func RegisterMetaServiceHandlerFromEndpoint(ctx context.Context, mux *runtime.ServeMux, endpoint string, ...) (err error)
- func RegisterMetaServiceHandlerServer(ctx context.Context, mux *runtime.ServeMux, server MetaServiceServer) error
- func RegisterMetaServiceServer(s grpc.ServiceRegistrar, srv MetaServiceServer)
- func SendCSRFToken(ctx context.Context, signingKey []byte) string
- func VerifyCSRF(ctx context.Context, signingKey []byte) error
- type ClientConfigRequest
- type ClientConfigResponse
- func (*ClientConfigResponse) Descriptor() ([]byte, []int)deprecated
- func (x *ClientConfigResponse) GetConfigs() map[string]string
- func (x *ClientConfigResponse) GetCsrfToken() string
- func (*ClientConfigResponse) ProtoMessage()
- func (x *ClientConfigResponse) ProtoReflect() protoreflect.Message
- func (x *ClientConfigResponse) Reset()
- func (x *ClientConfigResponse) String() string
- type ConfigInjector
- type CustomErrorResponse
- func (*CustomErrorResponse) Descriptor() ([]byte, []int)deprecated
- func (x *CustomErrorResponse) GetCode() int32
- func (x *CustomErrorResponse) GetCodeName() string
- func (x *CustomErrorResponse) GetDetails() []*anypb.Any
- func (x *CustomErrorResponse) GetMessage() string
- func (*CustomErrorResponse) ProtoMessage()
- func (x *CustomErrorResponse) ProtoReflect() protoreflect.Message
- func (x *CustomErrorResponse) Reset()
- func (x *CustomErrorResponse) String() string
- type DependentPlugin
- type InitializablePlugin
- type JSONHandler
- type MetaServiceClient
- type MetaServiceServer
- type OptionProvider
- type OptionalDependentPlugin
- type Plugin
- type Registry
- type SecurityHeaders
- type Server
- type ServerOption
- func WithCRSFSigningKey(signingKey string) ServerOption
- func WithClientConfig(key, value string) ServerOption
- func WithContext(ctx context.Context) ServerOption
- func WithGRPCGateway(...) ServerOption
- func WithGRPCInterceptor(interceptor grpc.UnaryServerInterceptor) ServerOption
- func WithGRPCReflection() ServerOption
- func WithGRPCService(desc *grpc.ServiceDesc, impl any) ServerOption
- func WithHTTPHandler(prefix string, h http.Handler) ServerOption
- func WithHTTPHandlerFunc(prefix string, h func(http.ResponseWriter, *http.Request)) ServerOption
- func WithHost(host string) ServerOption
- func WithIncomingHeaders(headers ...string) ServerOption
- func WithJSONHandler(prefix string, h JSONHandler) ServerOption
- func WithMaxRecvMsgSize(maxMsgSizeBytes int) ServerOption
- func WithPlugin(p Plugin) ServerOption
- func WithPort(port int) ServerOption
- func WithRequestConfig(injector ConfigInjector) ServerOption
- func WithSecurityHeaders(headers *SecurityHeaders) ServerOption
- func WithStaticFiles(prefix, dir string) ServerOption
- func WithTLS(certFile, keyFile string) ServerOption
- type ShutdownPlugin
- type UnimplementedMetaServiceServer
- type UnsafeMetaServiceServer
- type XFramesOptions
Constants ¶
const ConfigFile = "prefab.yaml"
Filename of the standard configuration file.
const (
MetaService_ClientConfig_FullMethodName = "/prefab.MetaService/ClientConfig"
)
Variables ¶
var Config = koanf.New(".")
Config is a global koanf instance used to access application level configuration options.
var ( // Whether CSRF verification should be handled by a GRPC Interceptor. // // Possible values are "on", "off", and "auto". // // "auto" will enable CSRF checks unless a safe HTTP method is detected (GET, // HEAD, and OPTIONS) from the GRPC Gateway. If no HTTP method is detected, it // is assumed that the request came via a non-browser client and CSRF checks // are disabled. // // Defaults to "auto". // // optional string csrf_mode = 50001; E_CsrfMode = &file_server_proto_extTypes[0] )
Extension fields to descriptorpb.MethodOptions.
var ( // HSTS requires a minimum expiration of 1 year for preload. ErrBadHSTSExpiration = errors.NewC("prefab: HSTS preload requires expiration of at least 1 year", codes.FailedPrecondition) )
var File_metaservice_proto protoreflect.FileDescriptor
var File_server_proto protoreflect.FileDescriptor
var JSONMarshalOptions = protojson.MarshalOptions{ Multiline: true, Indent: " ", EmitUnpopulated: true, UseProtoNames: false, }
Options passed to runtime.JSONPb when building the server.
var MetaService_ServiceDesc = grpc.ServiceDesc{ ServiceName: "prefab.MetaService", HandlerType: (*MetaServiceServer)(nil), Methods: []grpc.MethodDesc{ { MethodName: "ClientConfig", Handler: _MetaService_ClientConfig_Handler, }, }, Streams: []grpc.StreamDesc{}, Metadata: "metaservice.proto", }
MetaService_ServiceDesc is the grpc.ServiceDesc for MetaService service. It's only intended for direct use with grpc.RegisterService, and not to be introspected or modified (even as a copy)
Functions ¶
func RegisterMetaServiceHandler ¶
func RegisterMetaServiceHandler(ctx context.Context, mux *runtime.ServeMux, conn *grpc.ClientConn) error
RegisterMetaServiceHandler registers the http handlers for service MetaService to "mux". The handlers forward requests to the grpc endpoint over "conn".
func RegisterMetaServiceHandlerClient ¶
func RegisterMetaServiceHandlerClient(ctx context.Context, mux *runtime.ServeMux, client MetaServiceClient) error
RegisterMetaServiceHandlerClient registers the http handlers for service MetaService to "mux". The handlers forward requests to the grpc endpoint over the given implementation of "MetaServiceClient". Note: the gRPC framework executes interceptors within the gRPC handler. If the passed in "MetaServiceClient" doesn't go through the normal gRPC flow (creating a gRPC client etc.) then it will be up to the passed in "MetaServiceClient" to call the correct interceptors. This client ignores the HTTP middlewares.
func RegisterMetaServiceHandlerFromEndpoint ¶
func RegisterMetaServiceHandlerFromEndpoint(ctx context.Context, mux *runtime.ServeMux, endpoint string, opts []grpc.DialOption) (err error)
RegisterMetaServiceHandlerFromEndpoint is same as RegisterMetaServiceHandler but automatically dials to "endpoint" and closes the connection when "ctx" gets done.
func RegisterMetaServiceHandlerServer ¶
func RegisterMetaServiceHandlerServer(ctx context.Context, mux *runtime.ServeMux, server MetaServiceServer) error
RegisterMetaServiceHandlerServer registers the http handlers for service MetaService to "mux". UnaryRPC :call MetaServiceServer directly. StreamingRPC :currently unsupported pending https://github.com/grpc/grpc-go/issues/906. Note that using this registration option will cause many gRPC library features to stop working. Consider using RegisterMetaServiceHandlerFromEndpoint instead. GRPC interceptors will not work for this type of registration. To use interceptors, you must use the "runtime.WithMiddlewares" option in the "runtime.NewServeMux" call.
func RegisterMetaServiceServer ¶
func RegisterMetaServiceServer(s grpc.ServiceRegistrar, srv MetaServiceServer)
func SendCSRFToken ¶
SendCSRFToken sends a CSRF token in the response cookies and returns the value for use in the response body.
Types ¶
type ClientConfigRequest ¶
type ClientConfigRequest struct {
// contains filtered or unexported fields
}
Empty request object.
func (*ClientConfigRequest) Descriptor
deprecated
func (*ClientConfigRequest) Descriptor() ([]byte, []int)
Deprecated: Use ClientConfigRequest.ProtoReflect.Descriptor instead.
func (*ClientConfigRequest) ProtoMessage ¶
func (*ClientConfigRequest) ProtoMessage()
func (*ClientConfigRequest) ProtoReflect ¶
func (x *ClientConfigRequest) ProtoReflect() protoreflect.Message
func (*ClientConfigRequest) Reset ¶
func (x *ClientConfigRequest) Reset()
func (*ClientConfigRequest) String ¶
func (x *ClientConfigRequest) String() string
type ClientConfigResponse ¶
type ClientConfigResponse struct { // A map of key-value pairs configured by available plugins, for example // auth.google.client_id. Configs map[string]string `` /* 141-byte string literal not displayed */ // Token that should be used in non-XHR requests to avoid cross-site request // forgery attacks. CsrfToken string `protobuf:"bytes,2,opt,name=csrf_token,json=csrfToken,proto3" json:"csrf_token,omitempty"` // contains filtered or unexported fields }
Configuration information to help clients facilitate interactions with the API server.
func (*ClientConfigResponse) Descriptor
deprecated
func (*ClientConfigResponse) Descriptor() ([]byte, []int)
Deprecated: Use ClientConfigResponse.ProtoReflect.Descriptor instead.
func (*ClientConfigResponse) GetConfigs ¶
func (x *ClientConfigResponse) GetConfigs() map[string]string
func (*ClientConfigResponse) GetCsrfToken ¶
func (x *ClientConfigResponse) GetCsrfToken() string
func (*ClientConfigResponse) ProtoMessage ¶
func (*ClientConfigResponse) ProtoMessage()
func (*ClientConfigResponse) ProtoReflect ¶
func (x *ClientConfigResponse) ProtoReflect() protoreflect.Message
func (*ClientConfigResponse) Reset ¶
func (x *ClientConfigResponse) Reset()
func (*ClientConfigResponse) String ¶
func (x *ClientConfigResponse) String() string
type ConfigInjector ¶
ConfigInjector is a function that injects configuration into a context.
type CustomErrorResponse ¶
type CustomErrorResponse struct { Code int32 `protobuf:"varint,1,opt,name=code,proto3" json:"code,omitempty"` CodeName string `protobuf:"bytes,2,opt,name=code_name,json=codeName,proto3" json:"code_name,omitempty"` Message string `protobuf:"bytes,3,opt,name=message,proto3" json:"message,omitempty"` Details []*anypb.Any `protobuf:"bytes,4,rep,name=details,proto3" json:"details,omitempty"` // contains filtered or unexported fields }
Overrides the default error gateway error response to include a code_name for convenience.
func (*CustomErrorResponse) Descriptor
deprecated
func (*CustomErrorResponse) Descriptor() ([]byte, []int)
Deprecated: Use CustomErrorResponse.ProtoReflect.Descriptor instead.
func (*CustomErrorResponse) GetCode ¶
func (x *CustomErrorResponse) GetCode() int32
func (*CustomErrorResponse) GetCodeName ¶
func (x *CustomErrorResponse) GetCodeName() string
func (*CustomErrorResponse) GetDetails ¶
func (x *CustomErrorResponse) GetDetails() []*anypb.Any
func (*CustomErrorResponse) GetMessage ¶
func (x *CustomErrorResponse) GetMessage() string
func (*CustomErrorResponse) ProtoMessage ¶
func (*CustomErrorResponse) ProtoMessage()
func (*CustomErrorResponse) ProtoReflect ¶
func (x *CustomErrorResponse) ProtoReflect() protoreflect.Message
func (*CustomErrorResponse) Reset ¶
func (x *CustomErrorResponse) Reset()
func (*CustomErrorResponse) String ¶
func (x *CustomErrorResponse) String() string
type DependentPlugin ¶
type DependentPlugin interface { // Deps returns the names for plugins which this plugin depends on. Deps() []string }
Implemented if plugin depends on other plugins.
type InitializablePlugin ¶
type InitializablePlugin interface { // Init the plugin. Will be called in dependency order. Init(ctx context.Context, r *Registry) error }
Implemented if the plugin needs to be initialized outside construction.
type JSONHandler ¶
JSONHandler are regular HTTP handlers that return a response that should be encoded in a similar fashion to a gRPC Gateway response.
If the return value is a proto.Message, it will be marshaled using the same JSON marshaler as the gRPC Gateway.
type MetaServiceClient ¶
type MetaServiceClient interface { // ClientConfig returns configuration information that is required for clients // to interact with the server in various ways. All data is safe to be served // to unauthenticatd clients. ClientConfig(ctx context.Context, in *ClientConfigRequest, opts ...grpc.CallOption) (*ClientConfigResponse, error) }
MetaServiceClient is the client API for MetaService service.
For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream.
func NewMetaServiceClient ¶
func NewMetaServiceClient(cc grpc.ClientConnInterface) MetaServiceClient
type MetaServiceServer ¶
type MetaServiceServer interface { // ClientConfig returns configuration information that is required for clients // to interact with the server in various ways. All data is safe to be served // to unauthenticatd clients. ClientConfig(context.Context, *ClientConfigRequest) (*ClientConfigResponse, error) // contains filtered or unexported methods }
MetaServiceServer is the server API for MetaService service. All implementations must embed UnimplementedMetaServiceServer for forward compatibility.
type OptionProvider ¶
type OptionProvider interface {
ServerOptions() []ServerOption
}
OptionProvider can be implemented by plugins to augment the server at build time.
type OptionalDependentPlugin ¶
type OptionalDependentPlugin interface { // OptDeps returns the names for plugins which this plugin optionally depends on. OptDeps() []string }
Implemented if plugin has optional dependencies, which should be initialized before the plugin, but are not required.
type Plugin ¶
type Plugin interface { // Name of the plugin, used for querying and dependency resolution. Name() string }
The base plugin interface.
type Registry ¶
type Registry struct {
// contains filtered or unexported fields
}
Registry manages plugins and their dependencies.
type SecurityHeaders ¶
type SecurityHeaders struct { // X-Frame-Options controls whether the browser should allow the page to be // rendered in a frame or iframe. XFramesOptions XFramesOptions // Strict-Transport-Security (HSTS) tells the browser to always use HTTPS // when connecting to the site. HSTSExpiration time.Duration HSTSIncludeSubdomains bool HSTSPreload bool // Access-Control headers define which origins are allowed to access the // resource and what methods are allowed. // TODO: Should this allow for patterns instead of only exact origin matches? CORSOrigins []string CORSAllowMethods []string CORSAllowHeaders []string CORSExposeHeaders []string CORSAllowCredentials bool CORSMaxAge time.Duration // contains filtered or unexported fields }
SecurityHeaders contains the security headers that should be set on HTTP responses.
func (*SecurityHeaders) Apply ¶
func (s *SecurityHeaders) Apply(w http.ResponseWriter, r *http.Request) error
Apply the security headers to the given response.
type Server ¶
type Server struct {
// contains filtered or unexported fields
}
Server wraps a HTTP server, a GRPC server, and a GRPC Gateway.
Usage:
server := server.New(opts...) debugservice.RegisterDebugServiceHandlerFromEndpoint(server.GatewayArgs()) debugservice.RegisterDebugServiceServer(server.ServiceRegistrar(), &impl{}) server.Start()
See examples/simpleserver.
func (*Server) GRPCServerForReflection ¶
func (s *Server) GRPCServerForReflection() reflection.GRPCServer
GRPCServerForReflection returns the GRPC Server for use with reflection.
func (*Server) GatewayArgs ¶
func (s *Server) GatewayArgs() (ctx context.Context, mux *runtime.ServeMux, endpoint string, opts []grpc.DialOption)
GatewayArgs is used when registering a gateway handler.
For example, if you have DebugService:
debugservice.RegisterDebugServiceHandlerFromEndpoint(server.GatewayArgs())
func (*Server) ServiceRegistrar ¶
func (s *Server) ServiceRegistrar() grpc.ServiceRegistrar
GRPCServer returns the GRPC Service Registrar for use with service implementations.
For example, if you have DebugService:
debugservice.RegisterDebugServiceServer(server.ServiceRegistrar(), &debugServiceImpl{})
type ServerOption ¶
type ServerOption func(*builder)
ServerOptions customize the configuration and operation of the GRPC server.
func WithCRSFSigningKey ¶
func WithCRSFSigningKey(signingKey string) ServerOption
WithCRSFSigningKey sets the key used to sign CSRF tokens.
Config key: `server.csrfSigningKey`.
func WithClientConfig ¶
func WithClientConfig(key, value string) ServerOption
WithClientConfig adds a key value pair which will be made available to the client via the metaservice.
func WithContext ¶
func WithContext(ctx context.Context) ServerOption
WithContext sets the base context for the server. This context will be used for all requests and can be used to inject values into the context.
func WithGRPCGateway ¶
func WithGRPCGateway(fn func(ctx context.Context, mux *runtime.ServeMux, endpoint string, opts []grpc.DialOption) error) ServerOption
WithGRPCGateway registers a GRPC gateway handler.
Example:
WithGRPCGateway(debugservice.RegisterDebugServiceHandlerFromEndpoint)
func WithGRPCInterceptor ¶
func WithGRPCInterceptor(interceptor grpc.UnaryServerInterceptor) ServerOption
WithGRPCInterceptor configures GRPC Unary Interceptors. They will be executed in the order they were added.
func WithGRPCReflection ¶
func WithGRPCReflection() ServerOption
WithGRPCReflection registers the GRPC reflection service.
func WithGRPCService ¶
func WithGRPCService(desc *grpc.ServiceDesc, impl any) ServerOption
WithGRPCService registers a GRPC service handler.
func WithHTTPHandler ¶
func WithHTTPHandler(prefix string, h http.Handler) ServerOption
WithHTTPHandler adds an HTTP handler.
func WithHTTPHandlerFunc ¶
func WithHTTPHandlerFunc(prefix string, h func(http.ResponseWriter, *http.Request)) ServerOption
WithHTTPHandlerFunc adds an HTTP handler function.
func WithHost ¶
func WithHost(host string) ServerOption
WithHost configures the hostname or IP the server will listen on.
Config key: `server.host`.
func WithIncomingHeaders ¶
func WithIncomingHeaders(headers ...string) ServerOption
WithIncomingHeaders specifies a safe-list of headers that can be forwarded via gRPC metadata with the `prefab` prefix. Headers that are allowed by the CORS security config are automatically added to this list, see WithSecurityHeaders.
Config key: `server.incomingHeaders`.
func WithJSONHandler ¶
func WithJSONHandler(prefix string, h JSONHandler) ServerOption
WithJSONHandler adds a HTTP handler which returns JSON, serialized in a consistent way to gRPC gateway responses.
func WithMaxRecvMsgSize ¶
func WithMaxRecvMsgSize(maxMsgSizeBytes int) ServerOption
WithMaxRecvMsgSize sets the maximum GRPC message size. Default is 4Mb.
Config key: `server.maxMsgSizeBytes`.
func WithPlugin ¶
func WithPlugin(p Plugin) ServerOption
WithPlugin registers a plugin with the server's registry. Plugins will be initialized at server start. If the Plugin implements `OptionProvider` then additional server options can be configured for the server.
func WithPort ¶
func WithPort(port int) ServerOption
WithPort configures the port the server will listen on.
Config key: `server.port`.
func WithRequestConfig ¶
func WithRequestConfig(injector ConfigInjector) ServerOption
WithRequestConfig adds a ConfigInjector to the server. The injector will be called for every request and can be used to inject request scoped configuration into the context.
func WithSecurityHeaders ¶
func WithSecurityHeaders(headers *SecurityHeaders) ServerOption
WithSecurityHeaders sets the security headers that should be set on HTTP responses.
Config keys: - `server.security.xFramesOptions` - `server.security.hstsExpiration` - `server.security.hstsIncludeSubdomains` - `server.security.hstsPreload` - `server.security.corsOrigins` - `server.security.corsAllowMethods` - `server.security.corsAllowHeaders` - `server.security.corsExposeHeaders` - `server.security.corsAllowCredentials` - `server.security.corsMaxAge`.
func WithStaticFiles ¶
func WithStaticFiles(prefix, dir string) ServerOption
WithStaticFileServer configures the server to serve static files from disk for HTTP requests that match the given prefix.
func WithTLS ¶
func WithTLS(certFile, keyFile string) ServerOption
WithTLS configures the server to allow traffic via TLS using the provided cert. If not called server will use HTTP/H2C.
Config keys: `server.tls.certFile`, `server.tls.keyFile`.
type ShutdownPlugin ¶
Implemented if the plugin needs to be shutdown.
type UnimplementedMetaServiceServer ¶
type UnimplementedMetaServiceServer struct{}
UnimplementedMetaServiceServer must be embedded to have forward compatible implementations.
NOTE: this should be embedded by value instead of pointer to avoid a nil pointer dereference when methods are called.
func (UnimplementedMetaServiceServer) ClientConfig ¶
func (UnimplementedMetaServiceServer) ClientConfig(context.Context, *ClientConfigRequest) (*ClientConfigResponse, error)
type UnsafeMetaServiceServer ¶
type UnsafeMetaServiceServer interface {
// contains filtered or unexported methods
}
UnsafeMetaServiceServer may be embedded to opt out of forward compatibility for this service. Use of this interface is not recommended, as added methods to MetaServiceServer will result in compilation errors.
type XFramesOptions ¶
type XFramesOptions string
const ( XFramesOptionsNone XFramesOptions = "" XFramesOptionsDeny XFramesOptions = "DENY" XFramesOptionsSameOrigin XFramesOptions = "SAMEORIGIN" )
Source Files
¶
Directories
¶
Path | Synopsis |
---|---|
Package errors is a fork of `github.com/go-errors/errors` that adds support for gRPC status codes, public messages, as well as stack-traces.
|
Package errors is a fork of `github.com/go-errors/errors` that adds support for gRPC status codes, public messages, as well as stack-traces. |
examples
|
|
authz
command
Command-line tool to run the various authz examples
|
Command-line tool to run the various authz examples |
authz/builder
An example of how to use the Authz plugin with the common builder pattern.
|
An example of how to use the Authz plugin with the common builder pattern. |
authz/custom
An example of how to use the Authz plugin with fully custom configuration.
|
An example of how to use the Authz plugin with fully custom configuration. |
fakeauth
command
Example of how to use the fake auth plugin for testing scenarios
|
Example of how to use the fake auth plugin for testing scenarios |
googleauth
command
An example using google auth.
|
An example using google auth. |
magiclinkauth
command
An example using email based magic-link auth.
|
An example using email based magic-link auth. |
pwdauth
command
An example using password auth.
|
An example using password auth. |
simpleplugin
command
|
|
simpleserver
command
|
|
Package logging provides an abstract interface used internally and which can provide interop with various logging packages.
|
Package logging provides an abstract interface used internally and which can provide interop with various logging packages. |
plugins
|
|
auth
Package auth provides utilities for authenticating requests.
|
Package auth provides utilities for authenticating requests. |
auth/apikey
Package apikey provides an authentication plugin that allows for authentication via apikeys.
|
Package apikey provides an authentication plugin that allows for authentication via apikeys. |
auth/fakeauth
Package fake provides an authentication plugin for testing purposes.
|
Package fake provides an authentication plugin for testing purposes. |
auth/google
Package Google provides authentication via Google SSO.
|
Package Google provides authentication via Google SSO. |
auth/magiclink
Package magiclink provides passwordless authentication, allowing users to authenticate using a magic link that is sent to their email address.
|
Package magiclink provides passwordless authentication, allowing users to authenticate using a magic link that is sent to their email address. |
auth/pwdauth
Package pwdauth provides an authentication service plugin that allows users to authenticate via a email and password.
|
Package pwdauth provides an authentication service plugin that allows users to authenticate via a email and password. |
authz
Package authz provides a plugin for implementing role-based access control (RBAC).
|
Package authz provides a plugin for implementing role-based access control (RBAC). |
email
Package email provides an interface for plugins and application code to send email.
|
Package email provides an interface for plugins and application code to send email. |
eventbus
Package eventbus provides a simple publish/subscribe event bus.
|
Package eventbus provides a simple publish/subscribe event bus. |
storage
Package storage contains an extensible interface for providing persistence to simple applications and other prefab plugins.
|
Package storage contains an extensible interface for providing persistence to simple applications and other prefab plugins. |
storage/memstore
Package memstore implements storage.Store in a purely in-memory manner.
|
Package memstore implements storage.Store in a purely in-memory manner. |
storage/postgres
Package postgres provides a PostgreSQL implementation of storage.Store interface.
|
Package postgres provides a PostgreSQL implementation of storage.Store interface. |
storage/sqlite
Package sqlite provides a SQLite implementation of storage.Store interface.
|
Package sqlite provides a SQLite implementation of storage.Store interface. |
storage/storagetests
Package storagetests provides common acceptance tests for storage.Store implementations.
|
Package storagetests provides common acceptance tests for storage.Store implementations. |
templates
Package templates provides plugins access to Go templates.
|
Package templates provides plugins access to Go templates. |
upload
Package upload provides a prefab plugin that adds an HTTP handler for uploading files.
|
Package upload provides a prefab plugin that adds an HTTP handler for uploading files. |
TODO: Rename or/and break this package.
|
TODO: Rename or/and break this package. |