I have a website made in WordPress, installed in a subdirectory (let’s call it “wp_dir”). I have followed the instructions in https://wordpress.org/support/article/giving-wordpress-its-own-directory/, specifically:
- change the root htaccess file
- change the root index.php file
- change the wp_dir htaccess file
It works well, in desktop, but not in mobile. In desktop, the site is rendered well: when you type “example.com”, it renders the wordpress site well, from the wordpress installed in wp_dir folder, with SSL and everything. All menu links work well.
In mobile, instead, when you type “example.com”, the url changes to “example.com/wp_dir”, with SSL, and menu links are shown, but shows a 404 error. Links work.
I believe the problem is SSL related. I have also tried removing the [L] directives, in order to allow the instructions to continue being executed, but to no avail. Something is not working ok, or in the proper order, but I can’t find what.
The htaccess file is pretty messed up with many different instructions (SSL, non-www redirection, permissions to other subdirectories for management applications, block exploits, etc). The site was previously built in Joomla. Obviously I’ve done something wrong, but I can’t figure out what that is.
How can it work well when you access it in a desktop computer, and not in a mobile phone?
Here is the current htaccess in the root directory (without the mess):
# SSL rewrite RewriteEngine On RewriteCond %{SERVER_PORT} 80 RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [R=301,NE] RewriteBase / RewriteEngine On # non-www RewriteBase / RewriteCond %{HTTP_HOST} !^example.com$ [NC] RewriteCond %{HTTPS} OFF RewriteRule ^(.*)$ http://example.com/$1 [R=301,L] RewriteCond %{HTTP_HOST} !^example.com$ [NC] RewriteCond %{HTTPS} ON RewriteRule ^(.*)$ https://example.com/$1 [R=301,L] <IfModule mod_rewrite.c> RewriteEngine on RewriteCond %{HTTP_HOST} ^(www.)?example.com$ RewriteCond %{REQUEST_URI} !^/wp_dir/ RewriteCond %{REQUEST_FILENAME} !-f RewriteCond %{REQUEST_FILENAME} !-d RewriteRule ^(.*)$ /wp_dir/$1 RewriteCond %{HTTP_HOST} ^(www.)?example.com$ RewriteRule ^(/)?$ wp_dir/index.php [L] </IfModule>
And here is the htaccess in the WordPress subdirectory (“wp_dir”):
# Force SSL RewriteEngine On RewriteCond %{HTTPS} off RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301,NE] # BEGIN WordPress <IfModule mod_rewrite.c> RewriteEngine On RewriteBase / RewriteRule ^index.php$ - [L] RewriteCond %{REQUEST_FILENAME} !-f RewriteCond %{REQUEST_FILENAME} !-d RewriteRule . /index.php [L] </IfModule> # END WordPress
In case it’s useful to see the full htacess file (with the mess), here it is:
# SSL rewrite RewriteEngine On RewriteCond %{SERVER_PORT} 80 RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [R=301,NE] #RewriteEngine On #RewriteCond %{HTTPS} off #RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301,NE] RewriteBase / RewriteEngine On ## Begin - Rewrite rules to block out some common exploits. # If you experience problems on your site block out the operations listed below # This attempts to block the most common type of exploit `attempts` to Joomla! # # Block out any script trying to base64_encode data within the URL. RewriteCond %{QUERY_STRING} base64_encode[^(]*([^)]*) [OR] # Block out any script that includes a <script> tag in URL. RewriteCond %{QUERY_STRING} (<|%3C)([^s]*s)+cript.*(>|%3E) [NC,OR] # Block out any script trying to set a PHP GLOBALS variable via URL. RewriteCond %{QUERY_STRING} GLOBALS(=|[|%[0-9A-Z]{0,2}) [OR] # Block out any script trying to modify a _REQUEST variable via URL. RewriteCond %{QUERY_STRING} _REQUEST(=|[|%[0-9A-Z]{0,2}) # Return 403 Forbidden header and show the content of the root homepage RewriteRule .* index.php [F] # ## End - Rewrite rules to block out some common exploits. ## Allow access to 'gui' zone RewriteRule ^(gui)($|/) - [L] RewriteRule ^(gui/services)($|/) - [L] RewriteRule ^(gui/services/api.php)($|/) - [L] RewriteRule ^(gui/services/.*)($|/) - [L] RewriteRule ^(gui/services/customers)($|/) - [L] RewriteRule ^(gui/.*)($|/) - [L] RewriteCond %{REQUEST_URI} ^/(gui|gui/.*)$ RewriteRule ^.*$ - [L] RewriteCond %{REQUEST_URI} ^/(gui/services|gui/services/.*)$ RewriteRule ^.*$ - [L] RewriteCond %{REQUEST_URI} ^/(gui/index.php|gui/index.php*/.*)$ RewriteRule ^.*$ - [L] RewriteCond %{REQUEST_URI} ^/(gui/services/customers|gui/services/customers/.*)$ RewriteRule ^.*$ - [L] RewriteCond %{REQUEST_URI} ^/(gui/services/customers)$ RewriteRule ^.*$ - [L] RewriteCond %{REQUEST_URI} ^/(gui/services)$ RewriteRule ^.*$ - [L] RewriteCond %{REQUEST_URI} ^/(gui/services/.*)$ RewriteRule ^.*$ - [L] ## End access to 'gui' zone ## Allow access to dir_zone2 RewriteCond %{REQUEST_URI} ^/(dir_zone2/|dir_zone2/.*)$ RewriteRule ^.*$ - [L] # RewriteCond %{REQUEST_URI} !^/(gui|gui/.*)$ RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}] ## Joomla SEF Section # If the requested path and file is not /index.php and the request # has not already been internally rewritten to the index.php script RewriteCond %{REQUEST_URI} !^/index.php # and the request is for something within the component folder, # or for the site root, or for an extensionless URL, or the # requested URL ends with one of the listed extensions RewriteCond %{REQUEST_URI} /component/|(/[^.]*|.(php|html?|feed|pdf|vcf|raw))$ [NC] # and the requested path and file doesn't directly match a physical file RewriteCond %{REQUEST_FILENAME} !-f # and the requested path and file doesn't directly match a physical folder RewriteCond %{REQUEST_FILENAME} !-d # internally rewrite the request to the index.php script RewriteRule .* wp_dir/index.php [L] # ## End - Joomla! core SEF Section. RewriteCond %{HTTP_REFERER} !^(http|https)://example.com/.*$ [NC] RewriteCond %{HTTP_REFERER} !^(http|https)://example.com$ [NC] RewriteCond %{HTTP_REFERER} !^(http|https)://www.example.com/.*$ [NC] RewriteCond %{HTTP_REFERER} !^(http|https)://www.example.com$ [NC] RewriteRule .*.(jpg|jpeg|gif|png|bmp)$ - [F,NC] # non-www RewriteBase / #RewriteCond %{REQUEST_URI} !^/(robots.txt|favicon.ico|sitemap.xml)$ RewriteCond %{HTTP_HOST} !^example.com$ [NC] # 2017-03-06 RewriteCond %{HTTPS} OFF RewriteRule ^(.*)$ http://example.com/$1 [R=301,L] #RewriteCond %{REQUEST_URI} !^/(robots.txt|favicon.ico|sitemap.xml)$ RewriteCond %{HTTP_HOST} !^example.com$ [NC] # 2017-03-06 RewriteCond %{HTTPS} ON RewriteRule ^(.*)$ https://example.com/$1 [R=301,L] # WordPress #RewriteCond %{REQUEST_URI} ^/(wp_dir/|wp_dir/.*)$ #RewriteRule ^.*$ - [L] #RewriteCond %{HTTP_HOST} ^(www.)?example.com$ #RewriteRule ^(/)?$ wp_dir[L] <IfModule mod_rewrite.c> RewriteEngine on RewriteCond %{HTTP_HOST} ^(www.)?example.com$ RewriteCond %{REQUEST_URI} !^/wp_dir/ RewriteCond %{REQUEST_FILENAME} !-f RewriteCond %{REQUEST_FILENAME} !-d RewriteRule ^(.*)$ /wp_dir/$1 RewriteCond %{HTTP_HOST} ^(www.)?example.com$ RewriteRule ^(/)?$ wp_dir/index.php [L] </IfModule>
EDIT: Added headers
These are the headers obtained with two different browsers.
In Firefox, I get the 301, and url keeps at “http ://www.example.com”.
Response headers:
HTTP/1.1 301 Moved Permanently Server: Sucuri/Cloudproxy Date: Thu, 05 Mar 2020 17:31:13 GMT Content-Type: text/html; charset=iso-8859-1 Content-Length: 335 Connection: keep-alive X-Sucuri-ID: 15020 X-XSS-Protection: 1; mode=block X-Frame-Options: SAMEORIGIN X-Content-Type-Options: nosniff X-Sucuri-Cache: HIT
Request headers:
Host: www.example.com User-Agent: Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:73.0) Gecko/20100101 Firefox/73.0 Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8 Accept-Language: es-ES,es;q=0.8,en-US;q=0.5,en;q=0.3 Accept-Encoding: gzip, deflate Connection: keep-alive Upgrade-Insecure-Requests: 1
These are the headers in Chrome, where I get a 404 and url “https ://www.example.com/wp_dir/”:
General:
Request URL: https://www.example.com/wp_dir/ Request Method: GET Status Code: 404 Remote Address: 192.124.249.120:443 Referrer Policy: no-referrer-when-downgrade
Response headers:
cache-control: no-cache, must-revalidate, max-age=0 content-encoding: gzip content-length: 14112 content-security-policy: upgrade-insecure-requests; content-type: text/html; charset=UTF-8 date: Thu, 05 Mar 2020 17:27:18 GMT expires: Wed, 11 Jan 1984 05:00:00 GMT link: <https://www.example.com/wp-json/>; rel="https://api.w.org/" server: nginx status: 404 vary: Accept-Encoding,User-Agent x-content-type-options: nosniff x-frame-options: SAMEORIGIN x-sucuri-cache: EXPIRED x-sucuri-id: 15020 x-xss-protection: 1; mode=block
Request headers:
:authority: www.example.com :method: GET :path: /wp_dir/ :scheme: https accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9 accept-encoding: gzip, deflate, br accept-language: es-ES,es;q=0.9,ca;q=0.8,en;q=0.7,fr;q=0.6,ro;q=0.5,gl;q=0.4 cookie: pll_language=es; wp-settings-1=editor%3Dtinymce%26edit_element_vcUIPanelWidth%3D1379%26edit_element_vcUIPanelLeft%3D0px%26edit_element_vcUIPanelTop%3D74px%26libraryContent%3Dbrowse; wp-settings-time-1=1580451182; wordpress_test_cookie=WP+Cookie+check; _ga=GA1.2.2063032164.1566356615; __utma=98619150.2063032164.1566356615.1566523591.1566602595.2; d50c875bad7fd1a5e131e638c3965ba3=es-ES; pll_language=es; wordpress_test_cookie=WP+Cookie+check sec-fetch-mode: navigate sec-fetch-site: none upgrade-insecure-requests: 1 user-agent: Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.130 Safari/537.36
Advertisement
Answer
I think there might be a problem with your rewrite in the subdirectory. First I presume you want to keep the same link. If we look at the tutorial linked there is only need for one .htaccess in the root directory.
Since if a request is made anywhere on the site and if it’s not a direct file or directory the root htaccess file will redirect it to the subfolder.
Now, your second subfolder .htaccess file is actually pointing back to the root directory. If you want to have a .htaccess redirect in the subfolder you should add the rewrite base and the subfolder to the redirect.
# Force SSL RewriteEngine On RewriteCond %{HTTPS} off RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301,NE] # BEGIN WordPress <IfModule mod_rewrite.c> RewriteEngine On RewriteBase /wp_dir/ RewriteRule ^index.php$ - [L] RewriteCond %{REQUEST_FILENAME} !-f RewriteCond %{REQUEST_FILENAME} !-d RewriteRule . /wp_dir/index.php [L] </IfModule> # END WordPress
- If you look at this Hostinger tutorial it suggests you shouldn’t use the RewriteEngine On condition twice. And this is a nice explanation of this “problem”.
But summery if you use RewriteEngine or RewriteBase multiple times the last entry wins and is used throughout the .htaccess file.
Now I don’t understand did you access https://example.com/wp_dir/ directly or were you redirected there? If it was direct access I think the .htaccess was wrong as I pointed out.
Or it may be the phone cache.
Edit: And also modify the first .htaccess file. I think one https rewrite rule is redundant and another incorrect.
# SSL rewrite RewriteEngine On # RewriteCond %{SERVER_PORT} 80 # I think this shouldn't matter but lets use the same method for consistency RewriteCond %{HTTPS} Off RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [R=301,NE] RewriteBase / # RewriteEngine is already On # RewriteEngine On # non-www # RewriteBase / # RewriteBase is already defined # if we want to redirect to https lets specify that #RewriteCond %{HTTP_HOST} !^example.com$ [NC] #RewriteCond %{HTTPS} OFF # RewriteRule ^(.*)$ http://example.com/$1 [R=301,L] #RewriteRule ^(.*)$ https://example.com/$1 [R=301,L] # But I think the very first directive should take care of this # If we're using https why redirect to it? # Or am I missing something? #RewriteCond %{HTTP_HOST} !^example.com$ [NC] #RewriteCond %{HTTPS} ON #RewriteRule ^(.*)$ https://example.com/$1 [R=301,L] <IfModule mod_rewrite.c> RewriteEngine on RewriteCond %{HTTP_HOST} ^(www.)?example.com$ RewriteCond %{REQUEST_URI} !^/wp_dir/ RewriteCond %{REQUEST_FILENAME} !-f RewriteCond %{REQUEST_FILENAME} !-d RewriteRule ^(.*)$ /wp_dir/$1 RewriteCond %{HTTP_HOST} ^(www.)?example.com$ RewriteRule ^(/)?$ wp_dir/index.php [L] </IfModule>
File as I’d put it
<IfModule mod_rewrite.c> RewriteEngine On RewriteCond %{HTTPS} Off RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [R=301,NE] RewriteCond %{HTTP_HOST} ^(www.)?example.com$ RewriteCond %{REQUEST_URI} !^/wp_dir/ RewriteCond %{REQUEST_FILENAME} !-f RewriteCond %{REQUEST_FILENAME} !-d RewriteRule ^(.*)$ /wp_dir/$1 RewriteCond %{HTTP_HOST} ^(www.)?example.com$ RewriteRule ^(/)?$ wp_dir/index.php [L] </IfModule>
I may be wrong.