Exemplo n.º 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"
            Contract.Assert(split >= 0 && split - 1 < buffer.Length);
            var response = Encoding.ASCII.GetString(buffer, 0, split);

            if (_end == ConnectionEnd.Client)
            {
                int    status       = StatusCode.Code101SwitchingProtocols;
                string reasonPhrase = StatusCode.GetReasonPhrase(status);

                if (response.StartsWith(String.Format("{0} {1} {2}", Protocols.Http1, status.ToString(), reasonPhrase),
                                        StringComparison.OrdinalIgnoreCase) &&
                    response.IndexOf(String.Format("\r\n{0}: {1}\r\n", CommonHeaders.Connection, CommonHeaders.Upgrade),
                                     StringComparison.OrdinalIgnoreCase) >= 0 &&
                    response.IndexOf(String.Format("\r\n{0}: {1}\r\n", CommonHeaders.Upgrade, Protocols.Http2NoTls),
                                     StringComparison.OrdinalIgnoreCase) >= 0)
                {
                    handshake.Result = HandshakeResult.Upgrade;
                }
                else
                {
                    handshake.Result = HandshakeResult.NonUpgrade;
                }
            }
            else
            {
                if (
                    response.IndexOf(String.Format("\r\n{0}: {1}, {2}\r\n", CommonHeaders.Connection, CommonHeaders.Upgrade, CommonHeaders.Http2Settings),
                                     StringComparison.OrdinalIgnoreCase) >= 0 &&
                    response.IndexOf(String.Format("\r\n{0}: {1}\r\n", CommonHeaders.Upgrade, Protocols.Http2NoTls),
                                     StringComparison.OrdinalIgnoreCase) >= 0 &&
                    response.IndexOf(String.Format("\r\n{0}:", CommonHeaders.Http2Settings), StringComparison.OrdinalIgnoreCase) >= 0)
                {
                    GetHeaders(response);
                    handshake.Result = HandshakeResult.Upgrade;
                }
                else
                {
                    handshake.Result = HandshakeResult.NonUpgrade;
                }
            }

            return(handshake);
        }
Exemplo n.º 2
0
        /// <summary>
        /// // TODO
        /// </summary>
        /// <param name="stream"></param>
        /// <param name="data"></param>
        /// <param name="statusCode"></param>
        /// <param name="headers"></param>
        /// <param name="closeConnection">we don’t currently support persistent connection via Http1.1 so closeConnection:true</param>
        /// <returns></returns>
        public static int SendResponse(Stream stream, byte[] data, int statusCode, IDictionary <string, string[]> headers = null, bool closeConnection = true)
        {
            string initialLine = "HTTP/1.1 " + statusCode + " " + StatusCode.GetReasonPhrase(statusCode) + "\r\n";
            string headersPack = initialLine;

            if (headers == null)
            {
                headers = new Dictionary <string, string[]>(StringComparer.OrdinalIgnoreCase);
            }

            if (!headers.ContainsKey("Connection") && closeConnection)
            {
                headers.Add("Connection", new[] { "Close" });
            }

            if (!headers.ContainsKey("Content-Length"))
            {
                headers.Add("Content-Length", new [] { Convert.ToString(data.Length) });
            }

            headersPack = headers.Aggregate(headersPack, (current, header) => current + (header.Key + ": " + String.Join(",", header.Value) + "\r\n")) + "\r\n";

            int sent = stream.Write(Encoding.UTF8.GetBytes(headersPack));

            //Send headers and body separately
            //TODO It's needed for our client. Think out a way to avoid separate sending.
            stream.Flush();

            if (data.Length > 0)
            {
                sent += stream.Write(data);
            }

            Thread.Sleep(200);

            stream.Flush();
            return(sent);
        }
Exemplo n.º 3
0
        public static int SendResponse(SecureSocket socket, byte[] data, int statusCode, string contentType)
        {
            string initialLine = "HTTP/1.1 " + statusCode + " " + StatusCode.GetReasonPhrase(statusCode) + "\r\n";

            var headers = new Dictionary <string, string>();

            if (data.Length > 0)
            {
                headers.Add("Content-Type", contentType);
            }
            else
            {
                initialLine += "\r\n";
            }
            int sent = socket.Send(Encoding.UTF8.GetBytes(initialLine));

            SendHeaders(socket, headers, data.Length);
            if (data.Length > 0)
            {
                sent += socket.Send(data);
            }

            return(sent);
        }
Exemplo n.º 4
0
        public IDictionary <string, object> Handshake()
        {
            if (_end == ConnectionEnd.Client)
            {
                // Build the request
                var builder = new StringBuilder();
                builder.AppendFormat("{0} {1} {2}\r\n", Verbs.Get, _headers[CommonHeaders.Path], Protocols.Http1);
                //TODO pass here requested filename
                builder.AppendFormat("Host: {0}\r\n", _headers[CommonHeaders.Host]);
                builder.Append(String.Format("{0}: {1}, {2}\r\n", CommonHeaders.Connection, CommonHeaders.Upgrade, CommonHeaders.Http2Settings));
                builder.Append(String.Format("{0}: {1}\r\n", CommonHeaders.Upgrade, Protocols.Http2NoTls));
                var settingsPayload = String.Format("{0}, {1}", 200000, 100);
                var settingsBytes   = Encoding.UTF8.GetBytes(settingsPayload);
                var settingsBase64  = Convert.ToBase64String(settingsBytes);

                builder.Append(String.Format("{0}: {1}", CommonHeaders.Http2Settings, settingsBase64));
                builder.Append("\r\n\r\n");

                byte[] requestBytes = Encoding.UTF8.GetBytes(builder.ToString());
                _handshakeResult = new Dictionary <string, object>(_headers)
                {
                    { CommonHeaders.Method, Verbs.Get.ToLower() }
                };
                IoStream.Write(requestBytes, 0, requestBytes.Length);
                IoStream.Flush();
                ReadHeadersAndInspectHandshake();
            }
            else
            {
                ReadHeadersAndInspectHandshake();
                if (_response.Result == HandshakeResult.Upgrade)
                {
                    const int status   = StatusCode.Code101SwitchingProtocols;
                    string    protocol = Protocols.Http1;
                    string    postfix  = StatusCode.GetReasonPhrase(status);

                    var builder = new StringBuilder();
                    builder.AppendFormat("{0} {1} {2}\r\n", protocol, status, postfix);
                    builder.Append(String.Format("{0}: {1}\r\n", CommonHeaders.Connection, CommonHeaders.Upgrade));
                    builder.Append(String.Format("{0}: {1}\r\n", CommonHeaders.Upgrade, Protocols.Http2NoTls));
                    builder.Append("\r\n");

                    byte[] requestBytes = Encoding.ASCII.GetBytes(builder.ToString());
                    IoStream.Write(requestBytes, 0, requestBytes.Length);
                    IoStream.Flush();
                }
            }

            if (!_wasResponseReceived)
            {
                throw new Http2HandshakeFailed(HandshakeFailureReason.Timeout);
            }

            if (_response.Result != HandshakeResult.Upgrade)
            {
                _handshakeResult.Add(HandshakeKeys.Successful, HandshakeKeys.False);
                var path = _headers[CommonHeaders.Path] as string;

                Http2Logger.LogDebug("Handling with http11");
                var http11Adapter = new Http11ClientMessageHandler(IoStream, path);
                http11Adapter.HandleHttp11Response(_response.ResponseBytes.Array, 0, _response.ResponseBytes.Count);

                return(_handshakeResult);
            }

            _handshakeResult.Add(HandshakeKeys.Successful, HandshakeKeys.True);
            return(_handshakeResult);
        }