public static void ValidateHeaderNameCharacters(string headerCharacters) { var invalid = ProtoCharacters.IndexOfInvalidTokenChar(headerCharacters); if (invalid >= 0) { ThrowInvalidHeaderCharacter(headerCharacters[invalid]); } }
public static void ValidateHeaderValueCharacters(string headerCharacters) { if (headerCharacters != null) { var invalid = ProtoCharacters.IndexOfInvalidFieldValueChar(headerCharacters); if (invalid >= 0) { ThrowInvalidHeaderCharacter(headerCharacters[invalid]); } } }
private void OnAuthorityFormTarget(ProtoMethod method, Span <byte> target) { _requestTargetForm = ProtoRequestTarget.AuthorityForm; // This is not complete validation. It is just a quick scan for invalid characters // but doesn't check that the target fully matches the URI spec. if (ProtoCharacters.ContainsInvalidAuthorityChar(target)) { ThrowRequestTargetRejected(target); } // The authority-form of request-target is only used for CONNECT // requests (https://tools.ietf.org/html/rfc7231#section-4.3.6). if (method != ProtoMethod.Connect) { BadProtoRequestException.Throw(RequestRejectionReason.ConnectMethodRequired); } // When making a CONNECT request to establish a tunnel through one or // more proxies, a client MUST send only the target URI's authority // component (excluding any userinfo and its "@" delimiter) as the // request-target.For example, // // CONNECT www.example.com:80 HTTP/1.1 // // Allowed characters in the 'host + port' section of authority. // See https://tools.ietf.org/html/rfc3986#section-3.2 var previousValue = _parsedRawTarget; if (ServerOptions.DisableStringReuse || previousValue == null || previousValue.Length != target.Length || !StringUtilities.BytesOrdinalEqualsStringAndAscii(previousValue, target)) { // The previous string does not match what the bytes would convert to, // so we will need to generate a new string. RawTarget = _parsedRawTarget = target.GetAsciiStringNonNullCharacters(); } else { // Reuse previous value RawTarget = _parsedRawTarget; } Path = string.Empty; QueryString = string.Empty; // Clear parsedData for path and queryString as we won't check it if we come via this path again, // an setting to null is fast as it doesn't need to use a GC write barrier. _parsedPath = _parsedQueryString = null; }
// For testing internal KestrelServer(ITransportFactory transportFactory, ServiceContext serviceContext) { if (transportFactory == null) { throw new ArgumentNullException(nameof(transportFactory)); } _transportFactory = transportFactory; ServiceContext = serviceContext; Features = new FeatureCollection(); _serverAddresses = new ServerAddressesFeature(); Features.Set(_serverAddresses); ProtoCharacters.Initialize(); }
private bool TryValidateMethod() { // :method _methodText = RequestHeaders[HeaderNames.Method].ToString(); Method = ProtoUtilities.GetKnownMethod(_methodText); if (Method == ProtoMethod.None) { ResetAndAbort(new ConnectionAbortedException(CoreStrings.FormatProto2ErrorMethodInvalid(_methodText)), Proto2ErrorCode.PROTOCOL_ERROR); return(false); } if (Method == ProtoMethod.Custom) { if (ProtoCharacters.IndexOfInvalidTokenChar(_methodText) >= 0) { ResetAndAbort(new ConnectionAbortedException(CoreStrings.FormatProto2ErrorMethodInvalid(_methodText)), Proto2ErrorCode.PROTOCOL_ERROR); return(false); } } return(true); }