public HttpStatusLine(HttpVersion version, int code, string reason) : this() { if (null == version) { throw new ArgumentNullException("version"); } if (0 > code) { throw new ArgumentOutOfRangeException("code"); } if (null == reason) { throw new ArgumentNullException("reason"); } if (0 == reason.Length) { throw new ArgumentOutOfRangeException("reason"); } Version = version; Code = code; Reason = reason; }
public HttpRequest(HttpMethod method, Uri path, HttpVersion version, Dictionary<string, string> headerDictionary, string content) { Version = version; Method = method; Path = path; Headers = headerDictionary; Content = content; }
/// <summary> /// Creates a new instance of the http response class with the specified parameters. /// </summary> /// <param name="version">The http version.</param> /// <param name="state">The http state.</param> public HttpResponse(HttpVersion version, HttpState state) { if (!Enum.IsDefined(typeof(HttpVersion), version)) throw new ArgumentException("The argument is not valid.", nameof(version)); if (state == InvalidCode) throw new ArgumentException("The argument is not valid.", nameof(state)); HttpVersion = version; State = state; }
public static MessageBody For( HttpVersion httpVersion, FrameRequestHeaders headers, Frame context) { // see also http://tools.ietf.org/html/rfc2616#section-4.4 var keepAlive = httpVersion != HttpVersion.Http10; var connection = headers.HeaderConnection; var upgrade = false; if (connection.Count > 0) { var connectionOptions = FrameHeaders.ParseConnection(connection); upgrade = (connectionOptions & ConnectionOptions.Upgrade) == ConnectionOptions.Upgrade; keepAlive = (connectionOptions & ConnectionOptions.KeepAlive) == ConnectionOptions.KeepAlive; } var transferEncoding = headers.HeaderTransferEncoding; if (transferEncoding.Count > 0) { var transferCoding = FrameHeaders.GetFinalTransferCoding(headers.HeaderTransferEncoding); // https://tools.ietf.org/html/rfc7230#section-3.3.3 // If a Transfer-Encoding header field // is present in a request and the chunked transfer coding is not // the final encoding, the message body length cannot be determined // reliably; the server MUST respond with the 400 (Bad Request) // status code and then close the connection. if (transferCoding != TransferCoding.Chunked) { context.ThrowRequestRejected(RequestRejectionReason.FinalTransferCodingNotChunked, transferEncoding.ToString()); } if (upgrade) { context.ThrowRequestRejected(RequestRejectionReason.UpgradeRequestCannotHavePayload); } return(new ForChunkedEncoding(keepAlive, context)); } if (headers.ContentLength.HasValue) { var contentLength = headers.ContentLength.Value; if (contentLength == 0) { return(keepAlive ? _zeroContentLengthKeepAlive : _zeroContentLengthClose); } else if (upgrade) { context.ThrowRequestRejected(RequestRejectionReason.UpgradeRequestCannotHavePayload); } return(new ForContentLength(keepAlive, contentLength, context)); } // Avoid slowing down most common case if (!object.ReferenceEquals(context.Method, HttpMethods.Get)) { // If we got here, request contains no Content-Length or Transfer-Encoding header. // Reject with 411 Length Required. if (HttpMethods.IsPost(context.Method) || HttpMethods.IsPut(context.Method)) { var requestRejectionReason = httpVersion == HttpVersion.Http11 ? RequestRejectionReason.LengthRequired : RequestRejectionReason.LengthRequiredHttp10; context.ThrowRequestRejected(requestRejectionReason, context.Method); } } if (upgrade) { return(new ForUpgrade(context)); } return(keepAlive ? _zeroContentLengthKeepAlive : _zeroContentLengthClose); }
public WebSocketRequestBuilder HttpVersion(HttpVersion value) { this.httpVersion = value; return(this); }
public void OnStartLine(HttpMethod method, HttpVersion version, Span <byte> target, Span <byte> path, Span <byte> query, Span <byte> customMethod, bool pathEncoded) { }
public void OnStartLine(HttpMethod method, HttpVersion version, Span <byte> target, Span <byte> path, Span <byte> query, Span <byte> customMethod, bool pathEncoded) => RequestHandler.Connection.OnStartLine(method, version, target, path, query, customMethod, pathEncoded);
private int ParseMethodLine(byte[] array, int offset, int length, out HttpMethod method, out HttpVersion version, out RequestTarget requestTarget) { int crlfIndex = IndexOfCrlf(array, offset, length); string methodLineString = Encoding.ASCII.GetString(array, offset, crlfIndex - offset); string[] methodLineData = methodLineString.Split(' '); if (methodLineData.Length != 3 || string.IsNullOrWhiteSpace(methodLineString)) { throw new RequestHeaderParserException("Invalid format of method line"); } method = ParseMethod(methodLineData[0]); requestTarget = ParseRequestTarget(methodLineData[1]); version = ParseVersion(methodLineData[2]); return(crlfIndex - offset + 2); }
public static MessageBody For( HttpVersion httpVersion, HttpRequestHeaders headers, Http1Connection context) { // see also http://tools.ietf.org/html/rfc2616#section-4.4 var keepAlive = httpVersion != HttpVersion.Http10; var upgrade = false; if (headers.HasConnection) { var connectionOptions = HttpHeaders.ParseConnection(headers.HeaderConnection); upgrade = (connectionOptions & ConnectionOptions.Upgrade) == ConnectionOptions.Upgrade; keepAlive = (connectionOptions & ConnectionOptions.KeepAlive) == ConnectionOptions.KeepAlive; } if (upgrade) { if (headers.HeaderTransferEncoding.Count > 0 || (headers.ContentLength.HasValue && headers.ContentLength.Value != 0)) { BadHttpRequestException.Throw(RequestRejectionReason.UpgradeRequestCannotHavePayload); } return(new Http1UpgradeMessageBody(context)); } if (headers.HasTransferEncoding) { var transferEncoding = headers.HeaderTransferEncoding; var transferCoding = HttpHeaders.GetFinalTransferCoding(transferEncoding); // https://tools.ietf.org/html/rfc7230#section-3.3.3 // If a Transfer-Encoding header field // is present in a request and the chunked transfer coding is not // the final encoding, the message body length cannot be determined // reliably; the server MUST respond with the 400 (Bad Request) // status code and then close the connection. if (transferCoding != TransferCoding.Chunked) { BadHttpRequestException.Throw(RequestRejectionReason.FinalTransferCodingNotChunked, in transferEncoding); } // TODO may push more into the wrapper rather than just calling into the message body // NBD for now. return(new Http1ChunkedEncodingMessageBody(keepAlive, context)); } if (headers.ContentLength.HasValue) { var contentLength = headers.ContentLength.Value; if (contentLength == 0) { return(keepAlive ? MessageBody.ZeroContentLengthKeepAlive : MessageBody.ZeroContentLengthClose); } return(new Http1ContentLengthMessageBody(keepAlive, contentLength, context)); } // If we got here, request contains no Content-Length or Transfer-Encoding header. // Reject with 411 Length Required. if (context.Method == HttpMethod.Post || context.Method == HttpMethod.Put) { var requestRejectionReason = httpVersion == HttpVersion.Http11 ? RequestRejectionReason.LengthRequired : RequestRejectionReason.LengthRequiredHttp10; BadHttpRequestException.Throw(requestRejectionReason, context.Method); } return(keepAlive ? MessageBody.ZeroContentLengthKeepAlive : MessageBody.ZeroContentLengthClose); }
// Compare with Http2Stream.TryValidatePseudoHeaders private void OnOriginFormTarget(HttpMethod method, HttpVersion version, Span <byte> target, Span <byte> path, Span <byte> query, Span <byte> customMethod, bool pathEncoded) { Debug.Assert(target[0] == ByteForwardSlash, "Should only be called when path starts with /"); _requestTargetForm = HttpRequestTarget.OriginForm; if (target.Length == 1) { // If target.Length == 1 it can only be a forward slash (e.g. home page) // and we know RawTarget and Path are the same and QueryString is Empty RawTarget = ForwardSlash; Path = ForwardSlash; QueryString = string.Empty; // Clear parsedData 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. _parsedRawTarget = _parsedPath = _parsedQueryString = null; return; } // URIs are always encoded/escaped to ASCII https://tools.ietf.org/html/rfc3986#page-11 // Multibyte Internationalized Resource Identifiers (IRIs) are first converted to utf8; // then encoded/escaped to ASCII https://www.ietf.org/rfc/rfc3987.txt "Mapping of IRIs to URIs" try { var disableStringReuse = ServerOptions.DisableStringReuse; // Read raw target before mutating memory. var previousValue = _parsedRawTarget; if (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(); previousValue = _parsedQueryString; if (disableStringReuse || previousValue == null || previousValue.Length != query.Length || !StringUtilities.BytesOrdinalEqualsStringAndAscii(previousValue, query)) { // The previous string does not match what the bytes would convert to, // so we will need to generate a new string. QueryString = _parsedQueryString = query.GetAsciiStringNonNullCharacters(); } else { // Same as previous QueryString = _parsedQueryString; } if (path.Length == 1) { // If path.Length == 1 it can only be a forward slash (e.g. home page) Path = _parsedPath = ForwardSlash; } else { Path = _parsedPath = PathNormalizer.DecodePath(path, pathEncoded, RawTarget, query.Length); } } else { // As RawTarget is the same we can reuse the previous parsed values. RawTarget = _parsedRawTarget; Path = _parsedPath; QueryString = _parsedQueryString; } } catch (InvalidOperationException) { ThrowRequestTargetRejected(target); } }
public Response(ResponseSettings settings, HttpStatus status = HttpStatus.Ok, HttpVersion protocolVersion = HttpVersion.HTTP11) { Headers = settings.StaticResponseHeaders?.Clone() ?? new Dictionary <string, string>(); Status = status; ProtocolVersion = protocolVersion; }
public HttpRequest(HttpMethod method, string path, HttpVersion httpVersion, ICollection <HttpHeader> headers, ICollection <HttpCookie> cookies) : this(method, path, httpVersion) { this.headers = headers; this.cookies = cookies; }
/// <summary> /// Creates a new instane of the http request class with the specified parameters. /// </summary> /// <param name="method">The http method.</param> /// <param name="url">The requested, relative url.</param> /// <param name="version">The http version.</param> public HttpRequest(HttpMethod method, Uri url, HttpVersion version) { if (url == null) throw new ArgumentNullException(nameof(url)); if (url.IsAbsoluteUri) throw new ArgumentException("The specified url must not be absolute.", nameof(url)); if (!Enum.IsDefined(typeof(HttpVersion), version)) throw new ArgumentException("The argument is not valid.", nameof(version)); _requestUrl = url; _method = method; HttpVersion = version; }
public static HttpRequest Parse(string request) { string[] lines = request.Split(new string[] { NewLine }, StringSplitOptions.None); string[] requestLineTokens = lines[0].Split(' '); if (requestLineTokens.Length != 3) { throw new BadRequestException(InvalidRequestLine); } string[] linkTokens = requestLineTokens[1].Split(new char[] { '?' }, 2); HttpMethod method = HttpMethod.Parse(requestLineTokens[0]); string path = linkTokens[0]; HttpVersion version = HttpVersion.Parse(requestLineTokens[2]); HttpRequest httpRequest = new HttpRequest(method, path, version); if (linkTokens.Length == 2) { httpRequest.FormData = HttpFormData.Parse(linkTokens[1]); } int i = 0; try { while (!string.IsNullOrEmpty(lines[++i])) { HttpHeader header = HttpHeader.Parse(lines[i]); if (header.Name.ToLower() == "cookie") { string[] cookies = header.Value.Split(new string[] { "; " }, StringSplitOptions.RemoveEmptyEntries); foreach (var cookie in cookies) { string[] cookieKvp = cookie.Split('='); if (cookieKvp.Length != 2) { throw new BadRequestException(InvalidCookieHeader); } httpRequest.AddCookie(new HttpCookie(cookieKvp[0], cookieKvp[1])); } } else { httpRequest.AddHeader(header); } } } catch (IndexOutOfRangeException ex) { throw new BadRequestException(NoEndOfHeaders, ex); } if (i < lines.Length - 1) { StringBuilder body = new StringBuilder(); while (++i != lines.Length) { string line = lines[i]; body.Append(line + NewLine); } httpRequest.Body = body.ToString() .TrimEnd(new char[] { '\r', '\n' }); if (!string.IsNullOrEmpty(httpRequest.Body)) { httpRequest.FormData = HttpFormData.Parse(httpRequest.Body); } } return(httpRequest); }
public static void AppendHttpRequestLine <TFormatter>(this TFormatter formatter, HttpMethod method, HttpVersion version, string path) where TFormatter : ITextOutput { if (formatter.SymbolTable == SymbolTable.InvariantUtf8) { switch (method) { case HttpMethod.Get: formatter.AppendBytes(s_GetUtf8); break; case HttpMethod.Post: formatter.AppendBytes(s_PostUtf8); break; case HttpMethod.Put: formatter.AppendBytes(s_PutUtf8); break; case HttpMethod.Delete: formatter.AppendBytes(s_DeleteUtf8); break; default: formatter.Append(method.ToString()); formatter.Append(' '); break; } formatter.Append(path); switch (version) { case HttpVersion.V1_0: formatter.AppendBytes(s_Http10Utf8); break; case HttpVersion.V1_1: formatter.AppendBytes(s_Http11Utf8); break; case HttpVersion.V2_0: formatter.AppendBytes(s_Http20Utf8); break; default: throw new ArgumentException(nameof(version)); } } else { formatter.Append(method.ToString()); formatter.Append(' '); formatter.Append(path); formatter.Append(' '); switch (version) { case HttpVersion.V1_0: formatter.Append(Http10); break; case HttpVersion.V1_1: formatter.Append(Http11); break; case HttpVersion.V2_0: formatter.Append(Http20); break; default: throw new ArgumentException(nameof(version)); } formatter.AppendHttpNewLine(); } }
public static void AppendHttpStatusLine <TFormatter>(this TFormatter formatter, HttpVersion version, int statusCode, Utf8Span reasonCode) where TFormatter : ITextOutput { switch (version) { case HttpVersion.V1_0: formatter.Append(Http10); break; case HttpVersion.V1_1: formatter.Append(Http11); break; case HttpVersion.V2_0: formatter.Append(Http20); break; default: throw new ArgumentException(nameof(version)); } formatter.Append(" "); formatter.Append(statusCode); formatter.Append(" "); formatter.Append(reasonCode); formatter.AppendHttpNewLine(); }
private static void TestHttpRequest(string httpString, string expectedMethodString = null, string expectedUri = null, HttpVersion expectedVersion = null, HttpHeader expectedHeader = null, string expectedBodyString = null) { Datagram expectedBody = expectedBodyString == null ? null : new Datagram(Encoding.ASCII.GetBytes(expectedBodyString)); HttpRequestMethod expectedMethod = expectedMethodString == null ? null : new HttpRequestMethod(expectedMethodString); Packet packet = BuildPacket(httpString); // HTTP HttpDatagram http = packet.Ethernet.IpV4.Tcp.Http; Assert.IsTrue(http.IsRequest, "IsRequest " + httpString); Assert.IsFalse(http.IsResponse, "IsResponse " + httpString); Assert.AreEqual(expectedVersion, http.Version, "Version " + httpString); Assert.AreEqual(expectedHeader, http.Header, "Header " + httpString); if (expectedHeader != null) Assert.AreEqual(expectedHeader.ToString(), http.Header.ToString(), "Header " + httpString); HttpRequestDatagram request = (HttpRequestDatagram)http; Assert.AreEqual(expectedMethod, request.Method, "Method " + httpString); Assert.AreEqual(expectedUri, request.Uri, "Uri " + httpString); Assert.AreEqual(expectedBody, request.Body, "Body " + httpString); }
private void ReturnResponse(HttpRequestHeader request, int responseCode, string message, string method, HttpVersion version, DataAdapterToStream stm) { ReturnResponse(request, responseCode, message, method, version, new KeyDataPair <string> [0], stm); }
// TODO: this is not a very general purpose routine. Maybe should not be in this base class? protected static void WriteCommonHeaders( HttpResponse formatter, HttpVersion version, int statuCode, string reasonCode, bool keepAlive) { var currentTime = DateTime.UtcNow; formatter.Headers.AppendHttpStatusLine(version, statuCode, new Utf8String(reasonCode)); formatter.Headers.Append(new Utf8String("Date : ")); formatter.Headers.Append(currentTime, 'R'); formatter.Headers.AppendHttpNewLine(); formatter.Headers.Append("Server : .NET Core Sample Server"); formatter.Headers.AppendHttpNewLine(); formatter.Headers.Append("Content-Type : text/html; charset=UTF-8"); formatter.Headers.AppendHttpNewLine(); if (!keepAlive) { formatter.Headers.Append("Connection : close"); } }
protected DefaultHttpMessage(HttpVersion version) : this(version, true, false) { }
IHttpClientBuilder IHttpClientBuilder.SetVersion(HttpVersion version) { return(this.SetVersion(version)); }
public void OnStartLine(HttpMethod method, HttpVersion version, Span <byte> target, Span <byte> path, Span <byte> query, Span <byte> customMethod, bool pathEncoded) { Console.WriteLine("On start line"); }
private void ReturnResponse(HttpRequestHeader request, int responseCode, string message, string method, HttpVersion version, IEnumerable <KeyDataPair <string> > sendHeaders, DataAdapterToStream stm) { if (request != null) { FlushRequest(request); } HttpResponseDataChunk response = new HttpResponseDataChunk(); if (_config.Version10Proxy && !version.IsVersionUnknown) { response.Version = HttpVersion.Version10; } else { response.Version = version; } response.ResponseCode = responseCode; response.Message = message; response.FinalChunk = true; response.Body = new byte[0]; List <KeyDataPair <string> > headers = new List <KeyDataPair <string> >(sendHeaders); headers.Add(new KeyDataPair <string>("X-Proxy-Server", "CANAPE")); if (response.Body.Length > 0) { headers.Add(new KeyDataPair <string>("Content-Type", "text/html")); } response.Headers = headers.ToArray(); if (method.Equals("HEAD", StringComparison.OrdinalIgnoreCase)) { response.HeadResponse = true; } else if (method.Equals("CONNECT", StringComparison.OrdinalIgnoreCase)) { response.ConnectResponse = true; } response.WriteChunk(new DataWriter(stm)); }
/// <summary> /// 设置 HTTP 协议版本号。 /// </summary> /// <param name="version"></param> /// <returns></returns> public new WxpayApiClientBuilder SetVersion(HttpVersion version) { base.SetVersion(version); return(this); }
private void OnOriginFormTarget(HttpMethod method, HttpVersion version, Span <byte> target, Span <byte> path, Span <byte> query, Span <byte> customMethod, bool pathEncoded) { Debug.Assert(target[0] == ByteForwardSlash, "Should only be called when path starts with /"); _requestTargetForm = HttpRequestTarget.OriginForm; // URIs are always encoded/escaped to ASCII https://tools.ietf.org/html/rfc3986#page-11 // Multibyte Internationalized Resource Identifiers (IRIs) are first converted to utf8; // then encoded/escaped to ASCII https://www.ietf.org/rfc/rfc3987.txt "Mapping of IRIs to URIs" string requestUrlPath = null; string rawTarget = null; try { // Read raw target before mutating memory. rawTarget = target.GetAsciiStringNonNullCharacters(); if (pathEncoded) { // URI was encoded, unescape and then parse as UTF-8 var pathLength = UrlEncoder.Decode(path, path); // Removing dot segments must be done after unescaping. From RFC 3986: // // URI producing applications should percent-encode data octets that // correspond to characters in the reserved set unless these characters // are specifically allowed by the URI scheme to represent data in that // component. If a reserved character is found in a URI component and // no delimiting role is known for that character, then it must be // interpreted as representing the data octet corresponding to that // character's encoding in US-ASCII. // // https://tools.ietf.org/html/rfc3986#section-2.2 pathLength = PathNormalizer.RemoveDotSegments(path.Slice(0, pathLength)); requestUrlPath = GetUtf8String(path.Slice(0, pathLength)); } else { var pathLength = PathNormalizer.RemoveDotSegments(path); if (path.Length == pathLength && query.Length == 0) { // If no decoding was required, no dot segments were removed and // there is no query, the request path is the same as the raw target requestUrlPath = rawTarget; } else { requestUrlPath = path.Slice(0, pathLength).GetAsciiStringNonNullCharacters(); } } } catch (InvalidOperationException) { ThrowRequestTargetRejected(target); } QueryString = query.GetAsciiStringNonNullCharacters(); RawTarget = rawTarget; Path = requestUrlPath; }
public HeaderLine(HttpMethod method, Uri uri, HttpVersion version) { Method = method; Uri = uri; Version = version; }
protected override int ProcessData(byte[] data, bool writeExcess) { ThrowIfEnded(); bool run = true; int i = 0; for (; i < data.Length && run; i++) { char c = (char)data[i]; switch (State) { case ResponseParserState.Version: if (c != WHITESPACE) { StringQueue.Append(c); } else { if (!HttpVersion.TryParse(StringQueue.Next(), out HttpVersion result)) { End(); return(-1); } Incoming.Version = result; StringQueue.New(); State = ResponseParserState.StatusCode; } break; case ResponseParserState.StatusCode: if (c != WHITESPACE) { StringQueue.Append(c); } else { if (!ushort.TryParse(StringQueue.Next(), out ushort result)) { End(); return(-1); } Incoming.StatusCode = result; StringQueue.New(); State = ResponseParserState.StatusDescription; } break; case ResponseParserState.StatusDescription: if (c != CR) { StringQueue.Append(c); } else { Incoming.StatusDescription = StringQueue.Next(); StringQueue.New(); State = ResponseParserState.FirstLf; } break; case ResponseParserState.FirstLf: if (c != LF) { End(); return(-1); } State = ResponseParserState.HeaderName; break; case ResponseParserState.HeaderName: if (c == CR) { State = ResponseParserState.Lf; } else if (c != COLON) { StringQueue.Append(c); } else { StringQueue.New(); State = ResponseParserState.HeaderValue; } break; case ResponseParserState.HeaderValue: if (c != CR) { StringQueue.Append(c); } else { Incoming.Headers.Set(StringQueue.Next(), StringQueue.Next().Trim()); State = ResponseParserState.HeaderLf; } break; case ResponseParserState.HeaderLf: if (c != LF) { End(); return(-1); } else { StringQueue.New(); State = ResponseParserState.HeaderName; } break; case ResponseParserState.Lf: if (c != LF) { End(); return(-1); } run = false; PushIncoming(); State = ResponseParserState.Version; break; } } if (writeExcess) { int len = data.Length - i; byte[] sliced = new byte[len]; System.Buffer.BlockCopy(data, i, sliced, 0, len); Bwrite(sliced); } return(i); }
public void OnStartLine(HttpMethod method, HttpVersion version, Span <byte> target, Span <byte> path, Span <byte> query, Span <byte> customMethod, bool pathEncoded) => Frame.OnStartLine(method, version, target, path, query, customMethod, pathEncoded);
/// <summary> /// Handle a HTTP request /// </summary> /// <param name="method">The HTTP method</param> /// <param name="path">The HTTP path</param> /// <param name="body">The body of the data</param> /// <param name="headers">A dictionary of headers</param> /// <param name="version">HTTP version</param> /// <param name="logger">A logger to log data to</param> /// <returns>A HTTP response data object, or null if no response</returns> protected abstract HttpServerResponseData HandleRequest(string method, string path, byte[] body, Dictionary <string, string> headers, HttpVersion version, Logger logger);
public HttpResponse(ResponseCode responseCode, HttpVersion version = HttpVersion.Http11) { ResponseCode = responseCode; HttpVersion = version; }
protected override HttpServerResponseData HandleRequest(string method, string path, byte[] body, Dictionary <string, string> headers, HttpVersion version, Logger logger) { Regex pathRegex = GeneralUtils.GlobToRegex(Config.HttpPath); HttpServerResponseData data = new HttpServerResponseData(); data.CloseAfterSending = Config.CloseAfterSending; if (pathRegex.IsMatch(path)) { data.ResponseCode = 200; data.Message = "OK"; if (Config.ValidResponseData != null) { data.Body = Config.ValidResponseData; } } else { data.ResponseCode = 404; data.Message = "Not Found"; if (Config.NotFoundResponseData != null) { data.Body = Config.NotFoundResponseData; } } data.Headers["Content-Type"] = Config.ContentType ?? "text/html"; return(data); }
} // ValidateVerbCharacter // read headers public BaseTransportHeaders ReadHeaders() { bool bSendContinue = false; BaseTransportHeaders headers = new BaseTransportHeaders(); // read first line String verb, requestURI, version; ReadFirstLine(out verb, out requestURI, out version); if ((verb == null) || (requestURI == null) || (version == null)) { throw new RemotingException( CoreChannel.GetResourceString( "Remoting_Http_UnableToReadFirstLine")); } if (version.Equals("HTTP/1.1")) // most common case { _version = HttpVersion.V1_1; } else if (version.Equals("HTTP/1.0")) { _version = HttpVersion.V1_0; } else { _version = HttpVersion.V1_1; // (assume it will understand 1.1) } if (_version == HttpVersion.V1_1) { _allowChunkedResponse = true; _keepAlive = true; } else // it's a 1.0 client { _allowChunkedResponse = false; _keepAlive = false; } // update request uri to be sure that it has no channel data String channelURI; String objectURI; channelURI = HttpChannelHelper.ParseURL(requestURI, out objectURI); if (channelURI == null) { objectURI = requestURI; } headers["__RequestVerb"] = verb; headers.RequestUri = objectURI; headers["__HttpVersion"] = version; // check to see if we must send continue if ((_version == HttpVersion.V1_1) && (verb.Equals("POST") || verb.Equals("PUT"))) { bSendContinue = true; } ReadToEndOfHeaders(headers, out _chunkedEncoding, out _contentLength, ref _keepAlive, ref bSendContinue); if (bSendContinue && (_version != HttpVersion.V1_0)) { SendContinue(); } // add IP address and Connection Id to headers headers[CommonTransportKeys.IPAddress] = ((IPEndPoint)NetSocket.RemoteEndPoint).Address; headers[CommonTransportKeys.ConnectionId] = _connectionId; return(headers); } // ReadHeaders
internal HttpDatagram(byte[] buffer, int offset, int length, HttpVersion version, HttpHeader header, Datagram body) : base(buffer, offset, length) { Version = version; Header = header; Body = body; }
public void GetsKnownVersion(string input, bool expectedResult, string expectedKnownString, HttpVersion version) { // Arrange var block = new Span <byte>(Encoding.ASCII.GetBytes(input)); // Act HttpVersion knownVersion; var result = block.GetKnownVersion(out knownVersion, out var length); string toString = null; if (knownVersion != HttpVersion.Unknown) { toString = HttpUtilities.VersionToString(knownVersion); } // Assert Assert.Equal(expectedResult, result); Assert.Equal(expectedKnownString, toString); Assert.Equal(expectedKnownString?.Length ?? 0, length); }
public HttpParser Version(out HttpVersion version) { uint? major; uint? minor; Bytes(_httpSlash).DecimalNumber(out major).Dot().DecimalNumber(out minor); version = major != null && minor != null ? new HttpVersion(major.Value, minor.Value) : null; return this; }
public HttpResponse(HttpVersion httpVersion, HttpResponseCode responseCode, ICollection <HttpHeader> headers, ICollection <HttpCookie> cookies) : this(httpVersion, responseCode) { this.headers = headers; this.cookies = cookies; }
private static void TestHttpResponse(string httpString, HttpVersion expectedVersion = null, uint? expectedStatusCode = null, string expectedReasonPhrase = null, HttpHeader expectedHeader = null, string expectedBodyString = null) { Datagram expectedBody = expectedBodyString == null ? null : new Datagram(Encoding.ASCII.GetBytes(expectedBodyString)); Packet packet = BuildPacket(httpString); // HTTP HttpDatagram http = packet.Ethernet.IpV4.Tcp.Http; Assert.IsFalse(http.IsRequest, "IsRequest " + httpString); Assert.IsTrue(http.IsResponse, "IsResponse " + httpString); Assert.AreEqual(expectedVersion, http.Version, "Version " + httpString); Assert.AreEqual(expectedHeader, http.Header, "Header " + httpString); if (expectedHeader != null) Assert.IsNotNull(http.Header.ToString()); HttpResponseDatagram response = (HttpResponseDatagram)http; Assert.AreEqual(expectedStatusCode, response.StatusCode, "StatusCode " + httpString); Assert.AreEqual(expectedReasonPhrase == null ? null : new Datagram(Encoding.ASCII.GetBytes(expectedReasonPhrase)), response.ReasonPhrase, "ReasonPhrase " + httpString); Assert.AreEqual(expectedBody, response.Body, "Body " + httpString); }
public static string StringValue(this HttpVersion httpVersion) { return(httpVersion == HttpVersion.Http11 ? "HTTP/1.1" : "HTTP/1.0"); }
private static void TestHttpRequest(string httpString, string expectedMethodString = null, string expectedUri = null, HttpVersion expectedVersion = null, HttpHeader expectedHeader = null, string expectedBodyString = null) { Datagram expectedBody = expectedBodyString == null ? null : new Datagram(Encoding.ASCII.GetBytes(expectedBodyString)); HttpRequestMethod expectedMethod = expectedMethodString == null ? null : new HttpRequestMethod(expectedMethodString); Packet packet = BuildPacket(httpString); // HTTP HttpDatagram http = packet.Ethernet.IpV4.Tcp.Http; Assert.IsTrue(http.IsRequest, "IsRequest " + httpString); Assert.IsFalse(http.IsResponse, "IsResponse " + httpString); Assert.AreEqual(expectedVersion, http.Version, "Version " + httpString); Assert.AreEqual(expectedHeader, http.Header, "Header " + httpString); if (expectedHeader != null) { Assert.AreEqual(expectedHeader.ToString(), http.Header.ToString(), "Header " + httpString); } HttpRequestDatagram request = (HttpRequestDatagram)http; Assert.AreEqual(expectedMethod, request.Method, "Method " + httpString); Assert.AreEqual(expectedUri, request.Uri, "Uri " + httpString); Assert.AreEqual(expectedBody, request.Body, "Body " + httpString); }
public HttpStatusLine(HttpVersion version, HttpStatusCode code) : this(version, (int)code, ReasonPhase(code)) { }