Sunday, April 19, 2009

 

Apache 2.2.x modules with Delphi


If you want to create Apache modules with Delphi, you can start reading DrBob's Delphi 2006 and Apache Web Apps and this articles, they explain step by step how to create Apache modules with Dephi.

Apache 2.2.x

DrBob articles covers up to Apache 2.0.63, but the current version of the http server is 2.2.x, if you try to run them in this version, they won't work.

Don't worry, to make it work with the new version, you have to change and add a couple of lines to the same HTTPD2.pas file as follows:

Before start changing anything, copy the files HTTPD2.pas, ApacheTwoApp.pas and ApacheTwoHTTP.pas from the Delphi /source/win32/internet directory to the directory of your project, in this example c:\projects\apachemodule.

Changes

Find the text in the left column and replace by the one in the right.

Old HTTPD2.pas
New HTTPD2.pas
LibAPR = 'libapr.dll';     {do not localize}
LibAPR = 'libapr-1.dll';     {do not localize}
MODULE_MAGIC_COOKIE = $041503230;  (* "AP20" *)
{$EXTERNALSYM MODULE_MAGIC_COOKIE}
MODULE_MAGIC_NUMBER_MAJOR = 20020903; { Apache 2.0.42 }
{$EXTERNALSYM MODULE_MAGIC_NUMBER_MAJOR}
MODULE_MAGIC_NUMBER_MINOR = 0; (* 0...n *)
MODULE_MAGIC_COOKIE = $041503232; (* "AP22" *)
{$EXTERNALSYM MODULE_MAGIC_COOKIE}
MODULE_MAGIC_NUMBER_MAJOR = 20051115; { Apache 2.2.x }
{$EXTERNALSYM MODULE_MAGIC_NUMBER_MAJOR}
MODULE_MAGIC_NUMBER_MINOR = 0; (* 0...n *)
{$EXTERNALSYM apr_bucket_alloc_t}
{$EXTERNALSYM apr_bucket_alloc_t}
ap_conn_keepalive_e = (AP_CONN_UNKNOWN, AP_CONN_CLOSE, AP_CONN_KEEPALIVE);
(** Are we going to keep the connection alive for another request?
* @see ap_conn_keepalive_e *)
{keepalive: ap_conn_keepalive_e;}
(** Are we going to keep the connection alive for another request?
* @see ap_conn_keepalive_e *)
keepalive: ap_conn_keepalive_e;
(** The bucket allocator to use
for all bucket/brigade creations *)
bucket_alloc: Papr_bucket_alloc_t;
end;
  (** The bucket allocator to use
for all bucket/brigade creations *)
bucket_alloc: Papr_bucket_alloc_t;
// New for Apache 2.2
(** The current state of this connection *)
cs: Pointer;
(** Is there data pending in the input filters? *)
data_in_input_filters: Integer;
end;


Delphi 2009

To create an Apache module with Delphi 2009, go to File->New->Other->Delphi Projects->WebBroker->WebServer Application and Select CGI Stand-Alone executable, then click OK. This will create a new project, then go to the "uses" clause of this project and replace CGIApp by ApacheTwoApp. That's it.

Update: I added an example to this article, please, read it here.
Comments:
Great post - I'll add a link to your blog from the original article on Apache 2.0.x and Delphi.
 
const
MODULE_MAGIC_COOKIE = $41503232; { "AP22" }
MODULE_MAGIC_NUMBER_MAJOR = 20051115; { For 2.2.3 }
MODULE_MAGIC_NUMBER_MINOR = 3; // 0...n

procedure ReInitialize;
begin
// rewrite only version module constant !!!
with apache_module do
begin
version := MODULE_MAGIC_NUMBER_MAJOR;
minor_version := MODULE_MAGIC_NUMBER_MINOR;
magic := MODULE_MAGIC_COOKIE;
end;
end;

exports
apache_module name 'my_module';

begin
Application.Initialize;
// patch for new appach here
ReInitialize;
//.......................
 
Hi Leonardo,
I tried modifiying HTTPD2.pas file just as you explained but I still can not run my apache. I get following error when I run apache from Start->Programs->Apache2.2->Start:
The exception unknown software exception (0x0eedfade) occurred in the application at location 0x7c812afb.

If I run it from Delphi (My Run Settings point to Apache2.2/bin/httpd.exe), I get following error:
Debugger Fault Notification
---------------------------
Project C:\Program Files\Apache Software Foundation\Apache2.2\bin\httpd.exe faulted with message: 'application-defined exception (code 0xc0000008) at 0x7c90e4ff'. Process Stopped. Use Step or Run to continue.

Any idea what could be wrong?

Much Appreciated,
_dino_
 
Leonardo,
I got it working, please ignore my previous post. The reason for the error was the code I added in ApacheTwoApp.pas file that would write my debugging lines into a text file. As soon as I removed these, it was working smooth with your suggested changes.
Thanks,
_dino_
 
Great! Dino, I was trying to find the time to upload a sample project.
 
Great!
but it only works in windows.
it does not work in linux.
Can someone fix it in linux?
thanks and much Appreciated.
 
I'll check this in Linux with FPC, since I don't use Kylix since a long time.
 
Great post, but I cannot make it work. I have Delphi 2006 and Apache 2.2.4. I have followed the steps you said and i get the following error:

The Apache service named reported the following error:
>>> httpd.exe: Syntax error on line 115 of C:/Program Files/Apache Software Foundation/Apache2.2/conf/httpd.conf: Cannot load C:/Program Files/Apache Software Foundation/Apache2.2/modules/mod_Project1.so into server: The specified module could not be found.

I have also tried with MODULE_MAGIC_NUMBER_MINOR = 4; but still no luck. Any ideas please?

Thanks
Dimitris
 
Dimitris, the error says the module cannot be found, are you 100% sure the file mod_Project1.so is in modules directory?.

Remember that Delphi write libraries as .dll and you have to change the extension to .so, also take into account that Apache is Case Sensitive.
 
Leonardo, yes i'm sure the .so file is in the Apaches modules directory.

I have chenged the extension via the {$E so} command. So, it produces a so file at the end. Do you have a working example i could load in and try it?

Thanks
Dimitris
 
I added an example to this article, please, look at it:

http://leonardorame.blogspot.com/2009/07/apache-22x-modules-with-delphi-ii.html
 
Thanks a lot Leonardo, I managed to make it work! fantastic!

What i was doing wrong was that the library name and *.so file had different names and that because i used the wildcard {$LIBPREFIX 'mod_'} to change the output without changing the library name in the dpr file!

Fantastic, thanks again
 
Leonardo, any chance to present some step by step guide on how to perform this for Linux using FPC?
 
Dimitrios, I'm trying to find the time to create the FPC example. I think I'll be posting it this weekend.
 
Thanks a lot Leonardo, that would be really top if you can provide it.
 
Leonardo,

Will this work with Delphi 5?

KK Aw
 
I don't have a Delphi 5 here, but I think it should work.
 
Your blog keeps getting better and better! Your older articles are not as good as newer ones you have a lot more creativity and originality now. Keep it up!
And according to this article, I totally agree with your opinion, but only this time! :)
 
Hi,

I'm trying to commpile a web services demo with apache 2.2.15 and delphi 2009 and changed all the thhpd stuff - anyway I'm getting following exception: "helloworld.so is garbled - expected signature 41503232 but saw 00000000 - perhaps this is not an Apache module DSO, or was compiled for a different Apache version?"
Do you have any idea what's going wrong there?

Thanks
Lubos
 
This comment has been removed by the author.
 
Hi MichaelVK, on which Delphi and Apache version (for example 2.2.3) are you working?.

Probably the problem you are experiencing is related to MODULE_MAGIC_COOKIE, MODULE_MAGIC_NUMBER_MAJOR and
MODULE_MAGIC_NUMBER_MINOR, remember those numbers change on every minor release of apache.
 
I have some good news!

First, these changes worked great for getting an Apache 2.2 module working under Widnows, but like a few others on here I also wanted to get my Apache mod working under Linux. For about a week now I have been trying to figure why this thing would not work. Apache 2.2.14 was loading the module, but it was just ignoring it when it came time to call the handler. I even tried running "strace" on Apache which yielded vague results.

Well, I decided to see if I could get a Free Pascal apache mod working and it would not even load, complaining about not being able to find the API structure. I started digging around the internet seeing if others have had that problem and they had...one person suggested changing a type definition to match that of what was in the HTTPD2.pas file for Delphi. Well, I thought maybe I should try and update the Delphi/Kylix file to match that of FP. So I tried it and it and wadda know?...it worked. So, in order to get an Apache 2.2 module compiled using Kylix you also have to change this type declaration:

{$IFDEF MSWINDOWS}
apr_off_t = Int64;
{$EXTERNALSYM apr_off_t}
{$ENDIF}
{$IFDEF LINUX}
apr_off_t = Integer;
{$EXTERNALSYM apr_off_t}
{$ENDIF}

TO:

apr_off_t = Int64;

No need for the directives since it should be the same for both OSes.
 
Oh and I'm using Delphi 6 and Kylix 3 and did not have to do the "Reinitialize" work-around.
 
This should also stay as well.

{$EXTERNALSYM apr_off_t}
 
Hi Leonardo,
I am referring to your article about making Apache 2.2 work with Delphi.
It is a great article and thank you very much for posting it.
I was wondering what changes are needed to do same with Apache 2.4.x and Delphi (2010)?
Much appreciated.
Dino
 
Awsesome blog article. Exactly what I needed to get my shared DSO module working with Apache 2.2.x.
 
Hi,

our apache module made by Delphi7 is running under Apache 2.2. using the patched httpd2.pas file. Now we would like to make it running with apache 2.4.7. I guess it requires the same kind of changes inside httpd2.pas. Is there anyone who did it successfully or can supply some helpful information? Many thanks in advance.
 
Hello, Thanks. But your patch has not worked for me (2.2.25).
Found working httpd2.pas here
https://github.com/stijnsanders/xxm/blob/master/Delphi/apache/HTTPD2.pas

it works with delphi7 and apache 2.2.25.
 
Post a Comment



<< Home

This page is powered by Blogger. Isn't yours?