abw / Template2

Perl Template Toolkit v2
http://template-toolkit.org/
146 stars 94 forks source link

Template fails when used in a cgi script with method POST #264

Closed davidlai-webstandard closed 4 years ago

davidlai-webstandard commented 4 years ago

This is a very simple CGI script:

#!/usr/bin/perl

use strict;
use warnings;
use Template;

print "Content-type: text/plain\n\n";
print "OK\n";
exit(0);

This script "use Template" however the code doesnt actually use any of the Template functions. When I do a GET on the script (via wget or browser) it works fine (I get an OK). But if I POST to the script it fails on the server and I get nothing returned. Now the interesting part is if I comment out the "use Template;" - then the script works fine with GET and POST. Tested using the wget command to test a POST: wget --post-data=x=y $URL_TO_THE_SCRIPT.

Also on the server in the error log I see this: [Mon Apr 27 04:45:59.391316 2020] [core:error] [pid 27091:tid 140068505233152] (104)Connection reset by peer: [client 100.64.1.92:55696] AH00574: ap_content_length_filter: apr_bucket_read() failed

To me it seems that theres something going wrong inside the Template module because simply including the statement "use Template;" will cause the cgi script (which doesnt even use any Template functions) to fail on POST.

Anyone else seen this problem? Let me know if you need additional data. Server is a centos8 system with all recent updates. This package was installed: perl-Template-Toolkit-2.29-3.el8.x86_64 and perl is 5.26.3

davidlai-webstandard commented 4 years ago

I've traced this problem to Template::Provider. Just including Template::Provider is enough to trigger this problem. This code will exhibit the same POST error and narrows the problem to the one module:

#!/usr/bin/perl

use strict;
use warnings;
use Template::Provider;

print "Content-type: text/plain\n\n";
print "OK\n";
exit(0);

The problem also goes away if I comment out line 29 of Template.pm as follows:

[vendor_perl]# pwd
/usr/lib64/perl5/vendor_perl
[vendor_perl]# diff Template.pm.orig Template.pm
29c29
< use Template::Provider;
---
> # use Template::Provider;  # this is the problem

Of course these brute-force changes will likely lead to other issues; but this is strictly for testing only to try to narrow down this problem. Theres no way I'm advocating this as a patch.

At this point it appears that merely including the Tempate::Provider module will cause http POST to fail on a CGI script.

davidlai-webstandard commented 4 years ago

Ok - I'm gonna close this bug report. After doing a bunch of additional tracing it appears there is a problem with apache httpd POST to a cgi script if that script doesnt consume the POST data - and it manifests itself in strange ways when Template is being included into the script. Additional tracing showed that the problem happens AFTER the script finishes running, I was trying to find problems before the script runs. Anyways it seems that once the POST data is consumed (ie. with a CGI parse_form_data or equivalent) then the problems disappear. Anyways I suspect theres some weirdness in some of the atexit() type procedures included with Template if the POST data is not already consumed - which triggers assorted error messages from apache httpd. Drop me a message if you want to discuss further or want some of my test scripts to reproduce the problem on your end. Thanks.