4 # Copyright (c) 1996-2003 Jesse Vincent <jesse@bestpractical.com>
6 # (Except where explictly superceded by other copyright notices)
8 # This work is made available to you under the terms of Version 2 of
9 # the GNU General Public License. A copy of that license should have
10 # been provided with this software, but in any event can be snarfed
13 # This work is distributed in the hope that it will be useful, but
14 # WITHOUT ANY WARRANTY; without even the implied warranty of
15 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 # General Public License for more details.
18 # Unless otherwise specified, all modifications, corrections or
19 # extensions to this work which alter its source code become the
20 # property of Best Practical Solutions, LLC when submitted for
21 # inclusion in the work.
28 mason_handler.svc - Win32 IIS Service handler for RT
32 perl mason_handler.svc --install # install as service
33 perl mason_handler.svc --deinstall # deinstall this service
34 perl mason_handler.svc --help # show this help
35 perl mason_handler.svc # launch handler from command line
39 This script manages a stand-alone FastCGI server, and populates the necessary
40 registry settings to run it with Microsoft IIS Server 4.0 or above.
42 Before running it, you need to install the B<FCGI> module from CPAN, as well as
43 B<Win32::Daemon> from L<http://www.roth.net/perl/Daemon/> if you want to install
46 This script will automatically create a virtual directory under the IIS root;
47 its name is taken from C<$WebPath> in the F<RT_Config.pm> file. Additionally,
48 please install the ISAPI binary from L<http://www.caraveo.com/fastcgi/> and set
49 up an ISAPI Script Map that maps F<.html> files to F<isapi_fcgi.dll>.
51 Once the service is launched (either via C<net start RTFastCGI> or by running
52 C<perl mason_handler.svc>), a FCGI server will start and bind to port C<8284>
53 (mnemonics: the ASCII value of C<R> and C<T>); the ISAPI handler's C<BindPath>
54 registry setting will also be automatically populated.
60 require (dirname(__FILE__) . '/webmux.pl');
68 use Win32::TieRegistry;
74 Win32::Process::Create(
75 $ProcessObj, $^X, "$^X $0 --run", 0, NORMAL_PRIORITY_CLASS, "."
77 die Win32::FormatMessage( Win32::GetLastError() );
80 chdir File::Basename::dirname($0);
81 my $path = Cwd::cwd();
83 $path =~ s|bin$|share\\html|;
85 $Win32::TieRegistry::Registry->{
86 'HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\\'.
87 'W3SVC\Parameters\Virtual Roots\\'
88 }->{$RT::WebPath || '/'} = "$path,,205";
90 $Win32::TieRegistry::Registry->{
91 'HKEY_LOCAL_MACHINE\Software\FASTCGI\.html\\'
92 }->{'BindPath'} = $ENV{'FCGI_SOCKET_PATH'};
94 Win32::Service::StartService(Win32::NodeName, 'W3SVC');
97 if ($ARGV[0] eq '--deinstall') {
98 chdir File::Basename::dirname($0);
99 my $path = Cwd::cwd();
102 require Win32::Daemon;
103 Win32::Daemon::DeleteService('RTFastCGI');
104 warn "Service 'RTFastCGI' successfully deleted.\n";
107 elsif ($ARGV[0] eq '--install') {
108 chdir File::Basename::dirname($0);
109 my $path = Cwd::cwd();
112 require Win32::Daemon;
113 Win32::Daemon::DeleteService('RTFastCGI');
115 my $rv = Win32::Daemon::CreateService( {
118 display => 'RT FastCGI Handler',
122 description => 'Enables port 8284 as the RT FastCGI handler.',
123 parameters => File::Spec->catfile(
124 $path, File::Basename::basename($0)
129 warn "Service 'RTFastCGI' successfully created.\n";
132 warn "Failed to add service: " . Win32::FormatMessage(
133 Win32::Daemon::GetLastError()
138 elsif ($ARGV[0] eq '--service') {
139 require Win32::Daemon;
141 my $PrevState = Win32::Daemon::SERVICE_START_PENDING();
142 Win32::Daemon::StartService() or die $^E;
145 my $State = Win32::Daemon::State();
146 last if $State == Win32::Daemon::SERVICE_STOPPED();
148 if ( $State == Win32::Daemon::SERVICE_START_PENDING() ) {
150 Win32::Daemon::State( Win32::Daemon::SERVICE_RUNNING() );
151 $PrevState = Win32::Daemon::SERVICE_RUNNING();
153 elsif ( $State == Win32::Daemon::SERVICE_CONTINUE_PENDING() ) {
155 Win32::Daemon::State( Win32::Daemon::SERVICE_RUNNING() );
156 $PrevState = Win32::Daemon::SERVICE_RUNNING();
158 elsif ( $State == Win32::Daemon::SERVICE_STOP_PENDING() ) {
159 $ProcessObj->Kill(0);
160 Win32::Daemon::State( Win32::Daemon::SERVICE_STOPPED() );
161 $PrevState = Win32::Daemon::SERVICE_STOPPED();
163 elsif ( $State == Win32::Daemon::SERVICE_RUNNING() ) {
164 my $Message = Win32::Daemon::QueryLastMessage(1);
165 if ( $Message == Win32::Daemon::SERVICE_CONTROL_INTERROGATE() ) {
166 Win32::Daemon::State( $PrevState );
168 elsif ( $Message == Win32::Daemon::SERVICE_CONTROL_SHUTDOWN() ) {
169 Win32::Daemon::State( Win32::Daemon::SERVICE_STOP_PENDING(), 15000 );
171 elsif ( $Message != Win32::Daemon::SERVICE_CONTROL_NONE() ) {
172 Win32::Daemon::State( $PrevState );
176 Win32::Sleep( 1000 );
179 Win32::Daemon::StopService();
182 elsif ($ARGV[0] eq '--help') {
183 system("perldoc $0");
186 elsif ($ARGV[0] ne '--run') {
187 $SIG{__DIE__} = sub { $ProcessObj->Kill(0) if $ProcessObj };
189 warn "RT FastCGI Handler launched. Press [Enter] to terminate...\n";
195 ###############################################################################
197 warn "Begin listening on $ENV{'FCGI_SOCKET_PATH'}\n";
200 my $h = &RT::Interface::Web::NewCGIHandler(@RT::MasonParameters);
205 while( my $cgi = CGI::Fast->new ) {
206 my $comp = $ENV{'PATH_INFO'};
208 $comp = $1 if ($comp =~ /^(.*)$/);
209 $comp =~ s|^$RT::WebPath\b||i;
210 $comp .= "index.html" if ($comp =~ /\/$/);
211 $comp =~ s/.pl$/.html/g;
213 warn "Serving $comp\n";
215 $h->handle_cgi($comp);
216 # _should_ always be tied
223 Autrijus Tang E<lt>autrijus@autrijus.orgE<gt>
227 Copyright 2002 by Autrijus Tang E<lt>autrijus@autrijus.orgE<gt>.
229 This program is free software; you can redistribute it and/or
230 modify it under the same terms as Perl itself.
232 See L<http://www.perl.com/perl/misc/Artistic.html>