Issues with Streaming File Response from Azure App Service

Mohan, Suresh 0 Reputation points
2025-01-22T05:37:53.8466667+00:00

Hi,

We are facing issues with streaming file response from Azure App Service. We are reading the blob and returning a file stream response from an API hosted on Azure App Service. We noticed that when the code is deployed to App Service, it does not stream the response. Instead, it tries to download the full response and times out after 4 minutes.

Please find the code snippet below:

API:

[Route("download-document")]
[HttpPost]
public async Task<IActionResult> GetDocumentFromBlob([FromBody] string filePath)
{
    var (stream, contentType) = await this.docService.GetBlobStreamAsync(filePath);
    return this.File(stream, contentType);
}

// DocService.GetBlobStreamAsync
public async Task<(Stream stream, string contentType)> GetBlobStreamAsync(string filePath)
{
    var containerInstance = this.blobServiceClient.GetBlobContainerClient("abc");
    var blobInstance = containerInstance.GetBlobClient(filePath);
    string contentType = FileExtensionHelper.GetFileType(filePath);
    var options = new BlobOpenReadOptions(allowModifications: false)
    {
        BufferSize = 10 * 1024 * 1024, // 10 MB
    };
    var stream = await blobInstance.OpenReadAsync(options);
    return (stream, contentType);
}

Azure Blob Storage
Azure Blob Storage
An Azure service that stores unstructured data in the cloud as blobs.
3,052 questions
Azure App Service
Azure App Service
Azure App Service is a service used to create and deploy scalable, mission-critical web apps.
8,232 questions
0 comments No comments
{count} votes

1 answer

Sort by: Most helpful
  1. Chiugo Okpala 85 Reputation points MVP
    2025-01-23T09:31:09.3433333+00:00

    Hi @Mohan,Suresh

    This issue typically occurs because of how Azure App Service handles long-running requests. The default timeout for HTTP requests in Azure App Service is 230 seconds (or about 4 minutes). To stream files properly, you might need to make a few adjustments.

    Here are some suggestions to resolve this issue:

    1. Increase the Timeout Limit
    <configuration>
      <system.webServer>
        <security>
          <requestFiltering>
            <requestLimits maxAllowedContentLength="2147483648" />
          </requestFiltering>
        </security>
        <httpRuntime targetFramework="4.6.1" executionTimeout="3600" maxRequestLength="2147483648" />
      </system.webServer>
    </configuration>
    
    
    1. Implement Chunked Transfer Encoding

    Chunked transfer encoding allows data to be sent in chunks, which is useful for streaming large files. Here’s an example of how you can implement it in your API:

    [Route("download-document")]
    [HttpPost]
    public async Task GetDocumentFromBlob([FromBody] string filePath)
    {
        Response.ContentType = "application/octet-stream";
        var (stream, contentType) = await this.docService.GetBlobStreamAsync(filePath);
        
        // Use a buffer to read chunks of the file
        byte[] buffer = new byte[64 * 1024];
        int bytesRead;
        while ((bytesRead = await stream.ReadAsync(buffer, 0, buffer.Length)) > 0)
        {
            await Response.Body.WriteAsync(buffer, 0, bytesRead);
            await Response.Body.FlushAsync();
        }
    }
    
    
    
    1. Use Azure Blob Storage Directly

    Instead of streaming the file through your API, you can generate a SAS (Shared Access Signature) token for the blob and return the URL to the client. This way, the client can download the file directly from Azure Blob Storage.

    [Route("download-document-url")]
    [HttpPost]
    public async Task<IActionResult> GetDocumentUrl([FromBody] string filePath)
    {
        var blobClient = new BlobClient(connectionString, containerName, filePath);
        var sasToken = blobClient.GenerateSasUri(BlobSasPermissions.Read, DateTimeOffset.UtcNow.AddHours(1));
        return Ok(new { Url = sasToken.ToString() });
    }
    
    
    

    I hope one of these solutions can help you resolve the issue.


Your answer

Answers can be marked as Accepted Answers by the question author, which helps users to know the answer solved the author's problem.