The Slim Framework support forum has moved to http://discourse.slimframework.com. This Tender forum is no longer maintained or monitored.

URL routing breaks if rewrite rules don't match underlying structure

Zachary Tong's Avatar

Zachary Tong

17 May, 2012 09:34 PM

Another "not sure if this is a problem", but I wanted to report that Slim breaks if the URL rewrite rules do not match the underlying file structure. Here is an example:

RewriteCond %{REQUEST_URI} ^/api/v1/(.*)$
RewriteRule $ /api/v1.0/dispatch.php/%1 [L]

This actually occurred because of a typo (v1.0 compared to v1), but it lead me to finding this particular bug, if you wish to call it a bug. Here is some debug information taken from Environment.php:

[request_uri] => /api/v1/dispatch.php/202cb962ac59075b964b07152d234b70/tags/

[script_name] => /api/v1.0/dispatch.php

[env.path_info] => ispatch.php/202cb962ac59075b964b07152d234b70/tags/

[env.script_name] => /api/v1.0

Basically, the substr_replace that occurs in Environment.php removes too many characters because the request URI is different from the script name path.

  1. 1 Posted by PusherTech on 06 Jul, 2012 12:14 AM

    PusherTech's Avatar

    This is/was a real problem for our site (pusherhq.com). The getResourceUri() was (incorrectly) returning an empty string after adding some RewriteRules in our htaccess file. The PATH_INFO in fact was not starting with the SCRIPT_NAME.

    It'd be great to see a proper fix to avoid the kludge we added to our code to get around it.

  2. Support Staff 2 Posted by Josh Lockhart on 06 Jul, 2012 12:54 AM

    Josh Lockhart's Avatar

    @Zachary Which version are you on? Does this still occur on the latest version (1.6.4)?

    -Josh

  3. Support Staff 3 Posted by Josh Lockhart on 06 Jul, 2012 01:05 AM

    Josh Lockhart's Avatar

    I'm not convinced this is a bug. I'm also not sure why you would install a Slim app into a physical, public subdirectory but access it with a request URI that did not include the physical sub-directory path in the request URI. Can you? Sure. Why would you? I'm not really sure.

    I recommend that you either install Slim into the root of your virtual host. If you choose to install it into a physical sub-directory, then the physical path to the app must be present in the request URI for Slim to parse the request URI properly.

    If I'm missing something obvious, definitely let me know. But I don't think I am.

    Best regards,
    Josh

  4. 4 Posted by Zachary Tong on 06 Jul, 2012 02:14 AM

    Zachary Tong's Avatar

    My original "bug" was on version 1.6.0. We haven't updated to 1.6.4 yet, but I'll see about getting it switched sometime in the near future when we have a chance to test it out. I'll check back in with my observations then.

    At least in our situation, the "bug" was entirely due to a typo in the rewrite rules. We fixed the typo, not Slim. But it took me long enough to hunt down that I felt it a good idea to share, in case someone else runs into a similar problem.

    I know I usually treat Rewrites like magic routing, where you can twist the URIs into any format you want/need. Might be appropriate to put a disclaimer somewhere that Slim requires the URI to remain intact. Not a bug, but probably a requirement?

  5. 5 Posted by PusherTech on 06 Jul, 2012 03:27 AM

    PusherTech's Avatar

    @Zachary: thank you for your post - it definitely helped determine why the resourceUri was ending up blank for us.

    @Josh, great to see the prompt replies. Slim is a fantastic framework - inspiring job you've done!

    ....

    Regarding the problem pusherhq.com ran into -

    First, to answer the question "why you would install a Slim app into a physical, public subdirectory but access it with a request URI that did not include the physical sub-directory path in the request URI":

    The broader problem is web host restriction: all servable files (for all sub-domains) need to be under a fixed "public_html" folder. We were attempting to set up multiple Slim instances under there (e.g. version one under "public_html/www/v1", version two under "public_html/www/v2") and just use an RewriteRule to effectively change the document root to public_html/v1/public, etc. (Why we wanted different versions we could change rather easily is an issue entirely unrelated to Slim.) There are probably other (and better) ways to set things up but, given the web host restrictions and the fact we have things setup in git repositories in this structure, it seemed in theory like our setup should work just fine (or to flip that over, why wouldn't that work?). The above was at least why we had Slim apps in physical, public subdirectories but weren't accessing them via that physical, public subdirectory as the full URL.

    ...

    Second, taking a narrower look at the "problem" and looking at the code in isolation (temporarily ignoring the broader question of "Why would you even run into this in the first place?" for the moment), the following code in Environment.php...

    $env['PATH_INFO'] = substr_replace($_SERVER['REQUEST_URI'], '', 0, strlen($env['SCRIPT_NAME']));
    

    ...read to me as "Remove the prefix env['SCRIPT_NAME'] from env['REQUEST_URI']". Again looking only at that one line of code in isolation of the context, it seemed to me that it perhaps should check that the prefix actually is a prefix REQUEST_URI before attempting to remove, if that's what the real intent is. Sure, it may be defined that in any "valid" scenario it will be a prefix - I'll buy that as a valid argument for leaving the code as is. Maybe some sort of error if it's not found to be a prefix is appropriate? (e.g. "Error: Slim must be installed into a physical, public subdirectory such that the request URI includes the physical sub-directory path in the request URI.") That was my initial reaction in any case.

    ...

    I hope that at least clarifies why this seemed (at least to us) like it might be a bug. I certainly would agree that a larger problem might simply be that the web host doesn't allow the document root of the "www" sub-domain to be simply set to a different directory than the fixed public_html.

    By the way, the kludge I stuck in there to work around the issue (this is not a general fix, just enough to get us going) was roughly just to remove the prefix if and only if it actually is a prefix (this code may not be exactly right - I'm typing it from memory):

    /* Remove the SCRIPT_NAME prefix if and only if it's part of the request URI path */
    $requestUri = $_SERVER['REQUEST_URI'];
    $scriptName = $env['SCRIPT_NAME'];
    $prefixLen = strlen($scriptName);
    if (substr($requestUri, 0, $prefixLen) === $scriptName) {
        $env['PATH_INFO'] = substr_replace($requestUri, '', 0, $prefixLen);
    } else {
        $env['PATH_INFO'] = $requestUri; 
    }
    

    Hope that helps explain the issue. Thanks again for the excellent work on Slim!

  6. 6 Posted by PusherTech on 06 Jul, 2012 03:31 AM

    PusherTech's Avatar

    I should also add, this was an issue with version 1.6.0. I've not yet tested a newer version.

  7. Support Staff 7 Posted by Josh Lockhart on 06 Jul, 2012 12:46 PM

    Josh Lockhart's Avatar

    @PusherTech Thanks for the detailed explanation. I can see the dilemma if you are unable to access above the document root. You also make a fair point that I should make the install requirements more clear... I'll do that this weekend.

    I'll use your suggestions and run some tests this weekend to see what I can do without breaking existing apps.

    For now, I recommend you setup multiple subdomains for each app to keep things simple without resorting to htaccess wizardry :)

    Best,
    Josh

Reply to this discussion

Internal reply

Formatting help / Preview (switch to plain text) No formatting (switch to Markdown)

Attaching KB article:

»

Attached Files

You can attach files up to 10MB

If you don't have an account yet, we need to confirm you're human and not a machine trying to post spam.

Keyboard shortcuts

Generic

? Show this help
ESC Blurs the current field

Comment Form

r Focus the comment reply box
^ + ↩ Submit the comment

You can use Command ⌘ instead of Control ^ on Mac