Exemple #1
0
        protected Task ProduceEnd()
        {
            if (_requestRejected || _applicationException != null)
            {
                if (HasResponseStarted)
                {
                    // We can no longer change the response, so we simply close the connection.
                    _requestProcessingStopping = true;
                    return(TaskUtilities.CompletedTask);
                }

                if (_requestRejected)
                {
                    // 400 Bad Request
                    StatusCode = 400;
                    _keepAlive = false;
                }
                else
                {
                    // 500 Internal Server Error
                    StatusCode = 500;
                }

                ReasonPhrase = null;

                var responseHeaders = FrameResponseHeaders;
                responseHeaders.Reset();
                var dateHeaderValues = DateHeaderValueManager.GetDateHeaderValues();

                responseHeaders.SetRawDate(dateHeaderValues.String, dateHeaderValues.Bytes);
                responseHeaders.SetRawContentLength("0", _bytesContentLengthZero);

                if (ServerOptions.AddServerHeader)
                {
                    responseHeaders.SetRawServer(Constants.ServerName, _bytesServer);
                }
            }

            if (!HasResponseStarted)
            {
                return(ProduceEndAwaited());
            }

            return(WriteSuffix());
        }
Exemple #2
0
        private void CreateResponseHeader(
            byte[] statusBytes,
            bool appCompleted)
        {
            var responseHeaders = FrameResponseHeaders;

            responseHeaders.SetReadOnly();

            var hasConnection = responseHeaders.HasConnection;

            var end = SocketOutput.ProducingStart();

            if (_keepAlive && hasConnection)
            {
                foreach (var connectionValue in responseHeaders.HeaderConnection)
                {
                    if (connectionValue.IndexOf("close", StringComparison.OrdinalIgnoreCase) != -1)
                    {
                        _keepAlive = false;
                        break;
                    }
                }
            }

            if (_keepAlive && !responseHeaders.HasTransferEncoding && !responseHeaders.HasContentLength)
            {
                if (appCompleted)
                {
                    // Don't set the Content-Length or Transfer-Encoding headers
                    // automatically for HEAD requests or 101, 204, 205, 304 responses.
                    if (Method != "HEAD" && StatusCanHaveBody(StatusCode))
                    {
                        // Since the app has completed and we are only now generating
                        // the headers we can safely set the Content-Length to 0.
                        responseHeaders.SetRawContentLength("0", _bytesContentLengthZero);
                    }
                }
                else
                {
                    // Note for future reference: never change this to set _autoChunk to true on HTTP/1.0
                    // connections, even if we were to infer the client supports it because an HTTP/1.0 request
                    // was received that used chunked encoding. Sending a chunked response to an HTTP/1.0
                    // client would break compliance with RFC 7230 (section 3.3.1):
                    //
                    // A server MUST NOT send a response containing Transfer-Encoding unless the corresponding
                    // request indicates HTTP/1.1 (or later).
                    if (_httpVersion == HttpVersionType.Http11)
                    {
                        _autoChunk = true;
                        responseHeaders.SetRawTransferEncoding("chunked", _bytesTransferEncodingChunked);
                    }
                    else
                    {
                        _keepAlive = false;
                    }
                }
            }

            if (!_keepAlive && !hasConnection && _httpVersion != HttpVersionType.Http10)
            {
                responseHeaders.SetRawConnection("close", _bytesConnectionClose);
            }
            else if (_keepAlive && !hasConnection && _httpVersion == HttpVersionType.Http10)
            {
                responseHeaders.SetRawConnection("keep-alive", _bytesConnectionKeepAlive);
            }

            if (ServerOptions.AddServerHeader && !responseHeaders.HasServer)
            {
                responseHeaders.SetRawServer(Constants.ServerName, _bytesServer);
            }

            if (!responseHeaders.HasDate)
            {
                var dateHeaderValues = DateHeaderValueManager.GetDateHeaderValues();
                responseHeaders.SetRawDate(dateHeaderValues.String, dateHeaderValues.Bytes);
            }

            end.CopyFrom(_bytesHttpVersion11);
            end.CopyFrom(statusBytes);
            responseHeaders.CopyTo(ref end);
            end.CopyFrom(_bytesEndHeaders, 0, _bytesEndHeaders.Length);

            SocketOutput.ProducingComplete(end);
        }