Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations Mike Lewis on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

URI rewriting 1

Status
Not open for further replies.

ESquared

Programmer
Dec 23, 2003
6,129
US
Is there any way in ASP to rewrite URIs without having to use a commercial product like ISAPI Rewrite?

I know that ASP.Net has the Application BeginRequest event, which can be used to rewrite URIs, and I am considering making a hybrid web application that has only enough .Net to give me URI rewriting and then have everything else in classic ASP. (I plan to code it so that the site will operate even if URI rewriting is not working.)

But it would be far superior if I could avoid that hassle. You can make backups of ASP projects or move them to a new server just by copying the files, but ASP.Net requires compilation...
 
For the sake of simplicity, I suggest either:

1. Buying the ISAPI extension (it may be worth the initial investment to avoid all the hassle and work)
2. Write your own ISAPI extension (this depends on whether you have the skillset to do so or not)

But... there are some more esoteric ways to (kinda) achieve this using just ASP:

1. Error Page
Warning: This will create an overhead in the execution process
Essentially, just create an ASP page that will do all the controlling of the page execution (e.g. Server.Transfer/Execute etc). Then set this as the 404 custom error page. You will need to fiddle with the http response status code too - you don't want to send back a 404 for what is actually a valid page.

2. Create Physical Directories
Warning: This gets a bit messy when managing the placeholder files
Simple... create the actual path you want, then create a placeholder "default" document that simple does a server.transfer/execute/whatever to a controller file, that then serves the content. Problem is that all the placeholder files are likely to become out of date at some point, so you'll need a process to replace them with version changes. You also want to put this pseudo-structure inside it's own dir, so not to mess up your main site.. e.g. pages/this/is/the/path/to/your/content/no/5/

3. Pseudo-ReWrite
Warning: This still requires the '?', therefore if you are aiming to remove this querystring indicator for SEO purposes, then this isn't for you
Using a Controller Page as the default page for the website (e.g. index.asp, default.asp, or whatever), simply pass a raw querystring to the base url prefixed with '?' e.g.:
Then access this using [tt]Request.QueryString()[/tt], which will give you the raw querystring.


Please Note that none of these 3 options are perfect for the job - you are better off using an ISAPI extension to handle the request at the appropriate stage of the pipeline.

If you don't mind the '?' char being there, then option 3 would be the most efficient and easiest to maintain. Despite lots of bad press, I am not convinced that the ? character would prevent crawling of your content, even with the normal querystring structure (to some degree), so if you are aiming to do this for ease of use by humans, then this option would be a prime candidate.

In fact - I would recommend doing the whole thing in ASP.NET.. but it sounds like this is not an option for you out of preference.

Hope that helps.


A smile is worth a thousand kind words. So smile, it's easy! :)
 
I am willing to do ASP.Net at some point, but I am in rapid-application-development phase. I can't take the time to deal with steep learning curve (and I've done some of it). Plus, I'm not excited about some of the garbage and overhead I've seen of ASP.Net. Have you closely examined the HTML pages it serves up? Gawd.

One thing at least that I'd like to do is make .asp a sort of "default extension." But you can't add a new blank extension to the list of extensions, it has to have at least one character. I'm thinking of trying a registry hack to add "." as an ASP-handled file, so I can name my active server pages with no extension, and still have them load properly, and I don't have the nasty ".asp" in the URL.

But even better would be the rewriting engine rather than using hacks like this.

I don't want to use directories and default document names because then I get an extra forward slash in the URL before the ?:

or

I'm looking for


and maybe even


or perhaps even

 
The custom error page approach is the simplest to implement and the overhead is extremly slight.

I have it running on several sites with no server ill effects at all.



Chris.

Indifference will be the downfall of mankind, but who cares?
Woo Hoo! the cobblers kids get new shoes.
People Counting Systems

So long, and thanks for all the fish.
 
Esquared,

For the Physical Directories - The default document would be built into the path you want for the URL... e.g.:


The actual default page under this physical path name would do a server.transfer (or whatever method you choose) to the content controller file, and will pass the request path, which is effectively the variables in fixed positions. So you wouldn't need to have ? in the path at all. (still, this is ugly and nasty IMHO)

As for the other two, they would also work, one is more true to the rewriting process (the error doc one) and the other just has an extra '?' in the path - but you seem ok with that.

Chris's endorsement of the error doc option is pretty reasonable - I use it myself quite successfully, though I don't think I would use it for very high volume sites due to the disk IO overhead on every request. I haven't tried or performance tested to any great degree, so test it if you share the concern.

It also seems like you want to just remove the asp extension - is there any particular reason other than 'prettyness' ? (e.g.Security through obscurity or something?). You might want to ask the IIS forum for further help on that one.

So, I think that you have two potentials - the error doc and the ISAPI extension. Written properly the ISAPI extension will be more efficient, but slightly harder to maintain. The error doc option is the cleanest and easiest entry point, if not the most efficient (though it is possible the efficiency wont be a noticeable issue).

Hope that helps

A smile is worth a thousand kind words. So smile, it's easy! :)
 
I may just use the ASP.Net BeginRequest event as it can rewrite URIs handily...

But I'll look into the options provided and I truly appreciate all the input.
 
I have written my custom 404 handler and it is working beautifully. I was careful to set the parameter for the response code (I can't remember the name now and I'm not at my workstation) to 404 when it really is a missing page, since by using a URL it sends a 200 OK.

And by reading the thread I see I have to look at Server.Transfer because Response.Redirect doesn't do what I want! That just replaces the URL with the hidden one. I don't want that to show at all.

If Server.Transfer isn't right, I'd appreciate some input on how to give the content of the new page without the client seeing the URL change.
 

Server.Transfer will do what you want - it transfers the execution process over to the page you specify. You can also use Server.Execute if you want to execute multiple files in one request (kinda like includes, but more dynamic and uses it's own memory space).

You'll need to pass the parameters to the page via another mechanism though - e.g. a session variable (e.g. Session("QUERY_STRING") maybe) as neither of these methods will allow a querystring added to the relative url of the page.. don't ask me why, just another annoying 'feature'. Any QueryString or Post Content sent to the first page (the new URL scheme) should be forwarded on to the end target page though.

So, if you want to completely handover the processing to the page, use transfer - if you want to do something after the page has run in the handler page, then use execute




A smile is worth a thousand kind words. So smile, it's easy! :)
 
I was just coming back to ask how to transfer my parameters! Laugh. How annoying.

So I guess I'll write a function to encapsulate my request.querystring and request.form calls, which checks first to see if a correct session variable exists to get the information from, and if not, hands form or querystring value back. Then if in the future I change the way that I do URI rewriting, or switch to ASP.Net, all my calls for GET or POST data will still work.

Are you sure there's no other way to pass my parameters? Blah.
 

How annoying.
indeed :)
Are you sure there's no other way to pass my parameters?

I can't think of an easier one for Classic ASP - but you could always do it in ASP.NET.... ;-)

Good Luck with it, hope it goes well.



A smile is worth a thousand kind words. So smile, it's easy! :)
 
Yes, ASP.Net. When I'm done with certain critical development phases on this, perhaps I'll see about porting to that.
 
For what it's worth, not being able to spoof a querystring or form elements is a real hassle. Creating an object that functions exactly like those is a nasty task. Just the use of optional parameters as in "Request.Querystring()" requires cross-language scripting to take advantage of Javascript's optional parameters. And then the real object is easier to code in VB, especially because you need a default property of Item. Creating classes/objects in javascript is a nasty nightmare, anyway.

I gave up on URI rewriting for now. My application is simple enough that I am using a default page and server.transfer, which so far are allowing me to completely avoid using any non-directory names at all, although the querystring is still stuck on the end.
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top