htaccess not redirecting url - .htaccess

So I've been stuck on this a bit, and its more or less put a top on my project.
Just started up at a new job, and my current assignment is to create an API system for a new project we're launching. Its based on a modified version of wordpress, and my objective here is to take any request that goes to /contrib/api and instead have it direct to a file I have setup to sort out the incoming URL and redirect accordingly.
Here's what I currently have:
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /contrib/
RewriteCond %{REQUEST_URI} ^/api/
RewriteRule ^/content/apis/apis\.php$ - [L]
RewriteRule ^index\.php$ - [L]
# uploaded files -- no longer needed since we're serving files directly via apache
# RewriteRule ^([_0-9a-zA-Z-]+/)?files/(.+) wp-includes/ms-files.php?file=$2 [L]
# add a trailing slash to /network and /wp-admin
RewriteRule ^([_0-9a-zA-Z-]+/)?wp-admin$ $1wp-admin/ [R=301,L]
RewriteRule ^([_0-9a-zA-Z-]+/)?wp-admin/network$ $1wp-admin/network/ [R=301,L]
RewriteCond %{REQUEST_FILENAME} -f [OR]
RewriteCond %{REQUEST_FILENAME} -d
RewriteRule ^ - [L]
RewriteRule ^([_0-9a-zA-Z-]+/)?(wp-(content|admin|includes).*) wordpress/$2 [L]
RewriteRule ^([_0-9a-zA-Z-]+/)?(.*\.php)$ wordpress/$2 [L]
RewriteRule . /contrib/index.php [L]
</IfModule>
This was all here before me, except for near the top:
RewriteCond %{REQUEST_URI} ^/api/
RewriteRule ^/content/apis/apis\.php$ - [L]
My goal, as stated, is to take any request from /contrib/api/ and redirect it to my file instead of continuing. Instead, it seems to skip on and go ahead and point to the wp-admin (after a redirect I think). Regardless, it seems my command isn't getting caught, and I'm not sure why.
I thought that the commands are processed first come, but if its continuing on, would moving my code to the end make it work?
I know this is an easy thing to test, but I was hoping I could get some insight on what I'm doing/doing wrong, plus I don't yet have access to the server to actually upload/test code without going through my boss, and I'm thinking 2 weeks in, probably not a good idea to ask my boss to test code every 5 minutes, heh :(
EDIT: As per Bob Vale's notice, fixed the path issue.

You don't need the RewriteCond as the rule will be doing the match anyhow, you just need
RewriteRule ^contrib/api/ /content/apis/apis.php [L]
This will rewrite any url starting with contrib/api to the file /content/apis/apis.php

Related

Simple rewritecond in htaccess doesn't work as expected

This is super simple but it's driving me crazy! I have a website at http://example.org/ and a subdirectory at http://example.org/ccc/
I want to redirect anything outside of the /ccc/ directory to a different website.
RewriteEngine on
RewriteCond %{REQUEST_URI} !^/ccc/?.*
RewriteRule ^(.*)$ https://new-website.com/$1 [L]
But this code doesn't work, it redirects the /ccc/ directory. According to my research and testing with this htaccess tester, it should not redirect because the RewriteCond is checking against /ccc with optional slash and other characters after it.
What is happening? Does this look correct?
Edit: This method from this answer is also not working, the CCC domain is being redirected:
RewriteEngine on
RewriteRule ^ccc index.php [L]
RewriteRule (.*) https://new-website.com/$1 [R=301,L]
PHP 5.4.45, Apache/2.2.31
Assuming ccc/ directory doesn't have a separate .htaccess, you may use this rule:
RewriteEngine on
RewriteCond %{THE_REQUEST} !\s/ccc[/?\s] [NC]
RewriteRule ^ https://new-website.com%{REQUEST_URI} [L,R=301,NE]
THE_REQUEST variable represents original request received by Apache from your browser and it doesn't get overwritten after execution of other rewrite directives. An example value of this variable is GET /index.php?id=123 HTTP/1.1
It looks like [L] isn't behaving normally and I'm guessing it's the old version of Apache (2.2.31) because these rules worked on a separate website. I found this solution which seemed to work for this case, the third line below:
RewriteEngine on
RewriteRule ^ccc/? index.php [L]
RewriteCond %{ENV:REDIRECT_STATUS} != 200
RewriteRule ^(.*)$ https://new-website.com/$1 [L]
Explanation from that question:
The problem is that once the [L] flag is processed, all the next RewriteRules are indeed ignored, however, the file gets processed AGAIN from the begin, now with the new url.
This magic Condition will not process the catch all if the file was already redirected.

Semi-colons in URL changes to %3b via .htaccess

This is my .htaccess file -
RewriteCond %{REQUEST_URI} !(/$|\.)
RewriteRule (.*) %{REQUEST_URI}/ [R=301,L]
<IfModule mod_rewrite.c>
RewriteBase /
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
#RewriteRule ^template\.php$ - [L]
#RewriteRule ^index\.php$ - [L]
RewriteRule . /template.php [L]
</IfModule>
It's designed to funnel everything through /template.php so it processes the rest of the URL & domains.
For whatever reason, when there's semi-colons provided in the URL (which is an important piece of the URL constructing the listing queries on my real estate websites) the semicolons change to %3b which is NOT what I want.
Oddly enough this is happening on one website only... all of my sites are on the same server.
http://dev.brixwork.com/listings/city-Vancouver+West/area-Arbutus;Cambie;Coal+Harbour/order_by-create_date/order_direction-DESC/page-1
THe above test URL is fine.
However take that same file here..
http://suzannec.brixwork.com/listings/city-Vancouver+West/area-Arbutus;Cambie;Coal+Harbour/order_by-create_date/order_direction-DESC/page-1
And you'll notice that the ; between the subarea names (Arbutus, Cambie & Coal Harbour) mysteriously changes to %3b, and the page title generated is wrong as well, because it's not getting the proper array passed for processing.
I'm fully aware that this may NOT be an .htaccess issue... but that's the best I could think up.
Your first rule is doing this. When I click on your second link, since it doesn't end with a slash or a period, it redirects me to the same URI except with a slash. Try using the NE flag so that the semicolons don't get encoded:
RewriteCond %{REQUEST_URI} !(/$|\.)
RewriteRule (.*) %{REQUEST_URI}/ [R=301,L,NE]
Not sure why the dev site isn't doing the same thing, unless it's missing the redirect rule.

How to avoid a looping redirection from .htaccess?

I've set a .htaccess with a set of rules.
RewriteEngine on
RewriteCond $1 !^(index\.php|images|stylesheets|javascript|robots\.txt)
RewriteRule ^Canvas/(.*)/(.*)$ /canvas.php?a=$1&b=$2 [L]
RewriteRule ^(.*)$ /index.php/$1 [L]
The above rule get redirected and throwing 500 internal server error.
When I comment the last line, everything that follows the rule /canvas/something/something is working fine but things are going wrong when un-comment the last line.
I tried adding condition like
RewriteCond %{REQUEST_URI} !^/canvas.php.*
and
RewriteCond %{REQUEST_FILENAME} !^/canvas.php.*
but it didn't resolved the problem.
How could I resolve this?
[L] does not do what you think it does: It only stops "this round" and restarts the rewriting execution with the new URL. You might want to try [END].
See End vs Last flags.
Alternatively, you cant try using the skip flag [S=number_of_rules_to_skip].
You could perhaps try adding an environment variable to mark the fact you've redirected and trap for this using a RewriteCond. For example (untested):
RewriteEngine on
RewriteCond $1 !^(index\.php|images|stylesheets|javascript|robots\.txt)
RewriteRule ^Canvas/(.*)/(.*)$ /canvas.php?a=$1&b=$2 [E=REWRITEDONE:1,L]
RewriteCond %{ENV:REWRITEDONE} !1
RewriteRule ^(.*)$ /index.php/$1 [L]
Two things are happening here. First, /canvas.php is getting rewritten to /index.php/canvas.php. Then /index.php itself is getting rewritten to /index.php/index.php/canvas.php, and then that keeps looping. Your second rule has no conditions to prevent it from blindly rewriting everything that matches ^(.*)$ (which is everything). Note that RewriteCond's only affect the immediately following RewriteRule, so the one that routes to /index.php won't have any conditions on it. A few conditions that you can add to prevent the looping:
RewriteCond $1 !^(index\.php|canvas\.php|images|stylesheets|javascript|robots\.txt)
RewriteRule ^(.*)$ /index.php/$1 [L]
Rewrites everything that isn't index.php, canvas.php, images, stylesheets, scripts, and the robots.txt file. Or:
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ /index.php/$1 [L]
Rewrites everything that isn't pointing to an existing file or directory. This also excludes direct access to stuff like scripts and styles and the robots.txt, along with any other static content.
Another possibility is to prevent looping entirely, by adding this to the top of your rules (right below RewriteEngine On:
RewriteCond %{ENV:REDIRECT_STATUS} 200
RewriteRule ^ - [L]
This means if there's already an internal rewrite, stop rewriting completely by passing through the URI (the - target). The rewrite engine loops until the URI going in stops changing, the passthrough essentially does that. If you are using apache 2.4, you can also use the END rewrite flag to stop rewriting.

RewriteRule For Matching Arbitrary PHP Files

I'm somewhat new to htaccess rewrite rules, and have been scratching my head for the past few days on what's happening here. No amount of Googling seemed to help, so hopefully somebody knows the answer.
I have a site that can be accessed as:
www.site.com
www.site.com/684
www.site.com/684/some-slug-name-here
All of these scenarios should go to index.php and pass in the optional id=684 and slug=some-slug-name-here
Which works fine.
My problem is I have a separate file. Right now it's called admintagger.php - but this fails when I call it anything. 21g12fjhg2349yf234f.php has the same issue.
The problem is that that I would like to be able to access admintagger.php from www.site.com/admintagger
but it seems to be matching my rule for index, and taking me there instead.
Here is my code:
Options +FollowSymLinks
RewriteEngine On
RewriteBase /
RewriteRule ^imagetagger$ /imagetagger.php [NC,QSA]
RewriteRule ^([0-9]+)/?(.*)?/?$ index.php?id=$1&slug=$2 [NC,L,QSA]
If you want to arbitrarily be able to access php files via the name (sans extension) then you need to create a general rule for it. But you need to be careful otherwise you may be rewriting legitimate requests for existing resources (like a directory, or a slug). Try this instead:
# make sure we aren't clobbering legit requests:
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
# see if appending a ".php" to the end of the request will map to an existing file
RewriteCond %{REQUEST_FILENAME}.php -f
# internally rewrite to include the .php
RewriteRule ^(.*)$ /$1.php [L]
Then you can have your routing to index.php right after that:
RewriteRule ^([0-9]+)/?(.*)?/?$ index.php?id=$1&slug=$2 [NC,L,QSA]
Although you may be better off create a separate rule for each of your 3 cases:
RewriteRule ^([0-9]+)/([^/]+)/?$ /index.php?id=$1&slug=$2 [NC,L,QSA]
RewriteRule ^([0-9]+)/?$ /index.php?id=$1 [NC,L,QSA]
RewriteRule ^$ /index.php [L]

Excluding a script from the general UrlRewrite rules

I have following rewrite rules for a website:
RewriteEngine On
# Stop reading config files
RewriteCond %{REQUEST_FILENAME} .*/web.config$ [NC,OR]
RewriteCond %{REQUEST_FILENAME} .*/\.htaccess$ [NC]
RewriteRule ^(.+)$ - [F]
# Rewrite to url
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !^(/bilder_losning/|/bilder/|/gfx/|/js/|/css/|/doc/).*
RewriteRule ^(.+)$ index.cfm?smartLinkKey=%{REQUEST_URI} [L]
Now I have to exclude a script including its eventually querystrings from the above rules, so that I can access and execute it on the normal way, at the moment the whole url is being ignored and forwarded to the index page.
I need to have access to the script shoplink.cfm in the root which takes variables tduid and url (shoplink.cfm?tduid=1&url=)
I have tried to resolve it using this:
# maybe?:
RewriteRule !(^/shoplink.cfm [QSA]
but to be honest, I have not much of a clue of urlrewriting and have no idea what I am supposed to write. I just know that above will generate a nice 500 error.
I have been looking around a lot on stackoverflow and other websites on the same subject, but all I see is people trying to exclude directories, not files. In the worst case I could add the script to a seperate directory and exclude the directory from the rewriterules, but rather not since the script should really remain in the root.
Just also tried:
RewriteRule ^/shoplink.cfm$ $0 [L]
but that didn't do anything either.
Anyone who can help me out on this subject?
Thanks in advance.
Steven Esser
ColdFusion programmer
Please try to put the following line at the top of your config (after RewriteEngine on):
RewriteRule ^shoplink.cfm$ - [L]

Resources