Getting custom code out of CGI.pm
We have a custom site written in Perl that uses a slightly modified version of CGI.pm. During server updates, CGI.pm may be overwritten when it is updated. My goal is to be able to update the server without affecting the site - i.e. change the code that relies on the modified CGI.pm. Unfortunately I am not very familiar with Perl syntax or best practice.
Here is a diff of the modified CGI.pmn (line numbers are off from the most recent version of CGI.pm):
--- CGI.pm.orig Tue Nov 7 12:14:09 2006
+++ CGI.pm Tue Nov 7 12:13:29 2006
@@ -3386,7 +3386,7 @@ sub read_multipart {
if (defined $self->{'.upload_hook'})
{
$totalbytes += length($data);
- &{$self->{'.upload_hook'}}($filename ,$data, $totalbytes, $self->{'.upload_data'});
+ &{$self->{'.upload_hook'}}($filename ,$data, $totalbytes, $self->{'.upl开发者_StackOverflow中文版oad_data'}, $param, $header{'Content-Type'});
}
print $filehandle $data if ($self->{'use_tempfile'});
}
The code that relies on this diff follows:
my %file_hash = ();
my $page = new CGI(\&file_reader, \%file_hash, 0);
my $session = &get_session($page);
foreach my $param_name (keys %file_hash) {
my $notes_param = $param_name . "_notes";
&store_file($file_hash{$param_name}, $page->param($notes_param),
&get_session_name($session));
}
Without the diff, when the file is stored, the $param_name variable appears to be empty.
What is the best way to handle this? As I said before, my main goal is to simplify updates to the server; is there some way to either
a) (preferably) get %file_hash to work properly without a modified version of CGI.pm b) prevent updates to CGI.pm (and is this a bad idea)
Have you tried submitting this to the CGI RT as a desired improvement? It seems reasonable to pass $param
and \%header
(rather than $header{'Content-Type'}
) to the callback.
To answer your question, you could install CGI in a local directory. The directories in the PERL5LIB
env var are searched first, so your CGI version would be found instead of the one installed by the Ubuntu.
I'm the CGI.pm maintainer. I think there is a better option than using a local copy of CGI.pm. Instead, create a sub-class, and use the my subclass in your application. It would look like this:
package My::CGI;
use parent 'CGI';
sub my_sub_that_modified {
...
}
1;
So, you just need to copy in the subroutine that you modified. Then, when you upgrade CGI.pm, you likely don't need to touch your application, unless your modified subroutine changes.
With the "local lib" option, you would still need to manually merge in security updates and other changes you might want to into your local copy. The sub-class route minimizes that.
An example of this approach is Bugzilla::CGI which makes several changes in their sub-class.
精彩评论