Beispiel #1
0
        public override async Task Invoke(IOwinContext context)
        {
            var    contextEnv = context.Environment;
            Stream responseStream;

            if (!contextEnv.ContainsKey(CommonOwinKeys.AdditionalInfo))
            {
                PushFunc pushPromise = null;
                var      path        = context.Request.Path.Value;
                var      base64Req   = path.Remove(0, 1); //remove leading /
                var      isHtmlReq   = Regex.Match(base64Req, Base64Regex).Success;
                var      isJpeg      = !isHtmlReq && path.EndsWith(TileExtension);
                var      url         = String.Empty;

                if (isHtmlReq)
                {
                    var bingProcessor = new BingRequestProcessor(base64Req);

                    var images = bingProcessor.GetTilesSoapRequestsUrls();

                    foreach (var image in images.Where(image => TryGetPushPromise(context, out pushPromise)))
                    {
                        Push(context.Request, pushPromise, image);
                    }

                    url = BingRequestsUrl + base64Req;
                }
                else if (isJpeg)
                {
                    url = BingRequestProcessor.GetSoapUrlFromTileName(path);
                }
                else
                {
                    url = BingServiceUrl + path;
                }

                if (isHtmlReq)
                {
                    var responseString = new WebClient().DownloadString(url); //html on original request
                    //TODO handle errors
                    HtmlProcessor.PreprocessHtml(ref responseString);

                    var response = Encoding.UTF8.GetBytes(responseString);
                    responseStream = context.Response.Body;
                    responseStream.Write(response, 0, response.Length);
                }
                else
                {
                    DownloadVia11(url, context);
                }
            }
            else
            {
                var url = context.Get <string>(CommonOwinKeys.AdditionalInfo);
                DownloadVia11(url, context);
            }

            await Next.Invoke(context);
        }
Beispiel #2
0
        protected override void Push(IOwinRequest request, PushFunc pushPromise, string pushReference)
        {
            // Copy the headers
            var headers = new HeaderDictionary(
                new Dictionary <string, string[]>(request.Headers, StringComparer.OrdinalIgnoreCase));

            // Populate special HTTP2 headers
            headers[CommonHeaders.Method] = request.Method.ToUpper(); // TODO: Not all methods are allowed for push.  Don't push, or change to GET?
            headers[CommonHeaders.Scheme] = request.Scheme;
            headers.Remove("Host");
            headers[CommonHeaders.Authority] = request.Headers["Host"];
            headers.Remove(CommonHeaders.ContentLength); // Push promises cannot emulate requests with bodies.
            // TODO: What about cache headers? If-Match, If-None-Match, If-Modified-Since, If-Unmodified-Since.
            // If-Match & If-None-Match are multi-value so the client could send e-tags for the primary resource and referenced resources.
            // If-Modified-Since and If-Unmodified-Since are single value, so it may not make sense to apply them for secondary resources.

            // Change the request path to the pushed resource
            headers[CommonHeaders.Path] = pushReference;

            pushPromise(headers);
        }
Beispiel #3
0
 public static void ReplaceDefault(PushFunc pushFunc, GetFunc getFunc)
 {
     Set = pushFunc;
     Get = getFunc;
 }
 protected abstract void Push(IOwinRequest request, PushFunc pushPromise, string pushReference);
 protected bool TryGetPushPromise(IOwinContext context, out PushFunc pushPromise)
 {
     pushPromise = context.Get <PushFunc>(CommonOwinKeys.ServerPushFunc);
     return(pushPromise != null);
 }
 protected abstract void Push(IOwinRequest request, PushFunc pushPromise, string pushReference);
 protected bool TryGetPushPromise(IOwinContext context, out PushFunc pushPromise)
 {
     pushPromise = context.Get<PushFunc>(CommonOwinKeys.ServerPushFunc);
     return pushPromise != null;
 }
        protected override void Push(IOwinRequest request, PushFunc pushPromise, string pushReference)
        {
            request.Set(CommonOwinKeys.AdditionalInfo, pushReference);
            // Copy the headers
            var headers = new HeaderDictionary(
                new Dictionary<string, string[]>(request.Headers, StringComparer.OrdinalIgnoreCase));

            // Populate special HTTP2 headers
            headers[CommonHeaders.Method] = request.Method;
                // TODO: Not all methods are allowed for push.  Don't push, or change to GET?
            headers[CommonHeaders.Scheme] = request.Scheme;
            headers.Remove("Host");
            headers[CommonHeaders.Authority] = request.Headers["Host"];
            headers[CommonHeaders.Path] = BingRequestProcessor.GetTileQuadFromSoapUrl(pushReference);
            headers.Remove(CommonHeaders.ContentLength); // Push promises cannot emulate requests with bodies.

            // TODO: What about cache headers? If-Match, If-None-Match, If-Modified-Since, If-Unmodified-Since.
            // If-Match & If-None-Match are multi-value so the client could send e-tags for the primary resource and referenced resources.
            // If-Modified-Since and If-Unmodified-Since are single value, so it may not make sense to apply them for secondary resources.

            pushPromise(headers);
        }
Beispiel #9
0
        /// <summary>
        /// Overrides request processing logic.
        /// </summary>
        /// <param name="stream">The stream.</param>
        /// <param name="frame">The request header frame.</param>
        /// <returns></returns>
        protected override void ProcessRequest(Http2Stream stream, Frame frame)
        {
            /* 12 -> 8.1.3.1
             * All HTTP/2 requests MUST include exactly one valid value for the
             * ":method", ":scheme", and ":path" header fields, unless this is a
             * CONNECT request (Section 8.3).  An HTTP request that omits mandatory
             * header fields is malformed (Section 8.1.3.5). */

            if (stream.Headers.GetValue(CommonHeaders.Method) == null ||
                stream.Headers.GetValue(CommonHeaders.Path) == null ||
                stream.Headers.GetValue(CommonHeaders.Scheme) == null)
            {
                stream.WriteRst(ResetStatusCode.ProtocolError);
                stream.Close(ResetStatusCode.ProtocolError);
                return;
            }

            Task.Factory.StartNew(async() =>
            {
                try
                {
                    var context    = new Http2OwinMessageContext(stream);
                    var contextEnv = context.OwinContext.Environment;

                    PushFunc pushDelegate = null;
                    pushDelegate          = async pairs =>
                    {
                        var promisedStream = CreateStream();
                        //assume that we have already received endStream
                        promisedStream.HalfClosedLocal = true;
                        stream.WritePushPromise(pairs, promisedStream.Id);

                        var headers = new HeadersList(pairs);
                        promisedStream.Headers.AddRange(headers);

                        var http2MsgCtx  = new Http2OwinMessageContext(promisedStream);
                        var http2PushCtx = http2MsgCtx.OwinContext;

                        http2PushCtx.Set(CommonOwinKeys.ServerPushFunc, pushDelegate);

                        //pass add info from parent to child context. This info can store
                        //reference table for example or something els that should be passed from
                        //client request into child push requests.
                        if (contextEnv.ContainsKey(CommonOwinKeys.AdditionalInfo))
                        {
                            http2PushCtx.Set(CommonOwinKeys.AdditionalInfo, contextEnv[CommonOwinKeys.AdditionalInfo]);
                        }

                        await _next(http2PushCtx);

                        http2MsgCtx.FinishResponse();
                    };

                    context.OwinContext.Set(CommonOwinKeys.ServerPushFunc, pushDelegate);
                    context.OwinContext.Set(CommonOwinKeys.EnableServerPush, _isPushEnabled);

                    await _next(context.OwinContext);
                    context.FinishResponse();
                }
                catch (Exception ex)
                {
                    EndResponse(stream, ex);
                }
            });
        }