public Proto1ContentLengthMessageBody(bool keepAlive, long contentLength, Proto1Connection context)
     : base(context)
 {
     RequestKeepAlive = keepAlive;
     _contentLength   = contentLength;
     _inputLength     = _contentLength;
 }
        public Proto1ChunkedEncodingMessageBody(bool keepAlive, Proto1Connection context)
            : base(context)
        {
            RequestKeepAlive = keepAlive;

            _requestBodyPipe = CreateRequestBodyPipe(context);
        }
 private Pipe CreateRequestBodyPipe(Proto1Connection context)
 => new Pipe(new PipeOptions
             (
                 pool: context.MemoryPool,
                 readerScheduler: context.ServiceContext.Scheduler,
                 writerScheduler: PipeScheduler.Inline,
                 pauseWriterThreshold: 1,
                 resumeWriterThreshold: 1,
                 useSynchronizationContext: false,
                 minimumSegmentSize: KestrelMemoryPool.MinimumSegmentSize
             ));
 public Proto1UpgradeMessageBody(Proto1Connection context)
     : base(context)
 {
     RequestUpgrade = true;
 }
Exemple #5
0
 public Proto1ParsingHandler(Proto1Connection connection)
 {
     Connection = connection;
 }
 protected Proto1MessageBody(Proto1Connection context)
     : base(context, context.MinRequestBodyDataRate)
 {
     _context = context;
 }
        public static MessageBody For(
            ProtoVersion httpVersion,
            ProtoRequestHeaders headers,
            Proto1Connection context)
        {
            // see also http://tools.ietf.org/html/rfc2616#section-4.4
            var keepAlive = httpVersion != ProtoVersion.Proto10;

            var upgrade = false;

            if (headers.HasConnection)
            {
                var connectionOptions = ProtoHeaders.ParseConnection(headers.HeaderConnection);

                upgrade   = (connectionOptions & ConnectionOptions.Upgrade) == ConnectionOptions.Upgrade;
                keepAlive = (connectionOptions & ConnectionOptions.KeepAlive) == ConnectionOptions.KeepAlive;
            }

            if (upgrade)
            {
                if (headers.HeaderTransferEncoding.Count > 0 || (headers.ContentLength.HasValue && headers.ContentLength.Value != 0))
                {
                    BadProtoRequestException.Throw(RequestRejectionReason.UpgradeRequestCannotHavePayload);
                }

                return(new Proto1UpgradeMessageBody(context));
            }

            if (headers.HasTransferEncoding)
            {
                var transferEncoding = headers.HeaderTransferEncoding;
                var transferCoding   = ProtoHeaders.GetFinalTransferCoding(transferEncoding);

                // https://tools.ietf.org/html/rfc7230#section-3.3.3
                // If a Transfer-Encoding header field
                // is present in a request and the chunked transfer coding is not
                // the final encoding, the message body length cannot be determined
                // reliably; the server MUST respond with the 400 (Bad Request)
                // status code and then close the connection.
                if (transferCoding != TransferCoding.Chunked)
                {
                    BadProtoRequestException.Throw(RequestRejectionReason.FinalTransferCodingNotChunked, transferEncoding);
                }

                // TODO may push more into the wrapper rather than just calling into the message body
                // NBD for now.
                return(new Proto1ChunkedEncodingMessageBody(keepAlive, context));
            }

            if (headers.ContentLength.HasValue)
            {
                var contentLength = headers.ContentLength.Value;

                if (contentLength == 0)
                {
                    return(keepAlive ? MessageBody.ZeroContentLengthKeepAlive : MessageBody.ZeroContentLengthClose);
                }

                return(new Proto1ContentLengthMessageBody(keepAlive, contentLength, context));
            }

            // If we got here, request contains no Content-Length or Transfer-Encoding header.
            // Reject with 411 Length Required.
            if (context.Method == ProtoMethod.Post || context.Method == ProtoMethod.Put)
            {
                var requestRejectionReason = httpVersion == ProtoVersion.Proto11 ? RequestRejectionReason.LengthRequired : RequestRejectionReason.LengthRequiredProto10;
                BadProtoRequestException.Throw(requestRejectionReason, context.Method);
            }

            return(keepAlive ? MessageBody.ZeroContentLengthKeepAlive : MessageBody.ZeroContentLengthClose);
        }