Beispiel #1
0
 /// <summary>
 /// Writes the specified <see cref="System.IO.Stream"/> to the response.
 /// <para>
 /// This supports range requests (<see cref="StatusCodes.Status206PartialContent"/> or
 /// <see cref="StatusCodes.Status416RangeNotSatisfiable"/> if the range is not satisfiable).
 /// </para>
 /// <para>
 /// This API is an alias for <see cref="File(Stream, string, string?, DateTimeOffset?, EntityTagHeaderValue?, bool)"/>.
 /// </para>
 /// </summary>
 /// <param name="stream">The <see cref="System.IO.Stream"/> to write to the response.</param>
 /// <param name="contentType">The <c>Content-Type</c> of the response. Defaults to <c>application/octet-stream</c>.</param>
 /// <param name="fileDownloadName">The the file name to be used in the <c>Content-Disposition</c> header.</param>
 /// <param name="lastModified">The <see cref="DateTimeOffset"/> of when the file was last modified.
 /// Used to configure the <c>Last-Modified</c> response header and perform conditional range requests.</param>
 /// <param name="entityTag">The <see cref="EntityTagHeaderValue"/> to be configure the <c>ETag</c> response header
 /// and perform conditional requests.</param>
 /// <param name="enableRangeProcessing">Set to <c>true</c> to enable range requests processing.</param>
 /// <returns>The created <see cref="IResult"/> for the response.</returns>
 /// <remarks>
 /// The <paramref name="stream" /> parameter is disposed after the response is sent.
 /// </remarks>
 public static IResult Stream(
     Stream stream,
     string?contentType             = null,
     string?fileDownloadName        = null,
     DateTimeOffset?lastModified    = null,
     EntityTagHeaderValue?entityTag = null,
     bool enableRangeProcessing     = false)
 => TypedResults.Stream(stream, contentType, fileDownloadName, lastModified, entityTag, enableRangeProcessing);
Beispiel #2
0
    /// <summary>
    /// Allows writing directly to the response body.
    /// <para>
    /// This supports range requests (<see cref="StatusCodes.Status206PartialContent"/> or
    /// <see cref="StatusCodes.Status416RangeNotSatisfiable"/> if the range is not satisfiable).
    /// </para>
    /// </summary>
    /// <param name="streamWriterCallback">The callback that allows users to write directly to the response body.</param>
    /// <param name="contentType">The <c>Content-Type</c> of the response. Defaults to <c>application/octet-stream</c>.</param>
    /// <param name="fileDownloadName">The the file name to be used in the <c>Content-Disposition</c> header.</param>
    /// <param name="lastModified">The <see cref="DateTimeOffset"/> of when the file was last modified.
    /// Used to configure the <c>Last-Modified</c> response header and perform conditional range requests.</param>
    /// <param name="entityTag">The <see cref="EntityTagHeaderValue"/> to be configure the <c>ETag</c> response header
    /// and perform conditional requests.</param>
    /// <returns>The created <see cref="IResult"/> for the response.</returns>
#pragma warning disable RS0026 // Do not add multiple public overloads with optional parameters
    public static IResult Stream(
#pragma warning restore RS0026 // Do not add multiple public overloads with optional parameters
        Func <Stream, Task> streamWriterCallback,
        string?contentType             = null,
        string?fileDownloadName        = null,
        DateTimeOffset?lastModified    = null,
        EntityTagHeaderValue?entityTag = null)
    => TypedResults.Stream(streamWriterCallback, contentType, fileDownloadName, lastModified, entityTag);
Beispiel #3
0
    /// <summary>
    /// Writes the contents of specified <see cref="System.IO.Pipelines.PipeReader"/> to the response.
    /// <para>
    /// This supports range requests (<see cref="StatusCodes.Status206PartialContent"/> or
    /// <see cref="StatusCodes.Status416RangeNotSatisfiable"/> if the range is not satisfiable).
    /// </para>
    /// </summary>
    /// <param name="pipeReader">The <see cref="System.IO.Pipelines.PipeReader"/> to write to the response.</param>
    /// <param name="contentType">The <c>Content-Type</c> of the response. Defaults to <c>application/octet-stream</c>.</param>
    /// <param name="fileDownloadName">The the file name to be used in the <c>Content-Disposition</c> header.</param>
    /// <param name="lastModified">The <see cref="DateTimeOffset"/> of when the file was last modified.
    /// Used to configure the <c>Last-Modified</c> response header and perform conditional range requests.</param>
    /// <param name="entityTag">The <see cref="EntityTagHeaderValue"/> to be configure the <c>ETag</c> response header
    /// and perform conditional requests.</param>
    /// <param name="enableRangeProcessing">Set to <c>true</c> to enable range requests processing.</param>
    /// <returns>The created <see cref="IResult"/> for the response.</returns>
    /// <remarks>
    /// The <paramref name="pipeReader" /> parameter is completed after the response is sent.
    /// </remarks>
#pragma warning disable RS0026 // Do not add multiple public overloads with optional parameters
    public static IResult Stream(
#pragma warning restore RS0026 // Do not add multiple public overloads with optional parameters
        PipeReader pipeReader,
        string?contentType             = null,
        string?fileDownloadName        = null,
        DateTimeOffset?lastModified    = null,
        EntityTagHeaderValue?entityTag = null,
        bool enableRangeProcessing     = false)
    => TypedResults.Stream(pipeReader, contentType, fileDownloadName, lastModified, entityTag, enableRangeProcessing);
    public void Stream_ResultHasCorrectValues(int overload, string contentType, string fileDownloadName, bool enableRangeProcessing, DateTimeOffset lastModified, EntityTagHeaderValue entityTag)
    {
        // Arrange
        var stream = new MemoryStream();

        // Act
        var result = overload switch
        {
            0 => TypedResults.Stream(stream, contentType, fileDownloadName, lastModified, entityTag, enableRangeProcessing),
            1 => TypedResults.Stream(PipeReader.Create(stream), contentType, fileDownloadName, lastModified, entityTag, enableRangeProcessing),
            _ => (IResult)TypedResults.Stream((s) => Task.CompletedTask, contentType, fileDownloadName, lastModified, entityTag)
        };

        // Assert
        switch (overload)
        {
        case <= 1:
            var fileStreamResult = result as FileStreamHttpResult;
            Assert.NotNull(fileStreamResult.FileStream);
            Assert.Equal(contentType ?? "application/octet-stream", fileStreamResult.ContentType);
            Assert.Equal(fileDownloadName, fileStreamResult.FileDownloadName);
            Assert.Equal(enableRangeProcessing, fileStreamResult.EnableRangeProcessing);
            Assert.Equal(lastModified, fileStreamResult.LastModified);
            Assert.Equal(entityTag, fileStreamResult.EntityTag);
            break;

        default:
            var pushStreamResult = result as PushStreamHttpResult;
            Assert.Equal(contentType ?? "application/octet-stream", pushStreamResult.ContentType);
            Assert.Equal(fileDownloadName, pushStreamResult.FileDownloadName);
            Assert.False(pushStreamResult.EnableRangeProcessing);
            Assert.Equal(lastModified, pushStreamResult.LastModified);
            Assert.Equal(entityTag, pushStreamResult.EntityTag);
            break;
        }
    }
 public void Stream_WithNullCallback_ThrowsArgNullException()
 {
     Assert.Throws <ArgumentNullException>("streamWriterCallback", () => TypedResults.Stream(default(Func <Stream, Task>)));
 }
 public void Stream_WithNullPipeReader_ThrowsArgNullException()
 {
     Assert.Throws <ArgumentNullException>("pipeReader", () => TypedResults.Stream(default(PipeReader)));
 }
 public void Stream_WithNullStream_ThrowsArgNullException()
 {
     Assert.Throws <ArgumentNullException>("stream", () => TypedResults.Stream(default(Stream)));
 }