Skip Menu |

Preferred bug tracker

Please visit the preferred bug tracker to report your issue.

This queue is for tickets about the CGI CPAN distribution.

Report information
The Basics
Id: 12909
Status: resolved
Priority: 0/
Queue: CGI

People
Owner: MARKSTOS [...] cpan.org
Requestors: riQyRoe [...] skeptix.org
Cc:
AdminCc:

Bug Information
Severity: Normal
Broken in: (no value)
Fixed in: (no value)



Subject: http and https don't work correctly
I just checked the latest version (3.10) source code and the two subs http and https still won't work properly. :-) Explanations and corrected examples follow: # ORIGINAL sub http { my ($self,$parameter) = self_or_CGI(@_); # emits a warning under -w if no parameter supplied return $ENV{$parameter} if $parameter=~/^HTTP/; # emits a warning under -w if no parameter supplied $parameter =~ tr/-/_/; return $ENV{"HTTP_\U$parameter\E"} if $parameter; # that's a lot of work just to re-implement the built-in grep command my(@p); foreach (keys %ENV) { # captures HTTPS variables as well push(@p,$_) if /^HTTP/; } return @p; } # CORRECTED VERSION sub http { my ($self,$parameter) = self_or_CGI(@_); if (defined $parameter) { $parameter =~ tr/-a-z/_A-Z/; return $ENV{$parameter} if $parameter =~ /^HTTP(?:_|$)/; # I don't actually know of any webserver that sets this # but it provides consistency with https return $ENV{HTTP} if $parameter eq ''; return $ENV{"HTTP_$parameter"}; } return grep { /^HTTP(?:_|$)/ } keys %ENV; } # ORIGINAL sub https { # this should've been an indication U were doing something wrong local($^W)=0; my ($self,$parameter) = self_or_CGI(@_); # guess U didn't need to turn off warnings after all # since U return right away, but what about the HTTPS_ # variables? e.g. HTTPS_KEYSIZE return $ENV{HTTPS} unless $parameter; return $ENV{$parameter} if $parameter=~/^HTTPS/; $parameter =~ tr/-/_/; return $ENV{"HTTPS_\U$parameter\E"} if $parameter; # oh good, let's re-implement grep again my(@p); foreach (keys %ENV) { push(@p,$_) if /^HTTPS/; } return @p; } # CORRECTED VERSION sub https { my ($self,$parameter) = self_or_CGI(@_); if (defined $parameter) { $parameter =~ tr/-a-z/_A-Z/; return $ENV{$parameter} if $parameter =~ /^HTTPS(?:_|$)/; return $ENV{HTTPS} if $parameter eq ''; return $ENV{"HTTPS_$parameter"}; } return grep { /^HTTPS(?:_|$)/ } keys %ENV; }
Thanks for the report. Could you submit a Test::More-style test that illustrates some cases where the original code exhibits a wron behavior, and the new code works as desired? Mark On Fri May 20 18:22:39 2005, guest wrote: Show quoted text
> I just checked the latest version (3.10) source code and the two > subs http and https still won't work properly. :-) Explanations and > corrected examples follow: > > # ORIGINAL > sub http { > my ($self,$parameter) = self_or_CGI(@_); > # emits a warning under -w if no parameter supplied > return $ENV{$parameter} if $parameter=~/^HTTP/; > # emits a warning under -w if no parameter supplied > $parameter =~ tr/-/_/; > return $ENV{"HTTP_\U$parameter\E"} if $parameter; > # that's a lot of work just to re-implement the built-in grep command > my(@p); > foreach (keys %ENV) { > # captures HTTPS variables as well > push(@p,$_) if /^HTTP/; > } > return @p; > } > # CORRECTED VERSION > sub http { > my ($self,$parameter) = self_or_CGI(@_); > if (defined $parameter) { > $parameter =~ tr/-a-z/_A-Z/; > return $ENV{$parameter} if $parameter =~ /^HTTP(?:_|$)/; > # I don't actually know of any webserver that sets this > # but it provides consistency with https > return $ENV{HTTP} if $parameter eq ''; > return $ENV{"HTTP_$parameter"}; > } > return grep { /^HTTP(?:_|$)/ } keys %ENV; > } > > # ORIGINAL > sub https { > # this should've been an indication U were doing something wrong > local($^W)=0; > my ($self,$parameter) = self_or_CGI(@_); > # guess U didn't need to turn off warnings after all > # since U return right away, but what about the HTTPS_ > # variables? e.g. HTTPS_KEYSIZE > return $ENV{HTTPS} unless $parameter; > return $ENV{$parameter} if $parameter=~/^HTTPS/; > $parameter =~ tr/-/_/; > return $ENV{"HTTPS_\U$parameter\E"} if $parameter; > # oh good, let's re-implement grep again > my(@p); > foreach (keys %ENV) { > push(@p,$_) if /^HTTPS/; > } > return @p; > } > # CORRECTED VERSION > sub https { > my ($self,$parameter) = self_or_CGI(@_); > if (defined $parameter) { > $parameter =~ tr/-a-z/_A-Z/; > return $ENV{$parameter} if $parameter =~ /^HTTPS(?:_|$)/; > return $ENV{HTTPS} if $parameter eq ''; > return $ENV{"HTTPS_$parameter"}; > } > return grep { /^HTTPS(?:_|$)/ } keys %ENV; > }
Warnings: good point, has been fixed on github (http://github.com/rhesa/CGI.pm/commit/1c83470b7b43454adfc7f06ec36f70517c91ef91). http() returning https variables: good point, also fixed on github. http() not as case-insensitive as the docs say: fixed. https() needs to return $ENV{HTTPS} in scalar context, because C<$cgi->https eq 'ON'> is an established pattern (see e.g. the protocol() implementation, but I've also seen it in the wild). My github patch recommends using wantarray to decide what to return, so that C<my @ssl = $cgi->https()> returns all the https keys.
Thanks, this patch has now been applied in my git repo.
Subject: Thanks, released
The patch for this ticket has now been released in CGI.pm 3.47, and this ticket is considered resolved. Thanks again for you help to improve CGI.pm! Mark