System.Net.Connection.ProcessHeaderData C# (CSharp) Method

ProcessHeaderData() private method

private ProcessHeaderData ( bool &fHaveChunked, HttpWebRequest request, bool &dummyResponseStream ) : long
fHaveChunked bool
request HttpWebRequest
dummyResponseStream bool
return long
        private long ProcessHeaderData(ref bool fHaveChunked, HttpWebRequest request, out bool dummyResponseStream)
        {
            long contentLength = -1;
            fHaveChunked = false;
            //
            // Check for the "Transfer-Encoding" header to contain the "chunked" string
            //
            string transferEncodingString = m_ResponseData.m_ResponseHeaders[HttpKnownHeaderNames.TransferEncoding];
            if (transferEncodingString!=null) {
                transferEncodingString = transferEncodingString.ToLower(CultureInfo.InvariantCulture);
                fHaveChunked = transferEncodingString.IndexOf(HttpWebRequest.ChunkedHeader) != -1;
            }

            if (!fHaveChunked) {
                //
                // If the response is not chunked, parse the "Content-Length" into a long for data size.
                //
                string contentLengthString = m_ResponseData.m_ResponseHeaders.ContentLength;
                if (contentLengthString!=null) {
                    int index = contentLengthString.IndexOf(':');
                    if (index!=-1) {
                        contentLengthString = contentLengthString.Substring(index + 1);
                    }
                    bool success = long.TryParse(contentLengthString, NumberStyles.None, CultureInfo.InvariantCulture.NumberFormat, out contentLength);
                    if (!success) {
                        contentLength = -1;
                        //   in some very rare cases, a proxy server may
                        //   send us a pair of numbers in comma delimated
                        //   fashion, so we need to handle this case
                        index = contentLengthString.LastIndexOf(',');
                        if (index!=-1) {
                            contentLengthString = contentLengthString.Substring(index + 1);
                            success = long.TryParse(contentLengthString, NumberStyles.None, CultureInfo.InvariantCulture.NumberFormat, out contentLength);
                            if (!success) {
                                contentLength = -1;
                            }
                        }
                    }
                    if (contentLength < 0)
                    {
                        GlobalLog.Leave("Connection#" + ValidationHelper.HashString(this) + "::ProcessHeaderData - ContentLength value in header: " + contentLengthString + ", HttpWebRequest#"+ValidationHelper.HashString(m_CurrentRequest));
                        contentLength = c_InvalidContentLength; // This will indicate a CL error to the caller
                    }
                }
            }

            // ** else ** signal no content-length present??? or error out?
            GlobalLog.Print("Connection#" + ValidationHelper.HashString(this) + "::ProcessHeaderData() Content-Length parsed:" + contentLength.ToString(NumberFormatInfo.InvariantInfo));

            dummyResponseStream = !request.CanGetResponseStream || m_ResponseData.m_StatusCode < HttpStatusCode.OK ||
                                  m_ResponseData.m_StatusCode == HttpStatusCode.NoContent || (m_ResponseData.m_StatusCode == HttpStatusCode.NotModified && contentLength < 0) ;

            if (m_KeepAlive)
            {
                //
                // Deciding on  KEEP ALIVE
                //
                bool resetKeepAlive = false;

                //(1) if no content-length and no chunked, then turn off keep-alive
                //    In some cases, though, Content-Length should be assumed to be 0 based on HTTP RFC 2616
                if (!dummyResponseStream && contentLength < 0 && !fHaveChunked)
                {
                    resetKeepAlive = true;
                }
                //(2) A workaround for a failed client ssl session on IIS6
                //    The problem is that we cannot change the connection group name after it gets created.
                //    IIS6 does not close the connection on 403 so all subsequent requests will fail to be authorized on THAT connection.
                else if (m_ResponseData.m_StatusCode == HttpStatusCode.Forbidden )
                {
                    resetKeepAlive = true;
                }
                // (3) Possibly cease posting a big body on the connection, was invented mainly for the very first 401 response
                //
                //     This optimization is for the discovery legs only.  For ntlm this is fine, because the 1st actual authleg
                //     is always sent w/ content-length = 0.
                //     For Kerberos preauth, it there could be 1 or 2 auth legs, but we don't know how many there are in advance,
                //     so we don't have a way of eliminating the 1st auth leg.
                else if (m_ResponseData.m_StatusCode > HttpWebRequest.MaxOkStatus &&
                         ((request.CurrentMethod == KnownHttpVerb.Post || request.CurrentMethod == KnownHttpVerb.Put) &&
                            m_MaximumUnauthorizedUploadLength >= 0 && request.ContentLength > m_MaximumUnauthorizedUploadLength
                            && (request.CurrentAuthenticationState == null || request.CurrentAuthenticationState.Module == null)))
                {
                    resetKeepAlive = true;
                }
                //(4) for Http/1.0 servers, we can't be sure what their behavior
                //    in this case, so the best thing is to disable KeepAlive unless explicitly set
                //
                else
                {
                    bool haveClose = false;
                    bool haveKeepAlive = false;
                    string connection = m_ResponseData.m_ResponseHeaders[HttpKnownHeaderNames.Connection];
                    if (connection == null && ServicePoint.InternalProxyServicePoint) {
                        connection = m_ResponseData.m_ResponseHeaders[HttpKnownHeaderNames.ProxyConnection];
                    }

                    if (connection != null) {
                        connection = connection.ToLower(CultureInfo.InvariantCulture);
                        if (connection.IndexOf("keep-alive") != -1) {
                            haveKeepAlive = true;
                        }
                        else if (connection.IndexOf("close") != -1) {
                            haveClose = true;
                        }
                    }

                    if ((haveClose && ServicePoint.HttpBehaviour==HttpBehaviour.HTTP11) ||
                        (!haveKeepAlive && ServicePoint.HttpBehaviour<=HttpBehaviour.HTTP10))
                    {
                        resetKeepAlive = true;
                    }
                }


                if (resetKeepAlive)
                {
                    lock (this) {
                        m_KeepAlive = false;
                        m_Free = false;
                    }
                }
            }

            return contentLength;
        }