Hi, Is it possible to redirect to a specific page no matter what the user asks for? I mean the browser could request the url http://foo.bar.com/luser and I would redirect it to http://foo.bar.com/template?username=luser The problem is that when I request a URL that doesn't exist it reports a 'Not found' error. -- Konstantinos Margaritis Bullet S.A.
There's a product called Redirector - I haven't used it, but it looks like it does that.
From: Konstantinos Margaritis <markos@bullet-adv.gr> Date: Mon, 15 Oct 2001 22:39:41 +0300 To: zope@zope.org Subject: [Zope] Redirect to a specific page
Hi, Is it possible to redirect to a specific page no matter what the user asks for? I mean the browser could request the url
http://foo.bar.com/luser and I would redirect it to http://foo.bar.com/template?username=luser
The problem is that when I request a URL that doesn't exist it reports a 'Not found' error.
-- Konstantinos Margaritis Bullet S.A.
_______________________________________________ Zope maillist - Zope@zope.org http://lists.zope.org/mailman/listinfo/zope ** No cross posts or HTML encoding! ** (Related lists - http://lists.zope.org/mailman/listinfo/zope-announce http://lists.zope.org/mailman/listinfo/zope-dev )
Hi Kontantinos Did you take a look at SiteAccess? It is a standard Zope product and a very powerful tool. But take a backup of your ZODB bevor your start to play around, it's very easy to get locked out of your Zope instance. have fun Gidon Konstantinos Margaritis writes:
Hi, Is it possible to redirect to a specific page no matter what the user asks for? I mean the browser could request the url
http://foo.bar.com/luser and I would redirect it to http://foo.bar.com/template?username=luser
The problem is that when I request a URL that doesn't exist it reports a 'Not found' error.
-- Konstantinos Margaritis Bullet S.A.
_______________________________________________ Zope maillist - Zope@zope.org http://lists.zope.org/mailman/listinfo/zope ** No cross posts or HTML encoding! ** (Related lists - http://lists.zope.org/mailman/listinfo/zope-announce http://lists.zope.org/mailman/listinfo/zope-dev )
Hi Konstantinos! To redirect to a specific page, you do <dtml-call "RESPONSE.redirect(maybe_some_path_in_a_variable+'maybe_some_string_literal')"> in DTML, and in a Python Script context.REQUEST.RESPONSE.redirect(maybe_some_path_in_a_variable+'maybe_some_string_literal') If you want to redirect to a certain page when a user tries to access a non-existing resource, the easiest and most elegant approach IMHO would be to put a redirect into the standard_error_message, there you can check for a 404 and bring the client to whatever you think is a suitable standard page. For example, you could do something like this: <dtml-if "error_type=='NotFound'"> <dtml-call "RESPONSE.redirect(Home.absolute_url())"> </dtml-if> For more information on the standard_error_message and how to customize (most of the) error handling, see John Chandler's HowTo: http://www.zope.org/Members/JohnC/StandardErrorMessage Remember that since you can create standard_error_message objects further down your tree, you can redirect to different pages depending on the location of the last successful traversal step. In you your root folder, you could have "Sorry, the page you requested could not be found" while a standard_error_message in a subfolder "Members" could return "Sorry, this Member page could not be found. Please check the username" (bit silly, couldn't think of anything better right now) And since you always acquire from where you are, you can do a lot more tricks like having only one standard_error_message in the root folder, but taking the error_message - or even the URL to redirect to! - from a folder property: <dtml-call "RESPONSE.redirect(redirect_url_404)"> Whereever you want to redirect to a specific URL, you would now just create a folder property "redirect_url_404" (string) holding the url, and all request to non-existing resources inside that folder (and further down, until you redefine "redirect_url_404") will be redirected to that location. Another trick could be to let standard_error_message be a DTML Document instead of a DTML Method, then it always works in its _own_ namespace, not the caller's namespace. But IMHO this has more drawbacks than advantages. hth, Danny On Tuesday 16 October 2001 08:39, Konstantinos Margaritis wrote:
Hi, Is it possible to redirect to a specific page no matter what the user asks for? I mean the browser could request the url
http://foo.bar.com/luser and I would redirect it to http://foo.bar.com/template?username=luser
The problem is that when I request a URL that doesn't exist it reports a 'Not found' error.
Hi Konstantinos! Maybe I didn't get it right, but if you ALWAYS want to redirect, no matter what, you would simply add an Access Rule holding the redirect (this time its not normal redirecting, you change the Traversal Path before it has actually been processed): create a python script in your root folder holding this one line context.REQUEST.set('TraversalRequestNameStack',['myObject','mySubFolder']) and "Set Access Rule" (from the "Select type to add..." Menu, yes it's not a really appropriate place for it) to the id of this script (e.g. "access_rule") This will always bring you to "YOUR_ZOPE_ROOT/mySubFolder/myObject". Keep in mind that the TraversalRequestNameStack holds the objects to process in reverse order. For more information on Access Rules, see http://www.zope.org/Members/4am/SiteAccess2 If your Zope version is 2.3 or higher, the SiteAccess product is built in, on older versions you will have to install it first. After the installation you will be able to add "SiteRoot" objects and "Set Access Rule". hth, Danny On Tuesday 16 October 2001 08:39, Konstantinos Margaritis wrote:
Hi, Is it possible to redirect to a specific page no matter what the user asks for? I mean the browser could request the url
http://foo.bar.com/luser and I would redirect it to http://foo.bar.com/template?username=luser
The problem is that when I request a URL that doesn't exist it reports a 'Not found' error.
On Monday 15 October 2001 23:42, you wrote:
Hi Konstantinos!
Maybe I didn't get it right, but if you ALWAYS want to redirect, no matter what, you would simply add an Access Rule holding the redirect (this time its not normal redirecting, you change the Traversal Path before it has actually been processed):
YES YES! This is exactly what I wanted!!! After following many of the hints here regarding standard_error_message, and trying in vain for a lot of hours to accomplish here, I started looking at the use of the TraversalRequestNameStack variable. Indeed, this is exactly what I was looking for. Now this thing works! Really thanks. In case anyone is interested I will post a mail about what I was trying to do and how! Again, really thanks, you have saved me a lot of hours of hopeless testing!!! -- Konstantinos Margaritis Bullet S.A.
I would be interested to see what you were trying to do in the form of a howto, in case it helps. ;-) Konstantinos Margaritis wrote:
On Monday 15 October 2001 23:42, you wrote:
Hi Konstantinos!
Maybe I didn't get it right, but if you ALWAYS want to redirect, no matter what, you would simply add an Access Rule holding the redirect (this time its not normal redirecting, you change the Traversal Path before it has actually been processed):
YES YES! This is exactly what I wanted!!! After following many of the hints here regarding standard_error_message, and trying in vain for a lot of hours to accomplish here, I started looking at the use of the TraversalRequestNameStack variable. Indeed, this is exactly what I was looking for. Now this thing works! Really thanks. In case anyone is interested I will post a mail about what I was trying to do and how! Again, really thanks, you have saved me a lot of hours of hopeless testing!!!
-- Chris McDonough Zope Corporation http://www.zope.org http://www.zope.com "Killing hundreds of birds with thousands of stones"
On Tuesday 16 October 2001 04:06, you wrote:
I would be interested to see what you were trying to do in the form of a howto, in case it helps. ;-)
Ok. It's done now, so I thought I could share this info with all you guys. Basically, I wanted to create a member personal webpage system that is based on templates. For example, in my case I have a member database and you want to have a site that holds a personal page for each member in http//memberclub.com/username (fictitious URL) But you don't really want to keep a REAL html page for each member. Instead you want to make them enter their data in a form, insert a picture or two, add some personal links, etc. Then you use another database that holds the data and load these in a template (or more if you want to add variety). So how do I do this? You have to do the following steps. a) check the URL passed do some initial checking on the argument (so that we can check for malicious uses) and split the string into space-separated arguments and keep only the first argument. That is if someone enters the URL: http://memberclub.com/"this is a very big url that is meant to confuse the server" I keep http://memberclub.com/"this b) Check if this word corresponds to a username in the database. Easy. If not show an error screen (User does not exist) c) if b) is true, check if the user has a personal homepage (that is if the webpages database has an entry for this user). Then load the corresponding template with the correct data. Else show a "User does not have a homepage" error screen. Ok. This is what it does. Here is how it works: Have a redirect_index that has the following code: <dtml-unless "REQUEST.path and REQUEST.path[0][:6]=='manage'"> <dtml-let username="cleanupQueryString(REQUEST.PATH_INFO)"> <dtml-call "REQUEST.set('nickname',username)"> <dtml-call "REQUEST.set('TraversalRequestNameStack', ['index_html'])"> </dtml-let> </dtml-unless> (shamelessly stolen and adapted from some howto page in zope site :-) This redirects everything (except the manage screens) to index_html: <HTML> <dtml-if nickname> <dtml-in SelectMemberByUsername size=1 orphan=0> <dtml-call "REQUEST.set('page_owner',nickname)"> <dtml-in SelectWebPageByOwner size=1 orphan=0> <HEAD> <TITLE><dtml-var page_owner>'s Homepage</TITLE> </HEAD> <dtml-if "page_template==0"> <dtml-var template1> <dtml-elif "page_template==1"> <dtml-var template2> <dtml-elif "page_template==2"> <dtml-var template3> </dtml-if> <dtml-else><dtml-var UserNoPagePage> </dtml-in> <dtml-else><dtml-var NoUserPage> </dtml-in> <dtml-else> <dtml-var homepage> </dtml-if> </HTML> And I use the following Python script, and SQL methods: cleanupQueryString: import string queries = string.split(queryString) return queries[0][1:] (I know I have to build something more secure :-) SelectMemberByUsername: select nickname from members where <dtml-sqltest nickname op=eq type=nb> limit 1 SelectWebPageByOwner: select * from WEBPAGES where <dtml-sqltest page_owner op=eq type=nb> and of course the template[1-3], UserNoPagePage, NoUserPage and homepage DMTL methods. Hope this was of interest to at least one person. :-) Again thanks for a wonderful product... By the way, in case anyone is interested, awstats (http://awstats.sourceforge.net) works fine with zope and produces very nice statistics for all zope sites (even with virtual hosting). Although I had to do some extra work for the virtual hosting stuff. I could write a small howto for that if there is interest. Oh, and using awstats' statistic I saw around 20000 attack attempts on zope using Code Red/Nimda and other known exploits for IIS. You can't believe how relieved I am that I am using zope!!! -- Konstantinos Margaritis Bullet S.A.
Hi Konstantinos, Thanks for the heads up about AWStats. I'm checking it out now, to see if its better than analog, which we use. Analog was quite nice because all I needed to do was write a python oneliner that would call analog from my site and then publish the results into my interface. Awstats looks a bit more comprehensive on output, but more difficult to setup. Did you mention that you hooked it straight into Zserver? Perhaps that howto would be a great addition. I am certainly interested. Paul Zwarts -----Original Message----- From: zope-admin@zope.org [mailto:zope-admin@zope.org] On Behalf Of Konstantinos Margaritis Sent: Friday, October 26, 2001 12:57 PM To: zope@zope.org Subject: Re: [Zope] Redirect to a specific page, awstats for zope On Tuesday 16 October 2001 04:06, you wrote:
I would be interested to see what you were trying to do in the form of a howto, in case it helps. ;-)
Ok. It's done now, so I thought I could share this info with all you guys. Basically, I wanted to create a member personal webpage system that is based on templates. For example, in my case I have a member database and you want to have a site that holds a personal page for each member in http//memberclub.com/username (fictitious URL) But you don't really want to keep a REAL html page for each member. Instead you want to make them enter their data in a form, insert a picture or two, add some personal links, etc. Then you use another database that holds the data and load these in a template (or more if you want to add variety). So how do I do this? You have to do the following steps. a) check the URL passed do some initial checking on the argument (so that we can check for malicious uses) and split the string into space-separated arguments and keep only the first argument. That is if someone enters the URL: http://memberclub.com/"this is a very big url that is meant to confuse the server" I keep http://memberclub.com/"this b) Check if this word corresponds to a username in the database. Easy. If not show an error screen (User does not exist) c) if b) is true, check if the user has a personal homepage (that is if the webpages database has an entry for this user). Then load the corresponding template with the correct data. Else show a "User does not have a homepage" error screen. Ok. This is what it does. Here is how it works: Have a redirect_index that has the following code: <dtml-unless "REQUEST.path and REQUEST.path[0][:6]=='manage'"> <dtml-let username="cleanupQueryString(REQUEST.PATH_INFO)"> <dtml-call "REQUEST.set('nickname',username)"> <dtml-call "REQUEST.set('TraversalRequestNameStack', ['index_html'])"> </dtml-let> </dtml-unless> (shamelessly stolen and adapted from some howto page in zope site :-) This redirects everything (except the manage screens) to index_html: <HTML> <dtml-if nickname> <dtml-in SelectMemberByUsername size=1 orphan=0> <dtml-call "REQUEST.set('page_owner',nickname)"> <dtml-in SelectWebPageByOwner size=1 orphan=0> <HEAD> <TITLE><dtml-var page_owner>'s Homepage</TITLE> </HEAD> <dtml-if "page_template==0"> <dtml-var template1> <dtml-elif "page_template==1"> <dtml-var template2> <dtml-elif "page_template==2"> <dtml-var template3> </dtml-if> <dtml-else><dtml-var UserNoPagePage> </dtml-in> <dtml-else><dtml-var NoUserPage> </dtml-in> <dtml-else> <dtml-var homepage> </dtml-if> </HTML> And I use the following Python script, and SQL methods: cleanupQueryString: import string queries = string.split(queryString) return queries[0][1:] (I know I have to build something more secure :-) SelectMemberByUsername: select nickname from members where <dtml-sqltest nickname op=eq type=nb> limit 1 SelectWebPageByOwner: select * from WEBPAGES where <dtml-sqltest page_owner op=eq type=nb> and of course the template[1-3], UserNoPagePage, NoUserPage and homepage DMTL methods. Hope this was of interest to at least one person. :-) Again thanks for a wonderful product... By the way, in case anyone is interested, awstats (http://awstats.sourceforge.net) works fine with zope and produces very nice statistics for all zope sites (even with virtual hosting). Although I had to do some extra work for the virtual hosting stuff. I could write a small howto for that if there is interest. Oh, and using awstats' statistic I saw around 20000 attack attempts on zope using Code Red/Nimda and other known exploits for IIS. You can't believe how relieved I am that I am using zope!!! -- Konstantinos Margaritis Bullet S.A. _______________________________________________ Zope maillist - Zope@zope.org http://lists.zope.org/mailman/listinfo/zope ** No cross posts or HTML encoding! ** (Related lists - http://lists.zope.org/mailman/listinfo/zope-announce http://lists.zope.org/mailman/listinfo/zope-dev )
On Fri, Oct 26, 2001 at 01:57:02PM +0300, Konstantinos Margaritis wrote: Very cool! About that URL checking:
And I use the following Python script, and SQL methods:
cleanupQueryString: import string queries = string.split(queryString) return queries[0][1:]
(I know I have to build something more secure :-)
You could move this to an external method, and write a regexp that matches only valid user names. Another approach would be to scan for invalid characters. Obviously, how easy this is depends on how restrictive you are with usernames. # scan approach bad_chars='!@#$%^&*()+-=`{}[]\|;:\'"\\<>,./' for char in queries[0]: if char in bad_chars: raise SomeKindOfError return queries[0], queries[:1] # regexp approach valid_regexp = re.compile('regexp goes here') if valid_regexp.match(queries[0]): # NOT regexp.search! return possible_username, queries[1:] else: raise SomeKindOfError -- paul winkler home: http://www.slinkp.com music: http://www.reacharms.com calendars: http://www.calendargalaxy.com
Hi Konstantinos, fine, but whats the point in using a relational database when you already have an object database? I think the problem can even simplier solved if you make a ZClass with add-form, some properties for descriptions and so on and images as sub-object. You only need to catch the case where a user-page does not exist. This can be done with a custom error document. Best regards Tino Wildenhain --On Friday, October 26, 2001 13:57:02 +0300 Konstantinos Margaritis <markos@bullet-adv.gr> wrote:
On Tuesday 16 October 2001 04:06, you wrote:
I would be interested to see what you were trying to do in the form of a howto, in case it helps. ;-)
Ok. It's done now, so I thought I could share this info with all you guys. Basically, I wanted to create a member personal webpage system that is based on templates. For example, in my case I have a member database and you want to have a site that holds a personal page for each member in
http//memberclub.com/username (fictitious URL)
But you don't really want to keep a REAL html page for each member. Instead you want to make them enter their data in a form, insert a picture or two, add some personal links, etc. Then you use another database that holds the data and load these in a template (or more if you want to add variety). So how do I do this? You have to do the following steps.
a) check the URL passed do some initial checking on the argument (so that we can check for malicious uses) and split the string into space-separated arguments and keep only the first argument. That is if someone enters the URL: http://memberclub.com/"this is a very big url that is meant to confuse the server"
I keep http://memberclub.com/"this
b) Check if this word corresponds to a username in the database. Easy. If not show an error screen (User does not exist) c) if b) is true, check if the user has a personal homepage (that is if the webpages database has an entry for this user). Then load the corresponding template with the correct data. Else show a "User does not have a homepage" error screen.
Ok. This is what it does. Here is how it works:
Have a redirect_index that has the following code:
<dtml-unless "REQUEST.path and REQUEST.path[0][:6]=='manage'"> <dtml-let username="cleanupQueryString(REQUEST.PATH_INFO)"> <dtml-call "REQUEST.set('nickname',username)"> <dtml-call "REQUEST.set('TraversalRequestNameStack', ['index_html'])"> </dtml-let> </dtml-unless>
(shamelessly stolen and adapted from some howto page in zope site :-)
This redirects everything (except the manage screens) to index_html:
<HTML> <dtml-if nickname> <dtml-in SelectMemberByUsername size=1 orphan=0> <dtml-call "REQUEST.set('page_owner',nickname)"> <dtml-in SelectWebPageByOwner size=1 orphan=0> <HEAD> <TITLE><dtml-var page_owner>'s Homepage</TITLE> </HEAD> <dtml-if "page_template==0"> <dtml-var template1> <dtml-elif "page_template==1"> <dtml-var template2> <dtml-elif "page_template==2"> <dtml-var template3> </dtml-if> <dtml-else><dtml-var UserNoPagePage> </dtml-in> <dtml-else><dtml-var NoUserPage> </dtml-in> <dtml-else> <dtml-var homepage> </dtml-if> </HTML>
And I use the following Python script, and SQL methods:
cleanupQueryString: import string queries = string.split(queryString) return queries[0][1:]
(I know I have to build something more secure :-)
SelectMemberByUsername: select nickname from members where <dtml-sqltest nickname op=eq type=nb> limit 1
SelectWebPageByOwner: select * from WEBPAGES where <dtml-sqltest page_owner op=eq type=nb>
and of course the template[1-3], UserNoPagePage, NoUserPage and homepage DMTL methods.
Hope this was of interest to at least one person. :-)
Again thanks for a wonderful product...
By the way, in case anyone is interested, awstats (http://awstats.sourceforge.net) works fine with zope and produces very nice statistics for all zope sites (even with virtual hosting). Although I had to do some extra work for the virtual hosting stuff. I could write a small howto for that if there is interest. Oh, and using awstats' statistic I saw around 20000 attack attempts on zope using Code Red/Nimda and other known exploits for IIS. You can't believe how relieved I am that I am using zope!!!
-- Konstantinos Margaritis Bullet S.A.
_______________________________________________ Zope maillist - Zope@zope.org http://lists.zope.org/mailman/listinfo/zope ** No cross posts or HTML encoding! ** (Related lists - http://lists.zope.org/mailman/listinfo/zope-announce http://lists.zope.org/mailman/listinfo/zope-dev )
participants (8)
-
Chris McDonough -
Danny William Adair -
gfried@stars.ch -
Konstantinos Margaritis -
marc lindahl -
Paul Winkler -
Paul Zwarts -
Tino Wildenhain