LoadModule access_module modules/mod_access.so LoadModule auth_module modules/mod_auth.so LoadModule ext_filter_module modules/mod_ext_filter.so LoadModule include_module modules/mod_include.so LoadModule log_config_module modules/mod_log_config.so LoadModule env_module modules/mod_env.so LoadModule expires_module modules/mod_expires.so LoadModule headers_module modules/mod_headers.so LoadModule setenvif_module modules/mod_setenvif.so LoadModule mime_module modules/mod_mime.so LoadModule status_module modules/mod_status.so LoadModule autoindex_module modules/mod_autoindex.so LoadModule asis_module modules/mod_asis.so LoadModule info_module modules/mod_info.so LoadModule cgi_module modules/mod_cgi.so LoadModule vhost_alias_module modules/mod_vhost_alias.so LoadModule negotiation_module modules/mod_negotiation.so LoadModule dir_module modules/mod_dir.so LoadModule actions_module modules/mod_actions.so LoadModule speling_module modules/mod_speling.so LoadModule userdir_module modules/mod_userdir.so LoadModule alias_module modules/mod_alias.so LoadModule rewrite_module modules/mod_rewrite.so LoadModule python_module modules/mod_python.so Listen 8080 ServerAdmin general@gump.apache.org Timeout 300 KeepAlive On MaxKeepAliveRequests 100 KeepAliveTimeout 15 UseCanonicalName Off LogLevel debug PidFile logs/httpd.pid Options FollowSymLinks AllowOverride None DirectoryIndex index.html index.html.var index.py AccessFileName .htaccess Order allow,deny Deny from all TypesConfig conf.dist/mime.types DefaultType text/plain MIMEMagicFile conf.dist/magic HostnameLookups Off #EnableMMAP off #EnableSendfile off ServerTokens Full ServerSignature On IndexOptions VersionSort ReadmeName README.html HeaderName HEADER.html IndexIgnore .??* *~ *# HEADER* README* RCS CVS *,v *,t AddLanguage ca .ca AddLanguage cs .cz .cs AddLanguage da .dk AddLanguage de .de AddLanguage el .el AddLanguage en .en AddLanguage eo .eo AddLanguage es .es AddLanguage et .et AddLanguage fr .fr AddLanguage he .he AddLanguage hr .hr AddLanguage it .it AddLanguage ja .ja AddLanguage ko .ko AddLanguage ltz .ltz AddLanguage nl .nl AddLanguage nn .nn AddLanguage no .no AddLanguage pl .po AddLanguage pt .pt AddLanguage pt-BR .pt-br AddLanguage ru .ru AddLanguage sv .sv AddLanguage zh-CN .zh-cn AddLanguage zh-TW .zh-tw LanguagePriority en ca cs da de el eo es et fr he hr it ja ko ltz nl nn no pl pt pt-BR ru sv zh-CN zh-TW ForceLanguagePriority Prefer Fallback AddDefaultCharset ISO-8859-1 AddCharset ISO-8859-1 .iso8859-1 .latin1 AddCharset ISO-8859-2 .iso8859-2 .latin2 .cen AddCharset ISO-8859-3 .iso8859-3 .latin3 AddCharset ISO-8859-4 .iso8859-4 .latin4 AddCharset ISO-8859-5 .iso8859-5 .latin5 .cyr .iso-ru AddCharset ISO-8859-6 .iso8859-6 .latin6 .arb AddCharset ISO-8859-7 .iso8859-7 .latin7 .grk AddCharset ISO-8859-8 .iso8859-8 .latin8 .heb AddCharset ISO-8859-9 .iso8859-9 .latin9 .trk AddCharset ISO-2022-JP .iso2022-jp .jis AddCharset ISO-2022-KR .iso2022-kr .kis AddCharset ISO-2022-CN .iso2022-cn .cis AddCharset Big5 .Big5 .big5 # For russian, more than one charset is used (depends on client, mostly): AddCharset WINDOWS-1251 .cp-1251 .win-1251 AddCharset CP866 .cp866 AddCharset KOI8-r .koi8-r .koi8-ru AddCharset KOI8-ru .koi8-uk .ua AddCharset ISO-10646-UCS-2 .ucs2 AddCharset ISO-10646-UCS-4 .ucs4 AddCharset UTF-8 .utf8 AddCharset GB2312 .gb2312 .gb AddCharset utf-7 .utf7 AddCharset utf-8 .utf8 AddCharset big5 .big5 .b5 AddCharset EUC-TW .euc-tw AddCharset EUC-JP .euc-jp AddCharset EUC-KR .euc-kr AddCharset shift_jis .sjis BrowserMatch "Mozilla/2" nokeepalive BrowserMatch "MSIE 4\.0b2;" nokeepalive downgrade-1.0 force-response-1.0 BrowserMatch "RealPlayer 4\.0" force-response-1.0 BrowserMatch "Java/1\.0" force-response-1.0 BrowserMatch "JDK/1\.0" force-response-1.0 BrowserMatch "Microsoft Data Access Internet Publishing Provider" redirect-carefully BrowserMatch "^WebDrive" redirect-carefully BrowserMatch "^WebDAVFS/1.[012]" redirect-carefully BrowserMatch "^gnome-vfs" redirect-carefully ### .-------------------------------------------------------------. ### | FURSWA: Fancy URL Rewriting Scheme for Web Applications | ### .-------------------------------------------------------------. # The below combination of mod_rewrite directives allows any web application # that is built around a concept of controller+action pairs to have pretty # URLs on the outside, and easily parseable ones on the inside. All of the # rewrite rules combine to transform URLs that are requested like this: # # /controller/action/param1/value1/paramN/valueN/unparsed.stuff/index.html?otherparm=otherval#fragment # # into URLs like this as seen by your application: # # /myhandler?controller=controller&action=action¶m1=value1¶mN=valueN&path=unparsed.stuff/index.html&otherparm=otherval#fragment # # which can then be processed further by your web application in any way you # choose. # # The reverse process is also applied. This means that URLs that are requested # like this: # # /myhandler?controller=controller&action=action¶m1=value1¶mN=valueN&path=unparsed.stuff/index.html&otherparm=otherval#fragment # # are transformed into URLs like this: # # /controller/action/param1/value1/paramN/valueN/unparsed.stuff/index.html?otherparm=otherval#fragment # # which are sent back to the client with a 304 Moved Permanently redirect, so # that the client sees only the pretty url. This allows your web application to # output the ugly URLs and not worry about prettying those up. # # Note that none of the variables (controller, action, parameters, values) # that are parsed out can have a "/" or a "." in them. Also note that the order # of the controller, action and path parameters actually matters, not just when # transforming from ugly urls to pretty ones, but also when going back the other # way. # # Configuration # ------------- # # Of course, you still need to configure the /myhandler location that will be # used to actually process the requests. Simply replace "/app/handler.py" with # the path to your webapplication in all the rules below. # # In addition, you will need to configure exactly what URLs are considered as # being part of the web application, and which are pointers to (for example) # regular files. You can do that by customizing RULE 02. # # Combining with other rules # -------------------------- # # If you wish to use mod_rewrite rules in addition to the ones our "fancy # rewriting scheme" sets up, add them *after* all the rules below, i.e., # define them as RULE 22 and later. ### ### Section I: Setup ### RewriteEngine "On" # Enable the lines below for debugging #RewriteLog "logs/rewrite_log" #RewriteLogLevel 5 ### ### Section II: Mode handling ### ### Step 01: Determine which mode we're in # Here, we configure a set of rules that puts us in one of three matching # modes: # # 1) prettyfication. We have an ugly query-string based url referencing part # of our web application, which is rewritten to something fancy, then # provided to the user with a 304 Moved Permanently redirect. # 2) redirection. We have a pretty webapp url which internally is rewritten # into a query-string based url for easy processing by the CGI application # 3) other stuff. Neither of the above is the case, so we jump to another bit # that does other kinds of redirection. # RULE 01 RewriteCond "RULE1%{ENV:REWRITE_MODE}" =RULE1 RewriteRule "^/app/handler.py$" - [env=REWRITE_MODE:prettyfy] # RULE 02 RewriteCond "RULE2%{ENV:REWRITE_MODE}" =RULE2 RewriteCond "%{REQUEST_FILENAME}" !-f # Specify what bits are webapplications here RewriteCond "%{REQUEST_URI}" "^/home" [OR] RewriteCond "%{REQUEST_URI}" "^/doc" #RewriteCond "%{REQUEST_URI}" "^/webapp2" [OR] #RewriteCond "%{REQUEST_URI}" "^/webapp3" [OR] RewriteRule "^/([^/\.]+/[^/\.]+)(/.*)?$" - [env=REWRITE_MODE:redirection] # RULE 03 RewriteCond "RULE3%{ENV:REWRITE_MODE}" =RULE3 RewriteRule "." - [env=REWRITE_MODE:other] ### Step 02: Jump to relevant section # Here, we configure a set of rules that skip forward a number of rules to the # section matching our REWRITE_MODE. This means it is important to keep track # of the number of rewrite rules in each section except the last one! # RULE 05 # JUMP from RULE 05 to RULE 14: skip=(14-5-1=8) RewriteCond "RULE5%{ENV:REWRITE_MODE}" =RULE5redirection RewriteRule "." - [skip=8] # RULE 06 # JUMP from RULE 06 to RULE 21: skip=(21-6-1=14) RewriteCond "RULE6%{ENV:REWRITE_MODE}" =RULE6other RewriteRule "." - [skip=14] ### ### Section III: Prettyfication ### # Note that we never need to do qsappend here as we get "the rest" of # the query string all the time. ### Step 01: /app/handler.py -> RULE 07 ### prettyfy:/ # basic paranoia :-D RewriteCond "RULE7%{ENV:REWRITE_MODE}" =RULE7prettyfy RewriteRule "^/app/handler.py$" "prettyfy:/" ### Step 02: /?controller=controller&... -> RULE 08 ### /controller/...?... RewriteCond "RULE8%{QUERY_STRING}" "RULE8controller=([^/\.&]+)&?(.*)" RewriteRule "^prettyfy:/$" "prettyfy:/%1?%2" ### Step 03: /controller?action=action&... -> RULE 09 ### /controller/action/...?... RewriteCond "RULE9%{QUERY_STRING}" "RULE9action=([^/\.&]+)&?(.*)" RewriteRule "^prettyfy:/([^/\.]+)$" "prettyfy:/$1/%1?%2" ### Step 04: /...?path=unparsed.stuff/index.html&... -> RULE 10 ### /...?... && $PRETTYFY_PATH=unparsed.stuff/index.html RewriteCond "RULE10%{QUERY_STRING}" "RULE10path=([^&]+)&?(.*)" RewriteRule "^prettyfy:/(.*)$" "prettyfy:/$1?%2" [env=PRETTYFY_PATH=%1] ### Step 05: /controller/action?param=value&... -> RULE 11 ### /controller/action/param/value/...?... # JUMP from RULE 11 to RULE 01 RewriteCond "RULE11%{QUERY_STRING}" "RULE11([^/\.&]+)=([^/\.&]+)&?(.*)" RewriteRule "^prettyfy:/([^/\.]+)/([^/\.]+)$" "prettyfy:/$1/$2/%1/%2?%3" [next] ### Step 06: /controller/action/param=value/paramN=valueN?... -> RULE 12 ### /controller/action/param=value/paramN=valueN/unparsed.stuff/index.html?... RewriteCond "RULE12%{PRETTYFY_PATH}" !=RULE12 RewriteCond "%{QUERY_STRING}" "(.*)" RewriteRule "^prettyfy:/(.*)$" "prettyfy:/$1/%{ENV:PRETTYFY_PATH}?%1" ### Step 07: get rid of prefix RULE 13 # STOP processing RewriteRule "^prettyfy:/(.*)$" "/$1" [last,redirect=permanent] ### ### Section IV: Redirection ### ### Step 01: /... -> webapp:/... RULE 14 # basic paranoia :-D RewriteCond "RULE14%{ENV:REWRITE_MODE}" =RULE14redirection RewriteRule "^/(.*)$" "webapp:/$1" ### Step 02: /$controller/... -> /..., saving $controller in ENV # this processing is run only once (deal with looping) RULE 15 RewriteCond "RULE15%{ENV:WEBAPP_CONTROLLER}" =RULE15 RewriteRule "^webapp:/([^/\.]+)/(.*)$" "webapp:/$2" [env=WEBAPP_CONTROLLER:$1,chain] # make sure we have a default if no controller is specified # (for example, someone might request /myhandler directly) RULE 16 RewriteCond "RULE16%{ENV:WEBAPP_CONTROLLER}" =RULE16 RewriteRule "." - [env=WEBAPP_CONTROLLER:home] ### Step 03: /$action/... -> /..., saving $action in ENV # this processing is run only once (deal with looping) RULE 17 RewriteCond "RULE17%{ENV:WEBAPP_ACTION}" =RULE17 RewriteRule "^webapp:/([^/\.]+)/?(.*)$" "webapp:/$2" [env=WEBAPP_ACTION:$1,chain] # make sure we have a default if no controller is specified # (for example, someone might request /myhandler directly) RULE 18 RewriteCond "RULE18%{ENV:WEBAPP_ACTION}" =RULE18 RewriteRule "." - [env=WEBAPP_ACTION:view] ### Step 04: /param/value/... -> /...?param=value # JUMP from RULE 19 to RULE 01 RULE 19 RewriteRule "^webapp:/([^/\.]+)/([^/\.]+)/?(.*)$" "webapp:/$3?$1=$2" [next,qsappend] ### Step 05: /unparsed.stuff/index.html -> ### /app/handler.py?path=unparsed.stuff/index.html # save everything we did not process as "path", get rid of the # webapp: prefix, then call on the handler. # STOP processing RULE 20 RewriteRule "^webapp:(.*)$" "/app/handler.py?controller=%{ENV:WEBAPP_CONTROLLER}&action=%{ENV:WEBAPP_ACTION}&path=$1" [last,qsappend] ### ### Section V: Other ### ### Step 01: Basic paranoia :-D RULE 21 RewriteCond "RULE21%{ENV:REWRITE_MODE}" !=RULE21other RewriteRule "." - [L] ### Step 02: Whatever you want after this :-D # This is the place where you should do your own redirect rules, normally you will # want to make these external redirects, otherwise the above logic will not be # applied! RewriteRule "^/$" "/home/view" [redirect,last] RewriteRule "^/index.html?$" "/home/view?path=bla" [redirect,last]