Documentation ¶
Overview ¶
Example ¶
Example demonstrate the most basic setup for a cache controller where a single origin server is used
package main import ( "fmt" "net/http" "github.com/dylandreimerink/sharedhttpcache/layer" "github.com/dylandreimerink/sharedhttpcache" ) func main() { controller := &sharedhttpcache.CacheController{ DefaultForwardConfig: &sharedhttpcache.ForwardConfig{ Host: "example.com", TLS: true, }, Layers: []layer.CacheLayer{ layer.NewInMemoryCacheLayer(128 * 1024 * 1024), // 128MB of in-memory(RAM) storage }, } server := &http.Server{ Handler: controller, } err := server.ListenAndServe() if err != nil { fmt.Printf("Server exited with error: %s", err.Error()) } }
Output:
Example (Http2) ¶
ExampleHTTP2 demonstrates how to enable HTTP/2 on the connection from the client to the cache server and from the cache server to the origin. It is not required to have both connections support HTTP/2 one or the other will also work
package main import ( "crypto/tls" "crypto/x509" "fmt" "log" "net/http" "github.com/dylandreimerink/sharedhttpcache/layer" "golang.org/x/net/http2" "github.com/dylandreimerink/sharedhttpcache" ) func main() { systemCertPool, err := x509.SystemCertPool() if err != nil { panic(err) } http2Transport := &http2.Transport{ TLSClientConfig: &tls.Config{ RootCAs: systemCertPool, }, } controller := &sharedhttpcache.CacheController{ DefaultForwardConfig: &sharedhttpcache.ForwardConfig{ Host: "example.com", TLS: true, }, DefaultTransport: http2Transport, Layers: []layer.CacheLayer{ layer.NewInMemoryCacheLayer(128 * 1024 * 1024), // 128MB of in-memory(RAM) storage }, } certPem := []byte(`-----BEGIN CERTIFICATE----- MIICGTCCAcCgAwIBAgIIelEInVZKyIUwCgYIKoZIzj0EAwIwVDELMAkGA1UEBhMC TkwxEjAQBgNVBAMMCWxvY2FsaG9zdDETMBEGA1UECAwKU29tZS1TdGF0ZTEcMBoG A1UECgwTRGVmYXVsdCBDb21wYW55IEx0ZDAeFw0xOTExMDQyMjUwMTVaFw0yOTEx MDEyMjUwMTVaMFQxCzAJBgNVBAYTAk5MMRIwEAYDVQQDDAlsb2NhbGhvc3QxEzAR BgNVBAgMClNvbWUtU3RhdGUxHDAaBgNVBAoME0RlZmF1bHQgQ29tcGFueSBMdGQw WTATBgcqhkjOPQIBBggqhkjOPQMBBwNCAAQw8ez8+AGVCZWeWXRBy5EvbeqBVQ1G 8o6zYzVhgN13tY0sCKYaBro7oooyGat1JkcE7CoPE3Gv4n+hOujCd9Yto3wwejAd BgNVHQ4EFgQUUbULEj2qxKQ7NHcIS1XSw+wPtMEwHwYDVR0jBBgwFoAUUbULEj2q xKQ7NHcIS1XSw+wPtMEwDAYDVR0TBAUwAwEB/zALBgNVHQ8EBAMCA6gwHQYDVR0l BBYwFAYIKwYBBQUHAwIGCCsGAQUFBwMBMAoGCCqGSM49BAMCA0cAMEQCIAEzF98B zeZlCSU4EFZO5ZaO+YrqJGQOppWOtQcZgei7AiAS5E2ZhciP5xQEjmE0j3D9CNSG 7DrIoXvr+qKh/1/hcA== -----END CERTIFICATE-----`) keyPem := []byte(`-----BEGIN EC PRIVATE KEY----- MHcCAQEEII7nelmettK1JFHWoSmVHLGa0ho/2nE6bQbiASvKqQXHoAoGCCqGSM49 AwEHoUQDQgAEMPHs/PgBlQmVnll0QcuRL23qgVUNRvKOs2M1YYDdd7WNLAimGga6 O6KKMhmrdSZHBOwqDxNxr+J/oTrownfWLQ== -----END EC PRIVATE KEY-----`) cert, err := tls.X509KeyPair(certPem, keyPem) if err != nil { log.Fatal(err) } server := &http.Server{ Addr: ":4443", Handler: controller, //Use a secure TLS config (As of 2019) TLSConfig: &tls.Config{ Certificates: []tls.Certificate{cert}, MinVersion: tls.VersionTLS12, CurvePreferences: []tls.CurveID{tls.CurveP521, tls.CurveP384, tls.CurveP256}, PreferServerCipherSuites: true, CipherSuites: []uint16{ tls.TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384, tls.TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, tls.TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, tls.TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384, tls.TLS_RSA_WITH_AES_256_GCM_SHA384, }, }, } err = http2.ConfigureServer(server, nil) if err != nil { panic(err) } err = server.ListenAndServeTLS("", "") if err != nil { fmt.Printf("Server exited with error: %s", err.Error()) } }
Output:
Example (MultiOrigin) ¶
ExampleMultiOrigin demonstrates how the cache can forward to multiple origin server. The decision which origin server to use in this example is based on the Host header in the request
package main import ( "fmt" "net/http" "github.com/dylandreimerink/sharedhttpcache/layer" "github.com/dylandreimerink/sharedhttpcache" ) func main() { originServers := map[string]*sharedhttpcache.ForwardConfig{ "example.com": &sharedhttpcache.ForwardConfig{ Host: "2606:2800:220:1:248:1893:25c8:1946", TLS: true, }, "theuselessweb.com": &sharedhttpcache.ForwardConfig{ Host: "3.121.157.244", TLS: false, }, } controller := &sharedhttpcache.CacheController{ ForwardConfigResolver: sharedhttpcache.ForwardConfigResolverFunc(func(req *http.Request) *sharedhttpcache.ForwardConfig { return originServers[req.Host] }), Layers: []layer.CacheLayer{ layer.NewInMemoryCacheLayer(128 * 1024 * 1024), // 128MB of in-memory(RAM) storage }, } server := &http.Server{ Handler: controller, } err := server.ListenAndServe() if err != nil { fmt.Printf("Server exited with error: %s", err.Error()) } }
Output:
Index ¶
Examples ¶
Constants ¶
const ( AgeHeader = "Age" CacheControlHeader = "Cache-Control" ExpiresHeader = "Expires" DateHeader = "Date" VaryHeader = "Vary" NoCacheDirective = "no-cache" NoStoreDirective = "no-store" MustRevalidateDirective = "must-revalidate" ProxyRevalidateDirective = "proxy-revalidate" SMaxAgeDirective = "s-maxage" MaxAgeDirective = "max-age" PublicDirective = "public" PrivateDirective = "private" )
Variables ¶
This section is empty.
Functions ¶
This section is empty.
Types ¶
type CacheConfig ¶
type CacheConfig struct { //CacheableMethods is a list of request methods for which responses may be cached. // It is not advisable to cache unsafe methods like POST. Tho it is possible to do so // Note that unsafe methods will not be cached even if they are in this list as per section 4 of RFC7234 // // WARNING values must be uppercase, no case conversion is done at runtime CacheableMethods []string //SafeMethods is a list of "safe" request methods as defined in section 4.2.1 of RFC7231 // Any method not in this list is considered unsafe and will not be cached // If a request is made with a unsafe method it may cause invalidation as per section 4.4 of RFC7234 SafeMethods []string //StatusCodeDefaultExpirationTimes is a map of times index by the http response code // // These times will be used as default expiration time unless the response contains a header which specifies a different // // Not all responses should be cached for the same duration. // A 307 Temporary Redirect for example should be cached for less time than a 301 Moved Permanently // // Codes not appearing in this list will be considered NOT understood and thus make a response uncacheable according to section 3 of RFC7234. StatusCodeDefaultExpirationTimes map[int]time.Duration //CacheableFileExtensions is a list of cacheable file extensions // File extensions are used instead of MIME types because the same file extension can have separate MIME types // It is advised to only use static file types like stylesheets or images and not dynamic content like html CacheableFileExtensions []string //CacheIncompleteResponses enables or disables the optional feature mentioned in section 3.1 of RFC7234 // Caching of incomplete requests will cache responses with status code 206 (Partial Content) // // Note that this carries a performance impact because ranges have to be accounted for when storing and querying the cached content CacheIncompleteResponses bool //CombinePartialResponses enables or disables the optional feature mentioned in section 3.3 of RFC7234 // When this feature is enabled and incomplete responses are enabled // the caching server attempts to combine multiple incomplete responses into a complete response. // // Note that this carries a performance impact because at every time a new incomplete range is received reconstruction of the full resource will be attempted CombinePartialResponses bool //If ServeStaleOnError is true the cache will attempt to serve a stale response in case revalidation fails because the origin server returned a 5xx code or is unreachable //This setting respects the Cache-Control header of the client and server. ServeStaleOnError bool //If HTTPWarnings is true warnings as described in section 5.5 of RFC7234 will be added to HTTP responses // This is a option because the feature will be removed from future HTTP specs https://github.com/httpwg/http-core/issues/139 HTTPWarnings bool }
CacheConfig defines a config for how the cache should behave A different cache config can be used on a per request basis like for different websites or pages
func NewCacheConfig ¶
func NewCacheConfig() *CacheConfig
NewCacheConfig creates a new CacheConfig struct which is configures with good defaults which satisfy RFC7234
type CacheConfigResolver ¶
type CacheConfigResolver interface { //GetCacheConfig is called to resolve a CacheConfig depending on the request // If nil is returned the default config will be used GetCacheConfig(req *http.Request) *CacheConfig }
A CacheConfigResolver resolves which cache config to use for which request. Different websites or even different pages on the same site can have different cache settings
type CacheController ¶
type CacheController struct { //The default config is used if no host could be matched // if nil on first usage the default config CacheConfig from NewCacheConfig will be used DefaultCacheConfig *CacheConfig //CacheConfigResolver can optionally be set. // If not nil the CacheConfigResolver will be used to determine which cache config to use for a given request // If the CacheConfigResolver is not set the default config will always be used CacheConfigResolver CacheConfigResolver //The default transport used to contact the origin server // If nil the http.DefaultTransport will be used DefaultTransport http.RoundTripper //TransportResolver can optionally be set. // If not nil the TransportResolver will be used to determine which transport to use for a given request // If the TransportResolver is not set the default transport will always be used TransportResolver TransportResolver //The default config used to forward requests to the origin server // If nil all requests using the default config will return a 503 error DefaultForwardConfig *ForwardConfig //ForwardConfigResolver can optionally be set. // If not nil the ForwardConfigResolver will be used to determin which forwardConfig to use for a given request // If the ForwardConfigResolver is not set the DefaultForwardConfig will be used ForwardConfigResolver ForwardConfigResolver //The storage layers which will be searched, the layers are searched in order // Layers should be arranged from fastest to slowest // Faster caching layers typically have less capacity and thus will replace content sooner Layers []layer.CacheLayer //The Logger which will be used for logging // if nil the default logger will be used Logger *logrus.Logger }
The CacheController is the high level interface for a cache. The cache controller calls the caching logic and handles storing and retrieving of cached responses.
func (*CacheController) ServeHTTP ¶
func (controller *CacheController) ServeHTTP(resp http.ResponseWriter, req *http.Request)
type ForwardConfig ¶
type ForwardConfig struct { //Can be a Hostname or a IP address and optionally the tcp port // if no port is specified the default http or https port is used based on the TLS variable Host string //If a https (http over TLS) connection should be used TLS bool }
The ForwardConfig holds information about how to forward traffic to the origin server
type ForwardConfigResolver ¶
type ForwardConfigResolver interface { //GetForwardConfig is called to resolve a ForwardConfig depending on the request // If nil is returned the default forwardConfig will be used GetForwardConfig(req *http.Request) *ForwardConfig }
A ForwardConfigResolver resolves which forward config should be used for a particulair request
type ForwardConfigResolverFunc ¶
type ForwardConfigResolverFunc func(req *http.Request) *ForwardConfig
The ForwardConfigResolverFunc type is an adapter to allow the use of ordinary functions as ForwardConfigResolver
func (ForwardConfigResolverFunc) GetForwardConfig ¶
func (resolver ForwardConfigResolverFunc) GetForwardConfig(req *http.Request) *ForwardConfig
GetForwardConfig calls the underlying function to resolve a forward config from a request
type TransportResolver ¶
type TransportResolver interface { //GetTransport is called to resolve a CacheConfig depending on the request // If nil is returned the default transport will be used GetTransport(req *http.Request) http.RoundTripper }
A TransportResolver resolves which transport should be used for a particulair request
type TransportResolverFunc ¶
type TransportResolverFunc func(req *http.Request) http.RoundTripper
The TransportResolverFunc type is an adapter to allow the use of ordinary functions as TransportResolver
func (TransportResolverFunc) GetTransport ¶
func (resolver TransportResolverFunc) GetTransport(req *http.Request) http.RoundTripper
GetForwardConfig calls the underlying function to resolve a round tripper from a request