Ticket #19796: 19796-hack-day.12.diff

File 19796-hack-day.12.diff, 26.8 KB (added by evansolomon, 9 months ago)

Remove unused IIS multisite rewrites from iis7_url_rewrite_rules()

Line 
1Index: wp-includes/canonical.php
2===================================================================
3--- wp-includes/canonical.php   (revision 21495)
4+++ wp-includes/canonical.php   (working copy)
5@@ -18,7 +18,7 @@
6  * one or the other.
7  *
8  * Prevents redirection for feeds, trackbacks, searches, comment popup, and
9- * admin URLs. Does not redirect on non-pretty-permalink-supporting IIS 7,
10+ * admin URLs. Does not redirect on non-pretty-permalink-supporting IIS 7,
11  * page/post previews, WP admin, Trackbacks, robots.txt, searches, or on POST
12  * requests.
13  *
14@@ -282,7 +282,7 @@
15 
16                if ( 'wp-register.php' == basename( $redirect['path'] ) ) {
17                        if ( is_multisite() )
18-                               $redirect_url = apply_filters( 'wp_signup_location', site_url( 'wp-signup.php' ) );
19+                               $redirect_url = apply_filters( 'wp_signup_location', network_site_url( 'wp-signup.php' ) );
20                        else
21                                $redirect_url = site_url( 'wp-login.php?action=register' );
22                        wp_redirect( $redirect_url, 301 );
23@@ -517,7 +517,7 @@
24                site_url( 'dashboard', 'relative' ),
25                site_url( 'admin', 'relative' ),
26        );
27-       if ( in_array( untrailingslashit( $_SERVER['REQUEST_URI'] ), $admins ) ) {
28+       if ( parse_url( admin_url( '', 'relative' ), PHP_URL_PATH ) !== $_SERVER['REQUEST_URI'] && in_array( untrailingslashit( $_SERVER['REQUEST_URI'] ), $admins ) ) {
29                wp_redirect( admin_url() );
30                exit;
31        }
32Index: wp-includes/functions.php
33===================================================================
34--- wp-includes/functions.php   (revision 21495)
35+++ wp-includes/functions.php   (working copy)
36@@ -1434,6 +1434,8 @@
37 function wp_upload_dir( $time = null ) {
38        global $_wp_switched;
39        $siteurl = get_option( 'siteurl' );
40+       $homeurl = get_option( 'home' );
41+       $baseurl = is_multisite() && defined( 'MULTISITE' ) ? $homeurl : $siteurl;
42        $upload_path = get_option( 'upload_path' );
43        $upload_path = trim($upload_path);
44        $main_override = is_multisite() && defined( 'MULTISITE' ) && is_main_site();
45@@ -1453,12 +1455,12 @@
46                if ( empty($upload_path) || ( 'wp-content/uploads' == $upload_path ) || ( $upload_path == $dir ) )
47                        $url = WP_CONTENT_URL . '/uploads';
48                else
49-                       $url = trailingslashit( $siteurl ) . $upload_path;
50+                       $url = trailingslashit( $baseurl ) . $upload_path;
51        }
52 
53        if ( defined('UPLOADS') && ! $main_override && ! $_wp_switched ) {
54                $dir = ABSPATH . UPLOADS;
55-               $url = trailingslashit( $siteurl ) . UPLOADS;
56+               $url = trailingslashit( $baseurl ) . UPLOADS;
57        }
58 
59        if ( is_multisite() && ! $main_override && ! $_wp_switched  ) {
60Index: wp-includes/rewrite.php
61===================================================================
62--- wp-includes/rewrite.php     (revision 21495)
63+++ wp-includes/rewrite.php     (working copy)
64@@ -1726,75 +1726,17 @@
65                <rewrite>
66                        <rules>';
67                }
68-               if ( !is_multisite() ) {
69-                       $rules .= '
70-                               <rule name="wordpress" patternSyntax="Wildcard">
71-                                       <match url="*" />
72-                                               <conditions>
73-                                                       <add input="{REQUEST_FILENAME}" matchType="IsFile" negate="true" />
74-                                                       <add input="{REQUEST_FILENAME}" matchType="IsDirectory" negate="true" />
75-                                               </conditions>
76-                                       <action type="Rewrite" url="index.php" />
77-                               </rule>';
78-               } else {
79-                       if (is_subdomain_install()) {
80-                               $rules .= '
81-                               <rule name="wordpress - Rule 1" stopProcessing="true">
82-                                       <match url="^index\.php$" ignoreCase="false" />
83-                                       <action type="None" />
84-                               </rule>
85-                               <rule name="wordpress - Rule 2" stopProcessing="true">
86-                                       <match url="^files/(.+)" ignoreCase="false" />
87-                                       <action type="Rewrite" url="wp-includes/ms-files.php?file={R:1}" appendQueryString="false" />
88-                               </rule>
89-                               <rule name="wordpress - Rule 3" stopProcessing="true">
90-                                       <match url="^" ignoreCase="false" />
91-                                       <conditions logicalGrouping="MatchAny">
92-                                               <add input="{REQUEST_FILENAME}" matchType="IsFile" ignoreCase="false" />
93-                                               <add input="{REQUEST_FILENAME}" matchType="IsDirectory" ignoreCase="false" />
94+
95+               $rules .= '
96+                       <rule name="wordpress" patternSyntax="Wildcard">
97+                               <match url="*" />
98+                                       <conditions>
99+                                               <add input="{REQUEST_FILENAME}" matchType="IsFile" negate="true" />
100+                                               <add input="{REQUEST_FILENAME}" matchType="IsDirectory" negate="true" />
101                                        </conditions>
102-                                       <action type="None" />
103-                               </rule>
104-                               <rule name="wordpress - Rule 4" stopProcessing="true">
105-                                       <match url="." ignoreCase="false" />
106-                                       <action type="Rewrite" url="index.php" />
107-                               </rule>';
108-                       } else {
109-                               $rules .= '
110-                               <rule name="wordpress - Rule 1" stopProcessing="true">
111-                                       <match url="^index\.php$" ignoreCase="false" />
112-                                       <action type="None" />
113-                               </rule>
114-                               <rule name="wordpress - Rule 2" stopProcessing="true">
115-                                       <match url="^([_0-9a-zA-Z-]+/)?files/(.+)" ignoreCase="false" />
116-                                       <action type="Rewrite" url="wp-includes/ms-files.php?file={R:2}" appendQueryString="false" />
117-                               </rule>
118-                               <rule name="wordpress - Rule 3" stopProcessing="true">
119-                                       <match url="^([_0-9a-zA-Z-]+/)?wp-admin$" ignoreCase="false" />
120-                                       <action type="Redirect" url="{R:1}wp-admin/" redirectType="Permanent" />
121-                               </rule>
122-                               <rule name="wordpress - Rule 4" stopProcessing="true">
123-                                       <match url="^" ignoreCase="false" />
124-                                       <conditions logicalGrouping="MatchAny">
125-                                               <add input="{REQUEST_FILENAME}" matchType="IsFile" ignoreCase="false" />
126-                                               <add input="{REQUEST_FILENAME}" matchType="IsDirectory" ignoreCase="false" />
127-                                       </conditions>
128-                                       <action type="None" />
129-                               </rule>
130-                               <rule name="wordpress - Rule 5" stopProcessing="true">
131-                                       <match url="^([_0-9a-zA-Z-]+/)?(wp-(content|admin|includes).*)" ignoreCase="false" />
132-                                       <action type="Rewrite" url="{R:1}" />
133-                               </rule>
134-                               <rule name="wordpress - Rule 6" stopProcessing="true">
135-                                       <match url="^([_0-9a-zA-Z-]+/)?(.*\.php)$" ignoreCase="false" />
136-                                       <action type="Rewrite" url="{R:2}" />
137-                               </rule>
138-                               <rule name="wordpress - Rule 7" stopProcessing="true">
139-                                       <match url="." ignoreCase="false" />
140-                                       <action type="Rewrite" url="index.php" />
141-                               </rule>';
142-                       }
143-               }
144+                               <action type="Rewrite" url="index.php" />
145+                       </rule>';
146+
147                if ( $add_parent_tags ) {
148                        $rules .= '
149                        </rules>
150Index: wp-includes/ms-load.php
151===================================================================
152--- wp-includes/ms-load.php     (revision 21495)
153+++ wp-includes/ms-load.php     (working copy)
154@@ -142,6 +142,7 @@
155                $current_site->id = defined( 'SITE_ID_CURRENT_SITE' ) ? SITE_ID_CURRENT_SITE : 1;
156                $current_site->domain = DOMAIN_CURRENT_SITE;
157                $current_site->path   = $path = PATH_CURRENT_SITE;
158+
159                if ( defined( 'BLOG_ID_CURRENT_SITE' ) )
160                        $current_site->blog_id = BLOG_ID_CURRENT_SITE;
161                elseif ( defined( 'BLOGID_CURRENT_SITE' ) ) // deprecated.
162Index: wp-includes/ms-settings.php
163===================================================================
164--- wp-includes/ms-settings.php (revision 21495)
165+++ wp-includes/ms-settings.php (working copy)
166@@ -86,7 +86,7 @@
167                        if ( '%siteurl%' == $destination )
168                                $destination = "http://" . $current_site->domain . $current_site->path;
169                } else {
170-                       $destination = 'http://' . $current_site->domain . $current_site->path . 'wp-signup.php?new=' . str_replace( '.' . $current_site->domain, '', $domain );
171+                       $destination = 'http://' . $current_site->domain . $current_site->wp_siteurl_subdir . 'wp-signup.php?new=' . str_replace( '.' . $current_site->domain, '', $domain );
172                }
173                header( 'Location: ' . $destination );
174                die();
175Index: wp-includes/formatting.php
176===================================================================
177--- wp-includes/formatting.php  (revision 21495)
178+++ wp-includes/formatting.php  (working copy)
179@@ -1355,6 +1355,46 @@
180 }
181 
182 /**
183+ * Removes trailing and leading strings from elements (array), then combines elements
184+ * with a string in between each element. Leading and trailing strings should be
185+ * manually concatenated.
186+ *
187+ * @since  3.5.0
188+ *
189+ * @param  array $parts Items to be combined
190+ * @param  string $string String to be used to combine items
191+ * @return  string Concatenated parts with given strings in between each element.
192+ */
193+function join_with_string( $parts, $string ) {
194+       $members = array();
195+       foreach ( (array) $parts as $part ) {
196+               if ( is_array( $parts ) ) {
197+                       foreach ( $part as $member ) {
198+                               $members[] = trim( $member, $string );
199+                       }
200+               } else {
201+                       $members[] = trim( $part, $string );
202+               }
203+       }
204+
205+       return implode( $string, $members );
206+}
207+
208+/**
209+ * Removes trailing and leading slashes from elements (array or string args), then combines elements
210+ * with a slash in between each element. Leading and trailing slashes should be
211+ * manually concatenated.
212+ *
213+ * @since  3.5.0
214+ *
215+ * @return  string Concatenated string with slashes in between each element.
216+ */
217+function join_with_slashes() {
218+       $args = func_get_args();
219+       return join_with_string( $args, '/' );
220+}
221+
222+/**
223  * Adds slashes to escape strings.
224  *
225  * Slashes will first be removed if magic_quotes_gpc is set, see {@link
226Index: wp-includes/ms-functions.php
227===================================================================
228--- wp-includes/ms-functions.php        (revision 21495)
229+++ wp-includes/ms-functions.php        (working copy)
230@@ -595,8 +595,8 @@
231                $mydomain = $blogname . '.' . preg_replace( '|^www\.|', '', $domain );
232                $path = $base;
233        } else {
234-               $mydomain = "$domain";
235-               $path = $base.$blogname.'/';
236+               $mydomain = $domain;
237+               $path = '/' . join_with_slashes( $base, $blogname ) . '/';
238        }
239        if ( domain_exists($mydomain, $path) )
240                $errors->add('blogname', __('Sorry, that site already exists!'));
241@@ -1142,7 +1142,7 @@
242 
243        $wpdb->suppress_errors(false);
244 
245-       $url = get_blogaddress_by_id($blog_id);
246+       $homeurl = $siteurl = untrailingslashit( get_blogaddress_by_id( $blog_id ) );
247 
248        // Set everything up
249        make_db_current_silent( 'blog' );
250@@ -1150,21 +1150,22 @@
251        populate_roles();
252        $wp_roles->_init();
253 
254-       $url = untrailingslashit( $url );
255-       // fix url.
256-       update_option('siteurl', $url);
257-       update_option('home', $url);
258-       update_option('fileupload_url', $url . "/files" );
259-       update_option('upload_path', UPLOADBLOGSDIR . "/$blog_id/files");
260+       // Maybe fix url
261+       if ( defined( 'WP_SITEURL_SUBDIR' ) && WP_SITEURL_SUBDIR )
262+               $siteurl = join_with_slashes( $siteurl, WP_SITEURL_SUBDIR, '/' );
263+
264+       update_option('siteurl', $siteurl);
265+       update_option('home', $homeurl);
266+       update_option('fileupload_url', join_with_slashes( $homeurl, 'files', '/' ) );
267+       update_option('upload_path', join_with_slashes( UPLOADBLOGSDIR, $blog_id, 'files', '/' ) );
268        update_option('blogname', stripslashes( $blog_title ) );
269        update_option('admin_email', '');
270        $wpdb->update( $wpdb->options, array('option_value' => ''), array('option_name' => 'admin_email') );
271 
272        // remove all perms
273-       $wpdb->delete( $wpdb->usermeta, array( 'meta_key' => $table_prefix.'user_level' ) );
274+       $wpdb->delete( $wpdb->usermeta, array( 'meta_key' => $table_prefix . 'user_level'   ) );
275+       $wpdb->delete( $wpdb->usermeta, array( 'meta_key' => $table_prefix . 'capabilities' ) );
276 
277-       $wpdb->delete( $wpdb->usermeta, array( 'meta_key' => $table_prefix.'capabilities' ) );
278-
279        $wpdb->suppress_errors( false );
280 }
281 
282Index: wp-includes/link-template.php
283===================================================================
284--- wp-includes/link-template.php       (revision 21495)
285+++ wp-includes/link-template.php       (working copy)
286@@ -1964,11 +1964,14 @@
287                        $scheme = ( is_ssl() ? 'https' : 'http' );
288        }
289 
290-       if ( empty( $blog_id ) || !is_multisite() ) {
291-               $url = get_option( 'siteurl' );
292+       if ( empty( $blog_id ) ) {
293+               if ( is_multisite() )
294+                       $url = get_option( 'home' );
295+               else
296+                       $url = get_option( 'siteurl' );
297        } else {
298                switch_to_blog( $blog_id );
299-               $url = get_option( 'siteurl' );
300+               $url = get_option( 'home' );
301                restore_current_blog();
302        }
303 
304Index: wp-admin/network/site-new.php
305===================================================================
306--- wp-admin/network/site-new.php       (revision 21495)
307+++ wp-admin/network/site-new.php       (working copy)
308@@ -62,10 +62,10 @@
309 
310        if ( is_subdomain_install() ) {
311                $newdomain = $domain . '.' . preg_replace( '|^www\.|', '', $current_site->domain );
312-               $path = $base;
313+               $path      = $current_site->path;
314        } else {
315                $newdomain = $current_site->domain;
316-               $path = $base . $domain . '/';
317+               $path      = $current_site->path . $domain . '/';
318        }
319 
320        $password = 'N/A';
321Index: wp-admin/network.php
322===================================================================
323--- wp-admin/network.php        (revision 21495)
324+++ wp-admin/network.php        (working copy)
325@@ -51,8 +51,8 @@
326  * @return bool Whether subdomain install is allowed
327  */
328 function allow_subdomain_install() {
329-       $domain = preg_replace( '|https?://([^/]+)|', '$1', get_option( 'siteurl' ) );
330-       if( false !== strpos( $domain, '/' ) || 'localhost' == $domain || preg_match( '|[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+|', $domain ) )
331+       $domain = preg_replace( '|https?://([^/]+)|', '$1', get_option( 'home' ) );
332+       if( parse_url( get_option( 'home' ), PHP_URL_PATH ) || 'localhost' == $domain || preg_match( '|^[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+$|', $domain ) )
333                return false;
334 
335        return true;
336@@ -144,13 +144,6 @@
337 function network_step1( $errors = false ) {
338        global $is_apache;
339 
340-       if ( get_option( 'siteurl' ) != get_option( 'home' ) ) {
341-               echo '<div class="error"><p><strong>' . __('ERROR:') . '</strong> ' . sprintf( __( 'Your <strong>WordPress address</strong> must match your <strong>Site address</strong> before creating a Network. See <a href="%s">General Settings</a>.' ), esc_url( admin_url( 'options-general.php' ) ) ) . '</p></div>';
342-               echo '</div>';
343-               include ( ABSPATH . 'wp-admin/admin-footer.php' );
344-               die();
345-       }
346-
347        if ( defined('DO_NOT_UPGRADE_GLOBAL_TABLES') ) {
348                echo '<div class="error"><p><strong>' . __('ERROR:') . '</strong> ' . __( 'The constant DO_NOT_UPGRADE_GLOBAL_TABLES cannot be defined when creating a network.' ) . '</p></div>';
349                echo '</div>';
350@@ -314,21 +307,25 @@
351  * @since 3.0.0
352  */
353 function network_step2( $errors = false ) {
354-       global $base, $wpdb;
355-       $hostname = get_clean_basedomain();
356+       global $wpdb;
357 
358-       if ( ! isset( $base ) )
359-               $base = trailingslashit( stripslashes( dirname( dirname( $_SERVER['SCRIPT_NAME'] ) ) ) );
360+       $hostname          = get_clean_basedomain();
361+       $slashed_home      = trailingslashit( get_option( 'home'    ) );
362+       $slashed_siteurl   = trailingslashit( get_option( 'siteurl' ) );
363+       $wp_siteurl_subdir = '/' . str_replace( $slashed_home, '', $slashed_siteurl );
364+       $rewrite_base      = ! empty( $wp_siteurl_subdir ) ? ltrim( trailingslashit( $wp_siteurl_subdir ), '/' ) : '';
365+       $base              = parse_url( $slashed_home, PHP_URL_PATH );
366 
367        // Wildcard DNS message.
368        if ( is_wp_error( $errors ) )
369                echo '<div class="error">' . $errors->get_error_message() . '</div>';
370 
371-       if ( $_POST ) {
372-               if ( allow_subdomain_install() )
373+       if ( ! empty( $_POST ) ) {
374+               if ( allow_subdomain_install() ) {
375                        $subdomain_install = allow_subdirectory_install() ? ! empty( $_POST['subdomain_install'] ) : true;
376-               else
377+               } else {
378                        $subdomain_install = false;
379+               }
380        } else {
381                if ( is_multisite() ) {
382                        $subdomain_install = is_subdomain_install();
383@@ -337,6 +334,10 @@
384 <?php
385                } else {
386                        $subdomain_install = (bool) $wpdb->get_var( "SELECT meta_value FROM $wpdb->sitemeta WHERE site_id = 1 AND meta_key = 'subdomain_install'" );
387+
388+       $subdir_match       = $subdomain_install ? '' : '(?:[_0-9a-zA-Z-]+/)?';
389+       $subdir_replacement = $subdomain_install ? '' : '$1';
390+
391 ?>
392        <div class="error"><p><strong><?php _e('Warning:'); ?></strong> <?php _e( 'An existing WordPress network was detected.' ); ?></p></div>
393        <p><?php _e( 'Please complete the configuration steps. To create a new network, you will need to empty or remove the network database tables.' ); ?></p>
394@@ -344,7 +345,7 @@
395                }
396        }
397 
398-       if ( $_POST || ! is_multisite() ) {
399+       if ( ! empty( $_POST ) || ! is_multisite() ) {
400 ?>
401                <h3><?php esc_html_e( 'Enabling the Network' ); ?></h3>
402                <p><?php _e( 'Complete the following steps to enable the features for creating a network of sites.' ); ?></p>
403@@ -369,20 +370,25 @@
404                                <textarea class="code" readonly="readonly" cols="100" rows="7">
405 define('MULTISITE', true);
406 define('SUBDOMAIN_INSTALL', <?php echo $subdomain_install ? 'true' : 'false'; ?>);
407-$base = '<?php echo $base; ?>';
408 define('DOMAIN_CURRENT_SITE', '<?php echo $hostname; ?>');
409 define('PATH_CURRENT_SITE', '<?php echo $base; ?>');
410 define('SITE_ID_CURRENT_SITE', 1);
411-define('BLOG_ID_CURRENT_SITE', 1);</textarea>
412+define('BLOG_ID_CURRENT_SITE', 1);
413+<?php if ( $wp_siteurl_subdir ): ?>
414+define('WP_SITEURL_SUBDIR', '<?php echo $wp_siteurl_subdir; ?>');
415+<?php endif; // $wp_siteurl_subdir ?>
416+</textarea>
417 <?php
418        $keys_salts = array( 'AUTH_KEY' => '', 'SECURE_AUTH_KEY' => '', 'LOGGED_IN_KEY' => '', 'NONCE_KEY' => '', 'AUTH_SALT' => '', 'SECURE_AUTH_SALT' => '', 'LOGGED_IN_SALT' => '', 'NONCE_SALT' => '' );
419        foreach ( $keys_salts as $c => $v ) {
420-               if ( defined( $c ) )
421+               if ( defined( $c ) ) {
422                        unset( $keys_salts[ $c ] );
423+               }
424        }
425+
426        if ( ! empty( $keys_salts ) ) {
427                $keys_salts_str = '';
428-               $from_api = wp_remote_get( 'https://api.wordpress.org/secret-key/1.1/salt/' );
429+               $from_api       = wp_remote_get( 'https://api.wordpress.org/secret-key/1.1/salt/' );
430                if ( is_wp_error( $from_api ) ) {
431                        foreach ( $keys_salts as $c => $v ) {
432                                $keys_salts_str .= "\ndefine( '$c', '" . wp_generate_password( 64, true, true ) . "' );";
433@@ -404,10 +410,13 @@
434 </li>
435 <?php
436        if ( iis7_supports_permalinks() ) :
437+               // IIS doesn't support RewriteBase, all your RewriteBase are belong to us
438+               $iis_subdir_match = ltrim( $base, '/' ) . $subdir_match;
439+               $iis_rewrite_base = ltrim( $base, '/' ) . $rewrite_base;
440+               $iis_subdir_replacement = $subdomain_install ? '' : '{R:1}';
441 
442-                       if ( $subdomain_install ) {
443-                               $web_config_file =
444-'<?xml version="1.0" encoding="UTF-8"?>
445+               $web_config_file = <<<EOF
446+<?xml version="1.0" encoding="UTF-8"?>
447 <configuration>
448     <system.webServer>
449         <rewrite>
450@@ -417,45 +426,14 @@
451                     <action type="None" />
452                 </rule>
453                 <rule name="WordPress Rule 2" stopProcessing="true">
454-                    <match url="^files/(.+)" ignoreCase="false" />
455-                    <action type="Rewrite" url="wp-includes/ms-files.php?file={R:1}" appendQueryString="false" />
456+                    <match url="^{$iis_subdir_match}files/(.+)" ignoreCase="false" />
457+                    <action type="Rewrite" url="{$iis_rewrite_base}wp-includes/ms-files.php?file={R:1}" appendQueryString="false" />
458                 </rule>
459                 <rule name="WordPress Rule 3" stopProcessing="true">
460-                    <match url="^" ignoreCase="false" />
461-                    <conditions logicalGrouping="MatchAny">
462-                        <add input="{REQUEST_FILENAME}" matchType="IsFile" ignoreCase="false" />
463-                        <add input="{REQUEST_FILENAME}" matchType="IsDirectory" ignoreCase="false" />
464-                    </conditions>
465-                    <action type="None" />
466+                    <match url="^{$iis_subdir_match}wp-admin$" ignoreCase="false" />
467+                    <action type="Redirect" url="{$iis_subdir_replacement}wp-admin/" redirectType="Permanent" />
468                 </rule>
469                 <rule name="WordPress Rule 4" stopProcessing="true">
470-                    <match url="." ignoreCase="false" />
471-                    <action type="Rewrite" url="index.php" />
472-                </rule>
473-            </rules>
474-        </rewrite>
475-    </system.webServer>
476-</configuration>';
477-                       } else {
478-                               $web_config_file =
479-'<?xml version="1.0" encoding="UTF-8"?>
480-<configuration>
481-    <system.webServer>
482-        <rewrite>
483-            <rules>
484-                <rule name="WordPress Rule 1" stopProcessing="true">
485-                    <match url="^index\.php$" ignoreCase="false" />
486-                    <action type="None" />
487-                </rule>
488-                <rule name="WordPress Rule 2" stopProcessing="true">
489-                    <match url="^([_0-9a-zA-Z-]+/)?files/(.+)" ignoreCase="false" />
490-                    <action type="Rewrite" url="wp-includes/ms-files.php?file={R:2}" appendQueryString="false" />
491-                </rule>
492-                <rule name="WordPress Rule 3" stopProcessing="true">
493-                    <match url="^([_0-9a-zA-Z-]+/)?wp-admin$" ignoreCase="false" />
494-                    <action type="Redirect" url="{R:1}wp-admin/" redirectType="Permanent" />
495-                </rule>
496-                <rule name="WordPress Rule 4" stopProcessing="true">
497                     <match url="^" ignoreCase="false" />
498                     <conditions logicalGrouping="MatchAny">
499                         <add input="{REQUEST_FILENAME}" matchType="IsFile" ignoreCase="false" />
500@@ -464,12 +442,12 @@
501                     <action type="None" />
502                 </rule>
503                 <rule name="WordPress Rule 5" stopProcessing="true">
504-                    <match url="^[_0-9a-zA-Z-]+/(wp-(content|admin|includes).*)" ignoreCase="false" />
505-                    <action type="Rewrite" url="{R:1}" />
506+                    <match url="^{$iis_subdir_match}(wp-(content|admin|includes).*)" ignoreCase="false" />
507+                    <action type="Rewrite" url="{$iis_rewrite_base}{R:1}" />
508                 </rule>
509                 <rule name="WordPress Rule 6" stopProcessing="true">
510-                    <match url="^([_0-9a-zA-Z-]+/)?(.*\.php)$" ignoreCase="false" />
511-                    <action type="Rewrite" url="{R:2}" />
512+                    <match url="^{$iis_subdir_match}([_0-9a-zA-Z-]+/)?(.*\.php)$" ignoreCase="false" />
513+                    <action type="Rewrite" url="{$iis_rewrite_base}{R:2}" />
514                 </rule>
515                 <rule name="WordPress Rule 7" stopProcessing="true">
516                     <match url="." ignoreCase="false" />
517@@ -478,40 +456,39 @@
518             </rules>
519         </rewrite>
520     </system.webServer>
521-</configuration>';
522-                       }
523+</configuration>
524+EOF;
525+
526        ?>
527-               <li><p><?php printf( __( 'Add the following to your <code>web.config</code> file in <code>%s</code>, replacing other WordPress rules:' ), ABSPATH ); ?></p>
528+               <li><p><?php printf( __( 'Add the following to your <code>web.config</code> file in <code>%s</code>, replacing other WordPress rules:' ), $wp_siteurl_subdir ? dirname( ABSPATH ) : ABSPATH ); ?></p>
529                <textarea class="code" readonly="readonly" cols="100" rows="20">
530-               <?php echo esc_textarea( $web_config_file ); ?>
531+<?php echo esc_textarea( $web_config_file ); ?>
532                </textarea></li>
533                </ol>
534 
535        <?php else : // end iis7_supports_permalinks(). construct an htaccess file instead:
536-
537-               $htaccess_file = 'RewriteEngine On
538-RewriteBase ' . $base . '
539+               $htaccess_file = <<<EOF
540+RewriteEngine On
541+RewriteBase {$base}
542 RewriteRule ^index\.php$ - [L]
543 
544 # uploaded files
545-RewriteRule ^' . ( $subdomain_install ? '' : '([_0-9a-zA-Z-]+/)?' ) . 'files/(.+) wp-includes/ms-files.php?file=$' . ( $subdomain_install ? 1 : 2 ) . ' [L]' . "\n";
546+RewriteRule ^{$subdir_match}files/(.+) {$rewrite_base}wp-includes/ms-files.php?file=$1 [L]
547 
548-               if ( ! $subdomain_install )
549-                       $htaccess_file .= "\n# add a trailing slash to /wp-admin\n" . 'RewriteRule ^([_0-9a-zA-Z-]+/)?wp-admin$ $1wp-admin/ [R=301,L]' . "\n";
550+# add a trailing slash to /wp-admin
551+RewriteRule ^{$subdir_match}wp-admin$ {$subdir_replacement}wp-admin/ [R=301,L]
552 
553-               $htaccess_file .= "\n" . 'RewriteCond %{REQUEST_FILENAME} -f [OR]
554+RewriteCond %{REQUEST_FILENAME} -f [OR]
555 RewriteCond %{REQUEST_FILENAME} -d
556-RewriteRule ^ - [L]';
557+RewriteRule ^ - [L]
558+RewriteRule ^{$subdir_match}(wp-(content|admin|includes).*) {$rewrite_base}$1 [L]
559+RewriteRule ^{$subdir_match}(.*\.php)$ {$rewrite_base}$1 [L]
560+RewriteRule . index.php [L]
561+EOF;
562 
563-               // @todo custom content dir.
564-               if ( ! $subdomain_install )
565-                       $htaccess_file .= "\nRewriteRule  ^[_0-9a-zA-Z-]+/(wp-(content|admin|includes).*) $1 [L]\nRewriteRule  ^[_0-9a-zA-Z-]+/(.*\.php)$ $1 [L]";
566-
567-               $htaccess_file .= "\nRewriteRule . index.php [L]";
568-
569                ?>
570-               <li><p><?php printf( __( 'Add the following to your <code>.htaccess</code> file in <code>%s</code>, replacing other WordPress rules:' ), ABSPATH ); ?></p>
571-               <textarea class="code" readonly="readonly" cols="100" rows="<?php echo $subdomain_install ? 11 : 16; ?>">
572+               <li><p><?php printf( __( 'Add the following to your <code>.htaccess</code> file in <code>%s</code>, replacing other WordPress rules:' ), $wp_siteurl_subdir ? dirname( ABSPATH ) : ABSPATH ); ?></p>
573+               <textarea class="code" readonly="readonly" cols="100" rows="16">
574 <?php echo esc_textarea( $htaccess_file ); ?></textarea></li>
575                </ol>
576 
577@@ -523,24 +500,26 @@
578        }
579 }
580 
581-if ( $_POST ) {
582+if ( ! empty( $_POST ) ) {
583 
584-       $base = trailingslashit( stripslashes( dirname( dirname( $_SERVER['SCRIPT_NAME'] ) ) ) );
585-
586        check_admin_referer( 'install-network-1' );
587 
588        require_once( ABSPATH . 'wp-admin/includes/upgrade.php' );
589+
590        // create network tables
591        install_network();
592-       $hostname = get_clean_basedomain();
593+
594+       $base              = parse_url( trailingslashit( get_option( 'home' ) ), PHP_URL_PATH );
595        $subdomain_install = allow_subdomain_install() ? !empty( $_POST['subdomain_install'] ) : false;
596+
597        if ( ! network_domain_check() ) {
598                $result = populate_network( 1, get_clean_basedomain(), sanitize_email( $_POST['email'] ), stripslashes( $_POST['sitename'] ), $base, $subdomain_install );
599                if ( is_wp_error( $result ) ) {
600-                       if ( 1 == count( $result->get_error_codes() ) && 'no_wildcard_dns' == $result->get_error_code() )
601+                       if ( 1 == count( $result->get_error_codes() ) && 'no_wildcard_dns' == $result->get_error_code() ) {
602                                network_step2( $result );
603-                       else
604+                       } else {
605                                network_step1( $result );
606+                       }
607                } else {
608                        network_step2();
609                }
610Index: wp-admin/includes/ms.php
611===================================================================
612--- wp-admin/includes/ms.php    (revision 21495)
613+++ wp-admin/includes/ms.php    (working copy)
614@@ -673,7 +673,7 @@
615        <?php if ( in_array( get_site_option( 'registration' ), array( 'all', 'blog' ) ) ) : ?>
616                <tr>
617                        <th scope="row" colspan="2" class="th-full">
618-                               <a href="<?php echo apply_filters( 'wp_signup_location', network_home_url( 'wp-signup.php' ) ); ?>"><?php _e( 'Create a New Site' ); ?></a>
619+                               <a href="<?php echo apply_filters( 'wp_signup_location', network_site_url( 'wp-signup.php' ) ); ?>"><?php _e( 'Create a New Site' ); ?></a>
620                        </th>
621                </tr>
622        <?php endif; ?>
623Index: wp-signup.php
624===================================================================
625--- wp-signup.php       (revision 21495)
626+++ wp-signup.php       (working copy)
627@@ -394,7 +394,7 @@
628                $proto = 'https://';
629        else
630                $proto = 'http://';
631-       $login_url = site_url( 'wp-login.php?redirect_to=' . urlencode($proto . $_SERVER['HTTP_HOST'] . '/wp-signup.php' ));
632+       $login_url = site_url( 'wp-login.php?redirect_to=' . urlencode( network_site_url( 'wp-signup.php' ) ) );
633        echo sprintf( __( 'You must first <a href="%s">log in</a>, and then you can create a new site.' ), $login_url );
634 } else {
635        $stage = isset( $_POST['stage'] ) ?  $_POST['stage'] : 'default';
636Index: wp-login.php
637===================================================================
638--- wp-login.php        (revision 21495)
639+++ wp-login.php        (working copy)
640@@ -509,7 +509,7 @@
641 case 'register' :
642        if ( is_multisite() ) {
643                // Multisite uses wp-signup.php
644-               wp_redirect( apply_filters( 'wp_signup_location', site_url('wp-signup.php') ) );
645+               wp_redirect( apply_filters( 'wp_signup_location', network_site_url('wp-signup.php') ) );
646                exit;
647        }
648