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);
            }
        }
Exemple #2
0
        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;
        }
Exemple #4
0
        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);
        }