in reply to CGI: newlines, write exactly "\r\n" to end the headers, then turn off binmode
As documented, binmode can take a LAYER argument, which can be even :crlf or whatever you like.
In a CGI script, you usually don't need to care about ending the headers. Just use the $cgi->header(...) method correctly.
($q=q:Sq=~/;[c](.)(.)/;chr(-||-|5+lengthSq)`"S|oS2"`map{chr |+ord
}map{substrSq`S_+|`|}3E|-|`7**2-3:)=~y+S|`+$1,++print+eval$q,q,a,
Re: CGI: newlines, write exactly "\r\n" to end the headers, then turn off binmode
by 7stud (Deacon) on Mar 09, 2018 at 11:07 UTC
|
Thanks for the responses.
In a CGI script, you usually don't need to care about ending the headers. Just use the $cgi->header(...) method correctly.
In my case, I can't do that. I'm trying to read some simple json data in the body of a post request, but $cgi->{POSTDATA} gives me inconsistent results depending on my server. With an apache server, POSTDATA successfully contains the json. However, I tried my perl script on another server, and POSTDATA returns undef. To solve that issue, I'm reading from STDIN directly. I looked at the source code for CGI.pm, and I don't understand why CGI.pm fails to read the json while executing on my non-apache server, because I can get the json when I read from STDIN directly doing this:
(The cgi spec requires that a script not try to read more than Content-Length from STDIN.)
#!/usr/bin/env perl
use strict;
use warnings;
use 5.020;
use autodie;
use Data::Dumper;
use JSON;
if (my $content_len = $ENV{CONTENT_LENGTH}) {
read(STDIN, my $json, $content_len); #<===HERE ************
my $href = decode_json($json);
my $a = $href->{a};
my $b = $href->{b};
print 'Content-type: text/html';
print "\r\n\r\n";
print "<div>a=$a</div>";
print "<div>b=$b</div>";
}
else {
my $error = "Could not read json: No Content-Length header in requ
+est.";
print 'Content-type: text/html';
print "\r\n\r\n";
print "<div>$error</div>";
}
And, once I read from STDIN directly, then none of perl's CGI functionality works.
| [reply] [d/l] [select] |
|
what server? What version cgi.pm? You can create cgi objects without it reading fom stdin.
| [reply] |
|
what server? What version cgi.pm? You can create cgi objects without it reading fom stdin.
- I'm experimenting with an Erlang inets httpd server. If you install Erlang, I can give you the code to start a server.
- ~$ perl -MCGI -e 'print "$CGI::VERSION\n";' => 4.38
You can create cgi objects without it reading fom stdin.
When I create a cgi object after reading from STDIN, my curl request to my Erlang server for the cgi script hangs, then times out (but it does succeed on my apache server):
#!/usr/bin/env perl
use strict;
use warnings;
use 5.020;
use autodie;
use Data::Dumper;
use JSON;
use CGI;
use CGI::Carp qw(fatalsToBrowser);
if (my $content_len = $ENV{CONTENT_LENGTH}) {
read(STDIN, my $json, $content_len);
my $href = decode_json($json);
my $a = $href->{a};
my $b = $href->{b};
my $q = CGI->new; #Doesn't work with inets httpd server
print $q->header,
$q->start_html("Test Page"),
$q->div("json=$json"),
$q->div("a=$a"),
$q->div("b=$b"),
$q->end_html;
#print 'Content-type: text/html';
#print "\r\n\r\n";
#print "<div>a=$a</div>";
#print "<div>b=$b</div>";
}
else {
my $error = "Could not read json: No Content-Length header in requ
+est.";
#print 'Content-type: text/html';
#print "\r\n\r\n";
#print "<div>$error</div>";
my $q = CGI->new;
print $q->header,
$q->start_html("Test Page"),
$q->h1($error),
$q->end_html;
}
If I comment out the $q lines and uncomment the other print statements, then my curl request succeeds.
Failed curl request:
~$ curl -v -H 'Content-Type: application/json' --data '{"a": 1, "b": 2
+}' http://localhost:65451/cgi-bin/1.pl
* Trying ::1...
* TCP_NODELAY set
* Connection failed
* connect to ::1 port 65451 failed: Connection refused
* Trying 127.0.0.1...
* TCP_NODELAY set
* Connected to localhost (127.0.0.1) port 65451 (#0)
> POST /cgi-bin/1.pl HTTP/1.1
> Host: localhost:65451
> User-Agent: curl/7.58.0
> Accept: */*
> Content-Type: application/json
> Content-Length: 16
>
* upload completely sent off: 16 out of 16 bytes
==== Hangs here for about 5 sseconds =======
< HTTP/1.1 504 Gateway Time-out
< Date: Fri, 09 Mar 2018 14:40:55 GMT
< Content-Type: text/html
< Server: inets/6.4.5
* no chunk, no close, no size. Assume close to signal end
<
* Closing connection 0
~$
Succesful curl request:
~$ curl -v -H 'Content-Type: application/json' --data '{"a": 1, "b": 2
+}' http://localhost:65451/cgi-bin/1.pl
* Trying ::1...
* TCP_NODELAY set
* Connection failed
* connect to ::1 port 65451 failed: Connection refused
* Trying 127.0.0.1...
* TCP_NODELAY set
* Connected to localhost (127.0.0.1) port 65451 (#0)
> POST /cgi-bin/1.pl HTTP/1.1
> Host: localhost:65451
> User-Agent: curl/7.58.0
> Accept: */*
> Content-Type: application/json
> Content-Length: 16
>
* upload completely sent off: 16 out of 16 bytes
< HTTP/1.1 200 OK
< Date: Fri, 09 Mar 2018 14:52:03 GMT
< Server: inets/6.4.5
< Transfer-Encoding: chunked
< Content-Type: text/html
<
* Connection #0 to host localhost left intact
<div>a=1</div><div>b=2</div>~$
</div>
| [reply] [d/l] [select] |
|
|
|
|