Thursday, December 03, 2009
Apache 2.2 modules - FPC 64bits + Ubuntu 9.10
Yesterday I've received a inquiry from Harel Haruda about my example of Apache 2.2 modules for linux, he was having some trouble trying to let Apache load its modules.
My former example was compiled using FPC 2.2.2 on an i386 PC with Debian Linux, now I'm using Ubuntu 9.10 for x86-64 with FPC 2.2.3.
One very important change es in FPC 2.2.3, variables and functions have to be marked to be exportable, with the keyword "export". In previous versions, all functions and variables where exported automatically. I'd read this in the FPC Wiki.
The new code:
To compile this, I used this (long) command line:
This will create a "libmod_helloworld.so" library.
Then, I had to copy it to /usr/lib64/apache2/modules directory changing its name to mod_helloworld.so:
The next step, as usual, is to let Apache know from where to load the new module:
File /etc/apache2/mods-available/helloworld.load
File /etc/apache2/mods-available/helloworld.conf
Now, I created a symlink to those files, from the directory /etc/apache2/mods-enabled:
The last step is to restart Apache and test the module:
To test the module go to http://localhost/hello
My former example was compiled using FPC 2.2.2 on an i386 PC with Debian Linux, now I'm using Ubuntu 9.10 for x86-64 with FPC 2.2.3.
One very important change es in FPC 2.2.3, variables and functions have to be marked to be exportable, with the keyword "export". In previous versions, all functions and variables where exported automatically. I'd read this in the FPC Wiki.
The new code:
{*******************************************
* Test library of the Apache Pascal Headers
********************************************}
library mod_helloworld;
{$mode objfpc}{$H+}
uses SysUtils, httpd {$ifndef Apache1_3}, apr{$endif};
var
test_module: module; export;
default_module_ptr: Pmodule;
const
MODULE_NAME = 'mod_helloworld.so';
HANDLER = 'helloworld-handler';
exports test_module;
{****************************************************
* Handles apache requests
*****************************************************}
function DefaultHandler(r: Prequest_rec): Integer; cdecl;
var
RequestedHandler: string;
begin
RequestedHandler := r^.handler;
ap_log_error(MODULE_NAME, 54, APLOG_NOERRNO or APLOG_NOTICE,
0, r^.server, 'mod_hello: %s', [PChar('Before content is output')]);
if not SameText(RequestedHandler, 'helloworld-handler') then
begin
Result := DECLINED;
Exit;
end;
ap_set_content_type(r, 'text/html');
{ If the request is for a header only, and not a request for
the whole content, then return OK now. We don't have to do
anything else. }
if (r^.header_only <> 0) then
begin
Result := OK;
Exit;
end;
{ Now we just print the contents of the document using the
ap_rputs and ap_rprintf functions. More information about
the use of these can be found in http_protocol.inc }
ap_rputs('' + LineEnding, r);
ap_rputs('' + LineEnding, r);
ap_rputs('Hello There ' + LineEnding, r);
ap_rputs('' + LineEnding, r);
ap_rputs('' + LineEnding ,r);
ap_rputs('Hello world
' + LineEnding, r);
ap_rputs('This is the first Apache Module working with the new binding from Free Pascal' + LineEnding, r);
ap_rputs('' + LineEnding, r);
{ We can either return OK or DECLINED at this point. If we return
* OK, then no other modules will attempt to process this request }
Result := OK;
end;
{***************************************************
* Registers the hooks
****************************************************}
procedure RegisterHooks(p: Papr_pool_t); cdecl;
begin
ap_hook_handler(@DefaultHandler, nil, nil, APR_HOOK_MIDDLE);
end;
{***************************************************
* Library initialization code
****************************************************}
begin
default_module_ptr := @test_module;
FillChar(default_module_ptr^, SizeOf(default_module_ptr^), 0);
STANDARD20_MODULE_STUFF(test_module);
with test_module do
begin
name := MODULE_NAME;
register_hooks := @RegisterHooks;
end;
end.
To compile this, I used this (long) command line:
fpc -fPIC -B -WR -Xs -XX -Fu/usr/share/fpcsrc/2.2.4/packages/httpd22/src -Fu/usr/share/fpcsrc/2.2.4/packages/httpd22/src/apr -Fu/usr/share/fpcsrc/2.2.4/packages/httpd22/src/aprutil -Fu/usr/share/fpcsrc/2.2.4/src/apriconv mod_helloworld.pas
This will create a "libmod_helloworld.so" library.
Then, I had to copy it to /usr/lib64/apache2/modules directory changing its name to mod_helloworld.so:
cp libmod_helloworld.so /usr/lib64/apache2/modules/mod_helloworld.so
The next step, as usual, is to let Apache know from where to load the new module:
File /etc/apache2/mods-available/helloworld.load
LoadModule test_module /usr/lib64/apache2/modules/mod_helloworld.so
File /etc/apache2/mods-available/helloworld.conf
<Location /hello>
SetHandler helloworld-handler
</Location>
Now, I created a symlink to those files, from the directory /etc/apache2/mods-enabled:
ln -s /etc/apache2/mods-available/helloworld.conf /etc/apache2/mods-enabled/helloworld.conf
ln -s /etc/apache2/mods-available/helloworld.load /etc/apache2/mods-enabled/helloworld.load
The last step is to restart Apache and test the module:
sudo apache2ctl start
To test the module go to http://localhost/hello