예제 #1
0
        public override Task ProcessRequestAsync(IRequest req, IResponse res, string operationName)
        {
            if (HostContext.ApplyCustomHandlerRequestFilters(req, res))
            {
                return(EmptyTask);
            }

            res.ApplyGlobalResponseHeaders();

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

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

            var subscriptionId = req.QueryString["id"];

            if (!req.TryResolve <IServerEvents>().Pulse(subscriptionId))
            {
                res.StatusCode        = 404;
                res.StatusDescription = "Subscription {0} does not exist".Fmt(subscriptionId);
            }
            res.EndHttpHandlerRequest(skipHeaders: true);
            return(EmptyTask);
        }
예제 #2
0
            public override void ProcessRequest(IRequest httpReq, IResponse httpRes, string operationName)
            {
                if (HostContext.ApplyCustomHandlerRequestFilters(httpReq, httpRes))
                {
                    return;
                }

                httpRes.ContentType = MimeTypes.Xml;

                var xml = new StringBuilder();

                xml.AppendLine("<?xml version=\"1.0\" encoding=\"UTF-8\"?>");

                xml.Append("<sitemapindex");
                foreach (var ns in feature.UrlSetNamespaces)
                {
                    xml.Append(" {0}=\"{1}\"".Fmt(ns.Key, ns.Value));
                }
                xml.AppendLine(">");

                if (feature.CustomXml != null)
                {
                    if (feature.CustomXml.SitemapIndexHeaderXml != null)
                    {
                        xml.AppendLine(feature.CustomXml.SitemapIndexHeaderXml);
                    }
                }

                foreach (var sitemap in feature.SitemapIndex.Safe())
                {
                    xml.AppendLine("<sitemap>");

                    if (sitemap.Location != null || sitemap.AtPath != null)
                    {
                        xml.AppendLine("  <loc>{0}</loc>".Fmt((sitemap.Location ?? sitemap.AtPath.ToAbsoluteUri()).EncodeXml()));
                    }
                    if (sitemap.LastModified != null)
                    {
                        xml.AppendLine("  <lastmod>{0}</lastmod>".Fmt(sitemap.LastModified.Value.ToString("yyyy-MM-dd")));
                    }

                    if (sitemap.CustomXml != null)
                    {
                        xml.AppendLine(sitemap.CustomXml);
                    }

                    xml.AppendLine("</sitemap>");
                }

                if (feature.CustomXml != null)
                {
                    if (feature.CustomXml.SitemapIndexFooterXml != null)
                    {
                        xml.AppendLine(feature.CustomXml.SitemapIndexFooterXml);
                    }
                }

                xml.AppendLine("</sitemapindex>");
                httpRes.EndHttpHandlerRequest(skipClose: true, afterHeaders: r => r.Write(xml.ToString()));
            }
예제 #3
0
            public override async Task ProcessRequestAsync(IRequest httpReq, IResponse httpRes, string operationName)
            {
                if (HostContext.ApplyCustomHandlerRequestFilters(httpReq, httpRes))
                {
                    return;
                }

                httpRes.ContentType = MimeTypes.Xml;

                var xml = StringBuilderCache.Allocate();

                xml.AppendLine("<?xml version=\"1.0\" encoding=\"UTF-8\"?>");

                xml.Append("<sitemapindex");
                foreach (var ns in feature.UrlSetNamespaces)
                {
                    xml.Append($" {ns.Key}=\"{ns.Value}\"");
                }
                xml.AppendLine(">");

                if (feature.CustomXml?.SitemapIndexHeaderXml != null)
                {
                    xml.AppendLine(feature.CustomXml.SitemapIndexHeaderXml);
                }

                foreach (var sitemap in feature.SitemapIndex.Safe())
                {
                    xml.AppendLine("<sitemap>");

                    if (sitemap.Location != null || sitemap.AtPath != null)
                    {
                        xml.AppendLine($"  <loc>{(sitemap.Location ?? sitemap.AtPath.ToAbsoluteUri()).EncodeXml()}</loc>");
                    }
                    if (sitemap.LastModified != null)
                    {
                        xml.AppendLine($"  <lastmod>{sitemap.LastModified.Value:yyyy-MM-dd}</lastmod>");
                    }

                    if (sitemap.CustomXml != null)
                    {
                        xml.AppendLine(sitemap.CustomXml);
                    }

                    xml.AppendLine("</sitemap>");
                }

                if (feature.CustomXml?.SitemapIndexFooterXml != null)
                {
                    xml.AppendLine(feature.CustomXml.SitemapIndexFooterXml);
                }

                xml.AppendLine("</sitemapindex>");
                var text = StringBuilderCache.Retrieve(xml);
                await httpRes.EndHttpHandlerRequestAsync(skipClose : true, afterHeaders : r => r.WriteAsync(text));
            }
예제 #4
0
        public override Task ProcessRequestAsync(IRequest req, IResponse res, string operationName)
        {
            if (HostContext.ApplyCustomHandlerRequestFilters(req, res))
            {
                return(EmptyTask);
            }

            res.ApplyGlobalResponseHeaders();

            var serverEvents = req.TryResolve <IServerEvents>();

            serverEvents.RemoveExpiredSubscriptions();

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

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

            if (req.Response.IsClosed)
            {
                return(EmptyTask);
            }

            var subscriptionId = req.QueryString["id"];
            var subscription   = serverEvents.GetSubscriptionInfo(subscriptionId);

            if (subscription == null)
            {
                res.StatusCode        = 404;
                res.StatusDescription = ErrorMessages.SubscriptionNotExistsFmt.Fmt(subscriptionId);
                res.EndHttpHandlerRequest(skipHeaders: true);
                return(EmptyTask);
            }

            if (!feature.CanAccessSubscription(req, subscription))
            {
                res.StatusCode        = 403;
                res.StatusDescription = "Invalid User Address";
                res.EndHttpHandlerRequest(skipHeaders: true);
                return(EmptyTask);
            }

            if (!serverEvents.Pulse(subscriptionId))
            {
                res.StatusCode        = 404;
                res.StatusDescription = "Subscription {0} does not exist".Fmt(subscriptionId);
            }
            res.EndHttpHandlerRequest(skipHeaders: true);
            return(EmptyTask);
        }
예제 #5
0
        public override Task ProcessRequestAsync(IRequest req, IResponse response, string operationName)
        {
            if (HostContext.ApplyCustomHandlerRequestFilters(req, response))
            {
                return(TypeConstants.EmptyTask);
            }

            var httpReq  = (IHttpRequest)req;
            var proxyUrl = ResolveUrl(httpReq);

            try
            {
                return(ProxyRequestAsync(httpReq, proxyUrl));
            }
            catch (Exception ex)
            {
                return(req.Response.WriteErrorBody(ex));
            }
        }
예제 #6
0
        public override async Task ProcessRequestAsync(IRequest httpReq, IResponse httpRes, string operationName)
        {
            if (HostContext.ApplyCustomHandlerRequestFilters(httpReq, httpRes))
            {
                return;
            }

            var svg = Svg.GetImage(Id, Fill);

            if (svg == null)
            {
                httpRes.StatusCode        = 404;
                httpRes.StatusDescription = "SVG Image was not found";
            }
            else if (Format == "svg")
            {
                httpRes.ContentType = MimeTypes.ImageSvg;
                await httpRes.WriteAsync(svg);
            }
            else if (Format == "css")
            {
                httpRes.ContentType = "text/css";
                var css = $".svg-{Id} {{\n  {Svg.InBackgroundImageCss(Svg.GetImage(Id, Fill))}\n}}\n";
                await httpRes.WriteAsync(css);
            }
            else if (Format == "datauri")
            {
                var dataUri = Svg.GetDataUri(Id, Fill);
                httpRes.ContentType = MimeTypes.PlainText;
                await httpRes.WriteAsync(dataUri);
            }
            else
            {
                httpRes.StatusCode        = 400;
                httpRes.StatusDescription = "Unknown format, valid formats: svg, css, datauri";
            }
            await httpRes.EndRequestAsync();
        }
예제 #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 ProcessRequestAsync(IRequest httpReq, IResponse httpRes, string operationName)
            {
                if (HostContext.ApplyCustomHandlerRequestFilters(httpReq, httpRes))
                {
                    return;
                }

                httpRes.ContentType = MimeTypes.Xml;

                var xml = StringBuilderCache.Allocate();

                xml.AppendLine("<?xml version=\"1.0\" encoding=\"UTF-8\"?>");

                xml.Append("<urlset");
                foreach (var ns in feature.UrlSetNamespaces)
                {
                    xml.Append(" {0}=\"{1}\"".Fmt(ns.Key, ns.Value));
                }
                xml.AppendLine(">");

                if (feature.CustomXml?.UrlSetHeaderXml != null)
                {
                    xml.AppendLine(feature.CustomXml.UrlSetHeaderXml);
                }

                foreach (var url in urlSet.Safe())
                {
                    xml.AppendLine("<url>");

                    if (url.Location != null)
                    {
                        xml.AppendLine($"  <loc>{url.Location.EncodeXml()}</loc>");
                    }
                    if (url.LastModified != null)
                    {
                        xml.AppendLine($"  <lastmod>{url.LastModified.Value:yyyy-MM-dd}</lastmod>");
                    }
                    if (url.ChangeFrequency != null)
                    {
                        xml.AppendLine($"  <changefreq>{url.ChangeFrequency.Value.ToString().ToLower()}</changefreq>");
                    }
                    if (url.Priority != null)
                    {
                        xml.AppendLine($"  <priority>{url.Priority.Value.ToString(CultureInfo.InvariantCulture)}</priority>");
                    }

                    if (url.CustomXml != null)
                    {
                        xml.AppendLine(url.CustomXml);
                    }

                    xml.AppendLine("</url>");
                }

                if (feature.CustomXml?.UrlSetFooterXml != null)
                {
                    xml.AppendLine(feature.CustomXml.UrlSetFooterXml);
                }

                xml.AppendLine("</urlset>");

                var text = StringBuilderCache.Retrieve(xml);
                await httpRes.EndHttpHandlerRequestAsync(skipClose : true, afterHeaders : r => r.WriteAsync(text));
            }