From: Byrne R. <by...@ma...> - 2008-01-02 18:36:32
|
Ok, so I am writing not as a developer, but as a user. I was hoping that even though I have the programming skilz, that someone might help me out - after all, these days I am more of a product manager, then I am an engineer. Here is an excerpt from a bug with Movable Type (the product I am the PM for) - the bug being described is that XML-RPC will NOT work under mod_perl or FastCGI. :-(. I am looking for help in addressing the root cause of this problem, in addition to guidance on the best short term workaround. From lib/MT/XMLRPCServer.pm, line 21 (the line where the error occurs): $main::server->serializer->encoding('UTF-8'); When running under mod_perl, the $main::server variable is undefined (does not exist) for a number of reasons: 1. Scripts run under mod_perl are not run under package "main". 2. Under mod_perl, the mt-xmlrpc.cgi script is never executed. The mt-xmlrpc.cgi script defines a public $server variable when XMLRPC is run as a CGI script; mod_perl creates and initializes a $server instance through the Apache::XMLRPC::Lite perl module. 3. The Apache::XMLRPC::Lite perl module does not expose its $server variable, making it inaccessible to any code outside of the Apache::XMLRPC::Lite perl module. Because there is no $server variable available or accessible when Movable Type is configured to run XMLRPC under mod_perl, the code at line 21 in XMLRPCServer.pm makes it impossible to run Movable Type's XMLRPC under mod_perl. There appears to be a number of ways this issue could be addressed, but I am not sure if any of them are particularly good nor which one might be the best: 1. The Apache::XMLRPC::Lite code could be modified so that the $server variable it defines is a public variable rather than a private one. From /extlib/Apache/XMLRPC/Lite.pm, line 20: my $server = __PACKAGE__->new; This variable could be made a public one, in the same way the $server variable defined in the mt-xmlrpc.cgi script is defined as a public variable: use vars qw($server); $server = __PACKAGE__->new; With above change in the Apache::XMLRPC::Lite code, the code at line 21 in XMLRPCServer.pm could then be modified to allow the encoding to be set for the $server instance under both CGI and mod_perl: if ($ENV{MOD_PERL}) { $Apache::XMLRPC::Lite::server->serializer->encoding('UTF-8'); } else { $main::server->serializer->encoding('UTF-8'); } 2. If it is not desirable to modify the Apache::XMLRPC::Lite code, the Apache::XMLRPC::Lite class could be subclassed in the XMLRPCServer.pm module and within the subclass, define a $server variable which would be publicly available to other classes. Because the Apache::XMLRPC::Lite perl module contains so little code, it takes about the same amount of code to subclass Apache::XMLRPC::Lite as it does to just reimplement it in XMLRPCServer.pm. I added the following code at the beginning of XMLRPCServer.pm to reimplement the functionality provided by Apache::XMLRPC::Lite, and allow the $server variable to be accessible to other classes: package MT::XMLRPCServer::Lite; use strict; use XMLRPC::Transport::HTTP; use base qw( XMLRPC::Transport::HTTP::Apache ); use vars qw($server); $server = __PACKAGE__->new; sub handler { $server->configure(@_); $server->SUPER::handler(@_); } The mod_perl configuration was modified in the Apache httpd.conf file to use the new MT::XMLRPC::Lite class instead of Apache::XMLRPC::Lite: PerlModule MT::XMLRPCServer <Location /mt/xmlrpc> SetHandler perl-script PerlHandler MT::XMLRPCServer::Lite PerlSetVar dispatch_to "blogger, metaWeblog, mt" PerlSetVar MTConfig 'C:/Apache/www/MT-4.01-en/mt-config.cgi' PerlSetEnv MT_CONFIG 'C:/Apache/www/MT-4.01-en/mt-config.cgi' </Location> With above changes to XMLRPCServer.pm and the mod_perl configuration in the Apache httpd.conf file, the code at line 21 in XMLRPCServer.pm could then be modified to allow the encoding to be set for the $server instance under both CGI and mod_perl: if ($ENV{MOD_PERL}) { $MT::XMLRPCServer::Lite::server->serializer->encoding('UTF-8'); } else { $main::server->serializer->encoding('UTF-8'); } |