diff --git a/cache.go b/cache.go index 6f674c32..c78a5477 100644 --- a/cache.go +++ b/cache.go @@ -71,7 +71,6 @@ func (cs *cacheService) start() { now := time.Now() for k, v := range cs.cache { if now.After(v.expires) { - println("remove cache") delete(cs.cache, k) } } @@ -84,7 +83,7 @@ func (cs *cacheService) start() { func (cs *cacheService) get(key string) *cacheEntry { cs.mu.RLock() - if v, ok := cs.cache[key]; ok { + if v, ok := cs.cache[key]; ok && time.Now().Before(v.expires) { // we check for expiration, the gc clears the cache but gc maybe late cs.mu.RUnlock() return v } @@ -199,13 +198,8 @@ func getResponseStatusCode(ctx *Context) int { func (cs *cacheService) Cache(bodyHandler HandlerFunc, expiration time.Duration) HandlerFunc { expiration = validateCacheDuration(expiration) - if cs.gcDuration == -1 { - // if gc duration is not setted yet or this is the only one Cache which happens to have bigger expiration than the minimumAllowedCacheDuration - // then set that as the gcDuration - cs.gcDuration = expiration // the first time the lowerExpiration should be > minimumAllowedCacheDuration so: - } else if expiration < cs.gcDuration { // find the lower - // if this expiration is lower than the already setted, set the gcDuration to this - cs.gcDuration = expiration + if cs.gcDuration == -1 || expiration < cs.gcDuration { + cs.gcDuration = expiration // the first time the gcDuration should be > minimumAllowedCacheDuration so: } h := func(ctx *Context) { @@ -245,6 +239,9 @@ const ( queryCacheDuration = "cache_duration" queryCacheStatusCode = "cache_status_code" queryCacheContentType = "cache_content_type" + requestCacheTimeout = 5 * time.Second + statusCacheSucceed = StatusOK + statusCacheFailed = StatusBadRequest ) // RemoteCache accepts the remote server address and path of the external cache service, the body handler and optional an expiration @@ -262,25 +259,25 @@ func RemoteCache(cacheServerAddr string, bodyHandler HandlerFunc, expiration tim req := fasthttp.AcquireRequest() req.SetRequestURI(cacheServerAddr) req.Header.SetMethodBytes(MethodGetBytes) - req.URI().QueryArgs().Add("cache_key", GetRemoteCacheKey(ctx)) + req.URI().QueryArgs().Add(queryCacheKey, GetRemoteCacheKey(ctx)) res := fasthttp.AcquireResponse() - err := client.DoTimeout(req, res, time.Duration(5)*time.Second) - if err != nil || res.StatusCode() == StatusBadRequest { + err := client.DoTimeout(req, res, requestCacheTimeout) + if err != nil || res.StatusCode() == statusCacheFailed { // if not found on cache, then execute the handler and save the cache to the remote server bodyHandler.Serve(ctx) // save to the remote cache req.Header.SetMethodBytes(MethodPostBytes) - - req.URI().QueryArgs().Add("cache_duration", cacheDurationStr) + args := req.URI().QueryArgs() + args.Add(queryCacheDuration, cacheDurationStr) statusCode := strconv.Itoa(ctx.Response.StatusCode()) - req.URI().QueryArgs().Add("cache_status_code", statusCode) + args.Add(queryCacheStatusCode, statusCode) cType := string(ctx.Response.Header.Peek(contentType)) - req.URI().QueryArgs().Add("cache_content_type", cType) + args.Add(queryCacheContentType, cType) req.SetBody(ctx.Response.Body()) go func() { - client.DoTimeout(req, res, time.Duration(5)*time.Second) + client.DoTimeout(req, res, requestCacheTimeout) fasthttp.ReleaseRequest(req) fasthttp.ReleaseResponse(res) }() @@ -332,11 +329,11 @@ func ServeRemoteCache(gcDuration time.Duration) HandlerFunc { // use the app.ServeRemoteCache instead of iris.ServeRemoteCache func (cs *cacheService) ServeRemoteCache(gcDuration time.Duration) HandlerFunc { cs.gcDuration = validateCacheDuration(gcDuration) - + // the service started at pre-listen state(on .Build) if gcDuration > 0 h := func(ctx *Context) { - key := ctx.URLParam("cache_key") + key := ctx.URLParam(queryCacheKey) if key == "" { - ctx.SetStatusCode(StatusBadRequest) + ctx.SetStatusCode(statusCacheFailed) return } @@ -347,11 +344,11 @@ func (cs *cacheService) ServeRemoteCache(gcDuration time.Duration) HandlerFunc { } } else if ctx.IsPost() { // get the cache expiration via url param - expirationSeconds, err := ctx.URLParamInt64("cache_duration") + expirationSeconds, err := ctx.URLParamInt64(queryCacheDuration) // get the body from the requested body body := ctx.Request.Body() if len(body) == 0 { - ctx.SetStatusCode(StatusBadRequest) + ctx.SetStatusCode(statusCacheFailed) return } @@ -365,27 +362,22 @@ func (cs *cacheService) ServeRemoteCache(gcDuration time.Duration) HandlerFunc { expirationSeconds = int64(minimumAllowedCacheDuration.Seconds()) } - cacheDuration := time.Duration(expirationSeconds) * time.Second - statusCode, err := ctx.URLParamInt("cache_status_code") - if err != nil { - statusCode = StatusOK - } - cType := ctx.URLParam("cache_content_type") - if cType == "" { - cType = contentHTML - } + cacheDuration := validateCacheDuration(time.Duration(expirationSeconds) * time.Second) + statusCode, _ := ctx.URLParamInt(queryCacheDuration) + statusCode = validateStatusCode(statusCode) + cType := validateContentType(ctx.URLParam(queryCacheContentType)) cs.set(key, statusCode, cType, body, cacheDuration) - ctx.SetStatusCode(StatusOK) + ctx.SetStatusCode(statusCacheSucceed) return } else if ctx.IsDelete() { cs.remove(key) - ctx.SetStatusCode(StatusOK) + ctx.SetStatusCode(statusCacheSucceed) return } - ctx.SetStatusCode(StatusBadRequest) + ctx.SetStatusCode(statusCacheFailed) } return h diff --git a/http.go b/http.go index 0d0c5943..bc9a1934 100644 --- a/http.go +++ b/http.go @@ -1207,7 +1207,7 @@ func CERT(addr string, cert tls.Certificate) (net.Listener, error) { // LETSENCRYPT returns a new Automatic TLS Listener using letsencrypt.org service // receives two parameters, the first is the domain of the server // and the second is optionally, the cache file, if you skip it then the cache directory is "./letsencrypt.cache" -// if you want to disable cache file then simple give it a value of emtpy string "" +// if you want to disable cache file then simple give it a value of empty string "" // // supports localhost domains for testing, // but I recommend you to use the LETSENCRYPTPROD if you gonna to use it on production @@ -1243,7 +1243,7 @@ func LETSENCRYPT(addr string, cacheFileOptional ...string) (net.Listener, error) // LETSENCRYPTPROD returns a new Automatic TLS Listener using letsencrypt.org service // receives two parameters, the first is the domain of the server // and the second is optionally, the cache directory, if you skip it then the cache directory is "./certcache" -// if you want to disable cache directory then simple give it a value of emtpy string "" +// if you want to disable cache directory then simple give it a value of empty string "" // // does NOT supports localhost domains for testing, use LETSENCRYPT instead. // diff --git a/iris.go b/iris.go index 0d3e3418..d5742046 100644 --- a/iris.go +++ b/iris.go @@ -553,7 +553,7 @@ func (s *Framework) ListenTLS(addr string, certFile, keyFile string) { // it's also starts a second 'http' server to redirect all 'http://$ADDR_HOSTNAME:80' to the' https://$ADDR' // it creates a cache file to store the certifications, for performance reasons, this file by-default is "./letsencrypt.cache" // if you skip the second parameter then the cache file is "./letsencrypt.cache" -// if you want to disable cache then simple pass as second argument an empty emtpy string "" +// if you want to disable cache then simple pass as second argument an empty empty string "" // // example: https://github.com/iris-contrib/examples/blob/master/letsencyrpt/main.go // @@ -568,7 +568,7 @@ func ListenLETSENCRYPT(addr string, cacheFileOptional ...string) { // it's also starts a second 'http' server to redirect all 'http://$ADDR_HOSTNAME:80' to the' https://$ADDR' // it creates a cache file to store the certifications, for performance reasons, this file by-default is "./letsencrypt.cache" // if you skip the second parameter then the cache file is "./letsencrypt.cache" -// if you want to disable cache then simple pass as second argument an empty emtpy string "" +// if you want to disable cache then simple pass as second argument an empty empty string "" // // example: https://github.com/iris-contrib/examples/blob/master/letsencyrpt/main.go //