URL Rewriting Add a folder name to URLs - apache

I have an apache2 server.
My directory structure is - (below is inside - /some-folder/abc)
- app
- otherfolder
- pqr.php
- xyz.php
- js
- css
.htaccess is placed inside /some-folder/abc
Context root for virtual host is set till - /some-folder/
Now, I want my users to enter this URL - http://someserver.com/abc/xyz or http://someserver.com/abc/pqr
I want to open the page at - http://someserver.com/abc/app/xyz.php or http://someserver.com/abc/app/pqr.php
How can I achieve this using URL Rewriting mod_rewrite
This is what I have so far, which is not working -
Options +FollowSymLinks -MultiViews
#Turn mod_rewrite on
RewriteEngine On
#RewriteBase /abc
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME}\.php -f
RewriteRule ^(.*)$ /app/$1\.php [L] # this doesn't work either
# RewriteRule ^(.*)$ app/$1.php [L] # this doesn't work either
# RewriteRule ^abc/(.*)$ abc/app/$1.php [L] # this doesn't work either
Thank you for your help.
If possible, I would also like to take all query params using forward slash
ex - http://someserver.com/abc/app/xyz.php/xId/123/uId/938/sdh/8374 instead of http://someserver.com/abc/app/xyz.php?xId=123?uId=938?sdh=8374
There is no pattern for query params, they can be anything for an page. Is this possible by a generic mod_rewrite, or do I have to rewrite urls for each page, and each time my developers add a new query param?

This rule should work for you from /abc/.htaccess:
Options +FollowSymLinks -MultiViews
RewriteEngine On
RewriteCond %{DOCUMENT_ROOT}/abc/app/$1.php -f
RewriteRule ^(?!internal)(.+?)/?$ app/$1.php [L,NC]
RewriteCond makes sure that we have a corresponding .php file in /abc/app/ sub-directory.
(?!internal) is negative lookahead assertion to skip internal from this rewrite.
Also it appears you're using a relative URL for css/js/images e.g. src="abc.png" and your current URL is: /abc/xyz then browser resolves this relative URL to http://example.com/abc/xyz/abc.png which obviously will cause a 404 since your static files are residing in /abc/app/ sub-directory.
You can add this just below <head> section of your page's HTML:
<base href="/abc/app/" />
so that every relative URL is resolved from that base URL and not from the current page's URL.
Also as a practice to use absolute links instead of relative ones change relative link XYZ, to this one XYZ

Related

Redirect specific image to another specific image htaccess - WordPress

I have a WordPress website, where I want to specifically redirect one image to another image. I have tried using a redirection plugin and while this has worked for web pages, it didn't seem to work for my image and it suggested that I needed to add the redirect to my .htaccess file.
So I have tried adding the following:
# BEGIN WordPress
# The directives (lines) between "BEGIN WordPress" and "END WordPress" are
# dynamically generated, and should only be modified via WordPress filters.
# Any changes to the directives between these markers will be overwritten.
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}]
RewriteBase /
Options +FollowSymLinks
RewriteRule ^index\.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]
RewriteRule ^wp-content/uploads/2021/03/ImageA.jpg$ ^wp-content/uploads/2021/03/imageB.jpg [L,R=301]
</IfModule>
# END WordPress
However, this still doesn't seem to work. Is there something that I'm missing?
If the original URL/image exists as a physical file then the redirection plugin will not work since the WordPress engine is never initiated.
RewriteRule ^wp-content/uploads/2021/03/TrackClosed.jpg$ ^wp-content/uploads/2021/03/LightningTalks.jpg [L,R=301]
There are a few things potentially wrong with this:
By placing this after the WordPress front-controller it is only going to be processed if the original URL still exists as a physical file. If the source URL does not exist as a physical file then this directive needs to go before the WP front-controller (ie. before the # BEGIN WordPress section).
The target URL, starting with ^ is not valid. You should be explicit and start the destination URL with a slash (ie. root-relative). Although this is not strictly necessary since the RewriteBase directive is defined.
Should this really be an external 3xx redirect or an internal rewrite?
You should avoid editing the code inside the # BEGIN WordPress block since WP itself tries to main this section and any customisations could be overwritten.
Try the following instead, at the top of the .htacess file, before the # BEGIN WordPress section:
RewriteRule ^wp-content/uploads/2021/03/ImageA\.jpg$ /wp-content/uploads/2021/03/ImageB.jpg [R=301,L]
This "redirects" /wp-content/uploads/2021/03/ImageA.jpg (case-sensitive match) to /wp-content/uploads/2021/03/ImageB.jpg. To change this to an internal rewrite then simply remove the R=301 flag.
There is no need to repeat the RewriteEngine directive.
Test with a 302 (temporary) redirect first. You will likely need to clear your browser cache before testing.

htaccess redirect subdirectory (folder) to single page in same subdirectory

I am having another issue with .htaccess where I can't seem to find the right solution for it. What I am trying to accomplish is to redirect from a subdirectory to a specific html document within that same directory when you copy/paste the url displayed below
For example:
http://example.com/staging/test/ to http://example.com/staging/test/page.html
My (almost) working method:
Options -Indexes -MultiViews
RewriteEngine on
RewriteRule ^test/(.*)$ test/page.html [L]
The problem with this code is that it does basically redirect to the correct page.html but if you want to click on any link on page.html it just redirects to page.html again instead of going to a particular link within subdirectory /test/ let's say /test/page-2.html
Important: This redirect should only affect the subdirectory "staging". All other sub-directories including root can not be affected.
Other info:
This code is also in my .htaccess file to remove the .html extension for the directory "staging"
RewriteCond %{SCRIPT_FILENAME} !-f
RewriteCond %{SCRIPT_FILENAME} !-d
RewriteRule ^(.*)$ $1.html [L]
The directory "staging" is not connected to any CMS and only consists of .html files.
I am on a shared hosting environment (Hostgator/cPanel).
Thank you.
Use below rule, you are using only L flag but I am modifying it for redirect as you mentioned.
Options -Indexes -MultiViews
RewriteEngine on
RewriteRule ^test/$ /staging/test/page.html [R=301,L]
You want to redirect only the directoy, but not the files in it. The pattern in the rule says match the directory test/ followed by anything .*, including any files.
To match the directory alone, the pattern must stop at test, which is accomplished by an end of string anchor
RewriteRule ^test/$ /staging/test/page.html [R,L]
Instead of an absolute path, you can keep the relative path and add a RewriteBase directive
RewriteBase /staging
RewriteRule ^test/$ test/page.html [R,L]
If you want to rewrite only, leave out the R flag.

Images don't load after htaccess redirect

I wanted to redirect all IPs to a specific page except my IP. and I successfully did that, but if that page has some pictures they won't ever load. Tried more than one solution, but nothing works.
How I redirect them using .htacess file:
Options +FollowSymLinks
RewriteEngine on
RewriteRule (?:^|/)(css|js|img)/(.+)$ /$1/$2 [NC,QSA,L]
RewriteCond %{HTTP:X-FORWARDED-FOR} !^22\.22\.22\.22
RewriteCond %{REQUEST_URI} !/test.php$ [NC]
RewriteRule .* /test.php [R=302,L]
Images (and CSS and Javascript) don't load, because the first rule causes a rewrite loop. If you just want to serve requests to subfolders css, js or img without modification, you can exit the rule chain by using - as the target, see RewriteRule
- (dash)
A dash indicates that no substitution should be performed (the existing path is passed through untouched). This is used when a flag (see below) needs to be applied without changing the path.
RewriteRule ^(?:css|js|img)/ - [NC,L]

.htaccess - redirect to page/dir, while all pages/dir are internally parsed as query string parameters

Scenario:
I have a .htaccess file that is handling a lot of rewrites (I am aware it would be possbile/easier in PHP)
Everything worked fine
/some/fake/dir/foobar was internally rewritten to
/index.php?some=fake&dir=foobar
and any url containing a query string was stripped
so I wanted to make a "coming soon page" or a "under maintenance page" for any IP not matching the declared condition
Example of what I've tried:
I tried something like this, and some other variations.
# IF not from DEV address
RewriteCond %{REMOTE_ADDR} !^123\.123\.123\.123$
# AND not for comingsoon page or other assets
RewriteCond %{THE_REQUEST} !\?comingsoon [OR]
RewriteCond %{REQUEST_URI} !^/comingsoon
# THEN send them to comingsoon page
RewriteRule ^ /comingsoon [R,L]
I've tried it in all potential areas of the .htaccess file to meet the conditions.
It seems to be the problem is getting redirect loops. the apache logs show it requesting the /comingsoon page then redirecting to the root directory /. I'm assuming because of the internal conversion of /foo/bar to /?foo=bar. But I can't seem how to figure this out where / is redirected to the "ghost" page /comingsoon
below is the layout of the .htaccess file: (code omitted to save time understanding problem)
Options -Indexes
RewriteEngine on
RewriteBase /
# Forced https (should not effect the problem)
[...]
# To externally redirect /dir/index.php to /dir/
[...]
# To externally redirect /dir/foo.php to /dir/foo
[...]
# To internally redirect /dir/foo to /dir/foo.php
[...]
# Prevent Rewrite on existing directories, files, and links
[...]
# Remove query string
[...]
# To internally rewrite directories as query string
[...]
# Custom error documents
Comment if full .htaccess is required to solve. Thanks!
/EDIT:
Please note, I have gotten it working fine with "real" files as my script prevents rewrites on existing files being requested. This is not the solution I'm looking for. My main index file is serving the dynamic content dependent on what the request_uri is rewritten to via query strings
Well, I guess I solved it. had to check the %{THE_REQUEST} HEADERS for the hidden query string with ?comingsoon
You can see the whitelist of files or directories I added if anyone runs into this problem as well :)
# IF not from DEV address
RewriteCond %{REMOTE_ADDR} !^127\.0\.5\.1$
# AND not for comingsoon page or other assets
RewriteCond %{THE_REQUEST} !^GET\s(?:/\?comingsoon|/comingsoon|/assets/|/favicon\.ico|/google[A-Za-z0-9]+\.html) [NC]
# THEN send them to comingsoon page
RewriteRule ^ /comingsoon [R,L]

Apache mod_rewrite redirect, keep sub-directory name

I'm wondering if this is possible.
I have a single page site in which I'd like to incorporate a trailing slash with a file name that anchors to a section on that site. I'm trying to avoid using hash or hash-bangs.
For example; www.example.com/recent
Right now, I'm removing any trailing slash, but I get a 404 with /recent because it's expecting a file.
RewriteRule ^(.*)/$ /$1 [R=301,L]
Is it possible to redirect to www.example.com, but still maintain the /recent without the server thinking it's a file so I can read it client-side (php/js)? More so that I can keep using the back and forward buttons.
Thanks for any help!
TBH it is not 100% clear for me what you want. As I understand you want URL www.example.com/recent to be rewritten (internal redirect, when URL remains unchanged in browser) to www.example.com/index.php?page=recent (or something like that).
DirectorySlash Off
Options +FollowSymLinks -MultiViews
RewriteEngine On
RewriteBase /
# remove trailing slash if present
RewriteRule ^(.*)/$ /$1 [R=301,L]
# do not do anything for already existing files
RewriteCond %{REQUEST_FILENAME} -f [OR]
RewriteCond %{REQUEST_FILENAME} -d
RewriteRule .+ - [L]
# rewrite all non-existing resources to index.php
RewriteRule ^(.+)$ /index.php?page=$1 [L,QSA]
With the above rules (that need to be placed in .htaccess in website root folder) this can be achieved. Request for www.example.com/recent will be rewritten to www.example.com/index.php?page=recent so your single-page server side script knows which URL was requested. The same will be with any other non-existing resource e.g. www.example.com/hello/pink/kitten => www.example.com/index.php?page=hello/pink/kitten.
It may not be necessary to pass originally requested URI as a page parameter as you should be able to access it in PHP via $_SERVER['REQUEST_URI'] anyway.
If I misunderstood you and this is not what you want then you have to clarify your question (update it with more details, make it sound clear).