[Mono-list] Rewriting path with an HttpModule

Daniel Lopez daniel@rawbyte.com
Mon, 17 Mar 2003 05:42:46 -0800


--82I3+IH0IqGh5yIs
Content-Type: text/plain; charset=us-ascii
Content-Disposition: inline


As mentioned earlier, I am developing an ASP.NET HttpModule that maps URLs like

~/username/foo/bar.aspx

to the file on disk

/home/username/public_html/foo/bar.aspx

In a similar way to how Apache mod_userdir does.
That requires implementing RewritePath and changing the PhysicalFilePath
returned, small changes that I already commited.
The problem that I am running into is that some parts of the current codebase
assume that that file path does not change in the life of the request and
that is also rooted on AppPath.
I am looking for the minimal changes to get this to work, I attach a small
pacth that works, but since I am not familiar with that part of the
codebase, can you have a look before I apply? 

I also attach the sample module and a makefile. To test this, you will
need to copu UserDir.dll to where your other dlls are and add the following
to your machine.config in the <httpModules> section 

<add name="UserDir" type="ModMono.Examples.UserDir, UserDir" />


 

--82I3+IH0IqGh5yIs
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment; filename=patch

Index: class/System.Web/System.Web.Compilation/AspGenerator.cs
===================================================================
RCS file: /cvs/public/mcs/class/System.Web/System.Web.Compilation/AspGenerator.cs,v
retrieving revision 1.32
diff -u -r1.32 AspGenerator.cs
--- class/System.Web/System.Web.Compilation/AspGenerator.cs	10 Mar 2003 06:41:26 -0000	1.32
+++ class/System.Web/System.Web.Compilation/AspGenerator.cs	17 Mar 2003 13:11:45 -0000
@@ -1908,8 +1908,13 @@
 
 		if (templatePath == appPath)
 			return "/";
+		if (templatePath.StartsWith(appPath)) {
+			templatePath = templatePath.Substring (appPath.Length);
+		} else {
+			// If it is a rewrite, assume it is application path for now
+			return "/";
+		}
 
-		templatePath = templatePath.Substring (appPath.Length);
 		if (Path.DirectorySeparatorChar != '/')
 			templatePath = templatePath.Replace (Path.DirectorySeparatorChar, '/');
 			
Index: class/System.Web/System.Web.UI/TemplateControlParser.cs
===================================================================
RCS file: /cvs/public/mcs/class/System.Web/System.Web.UI/TemplateControlParser.cs,v
retrieving revision 1.4
diff -u -r1.4 TemplateControlParser.cs
--- class/System.Web/System.Web.UI/TemplateControlParser.cs	18 Dec 2002 02:17:17 -0000	1.4
+++ class/System.Web/System.Web.UI/TemplateControlParser.cs	17 Mar 2003 13:11:45 -0000
@@ -19,7 +19,10 @@
 		internal object GetCompiledInstance (string virtualPath, string inputFile, HttpContext context)
 		{
 			Context = context;
-			InputFile = MapPath (virtualPath);
+			if (inputFile == null) {
+				inputFile = MapPath (virtualPath);
+			}
+			InputFile = inputFile;
 			Type type = CompileIntoType ();
 			if (type == null)
 				return null;

--82I3+IH0IqGh5yIs
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment; filename="makedll.mak"

CSC=mcs
CSCFLAGS+= /debug+ /debug:full /nologo

# 
REFERENCES= System.Web
REFS= $(addsuffix .dll, $(addprefix /r:, $(REFERENCES)))
SOURCES = UserDir.cs

all: UserDir.dll

UserDir.dll: $(SOURCES)
	$(CSC) $(CSCFLAGS) $(REFS) /target:library /out:$@ $^

clean:
	rm -f UserDir.dll *~ *.pdb *.dbg



--82I3+IH0IqGh5yIs
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment; filename="UserDir.cs"

using System;
using System.Web;
using System.IO;

namespace ModMono.Examples
{

public class UserDir : IHttpModule
{
  private HttpApplication httpApp;
  
  public void Init(HttpApplication application)
    {
      httpApp = application;
      httpApp.BeginRequest += new EventHandler(this.UserDirHandler);
    }

  private void UserDirHandler(object sender, EventArgs e)
    {
      String path = httpApp.Request.Path;
      if (path == null) {
	return;
      }
      if (!path.StartsWith("/~") || (path.Length == 2)) {
	return;
      }

      int index = path.IndexOf('/', 2);
      string username, remaining;
      if (index == -1) {
	username = path.Substring(2);
	remaining = "/";
      } else {
	username = path.Substring(2,index - 1);
	remaining = path.Substring(index);
      }
      if (username[0] == '.') {
	return;
      }
      // Todo: More security checks (make sure final path
      // does not go outside /home/username/public_html)
      string translated = Path.Combine("/home/" + username, "public_html" + remaining);
      httpApp.Context.RewritePath(translated);
    }
  
  public void Dispose()
    {
    }
}  
}

--82I3+IH0IqGh5yIs--