Score:0

Why is my browser displaying the Content-Type line?

ge flag

Following what's described here --- https://httpd.apache.org/docs/2.4/howto/cgi.html --- I've created a tiny Perl document:

#!/usr/bin/perl
print "Content-Type: text/html; charset=utf-8\n\n";
print "Hello, World.";

and called it first.pl. I've also modified it so that it looks like

#!/usr/bin/perl
print "Content-Type: text/html; charset=utf-8\r\n\r\n";
print "Hello, World.";

because a friend pointed out that the meaning of "\n" is system-dependent, and what's required is CR-LF CR-LF, but the results are the same.)

When I look at localhost/~mylogin/first.pl from the Chrome browser I get the following output:

Content-Type: text/html; charset=utf-8

Hello, World.

(The ; charset=... stuff is a slight modification of what the Apache docs suggest, because leaving it off also produced a Content-Type line of output, and some searching suggested that the charset thing might be important. As it happened, it made no difference.)

The references Apache docs say "wherever you put your file, you will see the one line Hello, World. appear in your browser window. "

Clearly, I'm seeing two lines, the first of which should have been merely treated as description of the remaining content, and I think that's a problem.

I'm hoping that this is some really basic mistake, and would appreciate any suggestions.

Context

I'm on a Mac running Monterey 12.6.6

I got started following instructions from here.

Starting from the vanilla httpd.conf file, I've made just a few edits, uncommenting the following:

LoadModule perl_module libexec/apache2/mod_perl.so
LoadModule userdir_module libexec/apache2/mod_userdir.so
Include /private/etc/apache2/extra/httpd-userdir.conf

And in /etc/apache2/extra/httpd-userdir.conf, I've uncommented

Include /private/etc/apache2/users/*.conf

I've created /etc/apache2/users/mylogin.conf, and given it this content:

<Directory "/Users/mylogin/Sites/"> 
  AddLanguage en .en 
  AddHandler perl-script .pl 
  PerlHandler ModPerl::Registry 
  Options Indexes MultiViews FollowSymLinks ExecCGI 
  AllowOverride None 
  Require host localhost
</Directory>

I've run

chmod +a "_www allow execute" ~

[in all cases above, I've replaced "mylogin" with my actual login, of course]

And then, following instructions from Apache, I added this to the httpd.conf file:

<Directory "/Users/mylogin/Sites">
    Options +ExecCGI
    AddHandler cgi-script .cgi 
</Directory>
vn flag
Does it work fine when you **un**modify the line you changed?
John avatar
ge flag
Alas, no. Even using the apache-suggested `Content-type` rather than `Content-Type` (which is what the spec seems to require) and getting rid of `; charset=utf-8` doesn't seem to work, whether using `\n\n` or `\r\n\r\n`, unfortunately.
Score:2
jp flag

With AddHandler perl-script .pl, you do not run the script with mod_cgid (or mod_cgi) which the "Apache Tutorial: Dynamic Content with CGI" is about, but with mod_perl. While both can run Perl scripts, it is the CGI that expects the script to first send headers separated by \n\n from the body.

You can see the difference by switching between these configurations:

mod_perl

LoadModule perl_module /usr/lib/apache2/modules/mod_perl.so

<Directory "/Users/mylogin/Sites/">
  Options +ExecCGI
  AddHandler perl-script .pl
  PerlHandler ModPerl::Registry
</Directory>

Produces:

< HTTP/1.1 200 OK
< Server: Apache/2.4.41
< Transfer-Encoding: chunked
< Content-Type: text/x-perl
< 
Content-Type: text/html; charset=utf-8

Hello, World.

mod_cgid

LoadModule cgid_module /usr/lib/apache2/modules/mod_cgid.so

<Directory "/Users/mylogin/Sites/">
  Options +ExecCGI
  AddHandler cgi-script .pl
</Directory>

Produces:

< HTTP/1.1 200 OK
< Server: Apache/2.4.41
< Content-Length: 13
< Content-Type: text/html; charset=utf-8
< 
Hello, World.
John avatar
ge flag
Bless you! This (more or less) did the trick. I had to change your `LoadModule` to a different directory: `LoadModule cgid_module libexec/apache2/mod_cgid.so`, which I guessed from looking at the default `httpd.conf` file. And I had to add `Require host localhost` to make it work as well, which worries me a little when it comes to trying to reach this outside localhost...but that's a different problem for another day.
Score:0
ge flag

Following @Esa Jokinen's answer, I got things working, in the sense that loading http://localhost/~jfh/first.pl produced the expected one-line result, but I thought it'd be worth recording the final configuration state, because it required some slight fiddling.

To review: I got started following instructions from here.

Starting from the vanilla httpd.conf file, I've made just a few edits, uncommenting the following:

LoadModule perl_module libexec/apache2/mod_perl.so
LoadModule userdir_module libexec/apache2/mod_userdir.so
Include /private/etc/apache2/extra/httpd-userdir.conf

And in /etc/apache2/extra/httpd-userdir.conf, I've uncommented

Include /private/etc/apache2/users/*.conf

I've created /etc/apache2/users/jfh.conf, and given it this content:

LoadModule cgid_module libexec/apache2/mod_cgid.so

<Directory "/Users/jfh/Sites/">
  AddLanguage en .en
  Options Indexes MultiViews FollowSymLinks ExecCGI
  Options +ExecCGI
  AllowOverride None
  Require host localhost
  AddHandler cgi-script .pl
</Directory>

I've run

chmod +a "_www allow execute" ~

[in all cases above, my login is jfh, and if you want to copy this, you'll need to change that to your own login]

I did not make further edits to the httpd.conf file as described in my original question, but instead made the edits shown above in /etc/apache2/users/jfh.conf.

I hope this helps out someone else with comparable problems on a comparable system.

Finally, a concern I had about the difference between \r\n and \n in various perl versions seems to have been misplaced, for my first.pl file looks like this

#!/usr/bin/perl
print "Content-type: text/html\n\n";
print "Hello, World.";

and works fine (but I've also confirmed that it works fine when the \n\n is replaced with \r\n\r\n).

I sit in a Tesla and translated this thread with Ai:

mangohost

Post an answer

Most people don’t grasp that asking a lot of questions unlocks learning and improves interpersonal bonding. In Alison’s studies, for example, though people could accurately recall how many questions had been asked in their conversations, they didn’t intuit the link between questions and liking. Across four studies, in which participants were engaged in conversations themselves or read transcripts of others’ conversations, people tended not to realize that question asking would influence—or had influenced—the level of amity between the conversationalists.