Bootstrap less image URLs

238 views
Skip to first unread message

Greg Pendlebury

unread,
Jun 5, 2014, 10:54:22 PM6/5/14
to wr...@googlegroups.com
Heyo,

First of all, I'm very happy with wro4j and want to say thanks to any/all open source contributors. I think it is fantastic. I've spent the last couple of days playing around on a demo system and am now nearing the end of completely converting one of our larger apps. The results have been dramatic (like dropping 70+% of download size on some screens).

The last (I hope) hurdle I've run into is getting the CSS URL rewrite feature to play nicely with Bootstrap 2.3.2 from a webjar. I got this working (with help from Alex... thanks) using CSS, but in our main application the LESS imports are used. It appears that because Bootstrap has the URLs stored in LESS variables (eg. @iconSpritePath) that the CSS URL rewriter does not notice them, and then attempts to retrieve them fail with security exceptions.

For example, using CSS, the images are successfully rewritten to:
/static/article.css?wroAPI=wroResources&id=classpath:/META-INF/resources/webjars/bootstrap/2.3.2/img/glyphicons-halflings.png

But using LESS we get:
/static/article.css?wroAPI=wroResources&id=classpath:/META-INF/resources/webjars/bootstrap/2.3.2/less/../img/glyphicons-halflings.png

I think that the problem is the URL rewriter is generating converting this:
background-image: url("@{iconSpritePath}");
to this:
background-image: url("/static/article.css?wroAPI=wroResources&id=classpath:/META-INF/resources/webjars/bootstrap/2.3.2/less/@{iconSpritePath}");
and then the LESS compiler drops "../img/glyphicons-halflings.png" on the end.

At face value this is a good URL, but there is an authorisation exception retrieve because (just guessing here) that the URL rewriter did not see the whole URL when it parsed the import originally. This was my assumption because I tried manually loading the 'good' url:
/static/article.css?wroAPI=wroResources&id=classpath:/META-INF/resources/webjars/bootstrap/2.3.2/img/glyphicons-halflings.png
and it also gets an error, despite having a a correct URL.

Has anyone got this setup working? Is it just a matter of arranging pre/post processors in a particular way? The setup I've got now is:
managerFactoryClassName=ro.isdc.wro.extensions.manager.ExtensionsConfigurableWroManagerFactory
preProcessors
=cssUrlRewriting,lessCssImport,semicolonAppender
postProcessors
=less4j,jsMin

Haven't gone near css minification yet. I just removed it from the picture whilst testing. I've also tried 'lessCss' just to confirm they make no difference.

Any tips would be appreciated.

Ta,
Greg

Alex Objelean

unread,
Jun 6, 2014, 5:34:17 AM6/6/14
to wr...@googlegroups.com
Hi Greg,

The first suggestion is to use the cssUrlRewriting processor after the lessCssImport, so that the less variables are replaced when the url are rewritten and authorization is properly applied.

Also, I would recommend using less4j processor, as it is much faster comparing to lessCss (which is based on rhino) and also handles the import statements without needing additional lessCssImport processor. 

Onother solution is to customize ResourceAuthorizationManager. This way you could control which url is authorised. 

Let me know if any of the above solutions works for you.

Cheers,
Alex

Greg Pendlebury

unread,
Jun 9, 2014, 6:55:12 PM6/9/14
to wr...@googlegroups.com
Thanks for the reply, and sorry for delay; it was a long weekend here (ACT, Australia).

I had avoided having the URL rewriter after import because of the problem on the known issues page. I've tested it now though and it still doesn't work, so I'll take a look at the ResourceAuthorizationManager now.

I was also thinking over the weekend about having a post processor that did a similar job to the CSS URL rewriter, but rather than rewriting, it just notified the authorisation manager of anything it found. It would only make sense when paired with the cssUrlRewriting pre-processor.

Ta,
Greg


--
You received this message because you are subscribed to the Google Groups "wro4j" group.
To unsubscribe from this group and stop receiving emails from it, send an email to wro4j+un...@googlegroups.com.
To post to this group, send email to wr...@googlegroups.com.
Visit this group at http://groups.google.com/group/wro4j.
For more options, visit https://groups.google.com/d/optout.

Greg Pendlebury

unread,
Jun 10, 2014, 1:13:52 AM6/10/14
to wr...@googlegroups.com
Ok, so I've got it working now by adding a new processor. Thought process:
 1) hardcoding assets into the authorization manager was pretty unappealing,
 2) and even if I got it to read from a config file it would end up being weird for our UX designer to debug that process and remember to add them to a special file...
 3) Trying to make it smarter and match 'almost' URLs seemed like it would open us up to potential problems with people poking around on the classpath... those asset URLs 'look' pretty exposed already and will likely tempt some to try.

So the new processor is a copy/paste job from the CssUrlRewritingProcessor with most logic gutted. It just looks for URLs, confirms that they have 'classpath' in them, and makes sure that they are authorized.

Now our processors look like this:
managerFactoryClassName=ro.isdc.wro.extensions.manager.ExtensionsConfigurableWroManagerFactory
preProcessors=cssUrlRewriting,lessCssImport,semicolonAppender
postProcessors=less4j,cssClasspathUrlAuthorization,jsMin

If that sounds acceptable I can send a pull request with the new processor?
https://github.com/nla/wro4j/commit/ea2ccc3fd6a0a81c0c3e83f516b16a57d0b712c0

It includes two unit tests.. one in the core to ensure that using the processor does not alter the asset's contents, and another in the extensions module which goes through the reproduction steps of the two other processors interacting to break URLs and then fixes them.

I couldn't get a base build to pass the unit tests anyway, so I'm not sure how I need to hold my tongue on that one, but they pass in isolation at the very least, and I've put the 1.7.6-SNAPSHOT into our project for testing and it work fine and makes the problem go away.

Ta,
Greg

Greg Pendlebury

unread,
Jun 10, 2014, 9:57:27 PM6/10/14
to wr...@googlegroups.com
It now extends CssUrlRewritingProcessor, which I think means it is a bit more 'weighty' in terms of work done, but is certainly a lot less code and more maintainable.

Also removed the 'classpath' check.

Ta,
Greg
Reply all
Reply to author
Forward
0 new messages