Exemplo n.º 1
0
        public void UpdateWindowSize(Int32 delta)
        {
            if (IsFlowControlEnabled)
            {
                //09 -> 6.9.1.  The Flow Control Window
                //A sender MUST NOT allow a flow control window to exceed 2^31 - 1
                //bytes.  If a sender receives a WINDOW_UPDATE that causes a flow
                //control window to exceed this maximum it MUST terminate either the
                //stream or the connection, as appropriate.  For streams, the sender
                //sends a RST_STREAM with the error code of FLOW_CONTROL_ERROR code;
                //for the connection, a GOAWAY frame with a FLOW_CONTROL_ERROR code.
                WindowSize += delta;

                if (WindowSize > Constants.MaxWindowSize)
                {
                    Http2Logger.LogDebug("Incorrect window size : {0}", WindowSize);
                    throw new ProtocolError(ResetStatusCode.FlowControlError, String.Format("Incorrect window size : {0}", WindowSize));
                }
            }

            //Unblock stream if it was blocked by flowCtrlManager
            if (WindowSize > 0 && IsFlowControlBlocked)
            {
                IsFlowControlBlocked = false;
            }
        }
Exemplo n.º 2
0
        /// <summary>
        /// Starts session.
        /// </summary>
        /// <returns></returns>
        public Task Start()
        {
            Http2Logger.LogDebug("Session start");
            //Write settings. Settings must be the first frame in session.

            if (_useFlowControl)
            {
                WriteSettings(new[]
                {
                    new SettingsPair(SettingsFlags.None, SettingsIds.InitialWindowSize, 200000)
                });
            }
            else
            {
                WriteSettings(new[]
                {
                    new SettingsPair(SettingsFlags.None, SettingsIds.InitialWindowSize, 200000),
                    new SettingsPair(SettingsFlags.None, SettingsIds.FlowControlOptions, (byte)FlowControlOptions.DontUseFlowControl)
                });
            }
            // Listen for incoming Http/2.0 frames
            var incomingTask = new Task(PumpIncommingData);
            // Send outgoing Http/2.0 frames
            var outgoingTask = new Task(() => PumpOutgoingData());

            incomingTask.Start();
            outgoingTask.Start();

            return(Task.WhenAll(incomingTask, outgoingTask));
        }
Exemplo n.º 3
0
        private void RequestSentHandler(object sender, RequestSentEventArgs args)
        {
            var stream = args.Stream;
            var method = stream.Headers.GetValue(":method");

            if (method == "put" || method == "post")
            {
                var    localPath    = stream.Headers.GetValue(":localPath".ToLower());
                byte[] binary       = null;
                bool   gotException = false;
                try
                {
                    binary = _fileHelper.GetFile(localPath);
                }
                catch (FileNotFoundException)
                {
                    gotException = true;
                    Http2Logger.LogError("Specified file not found: " + localPath);
                }
                if (!gotException)
                {
                    SendDataTo(args.Stream, binary);
                }
            }
        }
Exemplo n.º 4
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);
            }
        }
Exemplo n.º 5
0
        public async void StartConnection()
        {
            Console.WriteLine("Start connection called");
            if (_useHttp20 && !_sessionAdapter.IsDisposed && !_isDisposed)
            {
                Dictionary <string, string> initialRequest = null;
                if (!_isSecure)
                {
                    initialRequest = new Dictionary <string, string>
                    {
                        { CommonHeaders.Path, _path },
                    };
                }

                await _sessionAdapter.StartSessionAsync(initialRequest);

                //GC.Collect();
            }

            if (!_sessionAdapter.IsDisposed)
            {
                return;
            }

            Http2Logger.LogError("Connection was aborted by the remote side. Check your session header.");
            Dispose(true);
        }
Exemplo n.º 6
0
        /// <summary>
        /// Writes the SETTINGS frame.
        /// </summary>
        /// <param name="settings">The settings pairs.</param>
        /// <param name="isAck">The ACK flag.</param>
        public void WriteSettings(SettingsPair[] settings, bool isAck)
        {
            if (settings == null)
            {
                throw new ArgumentNullException("settings");
            }

            var frame = new SettingsFrame(new List <SettingsPair>(settings), isAck);

            Http2Logger.LogDebug("Sending SETTINGS frame: stream id={0}, payload len={1}, is ack={2}, count={3}",
                                 frame.StreamId, frame.PayloadLength, frame.IsAck, frame.EntryCount);

            foreach (var s in settings)
            {
                Http2Logger.LogDebug("{0}: {1}", s.Id.ToString(), s.Value);
            }

            _writeQueue.WriteFrame(frame);

            if (!isAck && !_settingsAckReceived.WaitOne(60000))
            {
                WriteGoAway(ResetStatusCode.SettingsTimeout);
                Dispose();
            }

            _settingsAckReceived.Reset();

            if (OnSettingsSent != null)
            {
                OnSettingsSent(this, new SettingsSentEventArgs(frame));
            }
        }
Exemplo n.º 7
0
        /// <summary>
        /// Writes the data frame. Method is used for pushing unshipped frames.
        /// If flow control manager has blocked stream, frames are adding to the unshippedFrames collection.
        /// After window update for that stream they will be delivered.
        /// </summary>
        /// <param name="dataFrame">The data frame.</param>
        private void WriteDataFrame(DataFrame dataFrame)
        {
            if (dataFrame == null)
            {
                throw new ArgumentNullException("dataFrame is null");
            }

            if (Closed)
            {
                return;
            }

            if (!IsFlowControlBlocked)
            {
                _writeQueue.WriteFrame(dataFrame);
                SentDataAmount += dataFrame.Data.Count;

                _flowCrtlManager.DataFrameSentHandler(this, new DataFrameSentEventArgs(dataFrame));

                if (dataFrame.IsEndStream)
                {
                    Http2Logger.LogDebug("Bytes sent: {0}", SentDataAmount);
                    HalfClosedLocal = true;
                }

                if (OnFrameSent != null)
                {
                    OnFrameSent(this, new FrameSentEventArgs(dataFrame));
                }
            }
            else
            {
                _unshippedFrames.Enqueue(dataFrame);
            }
        }
Exemplo n.º 8
0
        public void WriteWindowUpdate(Int32 windowSize)
        {
            if (windowSize <= 0)
            {
                throw new ArgumentOutOfRangeException("windowSize should be greater than 0");
            }

            if (windowSize > Constants.MaxWindowSize)
            {
                throw new ProtocolError(ResetStatusCode.FlowControlError, "window size is too large");
            }

            //09 -> 6.9.4.  Ending Flow Control
            //After a receiver reads in a frame that marks the end of a stream (for
            //example, a data stream with a END_STREAM flag set), it MUST cease
            //transmission of WINDOW_UPDATE frames for that stream.
            if (Closed)
            {
                return;
            }

            //TODO handle idle state

            var frame = new WindowUpdateFrame(_id, windowSize);

            _writeQueue.WriteFrame(frame);

            Http2Logger.LogDebug("Sending WINDOW_UPDATE: stream id={0}, delta={1}", frame.StreamId, frame.Delta);

            if (OnFrameSent != null)
            {
                OnFrameSent(this, new FrameSentEventArgs(frame));
            }
        }
Exemplo n.º 9
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"));
        }
Exemplo n.º 10
0
        private void HandleRstFrame(RstStreamFrame resetFrame, out Http2Stream stream)
        {
            Http2Logger.LogDebug("RST_STREAM frame: stream id={0}, status code={1}",
                                 resetFrame.StreamId, resetFrame.StatusCode);

            /* 12 -> 6.4
             * RST_STREAM frames MUST be associated with a stream.  If a RST_STREAM
             * frame is received with a stream identifier of 0x0, the recipient MUST
             * treat this as a connection error of type PROTOCOL_ERROR. */
            if (resetFrame.StreamId == 0)
            {
                throw new ProtocolError(ResetStatusCode.ProtocolError, "Rst frame with stream id=0");
            }

            stream = GetStream(resetFrame.StreamId);

            if (stream.Closed)
            {
                /* 12 -> 5.4.2
                 * An endpoint MUST NOT send a RST_STREAM in response to an RST_STREAM
                 * frame, to avoid looping. */
                if (!stream.WasRstSent)
                {
                    throw new Http2StreamNotFoundException(resetFrame.StreamId);
                }
                return;
            }

            if (!(stream.ReservedRemote || stream.Opened || stream.HalfClosedLocal))
            {
                throw new ProtocolError(ResetStatusCode.ProtocolError, "Rst for non opened or reserved stream");
            }

            stream.Close(ResetStatusCode.None);
        }
Exemplo n.º 11
0
        private void HandlePingFrame(PingFrame pingFrame)
        {
            Http2Logger.LogDebug("PING frame: stream id={0}, payload={1}", pingFrame.StreamId,
                                 pingFrame.Payload.Count);

            /* 12 -> 6.7
             * PING frames are not associated with any individual stream.  If a PING
             * frame is received with a stream identifier field value other than
             * 0x0, the recipient MUST respond with a connection error of type PROTOCOL_ERROR. */
            if (pingFrame.StreamId != 0)
            {
                throw new ProtocolError(ResetStatusCode.ProtocolError,
                                        "Incoming ping frame with stream id != 0");
            }

            if (pingFrame.PayloadLength != PingFrame.DefPayloadLength)
            {
                throw new ProtocolError(ResetStatusCode.FrameSizeError, "Ping payload size is not equal to 8");
            }

            if (pingFrame.IsAck)
            {
                _pingReceived.Set();
            }
            else
            {
                var pingAckFrame = new PingFrame(true, pingFrame.Payload.ToArray());
                _writeQueue.WriteFrame(pingAckFrame);
            }
        }
Exemplo n.º 12
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();
            }
        }
Exemplo n.º 13
0
        public void Close(ResetStatusCode code)
        {
            if (Closed || Idle)
            {
                return;
            }

            OnFrameSent = null;

            Http2Logger.LogDebug("Total outgoing data frames volume " + SentDataAmount);
            Http2Logger.LogDebug("Total frames sent: {0}", FramesSent);
            Http2Logger.LogDebug("Total frames received: {0}", FramesReceived);

            if (code == ResetStatusCode.Cancel || code == ResetStatusCode.InternalError)
            {
                WriteRst(code);
            }

            _flowCrtlManager.StreamClosedHandler(this);

            Closed = true;

            if (OnClose != null)
            {
                OnClose(this, new StreamClosedEventArgs(_id));
            }

            OnClose = null;

            Http2Logger.LogDebug("Stream closed " + _id);
        }
Exemplo n.º 14
0
        /// <summary>
        /// Writes the data frame.
        /// If flow control manager has blocked stream, frames are adding to the unshippedFrames collection.
        /// After window update for that stream they will be delivered.
        /// </summary>
        /// <param name="dataFrame">The data frame.</param>
        public void WriteDataFrame(DataFrame dataFrame)
        {
            if (IsFlowControlBlocked == false)
            {
                _writeQueue.WriteFrame(dataFrame);
                SentDataAmount += dataFrame.FrameLength;

                _flowCrtlManager.DataFrameSentHandler(this, new DataFrameSentEventArgs(dataFrame));

                if (dataFrame.IsEndStream)
                {
                    Http2Logger.LogDebug("Transfer end");
                    EndStreamSent = true;
                }

                if (OnFrameSent != null)
                {
                    OnFrameSent(this, new FrameSentArgs(dataFrame));
                }
            }
            else
            {
                _unshippedFrames.Enqueue(dataFrame);
            }
        }
        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);
            }
        }
Exemplo n.º 16
0
        private void StartResponse()
        {
            Debug.Assert(!_responseStarted, "Response started more than once");
            _responseStarted = true;
            Http2Logger.LogDebug("Transfer begin");

            SendHeaders(final: false);
        }
Exemplo n.º 17
0
        /// <summary>
        /// Writes the data frame.
        /// If flow control manager has blocked stream, frames are adding to the unshippedFrames collection.
        /// After window update for that stream they will be delivered.
        /// </summary>
        /// <param name="data">The data.</param>
        /// <param name="isEndStream">if set to <c>true</c> [is fin].</param>
        public void WriteDataFrame(ArraySegment <byte> data, bool isEndStream)
        {
            if (data.Array == null)
            {
                throw new ArgumentNullException("data is null");
            }

            if (Closed)
            {
                return;
            }

            var dataFrame = new DataFrame(_id, data, isEndStream, true);

            Http2Logger.LogDebug(
                "Sending DATA frame: stream id={0}, payload len={1}, has pad={2}, pad high={3}, pad low={4}, " +
                "end stream={5}", dataFrame.StreamId, dataFrame.PayloadLength,
                dataFrame.HasPadding, dataFrame.PadHigh, dataFrame.PadLow, dataFrame.IsEndStream);

            //We cant let lesser frame that were passed through flow control window
            //be sent before greater frames that were not passed through flow control window

            //09 -> 6.9.1.  The Flow Control Window
            //The sender MUST NOT
            //send a flow controlled frame with a length that exceeds the space
            //available in either of the flow control windows advertised by the receiver.
            if (_unshippedFrames.Count != 0 || WindowSize - dataFrame.Data.Count < 0)
            {
                _unshippedFrames.Enqueue(dataFrame);
                return;
            }

            if (!IsFlowControlBlocked)
            {
                _writeQueue.WriteFrame(dataFrame);
                SentDataAmount += dataFrame.Data.Count;

                _flowCrtlManager.DataFrameSentHandler(this, new DataFrameSentEventArgs(dataFrame));

                if (dataFrame.IsEndStream)
                {
                    Http2Logger.LogDebug("Transfer end");
                    Http2Logger.LogDebug("Sent bytes: {0}", SentDataAmount);
                    HalfClosedLocal = true;
                }

                if (OnFrameSent != null)
                {
                    OnFrameSent(this, new FrameSentEventArgs(dataFrame));
                }
            }
            else
            {
                _unshippedFrames.Enqueue(dataFrame);
            }
        }
Exemplo n.º 18
0
        /// <summary>
        /// Accepts client and deals handshake with it.
        /// </summary>
        internal void Accept()
        {
            SecureSocket incomingClient;

            using (var monitor = new ALPNExtensionMonitor())
            {
                incomingClient = _server.AcceptSocket(monitor);
            }
            Http2Logger.LogDebug("New connection accepted");
            Task.Run(() => HandleAcceptedClient(incomingClient));
        }
Exemplo n.º 19
0
 public async void StartConnection()
 {
     if (_useHttp20 && !_socket.IsClosed && !_isDisposed)
     {
         await _clientSession.Start();
     }
     else if (_socket.IsClosed || _isDisposed)
     {
         Http2Logger.LogError("Connection was aborted by the remote side. Check your session header.");
         Dispose(true);
     }
 }
Exemplo n.º 20
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
                }
            }
        }
Exemplo n.º 21
0
        private void HandleWindowUpdateFrame(WindowUpdateFrame windowUpdateFrame, out Http2Stream stream)
        {
            Http2Logger.LogDebug("WINDOW_UPDATE frame: stream id={0}, delta={1}", windowUpdateFrame.StreamId,
                                 windowUpdateFrame.Delta);

            if (!_useFlowControl)
            {
                stream = null;
                return;
            }

            // TODO Remove this hack

            /* The WINDOW_UPDATE frame can be specific to a stream or to the entire
             * connection.  In the former case, the frame's stream identifier
             * indicates the affected stream; in the latter, the value "0" indicates
             * that the _entire connection_ is the subject of the frame. */
            if (windowUpdateFrame.StreamId == 0)
            {
                _flowControlManager.StreamsInitialWindowSize += windowUpdateFrame.Delta;
                stream = null;
                return;
            }

            stream = GetStream(windowUpdateFrame.StreamId);

            /* 12 -> 6.9
             * WINDOW_UPDATE can be sent by a peer that has sent a frame bearing the
             * END_STREAM flag.  This means that a receiver could receive a
             * WINDOW_UPDATE frame on a "half closed (remote)" or "closed" stream.
             * A receiver MUST NOT treat this as an error. */

            if (!(stream.Opened || stream.HalfClosedRemote || stream.HalfClosedLocal || stream.Closed))
            {
                throw new ProtocolError(ResetStatusCode.ProtocolError, "window update in incorrect state");
            }

            //09 -> 6.9.  WINDOW_UPDATE
            //The payload of a WINDOW_UPDATE frame is one reserved bit, plus an
            //unsigned 31-bit integer indicating the number of bytes that the
            //sender can transmit in addition to the existing flow control window.
            //The legal range for the increment to the flow control window is 1 to
            //2^31 - 1 (0x7fffffff) bytes.
            if (!(0 < windowUpdateFrame.Delta && windowUpdateFrame.Delta <= Constants.MaxPriority))
            {
                Http2Logger.LogDebug("Incorrect window update delta : {0}", windowUpdateFrame.Delta);
                throw new ProtocolError(ResetStatusCode.FlowControlError, String.Format("Incorrect window update delta : {0}", windowUpdateFrame.Delta));
            }

            stream.UpdateWindowSize(windowUpdateFrame.Delta);
            stream.PumpUnshippedFrames();
        }
Exemplo n.º 22
0
 public void ReadHeadersAndInspectHandshake()
 {
     try
     {
         _response            = Read11Headers();
         _wasResponseReceived = true;
     }
     catch (Exception ex)
     {
         Http2Logger.LogError(ex.Message);
         throw;
     }
 }
Exemplo n.º 23
0
        public HttpSocketServer(Func <IDictionary <string, object>, Task> next, IDictionary <string, object> properties)
        {
            _next = next;

            var addresses = (IList <IDictionary <string, object> >)properties[OwinConstants.CommonKeys.Addresses];

            var address = addresses.First();

            _port   = Int32.Parse(address.Get <string>("port"));
            _scheme = address.Get <string>("scheme");

            _useHandshake   = (bool)properties["use-handshake"];
            _usePriorities  = (bool)properties["use-priorities"];
            _useFlowControl = (bool)properties["use-flowControl"];

            int securePort;

            try
            {
                securePort = int.Parse(ConfigurationManager.AppSettings["securePort"]);
            }
            catch (Exception)
            {
                Http2Logger.LogError("Incorrect port in the config file!" + ConfigurationManager.AppSettings["securePort"]);
                return;
            }

            if (_port == securePort && _scheme == Uri.UriSchemeHttp ||
                _port != securePort && _scheme == Uri.UriSchemeHttps)
            {
                Http2Logger.LogError("Invalid scheme or port! Use https for secure port.");
                return;
            }

            var extensions = new[] { ExtensionType.Renegotiation, ExtensionType.ALPN };

            // protocols should be in order of their priority
            _options = _port == securePort ? new SecurityOptions(SecureProtocol.Tls1, extensions, new[] { Protocols.Http2, Protocols.Http1 }, ConnectionEnd.Server)
                                : new SecurityOptions(SecureProtocol.None, extensions, new[] { Protocols.Http2, Protocols.Http1 }, ConnectionEnd.Server);

            _options.VerificationType  = CredentialVerification.None;
            _options.Certificate       = Certificate.CreateFromCerFile(AssemblyName + CertificateFilename);
            _options.Flags             = SecurityFlags.Default;
            _options.AllowedAlgorithms = SslAlgorithms.RSA_AES_256_SHA | SslAlgorithms.NULL_COMPRESSION;

            _server = new SecureTcpListener(_port, _options);

            ThreadPool.SetMaxThreads(30, 10);

            Listen();
        }
Exemplo n.º 24
0
        public static void Http11SendResponse(SecureSocket socket)
        {
            string[] headers  = GetHttp11Headers(socket);
            string   filename = GetFileName(headers);


            if (headers.Length == 0)
            {
                Http2Logger.LogError("Request headers empty!");
            }

            string path        = Path.GetFullPath(AssemblyPath + @"\root" + filename);
            string contentType = ContentTypes.GetTypeFromFileName(filename);

            if (!File.Exists(path))
            {
                Http2Logger.LogError("File " + filename + " not found");
                SendResponse(socket, new byte[0], StatusCode.Code404NotFound, contentType);
                socket.Close();
                return;
            }

            try
            {
                using (var sr = new StreamReader(path))
                {
                    string file = sr.ReadToEnd();

                    var fileBytes = Encoding.UTF8.GetBytes(file);

                    int sent = SendResponse(socket, fileBytes, StatusCode.Code200Ok, contentType);
                    Http2Logger.LogDebug(string.Format("Sent: {0} bytes", sent));
                    Http2Logger.LogInfo("File sent: " + filename);

                    socket.Close();

                    if (OnSocketClosed != null)
                    {
                        OnSocketClosed(null, new SocketCloseEventArgs());
                    }
                }
            }
            catch (Exception ex)
            {
                var msgBytes = Encoding.UTF8.GetBytes(ex.Message);
                SendResponse(socket, msgBytes, StatusCode.Code500InternalServerError, contentType);
                Http2Logger.LogError(ex.Message);
            }
        }
        public void HandleHttp11Response(byte[] responseBinaryHeaders, int offset, int length)
        {
            var bytes = new byte[offset + length];

            Buffer.BlockCopy(responseBinaryHeaders, 0, bytes, offset, length);
            var response = ParseHeadersAndReadResponseBody(bytes);

            //TODO Handle headers somehow if it's needed
            using (var stream = new FileStream(AssemblyName + _path, FileMode.Create))
            {
                stream.Write(response.Value, 0, response.Value.Length);
            }

            Http2Logger.LogDebug("Response was saved as {0}", _path);
        }
Exemplo n.º 26
0
 /// <summary>
 /// Pumps the outgoing data to write queue
 /// </summary>
 /// <returns></returns>
 private Task PumpOutgoingData()
 {
     return(Task.Run(() =>
     {
         try
         {
             _writeQueue.PumpToStream();
         }
         catch (Exception)
         {
             Http2Logger.LogError("Sending frame was cancelled because connection was lost");
             Dispose();
         }
     }));
 }
Exemplo n.º 27
0
        /// <summary>
        /// Writes the GOAWAY frame.
        /// </summary>
        /// <param name="code">The Reset Status code.</param>
        public void WriteGoAway(ResetStatusCode code)
        {
            //if there were no streams opened
            if (_lastId == -1)
            {
                _lastId = 0; //then set lastId to 0 as spec tells. (See GoAway chapter)
            }

            var frame = new GoAwayFrame(_lastId, code);

            Http2Logger.LogDebug("Sending GOAWAY frame: stream id={0}, code={1}, last good id={2}",
                                 frame.StreamId, frame.StatusCode, frame.LastGoodStreamId);

            _writeQueue.WriteFrame(frame);
        }
Exemplo n.º 28
0
        private void HandleRequest(Stream incomingClient, string alpnSelectedProtocol, bool backToHttp11)
        {
            //Server checks selected protocol and calls http2 or http11 layer
            if (backToHttp11 || alpnSelectedProtocol == Protocols.Http1)
            {
                Http2Logger.LogDebug("Selected protocol: HTTP/1.1");

                new Http11ProtocolOwinAdapter(incomingClient, SslProtocols.Tls, _next.Invoke).ProcessRequest();
                return;
            }

            //ALPN selected http2. No need to perform upgrade handshake.
            Http2Logger.LogDebug("Selected protocol (ALPN): http/2");
            OpenHttp2Session(incomingClient);
        }
Exemplo n.º 29
0
        private void HandleGoAwayFrame(GoAwayFrame goAwayFrame)
        {
            Http2Logger.LogDebug("GOAWAY frame: stream id={0}, status code={1}", goAwayFrame.StreamId,
                                 goAwayFrame.StatusCode);

            if (goAwayFrame.StreamId != 0)
            {
                throw new ProtocolError(ResetStatusCode.ProtocolError, "GoAway Stream id should always be null");
            }

            _goAwayReceived = true;

            Http2Logger.LogDebug("last successful id = {0}", goAwayFrame.LastGoodStreamId);
            Dispose();
        }
Exemplo n.º 30
0
        private async void OpenHttp2Session(SecureSocket incomingClient, IDictionary <string, object> handshakeResult)
        {
            Http2Logger.LogDebug("Handshake successful");
            _session = new Http2Session(incomingClient, ConnectionEnd.Server, _usePriorities, _useFlowControl, handshakeResult);
            _session.OnFrameReceived += FrameReceivedHandler;

            try
            {
                await _session.Start();
            }
            catch (Exception)
            {
                Http2Logger.LogError("Client was disconnected");
            }
        }