8

I've taken over development of a fairly heavy-duty LAMP application. The original dev used an .htaccess file with RewriteMap and a PHP script to handle certain conditions of the app.

Specifically, when certain subdomain patterns are requested by the client, the RewriteMap catches them and sends them to the appropriate application module.

I'm quite comfortable with typical mod_rewrite redirects, and I think I've got the basic RewriteMap concept figured out; but I'm struggling to find decent documentation on how RewriteLock works. According to the Apache docs:

This directive sets the filename for a synchronization lockfile which mod_rewrite needs to communicate with RewriteMap programs. Set this lockfile to a local path (not on a NFS-mounted device) when you want to use a rewriting map-program. It is not required for other types of rewriting maps.

But this is still a little vague for me. Whats the exact purpose and function of RewriteLock and how does it work?

Brian Lacy
  • 18,785
  • 10
  • 55
  • 73
  • +1 this is one of the most poorly explained aspects of Mod_Rewrite I have yet seen. – puk Apr 14 '12 at 22:36

2 Answers2

3

RewriteLock is used with the prg: keyword. RewriteMap can be used with several keywords, to use text files (txt:), hashfiles (dbm:), randomized text (rnd:) or external mapping scripts ( this one is the prg: keyword ). In this mode the external script is launched when apache start. Then for every incoming request, when mod-rewrite is calling the prg: mapping, apache sends input to that script and reads the output stream to get the value.

RewriteLock must be used in that case to prevent parallel requests (so parallel inputs to that external process) to mix answers on this process standard output. It's a locking mechanism (a file, the given path, which is a classical token, only one user) to enforce serialization of the calls to this external mapping script. IMHO it should be transparently applied by mod-rewrite when using prg: as I never found a prg case where this locking thing is not mandatory.

Edit:

Well in fact you could use an external prg: without the rewriteLock if randomization of the output is not a problem, i.e. for a given entry you can get a response which was given for another entry, like in a script doing some advanced rnd:, your own round-robin service. But if the output must reflect the entry, then you need that semaphore, which of course can slow down the rewritemap process.

So if you're only using the hashmap or textmap you do not need to set the RewriteLock.

Edit:

You may find useful details on this thread, like the fact the lock file exists only for a few milliseconds, when apache calls the prg and waits for an answer.

Edit: On the question one strange fact is:

The original dev used an .htaccess file with RewriteMap

This is strange because RewriteMap cannot work on .htaccess files, .htaccess are configuration entries read dynamically and RewriteMap as stated here in the Context line can only be set in the main configuration or in a VirtualHost configuration. It cannot be in a Location, a Directory or a .htaccess. So chances are this will never work in a .htaccess.

Now @puk asked for an example of RewriteMap usage. Well, searching for "RewriteMap" in Stack overflow will show you several real examples:

Community
  • 1
  • 1
regilero
  • 29,806
  • 6
  • 60
  • 99
  • 1
    It might be useful to readers if you posted an example RewriteLock/RewriteMap statement. I don't feel confident enough with mod_rewrite to do this myself. – puk Apr 14 '12 at 22:26
  • thanks. the third example is useful. However, what I wanted to know specifically is whether one needs one RewriteLock per RewriteMap, whether that RewriteLock has to have the same/similar name as the RewriteMap and whether it has to be declared in a particular way (ie. immediately before/after the RewriteMap). These are the things I can't find on the web. – puk Apr 16 '12 at 18:22
  • @puk: I have no answers to that, except I think only one rewriteLock per Virtualhost is needed/available and that you could set that instruction anywhere in your Virtualhost or global configuration. But I'm not sure of that, a good question to ask on apache development lists. – regilero Apr 17 '12 at 09:53
  • my rewrite map is actually defined in my apache configuration file and not in my VHost file. Thanks all the same. – puk Apr 17 '12 at 10:23
  • 2
    I find it pretty hilarious that Apache allows you to use `prg` without `RewriteLock`, barely documents that this is a bad idea, and thereby defaults to a behaviour in which it *randomly swaps around the URLs that simultaneous requests get directed to* if you try to use `prg` without first reading the documentation with the utmost care. Requiring a voodoo incantation just to prevent people's requests being randomly swapped with each other is insane design; there's no good reason at all I can see for things to be like this. – Mark Amery May 29 '13 at 14:01
0

Apache hangs if you define more than one RewriteLock directives or if you use it in a VHOST config.

The RewriteLock should be specified at server config level and ONLY ONCE. This lock file will be used by all prg type maps. So if you want to use multiple prg maps, I suggest using an internal locking mechanism, for example in PHP there is the flock function, and simply ignore the warning apache writes in the error log.

See here for more info: http://books.google.com/books?id=HUpTYMf8-aEC&lpg=PP1&pg=PA298#v=onepage&q&f=false

D. Marti
  • 365
  • 2
  • 4
  • This sounds incorrect. What if two Apache threads send request to `prg` at once? Which reply will go to which request, even if you used flock() inside of them? This is undermined, thus, wrong suggestion. Not `prg`'s access to some third resource should be locked, but Apache's access to prg. – catpnosis Mar 29 '15 at 18:29