imazen/imageflow-dotnet

Issue w/ CDN Reverse Proxy

tachyon1337 opened this issue · 5 comments

Any reason why the following code snippet will work to successfully resize/process images(retrieved from Azure Blob Storage) if client requests are directed to the app service but fails if requests are forwarded from a CDN(in this, Azure FD)? This snippet is from custom middleware that replaces UseStaticFiles() running in an Azure app service that also serves as a CDN Origin for an Azure FD endpoint.

                    using var buildJob = new ImageJob();
                    var jobResult = await buildJob.BuildCommandString(blobResult.Content.ReadAllBytes(), new BytesDestination(), query).Finish().InProcessAsync();
                    var bytes = jobResult.First.TryGetBytes();
                    if (bytes != null && bytes.HasValue)
                    {
                        response.ContentType = blobResult.Details.ContentType;
                        response.ContentLength = bytes.Value.Count;
                        await response.Body.WriteAsync(bytes.Value.Array, bytes.Value.Offset, bytes.Value.Count);
                        return;
                    }
https://<id-azurewebsites.net>/<container>/<image>?width=600

works perfectly w 200 or 304 response.

https://<id-azurefd.net>/<container>/<image>?width=600

will only render about 75% of the image w/ a 200 while the browser spins for about 3 minutes before finally failing. Application Insights is not offering any insight. And the CDN reverse proxy works fine for rendering unprocessed blobs retrieved from Azure Blob Storage.

If anyone has run into this before, I thought I might give it a shot to ask here. Thanx.

commenting out the contentlength header was one of the first things I tried. Unfortunately, that results in client requests directed at the app service to stop working properly as well.

Ok, it appears converting the byte array back to a stream and using the CopyTo extension to write it to the response solved the issue. I'm not sure why CopyTo(response.BodyWriter) works and reponse.Body.Write doesn't vis a vis CDN reverse proxy, but it does. Anyways, thanx for your time.

Stream stream = new MemoryStream(bytes.Value.Array);
await stream.CopyToAsync(response.BodyWriter, ct);
//await response.Body.WriteAsync(bytes.Value.Array, bytes.Value.Offset, bytes.Value.Count);
return;
lilith commented

Sorry, I just saw your reply here. CopyToAsync is optimized for specific types including the PipeWriter (response.BodyWriter).

That said, please adjust MemoryStream there to use the offset and count. The ArraySegment means only part of the array is actually the data (although in practice it's often the whole array, it is important to only return the correct data).

Can I ask what about your situation didn't seem a good fit for Imageflow Server? What you've shared sounds pretty ideal for it.