Documentation ¶
Overview ¶
Package httpserver implements an HTTP server on top of Caddy.
Index ¶
- Constants
- Variables
- func CleanMaskedPath(reqPath string, masks ...string) string
- func CleanPath(reqPath string) string
- func ContextInclude(filename string, ctx interface{}, fs http.FileSystem) (string, error)
- func DefaultErrorFunc(w http.ResponseWriter, r *http.Request, status int)
- func IfMatcherKeyword(c *caddy.Controller) bool
- func IndexFile(root http.FileSystem, fpath string, indexFiles []string) (string, bool)
- func IsLogRollerSubdirective(subdir string) bool
- func MaxBytesReader(w http.ResponseWriter, r io.ReadCloser, n int64) io.ReadCloser
- func ParseRoller(l *LogRoller, what string, where string) error
- func RegisterDevDirective(name, before string)
- func SameNext(next1, next2 Handler) bool
- func SetLastModifiedHeader(w http.ResponseWriter, modTime time.Time)
- func WriteTextResponse(w http.ResponseWriter, status int, body string)
- type Address
- type ConfigSelector
- type Context
- func (c Context) Cookie(name string) string
- func (c Context) Env() map[string]string
- func (c Context) Ext(pathStr string) string
- func (c Context) Files(name string) ([]string, error)
- func (c Context) Header(name string) string
- func (c Context) Host() (string, error)
- func (c Context) Hostname() string
- func (c Context) IP() string
- func (c Context) Include(filename string, args ...interface{}) (string, error)
- func (c Context) IsMITM() bool
- func (c Context) Join(a []string, sep string) string
- func (c Context) Map(values ...interface{}) (map[string]interface{}, error)
- func (c Context) Markdown(filename string) (string, error)
- func (c Context) Method() string
- func (c Context) Now(format string) string
- func (c Context) NowDate() time.Time
- func (c Context) PathMatches(pattern string) bool
- func (c Context) Port() (string, error)
- func (c Context) RandomString(minLen, maxLen int) string
- func (c Context) Replace(input, find, replacement string) string
- func (c Context) ServerIP() string
- func (c Context) Slice(elems ...interface{}) []interface{}
- func (c Context) Split(s string, sep string) []string
- func (c Context) StripExt(path string) string
- func (c Context) StripHTML(s string) string
- func (c Context) ToLower(s string) string
- func (c Context) ToUpper(s string) string
- func (c Context) Truncate(input string, length int) string
- func (c Context) URI() string
- type Handler
- type HandlerConfig
- type HandlerFunc
- type IfMatcher
- type ListenerMiddleware
- type LogRoller
- type Logger
- type MaxBytesExceeded
- type Middleware
- type NonCloseNotifierError
- type NonFlusherError
- type NonHijackerError
- type Path
- type PathLimit
- type PathMatcher
- type Replacer
- type RequestMatcher
- type ResponseRecorder
- func (r *ResponseRecorder) CloseNotify() <-chan bool
- func (r *ResponseRecorder) Flush()
- func (r *ResponseRecorder) Hijack() (net.Conn, *bufio.ReadWriter, error)
- func (r *ResponseRecorder) Push(target string, opts *http.PushOptions) error
- func (r *ResponseRecorder) Size() int
- func (r *ResponseRecorder) Status() int
- func (r *ResponseRecorder) Write(buf []byte) (int, error)
- func (r *ResponseRecorder) WriteHeader(status int)
- type Server
- func (s *Server) Address() string
- func (s *Server) Listen() (net.Listener, error)
- func (s *Server) ListenPacket() (net.PacketConn, error)
- func (s *Server) OnStartupComplete()
- func (s *Server) Serve(ln net.Listener) error
- func (s *Server) ServeHTTP(w http.ResponseWriter, r *http.Request)
- func (s *Server) ServePacket(pc net.PacketConn) error
- func (s *Server) Stop() error
- type SiteConfig
- func (s *SiteConfig) AddListenerMiddleware(l ListenerMiddleware)
- func (s *SiteConfig) AddMiddleware(m Middleware)
- func (s SiteConfig) Host() string
- func (s SiteConfig) ListenerMiddleware() []ListenerMiddleware
- func (s SiteConfig) Middleware() []Middleware
- func (s SiteConfig) Port() string
- func (s SiteConfig) TLSConfig() *caddytls.Config
- type Timeouts
Constants ¶
const ( // URIxRewriteCtxKey is a context key used to store original unrewritten // URI in context.WithValue URIxRewriteCtxKey caddy.CtxKey = "caddy_rewrite_original_uri" // RemoteUserCtxKey is a context key used to store remote user for request RemoteUserCtxKey caddy.CtxKey = "remote_user" // MitmCtxKey stores Mitm result MitmCtxKey caddy.CtxKey = "mitm" )
Context key constants
const ( // cipher suites missing from the crypto/tls package, // in no particular order here TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384 = 0xc024 TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256 = 0xc023 TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384 = 0xc028 TLS_RSA_WITH_AES_128_CBC_SHA256 = 0x3c TLS_RSA_WITH_AES_256_CBC_SHA256 = 0x3d TLS_DHE_RSA_WITH_AES_128_CBC_SHA = 0x33 TLS_DHE_RSA_WITH_AES_256_CBC_SHA = 0x39 TLS_RSA_WITH_RC4_128_MD5 = 0x4 )
const ( // DefaultHost is the default host. DefaultHost = "" // DefaultPort is the default port. DefaultPort = "2015" // DefaultRoot is the default root folder. DefaultRoot = "." // DefaultHTTPPort is the default port for HTTP. DefaultHTTPPort = "80" // DefaultHTTPSPort is the default port for HTTPS. DefaultHTTPSPort = "443" )
const (
// MaxLogBodySize limits the size of logged request's body
MaxLogBodySize = 100 * 1024
)
Variables ¶
var ( // Root is the site root Root = DefaultRoot // Host is the site host Host = DefaultHost // Port is the site port Port = DefaultPort // GracefulTimeout is the maximum duration of a graceful shutdown. GracefulTimeout time.Duration // HTTP2 indicates whether HTTP2 is enabled or not. HTTP2 bool // QUIC indicates whether QUIC is enabled or not. QUIC bool // HTTPPort is the port to use for HTTP. HTTPPort = DefaultHTTPPort // HTTPSPort is the port to use for HTTPS. HTTPSPort = DefaultHTTPSPort )
These "soft defaults" are configurable by command line flags, etc.
var CaseSensitivePath = true
CaseSensitivePath determines if paths should be case sensitive. This is configurable via CASE_SENSITIVE_PATH environment variable.
var EmptyNext = HandlerFunc(func(w http.ResponseWriter, r *http.Request) (int, error) { return 0, nil })
EmptyNext is a no-op function that can be passed into Middleware functions so that the assignment to the Next field of the Handler can be tested.
Used primarily for testing but needs to be exported so plugins can use this as a convenience.
var TemplateFuncs = template.FuncMap{}
TemplateFuncs contains user defined functions
Functions ¶
func CleanMaskedPath ¶ added in v0.9.5
CleanMaskedPath prevents one or more of the path cleanup operations:
- collapse multiple slashes into one
- eliminate "/." (current directory)
- eliminate "<parent_directory>/.."
by masking certain patterns in the path with a temporary random string. This could be helpful when certain patterns in the path are desired to be preserved that would otherwise be changed by path.Clean(). One such use case is the presence of the double slashes as protocol separator (e.g., /api/endpoint/http://example.com). This is a common pattern in many applications to allow passing URIs as path argument.
func CleanPath ¶ added in v0.9.5
CleanPath calls CleanMaskedPath() with the default mask of "://" to preserve double slashes of protocols such as "http://", "https://", and "ftp://" etc.
func ContextInclude ¶
func ContextInclude(filename string, ctx interface{}, fs http.FileSystem) (string, error)
ContextInclude opens filename using fs and executes a template with the context ctx. This does the same thing that Context.Include() does, but with the ability to provide your own context so that the included files can have access to additional fields your type may provide. You can embed Context in your type, then override its Include method to call this function with ctx being the instance of your type, and fs being Context.Root.
func DefaultErrorFunc ¶
func DefaultErrorFunc(w http.ResponseWriter, r *http.Request, status int)
DefaultErrorFunc responds to an HTTP request with a simple description of the specified HTTP status code.
func IfMatcherKeyword ¶
func IfMatcherKeyword(c *caddy.Controller) bool
IfMatcherKeyword checks if the next value in the dispenser is a keyword for 'if' config block. If true, remaining arguments in the dispinser are cleard to keep the dispenser valid for use.
func IndexFile ¶
IndexFile looks for a file in /root/fpath/indexFile for each string in indexFiles. If an index file is found, it returns the root-relative path to the file and true. If no index file is found, empty string and false is returned. fpath must end in a forward slash '/' otherwise no index files will be tried (directory paths must end in a forward slash according to HTTP).
All paths passed into and returned from this function use '/' as the path separator, just like URLs. IndexFle handles path manipulation internally for systems that use different path separators.
func IsLogRollerSubdirective ¶ added in v0.10.0
IsLogRollerSubdirective is true if the subdirective is for the log roller.
func MaxBytesReader ¶ added in v0.9.4
func MaxBytesReader(w http.ResponseWriter, r io.ReadCloser, n int64) io.ReadCloser
MaxBytesReader and its associated methods are borrowed from the Go Standard library (comments intact). The only difference is that it returns a MaxBytesExceeded error instead of a generic error message when the request body has exceeded the requested limit
func ParseRoller ¶
ParseRoller parses roller contents out of c.
func RegisterDevDirective ¶ added in v0.9.2
func RegisterDevDirective(name, before string)
RegisterDevDirective splices name into the list of directives immediately before another directive. This function is ONLY for plugin development purposes! NEVER use it for a plugin that you are not currently building. If before is empty, the directive will be appended to the end of the list.
It is imperative that directives execute in the proper order, and hard-coding the list of directives guarantees a correct, absolute order every time. This function is convenient when developing a plugin, but it does not guarantee absolute ordering. Multiple plugins registering directives with this function will lead to non- deterministic builds and buggy software.
Directive names must be lower-cased and unique. Any errors here are fatal, and even successful calls print a message to stdout as a reminder to use it only in development.
func SameNext ¶
SameNext does a pointer comparison between next1 and next2.
Used primarily for testing but needs to be exported so plugins can use this as a convenience.
func SetLastModifiedHeader ¶
func SetLastModifiedHeader(w http.ResponseWriter, modTime time.Time)
SetLastModifiedHeader checks if the provided modTime is valid and if it is sets it as a Last-Modified header to the ResponseWriter. If the modTime is in the future the current time is used instead.
func WriteTextResponse ¶
func WriteTextResponse(w http.ResponseWriter, status int, body string)
WriteTextResponse writes body with code status to w. The body will be interpreted as plain text.
Types ¶
type Address ¶
type Address struct {
Original, Scheme, Host, Port, Path string
}
Address represents a site address. It contains the original input value, and the component parts of an address. The component parts may be updated to the correct values as setup proceeds, but the original value should never be changed.
type ConfigSelector ¶
type ConfigSelector []HandlerConfig
ConfigSelector selects a configuration.
func (ConfigSelector) Select ¶
func (c ConfigSelector) Select(r *http.Request) (config HandlerConfig)
Select selects a Config. This chooses the config with the longest length.
type Context ¶
type Context struct { Root http.FileSystem Req *http.Request URL *url.URL Args []interface{} // defined by arguments to .Include }
Context is the context with which Caddy templates are executed.
func (Context) Ext ¶
Ext returns the suffix beginning at the final dot in the final slash-separated element of the pathStr (or in other words, the file extension).
func (Context) Files ¶ added in v0.9.4
Files reads and returns a slice of names from the given directory relative to the root of Context c.
func (Context) Hostname ¶ added in v0.10.0
Hostname gets the (remote) hostname of the client making the request.
func (Context) IsMITM ¶ added in v0.10.0
IsMITM returns true if it seems likely that the TLS connection is being intercepted.
func (Context) Join ¶ added in v0.9.1
Join is a pass-through to strings.Join. It will join the first argument slice with the separator in the second argument and return the result.
func (Context) Map ¶
Map will convert the arguments into a map. It expects alternating string keys and values. This is useful for building more complicated data structures if you are using subtemplates or things like that.
func (Context) Markdown ¶
Markdown returns the HTML contents of the markdown contained in filename (relative to the site root).
func (Context) NowDate ¶
NowDate returns the current date/time that can be used in other time functions.
func (Context) PathMatches ¶
PathMatches returns true if the path portion of the request URL matches pattern.
func (Context) RandomString ¶ added in v0.10.0
RandomString generates a random string of random length given length bounds. Thanks to http://stackoverflow.com/a/35615565/1048862 for the clever technique that is fairly fast, secure, and maintains proper distributions over the dictionary.
func (Context) ServerIP ¶ added in v0.10.0
ServerIP gets the (local) IP address of the server. TODO: The bind directive should be honored in this method (see PR #1474).
func (Context) Slice ¶
func (c Context) Slice(elems ...interface{}) []interface{}
Slice will convert the given arguments into a slice.
func (Context) Split ¶
Split is a pass-through to strings.Split. It will split the first argument at each instance of the separator and return a slice of strings.
func (Context) StripExt ¶
StripExt returns the input string without the extension, which is the suffix starting with the final '.' character but not before the final path separator ('/') character. If there is no extension, the whole input is returned.
func (Context) StripHTML ¶
StripHTML returns s without HTML tags. It is fairly naive but works with most valid HTML inputs.
type Handler ¶
Handler is like http.Handler except ServeHTTP may return a status code and/or error.
If ServeHTTP writes the response header, it should return a status code of 0. This signals to other handlers before it that the response is already handled, and that they should not write to it also. Keep in mind that writing to the response body writes the header, too.
If ServeHTTP encounters an error, it should return the error value so it can be logged by designated error-handling middleware.
If writing a response after calling the next ServeHTTP method, the returned status code SHOULD be used when writing the response.
If handling errors after calling the next ServeHTTP method, the returned error value SHOULD be logged or handled accordingly.
Otherwise, return values should be propagated down the middleware chain by returning them unchanged.
type HandlerConfig ¶
type HandlerConfig interface { RequestMatcher BasePath() string }
HandlerConfig is a middleware configuration. This makes it possible for middlewares to have a common configuration interface.
TODO The long term plan is to get all middleware implement this interface for configurations.
type HandlerFunc ¶
HandlerFunc is a convenience type like http.HandlerFunc, except ServeHTTP returns a status code and an error. See Handler documentation for more information.
func (HandlerFunc) ServeHTTP ¶
func (f HandlerFunc) ServeHTTP(w http.ResponseWriter, r *http.Request) (int, error)
ServeHTTP implements the Handler interface.
type IfMatcher ¶
type IfMatcher struct {
// contains filtered or unexported fields
}
IfMatcher is a RequestMatcher for 'if' conditions.
type ListenerMiddleware ¶ added in v0.10.0
ListenerMiddleware is similar to the Middleware type, except it chains one net.Listener to the next.
type LogRoller ¶
LogRoller implements a type that provides a rolling logger.
func DefaultLogRoller ¶ added in v0.10.0
func DefaultLogRoller() *LogRoller
DefaultLogRoller will roll logs by default.
func (LogRoller) GetLogWriter ¶
GetLogWriter returns an io.Writer that writes to a rolling logger. This should be called only from the main goroutine (like during server setup) because this method is not thread-safe; it is careful to create only one log writer per log file, even if the log file is shared by different sites or middlewares. This ensures that rolling is synchronized, since a process (or multiple processes) should not create more than one roller on the same file at the same time. See issue #1363.
type Logger ¶ added in v0.10.0
type Logger struct { Output string *log.Logger Roller *LogRoller // contains filtered or unexported fields }
Logger is shared between errors and log plugins and supports both logging to a file (with an optional file roller), local and remote syslog servers.
func NewTestLogger ¶ added in v0.10.0
NewTestLogger creates logger suitable for testing purposes
func (*Logger) Attach ¶ added in v0.10.0
func (l *Logger) Attach(controller *caddy.Controller)
Attach binds logger Start and Close functions to controller's OnStartup and OnShutdown hooks.
type MaxBytesExceeded ¶ added in v0.9.4
type MaxBytesExceeded struct{}
MaxBytesExceeded is the error type returned by MaxBytesReader when the request body exceeds the limit imposed
func (MaxBytesExceeded) Error ¶ added in v0.9.4
func (err MaxBytesExceeded) Error() string
type Middleware ¶
Middleware is the middle layer which represents the traditional idea of middleware: it chains one Handler to the next by being passed the next Handler in the chain.
type NonCloseNotifierError ¶ added in v0.9.4
type NonCloseNotifierError struct {
// underlying type which doesn't implement CloseNotify
Underlying interface{}
}
NonCloseNotifierError is more descriptive error caused by a non closeNotifier
func (NonCloseNotifierError) Error ¶ added in v0.9.4
func (c NonCloseNotifierError) Error() string
Implement Error
type NonFlusherError ¶ added in v0.9.4
type NonFlusherError struct {
// underlying type which doesn't implement Flush
Underlying interface{}
}
NonFlusherError is more descriptive error caused by a non flusher
func (NonFlusherError) Error ¶ added in v0.9.4
func (f NonFlusherError) Error() string
Implement Error
type NonHijackerError ¶ added in v0.9.4
type NonHijackerError struct {
// underlying type which doesn't implement Hijack
Underlying interface{}
}
NonHijackerError is more descriptive error caused by a non hijacker
func (NonHijackerError) Error ¶ added in v0.9.4
func (h NonHijackerError) Error() string
Implement Error
type PathLimit ¶ added in v0.9.4
PathLimit is a mapping from a site's path to its corresponding maximum request body size (in bytes)
type Replacer ¶
Replacer is a type which can replace placeholder substrings in a string with actual values from a http.Request and ResponseRecorder. Always use NewReplacer to get one of these. Any placeholders made with Set() should overwrite existing values if the key is already used.
func NewReplacer ¶
func NewReplacer(r *http.Request, rr *ResponseRecorder, emptyValue string) Replacer
NewReplacer makes a new replacer based on r and rr which are used for request and response placeholders, respectively. Request placeholders are created immediately, whereas response placeholders are not created until Replace() is invoked. rr may be nil if it is not available. emptyValue should be the string that is used in place of empty string (can still be empty string).
type RequestMatcher ¶
RequestMatcher checks to see if current request should be handled by underlying handler.
func MergeRequestMatchers ¶
func MergeRequestMatchers(matchers ...RequestMatcher) RequestMatcher
MergeRequestMatchers merges multiple RequestMatchers into one. This allows a middleware to use multiple RequestMatchers.
func SetupIfMatcher ¶
func SetupIfMatcher(controller *caddy.Controller) (RequestMatcher, error)
SetupIfMatcher parses `if` or `if_op` in the current dispenser block. It returns a RequestMatcher and an error if any.
type ResponseRecorder ¶
type ResponseRecorder struct { http.ResponseWriter Replacer Replacer // contains filtered or unexported fields }
ResponseRecorder is a type of http.ResponseWriter that captures the status code written to it and also the size of the body written in the response. A status code does not have to be written, however, in which case 200 must be assumed. It is best to have the constructor initialize this type with that default status code.
Setting the Replacer field allows middlewares to type-assert the http.ResponseWriter to ResponseRecorder and set their own placeholder values for logging utilities to use.
Beware when accessing the Replacer value; it may be nil!
func NewResponseRecorder ¶
func NewResponseRecorder(w http.ResponseWriter) *ResponseRecorder
NewResponseRecorder makes and returns a new responseRecorder, which captures the HTTP Status code from the ResponseWriter and also the length of the response body written through it. Because a status is not set unless WriteHeader is called explicitly, this constructor initializes with a status code of 200 to cover the default case.
func (*ResponseRecorder) CloseNotify ¶
func (r *ResponseRecorder) CloseNotify() <-chan bool
CloseNotify implements http.CloseNotifier. It just inherits the underlying ResponseWriter's CloseNotify method.
func (*ResponseRecorder) Flush ¶
func (r *ResponseRecorder) Flush()
Flush implements http.Flusher. It simply wraps the underlying ResponseWriter's Flush method if there is one, or does nothing.
func (*ResponseRecorder) Hijack ¶
func (r *ResponseRecorder) Hijack() (net.Conn, *bufio.ReadWriter, error)
Hijack implements http.Hijacker. It simply wraps the underlying ResponseWriter's Hijack method if there is one, or returns an error.
func (*ResponseRecorder) Push ¶ added in v0.10.0
func (r *ResponseRecorder) Push(target string, opts *http.PushOptions) error
Push resource to client
func (*ResponseRecorder) Size ¶
func (r *ResponseRecorder) Size() int
Size is a Getter to size property
func (*ResponseRecorder) Status ¶
func (r *ResponseRecorder) Status() int
Status is a Getter to status property
func (*ResponseRecorder) Write ¶
func (r *ResponseRecorder) Write(buf []byte) (int, error)
Write is a wrapper that records the size of the body that gets written.
func (*ResponseRecorder) WriteHeader ¶
func (r *ResponseRecorder) WriteHeader(status int)
WriteHeader records the status code and calls the underlying ResponseWriter's WriteHeader method.
type Server ¶
Server is the HTTP server implementation.
func NewServer ¶
func NewServer(addr string, group []*SiteConfig) (*Server, error)
NewServer creates a new Server instance that will listen on addr and will serve the sites configured in group.
func (*Server) ListenPacket ¶
func (s *Server) ListenPacket() (net.PacketConn, error)
ListenPacket creates udp connection for QUIC if it is enabled,
func (*Server) OnStartupComplete ¶
func (s *Server) OnStartupComplete()
OnStartupComplete lists the sites served by this server and any relevant information, assuming caddy.Quiet == false.
func (*Server) ServeHTTP ¶
func (s *Server) ServeHTTP(w http.ResponseWriter, r *http.Request)
ServeHTTP is the entry point of all HTTP requests.
func (*Server) ServePacket ¶
func (s *Server) ServePacket(pc net.PacketConn) error
ServePacket serves QUIC requests on pc until it is closed.
type SiteConfig ¶
type SiteConfig struct { // The address of the site Addr Address // The hostname to bind listener to; // defaults to Addr.Host ListenHost string // TLS configuration TLS *caddytls.Config // Directory from which to serve files Root string // A list of files to hide (for example, the // source Caddyfile). TODO: Enforcing this // should be centralized, for example, a // standardized way of loading files from disk // for a request. HiddenFiles []string // Max amount of bytes a request can send on a given path MaxRequestBodySizes []PathLimit // These timeout values are used, in conjunction with other // site configs on the same server instance, to set the // respective timeout values on the http.Server that // is created. Sensible values will mitigate slowloris // attacks and overcome faulty networks, while still // preserving functionality needed for proxying, // websockets, etc. Timeouts Timeouts // contains filtered or unexported fields }
SiteConfig contains information about a site (also known as a virtual host).
func GetConfig ¶
func GetConfig(c *caddy.Controller) *SiteConfig
GetConfig gets the SiteConfig that corresponds to c. If none exist (should only happen in tests), then a new, empty one will be created.
func (*SiteConfig) AddListenerMiddleware ¶ added in v0.10.0
func (s *SiteConfig) AddListenerMiddleware(l ListenerMiddleware)
AddListenerMiddleware adds a listener middleware to a site's listenerMiddleware stack.
func (*SiteConfig) AddMiddleware ¶
func (s *SiteConfig) AddMiddleware(m Middleware)
AddMiddleware adds a middleware to a site's middleware stack.
func (SiteConfig) ListenerMiddleware ¶ added in v0.10.0
func (s SiteConfig) ListenerMiddleware() []ListenerMiddleware
ListenerMiddleware returns s.listenerMiddleware
func (SiteConfig) Middleware ¶
func (s SiteConfig) Middleware() []Middleware
Middleware returns s.middleware (useful for tests).
func (SiteConfig) TLSConfig ¶
func (s SiteConfig) TLSConfig() *caddytls.Config
TLSConfig returns s.TLS.
type Timeouts ¶ added in v0.9.5
type Timeouts struct { ReadTimeout time.Duration ReadTimeoutSet bool ReadHeaderTimeout time.Duration ReadHeaderTimeoutSet bool WriteTimeout time.Duration WriteTimeoutSet bool IdleTimeout time.Duration IdleTimeoutSet bool }
Timeouts specify various timeouts for a server to use. If the assocated bool field is true, then the duration value should be treated literally (i.e. a zero-value duration would mean "no timeout"). If false, the duration was left unset, so a zero-value duration would mean to use a default value (even if default is non-zero).