Category Archives: System Administration

YUI caching breaks editing

From the AJAX settings screen (/admin/settings.php?section=ajax) you can modify various parameters regarding how Moodle loads the YUI libraries. One of the options is to cache the JavaScript output. This has obvious performance benefits and should normally be enabled. However, during a recent update it appears that caching has broken the ability to edit. Whenever an editing page loads the browser throws the following error:

TypeError: M.core_formchangechecker is undefined

The form actually loads but because of the JavaScript error the rendering of the forum stops before it is complete, leaving the user unable to edit a number of options for the component being edited.

To work around the issue I have disabled caching. This isn’t ideal, but until a solution is found it is the most workable option.

WP redirects confuse IE

Some users were having problems on a community site that was implemented using WordPress+BuddyPress. After some testing the issue involved users visiting the site with Internet Explorer (IE). These users were receiving error pages instead of site content. Other web browsers did not have similar issues.

The cause of the problem turns out to be a confluence of issues:

  • The site is hosted on a Windows+IIS server, a rare platform for WordPress (and even more so for BuddyPress) and one that probably doesn’t receive full attention during quality assurance testing.
  • How WordPress performs redirects on IIS is a bit quirky. BuddyPress issues a lot of redirects so this redirect quirk comes into play quite often. The issue is that when WordPress needs to perform a redirect on IIS it returns a “refresh” header pointing to the new page rather than a “location” header.
  • IE’s attempt to make the Internet more friendly; specifically IE’s use of “friendly error pages.” These friendly error pages replace the content delivered by the server (if that content falls below a certain size in KB).

Normally none of these issue are a problem by themselves and a web browser (including IE) will load the page indicated by the redirect. However, all three of the above issues taken together result in a situation where IE never sees the header refresh and so doesn’t redirect the user to the correct location.

The fix is fairly simple: change the headers that WordPress sends to include the standard “location” header. To do this you modify wordpress/wp-includes/pluggable.php@wp_redirect() so that it reads as follows (line 14 is new):

function wp_redirect($location, $status = 302) {
	global $is_IIS;

	$location = apply_filters('wp_redirect', $location, $status);
	$status = apply_filters('wp_redirect_status', $status, $location);

	if ( !$location ) // allows the wp_redirect filter to cancel a redirect
		return false;

	$location = wp_sanitize_redirect($location);

	if ( $is_IIS ) {
		header("Refresh: 0;url=$location");
		header("Location: $location", true, $status);
	} else {
		if ( php_sapi_name() != 'cgi-fcgi' )
			status_header($status); // This causes problems on IIS and some FastCGI setups
		header("Location: $location", true, $status);
	}
}

What file was that in?

One of the more annoying things about coding is finding the right file. Or, even worse, finding a file you didn’t know you needed to look at. Especially when the number of files you’re parsing is in the thousands. If you’re on Windows the built-in search can help, but you never know if all the files in the target directory have been indexed.

Luckily, one of the nice things about coding is that you’re often dealing with plain text files. And you are typically searching for a particular string. As they say, there’s an app for that. Both *nix and Windows are capable of searching through the contents an entire hierarchy of files using command-line programs. Each OS has a variety of commands that can do the job, but I’ll highlight the two I use most often here.

In Windows you would use findstr.exe, and it’s as simple as running the following from the containing directory:

findstr.exe /MIS "searchtext" filetype

On *nix systems the grep command is your friend:

grep -lr "searchtext" filetype

Of course, a quick google search will get you all the help you need in refining your search.

Update 2012-08-22: What file wasn’t that in?

I recently had a need to find files that did not contain a specific string. A bit more difficult of a prospect. I suspect there’s probably a way to do this on the command line, but so far I’ve only come up with a work-around (in Windows). Use findstr.exe in a loop to show how many times each file contains the string, then filter for files with zero instances:

for /R %f in (filetypes) do find /C /I "searchtext" %f >> ..find.txt

(filetypes in this instance can be a space-separated list of possible file types.)

Executable blocking on Windows 2003

I was recently attempting to install PHP using an installer (MSI) I downloaded to my local workstation and copied to one of our servers. When I attempted to run the installer I received the following inscrutable warning:

Windows cannot access the specific device, path, or file. You may not have the appropriate permissions to access the item.

Thanks, Windows, that’s helpful. I had no idea what was happening, especially since I was logged in as an administrator with full control of the file.

As usual, the web was my friend in solving the problem. Windows 2003 Server has a security feature where executables copied from remote systems are blocked for execution unless allowed by an administrator. The feature appears to have been present for a while (since SP2?), but I don’t recall running into it before. As mentioned above, the file in my case was copied from my workstation over SMB; I don’t know if other transfer methods are also affected. I don’t have a problem with the feature, but I do have a problem with how it’s implemented. An indication in the pop-up of why the file could not be accessed would have resulted in a resolution of seconds not … er … minutes.

The resolution is simple enough, go into the properties for the file and you’ll see at the bottom a security warning and a button that allows you to unblock the file.

Click the “Unblock” button and you can execute the file as you normally would.

References:

suhosin to [internal web app]: you talk too much

Following up on my earlier post, I’ve had to make some further configuration adjustments to avoid suhosin-related restrictions in one of our custom web applications. This particular application has a function that generates a summary of data from student assessments. The summaries can be generated based on groupings of packets and items. Depending on the filtering parameters selected there can be a fairly large number of packets and items. Not all of the packets necessarily contain the items of interest, but it’s always easier to select all if you want an overall summary of item performance.

I recently noticed the following alert in the system log:

ALERT – configured POST variable limit exceeded – dropped variable ‘included_packet_ids[]’ (attacker USER_IP_ADDRESS, file REPORT_FILTERING_PAGE)

One of the reasons I use POST variables on this page is to avoid the relatively small data size limit of GET. Suhosin adds additional limits, including in the number of times you can reference an individual variable.  Our limit was set at 1000, meaning there were over 1000 packets selected. This points to a need to adjust how the filter “selects all” … but for now I’ve adjusted the suhosin limit upward by modifying the suhosin.post.max_vars setting.

References:

suhosin to WordPress: go on a diet

We were seeing a lot of suhosin alerts in the system messages log of the type:

ALERT – script tried to increase memory_limit to 268435456 bytes which is above the allowed value (attacker SERVER_IP_ADDRESS, file WP_MAIN_ADMIN_PAGE, line 96)

The source of the issue is WordPress. The application is trying to raise the memory limit and suhosin won’t let it. Apparently WordPress will try to set a 256MB memory limit before executing certain functions. The necessity of adjusting this setting seems questionable to me, but I also understand that it’s often better to play it safe when developing software for public consumption.

I don’t particularly like applications attempting to specify their own resource usage in a web environment. In my mind applications should specify a required/recommended memory limit in the system requirements and stay away from adjusting this setting behind-the-scenes. Tell me during setup if the current setting may result in non-optimal performance or even a halt in script execution. That’s not how it’s done here, but really no harm is done in the long run beyond the annoyance of suhosin throwing errors at the system logs.

There are two easy fixes to the problem:

  1. Set the PHP memory limit to 256MB
  2. Modify the suhosin.memory_limit parameter to 256MB

In our particular situation it’s just as easy to set the PHP memory limit. There’s always a risk of overloading the physical resources, but this site receives little enough traffic that I’m not concerned about the right confluence of request occurring to cause a crash.

References:

ALERT – script tried to increase memory_limit to 268435456 bytes which is above the allowed value

Rewriting URLs on IIS6

One of the nice things about CakePHP is that it attempts to make a site more friendly to the average web site visitor by creating easier-to-remember URLs. There are a few techniques that CakePHP uses, but for the sake of this conversation we’ll focus on one way in particular: apache’s mod_rewrite functionality. Using mod_rewrite, URLs that would normally include the controller file (index.php) and a querystring can be rewritten as a simple file path.

Microsoft doesn’t include mod_rewrite-style functionality in IIS by default, though it has created an extension for IIS7. Since we are currently using IIS6 the extension isn’t an option for us. Fortunately there are a few other options available, including an open-source project called Ionics Isapi Rewrite Filter (IIRF). IIRF is an ISAPI filter that is very similar to mod_rewrite in terms of functionality. After some testing I’ve found this filter works almost perfectly for enabling CakePHP’s friendly URLs.

Getting Started

Installation is painless and requires only a few steps. The following is based on the IIRF 2.0.1.15 release which does not include an installer:

  1. Extract the files from the IIRF archive to a folder on the server.
  2. Open the properties of the IIS root “Web Sites” folder or the specific site that needs IIRF.
  3. In the “ISAPI Filters” tab create a new entry for IIRF; name the new filter (e.g. “IIRF”); specify the IIRF DLL located with the extracted IIRF files at binIIRF.dll.
  4. Ensure that the IIS user has read/execute access to the IIRF DLL and read/write access to any directories that will be used for logging.
  5. Restart IIRF.

IIRF should now be installed, but I’ve found that sometimes the filter won’t appear to be active in the “ISAPI Filters” tab until it has been used the first time. To enable IIRF all you have to do is create a file called IIRF.ini and place it in the web site root folder or in the root of a virtual directory. This file contains any local configuration directives (such as log directory) and URL rewriting rules.

The obligatory gotcha

I mentioned before that the filter works almost perfectly. The only situation where I’ve had problems up to now is if the URL contains one or more space characters. The IIRF log indicates that a URL with a space is being parsed correctly and returning a valid URL. And yet the web server reports a 404 error.

I’ve only done testing when the final URL references a physical file, but based on a conversation in the support forum I suspect this problem also affects parameters in the querystring. I haven’t yet had a chance to fully investigate the issue, so I don’t have a work-around yet when the issue affects physical files. There does, however, appear to be a work-around for spaces in the querystring.

For now I have decided to ensure that any URLs parsed by IIRF that will point to a physical file/directory does not contain spaces.

References

CakePHP usage:

Space-in-URL problems:

Subversion and Third-Party Code

Often in the course of developing a project it is desirable to use code from a  third party. The main benefit, of course, is being able to add functionality without developing that functionality from scratch. Some third-party projects we have used in the past include FCKEditor (now CKEditor), the Yahoo! User Interface library, and, more recently, the CakePHP framework.

When our code is maintained in a subversion repository there are two options for including third-party code: externals and vendor branches. Continue reading Subversion and Third-Party Code

Apache Log Format Update

A note way past due.

I updated the log format for flora.p2061.org (but not the other sites on flora). Some information is not included in the default “combined” format that could help with debugging (such as user cookies). I set up a new format that is similar to the IIS W3C extended format. Two values not included that could prove useful are bytes received (%I) and bytes sent (%O). The logio_module has to be enabled to record this information. It would probably be worthwhile to add this functionality once we start placing more public content on the server. For now the following format suffices:

#Fields: date    time    c-ip    cs-host    cs-version    cs-method    cs-uri-stem    cs-uri-query    cs(Referer)    cs(User-Agent)    cs(Cookie)    sc-status    time-taken
LogFormat "%{%Y-%m-%d    %H:%M:%S}t    %h    %V    %H    %m    %U    %q    %{Referer}i    %{User-Agent}i    %{Cookie}i    %>s    %D" webapp

Playing nice with CPU usage

I needed to do a mass resampling of around 280,000 images. There are a number of ways to do this, but I settled on doing it via PHP because the images are stored on our web server, the total size of the images is large (~10GB), and I didn’t want to kill my machine trying to get it done.

PHP is ideal for a task such as this: parsing directories and subdirectories for images is easy; resampling using the built-in library (GD) is a breeze; specifying the destination as a subdirectory is simple. The one minus was processor usage. Performing image manipulation eats up the CPU in a big way.

Luckily linux systems have a built-in utility for addressing a situation like this: nice. nice will “run a program with modified scheduling priority.” I’m running the image manipulation script using the following command:

nice --adjustment=19 php script.php

If nothing else is going on the script will use whatever resources are available. When anything with a higher priority executes, that program will take precedence over the script with regard to system resources. The script should thus not affect the responsiveness of the web server. This is the reason I was searching for this kind of functionality.