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);
            }
        }
        private void HandleDataFrame(DataFrame dataFrame, out Http2Stream stream)
        {
            stream = GetStream(dataFrame.StreamId);

            //Aggressive window update
            if (stream != null)
            {
                Http2Logger.LogDebug("Data frame. StreamId: {0} Length: {1}", dataFrame.StreamId,
                                     dataFrame.FrameLength);
                if (stream.IsFlowControlEnabled)
                {
                    stream.WriteWindowUpdate(Constants.MaxFrameContentSize);
                }
            }
            else
            {
                throw new Http2StreamNotFoundException(dataFrame.StreamId);
            }
        }
        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.WriteDataFrame(new byte[0], true);

                //RST always has endstream flag
                //_fileHelper.RemoveStream(path);
                stream.Dispose(ResetStatusCode.InternalError);
                return;
            }

            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
            }
        }
Пример #4
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);
            }
        }
Пример #5
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);
            }
        }
Пример #6
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 (Disposed)
                return;

            if (!IsFlowControlBlocked)
            {
                _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 FrameSentEventArgs(dataFrame));
                }
            }
            else
            {
                _unshippedFrames.Enqueue(dataFrame);
            }
        }
Пример #7
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 (Disposed)
                return;

            var dataFrame = new DataFrame(_id, data, 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.FrameLength;

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

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

                if (OnFrameSent != null)
                {
                    OnFrameSent(this, new FrameSentEventArgs(dataFrame));
                }
            }
            else
            {
                _unshippedFrames.Enqueue(dataFrame);
            }
        }
        private void HandleDataFrame(DataFrame dataFrame, out Http2Stream stream)
        {
            //09 -> 6.1.  DATA
            //DATA frames MUST be associated with a stream.  If a DATA frame is
            //received whose stream identifier field is 0x0, the recipient MUST
            //respond with a connection error (Section 5.4.1) of type
            //PROTOCOL_ERROR.
            if (dataFrame.StreamId == 0)
            {
                throw new ProtocolError(ResetStatusCode.ProtocolError,
                                        "Incoming continuation frame with id = 0");
            }

            stream = GetStream(dataFrame.StreamId);

            //Aggressive window update
            if (stream != null)
            {
                Http2Logger.LogDebug("Data frame. StreamId: {0} Length: {1}", dataFrame.StreamId,
                                     dataFrame.FrameLength);
                if (stream.IsFlowControlEnabled)
                {
                    stream.WriteWindowUpdate(Constants.MaxFrameContentSize);
                }
            }
            else
            {
                throw new Http2StreamNotFoundException(dataFrame.StreamId);
            }
        }
        private void HandleDataFrame(DataFrame dataFrame, out Http2Stream stream)
        {
            Http2Logger.LogDebug("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);
            /* 12 -> 6.1
            DATA frames MUST be associated with a stream. If a DATA frame is
            received whose stream identifier field is 0x0, the recipient MUST 
            respond with a connection error of type PROTOCOL_ERROR. */
            if (dataFrame.StreamId == 0)
                throw new ProtocolError(ResetStatusCode.ProtocolError,
                                        "Incoming continuation frame with stream id=0");
            /* 12 -> 6.1 
            An endpoint that has not enabled DATA frame compression MUST
            treat the receipt of a DATA frame with the COMPRESSED flag set as a
            connection error of type PROTOCOL_ERROR. */
            if (dataFrame.IsCompressed)
                throw new ProtocolError(ResetStatusCode.ProtocolError,
                                        "GZIP compression is not enabled");

            stream = GetStream(dataFrame.StreamId);

            if (stream.Closed)
                throw new Http2StreamNotFoundException(dataFrame.StreamId);

            if (!(stream.Opened || stream.HalfClosedLocal))
                throw new ProtocolError(ResetStatusCode.ProtocolError, "data in non opened or half closed local stream");

            
            if (stream.IsFlowControlEnabled && !dataFrame.IsEndStream)
            {
                stream.WriteWindowUpdate(Constants.MaxFramePayloadSize);
            }
        }