How to make Apache pass control to Laravel for specific URLs - laravel

I have a Laravel route for /ad-reports/ and /ad-reports/promos that worked fine until I put directories matching those names inside public. Why did I do that? I need them for caching, so that a request for (e.g.) /ad-reports/promos/12345.pdf gets handled by Laravel if there is no PDF named 12345.pdf saved inside public/ad-reports/promos, but by Apache if the PDF has already been created and saved there.
I don't want to mess with my URL structure (the whole point of having routing is so we're not forced to let the file system dictate our URLs) and of course I can't afford to give up the caching.
How can I force Apache to ignore requests for /ad-reports/ and /ad-reports/promos, but handle everything that it should handle?
Or alternately (and better, actually) how can I make Apache ignore requests for folders, and only respond to requests for specific files, letting Laravel handle anything that does not match a file inside public?

Remove this line from your .htaccess file:
RewriteCond %{REQUEST_FILENAME} !-d
It tells apache to handle the directory if the directory exists, but you only need it to handle if the file exists, which is done by the -f line.

Related

Apache2 mixing mod_vhosts_alias and mod_rewrite

The Apache2 docs recommend mod_rewrite as a last resort for specifying which directory to send a given host request to. They said use mod_vhosts_alias. I set that up and its working without problem. However, I have a specific case that entails some mod_rewriting.
I have a domain like mydomain.com and a large number of subnames like sub.mydomain.com and sub2.mydomain.com. These subdomains all map to corresponding directories. But the subdomains will also have full top-level domains that map to respective directories. For instance:
sub.mydomain.com will map to the same directory as awesomeproducts.com sub2.mydomain.com will map to the same directory as widgets.com
What would be the best way to make sure both these methods of accessing each site will work without conflict?
Since the docs only say mod_rewrite isn't as "graceful" as mod_vhosts_alias, I didn't know if I ought to use mod_rewrite completely by itself for my situation or if I should be trying to mix the two approaches somehow.
Is mixing them the way to go or will that create problems?
The behaviors of RewriteRule and RewriteCond change when using mod_vhost_alias. Its been a few days since I tinkered with it so I'm sketchy on it, but watch out for the way RewriteRule interprets the portion of the URL to be rewritten. It may change when using mod_vhost_alias... and RewriteCond behavior might change too.
To accomplish the question I was asking about, I ended up using symbolic links for the actual domains. I setup a bunch of subdomains with associated folders so that sub1.stddomain.com would go to the folder sub1.stdomain.com. Then I added a symbolic link that maps domain1.com to the sub1.stddomain.com folder. That way anyone who visits domain1.com is shown the site in the sub1.stddomain.com folder.
IMPORTANT: After all that work and testing, I ended up going back to to a collection of virtualhost files WITHOUT mod_vhost_alias. Turns out that there is a known problem with mod_vhost_alias. DocumentRoot isn't correctly set when using it. This breaks tons of scripts. It was patched in February 2012 with new special variables and the programming team at Apache dropped the ball. They never wrote any documentation explaining how to use the patch or new variables.
I reopened the issue and stated that its still a bug since you can't write code and not tell anyone how to use it and then call it fixed. Unfortunately the issue had already been ignored for YEARS and it will probably continue to get ignored even though they supposedly wrote code for it.
RECOMMENDED LESSON FROM ALL THIS: Don't use mod_vhost_alias. Write shell scripts to manage your vhost files using one more template files.

Apache Redirect on downstream 404

We are building a mobile site whose url structure matches our current desktop site. We are hosting them on the same domain, and using apache to filter traffic between them using WURFL to help decide which agents go where.
Our filtering rules currently look like this:
RewriteCond %{HTTP_COOKIE} "bucket=mobile"
RewriteRule ^(.*)$ http://internal-mobile-pool.ourdomain.com/$1 [P]
RewriteRule ^(.*)$ http://internal-desktop-pool.ourdomain.com/$1 [P]
Our WURFL based solution sets the 'bucket' cookie for us.
The problem we are facing is that not all the urls on our desktop site have been re-implemented on our mobile site. What I would ideally like, is for the above rule to apply, but if it tries to go to the mobile servers, and gets a 404, it serves up the content from the desktop servers instead.
ie If a mobile requests www.ourdomain.com/some_desktop_only_resource.html, and the internal-mobile-pool.ourdomain.com/some_desktop_only_resource.html returns a 404 - for it to return the content on desktop-pool.ourdomain.com/some_desktop_only_resource.html
To describe this in pseudo-code
if(isMobile)
response = getMobileResponse(url)
if(response.code != 404)
serveResponse(response)
else
serveResponse(getDesktopResponse(url))
I know this is possible if I list all the supported urls in this file - I would like to avoid this, as I would like this Platform Recognition layer to be independent of the application it serves. I also know I could solve this in the mobile application itself by redirecting from there, but if at all possible, I would like this Platform Recognition layer to be self-contained.
Is this possible using mod_rewrite?
Don't think there's a way to do this using mod_rewrite. Because you're using the [P] flag to proxy, the RewriteRule hands the proxy request to mod_proxy and doesn't even know if it went through or not. If everything was in the same document root (or at least subdirectories of the document root), you'd be able to use the -f conditional check to see if a file exists.
Something you could try doing, though I have no idea if this will work, is using mod_proxy's ProxyErrorOverride along with ErrorDocument. If your ProxyErrorOverride is turned on, theoretically if a proxied request returns an error, mod_proxy will use the local error handler instead of the proxied one. You could then use a ErrorDocument 404 to handle the proxied 404 with a php script or something, then do something about re-routing it back through the local rewrite engine (with maybe a redirect with a special query string param?) so that it could be proxied to the desktop domain.

Multiple index files in different folders?

I just figured out that if I have multiple folders in my website such as logout and login I can then have a log out/in page within the folders called index.php
Now when someone goes to project.com/login/ it will load up the index.php file in that folder and the url will look nice.
Is there any problem in doing this?
As Candy Pointed out it is better to do this with url rewrite rather heeps of folders and index files. I went and looked it up and you can do a lot of cool things.
for the basics:
http://www.addedbytes.com/for-beginners/url-rewriting-for-beginners/
http://www.yourhtmlsource.com/sitemanagement/urlrewriting.html
Instead of creating many folders which would make the site confusing (for the developer) and having numerous index.php files which would also get confusing if you were editing more than one at a time, you can use the apache mod_rewrite module which lets you transparently (the url in the address bar stays the same) redirect one URL to another. You could use this to clean up messy url's and have /login/ instead of /login/login.php or /user/1335591/ or even /user/'username'/ rather than an ugly url which is hard to remember like the following: /user/user.php?user=1335591
to start first put RewriteEngine on in your .htaccess file to turn it on
redirects are then written in the .htaccess file in sequence
Below is an example:
RewriteRule ^products/([0-9][0-9])$ /products/$1/ [R]
RewriteRule ^products/([0-9][0-9])/$ /productinfo.php?prodID=$1
If the user types in products/12 the first rule will append a trailing slash to it. The second rule will transparently redirect this URL to productinfo.php?prodID=12

Custom URL's to users, dynamically at a scale

I need to create custom urls for my users, for ex: www.example.com/alpha, www.example.com/beta. I was creating symlinked directories, which I think worked as a good starting point for prototyping. However, now I need to do this at a scale, running on several web servers behind a load balancer. I am not sure on the right way to do this.
If you are running on an Apache server and you have access to .htaccess files then try this in a .htaccess file
RewriteEngine On
RewriteRule ^(.*)\.html$ index.php?p=$1
This will point all URL's to index.php?p=* internally.
A user will see the .html, and the server interprets it as the pointed url.
Example: yourdomain.com/cocacola.html -> yourdomain.com/index.php?p=cocacola

URL Rewrite to remove my controller's name from the url displayed

I have this site
http://cjbuilders.info/welcome/home
and all the links start with
http://cjbuilders.info/welcome
How can I use mod_rewrite to just remove
/welcome/
from the url? This should be an easy one, but i struggle with mod_rewrite.
Do you know about CodeIgniter's URI Routing? Add this into your routes.php config file and it should work just fine:
$route['home'] = 'welcome/home';
This should work, IIRC:
RewriteRule ^/welcome/(.*)$ /$1 [R]
However, guessing a bit about what's going on here, if the reason for this prefix is something like a Java app server deploying an app at a context called "welcome", then the better solution is not to rewrite the URLs but to fix the backend app server to have a null context, i.e. serve at / rather than at /welcome/.
This is because the app server will probably want to generate links to other views of its app, and will reinsert the "welcome": this becomes a pain, and means that all links on your pages will get HTTP redirects when visited (e.g. by search engines). There is no way that the proxying apache server can parse the HTML and tell when that "welcome" should be removed, so best to fix the server that's writing the links in the first place.

Resources