/// <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); } }); }