You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@httpd.apache.org by Rian Hunter <ri...@MIT.EDU> on 2005/07/01 08:44:19 UTC

mod_smtpd design.

Hi,

Currently there are two approaches we are looking at for mod_smtpd. We 
can use the existing request_rec structure, and store smtp specific data 
in a structure stucture in the r->request conf vector. With this we can 
reuse some of the existing core hooks that make sense (handler, 
create_request) while also adding some new ones for smtp (envelope, 
called after all necessary commands have been sent). The downside is 
that a lot of the request_rec members are extraneous for smtp.

The other approach is to use a custom smtp_request_rec structure for an 
smtp session. This has the advantage/disadvantage of defining new hooks 
only necessary for smtp, but the disadvantage is that currently in httpd 
2.x filters that alter content data require a valid request_rec. It 
would be possible to pass a bogus request_rec with the filters set to 
ap_add_*_filter*() (or ap_run_insert_filter() so we let reuse core's 
handle the Set(Out|In)putFilter directive), except that seems a little 
hackish to me.

Currently a session specific smtp data structure will have the fields:
(string) (he|eh)lo argument
(string) mail from argument
(string) rctp to argument

a module specific data structure wlil have the fields
(table) supported smtp extensions (could be extended by other modules 
with ap_run_post_config())
(bool) smtp enabled?
(string) server identifier (mod_smtpd by default)

Since filters are something of great importance to mod_smtpd, i'm 
leaning toward keeping request_rec, and storing session specific data in 
r->request_conf, although I am very open to doing away with request_rec 
completely and definining new hooks (which also means adding new handler 
directives, eg. SetSmtpHandler). Anyone have any thoughts and additional 
comments/considerations?

Here is a list of hooks i was thinking that mod_smtpd should call:


ap_hook_auth_checker     /* maybe this one after helo, mail from, rcpt
                             to but before data */
ap_hook_create_request   /* after the request_rec has been created */
ap_hook_fixups           /* right before calling handler */
ap_hook_handler          /* called to handle request or session */
ap_hook_insert_filter    /* right before calling handler */

either ap_hook_auth_checker or a new hook we'll define for smtp 
(tentatively called "envelope"). that's still up in the air. If we go 
with the discarding request_rec design, basically we'll still call these 
logical hooks.

Are there any complications I've overlooked? Any criticism or comments 
are very welcome!!
-rian

Re: mod_smtpd design.

Posted by Jem Berkes <jb...@users.pc9.org>.
> I'd like to see more of you on IRC:-)

OK, I'm regularly logging onto #apache-modules now

> SMTP is two tasks: accept incoming connections (a protocol module -
> c.f. the ftp modules), and make outgoing connections to another
> server.  The latter would be a proxy_smtp module in the mod_proxy
> framework - c.f. proxy_http and proxy_ftp.  These are clearly

That makes more sense than the route I was going

> Have you done any research on available code for handling the protocol?

I will do more along those lines. The only SMTP package I am familiar with 
is Postfix, but I think we encountered a licensing issue in earlier 
discussion. If the protocol handling has to be redone from scratch, I am 
willing to work on that.

> That's basically a similar task to CGI, and a first pass at that
> would be to try running procmail under CGI (with incoming HTTP POST
> or PUT requests will do fine).  I imagine that would be a pretty
> trivial job with perl or python.

Attached is a quick demo that allows mail delivery via CGI (HTTP POST).
cat raw-email-message | curl -s --data-binary @- http://.../cgi-procmail

It works on my Linux and FreeBSD system. It's hard coded to deliver to the 
current user only (web server user) but procmail runs suid root so you 
could deliver to other users too.

> Now look at what you needed to do.  That's a first-pass spec for
> this task.  It should be a fairly straightforward mod to mod_cgi(d).
> I'm not sure whether that's the best approach, but hacking it up
> will surely throw some light on the matter.

I don't quite understand this... are you saying that instead of an 
external CGI program (as attached), the pipe to procmail functionality 
should be a server module?

Re: mod_smtpd design.

Posted by Nick Kew <ni...@webthing.com>.
Jem Berkes wrote:
> Where are we in the mod_smtpd design/task allocation? Since there are 
> several people involved we're really going to have to divide up the tasks 
> and at least decide on how our various modules will communicate. I'd like 
> to start coding, if one of the mentors could push me in the direction they 
> want please :)

I'd like to see more of you on IRC:-)

> 
> As I understand it, we want to produce one module that deals with the SMTP 
> protocol, and a separate module to handle mail delivery (probably via 
> procmail is easiest for now). Does this mean we should also produce 
> separate modules, one for incoming and one for outgoing mail transactions? 
> In other words, several modules:
> 
> - SMTP protocol library

Hmmm, a library might be OTT.  If there's significant common code
it could in principle become something like util_smtp.
If you think it should be a lib, perhaps you could propose at
least the outline of an API for the lib.

SMTP is two tasks: accept incoming connections (a protocol module -
c.f. the ftp modules), and make outgoing connections to another
server.  The latter would be a proxy_smtp module in the mod_proxy
framework - c.f. proxy_http and proxy_ftp.  These are clearly

Have you done any research on available code for handling the protocol?

> - Incoming SMTP mail (hook connection/server)

Indeed, as discussed in recent correspondence on this list.
Wasn't someone going to evaluate options of reusing the
request_rec as-is vs developing a version customised for SMTP?

> - Outgoing SMTP mail (spooling, DNS MX, sendmail-ish)

Yep.

As you say, it'll want spooling.  Incoming mail will also want
spooling, so we've identified that as an important function.
I'm wondering if we could deal with that by introducing a new
spool bucket type, that will be like a file (or mmap) bucket
but with additional code/hooks to enable longer-term queueing,
and recovery after a system restart.

> - Delivery of SMTP message (to local, e.g. pipe to procmail)

That's basically a similar task to CGI, and a first pass at that
would be to try running procmail under CGI (with incoming HTTP POST
or PUT requests will do fine).  I imagine that would be a pretty
trivial job with perl or python.

Now look at what you needed to do.  That's a first-pass spec for
this task.  It should be a fairly straightforward mod to mod_cgi(d).
I'm not sure whether that's the best approach, but hacking it up
will surely throw some light on the matter.

> Or is that getting too fragmented?

Not at all.  The more modular we keep it, the better.  With of course
the proviso that the modules need to be coordinated with underlying
utilities such as spooling and util_smtp - if those are implemented
separately.

That gives us at least three subprojects.  You should probably
identify one of them and then concentrate on it.  If it's not
the SMTP frontend, start by running HTTP requests through it
for dev purposes and move to SMTP when available.  Post here to
stake out your territory (Rian - have you staked out any territory?
Mathieu - have you shared the SMTP hacking you started before we
got the SoC folks?)

And then there's the RBL and spamassassin input filters if you need
some more to do :-)

-- 
Nick Kew

Re: mod_smtpd design.

Posted by Joey Ekstrom <jc...@gmail.com>.
On 7/11/05, Jem Berkes <jb...@users.pc9.org> wrote:
> As I understand it, we want to produce one module that deals with the SMTP
> protocol, and a separate module to handle mail delivery (probably via
> procmail is easiest for now). Does this mean we should also produce
> separate modules, one for incoming and one for outgoing mail transactions?
> In other words, several modules:
> 
> - SMTP protocol library
> - Incoming SMTP mail (hook connection/server)
> - Outgoing SMTP mail (spooling, DNS MX, sendmail-ish)
> - Delivery of SMTP message (to local, e.g. pipe to procmail)

Why would these be different modules?  From my perspective, the module
should handle the entire protocol. You may or may not want to spawn
specified threads to make outbound connections, but local delivery
should probably just be handled on the request thread.

I figured that sending to mail to procmail or spam filters for
delivery would just be a called from a handler, and then fall through
to external delivery, etc.

-Joey

Re: mod_smtpd design.

Posted by Jem Berkes <jb...@users.pc9.org>.
Where are we in the mod_smtpd design/task allocation? Since there are 
several people involved we're really going to have to divide up the tasks 
and at least decide on how our various modules will communicate. I'd like 
to start coding, if one of the mentors could push me in the direction they 
want please :)

As I understand it, we want to produce one module that deals with the SMTP 
protocol, and a separate module to handle mail delivery (probably via 
procmail is easiest for now). Does this mean we should also produce 
separate modules, one for incoming and one for outgoing mail transactions? 
In other words, several modules:

- SMTP protocol library
- Incoming SMTP mail (hook connection/server)
- Outgoing SMTP mail (spooling, DNS MX, sendmail-ish)
- Delivery of SMTP message (to local, e.g. pipe to procmail)

Or is that getting too fragmented?



Re: mod_smtpd design.

Posted by Nick Kew <ni...@webthing.com>.
Jem Berkes wrote:

> Nick, in one of the background docs you sent me

[aside: that's the material to be used for the ApacheCon tutorial,
and work-in-progress on the book]

>	 the 'connection filters' 
> were described as operating outside the scope of HTTP or any request_rec.

Indeed.  An HTTP connection, like an SMTP connection, can carry more
than one request.

> know this is a living, changing work in progress but it seems confusing, at 
> least to me, to shoehorn arbitrary protocols into HTTP-ish "requests".

Yes.  As discussed elsewhere in this thread, Apache is protocol-agnostic
only at a fairly limited level.  The request_rec can surely be re-used
for SMTP, but doing so is ugly.

> I'm having difficulty envisioning how an SMTP communication can be broken 
> up into requests, i.e. something like HTTP requests. For example:
> 
> 01  HELO joe
> 02  MAIL FROM:<sender1>
> 03  RCPT TO:<abc>
> 04  RCPT TO:<xyz>
> 05  DATA
> 06  ...
> 07  MAIL FROM:<sender2>
> 08  RCPT TO:<niq>
> 09  DATA
> 10  ...
> 11  QUIT
> 
> Now how do you split this up into requests? Does 05 represent a single 
> request, or does that DATA generate two different requests

That's a very good question.

I think in practical terms it has to be two requests: the processing
may diverge a lot - e.g. if the recipients have different antispam
policies, .forward files, or if one of them is an alias.  ISTR reading
some more general reasons for one request per recipient in Dan
Bernstein's explanation of why qmail works like that.

The difficulty then is how the DATA can be fed to both requests.
Bear in mind that in SMTP, compared to HTTP, reliability is more
important than performance.  Mailservers spool messages to a queue
before attempting to deliver.

I think the answer to that has to be for the core SMTP filter to
spool messages in three parts: envelope, SMTP headers, and body.
It should also use a lock *file* while spooling, so that it can
reliably detect an incompletely-spooled message after an event
such as power failure.

Of course, the headers will only be read if the envelope is accepted.
And the body should only be spooled when someone starts to read it -
after any headers-based filtering has taken place.

If I were coding this, I'd start with the above as overall scheme,
and dig deep into existing mailservers for further inspiration.

>	 - 03 and 04 (one 
> for each recipient)?


>	 Or is the whole thing, until 11, a single request? 

That's easy.  No chance!

> Perhaps the MAIL FROM's start new requests, i.e. 02 and 07 (two requests).

The envelope is exactly what the protocol module has to deal with.

> 
> It just seems ambiguous and difficult to justify in any way. Mind you I 
> still might be not fully understanding Apache's request paradigm.

No, you've raised a good question, to which mine may not be the only -
or even the best - answer.

-- 
Nick Kew

Re: mod_smtpd design.

Posted by Jem Berkes <jb...@users.pc9.org>.
> > I don't see why it matters if there are redundant members in
> > request_rec. However, for purity, it might be cool to divide
> > request_rec up into common elements and protocol-specific stuff in a
> > union.
> 
> That's not really a problem, though of course it's hacky.  It's the
> logical consequence of declaring HTTPD to be multi-protocol while making
> so much of it revolve around the request_rec.

Nick, in one of the background docs you sent me the 'connection filters' 
were described as operating outside the scope of HTTP or any request_rec. I 
know this is a living, changing work in progress but it seems confusing, at 
least to me, to shoehorn arbitrary protocols into HTTP-ish "requests".

I'm having difficulty envisioning how an SMTP communication can be broken 
up into requests, i.e. something like HTTP requests. For example:

01  HELO joe
02  MAIL FROM:<sender1>
03  RCPT TO:<abc>
04  RCPT TO:<xyz>
05  DATA
06  ...
07  MAIL FROM:<sender2>
08  RCPT TO:<niq>
09  DATA
10  ...
11  QUIT

Now how do you split this up into requests? Does 05 represent a single 
request, or does that DATA generate two different requests - 03 and 04 (one 
for each recipient)? Or is the whole thing, until 11, a single request? 
Perhaps the MAIL FROM's start new requests, i.e. 02 and 07 (two requests).

It just seems ambiguous and difficult to justify in any way. Mind you I 
still might be not fully understanding Apache's request paradigm.



Re: mod_smtpd design.

Posted by Nick Kew <ni...@webthing.com>.
Ben Laurie wrote:

> I don't see why it matters if there are redundant members in
> request_rec. However, for purity, it might be cool to divide
> request_rec up into common elements and protocol-specific stuff in a
> union.

That's not really a problem, though of course it's hacky.  It's the
logical consequence of declaring HTTPD to be multi-protocol while
making so much of it revolve around the request_rec.

> The downside of this approach, though, is that you could easily call a
> module that expected the wrong union to be filled in.

An extra magic number and an API like ap_verify_protocol(AP_PROTO_FOOTP)
could deal with that relatively cleanly.  It can slot in well with
Paul's recent Listen/Protocol stuff.

> Another approach still would require a fairly large change to the core
> and many modules, but it strikes me as a better option...
> 
> struct http_data {
>     .
>     .
>     .
> };
> 
> struct smtp_data {
>     .
>     .
>     .
> };
> 
> struct request_rec {
>     .
>     . /* common stuff */
>     .
>     struct http_data *http;
>     struct smtp_data *smtp;
> }

The downside is back-compatibility: it'll imply a slightly bigger
change to modules.  Nothing difficult, but third-party developers who
don't read this list may not take the trouble, leaving their users
in an incompatible world.  That is a Bad Thing.  Especially when half
the world hasn't forgiven us for incompatible changes in 2.x over 1.x.

It's the filter rec that really wants updating here.  Currently we have
a conn_rec plus a request_rec.  That's ugly: either the conn_rec is
redundant or the request_rec is junk - should be a union.  With
additional protocols we just add more members to the union.

-- 
Nick Kew

Re: mod_smtpd design.

Posted by Nick Kew <ni...@webthing.com>.
On Friday 01 July 2005 16:47, Nick Kew wrote:
> On Friday 01 July 2005 16:34, Rian A Hunter wrote:
> > Quoting Garrett Rooney <ro...@electricjellyfish.net>:
> > > Rian Hunter wrote:
> > > > type misc_smtp_handler(request_rec *r) {
> > > >     smtpd_request_rec *smtp_data;
> > > >
> > > >     if (strncmp("http", r->protocol_name, 4)) {
> > > >         // decline to handle, this module doesn't handle
> > > >         // http requests.
> > > >     }
> > > >     //then get smtpd specific data
> > > >     smtp_data = get_smtpd_request(r);
> > > >
> > > >     // do some handlin'
> > > > }
>
> This is an interesting line to consider for the longer term (if we can
> resolve the back-compatibility issue).  But it's far too big a disruption
> to contemplate for 2.1/2.2 or the SoC timeframe.

I think I just misread what you wrote.  It's not a big disruption at all,
and I take back what I just said.

-- 
Nick Kew

Re: mod_smtpd design.

Posted by Nick Kew <ni...@webthing.com>.
On Friday 01 July 2005 16:34, Rian A Hunter wrote:
> Quoting Garrett Rooney <ro...@electricjellyfish.net>:
> > Rian Hunter wrote:
> > > type misc_smtp_handler(request_rec *r) {
> > >     smtpd_request_rec *smtp_data;
> > >
> > >     if (strncmp("http", r->protocol_name, 4)) {
> > >         // decline to handle, this module doesn't handle
> > >         // http requests.
> > >     }
> > >     //then get smtpd specific data
> > >     smtp_data = get_smtpd_request(r);
> > >
> > >     // do some handlin'
> > > }

This is an interesting line to consider for the longer term (if we can resolve
the back-compatibility issue).  But it's far too big a disruption to 
contemplate for 2.1/2.2 or the SoC timeframe.

>  Maybe we can use the official iana port
> description list to specifiy protocols like 80 means http, 25 means smtp,
> 143 means imap etc.

We already have Paul's Listen/Protocol updates.  So we can even be more
flexible than that:

 Listen 80 http

would map port 80 to HTTP

whereas if we want to be horribly perverse to make a point

 Listen 80 smtp

would map it to SMTP

But I'm happy with your proposal as an enum, too.


-- 
Nick Kew

Re: mod_smtpd design.

Posted by Greg Marr <gr...@alum.wpi.edu>.
At 11:34 AM 7/1/2005, Rian A Hunter wrote:
>Quoting Garrett Rooney <ro...@electricjellyfish.net>:
> > Rian Hunter wrote:
> > > type misc_smtp_handler(request_rec *r) {
> > >     smtpd_request_rec *smtp_data;
> > >
> > >     if (strncmp("http", r->protocol_name, 4)) {
> > >         // decline to handle, this module doesn't handle
> > >         // http requests.
> > >     }
> > >     //then get smtpd specific data
> > >     smtp_data = get_smtpd_request(r);
> > >
> > >     // do some handlin'
> > > }
> > >
> > > The advantage to this approach is a less bulky (but more all
> > > encompassing) request_rec with support for an arbitrary amount 
> of
> > > protocols and protocol specific data.
> >
> > Rather than inserting dozens of strcmps all throught the 
> processing, I'd
> > prefer to store an int identifying the protocol, and just have a 
> simple
> > compare.  No reason to burn CPU on the strcmp if we don't have to.
> >
> > -garrett
> >
>
>The reason I suggested a strcmp is that it gives freedom to module 
>developers to
>set and implement any protocol they like. Doing integer comparisons 
>would
>require us to maintain a list of "official" integer->protocol 
>mappings, but
>there may be other ways to approach it without having that 
>constraint. Maybe we
>can use the official iana port description list to specifiy 
>protocols like 80
>means http, 25 means smtp, 143 means imap etc.

It doesn't need to be a compile-time mapping.  There could be a 
per-process mapping from string to integer.  On load, each module 
calls a function to register the protocols that they're interested 
in.  If the protocol has already been registered, its integer is 
returned.  If not, it is given the next slot in the protocol table, 
and the new integer is returned.


Re: mod_smtpd design.

Posted by Rian A Hunter <ri...@MIT.EDU>.
Quoting Garrett Rooney <ro...@electricjellyfish.net>:
> Rian Hunter wrote:
> > type misc_smtp_handler(request_rec *r) {
> >     smtpd_request_rec *smtp_data;
> > 
> >     if (strncmp("http", r->protocol_name, 4)) {
> >         // decline to handle, this module doesn't handle
> >         // http requests.
> >     }
> >     //then get smtpd specific data
> >     smtp_data = get_smtpd_request(r);
> > 
> >     // do some handlin'
> > }
> > 
> > The advantage to this approach is a less bulky (but more all 
> > encompassing) request_rec with support for an arbitrary amount of 
> > protocols and protocol specific data.
> 
> Rather than inserting dozens of strcmps all throught the processing, I'd 
> prefer to store an int identifying the protocol, and just have a simple 
> compare.  No reason to burn CPU on the strcmp if we don't have to.
> 
> -garrett
> 

The reason I suggested a strcmp is that it gives freedom to module developers to
set and implement any protocol they like. Doing integer comparisons would
require us to maintain a list of "official" integer->protocol mappings, but
there may be other ways to approach it without having that constraint. Maybe we
can use the official iana port description list to specifiy protocols like 80
means http, 25 means smtp, 143 means imap etc.
-rian



Re: mod_smtpd design.

Posted by Garrett Rooney <ro...@electricjellyfish.net>.
Rian Hunter wrote:

> If there was going to be a large change to core, request_rec and friends 
> how about:
> 
> struct request_rec {
>     /* common stuff */
>     char *protocol_name; // different from r->protocol,
>                          // but maybe doesn't have to be
>     struct ap_conf_vector_t *request_config;
> };
> 
> The request_config vector would store all the protocol specific data. 
> Protocol_name would be so modules new what they were dealing with. To 
> retrieve protocol specific data define this in each protocol module:
> 
> smtpd_request_rec *get_smtpd_request(request_rec *r) {
>     return ap_get_module_config(r->request_config, &MODULE_NAME);
> }
> 
> Then in handler modules:
> 
> type misc_smtp_handler(request_rec *r) {
>     smtpd_request_rec *smtp_data;
> 
>     if (strncmp("http", r->protocol_name, 4)) {
>         // decline to handle, this module doesn't handle
>         // http requests.
>     }
>     //then get smtpd specific data
>     smtp_data = get_smtpd_request(r);
> 
>     // do some handlin'
> }
> 
> The advantage to this approach is a less bulky (but more all 
> encompassing) request_rec with support for an arbitrary amount of 
> protocols and protocol specific data.

Rather than inserting dozens of strcmps all throught the processing, I'd 
prefer to store an int identifying the protocol, and just have a simple 
compare.  No reason to burn CPU on the strcmp if we don't have to.

-garrett

Re: mod_smtpd design.

Posted by Rian Hunter <ri...@MIT.EDU>.
Ben Laurie wrote:
> Another approach still would require a fairly large change to the core 
> and many modules, but it strikes me as a better option...
> 
> struct http_data {
>     .
>     .
>     .
> };
> 
> struct smtp_data {
>     .
>     .
>     .
> };
> 
> struct request_rec {
>     .
>     . /* common stuff */
>     .
>     struct http_data *http;
>     struct smtp_data *smtp;
> }
> 

If there was going to be a large change to core, request_rec and friends 
how about:

struct request_rec {
	/* common stuff */
	char *protocol_name; // different from r->protocol,
	                     // but maybe doesn't have to be
	struct ap_conf_vector_t *request_config;
};

The request_config vector would store all the protocol specific data. 
Protocol_name would be so modules new what they were dealing with. To 
retrieve protocol specific data define this in each protocol module:

smtpd_request_rec *get_smtpd_request(request_rec *r) {
	return ap_get_module_config(r->request_config, &MODULE_NAME);
}

Then in handler modules:

type misc_smtp_handler(request_rec *r) {
	smtpd_request_rec *smtp_data;

	if (strncmp("http", r->protocol_name, 4)) {
		// decline to handle, this module doesn't handle
		// http requests.
	}
	//then get smtpd specific data
	smtp_data = get_smtpd_request(r);

	// do some handlin'
}

The advantage to this approach is a less bulky (but more all 
encompassing) request_rec with support for an arbitrary amount of 
protocols and protocol specific data.
-rian

Re: mod_smtpd design.

Posted by Matthieu Estrade <me...@apache.org>.
I agree with you, but when i tried to do this in the module you can find in
www.apache.org/~mestrade/ , i found many dependencies in some *http* files.
request_rec is defined in httpd.h and i think it will not be clean to handle
some smtp data in a file with a name containing http, that's why i am speaking
about code refactoring in an email before.

Maybe it's too late in 2.1 to refactor the code. I think we need to know  what
httpd mentor think about this problem, if we can fork code, release 2.2 and
start a 2.3 with this new protocol architecture etc...

Matthieu

>
> struct http_data {
> 	.
> 	.
> 	.
> };
>
> struct smtp_data {
> 	.
> 	.
> 	.
> };
>
> struct request_rec {
> 	.
> 	. /* common stuff */
> 	.
> 	struct http_data *http;
> 	struct smtp_data *smtp;
> }
>
> with http set to NULL when smtp data is there. This means that 
> modules that thought they were dealing with HTTP data on an SMTP 
> request would die rather than behaving unpredictably. Of course, 
> well-behaved modules would handle this gracefully.
>
> Cheers,
>
> Ben.
>
> -- 
> >>>ApacheCon Europe<<<                   http://www.apachecon.com/
>
> http://www.apache-ssl.org/ben.html       http://www.thebunker.net/
>
> "There is no limit to what a man can do or how far he can go if he
> doesn't mind who gets the credit." - Robert Woodruff
>



----------------------------------------------------------------
This message was sent using IMP, the Internet Messaging Program.


Re: mod_smtpd design.

Posted by Ben Laurie <be...@algroup.co.uk>.
Rian Hunter wrote:
> Hi,
> 
> Currently there are two approaches we are looking at for mod_smtpd. We 
> can use the existing request_rec structure, and store smtp specific data 
> in a structure stucture in the r->request conf vector. With this we can 
> reuse some of the existing core hooks that make sense (handler, 
> create_request) while also adding some new ones for smtp (envelope, 
> called after all necessary commands have been sent). The downside is 
> that a lot of the request_rec members are extraneous for smtp.
> 
> The other approach is to use a custom smtp_request_rec structure for an 
> smtp session. This has the advantage/disadvantage of defining new hooks 
> only necessary for smtp, but the disadvantage is that currently in httpd 
> 2.x filters that alter content data require a valid request_rec. It 
> would be possible to pass a bogus request_rec with the filters set to 
> ap_add_*_filter*() (or ap_run_insert_filter() so we let reuse core's 
> handle the Set(Out|In)putFilter directive), except that seems a little 
> hackish to me.

I don't see why it matters if there are redundant members in 
request_rec. However, for purity, it might be cool to divide request_rec 
up into common elements and protocol-specific stuff in a union.

The downside of this approach, though, is that you could easily call a 
module that expected the wrong union to be filled in. So, it might be 
better to have all protocols members in request_rec, but ensure that the 
irrelevant ones have values that are consistent with their irrelevancy.

Another approach still would require a fairly large change to the core 
and many modules, but it strikes me as a better option...

struct http_data {
	.
	.
	.
};

struct smtp_data {
	.
	.
	.
};

struct request_rec {
	.
	. /* common stuff */
	.
	struct http_data *http;
	struct smtp_data *smtp;
}

with http set to NULL when smtp data is there. This means that modules 
that thought they were dealing with HTTP data on an SMTP request would 
die rather than behaving unpredictably. Of course, well-behaved modules 
would handle this gracefully.

Cheers,

Ben.

-- 
 >>>ApacheCon Europe<<<                   http://www.apachecon.com/

http://www.apache-ssl.org/ben.html       http://www.thebunker.net/

"There is no limit to what a man can do or how far he can go if he
doesn't mind who gets the credit." - Robert Woodruff