Documentation ¶
Index ¶
- Constants
- Variables
- func CommonLog(w io.Writer) *commonLog
- func DefaultCallback(err error)
- func HeaderHas(h http.Header, key string, value string) bool
- func MemDir(path string) http.FileSystem
- func NewTraceFileSystem(f http.FileSystem) http.FileSystem
- func NewTrackingListener(l net.Listener, wg sync.WaitGroup) net.Listener
- func WriteJSON(w http.ResponseWriter, v interface{}) (int, error)
- func WriteJSONWithStatus(w http.ResponseWriter, code int, v interface{}) (int, error)
- type BasicAuthChecker
- type Chain
- type ErrorCallback
- type HTTPLogger
- type JSONData
- type MemRef
- type MemoryFile
- type MemoryFileSystem
- type Middleware
- func BasicAuthMiddleware(h http.Handler, realm string, c BasicAuthChecker) Middleware
- func CORSMiddleware(origin string, maxAge int) Middleware
- func CleanPathMiddleware() Middleware
- func GzipMiddleware(level int) Middleware
- func LogMiddleware(f HTTPLogger) Middleware
- func RecoveryMiddleware(callback ErrorCallback) Middleware
- func RequestIDMiddleware(g RequestIDGenerator) Middleware
- type MiddlewareList
- type RequestIDGenerator
Examples ¶
Constants ¶
const ( CommonLogFormat = `%h %l %u %t "%r" %>s %b` CommonDateFormat = "02/Jan/2006:15:04:05 -0700" )
const ( HeaderOrigin = "Origin" HeaderAccessControlAllowCredentials = "Access-Control-Allow-Credentials" HeaderAccessControlAllowHeaders = "Access-Control-Allow-Headers" HeaderAccessControlAllowOrigin = "Access-Control-Allow-Origin" HeaderAccessControlAllowMethods = "Access-Control-Allow-Methods" HeaderAccessControlRequestHeaders = "Access-Control-Request-Headers" HeaderAccessControlRequestMethod = "Access-Control-Request-Method" HeaderAccessControlExposeHeaders = "Access-Control-Expose-Headers" HeaderAccessControlMaxAge = "Access-Control-Max-Age" )
CORS-specific HTTP header extensions
const ( CONNECT = http.MethodConnect DELETE = http.MethodDelete GET = http.MethodGet HEAD = http.MethodHead OPTIONS = http.MethodOptions PATCH = http.MethodPatch // RFC 5789 POST = http.MethodPost PUT = http.MethodPut TRACE = http.MethodTrace )
HTTP methods
const ( HeaderAccept = "Accept" HeaderAcceptCharset = "Accept-Charset" HeaderAcceptEncoding = "Accept-Encoding" HeaderAcceptLanguage = "Accept-Language" HeaderAcceptRanges = "Accept-Ranges" HeaderAcceptPatch = "Accept-Patch" // RFC 5789 HeaderAge = "Age" HeaderAllow = "Allow" HeaderAllowPatch = "Allow-Patch" // RFC 5741 HeaderAuthorization = "Authorization" HeaderCacheControl = "Cache-Control" HeaderConnection = "Connection" HeaderContentDisposition = "Content-Disposition" // RFC 6266 HeaderContentEncoding = "Content-Encoding" HeaderContentLanguage = "Content-Language" HeaderContentLength = "Content-Length" HeaderContentLocation = "Content-Location" HeaderContentRange = "Content-Range" HeaderContentType = "Content-Type" HeaderCookie = "Cookie" HeaderDate = "Date" HeaderETag = "ETag" HeaderExpect = "Expect" HeaderExpires = "Expires" HeaderFrom = "From" HeaderHost = "Host" HeaderIfMatch = "If-Match" HeaderIfModifiedSince = "If-Modified-Since" HeaderIfNoneMatch = "If-None-Match" HeaderIfRange = "If-Range" HeaderIfUnmodifiedSince = "If-Unmodified-Since" HeaderKeepAlive = "Keep-Alive" HeaderLastModified = "Last-Modified" HeaderLocation = "Location" HeaderMaxForwards = "Max-Forwards" HeaderPragma = "Pragma" HeaderProxyAuthenticate = "Proxy-Authenticate" HeaderProxyAuthorization = "Proxy-Authorization" HeaderRange = "Range" HeaderReferer = "Referer" HeaderRetryAfter = "Retry-After" HeaderServer = "Server" HeaderSetCookie = "Set-Cookie" HeaderStrictTransportSecurity = "Strict-Transport-Security" // HSTS HeaderTE = "TE" HeaderTrailer = "Trailer" HeaderTransferEncoding = "Transfer-Encoding" HeaderUpgrade = "Upgrade" HeaderUserAgent = "User-Agent" HeaderVary = "Vary" HeaderVia = "Via" HeaderWWWAuthenticate = "WWW-Authenticate" HeaderWarning = "Warning" HeaderXForwardedFor = "X-Forwarded-For" HeaderXForwardedProto = "X-Forwarded-Proto" HeaderXFrameOptions = "X-Frame-Options" // RFC 7034 HeaderXRequestID = "X-Request-ID" )
HTTP headers
Everything is from RFC2616 + CORS + RFC 5741 + De-facto extensions
const ( StatusContinue = 100 StatusSwitchingProtocols = 101 StatusOK = 200 StatusCreated = 201 StatusAccepted = 202 StatusNonAuthoritativeInfo = 203 StatusNoContent = 204 StatusResetContent = 205 StatusPartialContent = 206 StatusMultipleChoices = 300 StatusMovedPermanently = 301 StatusFound = 302 StatusSeeOther = 303 StatusNotModified = 304 StatusUseProxy = 305 StatusTemporaryRedirect = 307 StatusBadRequest = 400 StatusPaymentRequired = 402 StatusForbidden = 403 StatusNotFound = 404 StatusMethodNotAllowed = 405 StatusNotAcceptable = 406 StatusProxyAuthRequired = 407 StatusRequestTimeout = 408 StatusConflict = 409 StatusGone = 410 StatusLengthRequired = 411 StatusPreconditionFailed = 412 StatusRequestEntityTooLarge = 413 StatusRequestURITooLong = 414 StatusUnsupportedMediaType = 415 StatusRequestedRangeNotSatisfiable = 416 StatusExpectationFailed = 417 StatusTeapot = 418 StatusPreconditionRequired = 428 StatusTooManyRequests = 429 StatusRequestHeaderFieldsTooLarge = 431 StatusInternalServerError = 500 StatusNotImplemented = 501 StatusBadGateway = 502 StatusGatewayTimeout = 504 StatusHTTPVersionNotSupported = 505 StatusNetworkAuthenticationRequired = 511 )
const JSONContentType = "application/json"
Variables ¶
var HopByHopHeaders = []string{ HeaderConnection, HeaderKeepAlive, HeaderProxyAuthenticate, HeaderProxyAuthorization, HeaderTE, HeaderTrailer, HeaderTransferEncoding, HeaderUpgrade, }
See http://www.w3.org/Protocols/rfc2616/rfc2616-sec13.html#sec13.5.1
var RequestHeaders = []string{ HeaderAccept, HeaderAcceptCharset, HeaderAcceptEncoding, HeaderAcceptLanguage, HeaderAcceptRanges, HeaderAuthorization, HeaderCacheControl, HeaderConnection, HeaderContentLength, HeaderContentType, HeaderCookie, HeaderDate, HeaderFrom, HeaderHost, HeaderIfMatch, HeaderIfModifiedSince, HeaderIfNoneMatch, HeaderIfRange, HeaderIfUnmodifiedSince, HeaderMaxForwards, HeaderMaxForwards, HeaderPragma, HeaderProxyAuthorization, HeaderRange, HeaderTE, HeaderUpgrade, HeaderUserAgent, HeaderVia, HeaderWarning, HeaderXForwardedFor, HeaderXForwardedProto, HeaderXRequestID, }
var ResponseHeaders = []string{ HeaderAcceptPatch, HeaderAcceptRanges, HeaderAge, HeaderAllow, HeaderCacheControl, HeaderConnection, HeaderContentDisposition, HeaderContentEncoding, HeaderContentLanguage, HeaderContentLength, HeaderContentLocation, HeaderContentRange, HeaderContentType, HeaderDate, HeaderETag, HeaderExpires, HeaderLastModified, HeaderLocation, HeaderPragma, HeaderProxyAuthenticate, HeaderRange, HeaderTrailer, HeaderTransferEncoding, HeaderVary, HeaderVia, HeaderWWWAuthenticate, HeaderWarning, HeaderXFrameOptions, HeaderAccessControlAllowMethods, HeaderRetryAfter, HeaderServer, HeaderSetCookie, HeaderStrictTransportSecurity, }
Functions ¶
func CommonLog ¶
Implements the Apache Common Log Format formatting for the LogMiddleware See: https://httpd.apache.org/docs/1.3/logs.html Example:
CommonLog(os.Stdout)
FIXME: Tokenize the string upfront
func DefaultCallback ¶
func DefaultCallback(err error)
func MemDir ¶
func MemDir(path string) http.FileSystem
Returns a new http.FileSystem that is first loaded into memory.
Great when Disk IO is very slow.
func NewTraceFileSystem ¶
func NewTraceFileSystem(f http.FileSystem) http.FileSystem
Used to debug http.FileSystem interfaces.
func NewTrackingListener ¶
A net.Listener that tracks the livelyhood of the connections such that the wg internal counter will go back to it's initial value once the listener and all it's issued net.Conn are closed.
This is useful for gracefully shutting down a server where first new connections are stoppped being accepted and then all the client connections are being shutdown as requests terminate.
Note that net/http.Server only provides HTTP/2 when ListenAndServeTLS is called directly (whereas here you would use the Serve(l) function).
Example ¶
package main import ( "net" "net/http" "os" "os/signal" "sync" "github.com/zimbatm/httputil2" ) func main() { // This WaitGroup is passed around and can be used to make sure everything // is finished. var done sync.WaitGroup // Setup the server s := http.Server{ Handler: http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { w.Write([]byte("hello")) }), } // Listen to connections l, err := net.Listen("tcp", ":8080") if err != nil { panic(err) } // And track them l = httputil2.NewTrackingListener(l, done) // Setup signal handling c := make(chan os.Signal) signal.Notify(c, os.Interrupt, os.Kill) // Close the listener on signal go func() { <-c l.Close() }() err = s.Serve(l) if err != nil { panic(err) } done.Wait() }
Output:
func WriteJSONWithStatus ¶
func WriteJSONWithStatus(w http.ResponseWriter, code int, v interface{}) (int, error)
Types ¶
type BasicAuthChecker ¶
type Chain ¶
type Chain []Middleware
A chain of middlewares
func NewChain ¶
func NewChain(chain ...Middleware) Chain
func (Chain) Append ¶
func (c Chain) Append(m ...Middleware) Chain
func (Chain) HandleFunc ¶
func (c Chain) HandleFunc(h http.HandlerFunc) http.Handler
type ErrorCallback ¶
type ErrorCallback func(error)
type HTTPLogger ¶
type MemRef ¶
func (*MemRef) Readdir ¶
Readdir reads the contents of the directory associated with file and returns a slice of up to n FileInfo values, as would be returned by Lstat, in directory order. Subsequent calls on the same file will yield further FileInfos.
If n > 0, Readdir returns at most n FileInfo structures. In this case, if Readdir returns an empty slice, it will return a non-nil error explaining why. At the end of a directory, the error is io.EOF.
If n <= 0, Readdir returns all the FileInfo from the directory in a single slice. In this case, if Readdir succeeds (reads all the way to the end of the directory), it returns the slice and a nil error. If it encounters an error before the end of the directory, Readdir returns the FileInfo read until that point and a non-nil error.
type MemoryFile ¶
type MemoryFile struct {
// contains filtered or unexported fields
}
func (*MemoryFile) IsDir ¶
func (self *MemoryFile) IsDir() bool
func (*MemoryFile) ModTime ¶
func (self *MemoryFile) ModTime() time.Time
func (*MemoryFile) Mode ¶
func (self *MemoryFile) Mode() os.FileMode
func (*MemoryFile) Name ¶
func (self *MemoryFile) Name() string
func (*MemoryFile) Size ¶
func (self *MemoryFile) Size() int64
func (*MemoryFile) Sys ¶
func (self *MemoryFile) Sys() interface{}
type MemoryFileSystem ¶
type MemoryFileSystem map[string]*MemoryFile
func NewMemoryFileSystem ¶
func NewMemoryFileSystem() MemoryFileSystem
func (MemoryFileSystem) AddDir ¶
func (self MemoryFileSystem) AddDir(path string) (err error)
type Middleware ¶
func BasicAuthMiddleware ¶
func BasicAuthMiddleware(h http.Handler, realm string, c BasicAuthChecker) Middleware
func CORSMiddleware ¶
func CORSMiddleware(origin string, maxAge int) Middleware
func CleanPathMiddleware ¶
func CleanPathMiddleware() Middleware
func GzipMiddleware ¶
func GzipMiddleware(level int) Middleware
You can use gzip.DefaultCompression (-1) or any number between 0 (no compression) and 9 (best compression)
func LogMiddleware ¶
func LogMiddleware(f HTTPLogger) Middleware
func RecoveryMiddleware ¶
func RecoveryMiddleware(callback ErrorCallback) Middleware
Recovers when a panic happens on a request
func RequestIDMiddleware ¶
func RequestIDMiddleware(g RequestIDGenerator) Middleware
Tags a request X-Request-ID header with a given ID from a RequestIDGenerator.
To be used with the uuid lib for example ¶
If g is nil it will use a RandomIDGenerator(32)
type MiddlewareList ¶
Deprecated, use httputil2.Chain instead
func (*MiddlewareList) Chain ¶
func (ml *MiddlewareList) Chain() http.Handler
Puts the list of middleware together, with the last one being the provided ml.Handler.
func (*MiddlewareList) Use ¶
func (ml *MiddlewareList) Use(ms ...Middleware)
Appends more middlewares to the stack
type RequestIDGenerator ¶
type RequestIDGenerator func() string
func RandomIDGenerator ¶
func RandomIDGenerator(size int) RequestIDGenerator
To be used with the IdHandler
size must be a power of 2
may fail if the random pool is exhausted