コード例 #1
0
        public static bool HasValidCache(this ICacheClient cache, IRequest req, string cacheKey, DateTime?checkLastModified, out DateTime?lastModified)
        {
            lastModified = null;

            if (!HostContext.GetPlugin <HttpCacheFeature>().ShouldAddLastModifiedToOptimizedResults())
            {
                return(false);
            }

            var ticks = cache.Get <long>(DateCacheKey(cacheKey));

            if (ticks > 0)
            {
                lastModified = new DateTime(ticks, DateTimeKind.Utc);
                if (checkLastModified == null)
                {
                    return(false);
                }

                return(checkLastModified.Value <= lastModified.Value);
            }

            return(false);
        }
コード例 #2
0
ファイル: PostmanFeature.cs プロジェクト: atzhangzt/Startest
        public List <PostmanRequest> GetRequests(Postman request, string parentId, IEnumerable <Operation> operations)
        {
            var ret     = new List <PostmanRequest>();
            var feature = HostContext.GetPlugin <PostmanFeature>();

            var headers = feature.Headers ?? ("Accept: " + MimeTypes.Json);

            var httpRes = Response as IHttpResponse;

            if (httpRes != null)
            {
                if (request.ssopt != null ||
                    request.sspid != null ||
                    request.ssid != null)
                {
                    if (feature.EnableSessionExport != true)
                    {
                        throw new ArgumentException("PostmanFeature.EnableSessionExport is not enabled");
                    }
                }

                if (request.ssopt != null)
                {
                    Request.AddSessionOptions(request.ssopt);
                }
                if (request.sspid != null)
                {
                    httpRes.Cookies.AddPermanentCookie(SessionFeature.PermanentSessionId, request.sspid);
                }
                if (request.ssid != null)
                {
                    httpRes.Cookies.AddSessionCookie(SessionFeature.SessionId, request.ssid,
                                                     (HostContext.Config.OnlySendSessionCookiesSecurely && Request.IsSecureConnection));
                }
            }

            foreach (var op in operations)
            {
                if (!HostContext.Metadata.IsVisible(base.Request, op))
                {
                    continue;
                }

                var allVerbs = op.Actions.Concat(
                    op.Routes.SelectMany(x => x.Verbs))
                               .SelectMany(x => x == ActionContext.AnyAction
                        ? feature.DefaultVerbsForAny
                        : new List <string> {
                    x
                })
                               .ToHashSet();

                var propertyTypes = new Dictionary <string, string>(StringComparer.OrdinalIgnoreCase);
                op.RequestType.GetSerializableFields()
                .Each(x => propertyTypes[x.Name] = x.FieldType.AsFriendlyName(feature));
                op.RequestType.GetSerializableProperties()
                .Each(x => propertyTypes[x.Name] = x.PropertyType.AsFriendlyName(feature));

                foreach (var route in op.Routes)
                {
                    var routeVerbs = route.Verbs.Contains(ActionContext.AnyAction)
                        ? feature.DefaultVerbsForAny.ToArray()
                        : route.Verbs;

                    var restRoute = route.ToRestRoute();

                    foreach (var verb in routeVerbs)
                    {
                        allVerbs.Remove(verb); //exclude handled verbs

                        var routeData = restRoute.QueryStringVariables
                                        .Map(x => new PostmanData
                        {
                            key   = x,
                            value = "",
                            type  = "text",
                        })
                                        .ApplyPropertyTypes(propertyTypes);

                        ret.Add(new PostmanRequest
                        {
                            collectionId  = parentId,
                            id            = SessionExtensions.CreateRandomSessionId(),
                            method        = verb,
                            url           = Request.GetBaseUrl().CombineWith(restRoute.Path.ToPostmanPathVariables()),
                            name          = GetName(feature, request, op.RequestType, restRoute.Path),
                            description   = op.RequestType.GetDescription(),
                            pathVariables = !verb.HasRequestBody()
                                ? restRoute.Variables.Concat(routeData.Select(x => x.key))
                                            .ApplyPropertyTypes(propertyTypes)
                                : null,
                            data = verb.HasRequestBody()
                                ? routeData
                                : null,
                            dataMode = "params",
                            headers  = headers,
                            version  = 2,
                            time     = DateTime.UtcNow.ToUnixTimeMs(),
                        });
                    }
                }

                var emptyRequest = op.RequestType.CreateInstance();
                var virtualPath  = emptyRequest.ToReplyUrlOnly();

                var requestParams = propertyTypes
                                    .Map(x => new PostmanData
                {
                    key   = x.Key,
                    value = x.Value,
                    type  = "text",
                });

                ret.AddRange(allVerbs.Select(verb =>
                                             new PostmanRequest
                {
                    collectionId  = parentId,
                    id            = SessionExtensions.CreateRandomSessionId(),
                    method        = verb,
                    url           = Request.GetBaseUrl().CombineWith(virtualPath),
                    pathVariables = !verb.HasRequestBody()
                            ? requestParams.Select(x => x.key)
                                    .ApplyPropertyTypes(propertyTypes)
                            : null,
                    name        = GetName(feature, request, op.RequestType, virtualPath),
                    description = op.RequestType.GetDescription(),
                    data        = verb.HasRequestBody()
                            ? requestParams
                            : null,
                    dataMode = "params",
                    headers  = headers,
                    version  = 2,
                    time     = DateTime.UtcNow.ToUnixTimeMs(),
                }));
            }

            return(ret);
        }
コード例 #3
0
        public object Any(AutoQueryMetadata request)
        {
            if (NativeTypesMetadata == null)
            {
                throw new NotSupportedException("AutoQueryViewer requries NativeTypesFeature");
            }

            var feature = HostContext.GetPlugin <AutoQueryMetadataFeature>();
            var config  = feature.AutoQueryViewerConfig;

            if (config == null)
            {
                throw new NotSupportedException("AutoQueryViewerConfig is missing");
            }

            if (config.ServiceBaseUrl == null)
            {
                config.ServiceBaseUrl = base.Request.GetBaseUrl();
            }

            if (config.ServiceName == null)
            {
                config.ServiceName = HostContext.AppHost.ServiceName;
            }

            var userSession = Request.GetSession();

            var typesConfig = NativeTypesMetadata.GetConfig(new TypesMetadata {
                BaseUrl = Request.GetBaseUrl()
            });

            foreach (var type in feature.ExportTypes)
            {
                typesConfig.ExportTypes.Add(type);
            }

            var metadataTypes = NativeTypesMetadata.GetMetadataTypes(Request, typesConfig,
                                                                     op => HostContext.Metadata.IsAuthorized(op, Request, userSession));

            var response = new AutoQueryMetadataResponse {
                Config   = config,
                UserInfo = new AutoQueryViewerUserInfo {
                    IsAuthenticated = userSession.IsAuthenticated,
                },
                Operations = new List <AutoQueryOperation>(),
                Types      = new List <MetadataType>(),
            };

            var includeTypeNames = new HashSet <string>();

            foreach (var op in metadataTypes.Operations)
            {
                if (op.Request.Inherits != null &&
                    (op.Request.Inherits.Name.StartsWith("QueryDb`") ||
                     op.Request.Inherits.Name.StartsWith("QueryData`"))
                    )
                {
                    if (config.OnlyShowAnnotatedServices)
                    {
                        var serviceAttrs = op.Request.Attributes.Safe();
                        var attr         = serviceAttrs.FirstOrDefault(x => x.Name + "Attribute" == nameof(AutoQueryViewerAttribute));
                        if (attr == null)
                        {
                            continue;
                        }
                    }

                    var inheritArgs = op.Request.Inherits.GenericArgs.Safe().ToArray();
                    response.Operations.Add(new AutoQueryOperation {
                        Request = op.Request.Name,
                        From    = inheritArgs.First(),
                        To      = inheritArgs.Last(),
                    });

                    response.Types.Add(op.Request);
                    op.Request.GetReferencedTypeNames().Each(x => includeTypeNames.Add(x));
                }
            }

            var allTypes = metadataTypes.GetAllTypes();
            var types    = allTypes.Where(x => includeTypeNames.Contains(x.Name)).ToList();

            //Add referenced types to type name search
            types.SelectMany(x => x.GetReferencedTypeNames()).Each(x => includeTypeNames.Add(x));

            //Only need to seek 1-level deep in AutoQuery's (db.LoadSelect)
            types = allTypes.Where(x => includeTypeNames.Contains(x.Name)).ToList();

            response.Types.AddRange(types);

            response.UserInfo.QueryCount = response.Operations.Count;

            feature.MetadataFilter?.Invoke(response);

            return(response);
        }
コード例 #4
0
 public T GetPlugin <T>() where T : class, IPlugin => GetResolver()?.TryResolve <T>() ?? HostContext.GetPlugin <T>();
コード例 #5
0
        public object Any(AutoQueryMetadata request)
        {
            if (NativeTypesMetadata == null)
                throw new NotSupportedException("AutoQueryViewer requries NativeTypesFeature");

            var feature = HostContext.GetPlugin<AutoQueryFeature>();
            var config = feature.AutoQueryViewerConfig;

            if (config == null)
                throw new NotSupportedException("AutoQueryViewerConfig is missing");

            if (config.ServiceBaseUrl == null)
                config.ServiceBaseUrl = base.Request.ResolveBaseUrl();

            if (config.ServiceName == null)
                config.ServiceName = HostContext.ServiceName;

            var typesConfig = NativeTypesMetadata.GetConfig(new TypesMetadata { BaseUrl = Request.GetBaseUrl() });
            var metadataTypes = NativeTypesMetadata.GetMetadataTypes(Request, typesConfig);

            var response = new AutoQueryMetadataResponse {
                Config = feature.AutoQueryViewerConfig,
                Operations = new List<AutoQueryOperation>(),
                Types = new List<MetadataType>(),
            };

            var includeTypeNames = new HashSet<string>();

            foreach (var op in metadataTypes.Operations)
            {
                if (op.Request.Inherits != null && op.Request.Inherits.Name.StartsWith("QueryBase`"))
                {
                    if (config.OnlyShowAnnotatedServices)
                    {
                        var serviceAttrs = op.Request.Attributes.Safe();
                        var attr = serviceAttrs.FirstOrDefault(x => x.Name + "Attribute" == typeof(AutoQueryViewerAttribute).Name);
                        if (attr == null)
                            continue;
                    }

                    var inheritArgs = op.Request.Inherits.GenericArgs.Safe().ToArray();
                    response.Operations.Add(new AutoQueryOperation {
                        Request = op.Request.Name,
                        From = inheritArgs.First(),
                        To = inheritArgs.Last(),
                    });

                    response.Types.Add(op.Request);
                    op.Request.GetReferencedTypeNames().Each(x => includeTypeNames.Add(x));
                }
            }

            var types = metadataTypes.Types.Where(x => includeTypeNames.Contains(x.Name));

            //Add referenced types to type name search
            types.SelectMany(x => x.GetReferencedTypeNames()).Each(x => includeTypeNames.Add(x));

            //Only need to seek 1-level deep in AutoQuery's (db.LoadSelect)
            types = metadataTypes.Types.Where(x => includeTypeNames.Contains(x.Name));

            response.Types.AddRange(types);

            return response;
        }
コード例 #6
0
        public override Task ProcessRequestAsync(IRequest req, IResponse res, string operationName)
        {
            var feature = HostContext.GetPlugin <ServerEventsFeature>();

            res.ContentType = MimeTypes.ServerSentEvents;
            res.AddHeader(HttpHeaders.CacheControl, "no-cache");
            res.UseBufferedStream = false;
            res.KeepAlive         = true;

            if (feature.OnInit != null)
            {
                feature.OnInit(req);
            }

            res.Flush();

            var serverEvents = req.TryResolve <IServerEvents>();
            var session      = req.GetSession();
            var userAuthId   = session != null ? session.UserAuthId : null;
            var anonUserId   = serverEvents.GetNextSequence("anonUser");
            var userId       = userAuthId ?? ("-" + anonUserId);
            var displayName  = session.GetSafeDisplayName()
                               ?? "user" + anonUserId;

            var now            = DateTime.UtcNow;
            var subscriptionId = SessionExtensions.CreateRandomSessionId();
            var subscription   = new EventSubscription(res)
            {
                CreatedAt       = now,
                LastPulseAt     = now,
                Channel         = req.QueryString["channel"] ?? EventSubscription.UnknownChannel,
                SubscriptionId  = subscriptionId,
                UserId          = userId,
                UserName        = session != null ? session.UserName : null,
                DisplayName     = displayName,
                SessionId       = req.GetPermanentSessionId(),
                IsAuthenticated = session != null && session.IsAuthenticated,
                OnPublish       = feature.OnPublish,
                Meta            =
                {
                    { "userId",                           userId                                                                 },
                    { "displayName",                      displayName                                                            },
                    { AuthMetadataProvider.ProfileUrlKey, session.GetProfileUrl() ?? AuthMetadataProvider.DefaultNoProfileImgUrl },
                }
            };

            if (feature.OnCreated != null)
            {
                feature.OnCreated(subscription, req);
            }

            var heartbeatUrl = req.ResolveAbsoluteUrl("~/".CombineWith(feature.HeartbeatPath))
                               .AddQueryParam("id", subscriptionId);
            var unRegisterUrl = req.ResolveAbsoluteUrl("~/".CombineWith(feature.UnRegisterPath))
                                .AddQueryParam("id", subscriptionId);
            var privateArgs = new Dictionary <string, string>(subscription.Meta)
            {
                { "id", subscriptionId },
                { "unRegisterUrl", unRegisterUrl },
                { "heartbeatUrl", heartbeatUrl },
                { "heartbeatIntervalMs", ((long)feature.HeartbeatInterval.TotalMilliseconds).ToString(CultureInfo.InvariantCulture) }
            };

            if (feature.OnConnect != null)
            {
                feature.OnConnect(subscription, privateArgs);
            }

            serverEvents.Register(subscription, privateArgs);

            var tcs = new TaskCompletionSource <bool>();

            subscription.OnDispose = _ =>
            {
                try
                {
                    res.EndHttpHandlerRequest(skipHeaders: true);
                }
                catch { }
                tcs.SetResult(true);
            };

            return(tcs.Task);
        }
コード例 #7
0
        public override Task ProcessRequestAsync(IRequest req, IResponse res, string operationName)
        {
            if (HostContext.ApplyCustomHandlerRequestFilters(req, res))
            {
                return(EmptyTask);
            }

            var feature = HostContext.GetPlugin <ServerEventsFeature>();

            var session = req.GetSession();

            if (feature.LimitToAuthenticatedUsers && !session.IsAuthenticated)
            {
                session.ReturnFailedAuthentication(req);
                return(EmptyTask);
            }

            res.ContentType = MimeTypes.ServerSentEvents;
            res.AddHeader(HttpHeaders.CacheControl, "no-cache");
            res.ApplyGlobalResponseHeaders();
            res.UseBufferedStream = false;
            res.KeepAlive         = true;

            if (feature.OnInit != null)
            {
                feature.OnInit(req);
            }

            res.Flush();

            var serverEvents = req.TryResolve <IServerEvents>();
            var userAuthId   = session != null ? session.UserAuthId : null;
            var anonUserId   = serverEvents.GetNextSequence("anonUser");
            var userId       = userAuthId ?? ("-" + anonUserId);
            var displayName  = session.GetSafeDisplayName()
                               ?? "user" + anonUserId;

            var now            = DateTime.UtcNow;
            var subscriptionId = SessionExtensions.CreateRandomSessionId();

            //Handle both ?channel=A,B,C or ?channels=A,B,C
            var channels = new List <string>();
            var channel  = req.QueryString["channel"];

            if (!string.IsNullOrEmpty(channel))
            {
                channels.AddRange(channel.Split(','));
            }
            channel = req.QueryString["channels"];
            if (!string.IsNullOrEmpty(channel))
            {
                channels.AddRange(channel.Split(','));
            }

            if (channels.Count == 0)
            {
                channels = EventSubscription.UnknownChannel.ToList();
            }

            var subscription = new EventSubscription(res)
            {
                CreatedAt       = now,
                LastPulseAt     = now,
                Channels        = channels.ToArray(),
                SubscriptionId  = subscriptionId,
                UserId          = userId,
                UserName        = session != null ? session.UserName : null,
                DisplayName     = displayName,
                SessionId       = req.GetPermanentSessionId(),
                IsAuthenticated = session != null && session.IsAuthenticated,
                UserAddress     = req.UserHostAddress,
                OnPublish       = feature.OnPublish,
                Meta            =
                {
                    { "userId",                           userId                                                                 },
                    { "displayName",                      displayName                                                            },
                    { "channels",                         string.Join(",", channels)                                             },
                    { AuthMetadataProvider.ProfileUrlKey, session.GetProfileUrl() ?? AuthMetadataProvider.DefaultNoProfileImgUrl },
                }
            };

            if (feature.OnCreated != null)
            {
                feature.OnCreated(subscription, req);
            }

            if (req.Response.IsClosed)
            {
                return(EmptyTask); //Allow short-circuiting in OnCreated callback
            }
            var heartbeatUrl = req.ResolveAbsoluteUrl("~/".CombineWith(feature.HeartbeatPath))
                               .AddQueryParam("id", subscriptionId);
            var unRegisterUrl = req.ResolveAbsoluteUrl("~/".CombineWith(feature.UnRegisterPath))
                                .AddQueryParam("id", subscriptionId);

            subscription.ConnectArgs = new Dictionary <string, string>(subscription.Meta)
            {
                { "id", subscriptionId },
                { "unRegisterUrl", unRegisterUrl },
                { "heartbeatUrl", heartbeatUrl },
                { "heartbeatIntervalMs", ((long)feature.HeartbeatInterval.TotalMilliseconds).ToString(CultureInfo.InvariantCulture) },
                { "idleTimeoutMs", ((long)feature.IdleTimeout.TotalMilliseconds).ToString(CultureInfo.InvariantCulture) }
            };

            if (feature.OnConnect != null)
            {
                feature.OnConnect(subscription, subscription.ConnectArgs);
            }

            serverEvents.Register(subscription, subscription.ConnectArgs);

            var tcs = new TaskCompletionSource <bool>();

            subscription.OnDispose = _ =>
            {
                try
                {
                    res.EndHttpHandlerRequest(skipHeaders: true);
                }
                catch { }
                tcs.SetResult(true);
            };

            return(tcs.Task);
        }
コード例 #8
0
        public override async Task ExecuteAsync(IRequest req, IResponse res, object requestDto)
        {
            if (req.Verb != HttpMethods.Get && req.Verb != HttpMethods.Head)
                return;
            if (req.IsInProcessRequest())
                return;

            var feature = HostContext.GetPlugin<HttpCacheFeature>();
            if (feature == null)
                throw new NotSupportedException(ErrorMessages.CacheFeatureMustBeEnabled.LocalizeFmt(req, "[CacheResponse]"));
            if (feature.DisableCaching)
                return;

            var keyBase = "res:" + req.RawUrl;
            var keySuffix = MimeTypes.GetExtension(req.ResponseContentType);

            var modifiers = "";
            if (req.ResponseContentType == MimeTypes.Json)
            {
                string jsonp = req.GetJsonpCallback();
                if (jsonp != null)
                    modifiers = "jsonp:" + jsonp.SafeVarName();
            }

            if (VaryByUser)
                modifiers += (modifiers.Length > 0 ? "+" : "") + "user:"******"+" : "") + "role:" + role;
                        }
                    }
                }
            }

            if (VaryByHeaders != null && VaryByHeaders.Length > 0)
            {
                foreach (var header in VaryByHeaders)
                {
                    var value = req.GetHeader(header);
                    if (!string.IsNullOrEmpty(value))
                    {
                        modifiers += (modifiers.Length > 0 ? "+" : "") + $"{header}:{value}";
                    }
                }
            }

            if (modifiers.Length > 0)
                keySuffix += "+" + modifiers;

            var cacheInfo = new CacheInfo
            {
                KeyBase = keyBase,
                KeyModifiers = keySuffix,
                ExpiresIn = Duration > 0 ? TimeSpan.FromSeconds(Duration) : (TimeSpan?)null,
                MaxAge = MaxAge >= 0 ? TimeSpan.FromSeconds(MaxAge) : (TimeSpan?)null,
                CacheControl = CacheControl,
                VaryByUser = VaryByUser,
                LocalCache = LocalCache,
                NoCompression = NoCompression,
            };

            if (await req.HandleValidCache(cacheInfo).ConfigAwait())
                return;

            req.Items[Keywords.CacheInfo] = cacheInfo;
        }
コード例 #9
0
        public static async Task<bool> HandleValidCache(this IRequest req, CacheInfo cacheInfo, CancellationToken token=default)
        {
            if (cacheInfo == null)
                return false;

            ICacheClient cache;
            ICacheClientAsync cacheAsync = null; // only non-null if native ICacheClientAsync exists
            if (cacheInfo.LocalCache)
                cache = HostContext.AppHost.GetMemoryCacheClient(req);
            else
                HostContext.AppHost.TryGetNativeCacheClient(req, out cache, out cacheAsync);

            var cacheControl = HostContext.GetPlugin<HttpCacheFeature>().BuildCacheControlHeader(cacheInfo);

            var res = req.Response;
            DateTime? lastModified = null;

            var doHttpCaching = cacheInfo.MaxAge != null || cacheInfo.CacheControl != CacheControl.None;
            if (doHttpCaching)
            {
                lastModified = cacheAsync != null 
                    ? await cacheAsync.GetAsync<DateTime?>(cacheInfo.LastModifiedKey(), token).ConfigAwait()
                    : cache.Get<DateTime?>(cacheInfo.LastModifiedKey());
                if (req.HasValidCache(lastModified))
                {
                    if (cacheControl != null)
                        res.AddHeader(HttpHeaders.CacheControl, cacheControl);

                    res.EndNotModified();
                    return true;
                }
            }

            var encoding = !cacheInfo.NoCompression 
                ? req.GetCompressionType()
                : null;

            var useCacheKey = encoding != null
                ? cacheInfo.CacheKey + "." + encoding
                : cacheInfo.CacheKey;
            
            var responseBytes = cacheAsync != null
                ? await cacheAsync.GetAsync<byte[]>(useCacheKey, token).ConfigAwait()
                : cache.Get<byte[]>(useCacheKey);

            if (responseBytes != null)
            {
                if (encoding != null)
                    res.AddHeader(HttpHeaders.ContentEncoding, encoding);
                if (cacheInfo.VaryByUser)
                    res.AddHeader(HttpHeaders.Vary, "Cookie");

                if (cacheControl != null)
                    res.AddHeader(HttpHeaders.CacheControl, cacheControl);

                if (!doHttpCaching)
                {
                    lastModified = cacheAsync != null ?
                        await cacheAsync.GetAsync<DateTime?>(cacheInfo.LastModifiedKey(), token).ConfigAwait() :
                        cache.Get<DateTime?>(cacheInfo.LastModifiedKey());
                }

                if (lastModified != null)
                    res.AddHeader(HttpHeaders.LastModified, lastModified.Value.ToUniversalTime().ToString("r"));

                await res.WriteBytesToResponse(responseBytes, req.ResponseContentType, token).ConfigAwait();
                return true;
            }

            return false;
        }
コード例 #10
0
 public EventSubscription(IResponse response)
 {
     this.response   = response;
     this.Meta       = new Dictionary <string, string>();
     this.WriteEvent = HostContext.GetPlugin <ServerEventsFeature>().WriteEvent;
 }
コード例 #11
0
        public static object Cache(this ICacheClient cacheClient,
                                   string cacheKey,
                                   object responseDto,
                                   IRequest request,
                                   TimeSpan?expireCacheIn = null)
        {
            request.Response.Dto = responseDto;
            cacheClient.Set(cacheKey, responseDto, expireCacheIn);

            if (!request.ResponseContentType.IsBinary())
            {
                string serializedDto = SerializeToString(request, responseDto);

                string modifiers = null;
                if (request.ResponseContentType.MatchesContentType(MimeTypes.Json))
                {
                    var jsonp = request.GetJsonpCallback();
                    if (jsonp != null)
                    {
                        modifiers     = ".jsonp," + jsonp.SafeVarName();
                        serializedDto = jsonp + "(" + serializedDto + ")";

                        //Add a default expire timespan for jsonp requests,
                        //because they aren't cleared when calling ClearCaches()
                        if (expireCacheIn == null)
                        {
                            expireCacheIn = HostContext.Config.DefaultJsonpCacheExpiration;
                        }
                    }
                }

                var cacheKeySerialized = GetCacheKeyForSerialized(cacheKey, request.ResponseContentType, modifiers);
                cacheClient.Set(cacheKeySerialized, serializedDto, expireCacheIn);

                var  compressionType = request.GetCompressionType();
                bool doCompression   = compressionType != null;
                if (doCompression)
                {
                    var lastModified = HostContext.GetPlugin <HttpCacheFeature>().ShouldAddLastModifiedToOptimizedResults() &&
                                       request.Response.GetHeader(HttpHeaders.CacheControl) == null
                        ? DateTime.UtcNow
                        : (DateTime?)null;

                    var cacheKeySerializedZip = GetCacheKeyForCompressed(cacheKeySerialized, compressionType);

                    byte[] compressedSerializedDto = serializedDto.Compress(compressionType);
                    cacheClient.Set(cacheKeySerializedZip, compressedSerializedDto, expireCacheIn);

                    if (lastModified != null)
                    {
                        cacheClient.Set(DateCacheKey(cacheKeySerializedZip), lastModified.Value.Ticks, expireCacheIn);
                    }

                    return(compressedSerializedDto != null
                        ? new CompressedResult(compressedSerializedDto, compressionType, request.ResponseContentType)
                    {
                        Status = request.Response.StatusCode,
                        LastModified = lastModified,
                    }
                        : null);
                }

                return(serializedDto);
            }
            else
            {
                string modifiers          = null;
                byte[] serializedDto      = HostContext.ContentTypes.SerializeToBytes(request, responseDto);
                var    cacheKeySerialized = GetCacheKeyForSerialized(cacheKey, request.ResponseContentType, modifiers);
                cacheClient.Set(cacheKeySerialized, serializedDto, expireCacheIn);
                return(serializedDto);
            }
        }
コード例 #12
0
        public override void Execute(IRequest req, IResponse res, object requestDto)
        {
            if (req.Verb != HttpMethods.Get && req.Verb != HttpMethods.Head)
            {
                return;
            }

            var feature = HostContext.GetPlugin <HttpCacheFeature>();

            if (feature == null)
            {
                throw new NotSupportedException(ErrorMessages.CacheFeatureMustBeEnabled.Fmt("[CacheResponse]"));
            }

            var keyBase   = "res:" + req.RawUrl;
            var keySuffix = MimeTypes.GetExtension(req.ResponseContentType);

            var modifiers = "";

            if (req.ResponseContentType == MimeTypes.Json)
            {
                string jsonp = req.GetJsonpCallback();
                if (jsonp != null)
                {
                    modifiers = "jsonp:" + jsonp.SafeVarName();
                }
            }

            if (VaryByUser)
            {
                modifiers += (modifiers.Length > 0 ? "+" : "") + "user:"******"+" : "") + "role:" + role;
                        }
                    }
                }
            }

            if (modifiers.Length > 0)
            {
                keySuffix += "+" + modifiers;
            }

            var cacheInfo = new CacheInfo
            {
                KeyBase      = keyBase,
                KeyModifiers = keySuffix,
                ExpiresIn    = Duration > 0 ? TimeSpan.FromSeconds(Duration) : (TimeSpan?)null,
                MaxAge       = MaxAge >= 0 ? TimeSpan.FromSeconds(MaxAge) : (TimeSpan?)null,
                CacheControl = CacheControl,
                VaryByUser   = VaryByUser,
                LocalCache   = LocalCache,
            };

            if (req.HandleValidCache(cacheInfo))
            {
                return;
            }

            req.Items[Keywords.CacheInfo] = cacheInfo;
        }
コード例 #13
0
        public static bool HandleValidCache(this IRequest req, CacheInfo cacheInfo)
        {
            if (cacheInfo == null)
            {
                return(false);
            }

            var res   = req.Response;
            var cache = cacheInfo.LocalCache ? HostContext.LocalCache : HostContext.Cache;

            DateTime?lastModified = null;

            var doHttpCaching = cacheInfo.MaxAge != null || cacheInfo.CacheControl != CacheControl.None;

            if (doHttpCaching)
            {
                lastModified = cache.Get <DateTime?>(cacheInfo.LastModifiedKey());
                if (req.HasValidCache(lastModified))
                {
                    res.EndNotModified();
                    return(true);
                }
            }

            var encoding = req.GetCompressionType();

            var responseBytes = encoding != null
                ? cache.Get <byte[]>(cacheInfo.CacheKey + "." + encoding)
                : cache.Get <byte[]>(cacheInfo.CacheKey);

            if (responseBytes != null)
            {
                if (encoding != null)
                {
                    res.AddHeader(HttpHeaders.ContentEncoding, encoding);
                }
                if (cacheInfo.VaryByUser)
                {
                    res.AddHeader(HttpHeaders.Vary, "Cookie");
                }

                var cacheControl = HostContext.GetPlugin <HttpCacheFeature>().BuildCacheControlHeader(cacheInfo);
                if (cacheControl != null)
                {
                    res.AddHeader(HttpHeaders.CacheControl, cacheControl);
                }

                if (!doHttpCaching)
                {
                    lastModified = cache.Get <DateTime?>(cacheInfo.LastModifiedKey());
                }

                if (lastModified != null)
                {
                    res.AddHeader(HttpHeaders.LastModified, lastModified.Value.ToUniversalTime().ToString("r"));
                }

                res.WriteBytesToResponse(responseBytes, req.ResponseContentType);
                return(true);
            }

            return(false);
        }