From bd661ff9ecd294a6bbfd7687ba49e3df28ceb1c4 Mon Sep 17 00:00:00 2001 From: Marcin Kaciuba Date: Fri, 9 Mar 2018 22:22:01 +0100 Subject: [PATCH] Fixes response status code --- pkg/processor/processor.go | 27 ++++++++++++++++++--------- pkg/response/response.go | 3 ++- pkg/storage/storage.go | 2 +- 3 files changed, 21 insertions(+), 11 deletions(-) diff --git a/pkg/processor/processor.go b/pkg/processor/processor.go index c119cb3..a96b686 100644 --- a/pkg/processor/processor.go +++ b/pkg/processor/processor.go @@ -96,7 +96,7 @@ func (r *RequestProcessor) replyWithError(obj *object.FileObject, sc int, err er } key := r.serverConfig.Placeholder + strconv.FormatUint(obj.Transforms.Hash().Sum64(), 16) - if cacheRes := r.fetchResponseFromCache(key); cacheRes != nil { + if cacheRes := r.fetchResponseFromCache(key, true); cacheRes != nil { cacheRes.StatusCode = sc return cacheRes } @@ -131,7 +131,7 @@ func (r *RequestProcessor) replyWithError(obj *object.FileObject, sc int, err er case <-timer.C: return response.NewError(sc, err) default: - if cacheRes := r.fetchResponseFromCache(key); cacheRes != nil { + if cacheRes := r.fetchResponseFromCache(key, false); cacheRes != nil { lockResult.Cancel <- true return cacheRes } @@ -197,7 +197,7 @@ func (r *RequestProcessor) collapseGET(req *http.Request, obj *object.FileObject lockResult.Cancel <- true return r.replyWithError(obj, 504, ErrTimeout) default: - if cacheRes := r.fetchResponseFromCache(obj.Key); cacheRes != nil { + if cacheRes := r.fetchResponseFromCache(obj.Key, true); cacheRes != nil { lockResult.Cancel <- true return cacheRes } @@ -206,7 +206,7 @@ func (r *RequestProcessor) collapseGET(req *http.Request, obj *object.FileObject } -func (r *RequestProcessor) fetchResponseFromCache(key string) *response.Response { +func (r *RequestProcessor) fetchResponseFromCache(key string, allowExpired bool) *response.Response { cacheValue := r.cache.Get(key) if cacheValue != nil { if cacheValue.Expired() == false { @@ -222,8 +222,15 @@ func (r *RequestProcessor) fetchResponseFromCache(key string) *response.Response monitoring.Log().Info("Handle Get cache", zap.String("cache", "expired"), zap.String("obj.Key", key)) monitoring.Report().Inc("cache_ratio;status:expired") res := cacheValue.Value().(*response.Response) - res.Close() - r.cache.Delete(key) + if allowExpired { + resCp, err := res.Copy() + if err == nil { + return resCp + } + } else { + res.Close() + r.cache.Delete(key) + } } } @@ -232,7 +239,7 @@ func (r *RequestProcessor) fetchResponseFromCache(key string) *response.Response } func (r *RequestProcessor) handleGET(req *http.Request, obj *object.FileObject) *response.Response { - if cacheRes := r.fetchResponseFromCache(obj.Key); cacheRes != nil { + if cacheRes := r.fetchResponseFromCache(obj.Key, false); cacheRes != nil { return cacheRes } @@ -269,7 +276,6 @@ func (r *RequestProcessor) handleGET(req *http.Request, obj *object.FileObject) }(parentObj) } -resLoop: for { select { case <-ctx.Done(): @@ -290,7 +296,7 @@ resLoop: } if res.StatusCode == 404 { - break resLoop + return r.handleNotFound(ctx, obj, parentObj, transformsTab, parentRes, res) } else { return res } @@ -304,6 +310,9 @@ resLoop: } } +} + +func (r *RequestProcessor) handleNotFound(ctx context.Context, obj, parentObj *object.FileObject, transformsTab []transforms.Transforms, parentRes, res *response.Response) *response.Response { if parentObj != nil { if !obj.CheckParent { parentRes = storage.Head(parentObj) diff --git a/pkg/response/response.go b/pkg/response/response.go index 27995d1..209fb31 100644 --- a/pkg/response/response.go +++ b/pkg/response/response.go @@ -235,7 +235,8 @@ func (r *Response) Send(w http.ResponseWriter) error { // SendContent use http.ServeContent to return response to client // It can handle range and condition requests func (r *Response) SendContent(req *http.Request, w http.ResponseWriter) error { - if r.bodySeeker == nil || isRangeOrCondition(req) == false { + // ServerContent will modified status code so to it we should pass only 200 response + if r.StatusCode != 200 || r.bodySeeker == nil || isRangeOrCondition(req) == false { return r.Send(w) } diff --git a/pkg/storage/storage.go b/pkg/storage/storage.go index bc30685..f944b13 100644 --- a/pkg/storage/storage.go +++ b/pkg/storage/storage.go @@ -85,7 +85,7 @@ func Head(obj *object.FileObject) *response.Response { if err != nil { if err == stow.ErrNotFound { monitoring.Logs().Infow("Storage/Head item response", zap.String("obj.Key", obj.Key), zap.String("obj.Bucket", obj.Bucket), zap.Int("sc", 404)) - return response.NewString(404, obj.Key) + return response.NewString(404, notFound) } monitoring.Logs().Infow("Storage/Head item response", zap.String("obj.Key", obj.Key), zap.String("obj.Bucket", obj.Bucket), zap.Error(err))