ctm / mb2-doc

Mb2, poker software
https://devctm.com
7 stars 2 forks source link

Add a content-based etag wrapper #1295

Closed ctm closed 6 months ago

ctm commented 6 months ago

Create an actix-web middleware that maps actix-web meta-data based etags to content-based etags.

As I mentioned here, actix-web's etags are done using meta-data that changes from deploy to deploy, so even though our mp3 files aren't changing, they have to be downloaded anew after every deploy (and I deploy several times a day). Since we know the paths of all the static assets that we serve, it's easy enough to precompute the actix-web etag for each of the static files and also compute a digest from the file contents and then create a mapping that is passed to the middleware to substitute the digest for the actix-web etag. At least I think we can pass in a mapping to middleware; I haven't looked at it yet.

ctm commented 6 months ago

FWIW, looks like at startup we can call NamedFile::open(...).into_response() to get something that will have the etag that actix-files creates. The HttpResponse that is returned might be able to be turned into bytes via try_into_bytes, but I don't know for sure and it doesn't really matter, since we can just do the IO ourselves using path that we'll hand to open.

At first glance, it looks like actix_web::App::wrap_fn will allow us to move a Hash into the closure.

So, with the above parts, I should be able to cobble together a proof-of-concept pretty quickly and if that works, expand it to work for all the static files we serve. This isn't labeled high priority, but I still may wind up working on it when I'm tired since it appears to be drop dead simple.

ctm commented 6 months ago

Ugh. into_response takes an &HttpRequest as an argument and there's no way to construct an HttpRequest. Duplicating the functionality of the etag creation code should work until they change that code, but is ugly and could break with any upgrade.

ctm commented 6 months ago

The joys of programming when tired…

I wrote my previous comment hours ago, but never clicked the "Comment" button. I then went on and duplicated the NamedFile::etag code and got middleware that replaced the outgoing etag with a content-based one. It didn't work locally, so I tried deploying it to craftpoker.com and it didn't work there, either. Duh!

In order to work, instead of a HashMap from actix-etag to content-digest, I need a BiMap and then I need to replace the request etag on the way in, in addition to replacing the response etag on the way out.

That's really not hard to do, but I'm leaning toward taking a nap between now and this evening's game.

ctm commented 6 months ago

I didn't take a nap. I did add the BiMap. It does work, except I forgot about weak etags, and the .wasm uses them, so although I got gong.mp3 to be cached across deploys, I broke the largest file being cached. Ugh. I'll get it fixed, but not in time for this evening's game.

ctm commented 6 months ago

Fixed. Tested locally. Deployed. Tested on craftpoker.com.