Re: [mp2] CGI redirects incorrectly handled?

2003-03-24 Thread Mark James
Stas Bekman wrote:

So can flushing be held off until either (1) blank line is printed,
(2) the 8k buffer fills, or (3) send_http_header is called?
 
1) is relevant only for handler that print headers, rather than set them
2) absolutely not, what if you want to flush data before?
3) send_http_header doesn't exist in Apache2/mod_perl2
I didn't realise that mp2 doesn't use send_http_header.  That explains
the appearance of wb-r-content_type in the mp2 code.  So is it
true that if headers are sent using the API then no output filtering
and transmission occurs until the 8k buffer is either filled or flushed
(explcitly or after exit)?

Only in the case that your handler is configured with:

  PerlOptions +ParseHeaders

*and*

it prints headers ala:

  print Content-type: 

In all other cases where headers are set via the API, e.g. 
$r-content_type, $r-headers_out, etc, there is no such a thing as the 
handler has send an empty line signaling the end of sending headers, 
because it never sends any headers at all, but uses api to set them.
Is +ParseHeaders always indicative of explicit header printing, or
can it also be set when using the API?  If the former, then yes, if
+ParseHeaders is set flushing could be held off until a blank line is seen.


With the current mp2 code, if you decide to
wait for the end of headers before doing cgi parsing and flushing then
the code is assuming that either the headers are less than 8k or that any
Status header is in the first 8k.  Otherwise the code would have to
be re-written to use continuous (spilling and merging) buffer buckets
like mod_cgi.  It can hold off on flushing indefinitely.


That approach will break this handler:

sub handler {
  my $r = shift;
  $r-content_type('text/plain');
  $r-rflush; # send something to the client immediately
  long_job();
  return Apache::OK
}
However notice that it doesn't have to set content_type() because some 
earlier handler could have done that and that should work as well:

sub handler {
  my $r = shift;
  $r-rflush; # send something to the client immediately
  long_job();
  return Apache::OK
}
So as you can see, this handler doesn't tell us when it's done with 
headers.

OK, you may say that that previous handler should have marked the end of 
headers settings, but that would be wrong if the response handler wants 
to set other headers as well.

Do we now agree that the event of end of sending headers is possible 
only in the case explained at the top?
Yes, the key I was missing is that mp2 no longer uses send_http_header.
Can you just lock out flushing when nothing has been printed and
content_type is undefined? (You impliy above that the content_type
setting is persistent, so the script would have to undef it if necessary.)
Then all the user script has to do is to make sure any Status header is
either printed or set via headers_out in the first batch of
printing/setting code before flush is called (again).



Re: [mp2] CGI redirects incorrectly handled?

2003-03-24 Thread Stas Bekman
Mark James wrote:
Stas Bekman wrote:

So can flushing be held off until either (1) blank line is printed,
(2) the 8k buffer fills, or (3) send_http_header is called?
 
1) is relevant only for handler that print headers, rather than set them
2) absolutely not, what if you want to flush data before?
3) send_http_header doesn't exist in Apache2/mod_perl2


I didn't realise that mp2 doesn't use send_http_header.  That explains
the appearance of wb-r-content_type in the mp2 code. 
I'm not quite happy yet about the current situation with send_http_header API 
removal. Currently an explicit call to $r-content_type (only in mod_perl 
handlers) turns the headers parsing off, if it was on. Which works fine as a 
replacement for $r-send_http_header. However it's possible that some earlier 
phase calls $r-content_type and the response phase still wants to *print* its 
headers, rather than use API to set them. If that's the case, we are in trouble.

I'll be soon working on providing the API for PerlOptions and other config 
options. And while most of these things are read-only, I'm thinking that I 
might be able to add a read/write accessor for ParseHeaders. So one can turn 
the parsing on and off, disregarding what was the setting in httpd.conf. I 
believe that would be the perfect solution, since it'll give developers a 
total flexibility.

So is it
true that if headers are sent using the API then no output filtering
and transmission occurs until the 8k buffer is either filled or flushed
(explcitly or after exit)?
That's correct. Though the headers are really sent by the Apache core http 
output filter, once we send the response body.

Only in the case that your handler is configured with:

  PerlOptions +ParseHeaders

*and*

it prints headers ala:

  print Content-type: 

In all other cases where headers are set via the API, e.g. 
$r-content_type, $r-headers_out, etc, there is no such a thing as 
the handler has send an empty line signaling the end of sending 
headers, because it never sends any headers at all, but uses api to 
set them.


Is +ParseHeaders always indicative of explicit header printing, or
can it also be set when using the API?  If the former, then yes, if
+ParseHeaders is set flushing could be held off until a blank line is seen.
See my plan and current situation explanation above.

Do we now agree that the event of end of sending headers is possible 
only in the case explained at the top?


Yes, the key I was missing is that mp2 no longer uses send_http_header.
Can you just lock out flushing when nothing has been printed and
content_type is undefined? (You impliy above that the content_type
setting is persistent, so the script would have to undef it if necessary.)
Then all the user script has to do is to make sure any Status header is
either printed or set via headers_out in the first batch of
printing/setting code before flush is called (again).
As I suggested earlier, I think the solution is to ignore rflush calls if we 
expect to parse headers and they weren't parsed yet. However if the buffer 
overflows, we have not much choice but to send it out. But I think that this 
will be a satisfactory solution.

Also since close($fh) always flushes in mod_cgi, I think you can get rid of 
the explicit flush for good. Since mod_perl's CLOSE is no-op, it won't cause 
the flush (at least for now).

__
Stas BekmanJAm_pH -- Just Another mod_perl Hacker
http://stason.org/ mod_perl Guide --- http://perl.apache.org
mailto:[EMAIL PROTECTED] http://use.perl.org http://apacheweek.com
http://modperlbook.org http://apache.org   http://ticketmaster.com


Re: [mp2] CGI redirects incorrectly handled?

2003-03-23 Thread Mark James
Stas Bekman wrote:
Mark James wrote:
STDOUT is flushed prior to a fork to exec an external binary (rcs).
I understand the cause. But I hope that you agree with me that this is 
an application's problem. If you haven't sent anything to STDOUT yet, 
don't flush. And if this is not under your control, reopen STDOUT to 
/dev/null before you call that piece of code, that flushes and then 
re-tie STDOUT again.
(See t/response/TestModperl/request_rec_tie_api.pm)
I guess the best way to fix the problem in-application would be to
either run nph, or do the /dev/null redirect you suggest.
Interestingly, commenting out the pre-fork flush fixes the problem
under mod_perl because close in mod_perl seems to be a no-op rather
than a flush.  If the close is also no problem under mod_cgi then
is there any real need for such a pre-fork flush in my script?

I see. But why is there no problem when using mod_cgi?
That's an interesting question. mod_cgi is a generic handler, which can 
run applications written in any language. Therefore it has no clue of 
what flush is. It simply creates a pipe to the application, and expects 
the headers headers followed by the data.

In your case, when cgi script flushes STDOUT, nothing happens at all, 
because there is no data to flush. So mod_cgi gets the headers and the 
data and all is cool

When the same code is run under mod_perl, flush generates a special 
bucket which is sent out to the filters chain, and since no headers are 
generated yet, they get generated and sent out.
Well, even under mod_cgi a program can still fflush or write.  The
difference between mod_cgi and mod_perl is that mod_cgi does not
activate the filter brigade until it has read all the headers.

Why would a perl handler script want to flush data down the filter chain
before it had finished writing all of it?
Here is an example: You have a long running process, you want the 
headers to be sent immediately, but the data won't follow for a while. 
So you create the headers, do $r-rflush, and later on send the data.
OK. So would there be a problem if mod_perl waited for the blank line
end of headers, or at least a Status header, before passing the buckets
down the line, just like mod_cgi?
mod_cgi uses spilling buckets, each of size 8K, to buffer script output,
including during the header scan, while mod_perl seems to scan the headers
when the first 8K buffer is either filled or flushed.



Re: [mp2] CGI redirects incorrectly handled?

2003-03-23 Thread Stas Bekman
Mark James wrote:
Stas Bekman wrote:

Mark James wrote:

STDOUT is flushed prior to a fork to exec an external binary (rcs).


I understand the cause. But I hope that you agree with me that this is 
an application's problem. If you haven't sent anything to STDOUT yet, 
don't flush. And if this is not under your control, reopen STDOUT to 
/dev/null before you call that piece of code, that flushes and then 
re-tie STDOUT again.
(See t/response/TestModperl/request_rec_tie_api.pm)


I guess the best way to fix the problem in-application would be to
either run nph, or do the /dev/null redirect you suggest.
Interestingly, commenting out the pre-fork flush fixes the problem
under mod_perl because close in mod_perl seems to be a no-op rather
than a flush.  If the close is also no problem under mod_cgi then
is there any real need for such a pre-fork flush in my script?
Since the mod_perl's internal STDOUT buffer isn't mangled if you re-tie it 
later, and it'll be always flushed at the end of the request, there is no 
*need* to flush on CLOSE. However in order to be consistent with perl fh close 
behavior, it probably needs to be changed to flush its buffer.

What do you think?

I see. But why is there no problem when using mod_cgi?


That's an interesting question. mod_cgi is a generic handler, which 
can run applications written in any language. Therefore it has no clue 
of what flush is. It simply creates a pipe to the application, and 
expects the headers headers followed by the data.

In your case, when cgi script flushes STDOUT, nothing happens at all, 
because there is no data to flush. So mod_cgi gets the headers and the 
data and all is cool

When the same code is run under mod_perl, flush generates a special 
bucket which is sent out to the filters chain, and since no headers 
are generated yet, they get generated and sent out.


Well, even under mod_cgi a program can still fflush or write.  
Ah, of course!

The
difference between mod_cgi and mod_perl is that mod_cgi does not
activate the filter brigade until it has read all the headers.
But in the case of mod_perl, this event is valid only for handlers which 
print their own headers, rather than using mod_perl API to set them. In the 
generic case, there is no way to tell whether a handler is going to set more 
headers or it has done with it.

I suppose that we could prevent flushing in the case the handler is configured 
to parse headers. Does it make sense?

Why would a perl handler script want to flush data down the filter chain
before it had finished writing all of it?


Here is an example: You have a long running process, you want the 
headers to be sent immediately, but the data won't follow for a while. 
So you create the headers, do $r-rflush, and later on send the data.


OK. So would there be a problem if mod_perl waited for the blank line
end of headers, or at least a Status header, before passing the buckets
down the line, just like mod_cgi?
See above.

mod_cgi uses spilling buckets, each of size 8K, to buffer script output,
including during the header scan, while mod_perl seems to scan the headers
when the first 8K buffer is either filled or flushed.
I don't think this is related to the issue in question. Since the problem is 
what to do on flush.

Also we might have a problem if the headers to parse are bigger than the size 
of the buffer (8k). Do you think someone will ever need to send headers bigger 
than 8k?

__
Stas BekmanJAm_pH -- Just Another mod_perl Hacker
http://stason.org/ mod_perl Guide --- http://perl.apache.org
mailto:[EMAIL PROTECTED] http://use.perl.org http://apacheweek.com
http://modperlbook.org http://apache.org   http://ticketmaster.com


Re: [mp2] CGI redirects incorrectly handled?

2003-03-23 Thread Mark James
Stas Bekman wrote:

Since the mod_perl's internal STDOUT buffer isn't mangled if you re-tie 
it later, and it'll be always flushed at the end of the request, there 
is no *need* to flush on CLOSE. However in order to be consistent with 
perl fh close behavior, it probably needs to be changed to flush its 
buffer.

What do you think?
Dunno.  But the problem I had would have been even harder to track
down if commenting out the flush hadn't fixed it.

The
difference between mod_cgi and mod_perl is that mod_cgi does not
activate the filter brigade until it has read all the headers.


But in the case of mod_perl, this event is valid only for handlers 
which print their own headers, rather than using mod_perl API to set 
them. In the generic case, there is no way to tell whether a handler is 
going to set more headers or it has done with it.
So can flushing be held off until either (1) blank line is printed,
(2) the 8k buffer fills, or (3) send_http_header is called?
I suppose that we could prevent flushing in the case the handler is 
configured to parse headers. Does it make sense?
No. Could you explain your reasoning.


mod_cgi uses spilling buckets, each of size 8K, to buffer script output,
including during the header scan, while mod_perl seems to scan the 
headers
when the first 8K buffer is either filled or flushed.


I don't think this is related to the issue in question. Since the 
problem is what to do on flush.

Also we might have a problem if the headers to parse are bigger than the 
size of the buffer (8k). Do you think someone will ever need to send 
headers bigger than 8k?
Yes, I mentioned the buffer size in case your objection to my proposal
to wait until end of headers was seen was based on the possiblity of
more than 8k of headers.  With the current mp2 code, if you decide to
wait for the end of headers before doing cgi parsing and flushing then
the code is assuming that either the headers are less than 8k or that any
Status header is in the first 8k.  Otherwise the code would have to
be re-written to use continuous (spilling and merging) buffer buckets
like mod_cgi.  It can hold off on flushing indefinitely.


Re: [mp2] CGI redirects incorrectly handled?

2003-03-23 Thread Stas Bekman

The
difference between mod_cgi and mod_perl is that mod_cgi does not
activate the filter brigade until it has read all the headers.


But in the case of mod_perl, this event is valid only for handlers 
which print their own headers, rather than using mod_perl API to set 
them. In the generic case, there is no way to tell whether a handler 
is going to set more headers or it has done with it.


So can flushing be held off until either (1) blank line is printed,
(2) the 8k buffer fills, or (3) send_http_header is called?
1) is relevant only for handler that print headers, rather than set them

2) absolutely not, what if you want to flush data before?

3) send_http_header doesn't exist in Apache2/mod_perl2

I suppose that we could prevent flushing in the case the handler is 
configured to parse headers. Does it make sense?


No. Could you explain your reasoning.
Only in the case that your handler is configured with:

  PerlOptions +ParseHeaders

*and*

it prints headers ala:

  print Content-type: 

In all other cases where headers are set via the API, e.g. $r-content_type, 
$r-headers_out, etc, there is no such a thing as the handler has send an 
empty line signaling the end of sending headers, because it never sends any 
headers at all, but uses api to set them.

Are we on the same page now?

mod_cgi uses spilling buckets, each of size 8K, to buffer script output,
including during the header scan, while mod_perl seems to scan the 
headers
when the first 8K buffer is either filled or flushed.


I don't think this is related to the issue in question. Since the 
problem is what to do on flush.

Also we might have a problem if the headers to parse are bigger than 
the size of the buffer (8k). Do you think someone will ever need to 
send headers bigger than 8k?


Yes, I mentioned the buffer size in case your objection to my proposal
to wait until end of headers was seen was based on the possiblity of
more than 8k of headers.  
Again, the concept of the end of headers exists only in certain cases.

With the current mp2 code, if you decide to
wait for the end of headers before doing cgi parsing and flushing then
the code is assuming that either the headers are less than 8k or that any
Status header is in the first 8k.  Otherwise the code would have to
be re-written to use continuous (spilling and merging) buffer buckets
like mod_cgi.  It can hold off on flushing indefinitely.
That approach will break this handler:

sub handler {
  my $r = shift;
  $r-content_type('text/plain');
  $r-rflush; # send something to the client immediately
  long_job();
  return Apache::OK
}
However notice that it doesn't have to set content_type() because some earlier 
handler could have done that and that should work as well:

sub handler {
  my $r = shift;
  $r-rflush; # send something to the client immediately
  long_job();
  return Apache::OK
}
So as you can see, this handler doesn't tell us when it's done with headers.

OK, you may say that that previous handler should have marked the end of 
headers settings, but that would be wrong if the response handler wants to set 
other headers as well.

Do we now agree that the event of end of sending headers is possible only in 
the case explained at the top?

__
Stas BekmanJAm_pH -- Just Another mod_perl Hacker
http://stason.org/ mod_perl Guide --- http://perl.apache.org
mailto:[EMAIL PROTECTED] http://use.perl.org http://apacheweek.com
http://modperlbook.org http://apache.org   http://ticketmaster.com


Re: [mp2] CGI redirects incorrectly handled?

2003-03-19 Thread Mark James
Mark James wrote:
I'm having CGI redirect problems mp2 (cvs).

Instead of being redirected to the proper web page, I'm sometimes
getting a 302 Moved page containing a link to the correct URL.
Damn this was a hard bug to track down.

The cause of the problem was my perl code calling flush.pl and
flushing STDOUT at a point prior to it printing the response headers.
Under mp2, flushing STDOUT calls mpxs_output_flush in
xs/Apache/RequestIO/Apache__RequestIO.h, which in turn calls
ap_rflush, which triggers creation of the HTTP header, which
at this stage, prior to my script printing its 302 header,
uses a 200 OK status.  So instead of a proper redirect
being sent back to the browser, a normal web page with an
embedded 302 link is sent.
Everything seems to work if the ap_rflush call is removed
from mpxs_output_flush, but I don't know if this is the
proper way to fix it.
Mark



Re: [mp2] CGI redirects incorrectly handled?

2003-03-19 Thread dom
 
 The cause of the problem was my perl code calling flush.pl and
 flushing STDOUT at a point prior to it printing the response headers.
 Under mp2, flushing STDOUT calls mpxs_output_flush in
 xs/Apache/RequestIO/Apache__RequestIO.h, which in turn calls
 ap_rflush, which triggers creation of the HTTP header, which
 at this stage, prior to my script printing its 302 header,
 uses a 200 OK status.

  Meaning no offence to the mp2 developpers, I find this observed
behaviour inappropriate - I recently have to develop a reverse-proxy
and got bitten by undocumented semantics of this sort every so often,
I had to resort to reading the source with pencil  paper like the
original poster apparently did.

  What is the architectural justification for not choosing one of
those two behaviours about header output, and erring on the middle
side:

  * headers are out-of-band, and the first call to print() prepends
whatever headers were set using the appropriate API
(e.g. print_header() should have no effect afterwards, or maybe
should set HTTP/1.1 trailers);

  * headers are regular flow, and Apache / mp2 never tries to add its
own ones (almost impossible to ensure under Apache / mp1).

  Thanks for any insight on this topic - maybe there is a FAQ
somewhere about MP2 architecture ?

-- 
Dominique QUATRAVAUX   Ingénieur développeur senior
01 44 42 00 08 IDEALX




Re: [mp2] CGI redirects incorrectly handled?

2003-03-19 Thread Stas Bekman
Mark James wrote:
Mark James wrote:

I'm having CGI redirect problems mp2 (cvs).

Instead of being redirected to the proper web page, I'm sometimes
getting a 302 Moved page containing a link to the correct URL.


Damn this was a hard bug to track down.

The cause of the problem was my perl code calling flush.pl and
flushing STDOUT at a point prior to it printing the response headers.
Under mp2, flushing STDOUT calls mpxs_output_flush in
xs/Apache/RequestIO/Apache__RequestIO.h, which in turn calls
ap_rflush, which triggers creation of the HTTP header, which
at this stage, prior to my script printing its 302 header,
uses a 200 OK status.  So instead of a proper redirect
being sent back to the browser, a normal web page with an
embedded 302 link is sent.
Hmm, why do you flush?

The way Apache2 is designed is that the moment you send anything down the 
filter chain, the headers are generated, because they have to be sent before 
any data goes out. However mod_perl has an internal buffer and it won't flush 
the data before it gets full or the code tells it to flush using $r-rflush. 
If $|==0, then the buffer is not used and the data is flushed on every print.

Everything seems to work if the ap_rflush call is removed
from mpxs_output_flush, but I don't know if this is the
proper way to fix it.
No, this is not a proper way to fix it. Otherwise those who want to flush 
their output won't be able to do so.



__
Stas BekmanJAm_pH -- Just Another mod_perl Hacker
http://stason.org/ mod_perl Guide --- http://perl.apache.org
mailto:[EMAIL PROTECTED] http://use.perl.org http://apacheweek.com
http://modperlbook.org http://apache.org   http://ticketmaster.com


Re: [mp2] CGI redirects incorrectly handled?

2003-03-19 Thread Stas Bekman
[EMAIL PROTECTED] wrote:
The cause of the problem was my perl code calling flush.pl and
flushing STDOUT at a point prior to it printing the response headers.
Under mp2, flushing STDOUT calls mpxs_output_flush in
xs/Apache/RequestIO/Apache__RequestIO.h, which in turn calls
ap_rflush, which triggers creation of the HTTP header, which
at this stage, prior to my script printing its 302 header,
uses a 200 OK status.


  Meaning no offence to the mp2 developpers, I find this observed
behaviour inappropriate - I recently have to develop a reverse-proxy
and got bitten by undocumented semantics of this sort every so often,
I had to resort to reading the source with pencil  paper like the
original poster apparently did.
I think you are confusing mp2 design with Apache2 design. This is how Apache2 
works, the main reason I believe to accomodate the filtering mechanism.

As for undocumented behavior, you are welcome to submit documentation patches 
or wait till someone will write them.

  What is the architectural justification for not choosing one of
those two behaviours about header output, and erring on the middle
side:
  * headers are out-of-band, and the first call to print() prepends
whatever headers were set using the appropriate API
(e.g. print_header() should have no effect afterwards, or maybe
should set HTTP/1.1 trailers);
That's exactly how it works. The first print/puts/printf/rflush causes the 
headers to be sent (assuming that STDOUT is unbuffered), using whatever 
headers were set so far. Do I miss something here? This is 1:1 mapping to 
Apache behavior.

The only difference is the mod_perl internal STDOUT buffer used for buffered 
STDOUT.

  * headers are regular flow, and Apache / mp2 never tries to add its
own ones (almost impossible to ensure under Apache / mp1).
  Thanks for any insight on this topic - maybe there is a FAQ
somewhere about MP2 architecture ?
There are Doug's architecture notes online, I did some changes to them to 
bring things to the current state of things. They are certainly could have 
some more work. Patches are welcome.

__
Stas BekmanJAm_pH -- Just Another mod_perl Hacker
http://stason.org/ mod_perl Guide --- http://perl.apache.org
mailto:[EMAIL PROTECTED] http://use.perl.org http://apacheweek.com
http://modperlbook.org http://apache.org   http://ticketmaster.com


Re: [mp2] CGI redirects incorrectly handled?

2003-03-19 Thread Mark James
Stas Bekman wrote:

Mark James wrote:
The cause of the problem was my perl code calling flush.pl and
flushing STDOUT at a point prior to it printing the response headers.
Hmm, why do you flush?
STDOUT is flushed prior to a fork to exec an external binary (rcs).
The child is closing STDOUT and then redirecting it into a pipe
to the parent.  I didn't write this part of the code, but the
comment on the flushing is:
# flush now, lest data in a buffer get flushed on close() in every stinking
# child process.
The code for the forking is:
bulletproof fork from camel book, 2ed, page 167
If necessary I can propose a patch to this perl package to make the
flushing conditional on not running under mod_perl.

The way Apache2 is designed is that the moment you send anything down 
the filter chain, the headers are generated, because they have to be 
sent before any data goes out. However mod_perl has an internal buffer 
and it won't flush the data before it gets full or the code tells it to 
flush using $r-rflush. If $|==0, then the buffer is not used and the 
data is flushed on every print.
I see. But why is there no problem when using mod_cgi?


Everything seems to work if the ap_rflush call is removed
from mpxs_output_flush, but I don't know if this is the
proper way to fix it.


No, this is not a proper way to fix it. Otherwise those who want to 
flush their output won't be able to do so.
Why would a perl handler script want to flush data down the filter chain
before it had finished writing all of it?
Mark



Re: [mp2] CGI redirects incorrectly handled?

2003-03-19 Thread Stas Bekman
Mark James wrote:
Stas Bekman wrote:

Mark James wrote:

The cause of the problem was my perl code calling flush.pl and
flushing STDOUT at a point prior to it printing the response headers.


Hmm, why do you flush?


STDOUT is flushed prior to a fork to exec an external binary (rcs).
The child is closing STDOUT and then redirecting it into a pipe
to the parent.  I didn't write this part of the code, but the
comment on the flushing is:
# flush now, lest data in a buffer get flushed on close() in every 
stinking
# child process.

The code for the forking is:
bulletproof fork from camel book, 2ed, page 167
If necessary I can propose a patch to this perl package to make the
flushing conditional on not running under mod_perl.
I understand the cause. But I hope that you agree with me that this is an 
application's problem. If you haven't sent anything to STDOUT yet, don't 
flush. And if this is not under your control, reopen STDOUT to /dev/null 
before you call that piece of code, that flushes and then re-tie STDOUT again.
(See t/response/TestModperl/request_rec_tie_api.pm)

Technically it's possible to add a flag in mod_perl 2.0 to ignore any flush 
attempts, if no data data was printed yet. However, this could become an 
undesirable behavior for someone who wants to send a flush before any data is 
sent. In your case, you can work around the problem, in the case of a person 
who wants the other behavior, there is no workaround. So I suggest that we 
keep the mp behavior generic and not create special cases we may regret about 
later on.

The way Apache2 is designed is that the moment you send anything down 
the filter chain, the headers are generated, because they have to be 
sent before any data goes out. However mod_perl has an internal buffer 
and it won't flush the data before it gets full or the code tells it 
to flush using $r-rflush. If $|==0, then the buffer is not used and 
the data is flushed on every print.


I see. But why is there no problem when using mod_cgi?
That's an interesting question. mod_cgi is a generic handler, which can run 
applications written in any language. Therefore it has no clue of what flush 
is. It simply creates a pipe to the application, and expects the headers 
headers followed by the data.

In your case, when cgi script flushes STDOUT, nothing happens at all, because 
there is no data to flush. So mod_cgi gets the headers and the data and all is 
cool.

When the same code is run under mod_perl, flush generates a special bucket 
which is sent out to the filters chain, and since no headers are generated 
yet, they get generated and sent out.

As I wrote this, I'm actually starting to think that it's Apache who should 
ignore the flush bucket if it had seen no other data so far, and not generate 
any headers till it actually sees the real data.

Everything seems to work if the ap_rflush call is removed
from mpxs_output_flush, but I don't know if this is the
proper way to fix it.


No, this is not a proper way to fix it. Otherwise those who want to 
flush their output won't be able to do so.


Why would a perl handler script want to flush data down the filter chain
before it had finished writing all of it?
Here is an example: You have a long running process, you want the headers to 
be sent immediately, but the data won't follow for a while. So you create the 
headers, do $r-rflush, and later on send the data.

__
Stas BekmanJAm_pH -- Just Another mod_perl Hacker
http://stason.org/ mod_perl Guide --- http://perl.apache.org
mailto:[EMAIL PROTECTED] http://use.perl.org http://apacheweek.com
http://modperlbook.org http://apache.org   http://ticketmaster.com


Re: [mp2] CGI redirects incorrectly handled?

2003-03-19 Thread Stas Bekman
Stas Bekman wrote:

As I wrote this, I'm actually starting to think that it's Apache who 
should ignore the flush bucket if it had seen no other data so far, and 
not generate any headers till it actually sees the real data.
And I went to produce a patch in http_filter, I figured that that would be 
wrong for the same reason, mod_perl shouldn't handle that as a special case, 
since that behavior might be a desired one.

Another workaround for your problem could be a custom output filter, that 
yanks any bucket brigades including only the flush bucket, if it had not seen 
any real data buckets yet.

__
Stas BekmanJAm_pH -- Just Another mod_perl Hacker
http://stason.org/ mod_perl Guide --- http://perl.apache.org
mailto:[EMAIL PROTECTED] http://use.perl.org http://apacheweek.com
http://modperlbook.org http://apache.org   http://ticketmaster.com


Re: [mp2] CGI redirects incorrectly handled?

2003-03-08 Thread Stas Bekman
Mark James wrote:
Stas Bekman wrote:

Can you send a short script (removing all the irrelevant bits) that we 
can reproduce the problem with?


Made a script that generated the same POST request and same
redirect as the problem code.  The problem was not reproduced!
The only difference I can see between working POSTs (both those
in my package code and the one in the test script) and the failing
one (a particular one in my package) is in the distribution of the
data across the TCP packets that carry the POST.
[snippet the packet dumps]

Could mod_perl, with its persistent buffer, be tripping up on this?
I'm trying now to trace the data through the mp2 code. -- Mark
mod_perl 2.0 is buffering only the content (response body, not the headers) 
(assuming that you aren't installing any output filters), so it's one of the 
apache core output filters, that decides how to split the data.

a normal output filter list ends with:

byterange(0x8841110): ctx=0x0, r=0x88402d0, c=0x883a390
content_length(0x8841128): ctx=0x0, r=0x88402d0, c=0x883a390
http_header(0x8841140): ctx=0x0, r=0x88402d0, c=0x883a390
core(0x883a760): ctx=0x883a738, r=0x0, c=0x883a390
you can dump this, using the dump_filters macro, which you can load by running

  gdb source /path/to/httpd-2.0/.gdbinit

the 'core' filter is in httpd-2.0/src/core.c: core_output_filter(...)

__
Stas BekmanJAm_pH -- Just Another mod_perl Hacker
http://stason.org/ mod_perl Guide --- http://perl.apache.org
mailto:[EMAIL PROTECTED] http://use.perl.org http://apacheweek.com
http://modperlbook.org http://apache.org   http://ticketmaster.com


Re: [mp2] CGI redirects incorrectly handled?

2003-03-06 Thread Mark James
Stas Bekman wrote:

Can you send a short script (removing all the irrelevant bits) that we 
can reproduce the problem with?
Made a script that generated the same POST request and same
redirect as the problem code.  The problem was not reproduced!
The only difference I can see between working POSTs (both those
in my package code and the one in the test script) and the failing
one (a particular one in my package) is in the distribution of the
data across the TCP packets that carry the POST.
Packet 1 always has the POST request and a set of headers.

When it works (a 302 is sent), Packet 2 has the Content-Type
header, Packet 3 has the Content-Length header, and Packet 4
has the POSTed variables:
PACKET 2:
0x   4500 0065 f659 4000 4006 4993 9084 ecce[EMAIL PROTECTED]@.I.
0x0010   9084 ecce 9ea1 0050 482e 99c3 4828 27ae...PH...H('.
0x0020   8018 7fff cd14  0101 080a 00a9 6185..a.
0x0030   00a9 6185 436f 6e74 656e 742d 5479 7065..a.Content-Type
0x0040   3a20 6170 706c 6963 6174 696f 6e2f 782d:.application/x-
0x0050    772d 666f 726d 2d75 726c 656e 636fwww-form-urlenco
0x0060   6465 640d 0a   ded..
PACKET 3:
0x   4500 004b f65a 4000 4006 49ac 9084 ecce[EMAIL PROTECTED]@.I.
0x0010   9084 ecce 9ea1 0050 482e 99f4 4828 27ae...PH...H('.
0x0020   8018 7fff d88d  0101 080a 00a9 6185..a.
0x0030   00a9 6185 436f 6e74 656e 742d 4c65 6e67..a.Content-Leng
0x0040   7468 3a20 3334 320d 0a0d 0ath:.342
PACKET 4:
0x   4500 018a f65b 4000 4006 486c 9084 ecce[EMAIL PROTECTED]@.Hl
0x0010   9084 ecce 9ea1 0050 482e 9a0b 4828 27ae...PH...H('.
0x0020   8018 7fff 945c  0101 080a 00a9 6185.\a.
0x0030   00a9 6185 5f70 6173 735f 6964 3d75 7365..a._pass_id=use
0x0040   7233 2534 306d 616b 6574 6865 6361 7365r3%40makethecase
0x0050   2e6e 6574 265f 7061 7373 5f70 6173 733d.net_pass_pass=
[rest of packet cut]
But when it fails (a 200 with a 302 link is sent),
all is in the one packet:
0x   4500 01af 1d11 4000 4006 2192 9084 ecce[EMAIL PROTECTED]@.!.
0x0010   9084 ecce 9faf 0050 f769 cb03 f764 9ec7...P.i...d..
0x0020   8018 bb9e fe65  0101 080a 00ad a4b7.e..
0x0030   00ad a4b7 436f 6e74 656e 742d 5479 7065Content-Type
0x0040   3a20 6170 706c 6963 6174 696f 6e2f 782d:.application/x-
0x0050    772d 666f 726d 2d75 726c 656e 636fwww-form-urlenco
0x0060   6465 640d 0a43 6f6e 7465 6e74 2d4c 656eded..Content-Len
0x0070   6774 683a 2033 3037 0d0a 0d0a 5f70 6173gth:.307_pas
0x0080   735f 6964 3d75 7365 7233 2534 306d 616bs_id=user3%40mak
0x0090   6574 6865 6361 7365 2e6e 6574 265f 7061ethecase.net_pa
0x00a0   7373 5f70 6173 733dss_pass=
[rest of packet cut]
Could mod_perl, with its persistent buffer, be tripping up on this?
I'm trying now to trace the data through the mp2 code. -- Mark


Re: [mp2] CGI redirects incorrectly handled?

2003-03-05 Thread Nick Tonkin

How are you telling the server to redirect? You do know it's different
from mp1, right?

In mp2 you need to do:

my $location = 'http://foo.bar.baz';

$r-headers_out-{'Location'} = $location;
# Or use $r-err_headers_out-{'Location'} which you will have
# to do with any other headers you want to have sent with the
# redirect, such as cookies

return Apache::HTTP_MOVED_TEMPORARILY;
# Apache::REDIRECT still supported, this is the correct
# constant though.

On Wed, 5 Mar 2003, Mark James wrote:

 I'm having CGI redirect problems mp2 (cvs).


How are you telling the server to redirect? You do know it's different
from mp1, right?

In mp2 you need to do:

my $location = 'http://foo.bar.baz';

$r-headers_out-{'Location'} = $location;
# Or use $r-err_headers_out-{'Location'} which you will have
# to do with any other headers you want to have sent with the
# redirect, such as cookies

return Apache::HTTP_MOVED_TEMPORARILY;
# Apache::REDIRECT still supported, this is the correct
# constant though.

Now that I think about it, maybe you're using CGI.pm to do your redirect?
If so, maybe the code in CGI.pm has not been correctly updated?


Hope this helps.

- nick

-- 


Nick Tonkin   {|8^)



Re: [mp2] CGI redirects incorrectly handled?

2003-03-05 Thread Nick Tonkin
On Thu, 6 Mar 2003, Mark James wrote:

 Nick Tonkin wrote:

  Now that I think about it, maybe you're using CGI.pm to do your redirect?
  If so, maybe the code in CGI.pm has not been correctly updated?

 Yes Nick, I'm using CGI.pm version 2.91 (the latest).  Its redirect code
 sends a Status: 302 Moved.

That wouldn't be the problem, if there is one. The problem would be in how
CGI.pm sets the Location header, noting the differences in syntax I
pointed out earlier.

You might try one of the CGI mailing lists to see if anyone there knows
whether the code is compliant with what I posted before. The documentation
is at http://xrl.us/dfb

Otherwise, try setting the redirect location manually as I showed you and
see if the problem persists.


- nick

-- 


Nick Tonkin   {|8^)



Re: [mp2] CGI redirects incorrectly handled?

2003-03-05 Thread Stas Bekman
Mark James wrote:
I'm having CGI redirect problems mp2 (cvs).

Instead of being redirected to the proper web page, I'm sometimes
getting a 302 Moved page containing a link to the correct URL.
Seems to be related to the following code in modperl_cgi.c:

if (location  (location[0] == '/')  (r-status == 200)) {
r-method = apr_pstrdup(r-pool, GET);
r-method_number = M_GET;
The Location field I'm redirecting to is a fully-qualified URL,
starting with http://, but still at the local server.  A debug
put in above this code confirms that location is set to a
string starting with http.
Why is the test for location[0] == '/' there?  Which section
of code is usually responsible for stripping off the server
part of the address if it is local?
as the comment just above this line says, that code was copy-n-pasted from 
mod_cgi. Can you reproduce the same problem while running a cgi script?

Also could it be that it has to do with the recent change, I've applied which 
was already reported by Beau as broken. May be your headers don't get parsed 
What happens if you do:

Index: src/modules/perl/modperl_filter.c
===
RCS file: /home/cvs/modperl-2.0/src/modules/perl/modperl_filter.c,v
retrieving revision 1.54
diff -u -r1.54 modperl_filter.c
--- src/modules/perl/modperl_filter.c   3 Mar 2003 03:39:06 -   1.54
+++ src/modules/perl/modperl_filter.c   5 Mar 2003 23:15:44 -
@@ -55,7 +55,7 @@
 apr_bucket *bucket;
 const char *work_buf = buf;
-if (wb-header_parse  !wb-r-content_type) {
+if (wb-header_parse) {
 request_rec *r = wb-r;
 const char *bodytext = NULL;
 int status;


__
Stas BekmanJAm_pH -- Just Another mod_perl Hacker
http://stason.org/ mod_perl Guide --- http://perl.apache.org
mailto:[EMAIL PROTECTED] http://use.perl.org http://apacheweek.com
http://modperlbook.org http://apache.org   http://ticketmaster.com


Re: [mp2] CGI redirects incorrectly handled?

2003-03-05 Thread Mark James
Stas Bekman wrote:
Mark James wrote:
I'm having CGI redirect problems mp2 (cvs).
as the comment just above this line says, that code was copy-n-pasted 
from mod_cgi. Can you reproduce the same problem while running a cgi 
script?
No, them problem only manifests under mod_perl (2, haven't used 1).

Also could it be that it has to do with the recent change, I've applied 
which was already reported by Beau as broken. May be your headers don't 
get parsed What happens if you do:
[patch]
Applied the patch, but the problem still occurred. No change also
when I commented out the location[0]=='/' test.
The redirect header being printed by my perl script is:

Server: Apache/2.0.44 (Unix) mod_perl/1.99_09-dev Perl/v5.8.0
Status: 302 Moved
Date: Thu, 06 Mar 2003 01:10:54 GMT
Location: http://makethecase.net/db?auth=ckffb2a5c44ee0editCmds=compactfile=62
Which is returned as a 302 link page.  This is a redirect response to a POST.

Strangely, another redirect, with header:

Server: Apache/2.0.44 (Unix) mod_perl/1.99_09-dev Perl/v5.8.0
Status: 302 Moved
Date: Thu, 06 Mar 2003 01:15:54 GMT
Location: 
http://makethecase.net/db?_reason=6%20Case1Pro_restart=editPartcheckSequenceNumber=60cmd=authenticateeditCmds=compactfile=62partnum=
works just fine.  This is a redirect after a GET.

Mark



Re: [mp2] CGI redirects incorrectly handled?

2003-03-05 Thread Stas Bekman
Mark James wrote:
Stas Bekman wrote:

Mark James wrote:

I'm having CGI redirect problems mp2 (cvs).


as the comment just above this line says, that code was copy-n-pasted 
from mod_cgi. Can you reproduce the same problem while running a cgi 
script?


No, them problem only manifests under mod_perl (2, haven't used 1).
Sorry, I'm not following your comment. I've suggested to test with mod_cgi 
(under Apache2), since mod_perl mimics mod_cgi's behavior here.

Also could it be that it has to do with the recent change, I've 
applied which was already reported by Beau as broken. May be your 
headers don't get parsed What happens if you do:
[patch]


Applied the patch, but the problem still occurred. No change also
when I commented out the location[0]=='/' test.
The redirect header being printed by my perl script is:

Server: Apache/2.0.44 (Unix) mod_perl/1.99_09-dev Perl/v5.8.0
Status: 302 Moved
Date: Thu, 06 Mar 2003 01:10:54 GMT
Location: 
http://makethecase.net/db?auth=ckffb2a5c44ee0editCmds=compactfile=62

Which is returned as a 302 link page.  This is a redirect response to a 
POST.

Strangely, another redirect, with header:

Server: Apache/2.0.44 (Unix) mod_perl/1.99_09-dev Perl/v5.8.0
Status: 302 Moved
Date: Thu, 06 Mar 2003 01:15:54 GMT
Location: 
http://makethecase.net/db?_reason=6%20Case1Pro_restart=editPartcheckSequenceNumber=60cmd=authenticateeditCmds=compactfile=62partnum= 

works just fine.  This is a redirect after a GET.
Should POST-redirect return 307?
http://ppewww.ph.gla.ac.uk/~flavell/www/post-redirect.html
http://rfc.net/rfc2616.html#s10.3.8
__
Stas BekmanJAm_pH -- Just Another mod_perl Hacker
http://stason.org/ mod_perl Guide --- http://perl.apache.org
mailto:[EMAIL PROTECTED] http://use.perl.org http://apacheweek.com
http://modperlbook.org http://apache.org   http://ticketmaster.com


Re: [mp2] CGI redirects incorrectly handled?

2003-03-05 Thread Mark James
Mark James wrote:

303 See Other is the correct post-POST redirect response:
http://rfc.net/rfc2616.html#s10.3.4
which your first link suggests works in all browsers.
Well, taking a closer look, 303 doesn't work in Netscape 3 or 4.


CGI.pm always returns a 302, though, if necessary, I can edit
its reply in my script before printing it.  I'll give this a go.
This didn't work.  Got a 303 link page instead of a 302 one.