Beefy Boxes and Bandwidth Generously Provided by pair Networks
XP is just a number
 
PerlMonks  

Re: CGI: write exactly "\r\n" to end the headers, then turn off binmode

by choroba (Cardinal)
on Mar 09, 2018 at 09:33 UTC ( [id://1210554]=note: print w/replies, xml ) Need Help??


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,

Replies are listed 'Best First'.
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.
      what server? What version cgi.pm? You can create cgi objects without it reading fom stdin.

        what server? What version cgi.pm? You can create cgi objects without it reading fom stdin.

        1. I'm experimenting with an Erlang inets httpd server. If you install Erlang, I can give you the code to start a server.
        2. ~$ 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>

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: note [id://1210554]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others studying the Monastery: (2)
As of 2024-06-19 07:08 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found

    Notices?
    erzuuli‥ 🛈The London Perl and Raku Workshop takes place on 26th Oct 2024. If your company depends on Perl, please consider sponsoring and/or attending.