static bool IsUpgradeRequest(IHttpObject msg) { if (!(msg is IHttpRequest request)) { return(false); } return(request.Headers.Contains(HttpHeaderNames.Upgrade)); }
public async Task ProcessRequest(HtcHttpContext httpContext) { object[] parameterData; if (RequireObject) { var exceptionList = new List <Exception>(); IHttpObject parsedHttpObject = null; foreach (var parser in _parsers) { try { parsedHttpObject = await parser.Parse(httpContext, _parameterType); } catch (Exception ex) { exceptionList.Add(ex); } if (parsedHttpObject == null) { continue; } } if (parsedHttpObject == null) { throw new HttpDecodeDataException(exceptionList.ToArray()); } if (!await parsedHttpObject.ValidateData(httpContext)) { throw new HttpDataValidationException(); } parameterData = new object[] { httpContext, parsedHttpObject }; } else { parameterData = new object[] { httpContext }; } var invokeReturn = _methodInfo.Invoke(_instance, parameterData); if (invokeReturn is Task <object> taskReturn) { var data = await taskReturn; try { await JsonSerializer.SerializeAsync(httpContext.Response.Body, data); } catch (Exception ex) { throw new HttpEncodeDataException(ex); } } else if (invokeReturn is Task task) { await task; } else { throw new HttpNullTaskException(); } }
protected override bool IsStartMessage(IHttpObject msg) { if (msg is IHttpRequest request) { HttpMethod method = request.Method; if (method.Equals(HttpMethod.Post)) { return(true); } } return(false); }
protected override bool IsStartMessage(IHttpObject msg) { if (msg is IHttpResponse response) { HttpHeaders headers = response.Headers; var contentType = headers.Get(HttpHeaderNames.ContentType, null); if (AsciiString.ContentEqualsIgnoreCase(contentType, HttpHeaderValues.TextPlain)) { return(true); } } return(false); }
protected internal override void Decode(IChannelHandlerContext context, IHttpObject message, List <object> output) { // Determine if we're already handling an upgrade request or just starting a new one. this.handlingUpgrade |= IsUpgradeRequest(message); if (!this.handlingUpgrade) { // Not handling an upgrade request, just pass it to the next handler. ReferenceCountUtil.Retain(message); output.Add(message); return; } if (message is IFullHttpRequest fullRequest) { ReferenceCountUtil.Retain(fullRequest); output.Add(fullRequest); } else { // Call the base class to handle the aggregation of the full request. base.Decode(context, message, output); if (output.Count == 0) { // The full request hasn't been created yet, still awaiting more data. return; } // Finished aggregating the full request, get it from the output list. Debug.Assert(output.Count == 1); this.handlingUpgrade = false; fullRequest = (IFullHttpRequest)output[0]; } if (this.Upgrade(context, fullRequest)) { // The upgrade was successful, remove the message from the output list // so that it's not propagated to the next handler. This request will // be propagated as a user event instead. output.Clear(); } // The upgrade did not succeed, just allow the full request to propagate to the // next handler. }
/// <summary> /// Determines whether or not the message is an HTTP upgrade request. /// </summary> /// <param name="msg"></param> /// <returns></returns> static bool IsUpgradeRequest(IHttpObject msg) { return(msg is IHttpRequest request && request.Headers.Contains(HttpHeaderNames.Upgrade)); }
protected internal override void Decode(IChannelHandlerContext context, IHttpObject message, List <object> output) { IFullHttpResponse response = null; try { if (!this.upgradeRequested) { throw new InvalidOperationException("Read HTTP response without requesting protocol switch"); } if (message is IHttpResponse rep) { if (!HttpResponseStatus.SwitchingProtocols.Equals(rep.Status)) { // The server does not support the requested protocol, just remove this handler // and continue processing HTTP. // NOTE: not releasing the response since we're letting it propagate to the // next handler. context.FireUserEventTriggered(UpgradeEvent.UpgradeRejected); RemoveThisHandler(context); context.FireChannelRead(rep); return; } } if (message is IFullHttpResponse fullRep) { response = fullRep; // Need to retain since the base class will release after returning from this method. response.Retain(); output.Add(response); } else { // Call the base class to handle the aggregation of the full request. base.Decode(context, message, output); if (output.Count == 0) { // The full request hasn't been created yet, still awaiting more data. return; } Debug.Assert(output.Count == 1); response = (IFullHttpResponse)output[0]; } if (response.Headers.TryGet(HttpHeaderNames.Upgrade, out ICharSequence upgradeHeader) && !AsciiString.ContentEqualsIgnoreCase(this.upgradeCodec.Protocol, upgradeHeader)) { throw new InvalidOperationException($"Switching Protocols response with unexpected UPGRADE protocol: {upgradeHeader}"); } // Upgrade to the new protocol. this.sourceCodec.PrepareUpgradeFrom(context); this.upgradeCodec.UpgradeTo(context, response); // Notify that the upgrade to the new protocol completed successfully. context.FireUserEventTriggered(UpgradeEvent.UpgradeSuccessful); // We guarantee UPGRADE_SUCCESSFUL event will be arrived at the next handler // before http2 setting frame and http response. this.sourceCodec.UpgradeFrom(context); // We switched protocols, so we're done with the upgrade response. // Release it and clear it from the output. response.Release(); output.Clear(); RemoveThisHandler(context); } catch (Exception exception) { ReferenceCountUtil.Release(response); context.FireExceptionCaught(exception); RemoveThisHandler(context); } }