2 # {{{ BEGIN BPS TAGGED BLOCK
6 # This software is Copyright (c) 1996-2004 Best Practical Solutions, LLC
7 # <jesse@bestpractical.com>
9 # (Except where explicitly superseded by other copyright notices)
14 # This work is made available to you under the terms of Version 2 of
15 # the GNU General Public License. A copy of that license should have
16 # been provided with this software, but in any event can be snarfed
19 # This work is distributed in the hope that it will be useful, but
20 # WITHOUT ANY WARRANTY; without even the implied warranty of
21 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
22 # General Public License for more details.
24 # You should have received a copy of the GNU General Public License
25 # along with this program; if not, write to the Free Software
26 # Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
29 # CONTRIBUTION SUBMISSION POLICY:
31 # (The following paragraph is not intended to limit the rights granted
32 # to you to modify and distribute this software under the terms of
33 # the GNU General Public License and is only of importance to you if
34 # you choose to contribute your changes and enhancements to the
35 # community by submitting them to Best Practical Solutions, LLC.)
37 # By intentionally submitting any modifications, corrections or
38 # derivatives to this work, or any other work intended for use with
39 # Request Tracker, to Best Practical Solutions, LLC, you confirm that
40 # you are the copyright holder for those contributions and you grant
41 # Best Practical Solutions, LLC a nonexclusive, worldwide, irrevocable,
42 # royalty-free, perpetual, license to use, copy, create derivative
43 # works based on those contributions, and sublicense and distribute
44 # those contributions and any derivatives thereof.
46 # }}} END BPS TAGGED BLOCK
49 mason_handler.svc - Win32 IIS Service handler for RT
53 perl mason_handler.svc --install # install as service
54 perl mason_handler.svc --deinstall # deinstall this service
55 perl mason_handler.svc --help # show this help
56 perl mason_handler.svc # launch handler from command line
60 This script manages a stand-alone FastCGI server, and populates the necessary
61 registry settings to run it with Microsoft IIS Server 4.0 or above.
63 Before running it, you need to install the B<FCGI> module from CPAN, as well as
64 B<Win32::Daemon> from L<http://www.roth.net/perl/Daemon/> if you want to install
67 This script will automatically create a virtual directory under the IIS root;
68 its name is taken from C<$WebPath> in the F<RT_Config.pm> file. Additionally,
69 please install the ISAPI binary from L<http://www.caraveo.com/fastcgi/> and set
70 up an ISAPI Script Map that maps F<.html> files to F<isapi_fcgi.dll>.
72 Once the service is launched (either via C<net start RTFastCGI> or by running
73 C<perl mason_handler.svc>), a FCGI server will start and bind to port C<8284>
74 (mnemonics: the ASCII value of C<R> and C<T>); the ISAPI handler's C<BindPath>
75 registry setting will also be automatically populated.
84 require (dirname(__FILE__) . '/webmux.pl');
92 use Win32::TieRegistry;
98 Win32::Process::Create(
99 $ProcessObj, $^X, "$^X $0 --run", 0, NORMAL_PRIORITY_CLASS, "."
101 die Win32::FormatMessage( Win32::GetLastError() );
104 chdir File::Basename::dirname($0);
105 my $path = Cwd::cwd();
107 $path =~ s|bin$|share\\html|;
109 $Win32::TieRegistry::Registry->{
110 'HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\\'.
111 'W3SVC\Parameters\Virtual Roots\\'
112 }->{$RT::WebPath || '/'} = "$path,,205";
114 $Win32::TieRegistry::Registry->{
115 'HKEY_LOCAL_MACHINE\Software\FASTCGI\.html\\'
116 }->{'BindPath'} = $ENV{'FCGI_SOCKET_PATH'};
118 Win32::Service::StartService(Win32::NodeName, 'W3SVC');
121 if ($ARGV[0] eq '--deinstall') {
122 chdir File::Basename::dirname($0);
123 my $path = Cwd::cwd();
126 require Win32::Daemon;
127 Win32::Daemon::DeleteService('RTFastCGI');
128 warn "Service 'RTFastCGI' successfully deleted.\n";
131 elsif ($ARGV[0] eq '--install') {
132 chdir File::Basename::dirname($0);
133 my $path = Cwd::cwd();
136 require Win32::Daemon;
137 Win32::Daemon::DeleteService('RTFastCGI');
139 my $rv = Win32::Daemon::CreateService( {
142 display => 'RT FastCGI Handler',
146 description => 'Enables port 8284 as the RT FastCGI handler.',
147 parameters => File::Spec->catfile(
148 $path, File::Basename::basename($0)
153 warn "Service 'RTFastCGI' successfully created.\n";
156 warn "Failed to add service: " . Win32::FormatMessage(
157 Win32::Daemon::GetLastError()
162 elsif ($ARGV[0] eq '--service') {
163 require Win32::Daemon;
165 my $PrevState = Win32::Daemon::SERVICE_START_PENDING();
166 Win32::Daemon::StartService() or die $^E;
169 my $State = Win32::Daemon::State();
170 last if $State == Win32::Daemon::SERVICE_STOPPED();
172 if ( $State == Win32::Daemon::SERVICE_START_PENDING() ) {
174 Win32::Daemon::State( Win32::Daemon::SERVICE_RUNNING() );
175 $PrevState = Win32::Daemon::SERVICE_RUNNING();
177 elsif ( $State == Win32::Daemon::SERVICE_CONTINUE_PENDING() ) {
179 Win32::Daemon::State( Win32::Daemon::SERVICE_RUNNING() );
180 $PrevState = Win32::Daemon::SERVICE_RUNNING();
182 elsif ( $State == Win32::Daemon::SERVICE_STOP_PENDING() ) {
183 $ProcessObj->Kill(0);
184 Win32::Daemon::State( Win32::Daemon::SERVICE_STOPPED() );
185 $PrevState = Win32::Daemon::SERVICE_STOPPED();
187 elsif ( $State == Win32::Daemon::SERVICE_RUNNING() ) {
188 my $Message = Win32::Daemon::QueryLastMessage(1);
189 if ( $Message == Win32::Daemon::SERVICE_CONTROL_INTERROGATE() ) {
190 Win32::Daemon::State( $PrevState );
192 elsif ( $Message == Win32::Daemon::SERVICE_CONTROL_SHUTDOWN() ) {
193 Win32::Daemon::State( Win32::Daemon::SERVICE_STOP_PENDING(), 15000 );
195 elsif ( $Message != Win32::Daemon::SERVICE_CONTROL_NONE() ) {
196 Win32::Daemon::State( $PrevState );
200 Win32::Sleep( 1000 );
203 Win32::Daemon::StopService();
206 elsif ($ARGV[0] eq '--help') {
207 system("perldoc $0");
210 elsif ($ARGV[0] ne '--run') {
211 $SIG{__DIE__} = sub { $ProcessObj->Kill(0) if $ProcessObj };
213 warn "RT FastCGI Handler launched. Press [Enter] to terminate...\n";
219 ###############################################################################
221 warn "Begin listening on $ENV{'FCGI_SOCKET_PATH'}\n";
228 while( my $cgi = CGI::Fast->new ) {
229 my $comp = $ENV{'PATH_INFO'};
231 $comp = $1 if ($comp =~ /^(.*)$/);
232 $comp =~ s|^$RT::WebPath\b||i;
233 $comp .= "index.html" if ($comp =~ /\/$/);
234 $comp =~ s/.pl$/.html/g;
236 warn "Serving $comp\n";
238 $Handler->handle_cgi($comp);
239 # _should_ always be tied
246 Autrijus Tang E<lt>autrijus@autrijus.orgE<gt>
250 Copyright 2002 by Autrijus Tang E<lt>autrijus@autrijus.orgE<gt>.
252 This program is free software; you can redistribute it and/or
253 modify it under the same terms as Perl itself.
255 See L<http://www.perl.com/perl/misc/Artistic.html>