peteboere / css-crush

CSS preprocessor.
http://the-echoplex.net/csscrush
MIT License
537 stars 51 forks source link

URL rewrites include part of the doc_root #54

Closed triplejumper12 closed 10 years ago

triplejumper12 commented 10 years ago

Let's say my doc_root is at /var/www. I have my initial file at /var/www/css/style.css that includes the import:

@import "/js/project/project.css"'.

My project.css file includes relative urls to images for backgrounds.

background: #dddddd url(images/image.png)...

The image's absolute path is /var/www/js/project/images/image.png.

When this gets rewritten to it's relative url, it steps below the doc_root. It gets rewritten to "../../www/js/project/images/image.png", when it should be "../js/project/images/image.png".

I'm generating the crushed file by calling:

CssCrush::file('/css/style.css', array('doc_root' => '/var/www'));

This was working in 1.11, but stopped working in 2.0.0 and still doesn't work in 2.0.1.

peteboere commented 10 years ago

Thanks for reporting this.

It's a tricky area, I'll look into it when I get a moment.

nrdobie commented 10 years ago

:+1:

peteboere commented 10 years ago

@triplejumper12 I've copied as you've described but it works fine for me (using PHP 5.4 builtin server).

The problem might be related to some server url rewriting. In fact I'm considering deprecating allowing the implied URL root paths e.g. '/css/styles.css' because of how it can be easily broken by url rewrites and server aliases.

Using the full system path, or relative path, is usually safer:

$file = csscrush_file(__DIR__ . '/css/style.css', $options);
// or relative 
$file = csscrush_file('css/style.css', $options);
triplejumper12 commented 9 years ago

@peteboere If all the style sheets live within the doc_root, it works properly. However, if you have css files that live outside of the doc_root, that is when it will step below the doc_root.

For instance. From my example above, it breaks if my initial file lives at /var/lib/css/style.css, my doc_root is at /var/www, and I'm importing a third party's css from /var/www/js/project/project.css into my crushed file. If that imported file contains relative paths to images, it looks like it is trying to make a relative URL from the path of the initial file (/var/lib/css/style.css) instead of from the imported file's location (/var/css/js/project/). My new url looks like ../../www/js/project/images/image.png when the full path is /var/www/js/project/images/image.png, and the expected url is /js/project/images/image.jpg.

I've tried running it with: CssCrush::file('/var/lib/css/style.css', array('doc_root' => '/var/www'));

I also tested it by symlinking the css into my web_root. ln -s /var/lib/css/style.css /var/www/css/style.css

Still fails when running: CssCrush::file('/css/style.css', array('doc_root' => '/var/www')); And: CssCrush::file('/var/www/css/style.css', array('doc_root' => '/var/www'));

If I had control over the css I'm importing, I could change all the urls to be absolute from the doc_root and it will work. However, I do not have control over all the css we are using. Sure I could modify the css or fork the project we're using, but that causes more complexity and potential issues when it comes time to update those projects.

Thoughts?