#23073 closed defect (bug) (fixed)
Wrong RewriteRule in a local Multisite installation
Reported by: | Guy_fr | Owned by: | markjaquith |
---|---|---|---|
Milestone: | 3.5.1 | Priority: | normal |
Severity: | normal | Version: | 3.5 |
Component: | Multisite | Keywords: | has-patch needs-testing needs-unit-tests |
Focuses: | Cc: |
Description
- WampServer on Windows 8
- Install Wordpress in a subdirectory of the document root(here a directory "multitest")
- Setup multisite in subfolder mode.
Rules displayed for .htaccess in the wordpress textarea of the network page are:
RewriteRule ^([_0-9a-zA-Z-]+/)?(wp-(content|admin|includes).*) c:\wamp\www\multitest/$2 [L] RewriteRule ^([_0-9a-zA-Z-]+/)?(.*\.php)$ c:\wamp\www\multitest/$2 [L]
Result in the browser window of a subsite admin board is an error:
Forbidden You don't have permission to access /multitest/C:wampwwwmultitest/wp-admin/ on this server.
For the subsite itself, at least paths for css are broken.
RewriteRules should be:
RewriteRule ^([_0-9a-zA-Z-]+/)?(wp-(content|admin|includes).*) /multitest/$2 [L] RewriteRule ^([_0-9a-zA-Z-]+/)?(.*\.php)$ /multitest/$2 [L]
Looking at code source in network.php, I fixed it for my personal use by adding: $rewrite_base = $base; before the htaccess code is displayed to users.
This could be done with local multisite installation only.
Attachments (10)
Change History (58)
#4
in reply to:
↑ 2
@
12 years ago
Replying to alexvorn2:
I think that local installation is not for multisite
By design, in source code and documentation, only subdomain multisite installation is forbidden. Subdirectories installations are allowed.
Trouble is only in the suggest for the .htaccess file in the dashboard.
#6
@
12 years ago
- Keywords reporter-feedback added
@Guy_fr - what was your hostname? IP address, localhost, etc. ?
#8
@
12 years ago
Looking through the way those rules are generated, it's not immediately obvious (to me) why it doesn't work. I don't have a windows machine/VM to test on. It would be useful to know what all of the variables around here are when it fails: http://core.trac.wordpress.org/browser/trunk/wp-admin/network.php?rev=23245#L312
#9
in reply to:
↑ 7
;
follow-ups:
↓ 10
↓ 11
@
12 years ago
Replying to SergeyBiryukov:
Related: #23104
This seems like a likely culprit. Does stuff like $_SERVER['DOCUMENT_ROOT']
use unix-style paths even on windows? If so, that would be an obvious reason it would break, and the patch from #23104 looks like it would fix it.
#10
in reply to:
↑ 9
@
12 years ago
Replying to evansolomon:
Replying to SergeyBiryukov:
Related: #23104
This seems like a likely culprit. Does stuff like
$_SERVER['DOCUMENT_ROOT']
use unix-style paths even on windows? If so, that would be an obvious reason it would break, and the patch from #23104 looks like it would fix it.
The document root is quite possibly c:\wamp\www\. I'm wondering if Wamp has a similar situation to having PHP-CGI without the fix_path_info flag set in the PHP config.
#11
in reply to:
↑ 9
@
12 years ago
Replying to evansolomon:
Replying to SergeyBiryukov:
Related: #23104
This seems like a likely culprit. Does stuff like
$_SERVER['DOCUMENT_ROOT']
use unix-style paths even on windows? If so, that would be an obvious reason it would break, and the patch from #23104 looks like it would fix it.
First, Happy new year :)
Actual configuration is:
$_SERVER["DOCUMENT_ROOT"]: C:/wamp/www realpath($_SERVER["DOCUMENT_ROOT"]): C:\wamp\www ABSPATH: C:\wamp\www\multitest/ slashed_home: http://localhost/multitest/ $base: /multitest/
with the #23104 patch, local variables in the network_step2 function will become:
$wp_dir_from_root: \multitest/ $wp_siteurl_subdir: /\multitest/ $rewrite_base: \multitest/
Which is not correct as the suggest lines in the .htacces will be:
RewriteRule ^([_0-9a-zA-Z-]+/)?(wp-(content|admin|includes).*) \multitest/$2 [L] RewriteRule ^([_0-9a-zA-Z-]+/)?(.*\.php)$ \multitest/$2 [L]
One fix could be to replace \ by / in the call to the global ABSPATH variable when building the $wp_dir_from_root:
$wp_dir_from_root = preg_replace( '#^' . preg_quote( $_SERVER['DOCUMENT_ROOT'], '#' ) . '#', '', preg_replace('/\\\\/', '/', ABSPATH));
with that fix, local variables in the fucntion will be:
$wp_dir_from_root: /multitest/ $wp_siteurl_subdir: / $rewrite_base:
and in the suggest for .htaccess file, you will find:
RewriteRule ^([_0-9a-zA-Z-]+/)?(wp-(content|admin|includes).*) $2 [L] RewriteRule ^([_0-9a-zA-Z-]+/)?(.*\.php)$ $2 [L]
which is not breaking acces to secondary site when installing on a windows local machine.
#12
follow-up:
↓ 13
@
12 years ago
Hit same issue. This is not caused by symlink in my case, but by where data is taken from - causing separator mismatch that makes $wp_dir_from_root = preg_replace( '#^' . preg_quote( $_SERVER['DOCUMENT_ROOT'], '#' ) . '#', '', ABSPATH );
replacement produce incorrect result (absolute path).
ABSPATH
is defined asdirname(__FILE__)
which is generated by PHP$_SERVER['DOCUMENT_ROOT']
seems to be taken verbatim from Apache configuration
Naturally there is no guarantee that the two use the same separator convention. Can't even rely on OS to determine which one Apache config uses since it can be typed in freeform.
So either data needs to come from compatible sources or separators need to be force equalized before running replacement.
#13
in reply to:
↑ 12
@
12 years ago
Replying to Rarst:
Hit same issue. This is not caused by symlink in my case, but by where data is taken from - causing separator mismatch that makes
$wp_dir_from_root = preg_replace( '#^' . preg_quote( $_SERVER['DOCUMENT_ROOT'], '#' ) . '#', '', ABSPATH );
replacement produce incorrect result (absolute path).
ABSPATH
is defined asdirname(__FILE__)
which is generated by PHP$_SERVER['DOCUMENT_ROOT']
seems to be taken verbatim from Apache configurationNaturally there is no guarantee that the two use the same separator convention. Can't even rely on OS to determine which one Apache config uses since it can be typed in freeform.
So either data needs to come from compatible sources or separators need to be force equalized before running replacement.
That is right, and I think the better fix would be to change all ABSPATH definitions to ensure separators are the same everywhere, better than only change in one place as I described previously. Something like that:
define( 'ABSPATH', preg_replace('/\\\\/', '/', dirname(__FILE__) . '/'));
but.... ABSPATH is used in so many places that it could be "dangerous" to modify that.
#14
@
12 years ago
It's pretty common to see str_replace( '\\', '/', $path)
elsewhere in core where we deal with filesystem paths.
I'd be +1 for standardising ABSPATH on windows to / as well as doing the same for any paths in $_SERVER which we use. Windows is very forgiving and accepts either slash, and AFAIK, doesn't believe in using \ as an escape character in paths. IIS on the other hand, may need checking to see if it complains.
#15
@
12 years ago
- Keywords has-patch added; reporter-feedback removed
Confirmed the issue. The current code was introduced in [22042].
23073.patch should fix this ticket along with #23104.
#17
@
12 years ago
I just visited network.php on my trunk MS in subdir install on OS X:
The rewrite rules in generates are also broken :(
RewriteEngine On RewriteBase /~peter/trunk.ms/ RewriteRule ^index\.php$ - [L] # uploaded files RewriteRule ^([_0-9a-zA-Z-]+/)?files/(.+) Users/peter/Sites/trunk.ms/wp-includes/ms-files.php?file=$2 [L] # add a trailing slash to /wp-admin RewriteRule ^([_0-9a-zA-Z-]+/)?wp-admin$ $1wp-admin/ [R=301,L] RewriteCond %{REQUEST_FILENAME} -f [OR] RewriteCond %{REQUEST_FILENAME} -d RewriteRule ^ - [L] RewriteRule ^([_0-9a-zA-Z-]+/)?(wp-(content|admin|includes).*) Users/peter/Sites/trunk.ms/$2 [L] RewriteRule ^([_0-9a-zA-Z-]+/)?(.*\.php)$ Users/peter/Sites/trunk.ms/$2 [L] RewriteRule . index.php [L]
#18
@
12 years ago
If I go back to [22041] then my OS X localhost install generates the right rules again. With [22042] they are broken.
Basically, $_SERVER['DOCUMENT_ROOT']
is about as useful as a pile of tribbles.
For example when you use mod_userdir the DOCUMENT_ROOT is not the root folder of the files at all and also the symlink issue highlighted in #23104.
We probably need to go back to divining the root of the server a different way.
#19
@
12 years ago
Okay. I had a patch on #22639 that removed DOCUMENT_ROOT from the equation, by using get_home_path() (which uses SCRIPT_FILENAME, but that seems to be working just fine for existing get_home_path() uses). attachment:ticket:22639:22639.2.diff
#20
follow-up:
↓ 21
@
12 years ago
23073.diff is the refreshed patch from #22639. Untested.
get_home_path() already standardizes slashes, too.
#21
in reply to:
↑ 20
@
12 years ago
Replying to nacin:
23073.diff is the refreshed patch from #22639. Untested.
get_home_path() already standardizes slashes, too.
This works on my OS X with mod_userdir setup and generates the same rules as pre [22042]
#22
@
12 years ago
Tested 23073.diff in a subdirectory on Windows, looks good.
#23
@
12 years ago
- Keywords commit added; dev-feedback removed
Great. Let's get as much testing/review on this as possible, Lots of environmental variables here, and a lot of PHP variables too.
#24
@
12 years ago
23073.diff busts a lot of links, notably network admin ones.
htaccess without 23073.diff:
RewriteEngine On RewriteBase / RewriteRule ^index\.php$ - [L] # add a trailing slash to /wp-admin RewriteRule ^([_0-9a-zA-Z-]+/)?wp-admin$ $1wp-admin/ [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 . index.php [L]
With 23073.diff:
RewriteEngine On RewriteBase / RewriteRule ^index\.php$ - [L] # add a trailing slash to /wp-admin RewriteRule ^([_0-9a-zA-Z-]+/)?wp-admin$ $1wp-admin/ [R=301,L] RewriteCond %{REQUEST_FILENAME} -f [OR] RewriteCond %{REQUEST_FILENAME} -d RewriteRule ^ - [L] RewriteRule ^([_0-9a-zA-Z-]+/)?(wp-(content|admin|includes).*) Users/ryan/Dropbox/htdocs/wpsubdir/$2 [L] RewriteRule ^([_0-9a-zA-Z-]+/)?(.*\.php)$ Users/ryan/Dropbox/htdocs/wpsubdir/$2 [L] RewriteRule . index.php [L]
#25
@
12 years ago
ABSPATH: /Users/ryan/Dropbox/htdocs/wpsubdir/wordpress/
get_home_path(): /Users/ryan/Dropbox/htdocs/wpsubdir/
#26
@
12 years ago
In 23073.diff, seems that $home_path
and ABSPATH
should be swapped in line 316.
#27
@
12 years ago
Correct, I had the variables flipped in the patch. 23073.2.diff looks proper. Curious why it was reported as working by westi.
#29
@
12 years ago
Looks good when WP isn't in a subdir. I don't have things set up to test subdomains, however.
#30
@
12 years ago
Does not work with subdomains with WP is in a subdir.
Expected:
RewriteEngine On RewriteBase / RewriteRule ^index\.php$ - [L] # uploaded files RewriteRule ^files/(.+) wp/wp/wp-includes/ms-files.php?file=$1 [L] # add a trailing slash to /wp-admin RewriteRule ^wp-admin$ wp-admin/ [R=301,L] RewriteCond %{REQUEST_FILENAME} -f [OR] RewriteCond %{REQUEST_FILENAME} -d RewriteRule ^ - [L] RewriteRule ^(wp-(content|admin|includes).*) wp/wp/$1 [L] RewriteRule ^(.*\.php)$ wp/wp/$1 [L] RewriteRule . index.php [L]
I get:
RewriteEngine On RewriteBase / RewriteRule ^index\.php$ - [L] # uploaded files RewriteRule ^files/(.+) wp-includes/ms-files.php?file=$1 [L] # add a trailing slash to /wp-admin RewriteRule ^wp-admin$ wp-admin/ [R=301,L] RewriteCond %{REQUEST_FILENAME} -f [OR] RewriteCond %{REQUEST_FILENAME} -d RewriteRule ^ - [L] RewriteRule ^(wp-(content|admin|includes).*) $1 [L] RewriteRule ^(.*\.php)$ $1 [L] RewriteRule . index.php [L]
#32
@
12 years ago
the 23073.2.diff was correct for me with subdomains and wordpress in its own directory (except that it should have the fix for mismatching separators: str_replace('\\', '/', ...)
on ABSPATH and $home_path )
Wordpress is installed in a subdir "wp":
RewriteEngine On RewriteBase / RewriteRule ^index\.php$ - [L] # add a trailing slash to /wp-admin RewriteRule ^wp-admin$ wp-admin/ [R=301,L] RewriteCond %{REQUEST_FILENAME} -f [OR] RewriteCond %{REQUEST_FILENAME} -d RewriteRule ^ - [L] RewriteRule ^(wp-(content|admin|includes).*) wp/$1 [L] RewriteRule ^(.*\.php)$ wp/$1 [L] RewriteRule . index.php [L]
#33
@
12 years ago
How does 23073.3.diff look like? Tested with the examples above.
#34
@
12 years ago
Still wrong:
RewriteEngine On RewriteBase / RewriteRule ^index\.php$ - [L] # uploaded files RewriteRule ^files/(.+) wp-includes/ms-files.php?file=$1 [L] # add a trailing slash to /wp-admin RewriteRule ^wp-admin$ wp-admin/ [R=301,L] RewriteCond %{REQUEST_FILENAME} -f [OR] RewriteCond %{REQUEST_FILENAME} -d RewriteRule ^ - [L] RewriteRule ^(wp-(content|admin|includes).*) $1 [L] RewriteRule ^(.*\.php)$ $1 [L] RewriteRule . index.php [L]
#35
@
12 years ago
Everyone/anyone, please test 23073.7.2.diff on every setup you have. Please be specific as to the setup, as it concerns both server setup and WP network setup. That could include (not limited to) any combination of the following:
- Windows Apache
- mod_userdir
- IIS
- An install where WordPress is in a subdirectory, like /wordpress (be sure to report whether home == siteurl for your main site)
- Installs configured for subdomains and subdirectories (we need to test both)
Please confirm not only that the rewrite rules are correct, but that the instructions tell you to edit the right .htaccess or web.config file. As markjaquith did above, please paste the .htaccess rules here if you have issues or are unsure. As also done above, please provide your values for $_SERVER['DOCUMENT_ROOT']
, $_SERVER['SCRIPT_FILENAME']
, ABSPATH
, get_home_path()
, etc.
#37
@
12 years ago
- Keywords needs-unit-tests added
I'm going to call "unit-tests" here!
It seems pretty obvious that while we do this testing we should collect the ENV vars that we are using as nacin mentions above and then take these a build some unit tests around this code.
This is probably 3.6 material with a slight refactor to make the code testable but it seems pretty important to do so we can change the code in future and feel confident about not having to test 10's of different configurations including ones we might not always have setup like Windows.
#38
@
12 years ago
test with 23073.7.2.diff
Conf:
- Windows Apache local virtual host (http://test_subd.loc)
- Wordpress multisite, subdomain and installed in its own dir "wp"
- Works as expected
Global env: $_SERVER["SCRIPT_FILENAME"]: C:/wamp/www/wordpress/test_subd/wp/wp-admin/network/setup.php $_SERVER["DOCUMENT_ROOT"]: C:/wamp/www/wordpress/test_subd $document_root_fix: C:/wamp/www/wordpress/test_subd ABSPATH: C:\wamp\www\wordpress\test_subd\wp/ $abspath_fix: C:/wamp/www/wordpress/test_subd/wp/ get_home_path(): C:/wamp/www/wordpress/test_subd/ get_option(home): http://test_subd.loc get_option(siteurl): http://test_subd.loc/wp local vars: $base: / $home_path: C:/wamp/www/wordpress/test_subd/ $wp_siteurl_subdir: wp/ $rewrite_base: wp/
file .htaccess
RewriteEngine On RewriteBase / RewriteRule ^index\.php$ - [L] # add a trailing slash to /wp-admin RewriteRule ^wp-admin$ wp-admin/ [R=301,L] RewriteCond %{REQUEST_FILENAME} -f [OR] RewriteCond %{REQUEST_FILENAME} -d RewriteRule ^ - [L] RewriteRule ^(wp-(content|admin|includes).*) wp/$1 [L] RewriteRule ^(.*\.php)$ wp/$1 [L] RewriteRule . index.php [L]
Note, in the next line, url to the folder should use $abspath_fix instead of ABSPATH:
Add the following to your wp-config.php file in C:\wamp\www\wordpress\test_subd\wp/ above the line reading /* That’s all, stop editing! Happy blogging. */:
#39
@
12 years ago
test with 23073.7.2.diff
Conf:
- Windows Apache localhost
- Wordpress multisite, Path-based installation (subfolder install) and core installed in a "multitest" directory
- Works as expected
Global env: $_SERVER["SCRIPT_FILENAME"]: C:/wamp/www/multitest/wp-admin/network/setup.php $_SERVER["DOCUMENT_ROOT"]: C:/wamp/www $document_root_fix: C:/wamp/www ABSPATH: C:\wamp\www\multitest/ $abspath_fix: C:/wamp/www/multitest/ get_home_path(): C:\wamp\www\multitest/ get_option(home): http://localhost/multitest get_option(siteurl): http://localhost/multitest local vars: $base: /multitest/ $home_path: C:/wamp/www/multitest/ $wp_siteurl_subdir: $rewrite_base:
file .htaccess:
RewriteEngine On RewriteBase /multitest/ RewriteRule ^index\.php$ - [L] # add a trailing slash to /wp-admin RewriteRule ^([_0-9a-zA-Z-]+/)?wp-admin$ $1wp-admin/ [R=301,L] RewriteCond %{REQUEST_FILENAME} -f [OR] RewriteCond %{REQUEST_FILENAME} -d RewriteRule ^ - [L] RewriteRule ^([_0-9a-zA-Z-]+/)?(wp-(content|admin|includes).*) $2 [L] RewriteRule ^([_0-9a-zA-Z-]+/)?(.*\.php)$ $2 [L] RewriteRule . index.php [L]
#40
follow-up:
↓ 43
@
12 years ago
looking at the two previous comments, it seems that get_home_path() does not return the same delimitors wheather siteurl and home are identical or not.
- identical : get_home_path(): C:\wamp\www\multitest/
- not identical: get_home_path(): C:/wamp/www/wordpress/test_subd/
#41
@
12 years ago
Test with 23073.7.2.diff
- Windows
- Apache
- locally mapped
dev.rarst.net
domain - subdir multisite
- core in
/wordpress
Data:
ABSPATH => C:\server\www\dev\wordpress/ $_SERVER['SCRIPT_FILENAME'] => C:/server/www/dev/wordpress/wp-admin/network/setup.php $_SERVER['DOCUMENT_ROOT'] => C:/server/www/dev/ get_home_path() => C:\server\www\dev\wordpress/ get_option('siteurl') => http://dev.rarst.net get_option('home') => http://dev.rarst.net hostname => dev.rarst.net slashed_home => http://dev.rarst.net/ base => / document_root_fix => C:/server/www/dev abspath_fix => C:/server/www/dev/wordpress/ home_path => C:/server/www/dev/ wp_siteurl_subdir => wordpress/ rewrite_base => wordpress/
Generated .htaccess
:
RewriteEngine On RewriteBase / RewriteRule ^index\.php$ - [L] # uploaded files RewriteRule ^([_0-9a-zA-Z-]+/)?files/(.+) wordpress/wp-includes/ms-files.php?file=$2 [L] # add a trailing slash to /wp-admin RewriteRule ^([_0-9a-zA-Z-]+/)?wp-admin$ $1wp-admin/ [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 . index.php [L]
Result:
.htaccess
rules work.htaccess
location is detected correctly
#43
in reply to:
↑ 40
;
follow-up:
↓ 46
@
12 years ago
Replying to guy_fr:
looking at the two previous comments, it seems that get_home_path() does not return the same delimitors if siteurl and home are identical or not.
Right. When siteurl
and home
are identical, it falls back to ABSPATH
:
http://core.trac.wordpress.org/browser/tags/3.5/wp-admin/includes/file.php#L84
We should probably make it always return consistent slashes in 3.6.
#44
@
12 years ago
- Owner set to markjaquith
- Resolution set to fixed
- Status changed from new to closed
In 23295:
#46
in reply to:
↑ 43
@
12 years ago
Replying to SergeyBiryukov:
We should probably make it always return consistent slashes in 3.6.
Follow-up: #23175
#48
@
11 years ago
Edit I can confirm 23073.7.2.diff does work, I was looking in the wrong spot.
Stats:
Windows 8
WAMP Version 2
Core in /multisite
Network site uses /en
Url: http://dev.work/multisite ABSPATH: D:\Sites\MultiSite/ $_SERVER['SCRIPT_FILENAME']: D:/Sites/MultiSite/wp-admin/network/index.php $_SERVER['DOCUMENT_ROOT'] D:/Sites get_home_path D:/Sites/MultiSite/ get_option('siteurl') http://dev.work/multisite get_option('home') http://dev.work/multisite
Moving for investigation.