perl-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From "Pavel V." <pavel2...@ngs.ru>
Subject Re: ModPerl::RegistryCooker default_handler returned status
Date Sun, 31 Aug 2014 20:15:34 GMT
Hi, Perrin.

> Hi Pavel,

> You might get more interesting answers on the "users" mailing list, but there's lots
of
> discussion about this in the archives.

Thanks for interesting reading. I will read for a last 4 hours.

>  For example:
> http://www.gossamer-threads.com/lists/modperl/modperl/45559?search_string=registry%20status;#45559

This thread is about 'how to do things incorrectly'.

The handler status and response status are different things, and only broken implementation
in
RegistryCooker mix them together.

I completely misunderstand, why we need to return HTTP_* codes from ModPerl handlers.
Why Apache::OK or Apache::SERVER_ERROR are not enough?

> http://www.gossamer-threads.com/lists/modperl/modperl/88690?search_string=registry%20status;#88690

This thread is exactly about this: '
> $r->status is used to communicate the registry handler return code,
> not really set r->status over in C-land (as it would be if you called it from a normal
> handler).'

Yes, I agreed with topicstarter - $r->status() is evil under ModPerl modules in current
implementation.

Current implementation uses $r->status to set handler status, and r->status is can not
be edited
using it. And this is ugly.

But WHY? What needs have led to this? I found no reasons for this in apache-1.3/apache-2.2
implementations. But it is written there:

> We have a bunch of old scripts that set $r->status explicitly. For
> handlers, that's deprecated and unnecessary, but I understand that was
> the usual way to do it in registry scripts in the old days of mp1.

Can anybody explain, why this was needed with mp1?
Why we are unable to left $r->status, the new value set by script, untouched?

---------

http://www.gossamer-threads.com/lists/modperl/modperl/54151?search_string=registry%20status;#54151
is more interesting - it is also about problem with non-200 response code.

Perrin, what personally you think about - 'why we need to reset status after running handler'?

Can you show discussion, explaining why this was neeeded? I know what this 'feature' appeared
at
mod_perl-1.21_03 - March 15, 2000.

As I understand, it was your answer in
http://www.gossamer-threads.com/lists/modperl/modperl/99700?search_string=registry%20status;#99700
:

> You also need to return the correct code from the handler. This is
> not simple to do from Registry. Have a quick look at the list
> archives for things related to Registry and 304/404 handling.

Why this should not be simple? Why this become a problem?
Lot of people had problems because of 'we need to reset status after running handler' decision.

WHY ?? WHY ?? WHY ??

http://www.gossamer-threads.com/lists/modperl/modperl/54154?search_string=registry%20status;#54154
is ever more interesting, but nothing changed for last decade.

> I think the gist of it is that some people make their Registry scripts set $r->status
because
> Registry doesn't scan the script output for a status header like mod_cgi does.

mod_cgi does such scan to set r->status by calling ap_scan_script_header_err_(buff|brigade|core)
and
does not scan nothing to produce OK in cgi_handler() 'return OK;' last line.

mod_perl does same scan by calling modperl_wbucket_pass() -> modperl_cgi_header_parse()
-> ap_scan_script_header_err_strs().

What do you think about how it runs the code like this:

  print "Status: 404 Not Found\n";
  print "Content-Type: text/html; charset=windows-1251\n\n";
  print 'NOTFOUND:' . '*' x 81;

This code works under mod_cgi and mod_perl both. $r->status was not set, right?
This code works, but it works differently, despite of ModPerl modules goal to "Run unaltered
CGI scripts under mod_perl".

>  However, that means Apache doesn't know what the real status is.
>  In order to tell Apache what the status is, Registry checks to see if you set $r->status
and
>  uses that as the return code, which may affect what status Apache decides to send.

 You mix handler status and response status again. These are different concepts.
 Why not leave r->status set by script execution? Moreover, r->status can be changed
by
 mod_perl.c/apache internals (when buffer flushed due to 8k overflow).

> I may be reading your use case incorrectly, but you seem to be trying to tell the server
you have
> a 200 OK but really return a 404.

No. As many other people I want send 404 (non-200/3xx) status into browser, and got problems
with this simple
task.

HTTP_OK and OK are different constants. I want to tell apache what mod_perl handler finished
it`s request processing, by returning OK code (0), not HTTP_OK (200). mod_cgi does this in
this way and I
want understand why mod_perl does not. Why not leave r->status untouched and return
Apache2::Const::OK in ModPerl::RegistryCooker default_handler() ?

http://www.gossamer-threads.com/lists/modperl/modperl/100810?search_string=registry%20status;#100810
- proposes this solution and was completely ignored!

Also, I described a problem I see: my browser get HTTP 200 status from two lines of
code script:

  print $q->header(-charset => "windows-1251", -type => "text/html", -status=>'404
Not Found');
  print "Sorry, page you requested does not exists.";

I think this abnormal. Did you?

This is because RegistryCooker 'reset the status after running handler' back to 200 (from
$old_status).

  r->status == 200 for 404 response - great!

Also, script output was appended by standard apache error page.
This was discussed many times too.

This was because when Registry return 404 (or other than 200) as handler status, then response
is
processed by apache as error.

When status is 200 $old_status == $new_status and $rc is returned in RegistryCooker.pm and
things
works correctly. Note, there will be $rc == Apache2::Const::OK, not HTTP_OK!

Look into httpd-2.2.27/modules/http/http_request.c:258, ap_process_request():

    access_status = ap_invoke_handler(r);
    if (access_status == DONE) {
        access_status = OK;
    }

    if (access_status == OK) {
        ap_finalize_request_protocol(r);    <---- Should be here in all non-error cases
    }
    else {
        r->status = HTTP_OK;
        ap_die(access_status, r);           <----- But ALL NON-200 handler status, such
as 3xx, 4xx, will be processed here
    }

And ap_die() also adds 'custom_response' which is is not needed and can break things - I described
this detailed.

> I may be reading your use case incorrectly, but you seem to be trying to tell the server
you have
> a 200 OK but really return a 404. That's discussed a little bit here:
> http://perl.apache.org/docs/2.0/api/Apache2/RequestRec.html#C_status_.

That description is wrong too, because it is about implementation which mixes request status
and
handler status together. Typical apache module uses three constants for handler status:

  #define DECLINED -1     /**< Module declines to handle */
  #define DONE -2         /**< Module has served the response completely.
                            *  - it's safe to die() with no more output
                           */
  #define OK 0            /**< Module has handled this stage. */

And this behavior is not a trick as written there, but the normal way - mod_cgi,mod_cgid examples
are good enough, I think.

> That is somewhat sophisticated for a Registry script, but you can always just make your
own subclass and override
> that method in RegistryCooker to do what you want.  It's intended to be customizable
in that way.

Sure, of course I know about this solution. It fully works for me.

I described in detail some cases when different problems occurs due RegistryCooker implementation.
Will we treat ModPerl Registry modules behaviour/implementation as a bug? Rhetorical question.

After reading mailing list I understand what nothing will change in nearest .... century.
Sorry to bother you.

-- 
Regards,
Pavel                          mailto:pavel2000@ngs.ru


---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@perl.apache.org
For additional commands, e-mail: dev-help@perl.apache.org


Mime
View raw message