Monday, July 25, 2011

Apache Server intermittently consumes all bandwidth

I noticed that my network would become very slow every few minutes. Sometimes RDP sessions would drop and reconnect. Sometimes messenger applications would drop and reconnect. Using some monitoring tools that come with my firewall appliance, I tracked it down to one server on the network. The server is a Windows 2000 server running an xampp installation of Apache Server 2.2 and Tomcat 6.0.20.

I noticed when I turned off Apache, the problem went away. Since I need Apache running though, this could not be the solution. After some reading, I decided to disable PHP. I commented out a couple of lines in a config file to disable it, but this did not fix it. I watched Windows Task Manager and noticed that php-cgi.exe would pop up when the bandwidth problem would occur. I researched php-cgi.exe and found that there are some issues with it running on Windows. I didn't investigate further to find out all the reasons, or even how to fix it because I don't need PHP running on my server. I renamed the php-cgi.exe file and the problem has gone away.

I suspect I could also have commented out more of the php settings in the config file, but renaming the exe file was sufficient.

Wednesday, July 06, 2011

301 Redirect in Struts

I had the need to do a 301 redirect in my Struts-based web application. I first tried using a redirect="true" attribute in struts-config.xml like this:

<action path="/oldPath" type="com.myapp.controller.MyAction" name="myForm" scope="request" validate="false" parameter="Dispatch">
<forward name="Success" redirect="true" path="/do/newPath">
</forward>

This worked but it turns out it does a 302 redirect (a temporary redirect) as opposed to a permanent redirect, which is a 301. I could not find a way to make this work. What I ended up doing was the following:

[struts-config.xml]
Modified the old action element to use a new MyRedirAction class.

<action path="/oldPath" type="com.myapp.controller.MyRedirAction" name="myForm" scope="request" validate="false" parameter="Dispatch">
</action>


The MyRedirAction class looks like this:

package com.calcxml.controller;

import java.util.HashMap;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.struts.action.ActionForm;
import org.apache.struts.action.ActionForward;
import org.apache.struts.action.ActionMapping;

import com.myStuff.base.ServiceException;

public class MyRedirAction extends MyBaseAction {

protected Map getKeyMethodMap() {
Map<string, string=""> map = new HashMap<string, string="">();
return map;
}

public ActionForward unspecified(ActionMapping mapping, ActionForm form, HttpServletRequest request,
HttpServletResponse response) throws ServiceException {
String qs = request.getQueryString();
response.setStatus(301);
if (qs != null) {
response.setHeader("Location", "newPath" + "?" + qs);
} else {
response.setHeader("Location", "newPath");
}
response.setHeader("Connection", "close" );
return null;
}
}



One gotcha that got me was that I assumed incorrectly that the query string (url parameters) would get passed along automatically in the redirect, but that was not the case. I had to add in the additional code to append the query string to the Location header variable.