imazen / imageflow-dotnet-server

A super-fast image server to speed up your site - deploy as a microservice, serverless, or embeddable.
https://docs.imageflow.io
GNU Affero General Public License v3.0
246 stars 33 forks source link

What is the equivalent of the human friendly configuration from ImageResizer for RemoteReader? #52

Closed twwilliams closed 2 years ago

twwilliams commented 2 years ago

With ImageResizer, we were able to use URL rewriting to make the use of remote URLs transparent.

In our CSHTML views, we would author something like:

/special-images/image.jpg?cache=yes&width=500

We then had a URL rewriting rule looked like:

<rule name="resizer remote images">
    <match url="special-images/(.+)" />
    <action type="Rewrite" url="remote/server.example.com/images/{R:1}" />
</rule>

And the code served to the browser would have a URL like:

/special-images/08f1a2712aa4455ab7e7a44cb7b9640a.jpg?cache=yes&width=500

And we have the domain whitelisted in Application_Start.

I think this is the human-friendly syntax as described at https://imageresizing.net/docs/v4/plugins/remotereader

How do we do the same thing with ImageFlow.Server?

lilith commented 2 years ago

You can either use AddRewiteHandler like in the readme or a general rewriting module like this:

https://docs.microsoft.com/en-us/aspnet/core/fundamentals/url-rewriting?view=aspnetcore-5.0

On Wed, Sep 22, 2021, 1:58 PM Tommy Williams @.***> wrote:

With ImageResizer, we were able to use URL rewriting to make the use of remote URLs transparent.

In our CSHTML views, we would author something like:

/special-images/image.jpg?cache=yes&width=500

We then had a URL rewriting rule looked like:

And the code served to the browser would have a URL like:

/special-images/08f1a2712aa4455ab7e7a44cb7b9640a.jpg?cache=yes&width=500

And we have the domain whitelisted in Application_Start.

I think this is the human-friendly syntax as described at https://imageresizing.net/docs/v4/plugins/remotereader

How do we do the same thing with ImageFlow.Server?

— You are receiving this because you are subscribed to this thread. Reply to this email directly, view it on GitHub https://github.com/imazen/imageflow-dotnet-server/issues/52, or unsubscribe https://github.com/notifications/unsubscribe-auth/AAA2LHZEQOXBWJLJJKNP2K3UDIYOJANCNFSM5ESDT6CQ . Triage notifications on the go with GitHub Mobile for iOS https://apps.apple.com/app/apple-store/id1477376905?ct=notification-email&mt=8&pt=524675 or Android https://play.google.com/store/apps/details?id=com.github.android&referrer=utm_campaign%3Dnotification-email%26utm_medium%3Demail%26utm_source%3Dgithub.

twwilliams commented 2 years ago

I have the rewrite in place, and it does look like ImageFlow.Server.Storage.RemoteReader is trying to retrieve the image, but I'm getting an error about a missing or invalid signature:

Imageflow.Server.Storage.RemoteReader.RemoteReaderService: Warning: Missing or Invalid signature on remote path: /remote/...

I have a signing key configured:

var remoteReaderServiceOptions = new RemoteReaderServiceOptions
{
    SigningKey = "00e17d53-86b7-487d-ba15-7a9eb759e5bf"
}
.AddPrefix("/remote/");

services.AddImageflowRemoteReaderService(remoteReaderServiceOptions);

Do I need to whitelist the server domain somehow?

twwilliams commented 2 years ago

And even if I avoid the rewrites and explicitly create the URL, I get the same error

@{
    var remoteUrl = "http://server.example.com/images/08f1a2712bb4458ab7e7a44cb7e6f640a.jpg";
    var encodedRemoteUrl = RemoteReaderService.EncodeAndSignUrl(remoteUrl, "00e17d53-86b7-487d-ba15-7a9eb759e5bf");
    var modifiedUrl = $"/remote/{encodedRemoteUrl}";
}
<img src="@modifiedUrl">

Going through the source code, it looks like the hmac in the encoded value doesn't match what is expected.

twwilliams commented 2 years ago

The signature problem was due to an IIS-level rewrite that was converting all URLs to lowercase.

I ended up implementing the rewriting I needed by creating an IRule class and adding it into the rewrite middleware we already had in place in Startup.cs.