getCss returning local paths

Hi there, can’t work out what I’m doing wrong here, please could someone have a read and see what they think?

Have been running Piwik on a pair of balanced webservers for a while and wanted to move our install to a different pair.

First attempt was to copy db, copy files and try and access. At this point getCss was returning local paths in the CSS, so a number of images weren’t loaded. Since then I have deleted whole source, and re-uploaded, and have also done the upgrade process twice (been trying that long!). Have searched the DB for references to the old or new path and can’t see it anywhere, have also checked the config and it’s not in there either.

I’ve even done a completely fresh install of 1.2.1 from scratch and I still have the same issue

Any ideas what I’ve done wrong?

Windows Server 2008 R2 64-bit, PHP 5.3.5, MySQL 5.1.49 (ubuntu). Tested in Chrome and FF.

Thanks for your time.

don’t copy the /tmp directory

Thanks for your suggestion, I had previously tried a re-install (as in delete and re-upload) but just tried it again and still the same.

So it’s a completely stock install, new files, new DB and it’s still doing it. Happy to accept if it’s something I’ve done wrong, but I had no such issues on the previous install (my earliest install files are 0.6.4, but I know i’ve installed before then).

Could it be related to the path itself causing some conflict/confusion? As far as I am aware the setup is exactly the same, I used MS Web platform installer to install PHP, it’s running under FastCGI (as it was before). It’s a newer version of PHP than on the running boxes, could that be it?

There are no hard-coded, absolute paths in the source; the css only contains relative URLs (as far as I can see) within the document root.

So it shouldn’t matter as long as the directory structure is mirrored on each server.

Hi,

that’s exactly the problem, there are full file paths in there, local paths on the server, not URL paths.

e.g.:

http://my.piwik.url/index.php?module=Proxy&action=getCss&cb=

In that, an example “wrong” entry is:


.header_alert{background:#FFFDF7 url(C:/full/path/to/files/on/server/themes/default/images/ico_alert.png) no-repeat 7px 4px;border:1px solid #FF7F00 ;font-weight:bold;}

There are numerous examples of this throughout that file. As I’ve done the re-installs enough times now, I’m going with a bug/incompatibility with my setup, so will gather as much data as I can and do a bug report. Unless anyone else mentions that they’ve also seen this happen. Will try and scour the source as well, just in case it’s an obvious enough fix.

Look at core/AssetManager.php’s generateMergedCssFile() function (around line 120) that rewrites the url paths.

At line 95 of core/AssetManager.c, try changing:


// absolute path to doc root
$rootDirectory = realpath(PIWIK_DOCUMENT_ROOT);

to:


// absolute path to doc root
$rootDirectory = str_replace('\\', '/', realpath(PIWIK_DOCUMENT_ROOT));

Check to see if create_function and/or preg_replace_callback are disabled functions on your new servers?

Hi, thanks for response and so sorry I haven’t got back to you sooner, client work has superseded this server move!

Anyway, have updated to 1.4, tried your code change and it didn’t work, so tested the two functions you mentioned using examples of their php man pages and both do work.

Am at a complete loss as to what’s going on, both systems are near enough identical, no other PHP application has had this issue, but then no-one else seems to have experienced this issue!

EDIT: Previous edit was red herring

EDIT2: Adding the following to line 124 of AssetManager.php is a dirty workaround but fixes it for now:


$content = str_replace("C:/Data/replicated/web/stats.dixcart.net/content", '', $content);

Hmm… If you delete the files in tmp/assets/, and dump some additional info, we might be able to figure this out, e.g.,


                        $baseDirectory = dirname($file);
var_dump($rootDirectory, $baseDirectory, $content);
                        $content = preg_replace_callback(
                                "/(url\(['\"]?)([^'\")]*)/",
                                create_function(
                                        '$matches',
                                        "return \$matches[1] . str_replace('\\\\', '/', substr(realpath(PIWIK_DOCUMENT_ROOT . '/$baseDirectory/' . \$matches[2]), $rootDirectoryLen));"
                                ),
                                $content
                        );
var_dump($rootDirectory, $baseDirectory, $content);

You can PM the results to me.

That’s really interesting actually, the first dump of $content is correct, it’s not until it passes through the preg_replace_callback that it gets broken.

Other than that $rootDirectory is (false) both times and $baseDirectory is “themes/default” both times.

Interesting. realpath() is broken in some way.

Can you test a little script?


<?php
var_dump(realpath('C:/'), realpath('C:/Data'), realpath('C:/Data/replicated'), realpath('C:/Data/replicated/web'), realpath('C:/Data/replicated/web/stats.dixcart.net'));

Are you using symlinks for any of these folders?


string(3) "C:\"
string(7) "C:\Data"
string(18) "C:\Data\replicated"
bool(false)
bool(false)

Interesting you should say that, the old servers DO use symlinks but these ones DON’T! Which I would hazard guess at being the opposite way round to what you expect.

I wondered if it could be permissions based (the user the site runs under only has access to …/content/ onwards) but adding the content folder to the realpath list also returns a false.

This does however prove that it is a config and not a piwik issue, so thank you for all your help so far, understand if you want to cut me loose now :slight_smile:

EDIT: it is permissions. PHP realpath() problem : The Official Microsoft IIS Forums - basically for realpath to work, the user the site runs under has to have read permissions on the directory above your website. There was me trying to set things up “properly” and it’s caused this issue all along!

Thanks again for identifying where the issue was, a simple fix from there!

It’s actually a php bug in php 5.3.x. PHP :: Bug #54110 :: tsrm_realpath_r and junction point with denied read access

I’ll try to figure out a workaround in the next release.