Пример #1
0
        // We've found a CRLFCRLF sequence.  Confirm the status code is 101 for upgrade.
        private HandshakeResponse InspectHanshake(byte[] buffer, int split, int limit)
        {
            var handshake = new HandshakeResponse
            {
                ResponseBytes = new ArraySegment <byte>(buffer, 0, split),
                ExtraData     = new ArraySegment <byte>(buffer, split, limit),
            };
            // Must be at least "HTTP/1.1 101\r\nConnection: Upgrade\r\nUpgrade: HTTP/2.0\r\n\r\n"
            string response = FrameHelpers.GetAsciiAt(buffer, 0, split);

            if (_end == ConnectionEnd.Client)
            {
                if (response.StartsWith("HTTP/1.1 101 SWITCHING PROTOCOLS", StringComparison.OrdinalIgnoreCase) &&
                    response.IndexOf("\r\nCONNECTION: UPGRADE\r\n", StringComparison.OrdinalIgnoreCase) >= 0 &&
                    response.IndexOf(string.Format("\r\nUPGRADE: {0}\r\n", Protocols.Http2), StringComparison.OrdinalIgnoreCase) >= 0)
                {
                    handshake.Result = HandshakeResult.Upgrade;
                }
                else
                {
                    handshake.Result = HandshakeResult.NonUpgrade;
                }
            }
            else
            {
                if (response.IndexOf("\r\nCONNECTION: UPGRADE, HTTP2-SETTINGS\r\n", StringComparison.OrdinalIgnoreCase) >= 0 &&
                    response.IndexOf(string.Format("\r\nUPGRADE: {0}\r\n", Protocols.Http2), StringComparison.OrdinalIgnoreCase) >= 0 &&
                    response.IndexOf("\r\nHTTP2-SETTINGS:", StringComparison.OrdinalIgnoreCase) >= 0)
                {
                    GetHeaders(response);
                    handshake.Result = HandshakeResult.Upgrade;
                }
                else
                {
                    handshake.Result = HandshakeResult.NonUpgrade;
                }
            }

            return(handshake);
        }
Пример #2
0
        public IDictionary<string, object> Handshake()
        {
            var response = new HandshakeResponse();
            _readThread = new Thread((object state) =>
                {
                    var handle = state as EventWaitHandle;

                    try
                    {
                        response = Read11Headers();
                        _wasResponseReceived = true;
                        if (handle != null) handle.Set();
                    }
                    catch (Exception ex)
                    {
                        Http2Logger.LogError(ex.Message);

                        // singal that there is an error
                        if (handle != null) handle.Set();
                        _error = ex;
                        throw;
                    }
                });

            _readThread.IsBackground = true;
            _readThread.Start(_responseReceivedRaised);

            if (_end == ConnectionEnd.Client)
            {
                // Build the request
                var builder = new StringBuilder();
                builder.AppendFormat("{0} {1} {2}\r\n", "GET", _headers[":path"], "HTTP/1.1");
                //TODO pass here requested filename
                builder.AppendFormat("Host: {0}\r\n", _headers[":host"]);
                builder.Append("Connection: Upgrade, Http2-Settings\r\n");
                builder.Append("Upgrade: HTTP-DRAFT-04/2.0\r\n");
                builder.Append("Http2-Settings: ");
                //TODO check out how to send window size and max_conc_streams

                if (_headers != null)
                {
                    var http2Settings = new StringBuilder();
                    foreach (var key in _headers.Keys)
                    {
                        if (!string.Equals(":path", key, StringComparison.OrdinalIgnoreCase))
                            http2Settings.AppendFormat("{0}: {1}\r\n", key, _headers[key]);
                    }
                    byte[] settingsBytes = Encoding.UTF8.GetBytes(http2Settings.ToString());
                    builder.Append(Convert.ToBase64String(settingsBytes));
                }
                builder.Append("\r\n\r\n");
                byte[] requestBytes = Encoding.UTF8.GetBytes(builder.ToString());
                _handshakeResult = new Dictionary<string, object>(_headers) {{":method", "get"}};
                InternalSocket.Send(requestBytes, 0, requestBytes.Length, SocketFlags.None);

                _responseReceivedRaised.WaitOne(Timeout);
                _responseReceivedRaised.Dispose();
            }
            else
            {
                _responseReceivedRaised.WaitOne(Timeout);
                _responseReceivedRaised.Dispose();

                if (response.Result == HandshakeResult.Upgrade)
                {
                    const string status = "101";
                    const string protocol = "HTTP/1.1";
                    const string postfix = "Switching Protocols";

                    var builder = new StringBuilder();
                    builder.AppendFormat("{0} {1} {2}\r\n", protocol, status, postfix);
                    builder.Append("Connection: Upgrade\r\n");
                    builder.Append("Upgrade: HTTP-draft-04/2.0\r\n");
                    builder.Append("\r\n");

                    byte[] requestBytes = Encoding.ASCII.GetBytes(builder.ToString());
                    InternalSocket.Send(requestBytes, 0, requestBytes.Length, SocketFlags.None);
                }
            }

            if (!_wasResponseReceived)
            {
                if (_readThread.IsAlive)
                {
                    _readThread.Abort();
                    _readThread.Join();
                }
                throw new Http2HandshakeFailed(HandshakeFailureReason.Timeout);
            }

            if (_error != null)
            {
                throw _error;
            }

            if (response.Result != HandshakeResult.Upgrade)
            {
                throw new Http2HandshakeFailed(HandshakeFailureReason.InternalError);
            }

            if (_readThread.IsAlive)
            {
                _readThread.Abort();
            }
            _readThread.Join();

            return _handshakeResult;
        }
Пример #3
0
        // We've found a CRLFCRLF sequence.  Confirm the status code is 101 for upgrade.
        private HandshakeResponse InspectHanshake(byte[] buffer, int split, int limit)
        {
            var handshake = new HandshakeResponse
                {
                    ResponseBytes = new ArraySegment<byte>(buffer, 0, split),
                    ExtraData = new ArraySegment<byte>(buffer, split, limit),
                };
            // Must be at least "HTTP/1.1 101\r\nConnection: Upgrade\r\nUpgrade: HTTP/2.0\r\n\r\n"
            string response = FrameHelpers.GetAsciiAt(buffer, 0, split);
            if (_end == ConnectionEnd.Client)
            {
                if (response.StartsWith("HTTP/1.1 101 SWITCHING PROTOCOLS", StringComparison.OrdinalIgnoreCase)
                    && response.IndexOf("\r\nCONNECTION: UPGRADE\r\n", StringComparison.OrdinalIgnoreCase) >= 0
                    && response.IndexOf(string.Format("\r\nUPGRADE: {0}\r\n", Protocols.Http2), StringComparison.OrdinalIgnoreCase) >= 0)
                {
                    handshake.Result = HandshakeResult.Upgrade;
                }
                else
                {
                    handshake.Result = HandshakeResult.NonUpgrade;
                }
            }
            else
            {
                if (response.IndexOf("\r\nCONNECTION: UPGRADE, HTTP2-SETTINGS\r\n", StringComparison.OrdinalIgnoreCase) >= 0
                    && response.IndexOf(string.Format("\r\nUPGRADE: {0}\r\n", Protocols.Http2), StringComparison.OrdinalIgnoreCase) >= 0
                    && response.IndexOf("\r\nHTTP2-SETTINGS:", StringComparison.OrdinalIgnoreCase) >= 0)
                {
                    GetHeaders(response);
                    handshake.Result = HandshakeResult.Upgrade;
                }
                else
                {
                    handshake.Result = HandshakeResult.NonUpgrade;
                }
            }

            return handshake;
        }
Пример #4
0
        public IDictionary <string, object> Handshake()
        {
            var response = new HandshakeResponse();

            _readThread = new Thread((object state) =>
            {
                var handle = state as EventWaitHandle;

                try
                {
                    response             = Read11Headers();
                    _wasResponseReceived = true;
                    if (handle != null)
                    {
                        handle.Set();
                    }
                }
                catch (Exception ex)
                {
                    Http2Logger.LogError(ex.Message);

                    // singal that there is an error
                    if (handle != null)
                    {
                        handle.Set();
                    }
                    _error = ex;
                    throw;
                }
            });

            _readThread.IsBackground = true;
            _readThread.Start(_responseReceivedRaised);

            if (_end == ConnectionEnd.Client)
            {
                // Build the request
                var builder = new StringBuilder();
                builder.AppendFormat("{0} {1} {2}\r\n", "GET", _headers[":path"], "HTTP/1.1");
                //TODO pass here requested filename
                builder.AppendFormat("Host: {0}\r\n", _headers[":host"]);
                builder.Append("Connection: Upgrade, Http2-Settings\r\n");
                builder.Append("Upgrade: HTTP-DRAFT-04/2.0\r\n");
                builder.Append("Http2-Settings: ");
                //TODO check out how to send window size and max_conc_streams

                if (_headers != null)
                {
                    var http2Settings = new StringBuilder();
                    foreach (var key in _headers.Keys)
                    {
                        if (!string.Equals(":path", key, StringComparison.OrdinalIgnoreCase))
                        {
                            http2Settings.AppendFormat("{0}: {1}\r\n", key, _headers[key]);
                        }
                    }
                    byte[] settingsBytes = Encoding.UTF8.GetBytes(http2Settings.ToString());
                    builder.Append(Convert.ToBase64String(settingsBytes));
                }
                builder.Append("\r\n\r\n");
                byte[] requestBytes = Encoding.UTF8.GetBytes(builder.ToString());
                InternalSocket.Send(requestBytes, 0, requestBytes.Length, SocketFlags.None);

                _responseReceivedRaised.WaitOne(Timeout);
                _responseReceivedRaised.Dispose();
            }
            else
            {
                _responseReceivedRaised.WaitOne(Timeout);
                _responseReceivedRaised.Dispose();

                if (response.Result == HandshakeResult.Upgrade)
                {
                    const string status   = "101";
                    const string protocol = "HTTP/1.1";
                    const string postfix  = "Switching Protocols";

                    var builder = new StringBuilder();
                    builder.AppendFormat("{0} {1} {2}\r\n", protocol, status, postfix);
                    builder.Append("Connection: Upgrade\r\n");
                    builder.Append("Upgrade: HTTP-draft-04/2.0\r\n");
                    builder.Append("\r\n");

                    byte[] requestBytes = Encoding.ASCII.GetBytes(builder.ToString());
                    InternalSocket.Send(requestBytes, 0, requestBytes.Length, SocketFlags.None);
                }
            }

            if (!_wasResponseReceived)
            {
                if (_readThread.IsAlive)
                {
                    _readThread.Abort();
                    _readThread.Join();
                }
                throw new Http2HandshakeFailed(HandshakeFailureReason.Timeout);
            }

            if (_error != null)
            {
                throw _error;
            }

            if (response.Result != HandshakeResult.Upgrade)
            {
                throw new Http2HandshakeFailed(HandshakeFailureReason.InternalError);
            }

            if (_readThread.IsAlive)
            {
                _readThread.Abort();
            }
            _readThread.Join();

            return(_handshakeResult);
        }
Пример #5
0
        public IDictionary<string, object> Handshake()
        {
            var response = new HandshakeResponse();
            var readThread = new Thread(() =>
                {
                    response = Read11Headers();
                }){IsBackground = true, Name = "ReadSocketDataThread"};
            readThread.Start();

            if (_end == ConnectionEnd.Client)
            {
                // Build the request
                var builder = new StringBuilder();
                builder.AppendFormat("{0} {1} {2}\r\n", "get", "/default.html", "HTTP/1.1"); //TODO pass here requested filename
                builder.AppendFormat("Host: {0}\r\n", _headers[":host"]);
                builder.Append("Connection: Upgrade, Http2-Settings\r\n");
                builder.Append("Upgrade: HTTP-DRAFT-04/2.0\r\n");
                builder.Append("Http2-Settings: SomeSettings\r\n"); //TODO check out how to send window size and max_conc_streams

                if (_headers != null)
                {
                    foreach (var key in _headers.Keys)
                    {
                        builder.AppendFormat("{0}: {1}\r\n", key, _headers[key]);
                    }
                }
                builder.Append("\r\n");

                byte[] requestBytes = Encoding.ASCII.GetBytes(builder.ToString());
                InternalSocket.Send(requestBytes, 0, requestBytes.Length, SocketFlags.None);

                _responseReceivedRaised.WaitOne(Timeout);
                _responseReceivedRaised.Dispose();
            }
            else
            {
                _responseReceivedRaised.WaitOne(Timeout);
                _responseReceivedRaised.Dispose();

                if (response.Result == HandshakeResult.Upgrade)
                {
                    const string status = "101";
                    const string protocol = "HTTP/1.1";
                    const string postfix = "Switching Protocols";

                    var builder = new StringBuilder();
                    builder.AppendFormat("{0} {1} {2}\r\n", protocol, status, postfix);
                    builder.Append("Connection: Upgrade\r\n");
                    builder.Append("Upgrade: HTTP-draft-04/2.0\r\n");
                    builder.Append("\r\n");

                    byte[] requestBytes = Encoding.ASCII.GetBytes(builder.ToString());
                    InternalSocket.Send(requestBytes, 0, requestBytes.Length, SocketFlags.None);
                }
            }

            if (!_wasResponseReceived)
            {
                OnResponseReceived = null;
                if (readThread.IsAlive)
                {
                    readThread.Abort();
                    readThread.Join();
                }
                throw new Http2HandshakeFailed(HandshakeFailureReason.Timeout);
            }
            if (response.Result != HandshakeResult.Upgrade)
            {
                throw new Http2HandshakeFailed(HandshakeFailureReason.InternalError);
            }
            OnResponseReceived = null;
            if (readThread.IsAlive)
            {
                readThread.Abort();
            }
            readThread.Join();

            return _handshakeResult;
        }
Пример #6
0
        // We've found a CRLFCRLF sequence.  Confirm the status code is 101 for upgrade.
        private HandshakeResponse InspectHanshake(byte[] buffer, int split, int limit)
        {
            var handshake = new HandshakeResponse
                {
                    ResponseBytes = new ArraySegment<byte>(buffer, 0, split),
                    ExtraData = new ArraySegment<byte>(buffer, split, limit),
                };
            // Must be at least "HTTP/1.1 101\r\nConnection: Upgrade\r\nUpgrade: HTTP/2.0\r\n\r\n"
            string response = FrameHelpers.GetAsciiAt(buffer, 0, split).ToUpperInvariant();
            if (_end == ConnectionEnd.Client)
            {
                if (response.StartsWith("HTTP/1.1 101 SWITCHING PROTOCOLS")
                    && response.Contains("\r\nCONNECTION: UPGRADE\r\n")
                    && response.Contains("\r\nUPGRADE: HTTP-DRAFT-04/2.0\r\n"))
                {
                    handshake.Result = HandshakeResult.Upgrade;
                }
                else
                {
                    handshake.Result = HandshakeResult.NonUpgrade;
                }
            }
            else
            {
                if (response.Contains("\r\nCONNECTION: UPGRADE, HTTP2-SETTINGS\r\n")
                    && response.Contains("\r\nUPGRADE: HTTP-DRAFT-04/2.0\r\n")
                    && response.Contains("\r\nHTTP2-SETTINGS:"))
                {
                    GetHeaders(response);
                    handshake.Result = HandshakeResult.Upgrade;
                }
                else
                {
                    handshake.Result = HandshakeResult.NonUpgrade;
                }
            }

            if (OnResponseReceived != null)
            {
                OnResponseReceived(this, null);
            }

            return handshake;
        }
Пример #7
0
 public void ReadHeadersAndInspectHandshake()
 {
     try
     {
         _response = Read11Headers();
         _wasResponseReceived = true;
     }
     catch (Exception ex)
     {
         Http2Logger.LogError(ex.Message);
         throw;
     }
 }