示例#1
0
        ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////

        public void Pass(ProxyResponse response)
        {
            response.pass_ = true;

            if (response.completable_ && !response.skipRemainingHandlers_ && (PostResponse != null))
            {
                PostResponse(response.request_, response);
            }

            if (response.pass_)
            {
                if (response.completable_ && (response.outbound_ != null))
                {
                    response.outbound_.Complete(response);
                }
                response.request_.encoding_ = null;
                response.request_.inbound_  = null;
                response.encoding_          = null;
                response.outbound_          = null;
            }
            else
            {
                Drop(response);
            }
        }
示例#2
0
        ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////

        internal void OnResponse(ProxyResponse response)
        {
            if ((response.request_ != null) && (response.request_.Header != null))
            {
                notifyQueueMutex_.WaitOne();
                notifyQueue_.Enqueue(response);
                threadNotifyEvent_.Set();
                notifyQueueMutex_.ReleaseMutex();
            }
        }
示例#3
0
        ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////

        internal void Complete(ProxyResponse response)
        {
            if (response.Completable && (response.header_ != null))
            {
                string header   = response.header_;
                string contents = response.contents_;

                byte[] headerBytes   = null;
                byte[] contentsBytes = new byte[0];
                if (contents != null)
                {
                    contentsBytes = response.encoding_.GetBytes(contents);
                    header       += "\r\nContent-Length: " + Convert.ToString(contentsBytes.Length) + "\r\n\r\n";
                    headerBytes   = wwwProxy_.defaultEncoding_.GetBytes(header);
                }

                wwwProxy_.log_.Write("Outbound.Complete()", header + ((contents != null) ? contents : ""));

                byte[] responseBytes = new byte[headerBytes.Length + contentsBytes.Length];

                Array.Copy(headerBytes, 0, responseBytes, 0, headerBytes.Length);
                Array.Copy(contentsBytes, 0, responseBytes, headerBytes.Length, contentsBytes.Length);

                inbound_.StopKeepAliveTimer();

                try
                {
                    inbound_.Send(responseBytes, 0, responseBytes.Length);
                }
                catch (IOException)
                {
                }
                catch (ObjectDisposedException)
                {
                }
                catch (SocketException)
                {
                }
            }

            if (responseCloseInbound_)
            {
                inbound_.Close();
            }

            if (completableResponse_)
            {
                completableResponse_  = false;
                responseCloseInbound_ = false;
            }

            response_ = null;
        }
示例#4
0
        ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////

        public void Drop(ProxyResponse response)
        {
            response.pass_ = false;
            response.skipRemainingHandlers_ = true;

            if (response.outbound_ != null)
            {
                if (response.outbound_.inbound_ != null)
                {
                    response.outbound_.inbound_.Close();
                }
                response.outbound_.Close();
            }
            response.request_.encoding_ = null;
            response.request_.inbound_  = null;
            response.encoding_          = null;
            response.outbound_          = null;
        }
示例#5
0
        ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////

        static void WwwProxy_Response(IPEndPoint ipEndPoint, WwwProxy.ProxyRequest request, WwwProxy.ProxyResponse response)
        {
            try
            {
                pythonMutex_.WaitOne();

                object[] args = new object[2];
                args[0] = request;
                args[1] = response;

                object rtnValue = Ops.Invoke(wwwPyFilterClassObject_, SymbolTable.StringToId("response_filter"), args);
                if (rtnValue is bool)
                {
                    if (!response.Completable || (bool)rtnValue)
                    {
                        wwwProxy_.Pass(response);
                    }
                    else
                    {
                        wwwProxy_.Drop(response);
                    }
                }
                else
                {
                    Console.WriteLine("WwwProxy_Response Warning: response_filter returned non-bool");
                    wwwProxy_.Pass(response);
                }
            }
            catch (Exception e)
            {
                Console.WriteLine("Error: {0}", e.Message);
                Console.WriteLine();
                Console.WriteLine(e.StackTrace);
            }
            finally
            {
                pythonMutex_.ReleaseMutex();
            }
        }
示例#6
0
        ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////

        private void RunNotifier()
        {
            WaitHandle[] waitHandles = new WaitHandle[2];
            waitHandles[0] = threadExitEvent_;
            waitHandles[1] = threadNotifyEvent_;

            while (!threadExitEvent_.WaitOne(0, false))
            {
                object notifyObject = null;

                if (WaitHandle.WaitAny(waitHandles, Timeout.Infinite, false) == 0)
                {
                    break;
                }

                notifyQueueMutex_.WaitOne();
                if (notifyQueue_.Count > 0)
                {
                    notifyObject = notifyQueue_.Dequeue();
                }
                else
                {
                    threadNotifyEvent_.Reset();
                }
                notifyQueueMutex_.ReleaseMutex();

                if (notifyObject != null)
                {
                    if (notifyObject is ProxyRequest)
                    {
                        ProxyRequest notifyRequest = (ProxyRequest)notifyObject;
                        notifyRequest.pass_ = true;
                        notifyRequest.skipRemainingHandlers_ = false;

                        if (PreRequest != null)
                        {
                            PreRequest(notifyRequest);
                        }
                        if (!notifyRequest.skipRemainingHandlers_ && (Request != null))
                        {
                            Request(notifyRequest);
                        }
                        else if (notifyRequest.pass_)
                        {
                            Pass(notifyRequest);
                        }
                        else
                        {
                            Drop(notifyRequest);
                        }
                    }
                    else if (notifyObject is ProxyResponse)
                    {
                        ProxyResponse notifyResponse = (ProxyResponse)notifyObject;
                        notifyResponse.pass_ = true;
                        notifyResponse.skipRemainingHandlers_ = notifyResponse.request_.skipRemainingHandlers_;

                        if (notifyResponse.completable_ && !notifyResponse.skipRemainingHandlers_ && (PreResponse != null))
                        {
                            PreResponse(notifyResponse.request_, notifyResponse);
                        }
                        if (!notifyResponse.skipRemainingHandlers_ && (Response != null))
                        {
                            Response(notifyResponse.request_, notifyResponse);
                        }
                        else if (notifyResponse.pass_)
                        {
                            Pass(notifyResponse);
                        }
                        else
                        {
                            Drop(notifyResponse);
                        }
                    }
                }
            }
        }
示例#7
0
        ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////

        private void RunSocket()
        {
            byte[] receiveBuffer      = new byte[4096];
            int    receiveBufferCount = 0;

            ushort outboundConnectionAttempt = 0;

            while (!outboundThreadExitEvent_.WaitOne(0, false))
            {
                try
                {
                    if (outboundSocket_ == null)
                    {
                        if (++outboundConnectionAttempt <= 5)
                        {
                            try
                            {
                                outboundSocket_ = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
                                outboundSocket_.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.Linger, new LingerOption(true, 1));
                                outboundSocket_.Connect(outboundIpEndPoint_);
                            }
                            catch (Exception)
                            {
                                break;
                            }

                            if (outboundSocket_.Connected)
                            {
                                outboundConnectionAttempt = 0xFFFF;
                            }
                            else
                            {
                                Thread.Sleep(1000);
                            }
                        }
                        else
                        {
                            wwwProxy_.OnError(inbound_, request_, null, "Connection Failed [" + outboundIpEndPoint_.Address.ToString() + ":" + outboundIpEndPoint_.Port + "]");
                            break;
                        }
                    }
                    else
                    {
                        if ((receiveBuffer.Length - receiveBufferCount) < 4096)
                        {
                            int newReceiveBufferLength = receiveBuffer.Length;
                            while ((newReceiveBufferLength - receiveBufferCount) < 4096)
                            {
                                newReceiveBufferLength *= 2;
                            }
                            byte[] newReceiveBuffer = new byte[newReceiveBufferLength];
                            Array.Copy(receiveBuffer, 0, newReceiveBuffer, 0, receiveBuffer.Length);
                            receiveBuffer = newReceiveBuffer;
                        }

                        if (ssl_)
                        {
                            if (useRemoteProxy_ && !sslProxyNegotiationSent_)
                            {
                                string sslProxyNegotiation     = "CONNECT " + host_ + ":" + port_ + " HTTP/1.0\r\n\r\n";
                                byte[] sslProxyNegotationBytes = wwwProxy_.defaultEncoding_.GetBytes(sslProxyNegotiation);
                                outboundSocket_.Send(sslProxyNegotationBytes, 0, sslProxyNegotationBytes.Length, SocketFlags.None);
                                sslProxyNegotiationSent_ = true;

                                while ((receiveBuffer.Length - receiveBufferCount) > 0)
                                {
                                    int bytesReceived = outboundSocket_.Receive(receiveBuffer, 0, receiveBuffer.Length, SocketFlags.None);
                                    receiveBufferCount += bytesReceived;

                                    bool bHeaderEnd = false;
                                    for (int i = 0; i < receiveBufferCount - 3; ++i)
                                    {
                                        if ((receiveBuffer[i] == '\r') &&
                                            (receiveBuffer[i + 1] == '\n') &&
                                            (receiveBuffer[i + 2] == '\r') &&
                                            (receiveBuffer[i + 3] == '\n'))
                                        {
                                            bHeaderEnd          = true;
                                            receiveBufferCount -= (i + 4);
                                            break;
                                        }
                                    }

                                    if (bHeaderEnd)
                                    {
                                        break;
                                    }
                                }

                                if (receiveBufferCount == receiveBuffer.Length)
                                {
                                    break;
                                }
                            }

                            if ((sslNetworkStream_ == null) || (sslStream_ == null))
                            {
                                sslNetworkStream_ = new NetworkStream(outboundSocket_);

                                sslStream_ = new SslStream(sslNetworkStream_, false, new RemoteCertificateValidationCallback(OnRemoteCertificateValidation));
                                sslStream_.AuthenticateAsClient(outboundIpEndPoint_.Address.ToString(), wwwProxy_.clientCertificates_, SslProtocols.Default, false);
                            }
                        }

                        if (outboundSocket_.Connected)
                        {
                            if ((request_ != null) && !request_.sent_)
                            {
                                Send(request_);
                            }

                            int bytesReceived = Receive(receiveBuffer, receiveBufferCount, receiveBuffer.Length - receiveBufferCount);
                            receiveBufferCount += bytesReceived;

                            if (receiveBufferCount > 0)
                            {
                                while (receiveBufferCount > 0)
                                {
                                    int bytesParsed = 0;
                                    if ((bytesRequired_ == 0) || ((bytesRequired_ -= bytesReceived) <= 0))
                                    {
                                        bytesRequired_ = 0;
                                        if (processResponse_)
                                        {
                                            bytesParsed = OnResponse(receiveBuffer, receiveBufferCount, (bytesReceived == 0));
                                        }
                                        else
                                        {
                                            inbound_.Send(receiveBuffer, 0, receiveBufferCount);
                                            bytesParsed = bytesReceived;
                                        }
                                    }

                                    if (bytesParsed > 0)
                                    {
                                        for (int i = 0; i < receiveBuffer.Length - bytesParsed; ++i)
                                        {
                                            receiveBuffer[i] = receiveBuffer[bytesParsed + i];
                                        }
                                        receiveBufferCount -= bytesParsed;
                                    }
                                    else
                                    {
                                        break;
                                    }
                                }

                                if (bytesReceived == 0)
                                {
                                    break;
                                }
                            }
                            else
                            {
                                break;
                            }
                        }
                        else
                        {
                            break;
                        }
                    }
                }
                catch (Exception e)
                {
                    wwwProxy_.OnError(inbound_, null, e, e.Message);
                }
            }

            if (outboundSocket_ != null)
            {
                if (outboundSocket_.Connected)
                {
                    outboundSocket_.Shutdown(SocketShutdown.Both);
                    outboundSocket_.Disconnect(false);
                }
                outboundSocket_.Close();
            }

            if (outboundThreadExitEvent_ != null)
            {
                outboundThreadExitEvent_.Close();
            }
            if (outboundSocketReceiveEvent_ != null)
            {
                outboundSocketReceiveEvent_.Close();
            }
            if (sslNetworkStreamReceiveEvent_ != null)
            {
                sslNetworkStreamReceiveEvent_.Close();
            }

            if (sslNetworkStream_ != null)
            {
                sslNetworkStream_.Close();
            }
            if (sslStream_ != null)
            {
                sslStream_.Close();
            }

            inbound_.OnDisconnect(this);
            if (!completableResponse_)
            {
                response_ = null;

                if (responseCloseInbound_)
                {
                    inbound_.Close();
                }
            }

            if (outboundThread_ != null)
            {
                outboundThread_ = null;
            }
        }
示例#8
0
        ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////

        private int OnResponse(byte[] receiveBuffer, int bytesReceived, bool bConnectionClosed)
        {
            string proxyResponse          = wwwProxy_.defaultEncoding_.GetString(receiveBuffer, 0, bytesReceived);
            int    processedResponseBytes = 0;

            wwwProxy_.log_.Write("Outbound.OnResponse()", proxyResponse);

            string header   = null;
            string contents = null;

            byte[] contentsBytes = null;

            string defaultCharset = "iso-8859-1";
            string charset        = defaultCharset;

            Match httpResponseMatch = Regex.Match(proxyResponse, "^HTTP/\\d\\.\\d\\s+(\\d+)\\s+", RegexOptions.IgnoreCase);

            if (httpResponseMatch.Success)
            {
                ushort httpResponseCode = Convert.ToUInt16(httpResponseMatch.Groups[1].Value);
                if ((httpResponseCode >= 100) && (httpResponseCode <= 199))
                {
                    inbound_.StopKeepAliveTimer();
                    inbound_.Send(receiveBuffer, 0, bytesReceived);
                    processedResponseBytes = bytesReceived;
                }
                else
                {
                    int contentsIndex = 0;

                    for (int i = 0; i < (proxyResponse.Length - 3); ++i)
                    {
                        if ((receiveBuffer[i] == '\r') &&
                            (receiveBuffer[i + 1] == '\n') &&
                            (receiveBuffer[i + 2] == '\r') &&
                            (receiveBuffer[i + 3] == '\n'))
                        {
                            contentsIndex = i + 4;
                            header        = wwwProxy_.defaultEncoding_.GetString(receiveBuffer, 0, i);
                            contentsBytes = new byte[bytesReceived - (contentsIndex)];
                            Array.Copy(receiveBuffer, contentsIndex, contentsBytes, 0, bytesReceived - (contentsIndex));
                            break;
                        }
                    }

                    if (header != null)
                    {
                        Match connectionCloseMatch     = Regex.Match(header, "^(Proxy-)*(Connection)+:\\s+close", RegexOptions.IgnoreCase | RegexOptions.Multiline);
                        Match contentEncodingTypeMatch = Regex.Match(header, "^Content-Type:\\s+\\S+?\\s*;\\s*charset=(\\S+)?", RegexOptions.IgnoreCase | RegexOptions.Multiline);
                        Match contentLengthMatch       = Regex.Match(header, "^Content-Length:\\s+(\\d+)[\r\n]*", RegexOptions.IgnoreCase | RegexOptions.Multiline);
                        Match contentTextTypeMatch     = Regex.Match(header, "^Content-Type:\\s+text|application/x-javascript", RegexOptions.IgnoreCase | RegexOptions.Multiline);
                        Match transferEncodingMatch    = Regex.Match(header, "^Transfer-Encoding:\\s+chunked\\s*[\r\n]*", RegexOptions.IgnoreCase | RegexOptions.Multiline);

                        if (contentEncodingTypeMatch.Success)
                        {
                            charset = contentEncodingTypeMatch.Groups[1].Value.ToLower();
                        }

                        Encoding responseEncoding = null;
                        try
                        {
                            responseEncoding = Encoding.GetEncoding(charset);
                        }
                        catch (ArgumentException)
                        {
                            responseEncoding = wwwProxy_.defaultEncoding_;
                        }

                        if (connectionCloseMatch.Success)
                        {
                            responseCloseInbound_ = true;
                        }

                        completableResponse_ = contentTextTypeMatch.Success || (httpResponseCode >= 300);
                        if (!completableResponse_)
                        {
                            inbound_.StopKeepAliveTimer();
                            inbound_.Send(receiveBuffer, 0, bytesReceived);
                            processedResponseBytes = bytesReceived;
                        }
                        else
                        {
                            if (contentLengthMatch.Success)
                            {
                                int contentsLength = Convert.ToInt32(contentLengthMatch.Groups[1].Value);
                                if (contentsBytes.Length >= contentsLength)
                                {
                                    header = Regex.Replace(header, "^Content-Length:\\s+(\\d+)[ \t]*[\r\n]*", "", RegexOptions.IgnoreCase | RegexOptions.Multiline);
                                    header = header.TrimEnd(" \t\r\n".ToCharArray());

                                    contents = responseEncoding.GetString(contentsBytes, 0, contentsBytes.Length);
                                    processedResponseBytes = contentsIndex + contentsLength;
                                }
                                else
                                {
                                    bytesRequired_ = contentsLength - contentsBytes.Length;
                                }
                            }
                            else if (transferEncodingMatch.Success)
                            {
                                int    deChunkingIndex = 0;
                                byte[] chunkedContents = new byte[contentsBytes.Length];
                                Array.Copy(contentsBytes, chunkedContents, contentsBytes.Length);

                                string deChunkedContents = "";

                                while (true)
                                {
                                    int chunkLengthEnd = -1;
                                    for (int i = deChunkingIndex; i < chunkedContents.Length; ++i)
                                    {
                                        if ((chunkedContents[i] == '\r') && (chunkedContents[i + 1] == '\n'))
                                        {
                                            chunkLengthEnd = i;
                                            break;
                                        }
                                    }
                                    if (chunkLengthEnd != -1)
                                    {
                                        int chunkLength = Convert.ToInt32(responseEncoding.GetString(chunkedContents,
                                                                                                     deChunkingIndex,
                                                                                                     chunkLengthEnd - deChunkingIndex).Trim(), 16);
                                        deChunkingIndex = chunkLengthEnd + 2;

                                        if (chunkLength != 0)
                                        {
                                            if (chunkedContents.Length >= (deChunkingIndex + chunkLength))
                                            {
                                                deChunkedContents += responseEncoding.GetString(chunkedContents, deChunkingIndex, chunkLength);
                                            }
                                            else
                                            {
                                                bytesRequired_    = (deChunkingIndex + chunkLength) - chunkedContents.Length;
                                                deChunkedContents = null;
                                            }
                                        }

                                        deChunkingIndex += chunkLength;
                                        while ((deChunkingIndex < chunkedContents.Length) &&
                                               ((chunkedContents[deChunkingIndex] == '\r') ||
                                                (chunkedContents[deChunkingIndex] == '\n')))
                                        {
                                            deChunkingIndex++;
                                        }

                                        if (chunkLength == 0)
                                        {
                                            break;
                                        }
                                    }
                                    else
                                    {
                                        deChunkedContents = null;
                                        break;
                                    }
                                }

                                if (deChunkedContents != null)
                                {
                                    header   = Regex.Replace(header, "^Transfer-Encoding:\\s+chunked(.*?)[ \t]*[\r\n]*", "", RegexOptions.IgnoreCase | RegexOptions.Multiline);
                                    header   = header.TrimEnd(" \t\r\n".ToCharArray());
                                    contents = deChunkedContents;

                                    processedResponseBytes = contentsIndex + deChunkingIndex;
                                }
                            }
                            else
                            {
                                if (((connectionCloseMatch.Success) && (bConnectionClosed)) || (bConnectionClosed) ||
                                    (httpResponseCode == 204) || (httpResponseCode == 304)) // http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html
                                {
                                    contents = responseEncoding.GetString(contentsBytes, 0, contentsBytes.Length);
                                    processedResponseBytes = bytesReceived;
                                }
                            }
                        }

                        if (processedResponseBytes != 0)
                        {
                            if (completableResponse_)
                            {
                                header = Regex.Replace(header, "^Proxy-Connection:\\s+(.*)?[ \t]*[\r\n]*", "", RegexOptions.IgnoreCase | RegexOptions.Multiline);
                                header = header.TrimEnd(" \t\r\n".ToCharArray());
                            }

                            if ((httpResponseCode == 401) || (httpResponseCode == 407))
                            {
                                if (wwwProxy_.ntlmEnabled_)
                                {
                                    Match urlMatch = Regex.Match(request_.completedHeader_, "([A-Z]+)\\s+(.*?)\\s+HTTP/\\d.\\d\r$", RegexOptions.IgnoreCase | RegexOptions.Multiline);
                                    if (urlMatch.Success)
                                    {
                                        try
                                        {
                                            wwwProxy_.ntlmListMutex_.WaitOne();

                                            string ntlmSite = host_ + ":" + port_;
                                            string ntlmPath = urlMatch.Groups[2].Value;

                                            Match wwwAuthenticateBasicMatch = Regex.Match(header, "^(WWW|Proxy)-Authenticate:\\s+Basic(.*)?[ \t]*[\r\n]*", RegexOptions.IgnoreCase | RegexOptions.Multiline);
                                            if (wwwAuthenticateBasicMatch.Success)
                                            {
                                                List <INtlm> toRemove = new List <INtlm>();
                                                foreach (INtlm w in wwwProxy_.ntlmList_)
                                                {
                                                    if (w.Site == ntlmSite)
                                                    {
                                                        toRemove.Add(w);
                                                    }
                                                }

                                                foreach (INtlm w in toRemove)
                                                {
                                                    wwwProxy_.ntlmList_.Remove(w);
                                                }
                                            }

                                            INtlm wwwProxyNtlm = null;
                                            foreach (INtlm w in wwwProxy_.ntlmList_)
                                            {
                                                if ((w.Site == ntlmSite) && (w.Path == ntlmPath))
                                                {
                                                    wwwProxyNtlm = w;
                                                    break;
                                                }
                                            }

                                            Match wwwAuthenticateNegotiateMatch    = Regex.Match(header, "^(WWW|Proxy)-Authenticate:\\s+Negotiate[ \t]*[\r\n]*", RegexOptions.IgnoreCase | RegexOptions.Multiline);
                                            Match wwwAuthenticateNTLMMatch         = Regex.Match(header, "^(WWW|Proxy)-Authenticate:\\s+NTLM[\r\n]*", RegexOptions.IgnoreCase | RegexOptions.Multiline);
                                            Match wwwAuthenticateNTLMResponseMatch = Regex.Match(header, "^(WWW|Proxy)-Authenticate:\\s+NTLM\\s+([A-Za-z0-9+/=]*)[ \t]*[\r\n]*", RegexOptions.IgnoreCase | RegexOptions.Multiline);

                                            if (wwwAuthenticateNegotiateMatch.Success && wwwAuthenticateNTLMMatch.Success)
                                            {
                                                string authType = wwwAuthenticateNegotiateMatch.Groups[1].Value;

                                                header = Regex.Replace(header,
                                                                       "^(WWW|Proxy)-Authenticate:\\s+Negotiate[ \t]*[\r\n]*",
                                                                       "",
                                                                       RegexOptions.IgnoreCase | RegexOptions.Multiline);
                                                header = Regex.Replace(header,
                                                                       "(^(WWW|Proxy)-Authenticate:\\s+)NTLM[ \t]*([\r\n]*)",
                                                                       "${1}Basic Realm=\"WwwProxy NTLM (" + authType + ")\"${3}",
                                                                       RegexOptions.IgnoreCase | RegexOptions.Multiline);
                                                header = header.TrimEnd(" \t\r\n".ToCharArray());

                                                if (wwwProxyNtlm == null)
                                                {
                                                    wwwProxyNtlm = wwwProxy_.ntlmFactory_.CreateInstance();
                                                    if (wwwProxyNtlm != null)
                                                    {
                                                        wwwProxyNtlm.Site = ntlmSite;
                                                        wwwProxyNtlm.Path = ntlmPath;
                                                        wwwProxyNtlm.Type = authType;
                                                        wwwProxy_.ntlmList_.Add(wwwProxyNtlm);
                                                    }
                                                }
                                                else
                                                {
                                                    wwwProxyNtlm.Reset();
                                                }
                                            }
                                            else if (wwwAuthenticateNTLMResponseMatch.Success)
                                            {
                                                string replacementAuth = "${1}" + wwwProxyNtlm.Continue(wwwAuthenticateNTLMResponseMatch.Groups[2].Value) + "${3}";
                                                request_.completedHeader_ = Regex.Replace(request_.completedHeader_,
                                                                                          "^((Proxy-)*Authorization:\\s+NTLM\\s+)[a-zA-Z0-9=]+[ \t]*([\r\n]*)",
                                                                                          replacementAuth,
                                                                                          RegexOptions.IgnoreCase | RegexOptions.Multiline);
                                                Send(request_);
                                                header = null;
                                            }
                                        }
                                        finally
                                        {
                                            wwwProxy_.ntlmListMutex_.ReleaseMutex();
                                        }
                                    }
                                }
                            }

                            if (header != null)
                            {
                                response_              = new ProxyResponse();
                                response_.encoding_    = responseEncoding;
                                response_.outbound_    = this;
                                response_.request_     = request_;
                                response_.completable_ = completableResponse_;
                                response_.ssl_         = ssl_;
                                response_.header_      = header;
                                response_.contents_    = contents;
                                wwwProxy_.OnResponse(response_);
                            }
                        }
                    }
                }
            }
            else
            {
                inbound_.StopKeepAliveTimer();
                inbound_.Send(receiveBuffer, 0, bytesReceived);
                processedResponseBytes = bytesReceived;

                bytesRequired_   = 0;
                processResponse_ = false;
            }

            return(processedResponseBytes);
        }