Subject: [CODE4LIB] tricky mod_rewrite

From: Eric Lease Morgan <[email-masked]>
Date: Tue, 30 Jun 2009 22:40:39 -0400

Can someone here help me with a tricky Apache mod_rewrite configuration?

I want to write a script accessible via a URL with the following shape:

   http://example.org/script/arg1/

Where script is my (Perl) script and arg1 is some... argument.

How do I configure Apache so script gets executed and passes the  
environment variable PATH_INFO along? I suppose I need to use  
mod_rewrite somehow. No?

-- 
Eric Lease Morgan
Head, Digital Access and Information Architecture Department
Hesburgh Libraries, University of Notre Dame

(574) 631-8604

---

From: Peter Kiraly <[email-masked]>
Date: Wed, 1 Jul 2009 10:58:27 +0200

Hi Eric,

try this:

<IfModule mod_rewrite.c>
  RewriteEngine on
  RewriteBase /script
  RewriteCond %{REQUEST_FILENAME} !-f
  RewriteCond %{REQUEST_FILENAME} !-d
  RewriteCond %{REQUEST_URI} !=/favicon.ico
  RewriteRule ^(.*)$ script.cgi?param1=$1 [L,QSA]
</IfModule>

Péter
http://extensiblecatalog.org

----- Original Message ----- 
From: "Eric Lease Morgan" <[email-masked]>
To: <[email-masked]>
Sent: Wednesday, July 01, 2009 4:40 AM
Subject: [CODE4LIB] tricky mod_rewrite

> environment variable PATH_INFO along? I suppose I need to use  mod_rewrite 
> somehow. No?
>
> -- 
> Eric Lease Morgan

---

From: Joe Hourcle <[email-masked]>
Date: Wed, 1 Jul 2009 08:14:07 -0400

On Tue, 30 Jun 2009, Eric Lease Morgan wrote:

> How do I configure Apache so script gets executed and passes the environment 
> variable PATH_INFO along? I suppose I need to use mod_rewrite somehow. No?

If 'script' is actually in your document root, and not hiding somewhere 
else, you just need to declare that

 	/script

is a CGI (or mod_perl, or fastCGI).

Normally, you'd declare an entire directory, but you can use AddType in 
the httpd.conf to declare that the appropriate file extension should be 
executed, and AddHandler to declare what should be used to run it.  In 
your example, you didn't show an extension, but I think it's a default 
that the extension matching is handled.  (eg, if you have 'file.txt' and 
'file.html', it'll look at the HTTP Accept header to determine which one 
is preferred, and serve the 'best' one.)

Your other option is to use ScriptAliasMatch, where you can tell it that 
it's a script, and that it's actually located somewhere else.

For the SCRIPT_INFO part -- you don't have to do anything, other than make 
sure that whatever you do with mod_rewrite or the like doesn't strip it 
off.

-----
Joe Hourcle

---

From: Godmar Back <[email-masked]>
Date: Wed, 1 Jul 2009 08:50:47 -0400

>  RewriteRule ^(.*)$ script.cgi?param1=$1 [L,QSA]

Here's a challenge question:

is it possible to write this without hardwiring the RewriteBase in it?  So
that it can be used, for instance, in an .htaccess file from within any
/path?

  - Godmar

---

From: Peter Kiraly <[email-masked]>
Date: Wed, 1 Jul 2009 15:13:07 +0200

From: "Godmar Back" <[email-masked]>
> that it can be used, for instance, in an .htaccess file from within any

Yes, you can put it into a .htaccess file, and the URL rewrite will
apply on that directory only.

Péter

---

From: Godmar Back <[email-masked]>
Date: Wed, 1 Jul 2009 09:20:00 -0400

> apply on that directory only.

You misunderstood the question; let me rephrase it:

Can I write a .htaccess file without specifying the path where the script
will be located in RewriteBase?
For instance, consider
http://code.google.com/p/tictoclookup/source/browse/trunk/standalone/.htaccess
Here, anybody who wishes to use this code has to adapt the .htaccess file to
their path and change the "RewriteBase" entry.

Is it possible to write a .htaccess file that works *no matter* where it is
located, entirely based on where it is located relative to the Apache root
or an Apache directory?

 - Godmar

---

From: Andrew Nagy <[email-masked]>
Date: Wed, 1 Jul 2009 09:38:02 -0400

You probably could if you get real tricky with the regex code - but I would
say probably not.  rewrite takes the entire url into consideration - so you
need to denote where to start with the rewrite base.

I use this for vufind:
RewriteRule ^([^/]+)/(.+)$ index.php?module=$1&action=$2 [L,QSA]

Which allows you to map:
vufind.library.edu/Search/Results
to:
vufind.library.edu/index.php?module=Search&action=Results

So with that - you could capture all of the "directories" in the URL and
just remove anything that doesn't look familiar.  But that is very hackish
since it could easily break and make it very difficult for someone to debug.

Andrew

---

From: "Walker, David" <[email-masked]>
Date: Wed, 1 Jul 2009 07:18:24 -0700

> Is it possible to write a .htaccess file that works 
> *no matter* where it is located

I don't believe so.

If the .htaccess file lives in a directory inside of the Apache root directory, then you _don't_ need to specify a RewriteBase.  It's really only necessary when .htacess lives in a virtual directory outside of the Apache root.

--Dave

==================
David Walker
Library Web Services Manager
California State University
http://xerxes.calstate.edu
________________________________________
From: Code for Libraries [[email-masked]] On Behalf Of Godmar Back [[email-masked]]
Sent: Wednesday, July 01, 2009 6:20 AM
To: [email-masked]
Subject: Re: [CODE4LIB] tricky mod_rewrite

 - Godmar

---

From: Godmar Back <[email-masked]>
Date: Wed, 1 Jul 2009 10:23:55 -0400

On Wed, Jul 1, 2009 at 10:18 AM, Walker, David <[email-masked]> wrote:

> If the .htaccess file lives in a directory inside of the Apache root
> directory, then you _don't_ need to specify a RewriteBase.  It's really only
> necessary when .htacess lives in a virtual directory outside of the Apache
> root.
>

I see.

Unfortunately, that's the common deployment case by non-administrators (many
librarians). They can create .htaccess files, but don't always have control
of the main Apache httpd.conf or the root directory.

 - Godmar

---

From: Jonathan Rochkind <[email-masked]>
Date: Wed, 1 Jul 2009 10:34:20 -0400

Apache docs say:

"*Notice:* If your webserver's URLs are *not* directly related to 
physical file paths, you have to use |RewriteBase| in every |.htaccess| 
files where you want to use |RewriteRule| directives."

So probably not.  I don't use .htaccess files that much myself.  But 
I've run into similar annoying issues in apache.conf files too.

Andrew Nagy wrote:
>>>> is it possible to write this without hardwiring the RewriteBase in it?
>>>>         
>>  So
>>

---

From: "Walker, David" <[email-masked]>
Date: Wed, 1 Jul 2009 07:38:44 -0700

> They can create .htaccess files, but don't always 
> have control of the main Apache httpd.conf or the 
> root directory.

Just to be clear, I didn't mean just the root directory itself.  If .htacess lives within a sub-directory of the Apache root, then you _don't_ need RewriteBase.

RewriteBase is only necessary when you're in a virtual directory, which is physically located outside of Apache's DocumentRoot path.

Correct me if I'm wrong.

--Dave

==================
David Walker
Sent: Wednesday, July 01, 2009 7:23 AM

I see.

 - Godmar

---

From: Godmar Back <[email-masked]>
Date: Wed, 1 Jul 2009 11:47:48 -0400

On Wed, Jul 1, 2009 at 10:38 AM, Walker, David <[email-masked]> wrote:

> Just to be clear, I didn't mean just the root directory itself.  If
> .htacess lives within a sub-directory of the Apache root, then you _don't_
> need RewriteBase.
>
> RewriteBase is only necessary when you're in a virtual directory, which is
> physically located outside of Apache's DocumentRoot path.
>
> Correct me if I'm wrong.
>

You are correct!  If I omit the RewriteBase, it still works in this case.

Let's have some more of that sendmail koolaid and up the challenge.

How can I write an .htaccess that's path-independent if I like to exclude
certain files in that directory, such as index.html?  So far, I've been
doing:

RewriteCond %{REQUEST_URI} !^/services/tictoclookup/standalone/index.html

To avoid running my script for index.html.  How would I do that?  (Hint: the
use of SERVER variables on the right-hand side in the CondPattern of a
RewriteCond is not allowed, but some trickery may be possible, according to
http://www.issociate.de/board/post/495372/Server-Variables_in_CondPattern_of_RewriteCond_directive.html)

 - Godmar

---

From: Jonathan Rochkind <[email-masked]>
Date: Wed, 1 Jul 2009 11:58:58 -0400

If you do find the answer, let me know. I've been looking for a while 
too, and unsuccesful.  Thanks for that pointer to that weird workaround 
to variables in the right-hand side, I didn't know about that and it 
could be useful.

mod_rewrite totally drives me to mythical sendmail levels of insanity on 
a regular basis. (I've never actually had to maintain sendmail myself, 
so I can only metaphorize.)

---

From: "Walker, David" <[email-masked]>
Date: Wed, 1 Jul 2009 11:42:38 -0700

> How can I write an .htaccess that's path-independent 
> if I like to exclude certain files in that directory, 
> such as index.html?

This is what the Zend Framework uses.  I think it's pretty clever:

  RewriteRule ^.*$ index.php

It basically says that, if the request is for a real, physical file or directory within your application, then Apache should go ahead and serve it up directly.  If it's not, then go ahead and rewrite the request through your script (index.php).

--Dave

==================
David Walker
Sent: Wednesday, July 01, 2009 8:47 AM

 - Godmar

---

From: Joe Hourcle <[email-masked]>
Date: Wed, 1 Jul 2009 14:48:36 -0400

> http://www.issociate.de/board/post/495372/Server-Variables_in_CondPattern_of_RewriteCond_directive.html)

If you're not dealing with further subdirectories, where the index.html 
file should _not_ be exempted it's easy -- just leave out the path, 
and anchor it to the end of the string:

 	RewriteCond %{REQUEST_URI} !/index.html$

(this wouldn't work if 'index.html' if PATH_INFO or QUERY_STRING is sent, 
but then just don't anchor it, or give it a more complex regex to deal 
with the alternate forms)

-----
Joe Hourcle

---

From: Eric Lease Morgan <[email-masked]>
Date: Wed, 1 Jul 2009 22:25:38 -0400

> Can someone here help me with a tricky Apache mod_rewrite  

Thank you for all the helpful replies, both on and off list. Very  
interesting, and not as straight-forward as I would like.

Call me lazy, but since my script requires a many and varied number of  
parameters, I am initially implementing it using name/value pairs as a  
part of GET query. See:

   http://infomotions.com/sandbox/concordance/

Okay, go ahead, chastise me for being un-RESTful. Habits are hard to  
break.  restful_computing+-

-- 
Eric Lease Morgan

---

From: stuart yeates <[email-masked]>
Date: Thu, 2 Jul 2009 14:55:30 +1200

>    http://infomotions.com/sandbox/concordance/

For that sort of thing I'd be using TEI rather than HTML. TEI is a 
community of humanities computing people gathered for self-support. Our 
major product is a file format.

Find us at http://www.tei-c.org/index.xml

cheers
stuart
-- 
Stuart Yeates
http://www.nzetc.org/       New Zealand Electronic Text Centre
http://researcharchive.vuw.ac.nz/     Institutional Repository

---

From: Roy Tennant <[email-masked]>
Date: Wed, 1 Jul 2009 19:59:31 -0700

I know you mean well, but do you really think that Eric Morgan is not
familiar with TEI? These texts appear to be largely from Project Gutenberg,
which doesn't know TEI from a hole in the ground. All in all, I think Eric
is doing some pretty good work to make these plain vanilla texts usable in
interesting ways without having to put the work into it to bring them up to
the TEI standard. This by no means is anything against the good work of the
TEI consortium, but not everything can be marked up like that and, frankly,
that's OK.
Roy

--