> On Wed, 14 Mar 2001, Perrin Harkins wrote:
>
> > On Wed, 14 Mar 2001, Issac Goldstand wrote:
> > >   I still think that the above line is confusing:  It is
> because mod_perl is
> > > not sending headers by itelf, but rather your script must provide the
> > > headers (to be returned by mod_perl).  However, when you just
> say "mod_perl
> > > will send headers" it is misleading; it seems to indeicate
> that mod_perl
> > > will send "Content-Type: text/html\r\n\r\n" all by itself, and that
> > > conversely, to disable that PerlSendHeaders should be Off.
> >
> > Would it help if it said "PerlSendHeader On makes mod_perl act just like
> > CGI with regard to headers"?
>
> A small correction: "PerlSendHeader On makes mod_perl act just like
> mod_cgi with regard to HTTP headers" :)
>
> CGI is a protocol...

Hmm.  What nobody seems to be mentioning explicitly (for the newbees who
would benefit from this discussion) are the things that
mod_cgi/PerlSendHeaders *DO*, that otherwise would have to be done manually.

Or, to put it more succinctly, what is the *exact* difference in headers
between PerlSendHeaders On and Off (which happen to be the same difference
as between a regular CGI script and an NPH script)?

It seems like almost all of the available documentation assumes that A) you
already know, or B) you don't need to know.

So at the risk of seeming bold, and understanding that this summary *is*
going to be incomplete:

There is a similarity of requirements between a CGI nph-script (Non Parsed
Headers) and mod_perl with PerlSendHeaders Off.

In basic CGI, one can simply:
print "Content-Type: text/html\r\n\r\n";

When the CGI script goes back to the web server, it can see from this
output, destined for the client browser, that:
The request was successful
The content type is specified
There is nothing further special about this request.

On (one of) my machines this returns:
HTTP/1.1 200 OK
Connection: close
Date: Thu, 15 Mar 2001 19:09:23 GMT
Server: Apache/1.3.3 (Unix)  (Red Hat/Linux) mod_perl/1.19
Content-Type: text/html
Client-Date: Thu, 15 Mar 2001 19:09:24 GMT
Client-Peer: xx.xx.xx.xx:80

This is actually pretty boring so far.  I could send a cookie, too:
print "Set-Cookie: mycookie=test\r\n";
print "Content-Type: text/html\r\n\r\n";

Or any other headers I want, and the remainder is filled in by the webserver
for me.

But some magic happens when I want to, say, redirect.  Instead of printing
my content-type header,  all I have to do is print the following instead:
"Location: http://elsewhere.com\r\n\r\n";

Look what happens to the response!
HTTP/1.1 302 Found
Date: <same>
Server: <same>
Location: http://elsewhere.com
Connection: close
Content-Type: text/html

I have a different status line altogether (along with the Location: that I
printed)!  One can arbitrarily send custom status codes, too... I've done
this with CGI form re-submits:
print "Status: 204 No Content\r\n\r\n";

This returns:
HTTP/1.1 204 No Content
Date: Thu, 15 Mar 2001 19:22:21 GMT
Server: Apache/1.3.3 (Unix)  (Red Hat/Linux) mod_perl/1.19
Connection: close
Content-Type: text/plain

Which is an expensive NO-OP to a browser. No change in window content
WHATSOEVER. (I love that trick.  Just love it! :-)

*NOW*
In mod_perl with PerlSendHeader Off, in order to perform a redirect one must
set up the headers manually:
Test.pm
=======
package Test;

use Apache::Constants qw/:common REDIRECT/;
use strict;

sub handler() {
    my $r = shift;
    $r->content_type('text/html');
    $r->headers_out->set(Location => "http://elsewhere.com");
    return REDIRECT;
}

1;
========
REDIRECT here is a constant for the HTTP status code 302 (Moved).


But with PerlSendHeader On, I can take the same shortcuts as with CGI:

sub handler() {
    print "Location: http://elsewhere.com\r\n\r\n";
}

And the response:
HTTP/1.1 302 Found
Date: Thu, 15 Mar 2001 19:32:10 GMT
Server: Apache/1.3.9 (Unix)  (Red Hat/Linux) mod_perl/1.21
Location: http://elsewhere.com
Connection: close
Content-Type: text/plain

But THE *SAME* CODE with PerlSendHeader Off returns:
Location: http://elsewhere.com

And that's *IT*.  Which parses as HTTP/0.9 and text/plain, causing my
browser to show that single line of text as my content.



NOW... to any non-newbies reading this, what have I left out? :-)

L8r,
Rob

#!/usr/bin/perl -w
use Disclaimer qw/:standard/;

Reply via email to