/// <summary>
        /// Starts the connection
        /// </summary>
        public virtual void Start()
        {
            _stop = false;
            try
            {
                if (_isSecure)
                {
                    if (!TrySecureStream())
                    {
                        return;
                    }
                }

                // Keep on reading
                IAsyncResult result = ClientStreamWrapper.BeginRead(Buffer, 0, Buffer.Length, new AsyncCallback(OnRead), ClientStreamWrapper);
                if (result == null)
                {
                    ClientStreamWrapper.Close();
                }
            }
            catch (Exception ex)
            {
                HttpServerConsole.Instance.WriteLine("Error starting proxy connection: {0}", ex.Message);
            }
        }
        /// <summary>
        /// Process a CONNECT request
        /// </summary>
        protected void ProcessConnect()
        {
            // Reset request
            _requestBuilder = new ByteArrayBuilder();

            try
            {
                // got a connect
                string response = _requestInfo.HttpVersion + " 200 Connection established\r\nContent-length: 0\r\nProxy-Agent: Traffic Viewer Proxy\r\n\r\n";
                byte[] line     = Constants.DefaultEncoding.GetBytes(response);

                HttpServerConsole.Instance.WriteLine(LogMessageType.Information,
                                                     "Sending response: 200 Connection established for request: {0}", _requestInfo.RequestLine);

                // Give the OK
                if (!TryWriteToStream(line))
                {
                    return;
                }

                if (!TrySecureStream())
                {
                    return;
                }

                // Keep reading on this now encrypted stream
                ClientStreamWrapper.BeginRead(Buffer, 0, Buffer.Length, new AsyncCallback(OnRead), ClientStreamWrapper);
            }
            catch (Exception ex)
            {
                HttpServerConsole.Instance.WriteLine(LogMessageType.Error,
                                                     "SSL Connect failed: {0}", ex.Message);
                ClientStreamWrapper.Close();
            }
        }
 /// <summary>
 /// Stops the proxy
 /// </summary>
 public void Stop()
 {
     _stop = true;
     if (ClientStreamWrapper != null)
     {
         ClientStreamWrapper.Close();
     }
 }
Пример #4
0
 public void Close()
 {
     HttpServerConsole.Instance.WriteLine(LogMessageType.Information,
                                          "Closing upstream and downstream connections");
     ClientStreamWrapper.Close();
     _upStreamConnection.Close();
     _isReading = false;
     IsBusy     = false;
 }
        /// <summary>
        /// Attempts to write to the network stream
        /// </summary>
        /// <param name="bytes"></param>
        /// <returns>true on success</returns>
        private bool TryWriteToStream(byte[] bytes)
        {
            bool success = ClientStreamWrapper.Write(bytes, 0, bytes.Length);

            if (!success)
            {
                ClientStreamWrapper.Close();
            }
            return(success);
        }
Пример #6
0
        /// <summary>
        /// Secures the current connection stream
        /// </summary>
        /// <returns>True if the operation is successful</returns>
        protected override bool TrySecureStream()
        {
            bool success = ClientStreamWrapper.SecureStream(_fwHost);

            if (!success)
            {
                ClientStreamWrapper.Close();
            }
            return(success);
        }
        /// <summary>
        /// Override to change the OnRead behavior
        /// </summary>
        /// <param name="ar"></param>
        protected virtual void OnRead(IAsyncResult ar)
        {
            try
            {
                if (_stop || Closed)
                {
                    return;
                }

                _isBusy = true;
                HttpProxyClientStreamWrapper wrapper = (HttpProxyClientStreamWrapper)ar.AsyncState;
                int bytesRead = 0;

                bytesRead = wrapper.EndRead(ar);

                //we are still connected and we read more bytes

                if (bytesRead > 0)
                {
                    // Append data to the request
                    _requestBuilder.AddChunkReference(Buffer, bytesRead);

                    _requestInfo = new HttpRequestInfo(_requestBuilder.ToArray(), false);

                    if (!_requestInfo.IsFullRequest)
                    {
                        // not finished keep on reading!
                        wrapper.BeginRead(Buffer, 0, Buffer.Length, new AsyncCallback(OnRead), wrapper);
                    }
                    else
                    {
                        lock (_proxyLock)
                        {
                            // Done reading, process the request
                            ProcessRequest();
                        }
                    }
                }
                else
                {
                    //we read 0 bytes
                    _isBusy = _requestBuilder.Length > 0;
                }
            }
            catch (Exception ex)
            {
                ClientStreamWrapper.Close();
                HttpServerConsole.Instance.WriteLine(ex);
            }
        }
        /// <summary>
        /// Secures the current connection stream
        /// </summary>
        /// <returns>True if the operation is successful</returns>
        protected virtual bool TrySecureStream()
        {
            string host = null;

            if (_requestInfo != null)
            {
                host = _requestInfo.Host;
            }
            bool success = ClientStreamWrapper.SecureStream(host);

            if (!success)
            {
                ClientStreamWrapper.Close();
            }
            return(success);
        }
        /// <summary>
        /// Writes a CRWAE message to the client when response is not available from server
        /// </summary>
        /// <param name="statusCode">HTTP status code for the response</param>
        /// <param name="reason">Brief explanation of error</param>
        /// <param name="serviceCode">ID of the CRAWE message</param>
        /// <param name="args">Message args</param>
        protected virtual void ReturnHttpErrorResponse(HttpStatusCode statusCode, string reason, ServiceCode serviceCode, params object [] args)
        {
            byte[] messageBytes = HttpErrorResponse.GenerateHttpErrorResponse(statusCode, reason, serviceCode, args);
            if (!TryWriteToStream(messageBytes))
            {
                return;
            }

            //add the response if we are adding requests to the data source
            if (_currDataStoreRequestInfo != null)
            {
                _currDataStoreRequestInfo.ResponseStatus = statusCode.ToString();
                _currDataStoreRequestInfo.ResponseTime   = DateTime.Now;
                TrafficDataStore.SaveResponse(_currDataStoreRequestInfo.Id, messageBytes);
                _currDataStoreRequestInfo = null;
            }
            ClientStreamWrapper.Close();
        }
        /// <summary>
        /// Writes a response to the client stream
        /// </summary>
        /// <param name="responseInfo"></param>
        protected virtual void ReturnResponse(HttpResponseInfo responseInfo)
        {
            HttpServerConsole.Instance.WriteLine(LogMessageType.Information,
                                                 "Sending response: {0} for request: {1}", responseInfo.StatusLine, _requestInfo.RequestLine);


            if (_currDataStoreRequestInfo != null)
            {
                _currDataStoreRequestInfo.ResponseStatus = responseInfo.Status.ToString();
                _currDataStoreRequestInfo.ResponseTime   = DateTime.Now;
            }

            //process response headers
            if (responseInfo.Status == 401)
            {
                //we need to send the proxy support header/ or overwrite the existing proxy support header
                responseInfo.Headers["Proxy-Support"] = "Session-Based-Authentication";
            }

            //if connection is close disconnect, or if the client sent us a connection close message
            if (String.Compare(responseInfo.Headers[CONNECTION_HEADER], "close", true) == 0 ||
                String.Compare(_requestInfo.Headers[CONNECTION_HEADER], "close", true) == 0)
            {
                _isClose = true;
            }

            byte[] responseHead = HandleResponseByteChunk(responseInfo.ResponseHead);

            if (!TryWriteToStream(responseHead))
            {
                return;
            }
            ;

            // Return the substitute response body
            if (responseInfo.ResponseBody.IsChunked)
            {
                byte[] chunk;
                byte[] chunkBuf;
                while ((chunk = responseInfo.ResponseBody.ReadChunk()) != null)
                {
                    //write the chunk size line
                    chunkBuf = Constants.DefaultEncoding.GetBytes(String.Format("{0:x}\r\n", chunk.Length));
                    chunkBuf = HandleResponseByteChunk(chunkBuf);
                    if (!TryWriteToStream(chunkBuf))
                    {
                        return;
                    }
                    //write the chunk
                    chunk = HandleResponseByteChunk(chunk);
                    if (!TryWriteToStream(chunk))
                    {
                        return;
                    }
                    chunkBuf = Constants.DefaultEncoding.GetBytes("\r\n");
                    chunkBuf = HandleResponseByteChunk(chunkBuf);
                    if (!TryWriteToStream(chunkBuf))
                    {
                        return;
                    }
                }
                //write a last chunk with the value 0
                // write the last chunk size
                chunkBuf = Constants.DefaultEncoding.GetBytes("0\r\n\r\n");
                chunkBuf = HandleResponseByteChunk(chunkBuf);
                if (!TryWriteToStream(chunkBuf))
                {
                    return;
                }
            }
            else
            {
                byte[] buffer = responseInfo.ResponseBody.ToArray();
                if (buffer != null)
                {
                    buffer = HandleResponseByteChunk(buffer);
                    if (!TryWriteToStream(buffer))
                    {
                        return;
                    }
                }
            }


            //cleanup the request info
            _requestBuilder = new ByteArrayBuilder();

            if (_currDataStoreRequestInfo != null)
            {
                TrafficDataStore.SaveResponse(_currDataStoreRequestInfo.Id, _currentRequestResponseBytes);
            }

            _currDataStoreRequestInfo    = null;
            _currentRequestResponseBytes = null;

            //close the connection if the request had a connection close header
            if (_isClose)
            {
                ClientStreamWrapper.Close();
            }
            else
            {
                _isBusy = false;
                ClientStreamWrapper.BeginRead(Buffer, 0, Buffer.Length, new AsyncCallback(OnRead), ClientStreamWrapper);
            }
        }