-
Notifications
You must be signed in to change notification settings - Fork 378
Historic: Redirects
A redirect is processed as follows:
- The CGI script is looked up in the Redirects table. This gets a start of a URL, and a default '
rest
' and 'remove
' string. - If there are related rows in the Commands table, and the URL has a command= argument, the Command row's URL is appended and the '
rest
' and 'remove
' strings are used from the related Suffixes row instead. - The '
rest
' string is formatted with the GET arguments. If this succeeds, it is appended to the URL. - The '
remove
' string is removed from the end of the URL, if it's present. - The result is returned as a redirect.
Incoming URL: /public/liaisons.cgi
Redirects table content:
- CGI:
public/liaisons.cgi
- URL:
liaisons
- Rest: empty
- Remove: empty
This results in a simple redirect to /liaisons/
. Why bother with this complicated syntax, then?
Incoming URL: /public/liaison_detal.cgi?detail_id=27
Redirects table content:
- CGI:
public/liaison_detail.cgi
- URL:
liaisons
- Rest:
%(detail_id)s
- Remove: empty
This results in a redirect to /liaisons/27/
. A request for /public/liaison_detail.cgi
with no detail_id would redirect to /liaisons/
.
There's an even more complex example, when a given script serves several different purposes. This is embodied by the idindex example:
Redirects table content:
- CGI:
public/idindex.cgi
- URL:
idindex
- Rest:
%(id)s/%(command)s
- Remove:
id_detail
Commands table content:
Command: show_ind_id
|
URL: inddocs
|
Suffix: %(fl)s
|
---|---|---|
Command: show_wg
|
URL: wglist
|
Suffix: %(fl)s
|
Command: show_list
|
URL: showdocs
|
Suffix: %(cat)s/%(sort)s
|
Some sample URLs and their rewritten results:
/public/idindex.cgi |
/idindex/ |
(using redirects row) |
---|---|---|
/public/idindex.cgi?command=id_detail?id=2468 |
/idindex/2468/ |
((using redirects row)) |
/public/idindex.cgi?command=view_related_docs?id=2468 |
/idindex/2468/view_related_docs |
(using redirects row) |
/public/idindex.cgi?command=show_ind_id?fl=f |
/idindex/inddocs/f/ |
(using command row) |
/public/idindex.cgi?command=show_list?sort=date&cat=dead |
/idindex/showdocs/dead/date/ |
(using command row) |
/public/idindex.cgi?command=search&filename=fenner |
/idindex/?filename=fenner |
When the command begins with a caret (!^), its format becomes !^flag_variable
[!^command
]. With this syntax, the flag variable is checked for in the query arguments; if it is present and its value is 1, then the command is checked (if present). If the command is absent, or if it is present and matches, then this command row is selected.
This is used for some very special cases. The main one is rfc_flag in I-D tracker.
The table indexes are structured such that this comparison can occur quickly.
The Redirects application has 3 tables: Redirects, Commands and Suffixes. They are all edited via the redirects table in the admin interface: /admin/redirects/redirect/ .
A redirect has 4 parts:
- CGI: This is the cgi script being replaced, including path (but not leading /), e.g.,
public/idindex.cgi
- URL: The django URL to the tool that replaces it, excluding leading slash (current entries have it, so need to fix this inconsistency), e.g.,
/idindex
- Rest: A sprintf-like format string to format the query arguments.
- Remove: A string to remove from the end of the string if it is present after "rest" has been added, e.g.,
main_menu
It can also have zero or more Commands associated with it. The two simple cases at the top are handled with no related commands, but commands are needed if a given script serves lots of options based on the command= string. When adding a command, the rest and remove arguments are taken from the Suffixes table, which is presented as a pulldown box at the end of the Command row. Click the green "+" to the right of the pulldown to add a suffix if the one you need isn't there.
The data for the redirects table is supplied in the fixture redirects/fixtures/initial_data.xml
. It is in the format outputted by manage.py dumpdata
, except that the xml is pretty-printed to make it easier to store/diff in SVN.
There is a script, bin/redirect-dump
, which will output the contents of the redirect app's tables in the desired format. Run it in the same directory as manage.py
:
bin/redirect-dump > redirects/fixtures/initial_data.xml
In order to avoid conflicts, the best way to edit this data is:
-
svn update
(to make sure that you have the current fixture) -
python manage.py syncdb
(to make sure that the fixture data is installed) - Edit the redirects table in the admin interface
bin/redirect-dump > redirects/fixtures/initial_data.xml
svn commit
If you get conflicts, please don't try to resolve them. Simply svn revert initial_data.xml
and start these steps over. If you do the update, syncdb, edit, dump, commit quickly, that should minimize the likelyhood of conflicts.
This will probably be its own django application, with a database table to track redirects.
table contents:
- cgi script name
- new url, in python string format, which will be rendered % { dict of cgi parameters }
- default command, which will be removed from the new url
- url base of new tool
xample of default command: redirecting /public/pidtracker.cgi to /idtracker/%{dTag}/%{command}/ but remove view_id/ from the url because that's the default action.
-
This is now implemented and partly tested. It was somewhat naive. Different commands will require different new url formats; this may work as 2 tables, one being the cgi script name and the command parameter name, and the other having command values and new urls.
-
Really, there are 3 things here:
- CGI script
- New URL suffix (e.g., %(dTag)s/%(command)s/) and piece to remove
- Set of command values for each URL suffix (e.g., everything that takes a dTag can point to the same URL suffix)
(note: don't know how to handle rfc_flag requiring a different new url - is it enough to have two new urls and a field that says what to use to decide which to use, or does it just get to code at that point?)
Also, anything that's too complex for the database table can be handled by a custom view and an entry in urls.
Another possibility, if the cgi parameters don't need too much mangling, is to do this with Apache's RedirectMatch or mod_rewrite rules.
- Full compatability with certain scripts will requre cgi parameter mangling. While I think mod_rewrite can do this (since I think mod_rewrite is probably turing-complete), it's probably easier to write this fairly simple bit. Remember that we don't have to write any code to get a database administration front end for the table.
Ok. I was thinking a bit of the overhead, but this is much less an issue with fastcgi (or mod_python, for that matter -- I haven't checked if that's an option and whether it buys anything over fastcgi) than if this was to be done by regular cgi scripts.
- mod_python is the preferred method, apparently; I was planning on fastcgi for my server so that I didn't have to load Yet Another Module.