mod_coldfusion stealing from other Apache modules
Posted: 8/1/2001 5:56:47 PM
By: Comfortably Anonymous
Times Read: 2,356
0 Dislikes: 0
Topic: Internet and WWW
The NEW mod_gzip uses the Apache 'type_checker' hook. It had to do this for basically one reason... so things would work with everything including 'ColdFusion'. ColdFusion is doing some whacky shit in a 'type_checker' routine of their own inside mod_coldfusion and so the lowest common denominator for handling mod_php, mod_perl, mod_include, mod_coldfusion, and mod_whatever turned out to be this 'type_checker' hook.

The way Apache works... if any module returns OK from the low level type_checker hook then no other module with a type_checker hook gets 'called'. This is what ColdFusion is
doing. It is 'stealing away' the type_checker chain early on and no other module gets a chance to play once that happens.

So... the only way to get control of the output from ColdFusion backend ( and other modules ) is to 'steal from the stealer'.

Here is where the 'load order' comes into play...

Apache allows the LAST 'LoadModule' binary listed in httpd.conf to become the FIRST module called when it starts calling all the low level 'hooks'. It's a 'last in first called' approach since they are simply 'pushing' module pointers onto a 'stack' internally as they are encountered in the httpd.conf file.

( Aside: This is what 'ClearModuleList' config command is really for and why Apache has warnings in their ./Configure script about 'Don't change load order unless you know what you are doing'. The 'ClearModuleList' and subsequent 'AddModule' commands are a way to re-order the module calling order 'on the fly' even for modules compiled into the core. )

If mod_gzip is not the LAST module 'loaded' in httpd.conf then it can still compress everything coming out of any module that comes BEFORE it... but there is no guarantee that it can 'intercept' the data coming out of any module that is loaded AFTER mod_gzip.

To make things more complicated, however, the above is not always the case. It has to do with whether or not a module is using the 'type_checker' hook. If any module loaded AFTER mod_gzip is not using a 'type_checker' hook then the output from that module will probably still get compressed.

If, however, you load a module like mod_coldfusion ( which has its own 'stealing' type checker' ) AFTER mod_gzip then the output of ColdFusion will probably never pass through mod_gzip.

Confused? You should be. It's a confusing thing, for sure, but it's the way Apache works.

The previous version of mod_gzip did not have the 'steal from the stealer' low level hooks so only those 'mod_xxxxx' modules that were 'playing fair' would allow mod_gzip to 'see' the output and compress it.

There is still a standard 'mod_gzip_handler()' routine as there was before... but it is now receiving its marching orders from the lower level hooks which can 'see' everything that is happening and 'steal from the stealer'.

This is NOT 'hacking around in Apache'. mod_gzip follows the rules for modules perfectly and is doing nothing that is not 'allowed' in the current Apache module design scheme... it's just making some pretty sophisticated use of what is 'allowable' and ends up being
'smarter' than any other module loaded into the Server.

As 'smart' as it is, however, it still is 'playing by the rules' and that means the order in which modules are loaded can directly affect what it is or is not able to do.

It is possible, with Apache, to load modules in any order and then have any one particular module make sure it is the 'top dog' but this, itself, invloves what even I would call 'hacking around' in Apache. To do this ( and I have in previous test versions ) you have to rewrite Apache's internal call tables in much the same way
you would re-arrange interrupt vector tables to re-position a device driver in the interrupt chain. I have decided NOT to do this since that approach become Apache 'version dependent' and you have to do things differently based on what version of Apache it really is.

As it is... mod_gzip accomplishes the 'magic' and is totally version independent. I have tested it all the way back to Apache 1.3.6 and it still works fine. I don't even have a version of Apache older than that but it will probably work all the way back to 1.2.x versions, if anyone is crazy enough to still be using that old a version of Apache.

SUMMARY

In order to be SURE that mod_gzip can compress the output from ANY other module either compiled into the server or dynamically loaded then it should always be the LAST one loaded in your httpd.conf file.

It will STILL WORK if it is not the 'last one' but now it gets 'conditional'.

Here is the list you gave and I have added some comments out to the right to explain what ( might ) happen...

>        mod_php4
>        mod_fastcgi
>        mod_ssl
>        mod_roaming
>        mod_perl
>        mod_gzip    -- All output from modules ABOVE this point can
definitely be compressed
>        mod_ruby   -- If this module has a 'type_checker' hook that
'steals' the chain then it might not work
>        mod_jk       -- Ditto. Output might be able to be compressed, might
not. It depends.

I hope that helps.

Again... there is no way to really understand why the load order is important unless
you know a least a little about how Apache 'calls' modules at run-time. It's complicated.

Later...
Kevin Kiley
Rating: (You must be logged in to vote)