I just noticed this while looking at the details page of a watchdog report. The location field starts with double slashes (my drupal site is on the root).

Following the cause, I've obeserved that this field is populated from request_uri() which loads the data from the $_SERVER array. URIs here are prefixed with a slash, and that's what gets stored in the watchdog table.

Then, watchdog reports uses l($watchdog->location, $watchdog->location) to render the location URI, function l() calls function url() to format the URI. And it is here when base path prefixes those URLs (note that argument $absolute is FALSE).

If argument $absolute wa TRUE, the the resulting URL would look like http://www.example.com//resource (note double slashes here as well)

Conclussion: function url() generates malformed URL when $path argument is prefixed with a slash.

Not sure how to better fix, though.

Comments

chx’s picture

Fix is possible two ways. Either we need to apply trim($string, '/'). a) fix this place only b) fix request_uri. I have looked at includes and b) causes no apparent problem there. I am wary of the two usages in modules though.

Oh, a third way is to trim on INSERT. Looking at alternatives, this looks best...

markus_petrux’s picture

The heart of the problem is located in funtion url() though. Someone else, for whatever reason, could use url() (or function l()) with a path prefixed with a slash.

markus_petrux’s picture

Status: Active » Needs review
StatusFileSize
new426 bytes

hmm... in function url() if the argument $path is prefixed with a slash, it means it has already been prefixed with $base_path, right? So, all we have to do is check, if $path[0]=='/' then remove the $base_path.

Am I missing something?

markus_petrux’s picture

Forgot to say I made some tests, and seems to work. But I'm afraid to say it is the best approach.

chx’s picture

I'd rather not add another check to url(). That function is not to be called with a slash'd path IMO.

dries’s picture

url() and l() are called an aweful lot. Often, their accumulated cost exceeds the accumulated cost of all database queries.

Maybe better to modify request_uri() to return a Drupal path. In the code, Drupal paths don't have a leading '/'.

markus_petrux’s picture

But if you tough request_uri() to not return the leading slash, that will break other places where request_uri() is used, becuase they rely on that leading slash. This is something that will probably break contrib modules.

markus_petrux’s picture

sorry: s/tough/touch

Torenware’s picture

Title: function url() generates malformed URL when $path argument is prefixed with a slash » Patch of 31 Jan had "$base_path" and not "$path"
StatusFileSize
new623 bytes

Old patch did not work; the new patch here does work.

dries’s picture

IMO, it would be cleaner if all functions would use the same URL syntax. Having some functions return a leading slash, and some functions not, is going to be confusing.

Torenware’s picture

Title: Patch of 31 Jan had "$base_path" and not "$path" » Cases where we call request_uri

Cases where we make no assumptions about concatenating to the $base....

form
locale
system_elements
watchdog

Cases where we make assumptions

page_get_cache (bootstrap.inc)
page_set_cache

So it appears that the fix should include a check in request_uri, and adding a slash in page_get_cache and page_set_cache.

Torenware’s picture

Title: Cases where we call request_uri » Patch to fix request_uri, page_set_cache, page_get_cache
StatusFileSize
new1.45 KB

The attached patch guarantees that request_uri does not return a trailing slash, and removes any code that assumes that request_uri might return a trailing slash.

Torenware’s picture

Title: Patch to fix request_uri, page_set_cache, page_get_cache » I can't verify that the new patch actually fixes your problem

markus_petrux: I'm not really set up to verify that my new patch really fixes your issue with watchdog.

Could you please see if applying this patch works correctly for you? It does not seem to cause any harm, but I'm also not sure if it will really help either.

Once you can verify that this fixes the problem, Dries will give it another look.

Thanks,
Rob Thorne
Torenware Networks

Steven’s picture

Title: I can't verify that the new patch actually fixes your problem » function url() generates malformed URL when $path argument is prefixed with a slash

Please keep the issue title static.

markus_petrux’s picture

Title: function url() generates malformed URL when $path argument is prefixed with a slash » function url() generates malformed URL when $path argument is prefixed with a slash

Torenware: I believe your patch doesn't fix the problem.

1) It is the leading slash that would have to be stripped out.
2) Note that $base_path is included request_uri, you would have to strip it too.

Not sure if this is the best approach, this way request_uri() would always be relative to $base_path, so that changes the meaning, maybe also the original purpose of that function? Can that lead to break contrib modules that need a reliable method to obtain the real request uri?

markus_petrux’s picture

Another consideration. Watchdog uses request_uri() to capture the current location where the event occurred. Ok.

If you redirect access denied requests to your Drupal installation, then request_uri() may point to non Drupal paths. Say Drupal is not on the root folder, say you have a folder htaccess protected that generates 403 errors, that are captured by Drupal's watchdog. In this case request_uri() MUST point to the correct resource. See what I mean?

IMHO, patch in comment #3 (or something on that direction) is the way to go.

markus_petrux’s picture

What I mean is, IMO, request_uri() is correct as it is. What needs to be fixed is the way l() deals with absolute paths, or the way certain urls are built.

m3avrck’s picture

This is related to another fix I have for l() as well:

http://drupal.org/node/41595

markus_petrux’s picture

Status: Needs review » Fixed

I believe this has been fixed already.

Anonymous’s picture

Status: Fixed » Closed (fixed)