State?ReadHeaders(IByteBuffer buffer) { IHttpMessage httpMessage = _message; HttpHeaders headers = httpMessage.Headers; AppendableCharSequence line = _headerParser.Parse(buffer); if (line is null) { return(null); } // ReSharper disable once ConvertIfDoToWhile if ((uint)line.Count > 0u) { do { byte firstChar = line.Bytes[0]; if (_name is object && (firstChar == c_space || firstChar == c_tab)) { //please do not make one line from below code //as it breaks +XX:OptimizeStringConcat optimization ICharSequence trimmedLine = CharUtil.Trim(line); _value = new AsciiString($"{_value} {trimmedLine}"); } else { if (_name is object) { _ = headers.Add(_name, _value); } SplitHeader(line); } line = _headerParser.Parse(buffer); if (line is null) { return(null); } } while ((uint)line.Count > 0u); } // Add the last header. if (_name is object) { _ = headers.Add(_name, _value); } // reset name and value fields _name = null; _value = null; var values = headers.GetAll(HttpHeaderNames.ContentLength); uint contentLengthValuesCount = (uint)values.Count; if (contentLengthValuesCount > 0u) { // Guard against multiple Content-Length headers as stated in // https://tools.ietf.org/html/rfc7230#section-3.3.2: // // If a message is received that has multiple Content-Length header // fields with field-values consisting of the same decimal value, or a // single Content-Length header field with a field value containing a // list of identical decimal values (e.g., "Content-Length: 42, 42"), // indicating that duplicate Content-Length header fields have been // generated or combined by an upstream message processor, then the // recipient MUST either reject the message as invalid or replace the // duplicated field-values with a single valid Content-Length field // containing that decimal value prior to determining the message body // length or forwarding the message. if (contentLengthValuesCount > 1u && httpMessage.ProtocolVersion == HttpVersion.Http11) { ThrowHelper.ThrowArgumentException_Multiple_Content_Length_Headers_Found(); } if (!long.TryParse(values[0].ToString(), out _contentLength)) { ThrowHelper.ThrowArgumentException_Invalid_Content_Length(); } } if (IsContentAlwaysEmpty(httpMessage)) { HttpUtil.SetTransferEncodingChunked(httpMessage, false); return(State.SkipControlChars); } else if (HttpUtil.IsTransferEncodingChunked(httpMessage)) { if (contentLengthValuesCount > 0u && httpMessage.ProtocolVersion == HttpVersion.Http11) { HandleTransferEncodingChunkedWithContentLength(httpMessage); } return(State.ReadChunkSize); } else if (ContentLength() >= 0L) { return(State.ReadFixedLengthContent); } else { return(State.ReadVariableLengthContent); } }
State?ReadHeaders(IByteBuffer buffer) { IHttpMessage httpMessage = this.message; HttpHeaders headers = httpMessage.Headers; AppendableCharSequence line = this.headerParser.Parse(buffer); if (line == null) { return(null); } // ReSharper disable once ConvertIfDoToWhile if (line.Count > 0) { do { byte firstChar = line.Bytes[0]; if (this.name != null && (firstChar == ' ' || firstChar == '\t')) { ICharSequence trimmedLine = CharUtil.Trim(line); this.value = new AsciiString($"{this.value} {trimmedLine}"); } else { if (this.name != null) { headers.Add(this.name, this.value); } this.SplitHeader(line); } line = this.headerParser.Parse(buffer); if (line == null) { return(null); } } while (line.Count > 0); } // Add the last header. if (this.name != null) { headers.Add(this.name, this.value); } // reset name and value fields this.name = null; this.value = null; State nextState; if (this.IsContentAlwaysEmpty(httpMessage)) { HttpUtil.SetTransferEncodingChunked(httpMessage, false); nextState = State.SkipControlChars; } else if (HttpUtil.IsTransferEncodingChunked(httpMessage)) { nextState = State.ReadChunkSize; } else if (this.ContentLength() >= 0) { nextState = State.ReadFixedLengthContent; } else { nextState = State.ReadVariableLengthContent; } return(nextState); }