示例#1
0
        private void FrameReceivedHandler(object sender, FrameReceivedEventArgs args)
        {
            var stream = args.Stream;
            var method = stream.Headers.GetValue(":method").ToLower();

            try
            {
                switch (method)
                {
                case "dir":
                case "get":
                    if (args.Frame is DataFrame)
                    {
                        SaveDataFrame(stream, (DataFrame)args.Frame);
                    }
                    else if (args.Frame is HeadersFrame)
                    {
                        Http2Logger.LogConsole("Headers received for stream: " + args.Frame.StreamId + " status:" + ((HeadersFrame)args.Frame).Headers.GetValue(":status"));
                    }
                    break;
                }
            }
            catch (Exception)
            {
                stream.WriteRst(ResetStatusCode.InternalError);
                stream.Dispose();
            }
        }
示例#2
0
        //Method for future usage in server push
        private void SendDataTo(Http2Stream stream, byte[] binaryData)
        {
            int i = 0;

            Http2Logger.LogConsole("Transfer begin");

            do
            {
                bool isLastData = binaryData.Length - i < Constants.MaxDataFrameContentSize;

                int chunkSize = stream.WindowSize > 0
                                    ? MathEx.Min(binaryData.Length - i, Constants.MaxDataFrameContentSize,
                                                 stream.WindowSize)
                                    : MathEx.Min(binaryData.Length - i, Constants.MaxDataFrameContentSize);

                var chunk = new byte[chunkSize];
                Buffer.BlockCopy(binaryData, i, chunk, 0, chunk.Length);

                stream.WriteDataFrame(chunk, isLastData);

                i += chunkSize;
            } while (binaryData.Length > i);

            //It was not send exactly. Some of the data frames could be pushed to the unshipped frames collection
            Http2Logger.LogConsole("File sent: " + stream.Headers.GetValue(":path"));
        }
示例#3
0
        public void SendRequestAsync(Uri request, string method, string localPath = null, string serverPostAct = null)
        {
            if (!_socket.IsClosed)
            {
                if (_host != request.Host || _port != request.Port || _scheme != request.Scheme)
                {
                    throw new InvalidOperationException("Trying to send request to non connected address");
                }

                if (_useHttp20 == false)
                {
                    Http2Logger.LogConsole("Download with Http/1.1");

                    //Download with http11 in another thread.
                    Http11Manager.Http11DownloadResource(_socket, request);
                    return;
                }

                //Submit request if http2 was chosen
                Http2Logger.LogConsole("Submitting request");

                //Submit request in the current thread, response will be handled in the session thread.
                SubmitRequest(request, method, localPath, serverPostAct);
            }
        }
        private void SaveDataFrame(Http2Stream stream, DataFrame dataFrame)
        {
            string originalPath = stream.Headers.GetValue(CommonHeaders.Path.ToLower());
            //If user sets the empty file in get command we return notFound webpage
            string fileName = string.IsNullOrEmpty(Path.GetFileName(originalPath)) ? Index : Path.GetFileName(originalPath);
            string path     = Path.Combine(AssemblyPath, fileName);

            try
            {
                _fileHelper.SaveToFile(dataFrame.Data.Array, dataFrame.Data.Offset, dataFrame.Data.Count,
                                       path, stream.ReceivedDataAmount != 0);
            }
            catch (IOException)
            {
                Http2Logger.LogError("File is still downloading. Repeat request later");

                stream.Close(ResetStatusCode.InternalError);
                return;
            }

            stream.ReceivedDataAmount += dataFrame.Data.Count;

            if (dataFrame.IsEndStream)
            {
                if (stream.HalfClosedRemote)
                {
                    //send terminator
                    stream.WriteDataFrame(new ArraySegment <byte>(new byte[0]), true);
                    Http2Logger.LogConsole("Terminator was sent");
                }
                _fileHelper.RemoveStream(path);
                Http2Logger.LogConsole("Bytes received: " + stream.ReceivedDataAmount);
            }
        }
示例#5
0
        private void SaveDataFrame(Http2Stream stream, DataFrame dataFrame)
        {
            lock (_writeLock)
            {
                string originalPath = stream.Headers.GetValue(":path".ToLower());
                //If user sets the empty file in get command we return notFound webpage
                string fileName = string.IsNullOrEmpty(Path.GetFileName(originalPath)) ? NotFound : Path.GetFileName(originalPath);
                string path     = Path.Combine(AssemblyPath, fileName);

                try
                {
                    _fileHelper.SaveToFile(dataFrame.Data.Array, dataFrame.Data.Offset, dataFrame.Data.Count,
                                           path, stream.ReceivedDataAmount != 0);
                }
                catch (IOException)
                {
                    Http2Logger.LogError("File is still downloading. Repeat request later");
                    stream.WriteDataFrame(new byte[0], true);
                    stream.Dispose();
                }

                stream.ReceivedDataAmount += dataFrame.FrameLength;

                if (dataFrame.IsEndStream)
                {
                    if (!stream.EndStreamSent)
                    {
                        //send terminator
                        stream.WriteDataFrame(new byte[0], true);
                        Http2Logger.LogConsole("Terminator was sent");
                    }
                    _fileHelper.RemoveStream(path);
                    Http2Logger.LogConsole("Bytes received " + stream.ReceivedDataAmount);
#if DEBUG
                    const string wayToServerRoot1 = @"..\..\..\..\..\Drop\Root";
                    const string wayToServerRoot2 = @".\Root";
                    var          areFilesEqual    = _fileHelper.CompareFiles(path, wayToServerRoot1 + originalPath) ||
                                                    _fileHelper.CompareFiles(path, wayToServerRoot2 + originalPath);
                    if (!areFilesEqual)
                    {
                        Console.ForegroundColor = ConsoleColor.Red;
                        Http2Logger.LogError("Files are NOT EQUAL!");
                    }
                    else
                    {
                        Console.ForegroundColor = ConsoleColor.Green;
                        Http2Logger.LogConsole("Files are EQUAL!");
                    }
                    Console.ForegroundColor = ConsoleColor.Gray;
#endif
                }
            }
        }
        public void SendRequestAsync(Uri request, string method)
        {
            if (!_sessionAdapter.IsDisposed)
            {
                if (_host != request.Host || _port != request.Port || _scheme != request.Scheme)
                {
                    throw new InvalidOperationException("Trying to send request to non connected address");
                }

                if (!_useHttp20)
                {
                    Http2Logger.LogConsole("Download with Http/1.1");
                }

                //Submit request in the current thread, response will be handled in the session thread.
                SubmitRequest(request, method);
            }
        }
        //localPath should be provided only for post and put cmds
        //serverPostAct should be provided only for post cmd
        private void SubmitRequest(Uri request, string method)
        {
            //Submit request if http2 was chosen
            Http2Logger.LogConsole("Submitting request");

            var headers = new HeadersList
            {
                new KeyValuePair <string, string>(CommonHeaders.Method, method.ToLower()),
                new KeyValuePair <string, string>(CommonHeaders.Path, request.PathAndQuery.ToLower()),
                new KeyValuePair <string, string>(CommonHeaders.Authority, _host.ToLower()),
                new KeyValuePair <string, string>(CommonHeaders.Scheme, _scheme.ToLower()),
            };

            Http2Logger.LogHeaders(headers);

            //Sending request with default  priority
            _sessionAdapter.SendRequest(headers, Constants.DefaultStreamPriority, true);
            Http2Logger.LogConsole("Request sent");
        }
示例#8
0
        public static void Main(string[] args)
        {
            Console.SetWindowSize(125, 29);
            Http2Logger.WriteToFile = false;

            _sessions    = new Dictionary <string, Http2SessionHandler>();
            _environment = ArgsHelper.GetEnvironment(args);

            var isTestsEnabled     = ConfigurationManager.AppSettings["testModeEnabled"] == "true";
            var waitForTestsFinish = new ManualResetEvent(!isTestsEnabled);

            Console.WriteLine();
            Console.WriteLine();
            Http2Logger.LogDebug("Tests enabled: " + isTestsEnabled);

            ThreadPool.SetMaxThreads(10, 10);

            var uri = ArgsHelper.TryGetUri(args);

            if (!isTestsEnabled)
            {
                HelpDisplayer.ShowMainMenuHelp();
                Console.WriteLine("Enter command");
            }

            do
            {
                try
                {
                    Command cmd;
                    string  command;
                    if (uri != null)
                    {
                        command = Verbs.Get + " " + uri; //TODO set up method correctly
                    }
                    else
                    {
                        Console.Write(">");
                        command = Console.ReadLine();
                    }

                    try
                    {
                        cmd = CommandParser.CommandParser.Parse(command);
                    }
                    catch (Exception ex)
                    {
                        Http2Logger.LogError(ex.Message);
                        continue;
                    }
                    //Scheme and port were checked during parsing get cmd.
                    switch (cmd.GetCmdType())
                    {
                    case CommandType.Put:
                    case CommandType.Post:
                    case CommandType.Get:
                    case CommandType.Delete:
                    case CommandType.Dir:
                        Http2Logger.LogConsole("Uri command detected");
                        var uriCmd = (IUriCommand)cmd;

                        string method = uriCmd.Method;

                        //Only unique sessions can be opened
                        if (_sessions.ContainsKey(uriCmd.Uri.Authority))
                        {
                            Http2Logger.LogConsole("Session already exists");
                            _sessions[uriCmd.Uri.Authority].SendRequestAsync(uriCmd.Uri, method);
                            break;
                        }

                        Http2Logger.LogConsole("Creating new session");
                        var sessionHandler = new Http2SessionHandler(_environment);
                        _sessions.Add(uriCmd.Uri.Authority, sessionHandler);
                        sessionHandler.OnClosed +=
                            (sender, eventArgs) =>
                        {
                            _sessions.Remove(sessionHandler.ServerUri);
                            Http2Logger.LogDebug("Session deleted from collection: " + sessionHandler.ServerUri);

                            waitForTestsFinish.Set();
                        };

                        //Get cmd is equivalent for connect -> get. This means, that each get request
                        //will open new session.
                        Console.WriteLine(uriCmd.Uri.ToString());
                        bool success = sessionHandler.Connect(uriCmd.Uri);
                        if (!success)
                        {
                            Http2Logger.LogError("Connection failed");
                            break;
                        }

                        if (!sessionHandler.WasHttp1Used)
                        {
                            sessionHandler.StartConnection();

                            if (sessionHandler.Protocol != SslProtocols.None)
                            {
                                sessionHandler.SendRequestAsync(uriCmd.Uri, method);
                            }
                        }
                        break;

                    case CommandType.Help:
                        ((HelpCommand)cmd).ShowHelp.Invoke();
                        break;

                    case CommandType.Ping:
                        string url = ((PingCommand)cmd).Uri.Authority;
                        if (_sessions.ContainsKey(url))
                        {
                            _sessions[url].Ping();
                        }
                        else
                        {
                            Http2Logger.LogError("Can't ping until session is opened.");
                        }
                        break;

                    case CommandType.Exit:

                        var sessionsDictCopy = new Dictionary <string, Http2SessionHandler>(_sessions);
                        foreach (var sessionUri in sessionsDictCopy.Keys)
                        {
                            sessionsDictCopy[sessionUri].Dispose(false);
                        }
                        sessionsDictCopy.Clear();
                        return;
                    }
                }
                catch (Exception e)
                {
                    Http2Logger.LogError("Problems occurred - please restart client. Error: " + e.Message);
                }
            } while (!isTestsEnabled);

            waitForTestsFinish.WaitOne(5000);

            Http2Logger.LogDebug("Exiting");
            Console.WriteLine();
            Console.WriteLine();
        }