#!@PERL@ -w # {{{ BEGIN BPS TAGGED BLOCK # # COPYRIGHT: # # This software is Copyright (c) 1996-2004 Best Practical Solutions, LLC # # # (Except where explicitly superseded by other copyright notices) # # # LICENSE: # # This work is made available to you under the terms of Version 2 of # the GNU General Public License. A copy of that license should have # been provided with this software, but in any event can be snarfed # from www.gnu.org. # # This work is distributed in the hope that it will be useful, but # WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU # General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. # # # CONTRIBUTION SUBMISSION POLICY: # # (The following paragraph is not intended to limit the rights granted # to you to modify and distribute this software under the terms of # the GNU General Public License and is only of importance to you if # you choose to contribute your changes and enhancements to the # community by submitting them to Best Practical Solutions, LLC.) # # By intentionally submitting any modifications, corrections or # derivatives to this work, or any other work intended for use with # Request Tracker, to Best Practical Solutions, LLC, you confirm that # you are the copyright holder for those contributions and you grant # Best Practical Solutions, LLC a nonexclusive, worldwide, irrevocable, # royalty-free, perpetual, license to use, copy, create derivative # works based on those contributions, and sublicense and distribute # those contributions and any derivatives thereof. # # }}} END BPS TAGGED BLOCK package RT::Mason; use strict; use vars '$Handler'; require ('@RT_BIN_PATH@/webmux.pl'); use lib( "@LOCAL_LIB_PATH@", "@RT_LIB_PATH@"); use Socket; RT::Init(); my $port = shift || '8080'; main_loop($port); sub main_loop { my $port = shift; my $tcp = getprotobyname('tcp'); socket( HTTPDaemon, PF_INET, SOCK_STREAM, $tcp ) or die "socket: $!"; setsockopt( HTTPDaemon, SOL_SOCKET, SO_REUSEADDR, pack( "l", 1 ) ) or warn "setsockopt: $!"; bind( HTTPDaemon, sockaddr_in( $port, INADDR_ANY ) ) or die "bind: $!"; listen( HTTPDaemon, SOMAXCONN ) or die "listen: $!"; print("You can connect to your RT server at http://localhost:$port/\n"); while (1) { for ( ; accept( Remote, HTTPDaemon ); close Remote ) { *STDIN = *Remote; *STDOUT = *Remote; my $remote_sockaddr = getpeername(STDIN); my ( undef, $iaddr ) = sockaddr_in($remote_sockaddr); my $peername = gethostbyaddr( $iaddr, AF_INET ) || "localhost"; my $peeraddr = inet_ntoa($iaddr) || "127.0.0.1"; my $local_sockaddr = getsockname(STDIN); my ( undef, $localiaddr ) = sockaddr_in($local_sockaddr); my $localname = gethostbyaddr( $localiaddr, AF_INET ) || "localhost"; my $localaddr = inet_ntoa($localiaddr) || "127.0.0.1"; chomp( $_ = ); my ( $method, $request_uri, $proto, undef ) = split; #$request_uri =~ s#\\#/#g; $RT::Logger->info("<- $peername: $_"); my ( $file, undef, $query_string ) = ( $request_uri =~ /([^?]*)(\?(.*))?/ ); # split at ? #$file =~ s/%([\dA-Fa-f]{2})/chr(hex($1))/eg; # decode url-escaped entities last if ( $method !~ /^(GET|POST|HEAD)$/ ); build_cgi_env( method => $method, query_string => $query_string, path => $file, method => $method, port => $port, peername => $peername, peeraddr => $peeraddr, localname => $localname, request_uri => $request_uri ); RT::ConnectToDatabase(); my $cgi = CGI->new(); print "HTTP/1.0 200 OK\n"; # probably OK by now if ( ( !$Handler->interp->comp_exists( $cgi->path_info ) ) && ($Handler->interp->comp_exists( $cgi->path_info . "/index.html" ) ) ) { $cgi->path_info( $cgi->path_info . "/index.html" ); } eval { $Handler->handle_cgi_object($cgi); }; $RT::Logger->crit($@) if ($@); if ( $RT::Handle->TransactionDepth ) { $RT::Handle->ForceRollback; $RT::Logger->crit( "Transaction not committed. Usually indicates a software fault. Data loss may have occurred"); } } } } sub build_cgi_env { my %args = ( query_string => '', path => '', port => undef, protocol => undef, localname => undef, method => undef, remote_name => undef, @_); foreach my $var qw(USER_AGENT CONTENT_LENGTH CONTENT_TYPE COOKIE SERVER_PORT SERVER_PROTOCOL SERVER_NAME PATH_INFO REQUEST_URI REQUEST_METHOD REMOTE_ADDR REMOTE_HOST QUERY_STRING SERVER_SOFTWARE) { delete $ENV{$var}; } while () { s/[\r\l\n\s]+$//; if( /^([\w\-]+): (.+)/i) { my $tag = uc($1); $tag =~ s/^COOKIES$/COOKIE/; my $val = $2; $tag =~ s/-/_/g; $tag = "HTTP_".$tag unless (grep /^$tag$/, qw(CONTENT_LENGTH CONTENT_TYPE COOKIE)); if ($ENV{$tag}) { $ENV{$tag} .= "; $val"; } else { $ENV{$tag} = $val; } } last if (/^$/); } $ENV{SERVER_PROTOCOL} = $args{protocol}; $ENV{SERVER_PORT} = $args{port}; $ENV{SERVER_NAME} = $args{'localname'}; $ENV{SERVER_URL} = "http://".$args{'localname'}.":".$args{'port'}."/"; $ENV{PATH_INFO} = $args{'path'}; $ENV{REQUEST_URI} = $args{'request_uri'}; $ENV{REQUEST_METHOD} = $args{method}; $ENV{REMOTE_ADDR} = $args{'peeraddr'}; $ENV{REMOTE_HOST} = $args{'peername'}; $ENV{QUERY_STRING} = $args{'query_string'}; $ENV{SERVER_SOFTWARE} = "rt-standalone/$RT::VERSION"; CGI::initialize_globals(); }