Archive

Posts Tagged ‘iis’

FIX: WordPress Older Posts not working in IIS with Permalinks

April 28th, 2010 2 comments

I spent some time tweaking my blog today after moving it to some fresh hardware. You may find that everything is loading much faster now which can be attributed to two plugins in addition to the hardware upgrade – wp-super-cache and wp-widget-cache.

I’ve also fixed a long standing bug with my particular configuration of WordPress that runs on IIS which causes the “Older posts” link at the bottom does not function for the second page. The WordPress generated URL for this is

http://www.thushanfernando.com/index.php/Index.php/page/2

Which is a bit problematic, this ofcourse can be reproduced only on IIS from my musings (serves me right eh?). There are a couple of suggestions by people on the forums already, but I wasn’t too keen on them as they seemed too high-level fixes.

I’ve enabled Permalinks with this format:

http://www.thushanfernando.com/index.php/2010/04/28/sample-post/

So I looked through the sources to see why this was happening. After a bit of snooping about I got to the get_pagenum_link function in wp-includes/link-template.php file.

Heres a bit of source for reference – this is with WordPress 2.9.2:

function get_pagenum_link($pagenum = 1) {
	global $wp_rewrite;

	$pagenum = (int) $pagenum;

	$request = remove_query_arg( 'paged' );

	$home_root = parse_url(get_option('home'));
	$home_root = ( isset($home_root['path']) ) ? $home_root['path'] : '';
	$home_root = preg_quote( trailingslashit( $home_root ), '|' );

	$request = preg_replace('|^'. $home_root . '|', '', $request);
	$request = preg_replace('|^/+|', '', $request);

	if ( !$wp_rewrite->using_permalinks() || is_admin() ) {
		$base = trailingslashit( get_bloginfo( 'home' ) );

		if ( $pagenum > 1 ) {
			$result = add_query_arg( 'paged', $pagenum, $base . $request );
		} else {
			$result = $base . $request;
		}
	} else {
		$qs_regex = '|\?.*?$|';
		preg_match( $qs_regex, $request, $qs_match );

		if ( !empty( $qs_match[0] ) ) {
			$query_string = $qs_match[0];
			$request = preg_replace( $qs_regex, '', $request );
		} else {
			$query_string = '';
		}

		$request = preg_replace( '|page/\d+/?$|', '', $request);
		$request = preg_replace( '|^index\.php|', '', $request);
		$request = ltrim($request, '/');

		$base = trailingslashit( get_bloginfo( 'url' ) );

	if ( $wp_rewrite->using_index_permalinks() && ( $pagenum > 1 || '' != $request ) )
		$base .= 'index.php/';

		if ( $pagenum > 1 ) {
			$request = ( ( !empty( $request ) ) ? trailingslashit( $request ) : $request ) . user_trailingslashit( 'page/' . $pagenum, 'paged' );
		}

		$result = $base . $request . $query_string;
	}

	$result = apply_filters('get_pagenum_link', $result);

	return $result;
}

This function (from reading through) essentially generates the links for the page numbers & page navigation taking into account Permalinks if configured. This is all fine and dandy for Unix hosts but for Windows, unfortunately this bit of code fails us.

...
$request = preg_replace( '|page/\d+/?$|', '', $request);
$request = preg_replace( '|^index\.php|', '', $request);
$request = ltrim($request, '/');
...

As the preg_replace is case sensitive, it will not replace the invalid Index.php that is seen on IIS. So the easiest fix is to tweak the regex pattern a little bit and tell it be case insensitive.

...
$request = preg_replace( '|page/\d+/?$|', '', $request);
$request = preg_replace( '/|^index\.php|/i', '', $request);
$request = ltrim($request, '/');
...

This will then generate the (invalid) urls and the preg_replace will remove any additional Index.php’s from the request URL as its already mentioned in the $base variable a few lines below:

...
if ( $wp_rewrite->using_index_permalinks() && ( $pagenum > 1 || '' != $request ) )
$base .= 'index.php/';
...

Once you make the change and upload the files, your “Older posts” will start working again. I’ll submit a patch to WordPress I’ve submitted a patch to WordPress Trac, now its just a wait and see what they say, in the meantime here’s a patch file if you don’t want to modify sources manually. If there any issues, post a comment 🙂

{lang: 'en-GB'}
Share

Windows Server 2008 R2 Beta Download

January 11th, 2009 1 comment

Now that the road to downloading Windows 7 Beta 1 and finding a key for Windows 7 Beta 1 have been travelled by most, its time to look towards Windows Server 2008 R2 Beta.

This release contains some significant updates to the virtualisation hypervisor in Windows Server (Hyper-Vwiki) and will only be offered as a 64-bit release sporting 256 processors (with 32 processors in VMs).

{lang: 'en-GB'}
Share

TIP: Quick tip on how to Debug ASP.NET Web Application Deployed in IIS

September 8th, 2008 1 comment

Heres a real quick tip (+ info) on how to debug a ASP.NET Web Application/Site when running inside IIS itself. After the launch of Whidbey (Visual Studio 2005) we didn’t really need to have Internet Information Services (IIS) installed thanks partly to the bundled hosting engine (based on Cassini). But sometimes – just sometimes  🙄 – when you deploy your ASP.NET web apps to IIS you’ll find things break – like we just experienced – unlike running via the internal web-server.

To debug an already running IIS process – with the project loaded.

  1. Debug > Attach to Process
  2. Select either aspnet_wp.exe or w3wp.exe. (see note below)
  3. Enter a break-point somewhere in your code
  4. Visit the page/refresh.

Sometimes you may need to untick “Enable Just My Code (Managed Only)” in the Options > Debugging list.

Why the aspnet_wp.exe and w3wp.exe difference?

If the IIS server is running under IIS 5.0 Isolation Mode, then you need to attach to the ASP.NET Worker Process (aspnet_wp.exe) where as if your running under the Worker Process Isolation Mode (which is the default in IIS 6.0) you will need to attach to the w3wp.exe process.

From the TechNet Documentation:

Worker process isolation mode delivers all the benefits of IIS 6.0 new architecture: robust application pooling; automated restarts, scalability, debugging; and finely-tuned performance tuning. Web applications run with the Network Service identity, which provides a security advantage: the Network Service account has lower access privileges than LocalSystem.

In version 5.x of IIS the ASP.NET ISAPI Filter (aspnet_isapi) which is an unmanaged piece of code that runs within the inetinfo.exe process that offloads the work to the ASP.NET Worker Process (aspnet_wp) that trickles the workload down the rabbit hole.

However in IIS 6.x the process is a little different, specifically we have a kernel mode HTTP driver (http.sys) which ships apart of the Windows Networking subsystem. This acts as the gateway for the incoming requests for the web-server. It first parses the request and dispatches it to the IIS 6.0 Worker Process (w3wp.exe) which then loads the ASP.NET ISAPI (aspnet_isapi) and follows on down the rabbit hole.

Read the TechNet articles on more information about the HTTP Protocol Stack in IIS 6.0.

Just how far down does the rabbit hole go?

If your interested in learning more about the internals of the ASP.NET Worker Process and inparticular how ASP.NET works ‘under the hood’ you’re best to look at Rick Strahl‘s *excellent* article – A Low-Level look at teh ASP.NET Architecture which just got updated late last month (24th)!

{lang: 'en-GB'}
Share