/// <summary>
		/// Initializes a new instance of the <see cref="HttpClientContext"/> class.
        /// </summary>
        /// <param name="secured">true if the connection is secured (SSL/TLS)</param>
        /// <param name="remoteEndPoint">client that connected.</param>
        /// <param name="stream">Stream used for communication</param>
        /// <param name="clientCertificate">Client security certificate</param>
        /// <param name="parserFactory">Used to create a <see cref="IHttpRequestParser"/>.</param>
        /// <param name="bufferSize">Size of buffer to use when reading data. Must be at least 4096 bytes.</param>
        /// <param name="socket">Client socket</param>
        /// <exception cref="SocketException">If <see cref="Socket.BeginReceive(byte[],int,int,SocketFlags,AsyncCallback,object)"/> fails</exception>
        /// <exception cref="ArgumentException">Stream must be writable and readable.</exception>
        public HttpClientContext(bool secured, IPEndPoint remoteEndPoint, Stream stream, 
            ClientCertificate clientCertificate, IRequestParserFactory parserFactory, int bufferSize, Socket socket)
        {
            Check.Require(remoteEndPoint, "remoteEndPoint");
            Check.NotEmpty(remoteEndPoint.Address.ToString(), "remoteEndPoint.Address");
            Check.Require(stream, "stream");
            Check.Require(parserFactory, "parser");
            Check.Min(4096, bufferSize, "bufferSize");
            Check.Require(socket, "socket");

            if (!stream.CanWrite || !stream.CanRead)
                throw new ArgumentException("Stream must be writable and readable.");

            _bufferSize = bufferSize;
			RemoteAddress = remoteEndPoint.Address.ToString();
			RemotePort = remoteEndPoint.Port.ToString();
            _log = NullLogWriter.Instance;
            _parser = parserFactory.CreateParser(_log);
            _parser.RequestCompleted += OnRequestCompleted;
            _parser.RequestLineReceived += OnRequestLine;
            _parser.HeaderReceived += OnHeaderReceived;
            _parser.BodyBytesReceived += OnBodyBytesReceived;
        	_localEndPoint = (IPEndPoint)socket.LocalEndPoint;

            HttpRequest request = new HttpRequest();
            request._remoteEndPoint = remoteEndPoint;
            request.Secure = secured;
            _currentRequest = request;

            IsSecured = secured;
            _stream = stream;
            _clientCertificate = clientCertificate;
            _buffer = new byte[bufferSize];

        }
Esempio n. 2
0
        /// <summary>
        /// Create a new context.
        /// </summary>
        /// <param name="isSecured">true if socket is running HTTPS.</param>
        /// <param name="endPoint">Client that connected</param>
        /// <param name="clientCertificate">Client security certificate</param>
        /// <param name="stream">Network/SSL stream.</param>
        /// <param name="socket">Client socket</param>
        /// <returns>A context.</returns>
        protected HttpClientContext CreateContext(bool isSecured, IPEndPoint endPoint, ClientCertificate clientCertificate, Stream stream, Socket socket)
        {
        	HttpClientContext context;
            lock (_contextQueue)
            {
                if (_contextQueue.Count > 0)
                {
                    context = _contextQueue.Dequeue();
                    if (!context.IsAvailable)
                    {
                        context = CreateNewContext(isSecured, endPoint, clientCertificate, stream, socket);
                        context.Disconnected += OnFreeContext;
                        context.RequestReceived += OnRequestReceived;
                        context.EndWhenDone = true;
                        
                    }
                }
                else
                {
                    context = CreateNewContext(isSecured, endPoint, clientCertificate, stream, socket);
                    context.Disconnected += OnFreeContext;
                    context.RequestReceived += OnRequestReceived;
                }
            }

        	context.Assign(stream, (IPEndPoint)socket.LocalEndPoint);
			context.IsSecured = isSecured;
			context.RemotePort = endPoint.Port.ToString();
			context.RemoteAddress = endPoint.Address.ToString();
			context.Start();
            return context;
        }
        /// <summary>
        /// Create a new context.
        /// </summary>
        /// <param name="isSecured">true if socket is running HTTPS.</param>
        /// <param name="endPoint">Client that connected</param>
        /// <param name="clientCertificate">Client security certificate</param>
        /// <param name="stream">Network/SSL stream.</param>
        /// <returns>A context.</returns>
        protected HttpClientContextImp CreateContext(bool isSecured, IPEndPoint endPoint, ClientCertificate clientCertificate, Stream stream)
        {
        	HttpClientContextImp context;
            lock (_contextQueue)
            {
				if (_contextQueue.Count > 0)
					context = _contextQueue.Dequeue();
				else
				{
					context = CreateNewContext(isSecured, endPoint, clientCertificate, stream);
					context.Disconnected += OnFreeContext;
					context.RequestReceived += OnRequestReceived;
				}
            }

        	context.Stream = stream;
			context.IsSecured = isSecured;
			context.Start();
            return context;
        }
		/// <summary>
		/// Create a new context.
		/// </summary>
		/// <param name="isSecured">true if HTTPS is used.</param>
		/// <param name="endPoint">Remote client</param>
        /// <param name="clientCertificate">Client security certificate</param>
		/// <param name="stream">Network stream, <see cref="HttpClientContextImp"/> uses <see cref="ReusableSocketNetworkStream"/>.</param>
		/// <returns>A new context (always).</returns>
    	protected virtual HttpClientContextImp CreateNewContext(bool isSecured, IPEndPoint endPoint, ClientCertificate clientCertificate, Stream stream)
    	{
    		return new HttpClientContextImp(isSecured, endPoint, stream, clientCertificate, _factory, _bufferSize, _logWriter);
    	}
        /// <summary>
        /// Create a secure <see cref="IHttpClientContext"/>.
        /// </summary>
        /// <param name="socket">Client socket (accepted by the <see cref="HttpListener"/>).</param>
        /// <param name="certificate">HTTPS certificate to use.</param>
        /// <param name="protocol">Kind of HTTPS protocol. Usually TLS or SSL.</param>
        /// <param name="requireClientCert">Require an SSL client certificate</param>
        /// <returns>
        /// A created <see cref="IHttpClientContext"/>.
        /// </returns>
        public IHttpClientContext CreateSecureContext(Socket socket, X509Certificate certificate, SslProtocols protocol, bool requireClientCert)
        {
			var networkStream = new ReusableSocketNetworkStream(socket, true);
            var remoteEndPoint = (IPEndPoint) socket.RemoteEndPoint;

            ClientCertificate clientCertificate = null;

            SslStream sslStream = new SslStream(networkStream, false,
                delegate(object sender, X509Certificate receivedCertificate, X509Chain chain, SslPolicyErrors sslPolicyErrors)
                {
                    clientCertificate = new ClientCertificate(receivedCertificate, chain, sslPolicyErrors);
                    return !(requireClientCert && receivedCertificate == null);
                }
            );

            try
            {
                sslStream.AuthenticateAsServer(certificate, requireClientCert, protocol, false);
                return CreateContext(true, remoteEndPoint, clientCertificate, sslStream);
            }
            catch (IOException err)
            {
                if (UseTraceLogs)
                    _logWriter.Write(this, LogPrio.Trace, err.Message);
            }
            catch (ObjectDisposedException err)
            {
                if (UseTraceLogs)
                    _logWriter.Write(this, LogPrio.Trace, err.Message);
            }
            catch (AuthenticationException err)
            {
                if (UseTraceLogs)
                    _logWriter.Write(this, LogPrio.Warning, (err.InnerException != null) ? err.InnerException.Message : err.Message);
            }

            return null;
        }
Esempio n. 6
0
		/// <summary>
		/// Create a new context.
		/// </summary>
		/// <param name="isSecured">true if HTTPS is used.</param>
		/// <param name="endPoint">Remote client</param>
        /// <param name="clientCertificate">Client security certificate</param>
		/// <param name="stream">Network stream, <see cref="HttpClientContext"/> uses <see cref="ReusableSocketNetworkStream"/>.</param>
        /// <param name="socket">Client socket</param>
		/// <returns>A new context (always).</returns>
    	protected virtual HttpClientContext CreateNewContext(bool isSecured, IPEndPoint endPoint, ClientCertificate clientCertificate,
            Stream stream, Socket socket)
    	{
    		return new HttpClientContext(isSecured, endPoint, stream, clientCertificate, _factory, _bufferSize, socket);
    	}