You can accomplish this problem by writing an HttpModule and then adding it to IIS on the php app server. Here is the code:
public class AdServerModule : IHttpModule
{
public void OnBeginRequest(object sender, EventArgs e)
{
var context = ((HttpApplication)sender).Context;
var queryString = context.Request.QueryString;
var readonlyProperty = queryString.GetType().GetProperty("IsReadOnly", BindingFlags.Instance | BindingFlags.NonPublic);
readonlyProperty.SetValue(queryString, false, null);
var path = GetVirtualPath(context);
queryString.Add("foo", "bar");
context.RewritePath(path, String.Empty, queryString.ToString());
readonlyProperty.SetValue(queryString, true, null);
}
public void Init(HttpApplication context)
{
context.BeginRequest += new EventHandler(OnBeginRequest);
}
private static string GetVirtualPath(HttpContext context)
{
var path = context.Request.RawUrl;
var queryStringIndex = path.IndexOf("?");
path = path.Substring(0, queryStringIndex >= 0 ? queryStringIndex : path.Length);
path = path.Substring(path.LastIndexOf("/") + 1);
return path;
}
public void Dispose() { }
}
The OnBeginRequest() method fires on the php server before the php app handles the request. As you can see, I'm using reflection to make the QueryString property of the request not read only. You don't necessarily have to do this as long as you pass your intended query string into the RewritePath() call. The RewritePath() call is where request is actually changed. You also aren't just limited to manipulating the URL. The Request object is completely exposed so you can alter the Form, Headers, etc.
Once you've written the HttpModule, you need to deploy it. First you need to register the HttpModule's assembly into the GAC on the machine where you're deploying it (in our case, the php app server) using the following command:
gacutil /i c:\MyHttpModule.dll
Note that if your HttpModule has references that don't exist on the target machine, you'll need to include them in your assembly (ILMerge FTW). You'll also most likely have to sign referenced assemblies that you wrote for the gacutil like so:
Once your assembly is loaded on the target machine, you just need to register that module to IIS. You can do this in the web.config:
<system.webServer>
<modules runAllManagedModulesForAllRequests="true">
<add type="Product.AdServer.TrafficManager.AdServerModule" name="AdServerModule" />
</modules> </system.webServer>
You can also register the module directly in IIS:
That's it!
No comments:
Post a Comment