private void ParseHeaders(string responseHeaders) { if (string.IsNullOrEmpty(responseHeaders)) { return; } byte[] buffer = System.Text.Encoding.UTF8.GetBytes(responseHeaders); WebParseError error = new WebParseError(); int totalResponseHeadersLength = 0; int offset = 0; int maxHeaderLength = 64000; try { DataParseStatus result = this.headers.ParseHeaders(buffer, buffer.Length, ref offset, ref totalResponseHeadersLength, maxHeaderLength, ref error); if (result != DataParseStatus.Done) { throw WebException.CreateInternal("HttpWebResponse.ParseHeaders"); } } catch (WebException) { throw; } catch (Exception e) { string message = System.Data.Services.Client.Strings.HttpWeb_Internal("HttpWebResponse.ParseHeaders.2"); throw new WebException(message, e); } }
internal DataParseStatus ParseHeaders( byte[] byteBuffer, int size, ref int unparsed, ref int totalResponseHeadersLength, int maximumResponseHeadersLength, ref WebParseError parseError) { if (byteBuffer.Length < size) { return DataParseStatus.NeedMoreData; } char ch; int headerNameStartOffset = -1; int headerNameEndOffset = -1; int headerValueStartOffset = -1; int headerValueEndOffset = -1; int numberOfLf = -1; int index = unparsed; bool spaceAfterLf; string headerMultiLineValue; string headerName; string headerValue; int localTotalResponseHeadersLength = totalResponseHeadersLength; WebParseErrorCode parseErrorCode = WebParseErrorCode.Generic; DataParseStatus parseStatus = DataParseStatus.Invalid; for (;;) { headerName = string.Empty; headerValue = string.Empty; spaceAfterLf = false; headerMultiLineValue = null; if (this.Count == 0) { while (index < size) { ch = (char)byteBuffer[index]; if (ch == ' ' || ch == '\t') { ++index; if (maximumResponseHeadersLength >= 0 && ++localTotalResponseHeadersLength >= maximumResponseHeadersLength) { parseStatus = DataParseStatus.DataTooBig; goto quit; } } else { break; } } if (index == size) { parseStatus = DataParseStatus.NeedMoreData; goto quit; } } headerNameStartOffset = index; while (index < size) { ch = (char)byteBuffer[index]; if (ch != ':' && ch != '\n') { if (ch > ' ') { headerNameEndOffset = index; } ++index; if (maximumResponseHeadersLength >= 0 && ++localTotalResponseHeadersLength >= maximumResponseHeadersLength) { parseStatus = DataParseStatus.DataTooBig; goto quit; } } else { if (ch == ':') { ++index; if (maximumResponseHeadersLength >= 0 && ++localTotalResponseHeadersLength >= maximumResponseHeadersLength) { parseStatus = DataParseStatus.DataTooBig; goto quit; } } break; } } if (index == size) { parseStatus = DataParseStatus.NeedMoreData; goto quit; } startOfValue: numberOfLf = (this.Count == 0 && headerNameEndOffset < 0) ? 1 : 0; while (index < size && numberOfLf < 2) { ch = (char)byteBuffer[index]; if (ch <= ' ') { if (ch == '\n') { numberOfLf++; if (numberOfLf == 1) { if (index + 1 == size) { parseStatus = DataParseStatus.NeedMoreData; goto quit; } spaceAfterLf = (char)byteBuffer[index + 1] == ' ' || (char)byteBuffer[index + 1] == '\t'; } } ++index; if (maximumResponseHeadersLength >= 0 && ++localTotalResponseHeadersLength >= maximumResponseHeadersLength) { parseStatus = DataParseStatus.DataTooBig; goto quit; } } else { break; } } if (numberOfLf == 2 || (numberOfLf == 1 && !spaceAfterLf)) { goto addHeader; } if (index == size) { parseStatus = DataParseStatus.NeedMoreData; goto quit; } headerValueStartOffset = index; while (index < size) { ch = (char)byteBuffer[index]; if (ch != '\n') { if (ch > ' ') { headerValueEndOffset = index; } ++index; if (maximumResponseHeadersLength >= 0 && ++localTotalResponseHeadersLength >= maximumResponseHeadersLength) { parseStatus = DataParseStatus.DataTooBig; goto quit; } } else { break; } } if (index == size) { parseStatus = DataParseStatus.NeedMoreData; goto quit; } numberOfLf = 0; while (index < size && numberOfLf < 2) { ch = (char)byteBuffer[index]; if (ch == '\r' || ch == '\n') { if (ch == '\n') { numberOfLf++; } ++index; if (maximumResponseHeadersLength >= 0 && ++localTotalResponseHeadersLength >= maximumResponseHeadersLength) { parseStatus = DataParseStatus.DataTooBig; goto quit; } } else { break; } } if (index == size && numberOfLf < 2) { parseStatus = DataParseStatus.NeedMoreData; goto quit; } addHeader: if (headerValueStartOffset >= 0 && headerValueStartOffset > headerNameEndOffset && headerValueEndOffset >= headerValueStartOffset) { headerValue = System.Text.Encoding.UTF8.GetString(byteBuffer, headerValueStartOffset, headerValueEndOffset - headerValueStartOffset + 1); } headerMultiLineValue = (headerMultiLineValue == null ? headerValue : headerMultiLineValue + " " + headerValue); if (index < size && numberOfLf == 1) { ch = (char)byteBuffer[index]; if (ch == ' ' || ch == '\t') { ++index; if (maximumResponseHeadersLength >= 0 && ++localTotalResponseHeadersLength >= maximumResponseHeadersLength) { parseStatus = DataParseStatus.DataTooBig; goto quit; } goto startOfValue; } } if (headerNameStartOffset >= 0 && headerNameEndOffset >= headerNameStartOffset) { headerName = System.Text.Encoding.UTF8.GetString(byteBuffer, headerNameStartOffset, headerNameEndOffset - headerNameStartOffset + 1); } if (headerName.Length > 0) { this.Add(headerName, headerMultiLineValue); } totalResponseHeadersLength = localTotalResponseHeadersLength; unparsed = index; if (numberOfLf == 2) { parseStatus = DataParseStatus.Done; goto quit; } } quit: if (parseStatus == DataParseStatus.Invalid) { parseError.Section = WebParseErrorSection.ResponseHeader; parseError.Code = parseErrorCode; } return parseStatus; }
internal DataParseStatus ParseHeaders( byte[] byteBuffer, int size, ref int unparsed, ref int totalResponseHeadersLength, int maximumResponseHeadersLength, ref WebParseError parseError) { if (byteBuffer.Length < size) { return(DataParseStatus.NeedMoreData); } char ch; int headerNameStartOffset = -1; int headerNameEndOffset = -1; int headerValueStartOffset = -1; int headerValueEndOffset = -1; int numberOfLf = -1; int index = unparsed; bool spaceAfterLf; string headerMultiLineValue; string headerName; string headerValue; int localTotalResponseHeadersLength = totalResponseHeadersLength; WebParseErrorCode parseErrorCode = WebParseErrorCode.Generic; DataParseStatus parseStatus = DataParseStatus.Invalid; for (;;) { headerName = string.Empty; headerValue = string.Empty; spaceAfterLf = false; headerMultiLineValue = null; if (this.Count == 0) { while (index < size) { ch = (char)byteBuffer[index]; if (ch == ' ' || ch == '\t') { ++index; if (maximumResponseHeadersLength >= 0 && ++localTotalResponseHeadersLength >= maximumResponseHeadersLength) { parseStatus = DataParseStatus.DataTooBig; goto quit; } } else { break; } } if (index == size) { parseStatus = DataParseStatus.NeedMoreData; goto quit; } } headerNameStartOffset = index; while (index < size) { ch = (char)byteBuffer[index]; if (ch != ':' && ch != '\n') { if (ch > ' ') { headerNameEndOffset = index; } ++index; if (maximumResponseHeadersLength >= 0 && ++localTotalResponseHeadersLength >= maximumResponseHeadersLength) { parseStatus = DataParseStatus.DataTooBig; goto quit; } } else { if (ch == ':') { ++index; if (maximumResponseHeadersLength >= 0 && ++localTotalResponseHeadersLength >= maximumResponseHeadersLength) { parseStatus = DataParseStatus.DataTooBig; goto quit; } } break; } } if (index == size) { parseStatus = DataParseStatus.NeedMoreData; goto quit; } startOfValue: numberOfLf = (this.Count == 0 && headerNameEndOffset < 0) ? 1 : 0; while (index < size && numberOfLf < 2) { ch = (char)byteBuffer[index]; if (ch <= ' ') { if (ch == '\n') { numberOfLf++; if (numberOfLf == 1) { if (index + 1 == size) { parseStatus = DataParseStatus.NeedMoreData; goto quit; } spaceAfterLf = (char)byteBuffer[index + 1] == ' ' || (char)byteBuffer[index + 1] == '\t'; } } ++index; if (maximumResponseHeadersLength >= 0 && ++localTotalResponseHeadersLength >= maximumResponseHeadersLength) { parseStatus = DataParseStatus.DataTooBig; goto quit; } } else { break; } } if (numberOfLf == 2 || (numberOfLf == 1 && !spaceAfterLf)) { goto addHeader; } if (index == size) { parseStatus = DataParseStatus.NeedMoreData; goto quit; } headerValueStartOffset = index; while (index < size) { ch = (char)byteBuffer[index]; if (ch != '\n') { if (ch > ' ') { headerValueEndOffset = index; } ++index; if (maximumResponseHeadersLength >= 0 && ++localTotalResponseHeadersLength >= maximumResponseHeadersLength) { parseStatus = DataParseStatus.DataTooBig; goto quit; } } else { break; } } if (index == size) { parseStatus = DataParseStatus.NeedMoreData; goto quit; } numberOfLf = 0; while (index < size && numberOfLf < 2) { ch = (char)byteBuffer[index]; if (ch == '\r' || ch == '\n') { if (ch == '\n') { numberOfLf++; } ++index; if (maximumResponseHeadersLength >= 0 && ++localTotalResponseHeadersLength >= maximumResponseHeadersLength) { parseStatus = DataParseStatus.DataTooBig; goto quit; } } else { break; } } if (index == size && numberOfLf < 2) { parseStatus = DataParseStatus.NeedMoreData; goto quit; } addHeader: if (headerValueStartOffset >= 0 && headerValueStartOffset > headerNameEndOffset && headerValueEndOffset >= headerValueStartOffset) { headerValue = System.Text.Encoding.UTF8.GetString(byteBuffer, headerValueStartOffset, headerValueEndOffset - headerValueStartOffset + 1); } headerMultiLineValue = (headerMultiLineValue == null ? headerValue : headerMultiLineValue + " " + headerValue); if (index < size && numberOfLf == 1) { ch = (char)byteBuffer[index]; if (ch == ' ' || ch == '\t') { ++index; if (maximumResponseHeadersLength >= 0 && ++localTotalResponseHeadersLength >= maximumResponseHeadersLength) { parseStatus = DataParseStatus.DataTooBig; goto quit; } goto startOfValue; } } if (headerNameStartOffset >= 0 && headerNameEndOffset >= headerNameStartOffset) { headerName = System.Text.Encoding.UTF8.GetString(byteBuffer, headerNameStartOffset, headerNameEndOffset - headerNameStartOffset + 1); } if (headerName.Length > 0) { this.Add(headerName, headerMultiLineValue); } totalResponseHeadersLength = localTotalResponseHeadersLength; unparsed = index; if (numberOfLf == 2) { parseStatus = DataParseStatus.Done; goto quit; } } quit: if (parseStatus == DataParseStatus.Invalid) { parseError.Section = WebParseErrorSection.ResponseHeader; parseError.Code = parseErrorCode; } return(parseStatus); }