/// <summary> /// Inspect if request if http2 upgrade /// If so starts http2 session via provider. /// Calls next layer if not. /// </summary> /// <param name="environment">The environment.</param> /// <returns></returns> public async Task Invoke(IDictionary<string, object> environment) { var context = new OwinContext(environment); if (IsOpaqueUpgradePossible(context.Request) && IsRequestForHttp2Upgrade(context.Request)) { var upgradeDelegate = environment[CommonOwinKeys.OpaqueUpgrade] as UpgradeDelegate; Debug.Assert(upgradeDelegate != null, "upgradeDelegate is not null"); var trInfo = CreateTransportInfo(context.Request); // save original request parameters; used to complete request after upaque upgrade is done var requestCopy = GetInitialRequestParams(context.Request); upgradeDelegate.Invoke(new Dictionary<string, object>(), async opaque => { //use the same stream which was used during upgrade var opaqueStream = opaque[CommonOwinKeys.OpaqueStream] as DuplexStream; //TODO Provide cancellation token here // Move to method try { using (var http2MessageHandler = new Http2OwinMessageHandler(opaqueStream, ConnectionEnd.Server, trInfo, _next, CancellationToken.None) ) { await http2MessageHandler.StartSessionAsync(requestCopy); GC.Collect(); } } catch (Exception ex) { Http2Logger.LogError(ex.Message); } }); // specify Upgrade protocol context.Response.Headers.Add(CommonHeaders.Upgrade, new[] { Protocols.Http2 }); return; } //If we dont have upgrade delegate then pass request to the next layer await _next(environment); }
private async void OpenHttp2Session(DuplexStream incomingClientStream, TransportInformation transportInformation) { Http2Logger.LogDebug("Handshake successful"); using (var messageHandler = new Http2OwinMessageHandler(incomingClientStream, ConnectionEnd.Server, transportInformation, _next, _cancelClientHandling.Token)) { try { await messageHandler.StartSessionAsync(); } catch (Exception) { Http2Logger.LogError("Client was disconnected"); } } GC.Collect(); }