You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@httpd.apache.org by Greg Stein <gs...@lyra.org> on 2002/10/01 20:12:46 UTC

Re: PHP POST handling

On Tue, Oct 01, 2002 at 01:34:20PM -0400, Ryan Bloom wrote:
> On Tue, 1 Oct 2002, Greg Stein wrote:
>...
> > The default_handler is broken. If you POST to a resource, it returns the
> > resource. That isn't right.
> > 
> > But the PHP point is a good one. So how do we prevent a POST from returning
> > the resource, yet make it available for PHP?
> > 
> > I think that we have a model problem here. For a POST method, you need
> > something to *handle* the POST. Somebody actually needs to accept the posted
> > content, do something with it, and then *generate* a response. That response
> > might actually have other filter processing to apply to it.
> > 
> > It almost seems like PHP needs to act as a handler for POST requests (to
> > deal with the posted content), and as a filter for GET requests.
> > 
> > Does that seem right?
> 
> No, it doesn't seem right.  The default_handler is designed to deliver a
> file from disk down to the next filter.  In the case of filters, we have
> extended the handler to work for POST and GET requests, because that is
> how filters work.

If we want this design, then all right. But it only works if we have
something to intercept the POST if nobody handles it. If a filter does not
handle the POSTed request body, then we need to return 405 (Method Not
Allowed).

IOW, alter the handler as I suggested, or have another filter to figure out
that the body wasn't processed and to rejigger the response into an error
response. That latter design for turn-into-error seems a bit hacky, tho,
which is why I suggested the handler mechanism.

> The assumption is that if it is a POST request, and the default_handler
> gets the request, then there is a filter that will actually run the
> request.  This works, and has worked since we introduced filters, and
> converted some handlers to filters.

Well... by this logic, we need to fix the default handler to *also* deliver
files for PROPFIND, PROPPATCH, REPORT, etc. It is just as easy to argue that
a PHP script can/should handle those requests, too.

I simply don't think that a filter should read/consume a request body. The
handler is responsible for handling the request, which includes processing
the body.

> The bug is in mod_dav.  It is trying to handle too many requests.  There

Yup. You fixed it, but that also broke the lock-checking. But no biggy --
you didn't know and that is exactly why you asked for a review :-)  I'll get
that extra check behavior put back in.

Ideally, we should have a hook that runs around fixup time which says
"should this request be handled?" That hook would be used for "if" header
processing (If:, If-Matches:, If-Not-Modifed:, etc), and it can be used for
checking WebDAV locks.

Currently, the handlers are doing all this stuff by calling
ap_meets_conditions(). That will check some of the If-* headers, but not
WebDAV's If: header. And if a handler forgets to include the call to
meets_conditions, then it is "broken".

>...
> Because I don't believe there was a bug in the default_handler, it was
> working as designed.

Well, it delivers files for POST, sure, but nothing stopped that from
getting to the client if nobody handled it.

> The default_handler assumes that it will be run
> last, and that other modules will have an opportunity to serve the request
> if they are supposed to.

Right.

> I am not trying to show that I have all the answers, but in this case, I
> did the research, and I found the bug.  And, I do have a VERY strong
> opinion about how it should be solved.  Filters introduced some
> intricacies that weren't in the server before.  If we leave the change in
> that was made to the default_handler, nothing will be fixed.  If we add a
> new handler that handles POST requests for PHP, what does that get us?  It
> wouldn't have stopped the bug that we are discussing.  At best, it would
> have changed the response the server gave to the user.  However, that is
> only if the request was for a CGI script.  In the case of PHP, php
> requests were working before my fix, because the default_handler was doing
> it's job.  
> 
> With the fix to the default_handler that is in place now and without the
> mod_dav fix, both CGI and PHP are broken.  Without the default_handler fix
> and without the mod_dav fix, Just CGI are broken.  With just the mod_dav
> fix, and without the default_handler fix, CGI and PHP work.  With both
> fixes, CGI work and PHP are broken.
> 
> You want to fix PHP scripts now by adding a new handler for PHP.  Would
> that be specific to PHP?  If so, then there are two ways to run PHP
> scripts.  No thanks.  If not, then I fail to see what is being fixed.

I think we're refining our handling. These intermediates are broken in one
way or another, but we're getting there.

About a month ago, before we started messing with mod_dav's decision making
for handling, we had some problem or another (I forget what). Then Justin
and I started monkeying with it in mod_dav, and we lost the "dav-handler"
thing, and that threw off mod_dir because it jumped in when it shouldn't
have. Then we put the dav-handler back in to prevent mod_dir from doing the
work thing, but then that broke POSTing to a CGI in a DAV-enabled area. You
fixed that, but broken lock checking during a POST. I thought that covered
up a bug in default_handler, so I fixed that, but still need to go back and
fix the lock-checking. The change to default_handler broke PHP.

Whew :-)

Really... I think that anything which reads the request body ought to be a
handler. It is the one and only thing handling the request. You can't have
multiple people reading that body.

Consider it this way: the handler represents the resource. It handles any
method applied to that resource.

For PHP, we said "make it a filter [so the source can come from anywhere]".
I think we really should have said "for GET requests, allow it to be
processed by PHP." The POST, PROPFIND, COPY, etc should all be possible to
handle by PHP, which means that PHP also needs a handler.

Heck, PHP should also be able to handle a GET request. For example, it
should be able to retrieve the content from a database, and then shove that
into the filter stack.

IOW, PHP is really a handler *and* a filter. It can handle the generation of
content, but it can also process generated content when that content is a
PHP script.

Cheers,
-g

-- 
Greg Stein, http://www.lyra.org/

Re: PHP POST handling

Posted by Justin Erenkrantz <je...@apache.org>.
--On Tuesday, October 1, 2002 11:54 AM -0700 Ian Holsman <ia...@apache.org> 
wrote:

>
> how many sites are you going to break with this core.c change?
>  From what I have heard the RFC says that the server can do what it
> chooses on a POST to a file. we (apache 1.3 & apache 2.042 and below)
> chose to serve a file.

Nah, 1.3 returns 405 (Method Not Allowed) on a POST on a page served by the 
default_handler.

See src/main/http_core.c:3860.  -- justin

Re: PHP POST handling

Posted by Ian Holsman <ia...@apache.org>.
how many sites are you going to break with this core.c change?
 From what I have heard the RFC says that the server can do what it 
chooses on a POST to a file. we (apache 1.3 & apache 2.042 and below) 
chose to serve a file.



Greg Stein wrote:
> On Tue, Oct 01, 2002 at 01:34:20PM -0400, Ryan Bloom wrote:
> 
>>On Tue, 1 Oct 2002, Greg Stein wrote:
>>...
>>
>>>The default_handler is broken. If you POST to a resource, it returns the
>>>resource. That isn't right.
>>>
>>>But the PHP point is a good one. So how do we prevent a POST from returning
>>>the resource, yet make it available for PHP?
>>>
>>>I think that we have a model problem here. For a POST method, you need
>>>something to *handle* the POST. Somebody actually needs to accept the posted
>>>content, do something with it, and then *generate* a response. That response
>>>might actually have other filter processing to apply to it.
>>>
>>>It almost seems like PHP needs to act as a handler for POST requests (to
>>>deal with the posted content), and as a filter for GET requests.
>>>
>>>Does that seem right?
>>
>>No, it doesn't seem right.  The default_handler is designed to deliver a
>>file from disk down to the next filter.  In the case of filters, we have
>>extended the handler to work for POST and GET requests, because that is
>>how filters work.
> 
> 
> If we want this design, then all right. But it only works if we have
> something to intercept the POST if nobody handles it. If a filter does not
> handle the POSTed request body, then we need to return 405 (Method Not
> Allowed).
> 
> IOW, alter the handler as I suggested, or have another filter to figure out
> that the body wasn't processed and to rejigger the response into an error
> response. That latter design for turn-into-error seems a bit hacky, tho,
> which is why I suggested the handler mechanism.
> 
> 
>>The assumption is that if it is a POST request, and the default_handler
>>gets the request, then there is a filter that will actually run the
>>request.  This works, and has worked since we introduced filters, and
>>converted some handlers to filters.
> 
> 
> Well... by this logic, we need to fix the default handler to *also* deliver
> files for PROPFIND, PROPPATCH, REPORT, etc. It is just as easy to argue that
> a PHP script can/should handle those requests, too.
> 
> I simply don't think that a filter should read/consume a request body. The
> handler is responsible for handling the request, which includes processing
> the body.
> 
> 
>>The bug is in mod_dav.  It is trying to handle too many requests.  There
> 
> 
> Yup. You fixed it, but that also broke the lock-checking. But no biggy --
> you didn't know and that is exactly why you asked for a review :-)  I'll get
> that extra check behavior put back in.
> 
> Ideally, we should have a hook that runs around fixup time which says
> "should this request be handled?" That hook would be used for "if" header
> processing (If:, If-Matches:, If-Not-Modifed:, etc), and it can be used for
> checking WebDAV locks.
> 
> Currently, the handlers are doing all this stuff by calling
> ap_meets_conditions(). That will check some of the If-* headers, but not
> WebDAV's If: header. And if a handler forgets to include the call to
> meets_conditions, then it is "broken".
> 
> 
>>...
>>Because I don't believe there was a bug in the default_handler, it was
>>working as designed.
> 
> 
> Well, it delivers files for POST, sure, but nothing stopped that from
> getting to the client if nobody handled it.
> 
> 
>>The default_handler assumes that it will be run
>>last, and that other modules will have an opportunity to serve the request
>>if they are supposed to.
> 
> 
> Right.
> 
> 
>>I am not trying to show that I have all the answers, but in this case, I
>>did the research, and I found the bug.  And, I do have a VERY strong
>>opinion about how it should be solved.  Filters introduced some
>>intricacies that weren't in the server before.  If we leave the change in
>>that was made to the default_handler, nothing will be fixed.  If we add a
>>new handler that handles POST requests for PHP, what does that get us?  It
>>wouldn't have stopped the bug that we are discussing.  At best, it would
>>have changed the response the server gave to the user.  However, that is
>>only if the request was for a CGI script.  In the case of PHP, php
>>requests were working before my fix, because the default_handler was doing
>>it's job.  
>>
>>With the fix to the default_handler that is in place now and without the
>>mod_dav fix, both CGI and PHP are broken.  Without the default_handler fix
>>and without the mod_dav fix, Just CGI are broken.  With just the mod_dav
>>fix, and without the default_handler fix, CGI and PHP work.  With both
>>fixes, CGI work and PHP are broken.
>>
>>You want to fix PHP scripts now by adding a new handler for PHP.  Would
>>that be specific to PHP?  If so, then there are two ways to run PHP
>>scripts.  No thanks.  If not, then I fail to see what is being fixed.
> 
> 
> I think we're refining our handling. These intermediates are broken in one
> way or another, but we're getting there.
> 
> About a month ago, before we started messing with mod_dav's decision making
> for handling, we had some problem or another (I forget what). Then Justin
> and I started monkeying with it in mod_dav, and we lost the "dav-handler"
> thing, and that threw off mod_dir because it jumped in when it shouldn't
> have. Then we put the dav-handler back in to prevent mod_dir from doing the
> work thing, but then that broke POSTing to a CGI in a DAV-enabled area. You
> fixed that, but broken lock checking during a POST. I thought that covered
> up a bug in default_handler, so I fixed that, but still need to go back and
> fix the lock-checking. The change to default_handler broke PHP.
> 
> Whew :-)
> 
> Really... I think that anything which reads the request body ought to be a
> handler. It is the one and only thing handling the request. You can't have
> multiple people reading that body.
> 
> Consider it this way: the handler represents the resource. It handles any
> method applied to that resource.
> 
> For PHP, we said "make it a filter [so the source can come from anywhere]".
> I think we really should have said "for GET requests, allow it to be
> processed by PHP." The POST, PROPFIND, COPY, etc should all be possible to
> handle by PHP, which means that PHP also needs a handler.
> 
> Heck, PHP should also be able to handle a GET request. For example, it
> should be able to retrieve the content from a database, and then shove that
> into the filter stack.
> 
> IOW, PHP is really a handler *and* a filter. It can handle the generation of
> content, but it can also process generated content when that content is a
> PHP script.
> 
> Cheers,
> -g
> 



Re: PHP POST handling

Posted by Justin Erenkrantz <je...@apache.org>.
--On Tuesday, October 1, 2002 3:26 PM -0700 Greg Stein <gs...@lyra.org> 
wrote:

> So you're saying that if I do "file upload" to a PHP script, and upload a
> 10 megabyte file, then it is going to spool that whole mother into memory?

Yup.

> Oh oh... even better. Let's just say that the PHP script isn't even
> *thinking* about handling a request body. Maybe it is only set up for a
> GET request. Or maybe it *is* set up for POST, but only for FORM
> contents. But Mr Attacker comes along and throws 1 gigabyte into the
> request. What then? DoS? Swap hell on the server?

The PHP input filter will always read the body and allocate the space - 
irrespective of what the real script desires.

In fact, looking at the code, I believe PHP will only free the memory if 
the script reads the body (do all scripts read the entire body?).  So, a 
GET with a body (perfectly valid) may introduce memory leakage.  PHP uses 
malloc/realloc/free because it wants the body in one contiguous chunk - 
therefore, our pools don't help.

> I think a filter *can* read the request body (i.e. the content generator
> loads a PHP script, PHP runs it (as the first filter), reads the body, and
> loads content from a database). But that implies that the request body
> should not have been thrown out in the default handler.

Correct.  At one point, I submitted a patch to the PHP lists to do exactly 
that, but once we rearranged how we discard bodies, this method couldn't 
work.

The problem we had was when to 'discard' the body - we originally had it 
discarding at the end, but in order to properly handle 413s, we have to 
discard the body before generating the response.  That's fairly new 
behavior on our part, but one I think that brings us in line with the 
desires of the RFC.

Otherwise, we could have a 200 and then find out that it really should have 
been a 413 (because the body is too large).  Therefore, we have to process 
the body before generating any content.  And, since we now allow chunked 
encoding almost everywhere, we do have to read the entire body to know if 
it exceeds our limit.  1.3 chickened out on this and forbade 
chunked-encoding on request bodies.

> But it almost seems cleaner to say there is a series of stages which
> perform the request handling: process the body and generate the (initial)
> content. These stages could load a script from somewhere, run it,
> (repeat) and generate the content into the filter stack.
>
> Right now, we are confusing a *script* with *content*.

I think the problem is that we aren't doing a good job of getting the 
script the content it (may) need.  While it could be interesting to try to 
separate reading and writing in Apache, certainly the PHP language doesn't 
support that (as I believe you can write and then read the body).  So, I'm 
not sure that we can split it out into multiple phases in an effective 
manner.  Reading and writing in PHP (or any CGI script) is just too 
intertwined to support this.

I think we're sorta stuck, but I might be wrong.  -- justin

Re: PHP POST handling

Posted by Greg Stein <gs...@lyra.org>.
On Tue, Oct 01, 2002 at 11:51:12AM -0700, Justin Erenkrantz wrote:
> --On Tuesday, October 1, 2002 11:12 AM -0700 Greg Stein <gs...@lyra.org> 
> wrote:
> 
> > I simply don't think that a filter should read/consume a request body. The
> > handler is responsible for handling the request, which includes processing
> > the body.
> 
> Wellllll, PHP doesn't exactly do that.
> 
> PHP's current strategy is to create an input filter that setsaside all 
> input.  This is triggered by the ap_discard_request_body() call in 
> default_handler (as discard causes all data to be read).  So, when data is 
> actually pushed down into the output filter chain, PHP has a copy of the 
> body in its private structure.  And, if its script requires the body, it 
> returns the ctx->post_data value in its callbacks.

Ohmigod. I *really* didn't need to hear that.

So you're saying that if I do "file upload" to a PHP script, and upload a 10
megabyte file, then it is going to spool that whole mother into memory?

Oh oh... even better. Let's just say that the PHP script isn't even
*thinking* about handling a request body. Maybe it is only set up for a GET
request. Or maybe it *is* set up for POST, but only for FORM contents. But
Mr Attacker comes along and throws 1 gigabyte into the request. What then?
DoS? Swap hell on the server?

> I think the biggest concern is when multiple modules want the input body. 
> Right now, it's fairly vague what will happen (and I'm not even sure what 
> the right answer is here).  Forcing input filters and doing setasides (flat 
> void* instead of bb's in PHP) seems a bit clunky.  However, we also don't 
> want to store the request body in memory.  -- justin

Agreed on all parts.

I think a filter *can* read the request body (i.e. the content generator
loads a PHP script, PHP runs it (as the first filter), reads the body, and
loads content from a database). But that implies that the request body
should not have been thrown out in the default handler.

But it almost seems cleaner to say there is a series of stages which perform
the request handling: process the body and generate the (initial) content.
These stages could load a script from somewhere, run it, (repeat) and
generate the content into the filter stack.

Right now, we are confusing a *script* with *content*.

Cheers,
-g

-- 
Greg Stein, http://www.lyra.org/

Re: PHP POST handling

Posted by Justin Erenkrantz <je...@apache.org>.
--On Tuesday, October 1, 2002 11:12 AM -0700 Greg Stein <gs...@lyra.org> 
wrote:

> I simply don't think that a filter should read/consume a request body. The
> handler is responsible for handling the request, which includes processing
> the body.

Wellllll, PHP doesn't exactly do that.

PHP's current strategy is to create an input filter that setsaside all 
input.  This is triggered by the ap_discard_request_body() call in 
default_handler (as discard causes all data to be read).  So, when data is 
actually pushed down into the output filter chain, PHP has a copy of the 
body in its private structure.  And, if its script requires the body, it 
returns the ctx->post_data value in its callbacks.

I think the biggest concern is when multiple modules want the input body. 
Right now, it's fairly vague what will happen (and I'm not even sure what 
the right answer is here).  Forcing input filters and doing setasides (flat 
void* instead of bb's in PHP) seems a bit clunky.  However, we also don't 
want to store the request body in memory.  -- justin

Re: PHP POST handling

Posted by "William A. Rowe, Jr." <wr...@rowe-clan.net>.
At 10:22 PM 10/2/2002, Roy T. Fielding wrote:
>Output filters cannot handle methods -- only input filters can do that.
>It sounds to me like you guys are just arguing past each other -- the
>architecture is broken, not the individual modules.  Just fix it.
>
>Greg is right -- the default handler is incapable of supporting any
>method other than GET, HEAD, and OPTIONS, and must error if it sees
>anything else.  OTOH, mod_dav should not be monkeying with the content
>hook if it isn't the content handler.  If you don't fix both problems
>then the security issue will resurface at a later time.

Agreed; and yea - we are probably talking around each other.

Because content filters -can- accept post bodies and modify the
output of a disk resource (spooled by the default 'handler') ... we
must have a way to -permit- the core filter to handle non-GET,
HEAD and OPTIONS results.

But that shouldn't be the default, and Greg and I agree at this
point.  The only question is what mechanism is used by a
content filter to permit non-GET/HEAD/OPTIONS requests,
such that a default OPTIONS request and the core handler
accepts the FOO method that the content filter is prepared
to deal with.

In any case, this should be an mmn bump to assure that
module authors have considered this change in POST behavior,
and really isn't appropriate for the 2.0.43 release.  It will be fixed
(well, has already been fixed) immediately following that release.

I'm using content filter, in this case, to describe a filter which is 
both an input body filter and an output body filter.

Bill


Re: PHP POST handling

Posted by "Roy T. Fielding" <fi...@apache.org>.
Output filters cannot handle methods -- only input filters can do that.
It sounds to me like you guys are just arguing past each other -- the
architecture is broken, not the individual modules.  Just fix it.

Greg is right -- the default handler is incapable of supporting any
method other than GET, HEAD, and OPTIONS, and must error if it sees
anything else.  OTOH, mod_dav should not be monkeying with the content
hook if it isn't the content handler.  If you don't fix both problems
then the security issue will resurface at a later time.

....Roy


Re: PHP POST handling

Posted by "William A. Rowe, Jr." <wr...@rowe-clan.net>.
At 06:23 PM 10/2/2002, Greg Stein wrote:
>On Tue, Oct 01, 2002 at 07:10:32PM -0500, William A. Rowe, Jr. wrote:
>> At 05:19 PM 10/1/2002, Greg Stein wrote:
>>...
>> >As long as it is understood that only *one* thing can consume the request
>> >body. Then the question arises: how do you arbitrate that? It would be nice
>> >to simply say "the handler is the consume" but that doesn't solve the case
>> >of a PHP script stored in an SVN repository. It is almost like we need some
>> >concept of stages leading up to request [body] processing and content
>> >generation.
>> 
>> Wrong.
>
>Boy... not very subtle, are you? :-)

That's not something I'm accused of very often... no :-)

>> Multiple things can access the properties from the request.
>> Consider some form variables.  One filter might be transforming on
>> variable X, while another performs some transformation on variable Z.
>> And they use the same storage for all small bits of the POST.
>
>Well... if by "properties" you mean the headers: sure. But only one person
>understands the POST body, and only one should be reading it.

No, there are several well defined content-types for POST bodies, all
of which define variables, or properties.  application/x-www-form-urlencoded,
multipart/form-data or application/xml are all reasonably well defined.

Others would clearly be considered 'not available' in unpacked form.
While the filters could all serialize and review the contents, the majority
of applications would probably not be interested in the contents, and
the others must be prepared to decipher the obscure client body.

>> In the case of upload requests, one consumer must 'sign up' to stream
>> the file, and provide a method for retrieving the contents if anyone else
>> cares {for the duration of the request.}  In theory, that consumer is the
>> script that wants to persist the POSTed file upload.  If nobody wants
>> to capture a huge POST body, we may end up with a tmpfile method,
>> but if the file will be persisted, there is no reason to stow it twice.
>
>This seems to assume that Apache [core] is processing POST bodies in some
>way, and then providing APIs for other modules/scripts to access the
>processed data.

No, we are suggesting that apreq be built into httpd.  At the same time,
the Apache apreq filter would ONLY process the client's body if an apreq
consumer of this specific request injects the apreq filter (through some
simple API) into the request process prior to the handler processing
the request.  Multiple calls to inject the apreq filter would resolve to a
single instance of the apreq filter and decomposition.

>I'd be very leery of automatic POST body processing in any form. Providing
>standard functions? Sure. And that is what libapreq is about, right? :-)

Automatic?  Only by request.  If a tree falls and noone is listening, any
sound it made is wasted.  Same with apreq ... I sure don't want to waste
memory or cpu breaking apart POST bodies with no consumers :-)

>> >But they are two modes of operation. In one, you generate the original
>> >content (e.g. a PROPFIND or GET response against a database), in the 
>> >other you're filtering content.
>> 
>> In both cases you are transforming a PHP script into the resulting
>> output from processing the script.  No difference, truly.
>
>At a technical level, no, not really. But the problem is that the filter
>stack is about filtering the *content*. If the *script* is travelling
>through the filter chain, then you've got issues :-)

I don't really see any issues.  Please elaborate :-)

>The workaround to that is to always ensure that the script processor is the
>first filter on the chain. But that seems kind of hacky... you could end up
>with some contention there, with filters trying to jocky their way into
>"first". What if a filter got itself in front of PHP? Uh oh. (yes, it would
>be fine if the filter knows it is processing a script, but if it *doesn't...)

Why 'first'?  Perhaps I have a mixture of javascript and php in a composite
document.  Perhaps I want one, then the other to process the data.  In any
case, I (the admin) should be able to order these filters.  Right now we are
really not there in terms of ordering, but we all agree that's got to be fixed.

>As an example of fighting for first: the OLD_WRITE filter. How do we
>arbitrate that "first" spot between PHP (or some other script processor) and
>OLD_WRITE?
>
>That is why I suggested there might be a need for some kind of staged
>process where we manage non-content data.

If we want to have a specific domain for 'parser/scripts' in the stack, just
like we have request and connection oriented filters today, that would be
fine by me.  See my comments on ordering above.

>>...
>> >> And that said, you can't break POST to the default handler, please
>> >> revert that change.
>> >
>> >The POST behavior before my fix was a regression against 1.3. Its existence
>> >was to support the PHP-processing-as-a-filter implementation. The impact of
>> >adding the POST "feature" to the default handler was never really detected
>> >until we uncovered it via a bug in mod_dav. Since this regression was found,
>> >I went in and fixed it. Unfortunately, that breaks PHP :-) But I think the
>> >PHP integration is broken and needs to be fixed.
>> >
>> >While new PHP integration is being solved, we can *temporarily* revert the
>> >change so that PHP users aren't inconvenienced while the integration is
>> >worked on. But the default_handler fix does need to go in to prevent the
>> >regression.
>> >
>> >(I term it a regression because 1.3 didn't do it, and POSTing to something
>> > which isn't going to handle the posted content is not right; we should be
>> > generating an error that states the POST is not allowed for that resource;
>> > that is what 405 is all about)
>> 
>> We should continue this discussion after the change is reverted,
>> and let's find a better answer.
>
>The default handler shouldn't be serving up the file for a POST. The
>original change that did that was wrong.

The RFC leaves it undefined.  Your religion or mine?  (Or rbb's?)

Here's where I agree.  If no module injects that ->accept aught to include
POST, then POST should be declined by the default handler.  But if any
module raises it's hand and says, YES, I want to accept POST requests
on these 'files', then the default handler should concur.  So PHP could
inject the POST method into accepted methods, and the default handler
should respect that.

And the same philosophy should apply to any method that a module wants
to apply against the default handler.  The default handler is simply a simple
endpoint for any filtering designs that originate from a file.

>> Going back to the apreq input filter, I can see where it would share
>> with the core if anyone registered to review the client body.  If someone
>> does, the handler could be toggled to accept POST.  If nobody registers,
>> then we could decline POST.
>
>I like this.

So do I :-)

>However, it really shouldn't be tied to POST, but should work for any
>method. And it would seem to be a new request_rec field. However, to avoid
>an MMN bump, I might suggest that we put the flag into the core config
>record (core_request_config structure) and an API to set the flag.

Same page here :-)  I'm suggesting the r->accept field might work fine.

>So the next question then becomes: what to call the API function? Maybe
>ap_method_requires_script()? It basically says "normally, this method does
>not return the resource as content, but I require it because I'll interpret
>it as a script to process this method." Script processors which are
>installed as filters would call it. We would also recommend that the
>processors have some way to configure which methods the script is actually
>intended to handle, and call the function based on whether the script will
>truly handle it (and if not, then the default behavior will return the
>normal 405 (Method Not Allowed)).

See also the concepts of AcceptPathInfo... We are rather in the same place
with the PATH_INFO concept and POST and even client bodies against GET.

>I'll go fix the code to introduce the flag, and I'll default the flag (for
>now) to provide the old behavior. Once we get a function name and add the
>function, then we can change the default and have the PHP filter call the
>thing to enable delivering scripts into the filter stack.

Again, I don't intend to incorporate this into .43 - please proceed as you will,
and let's work through all these design issues.  My weekend is set aside to
finally provide some of the plug-ins for apreq in preparation for porting it as
a filter ;-)

Bill



Re: PHP POST handling

Posted by Greg Stein <gs...@lyra.org>.
On Tue, Oct 01, 2002 at 07:10:32PM -0500, William A. Rowe, Jr. wrote:
> At 05:19 PM 10/1/2002, Greg Stein wrote:
>...
> >As long as it is understood that only *one* thing can consume the request
> >body. Then the question arises: how do you arbitrate that? It would be nice
> >to simply say "the handler is the consume" but that doesn't solve the case
> >of a PHP script stored in an SVN repository. It is almost like we need some
> >concept of stages leading up to request [body] processing and content
> >generation.
> 
> Wrong.

Boy... not very subtle, are you? :-)

> Multiple things can access the properties from the request.
> Consider some form variables.  One filter might be transforming on
> variable X, while another performs some transformation on variable Z.
> And they use the same storage for all small bits of the POST.

Well... if by "properties" you mean the headers: sure. But only one person
understands the POST body, and only one should be reading it.

> In the case of upload requests, one consumer must 'sign up' to stream
> the file, and provide a method for retrieving the contents if anyone else
> cares {for the duration of the request.}  In theory, that consumer is the
> script that wants to persist the POSTed file upload.  If nobody wants
> to capture a huge POST body, we may end up with a tmpfile method,
> but if the file will be persisted, there is no reason to stow it twice.

This seems to assume that Apache [core] is processing POST bodies in some
way, and then providing APIs for other modules/scripts to access the
processed data.

I'd be very leery of automatic POST body processing in any form. Providing
standard functions? Sure. And that is what libapreq is about, right? :-)

>...
> >But they are two modes of operation. In one, you generate the original
> >content (e.g. a PROPFIND or GET response against a database), in the other
> >you're filtering content.
> 
> In both cases you are transforming a PHP script into the resulting
> output from processing the script.  No difference, truly.

At a technical level, no, not really. But the problem is that the filter
stack is about filtering the *content*. If the *script* is travelling
through the filter chain, then you've got issues :-)

The workaround to that is to always ensure that the script processor is the
first filter on the chain. But that seems kind of hacky... you could end up
with some contention there, with filters trying to jocky their way into
"first". What if a filter got itself in front of PHP? Uh oh. (yes, it would
be fine if the filter knows it is processing a script, but if it *doesn't...)

As an example of fighting for first: the OLD_WRITE filter. How do we
arbitrate that "first" spot between PHP (or some other script processor) and
OLD_WRITE?

That is why I suggested there might be a need for some kind of staged
process where we manage non-content data.

>...
> >> And that said, you can't break POST to the default handler, please
> >> revert that change.
> >
> >The POST behavior before my fix was a regression against 1.3. Its existence
> >was to support the PHP-processing-as-a-filter implementation. The impact of
> >adding the POST "feature" to the default handler was never really detected
> >until we uncovered it via a bug in mod_dav. Since this regression was found,
> >I went in and fixed it. Unfortunately, that breaks PHP :-) But I think the
> >PHP integration is broken and needs to be fixed.
> >
> >While new PHP integration is being solved, we can *temporarily* revert the
> >change so that PHP users aren't inconvenienced while the integration is
> >worked on. But the default_handler fix does need to go in to prevent the
> >regression.
> >
> >(I term it a regression because 1.3 didn't do it, and POSTing to something
> > which isn't going to handle the posted content is not right; we should be
> > generating an error that states the POST is not allowed for that resource;
> > that is what 405 is all about)
> 
> We should continue this discussion after the change is reverted,
> and let's find a better answer.

The default handler shouldn't be serving up the file for a POST. The
original change that did that was wrong.

> Going back to the apreq input filter, I can see where it would share
> with the core if anyone registered to review the client body.  If someone
> does, the handler could be toggled to accept POST.  If nobody registers,
> then we could decline POST.

I like this.

However, it really shouldn't be tied to POST, but should work for any
method. And it would seem to be a new request_rec field. However, to avoid
an MMN bump, I might suggest that we put the flag into the core config
record (core_request_config structure) and an API to set the flag.

So the next question then becomes: what to call the API function? Maybe
ap_method_requires_script()? It basically says "normally, this method does
not return the resource as content, but I require it because I'll interpret
it as a script to process this method." Script processors which are
installed as filters would call it. We would also recommend that the
processors have some way to configure which methods the script is actually
intended to handle, and call the function based on whether the script will
truly handle it (and if not, then the default behavior will return the
normal 405 (Method Not Allowed)).

I'll go fix the code to introduce the flag, and I'll default the flag (for
now) to provide the old behavior. Once we get a function name and add the
function, then we can change the default and have the PHP filter call the
thing to enable delivering scripts into the filter stack.

Cheers,
-g

-- 
Greg Stein, http://www.lyra.org/

Re: PHP POST handling

Posted by "William A. Rowe, Jr." <wr...@rowe-clan.net>.
At 05:19 PM 10/1/2002, Greg Stein wrote:
>On Tue, Oct 01, 2002 at 01:32:16PM -0500, William A. Rowe, Jr. wrote:
>> At 01:12 PM 10/1/2002, Greg Stein wrote:
>>...
>> One of my itches that I haven't had time yet to scratch is to implement
>> the apreq filter to expose the post (propfind, copy, etc) data to one or
>> more than one filter who -might- be interested in the client request body.
>
>As long as it is understood that only *one* thing can consume the request
>body. Then the question arises: how do you arbitrate that? It would be nice
>to simply say "the handler is the consume" but that doesn't solve the case
>of a PHP script stored in an SVN repository. It is almost like we need some
>concept of stages leading up to request [body] processing and content
>generation.

Wrong.  Multiple things can access the properties from the request.
Consider some form variables.  One filter might be transforming on
variable X, while another performs some transformation on variable Z.
And they use the same storage for all small bits of the POST.

In the case of upload requests, one consumer must 'sign up' to stream
the file, and provide a method for retrieving the contents if anyone else
cares {for the duration of the request.}  In theory, that consumer is the
script that wants to persist the POSTed file upload.  If nobody wants
to capture a huge POST body, we may end up with a tmpfile method,
but if the file will be persisted, there is no reason to stow it twice.

>> >Heck, PHP should also be able to handle a GET request. For example, it
>> >should be able to retrieve the content from a database, and then shove that
>> >into the filter stack.
>> >
>> >IOW, PHP is really a handler *and* a filter. It can handle the generation of
>> >content, but it can also process generated content when that content is a
>> >PHP script.
>> 
>> That sort of misplaced design ends up exposing two fault points, one in
>> the PHP handler, and one in the PHP filter.  Better one source of pain.
>
>But they are two modes of operation. In one, you generate the original
>content (e.g. a PROPFIND or GET response against a database), in the other
>you're filtering content.

In both cases you are transforming a PHP script into the resulting
output from processing the script.  No difference, truly.

>> That said, it is -still- a handler since it just picks up the fd out of the
>> sendfile bucket and processes that file.  Until the zend mechanics are
>> in place to slurp from brigade -> output results, this never really belonged
>> as a filter anyways.
>
>The problem is that it isn't really "filtering" content. The filter thing
>was a hack to enable us to have PHP scripts in arbitrary locations (e.g. in
>a DAV repository). But it isn't *filtering*. It is executing the script and
>producing output.
>
>The notion of "take this input, munge it in some way, and produce output" is
>*very* shaky.
>
>> And that said, you can't break POST to the default handler, please
>> revert that change.
>
>The POST behavior before my fix was a regression against 1.3. Its existence
>was to support the PHP-processing-as-a-filter implementation. The impact of
>adding the POST "feature" to the default handler was never really detected
>until we uncovered it via a bug in mod_dav. Since this regression was found,
>I went in and fixed it. Unfortunately, that breaks PHP :-) But I think the
>PHP integration is broken and needs to be fixed.
>
>While new PHP integration is being solved, we can *temporarily* revert the
>change so that PHP users aren't inconvenienced while the integration is
>worked on. But the default_handler fix does need to go in to prevent the
>regression.
>
>(I term it a regression because 1.3 didn't do it, and POSTing to something
> which isn't going to handle the posted content is not right; we should be
> generating an error that states the POST is not allowed for that resource;
> that is what 405 is all about)

We should continue this discussion after the change is reverted,
and let's find a better answer.

Going back to the apreq input filter, I can see where it would share
with the core if anyone registered to review the client body.  If someone
does, the handler could be toggled to accept POST.  If nobody registers,
then we could decline POST.

Bill



Re: PHP POST handling

Posted by Greg Stein <gs...@lyra.org>.
On Tue, Oct 01, 2002 at 01:32:16PM -0500, William A. Rowe, Jr. wrote:
> At 01:12 PM 10/1/2002, Greg Stein wrote:
>...
> One of my itches that I haven't had time yet to scratch is to implement
> the apreq filter to expose the post (propfind, copy, etc) data to one or
> more than one filter who -might- be interested in the client request body.

As long as it is understood that only *one* thing can consume the request
body. Then the question arises: how do you arbitrate that? It would be nice
to simply say "the handler is the consume" but that doesn't solve the case
of a PHP script stored in an SVN repository. It is almost like we need some
concept of stages leading up to request [body] processing and content
generation.

> >Heck, PHP should also be able to handle a GET request. For example, it
> >should be able to retrieve the content from a database, and then shove that
> >into the filter stack.
> >
> >IOW, PHP is really a handler *and* a filter. It can handle the generation of
> >content, but it can also process generated content when that content is a
> >PHP script.
> 
> That sort of misplaced design ends up exposing two fault points, one in
> the PHP handler, and one in the PHP filter.  Better one source of pain.

But they are two modes of operation. In one, you generate the original
content (e.g. a PROPFIND or GET response against a database), in the other
you're filtering content.

> That said, it is -still- a handler since it just picks up the fd out of the
> sendfile bucket and processes that file.  Until the zend mechanics are
> in place to slurp from brigade -> output results, this never really belonged
> as a filter anyways.

The problem is that it isn't really "filtering" content. The filter thing
was a hack to enable us to have PHP scripts in arbitrary locations (e.g. in
a DAV repository). But it isn't *filtering*. It is executing the script and
producing output.

The notion of "take this input, munge it in some way, and produce output" is
*very* shaky.

> And that said, you can't break POST to the default handler, please
> revert that change.

The POST behavior before my fix was a regression against 1.3. Its existence
was to support the PHP-processing-as-a-filter implementation. The impact of
adding the POST "feature" to the default handler was never really detected
until we uncovered it via a bug in mod_dav. Since this regression was found,
I went in and fixed it. Unfortunately, that breaks PHP :-) But I think the
PHP integration is broken and needs to be fixed.

While new PHP integration is being solved, we can *temporarily* revert the
change so that PHP users aren't inconvenienced while the integration is
worked on. But the default_handler fix does need to go in to prevent the
regression.

(I term it a regression because 1.3 didn't do it, and POSTing to something
 which isn't going to handle the posted content is not right; we should be
 generating an error that states the POST is not allowed for that resource;
 that is what 405 is all about)

Cheers,
-g

-- 
Greg Stein, http://www.lyra.org/

Re: PHP POST handling

Posted by Taisuke Yamada <ta...@iij.ad.jp>.
> Both Greg and I are stating that PHP should be able to serve
> PROPFIND, COPY, GET, POST, DELETE, or FOOBAR requests.  PHP scripts
> can be coerced into providing all sorts of useful behaviors, not
> the least of which is GET.  Much like a CGI script might know how
> to handle DAV or other sorts of requests.

I know I'm being offtopic here, but CGI script cannot provide
DAV service currently because mod_cgi.c does not let script handle
OPTIONS request. So even if CGI script knew how to handle it, it's
impossible to notify client about that capability.

I've looked though past discussion, and it seems there was no
negative response on making this behavior configurable. There
even was a patch (not the one I posted sometime ago - it existed
for several years), but for some reason, it never got incorporated.

--
Taisuke Yamada <ta...@iij.ad.jp>
Internet Initiative Japan Inc., Technical Planning Division

Re: PHP POST handling

Posted by "William A. Rowe, Jr." <wr...@rowe-clan.net>.
At 03:27 PM 10/1/2002, Ryan Bloom wrote:
>On Tue, 1 Oct 2002, William A. Rowe, Jr. wrote:
>
>> At 01:12 PM 10/1/2002, Greg Stein wrote:
>> >For PHP, we said "make it a filter [so the source can come from anywhere]".
>> >I think we really should have said "for GET requests, allow it to be
>> >processed by PHP." The POST, PROPFIND, COPY, etc should all be possible to handle by PHP, which means that PHP also needs a handler.
>> 
>> Agreed, if you write a PHP script we better allow you to PROPFIND
>> or COPY the puppy, in addition to POST.
>
>These are two different statements, if I am reading both
>correctly.  Please correct me if I am not.  Will, you are saying that if
>we have a PHP script, then we need to be able to do all DAV operations on
>the script.  Greg, you are saying that a PHP script needs to be able to
>satisfy a DAV request (meaning that the PHP code actually copies the
>resource, or generates the PROPFIND data).

Both Greg and I are stating that PHP should be able to serve PROPFIND,
COPY, GET, POST, DELETE, or FOOBAR requests.  PHP scripts can
be coerced into providing all sorts of useful behaviors, not the least of
which is GET.  Much like a CGI script might know how to handle DAV
or other sorts of requests.

>Assuming I am reading the two statements correctly, I agree with
>Will, but not with Greg.  There is a major difference between satisfying a
>COPY or PROPFIND request and generating a page that has accepted POST
>data.

There is a trivial difference.  Both take client bodies.

I'm not even suggesting that COPY or PROPFIND or FOOBAR should be
allowed by default, but the administrator should be able to override the
defaults if they have a script to handle such methods.

>A filter will never be able to satisfy COPY or PROPFIND, because those are
>actions that should be done in the handler phase.  However, having two
>ways to read the PHP script from disk (default_handler and php_handler),
>and run the page through the interpreter doesn't make sense.  That is why
>PHP was re-written as a filter, to allow it to take advantage of ANY
>back-end data store that we have.

That's bogus.  You REALLY can't argue that FOOBAR must be a handler
but POST must be a filter, since both take client bodies and provide response
bodies.  Pick your argument and quit waffling on the fence.

>> >Heck, PHP should also be able to handle a GET request. For example, it
>> >should be able to retrieve the content from a database, and then shove that
>> >into the filter stack.
>> >
>> >IOW, PHP is really a handler *and* a filter. It can handle the generation of
>> >content, but it can also process generated content when that content is a
>> >PHP script.
>
>I think I am missing something here.  PHP doesn't handle content
>generation.  It never has.  In Apache 1.3, PHP could read a script from
>the disk and interpret it.  In Apache 2.0, PHP _should_ be able to read a
>script from a bucket and interpret it.  

That script result wasn't generated?  What am I missing here?

>(The fact that it doesn't right
>now, is not really germane to this discussion).  

Agreed, we are discussing how things aught to work, not how they
have been kludged to work.

>>>From my reading of the statement above, you want people to be able to
>write handlers in PHP, which would find another page or script in a
>database and send it down the filter stack.  That can't be done right now,
>PHP can't write handlers that way, at least not that I am aware of.
>
>This BTW, is why mod_perl has both concepts, handlers and
>filters.  Handlers are used as content endpoints, they generate
>data.  Filters are used to modify data that was already generated.
>
>Please let me know if I have misunderstood anything in this
>mail.  Everything I have said above is based on my reading of the message,
>and I tried to point out where I may have not understood what the original
>author was saying.

Greg and I are really in the same place, but arguing opposite solutions
{we agree all these cases should be consistent, and Greg argues that
the answer is handler+filter, while I argue the answer is remains filters.}

Bill



Re: PHP POST handling

Posted by Greg Stein <gs...@lyra.org>.
On Tue, Oct 01, 2002 at 03:30:43PM -0700, Rasmus Lerdorf wrote:
>...
> > Why couldn't mod_dav be implemented in PHP? I see no particular reason why
> > not... Currently, PHP cannot because it is a filter, not a handler.
> 
> We have a switch in PHP now to handle mod_dav requests actually (under
> 1.3.x)  There is no specific DAV support in there, it's just a switch that
> allows PHP to be a handler for things other than GET, HEAD and POST so
> people can implement whatever DAV stuff they want in userspace.

Sweet! That is really nice...

Also, it would be prudent to point out that we aren't
*just* talking about WebDAV methods. It should be quite possible to
experiment and try out new HTTP methods. HTTP is explicitly defined to allow
arbitrary methods (especially for experimenting prior to an RFC, as new RFCs
are released, vendor specific, or just plain ol' having fun).

Cheers,
-g

-- 
Greg Stein, http://www.lyra.org/

Re: PHP POST handling

Posted by Rasmus Lerdorf <ra...@apache.org>.
> On Tue, Oct 01, 2002 at 04:27:15PM -0400, Ryan Bloom wrote:
> > On Tue, 1 Oct 2002, William A. Rowe, Jr. wrote:
> >
> > > At 01:12 PM 10/1/2002, Greg Stein wrote:
> > > >For PHP, we said "make it a filter [so the source can come from anywhere]".
> > > >I think we really should have said "for GET requests, allow it to be
> > > >processed by PHP." The POST, PROPFIND, COPY, etc should all be possible to handle by PHP, which means that PHP also needs a handler.
> > >
> > > Agreed, if you write a PHP script we better allow you to PROPFIND
> > > or COPY the puppy, in addition to POST.
> >
> > These are two different statements, if I am reading both
> > correctly.  Please correct me if I am not.  Will, you are saying that if
> > we have a PHP script, then we need to be able to do all DAV operations on
> > the script.  Greg, you are saying that a PHP script needs to be able to
> > satisfy a DAV request (meaning that the PHP code actually copies the
> > resource, or generates the PROPFIND data).
> >
> > Assuming I am reading the two statements correctly, I agree with
> > Will, but not with Greg.
>
> Why couldn't mod_dav be implemented in PHP? I see no particular reason why
> not... Currently, PHP cannot because it is a filter, not a handler.

We have a switch in PHP now to handle mod_dav requests actually (under
1.3.x)  There is no specific DAV support in there, it's just a switch that
allows PHP to be a handler for things other than GET, HEAD and POST so
people can implement whatever DAV stuff they want in userspace.

-Rasmus


Re: PHP POST handling

Posted by Greg Stein <gs...@lyra.org>.
On Tue, Oct 01, 2002 at 04:27:15PM -0400, Ryan Bloom wrote:
> On Tue, 1 Oct 2002, William A. Rowe, Jr. wrote:
> 
> > At 01:12 PM 10/1/2002, Greg Stein wrote:
> > >For PHP, we said "make it a filter [so the source can come from anywhere]".
> > >I think we really should have said "for GET requests, allow it to be
> > >processed by PHP." The POST, PROPFIND, COPY, etc should all be possible to handle by PHP, which means that PHP also needs a handler.
> > 
> > Agreed, if you write a PHP script we better allow you to PROPFIND
> > or COPY the puppy, in addition to POST.
> 
> These are two different statements, if I am reading both
> correctly.  Please correct me if I am not.  Will, you are saying that if
> we have a PHP script, then we need to be able to do all DAV operations on
> the script.  Greg, you are saying that a PHP script needs to be able to
> satisfy a DAV request (meaning that the PHP code actually copies the
> resource, or generates the PROPFIND data).
> 
> Assuming I am reading the two statements correctly, I agree with
> Will, but not with Greg.

Why couldn't mod_dav be implemented in PHP? I see no particular reason why
not... Currently, PHP cannot because it is a filter, not a handler.

[ and yes: you should be able to manage the *scripts* using DAV operations;
  typically, you do that through a different vhost or path on the server so
  that you don't confuse GET between "GET source" and "GET output" ]

> There is a major difference between satisfying a
> COPY or PROPFIND request and generating a page that has accepted POST
> data.

Actually, I see little difference. A POST method accepts posted data and
generates a response. PROPFIND accepts data and generates a response. COPY
is mostly header-based, but I certainly don't see COPY being handled by a
filter :-)

> A filter will never be able to satisfy COPY or PROPFIND, because those are
> actions that should be done in the handler phase.

What makes these different from POST? If you can articulate that, then I'll
be able to understand your POV much better.

> However, having two
> ways to read the PHP script from disk (default_handler and php_handler),
> and run the page through the interpreter doesn't make sense.  That is why
> PHP was re-written as a filter, to allow it to take advantage of ANY
> back-end data store that we have.

In this case, you're saying "content generator provides script. execute
script." But how do we get PHP to be a content generator? Should PHP never
be able to act as a content generator?

How do we get PHP to yank a Perl script out of a database and feed it to
mod_perl?

Heck... we don't have enough resolution in our codebase right now. How do we
write a DAV provider in PHP, and store those scripts in SVN? In other words,
I want SVN to provide the raw content (but not act as a DAV provider), then
have that content executed by PHP to operate as a DAV server.

There is a lot of fuzziness in the early stages of the filter stack. Where
is the line between a handler and the beginning of the stack? How many
stages does the server go thru before the initial content is found? For
example, a disk file contains a PHP script which is a DAV server which loads
the content out of a database which is a Perl script to generate content.
That content is then SSI-processed, gzip'd, and then shoved onto the wire.

If there is no request body, then the line between handler and filter stack
just isn't there. You just kick an EOS brigade into the filter stack and the
first filter inserts content before the EOS (say, by reading it off disk).
When you get a request body, then it becomes a bit more difficult as it
would be "neat" to pass that through the filter stack, but it becomes hard
to distinguish between the input and the generated content.


Blah blah. I'm a bit off track there. There is one entity in the request
processing which is responsible for managing the request body. Everything
else is about altering the resulting output. Who handles the request? It
can't positively be the content generator, as we said that we want to load a
script, and have that script be the handler (e.g. handle PROPFIND).

> > >Heck, PHP should also be able to handle a GET request. For example, it
> > >should be able to retrieve the content from a database, and then shove that
> > >into the filter stack.
> > >
> > >IOW, PHP is really a handler *and* a filter. It can handle the generation of
> > >content, but it can also process generated content when that content is a
> > >PHP script.
> 
> I think I am missing something here.  PHP doesn't handle content
> generation.  It never has.  In Apache 1.3, PHP could read a script from
> the disk and interpret it.  In Apache 2.0, PHP _should_ be able to read a
> script from a bucket and interpret it.

In 2.0, we have a thing called "content generation" which means "generate
the script content." In 1.3, that was wrapped into the processing of that
script. So yes... PHP used to handle the concept of content generation, as
we know it in 2.0 today.

By moving PHP to a filter, we simply allowed the script to be located
anywhere. But I don't think the filter is the right place to handle *all*
types of PHP requests. e.g. POST or PROPFIND

> (The fact that it doesn't right
> now, is not really germane to this discussion).

Agreed.

> From my reading of the statement above, you want people to be able to
> write handlers in PHP, which would find another page or script in a
> database and send it down the filter stack.  That can't be done right now,
> PHP can't write handlers that way, at least not that I am aware of.

Yup, cuz we moved the integration point of PHP. But there is nothing
inherent in PHP which should prevent this.

> This BTW, is why mod_perl has both concepts, handlers and
> filters.  Handlers are used as content endpoints, they generate
> data.  Filters are used to modify data that was already generated.

Excellent.

> Please let me know if I have misunderstood anything in this
> mail.  Everything I have said above is based on my reading of the message,
> and I tried to point out where I may have not understood what the original
> author was saying.

It all seems fine, but I don't understand your POV on why POST is different
than, say, a WebDAV method. And if you agree that DAV methods shouldn't be
handled by filters, then why POST?

That seems to be the only point of question. I've blue-skyed some richer
behaviors of mixing content generation and script interpretation, but the
core question seems to boil down to where POST is handled.

Cheers,
-g

-- 
Greg Stein, http://www.lyra.org/

Re: PHP POST handling

Posted by Ryan Bloom <rb...@ntrnet.net>.
On Tue, 1 Oct 2002, William A. Rowe, Jr. wrote:

> At 01:12 PM 10/1/2002, Greg Stein wrote:
> >For PHP, we said "make it a filter [so the source can come from anywhere]".
> >I think we really should have said "for GET requests, allow it to be
> >processed by PHP." The POST, PROPFIND, COPY, etc should all be possible to handle by PHP, which means that PHP also needs a handler.
> 
> Agreed, if you write a PHP script we better allow you to PROPFIND
> or COPY the puppy, in addition to POST.

These are two different statements, if I am reading both
correctly.  Please correct me if I am not.  Will, you are saying that if
we have a PHP script, then we need to be able to do all DAV operations on
the script.  Greg, you are saying that a PHP script needs to be able to
satisfy a DAV request (meaning that the PHP code actually copies the
resource, or generates the PROPFIND data).

Assuming I am reading the two statements correctly, I agree with
Will, but not with Greg.  There is a major difference between satisfying a
COPY or PROPFIND request and generating a page that has accepted POST
data.

A filter will never be able to satisfy COPY or PROPFIND, because those are
actions that should be done in the handler phase.  However, having two
ways to read the PHP script from disk (default_handler and php_handler),
and run the page through the interpreter doesn't make sense.  That is why
PHP was re-written as a filter, to allow it to take advantage of ANY
back-end data store that we have.

> >Heck, PHP should also be able to handle a GET request. For example, it
> >should be able to retrieve the content from a database, and then shove that
> >into the filter stack.
> >
> >IOW, PHP is really a handler *and* a filter. It can handle the generation of
> >content, but it can also process generated content when that content is a
> >PHP script.

I think I am missing something here.  PHP doesn't handle content
generation.  It never has.  In Apache 1.3, PHP could read a script from
the disk and interpret it.  In Apache 2.0, PHP _should_ be able to read a
script from a bucket and interpret it.  (The fact that it doesn't right
now, is not really germane to this discussion).  

>From my reading of the statement above, you want people to be able to
write handlers in PHP, which would find another page or script in a
database and send it down the filter stack.  That can't be done right now,
PHP can't write handlers that way, at least not that I am aware of.

This BTW, is why mod_perl has both concepts, handlers and
filters.  Handlers are used as content endpoints, they generate
data.  Filters are used to modify data that was already generated.

Please let me know if I have misunderstood anything in this
mail.  Everything I have said above is based on my reading of the message,
and I tried to point out where I may have not understood what the original
author was saying.

Ryan

_______________________________________________________________________________
Ryan Bloom                        	rbb@apache.org
550 Jean St
Oakland CA 94610
-------------------------------------------------------------------------------



Re: PHP POST handling

Posted by "William A. Rowe, Jr." <wr...@rowe-clan.net>.
At 01:12 PM 10/1/2002, Greg Stein wrote:
>For PHP, we said "make it a filter [so the source can come from anywhere]".
>I think we really should have said "for GET requests, allow it to be
>processed by PHP." The POST, PROPFIND, COPY, etc should all be possible to handle by PHP, which means that PHP also needs a handler.

Agreed, if you write a PHP script we better allow you to PROPFIND
or COPY the puppy, in addition to POST.

It doesn't mean we need a handler.  We need to know if something is
expected to be coming down the wire at one of our filters.  Maybe more
than one of our filters.

One of my itches that I haven't had time yet to scratch is to implement
the apreq filter to expose the post (propfind, copy, etc) data to one or
more than one filter who -might- be interested in the client request body.

>Heck, PHP should also be able to handle a GET request. For example, it
>should be able to retrieve the content from a database, and then shove that
>into the filter stack.
>
>IOW, PHP is really a handler *and* a filter. It can handle the generation of
>content, but it can also process generated content when that content is a
>PHP script.

That sort of misplaced design ends up exposing two fault points, one in
the PHP handler, and one in the PHP filter.  Better one source of pain.

That said, it is -still- a handler since it just picks up the fd out of the
sendfile bucket and processes that file.  Until the zend mechanics are
in place to slurp from brigade -> output results, this never really belonged
as a filter anyways.

And that said, you can't break POST to the default handler, please
revert that change.

Bill