Ejemplo n.º 1
0
        private ProxyToken HandleOtherRequest(HttpRequestHeader header, DataAdapterToStream stm, TcpClientDataAdapter tcpAdapter)
        {
            string host = null;

            foreach (KeyDataPair<string> pair in header.Headers)
            {
                if (pair.Name.Equals("host", StringComparison.OrdinalIgnoreCase))
                {
                    host = pair.Value;
                }
            }

            Uri url = GetUri(host, tcpAdapter);

            if (url != null)
            {
                // Use generic token so filters don't get used
                IpProxyToken ret = new IpProxyToken(null, url.Host, url.Port, IpProxyToken.IpClientType.Tcp, false);

                if(_config.SslConfig.Enabled)
                {
                    ret.Layers = new INetworkLayer[1];
                    ret.Layers[0] = new SslNetworkLayer(new SslNetworkLayerConfig(false, true) { Enabled = true });
                }

                ret.State.Add("url", url);
                ret.State.Add("stm", stm);
                ret.State.Add("header", header);

                return ret;
            }
            else
            {
                _logger.LogError(CANAPE.Net.Properties.Resources.HttpProxyServer_InvalidUrl, header.Path);

                ReturnResponse(null, 400, "Bad Request", header.Method, header.Version, stm);

                return null;
            }
        }
Ejemplo n.º 2
0
 private void ReturnResponse(HttpRequestHeader request, int responseCode, string message, string method, HttpVersion version, DataAdapterToStream stm)
 {
     ReturnResponse(request, responseCode, message, method, version, new KeyDataPair<string>[0], stm);
 }
Ejemplo n.º 3
0
 internal HttpRequestDataChunk(HttpRequestHeader header)
     : base(header.Headers, header.Version)
 {
     Method = header.Method;
     Path = header.Path;
 }
Ejemplo n.º 4
0
        private void FlushRequest(HttpRequestHeader request)
        {
            if (!request.IsConnect)
            {
                HttpParserConfig config = new HttpParserConfig();
                config.StreamBody = true;

                IEnumerator<HttpRequestDataChunk> e = request.ReadChunks(config).GetEnumerator();
                while (e.MoveNext())
                {
                }
            }
        }
Ejemplo n.º 5
0
        /// <summary>
        /// 
        /// </summary>
        /// <param name="request"></param>
        /// <param name="response"></param>
        /// <returns></returns>
        public bool IsMatch(HttpRequestHeader request, HttpResponseHeader response)
        {
            if (IsMatch(request))
            {
                foreach (KeyDataPair<string> pair in response.Headers)
                {
                    if(pair.Name.Equals("Content-Type", StringComparison.OrdinalIgnoreCase))
                    {
                        return ContentTypeMatch.IsMatch(pair.Value);
                    }
                }
            }

            return false;
        }
Ejemplo n.º 6
0
            private HttpParserConfig CreateConfig(HttpRequestHeader header)
            {
                HttpParserConfig config = new HttpParserConfig();

                HttpLayerConfigEntry entry = _layer._config.GetEntry(header);

                config.StreamBody = entry.RequestStreamBody;
                config.StreamChunkSize = _layer._config.RequestStreamChunkSize;
                config.StrictParsing = _layer._config.RequestStrictParsing;

                if (_layer._config.BufferedRequestMaxLength != 0 && (header.ContentLength > _layer._config.BufferedRequestMaxLength))
                {
                    config.StreamBody = true;
                }

                return config;
            }
Ejemplo n.º 7
0
            public HttpProxyServerAdapter(FullHttpProxyServer server, DataAdapterToStream stm, HttpRequestHeader initialRequest, Logger logger)
            {
                _server = server;
                _stm = stm;
                _writer = new DataWriter(_stm);
                _request = initialRequest;
                ProcessProxyRequestHeaders(_request);
                _config = new HttpParserConfig();
                _config.StreamBody = true;
                _logger = logger;
                _requestQueue = new Queue<HttpRequestHeader>();
                _requestQueue.Enqueue(_request);

                Description = stm.Description;
            }
Ejemplo n.º 8
0
            public override DataFrame Read()
            {
                try
                {
                    if (_request == null)
                    {
                        _request = HttpParser.ReadRequestHeader(new DataReader(_stm), false, _logger);
                    }

                    if (_chunks == null)
                    {
                        _chunks = _request.ReadChunks(_config).GetEnumerator();

                        // If we can't move to the first chunk (headers) there is a serious issue
                        if (!_chunks.MoveNext())
                        {
                            throw new EndOfStreamException();
                        }
                    }

                    HttpRequestDataChunk chunk = _chunks.Current;

                    if (!_chunks.MoveNext())
                    {
                        _request = null;
                        _chunks = null;
                    }

                    MemoryStream stm = new MemoryStream();
                    DataWriter writer = new DataWriter(stm);

                    chunk.WriteChunk(writer);

                    return new DataFrame(stm.ToArray());
                }
                catch (EndOfStreamException)
                {
                    return null;
                }
            }
Ejemplo n.º 9
0
 private bool MustCloseConnection(HttpRequestHeader request)
 {
     return request.Version.IsVersion10
         || request.Version.IsVersionUnknown
         || _config.Version10Proxy
         || request.Headers.HasHeader("Connection", "close")
         || request.Headers.HasHeader("Proxy-Connection", "close");
 }
Ejemplo n.º 10
0
        private bool ProcessProxyAuth(HttpRequestHeader request)
        {
            bool ret = false;

            if (_config.RequireAuth)
            {
                if (request.Headers.HasHeader("Proxy-Authorization"))
                {
                    string[] values = request.Headers.GetHeaderValues("Proxy-Authorization").First().Split(new char[] { ' ' }, 2);

                    if (values.Length == 2)
                    {
                        if (values[0].Equals("Basic", StringComparison.OrdinalIgnoreCase))
                        {
                            try
                            {
                                string data = BinaryEncoding.Instance.GetString(Convert.FromBase64String(values[1]));

                                string[] vs = data.Split(new char[] { ':' }, 2);
                                if ((vs.Length == 0) || (String.IsNullOrWhiteSpace(vs[0])))
                                {
                                    _logger.LogError(Properties.Resources.FullHttpProxyServer_InvalidUsernamePasswordString);
                                }
                                else
                                {
                                    // Username case-insensitive, password case sensitive
                                    ret = vs[0].Equals(_config.ProxyUsername, StringComparison.OrdinalIgnoreCase)
                                        && _config.ProxyPassword.Equals(vs.Length > 1 ? vs[1] : String.Empty);
                                }
                            }
                            catch (FormatException)
                            {
                                _logger.LogError(Properties.Resources.FullHttpProxyServer_InvalidBase64Auth);
                            }
                        }
                        else
                        {
                            _logger.LogError(Properties.Resources.FullHttpProxyServer_OnlySupportBasicAuth);
                        }
                    }
                    else
                    {
                        _logger.LogError(Properties.Resources.FullHttpProxyServer_InvalidAuthLine);
                    }
                }
            }
            else
            {
                ret = true;
            }

            return ret;
        }
Ejemplo n.º 11
0
        private bool HandleProxyAuthentication(DataReader reader, DataAdapterToStream stm, ref HttpRequestHeader request)
        {
            if (_config.RequireAuth)
            {
                bool auth = ProcessProxyAuth(request);

                if (!auth)
                {
                    ReturnResponse(request, 407, "Proxy Authentication Required", request.Method, request.Version,
                        new KeyDataPair<string>[] { new KeyDataPair<string>("Proxy-Authenticate",
                            String.Format("Basic realm=\"{0}\"", _config.AuthRealm ?? "canape.local")) }, stm);

                    if (!MustCloseConnection(request))
                    {
                        // If version 1.1 server we can assume connection will probably stay up so re-read request
                        // Only give it one chance to get it right though
                        request = HttpParser.ReadRequestHeader(reader, false, _logger);

                        auth = ProcessProxyAuth(request);
                    }
                }

                return auth;
            }
            else
            {
                return true;
            }
        }
Ejemplo n.º 12
0
        private ProxyToken HandleOtherRequest(HttpRequestHeader header, DataAdapterToStream stm, ProxyNetworkService service)
        {
            Uri url;

            if (Uri.TryCreate(header.Path, UriKind.Absolute, out url))
            {
                // Use generic token so filters don't get used
                ProxyToken ret = new ProxyToken();

                ret.State.Add("url", url);
                ret.State.Add("stm", stm);
                ret.State.Add("header", header);

                ret.Client = new HttpProxyDummyClient(this, service);
                ret.Graph = _factory;

                return ret;
            }
            else
            {
                _logger.LogError(CANAPE.Net.Properties.Resources.HttpProxyServer_InvalidUrl, header.Path);

                // TODO: Put in some decent error codes
                ReturnResponse(null, 400, "Bad Request", header.Method, header.Version, stm);

                return null;
            }
        }
Ejemplo n.º 13
0
        private IpProxyToken HandleConnect(HttpRequestHeader header, DataAdapterToStream stm)
        {
            string hostName = null;
            int port = 80;
            string[] connectHeader = header.Path.Split(':');
            IpProxyToken ret = null;

            if (connectHeader.Length > 0)
            {
                hostName = connectHeader[0];
                if (connectHeader.Length > 1)
                {
                    if (!int.TryParse(connectHeader[1], out port))
                    {
                        _logger.LogError(CANAPE.Net.Properties.Resources.HttpProxyServer_InvalidConnect, connectHeader[1]);
                        port = 0;
                    }
                }

                if (port > 0)
                {
                    ret = new IpProxyToken(null, hostName, port, IpProxyToken.IpClientType.Tcp, false);

                    ret.State.Add("stm", stm);
                    ret.State.Add("header", header);
                }
                else
                {
                    ReturnResponse(null, 400, "Bad Request", header.Method, header.Version, stm);
                }
            }

            return ret;
        }
Ejemplo n.º 14
0
        private void ReturnResponse(HttpRequestHeader request, int responseCode, string message, string method, HttpVersion version, IEnumerable<KeyDataPair<string>> sendHeaders, DataAdapterToStream stm)
        {
            if (request != null)
            {
                FlushRequest(request);
            }

            HttpResponseDataChunk response = new HttpResponseDataChunk();

            if (_config.Version10Proxy && !version.IsVersionUnknown)
            {
                response.Version = HttpVersion.Version10;
            }
            else
            {
                response.Version = version;
            }

            response.ResponseCode = responseCode;
            response.Message = message;
            response.FinalChunk = true;
            response.Body = new byte[0];

            List<KeyDataPair<string>> headers = new List<KeyDataPair<string>>(sendHeaders);

            headers.Add(new KeyDataPair<string>("X-Proxy-Server", "CANAPE"));

            if (response.Body.Length > 0)
            {
                headers.Add(new KeyDataPair<string>("Content-Type", "text/html"));
            }

            response.Headers = headers.ToArray();

            if (method.Equals("HEAD", StringComparison.OrdinalIgnoreCase))
            {
                response.HeadResponse = true;
            }
            else if (method.Equals("CONNECT", StringComparison.OrdinalIgnoreCase))
            {
                response.ConnectResponse = true;
            }

            response.WriteChunk(new DataWriter(stm));
        }
Ejemplo n.º 15
0
            public override DataFrame Read()
            {
                try
                {
                    if(_request == null)
                    {
                        _request = HttpParser.ReadRequestHeader(new DataReader(_stm), false, _logger);

                        lock (_requestQueue)
                        {
                            _requestQueue.Enqueue(_request);
                        }

                        ProcessProxyRequestHeaders(_request);
                    }

                    if (_chunks == null)
                    {
                        _chunks = _request.ReadChunks(_config).GetEnumerator();

                        // If we can't move to the first chunk (headers) there is a serious issue
                        if (!_chunks.MoveNext())
                        {
                            throw new EndOfStreamException();
                        }
                    }

                    HttpRequestDataChunk chunk = _chunks.Current;

                    if (!_chunks.MoveNext())
                    {
                        _request = null;
                        _chunks = null;
                    }

                    DataKey root = new DataKey("Root");
                    root.AddValue(new DynamicDataValue(DATA_NAME, chunk));
                    return new DataFrame(root);
                }
                catch (EndOfStreamException)
                {
                    return null;
                }
            }
Ejemplo n.º 16
0
            public HttpProxyServerAdapter(DataAdapterToStream stm, HttpRequestHeader initialRequest, Logger logger)
            {
                _stm = stm;
                _writer = new DataWriter(_stm);
                _request = initialRequest;
                _config = new HttpParserConfig();
                _config.StreamBody = true;
                _logger = logger;

                Description = stm.Description;
            }
Ejemplo n.º 17
0
            private void ProcessProxyRequestHeaders(HttpRequestHeader request)
            {
                int i = 0;

                // If we have a request for a client version which will close then ensure the job is done
                if (request.Version.IsVersionUnknown || request.Version.IsVersion10 || _server._config.Version10Proxy)
                {
                    _closeConnection = true;
                }

                while(i < request.Headers.Count)
                {
                    KeyDataPair<string> pair = request.Headers[i];

                    // Just remove, we already have handled this
                    if (pair.Name.Equals("Proxy-Authorization", StringComparison.OrdinalIgnoreCase))
                    {
                        request.Headers.RemoveAt(i);
                    }
                    else if (pair.Name.Equals("Connection", StringComparison.OrdinalIgnoreCase)
                        || pair.Name.Equals("Proxy-Connection", StringComparison.OrdinalIgnoreCase))
                    {
                        // If sender wants the connection close then signal it for next response
                        if (pair.Value.Equals("close", StringComparison.OrdinalIgnoreCase))
                        {
                            _closeConnection = true;
                        }

                        request.Headers.RemoveAt(i);
                    }
                    else
                    {
                        ++i;
                    }
                }
            }
Ejemplo n.º 18
0
        /// <summary>
        /// Does this entry match the request
        /// </summary>
        /// <param name="request">The request</param>
        /// <returns>True if it matches</returns>
        public bool IsMatch(HttpRequestHeader request)
        {
            bool ret = true;

            if (request != null)
            {
                if (!PathMatch.IsMatch(request.Path))
                {
                    ret = false;
                }

                if (MethodMatch.IsMatch(request.Method))
                {
                    ret = false;
                }
            }

            return ret;
        }
Ejemplo n.º 19
0
 /// <summary>
 /// 
 /// </summary>
 /// <param name="request"></param>
 /// <returns></returns>
 public HttpLayerConfigEntry GetEntry(HttpRequestHeader request)
 {
     return GetEntry(e => e.IsMatch(request));
 }
Ejemplo n.º 20
0
            public override DataFrame Read()
            {
                DataFrame frame = null;

                try
                {
                    if (_chunks == null || !_chunks.MoveNext())
                    {
                        char firstChar = _reader.ReadChar();

                        // Check whether we need to upgrade the connection to raw data, could even at this point actually implement
                        // TLS upgrade (and put back the HTTP parser on top?)
                        if (_isTransparent)
                        {
                            // If transparent send the first chunk along and don't increment enumerator
                            _chunks = BaseHttpDataAdapter.ReadFrames(new DataFrame(new byte[] { (byte)firstChar }), _reader).GetEnumerator();
                        }
                        else
                        {
                            _currentHeader = HttpParser.ReadRequestHeader(_reader, _layer._config.RequestStrictParsing, _logger, new char[] { firstChar });

                            if (_currentHeader.Version.IsVersion11 && _layer._config.Handle100Continue)
                            {
                                bool sendResponse = false;

                                int i = 0;

                                while(i < _currentHeader.Headers.Count)
                                {
                                    KeyDataPair<string> header = _currentHeader.Headers[i];

                                    // Remove expect headers
                                    if (header.Name.Equals("Expect", StringComparison.OrdinalIgnoreCase) && header.Value.Equals("100-continue", StringComparison.OrdinalIgnoreCase))
                                    {
                                        _currentHeader.Headers.RemoveAt(i);
                                        sendResponse = true;
                                    }
                                    else
                                    {
                                        i++;
                                    }
                                }

                                if (sendResponse)
                                {
                                    _adapter.Write(new DataFrame("HTTP/1.1 100 Continue\r\n\r\n"));
                                }
                            }

                            _chunks = _currentHeader.ReadFrames(CreateConfig(_currentHeader)).GetEnumerator();
                        }

                        // Increment to next chunk
                        if (!_chunks.MoveNext())
                        {
                            throw new EndOfStreamException();
                        }
                    }

                    frame = _chunks.Current;
                }
                catch(EndOfStreamException)
                {
                    frame = null;
                }

                return frame;
            }
Ejemplo n.º 21
0
 /// <summary>
 /// 
 /// </summary>
 /// <param name="request"></param>
 /// <param name="response"></param>
 /// <returns></returns>
 public HttpLayerConfigEntry GetEntry(HttpRequestHeader request, HttpResponseHeader response)
 {
     return GetEntry(e => e.IsMatch(request, response));
 }
Ejemplo n.º 22
0
            private HttpParserConfig CreateConfig(HttpResponseHeader response, HttpRequestHeader request)
            {
                HttpParserConfig config = new HttpParserConfig();

                HttpLayerConfigEntry entry = _layer._config.GetEntry(request, response);

                config.ConvertToChunked = entry.ConvertToChunked;
                config.StreamBody = entry.ResponseStreamBody;
                config.StreamChunkSize = _layer._config.ResponseStreamChunkSize;
                config.StrictParsing = _layer._config.ResponseStrictParsing;

                if (_layer._config.BufferedResponseMaxLength != 0 && (response.ContentLength > _layer._config.BufferedResponseMaxLength))
                {
                    config.StreamBody = true;
                }

                return config;
            }
Ejemplo n.º 23
0
 internal HttpRequestDataChunk(HttpRequestHeader header)
     : base(header.Headers, header.Version)
 {
     Method = header.Method;
     Path   = header.Path;
 }