I'm no expert in this stuff so I won't comment too much on the mechanism.
One comment I do have is that "should_serve_asset" being either undef or
sub { 1 } both mean yes is really confusing. I'd suggest that you make the
static yes/no be booleans and only consider the subref if passed a subref.
(Aside: you could even take it further I suppose and have any non-sub value
be false and require sub { 1 } to mean always true, but that does introduce
some inefficiency.)
Cheers,
Joel
On Thursday, April 11, 2019 at 12:05:50 AM UTC-5, Adam Hopkins wrote:
>
> I've come up with an attempted solution. It's not finished yet (no tests
> and I haven't published to CPAN), because I was hoping to get some feedback
> if anyone has time before I move further in case it's not a great solution
> :)
>
> I created a role that uses the before method modifiers on serve_asset
> <https://metacpan.org/pod/Mojolicious::Static#serve_asset> and is_fresh
> <https://metacpan.org/pod/Mojolicious::Static#is_fresh>.
>
> In the serve_asset before, I check if serving a compressed asset is
> appropriate (the asset is a Mojo::Asset::File, the compressed asset exists
> for the file, the client accepts that type of encoding), and then serve if
> while adding the necessary headers (content_encoding, etc). If none of
> those conditions are met, the uncompressed asset will be served.
>
> The is_fresh before method is used only if a compressed asset exists to
> set the last modified time of the compressed asset to the last modified
> time of the uncompressed asset, and also to modify the etag to contain the
> encoding at the end.
>
> I would really appreciate any feedback or recommendations :) Here's a link
> to the github repo, which has a README with documentation:
>
> https://github.com/srchulo/Mojolicious-Static-Role-Compressed
>
> On Monday, April 1, 2019 at 11:38:55 PM UTC-5, Adam Hopkins wrote:
>>
>> Hi all,
>>
>> I wanted to get some feedback on how to approach serving compressed
>> static assets. I have my static assets along with pre-compressed versions
>> of the assets via gzip and brotli. I’d like to serve static assets first by
>> the brotli compressed asset if it exists, then gzip if it exists
>> (preferrably the smallest first, but that should be the brotli asset if it
>> exists), then the regular asset if there is neither.
>>
>> I had mentioned this in the #mojo IRC channel, and kraih and batman had
>> recommended maybe this would make sense as a part of
>> Mojolicious::Plugin::AssetPack
>> <https://metacpan.org/pod/Mojolicious::Plugin::AssetPack>. However, now
>> I already have the assets compressed, so I’m not sure that this would make
>> sense.
>>
>> A suggestion was made that a before_dispatch
>> <https://mojolicious.org/perldoc/Mojolicious#before_dispatch> hook could
>> maybe look at Accept-Encoding and modify the request if gzip or br was
>> accepted and the file existed. I have a few concerns with this after
>> thinking about it. One is that this won’t work for static files that are
>> served via reply->static
>> <https://metacpan.org/pod/Mojolicious::Plugin::DefaultHelpers#reply-%3Estatic>,
>>
>> or serve in Mojolicious::Static
>> <https://metacpan.org/pod/Mojolicious::Static#serve>. Another concern is
>> that the Last-Modified time for asset.css.gzip isn’t guaranteed to be the
>> same as asset.css, and I feel like asset.css’s Last-Modified time is what
>> should be used. Another is that ETags are suppose to be content coding
>> aware:
>>
>> https://tools.ietf.org/html/rfc7232#section-2.3.3
>>
>> And since Mojolicous::Static
>> <https://metacpan.org/pod/Mojolicious::Static> calls md5_sum
>> <https://metacpan.org/pod/Mojo::Util#md5_sum> on the files Last-Modified
>> time, it’s not guaranteed that the different content-codings will have
>> different ETags.
>>
>> After thinking about all of this, it seems like what would need to be
>> done is create a Mojolicious::Static
>> <https://metacpan.org/pod/Mojolicious::Static> class or a subclass. I
>> believe maybe just serve in Mojolicious::Static
>> <https://metacpan.org/pod/Mojolicious::Static#serve> would need to be
>> overridden. However, I definitely prefer to avoid this approach as changes
>> in Mojolicious::Static <https://metacpan.org/pod/Mojolicious::Static> or
>> what methods Mojolicious <https://metacpan.org/pod/Mojolicious> expects
>> the object in static <https://metacpan.org/pod/Mojolicious#static> to
>> handle could cause it to break. Also, there's a lot of HTTP/RFC login in
>> serve, and I'd prefer not to mess with that.
>>
>> Is there a good way to solve this with a plugin? Or am I correct in
>> assuming that this would need to happen at some level in the object in
>> static <https://metacpan.org/pod/Mojolicious#static>?
>>
>>
--
You received this message because you are subscribed to the Google Groups
"Mojolicious" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
To post to this group, send email to [email protected].
Visit this group at https://groups.google.com/group/mojolicious.
For more options, visit https://groups.google.com/d/optout.