diff options
Diffstat (limited to 'rt/bin/standalone_httpd.in')
-rwxr-xr-x | rt/bin/standalone_httpd.in | 192 |
1 files changed, 192 insertions, 0 deletions
diff --git a/rt/bin/standalone_httpd.in b/rt/bin/standalone_httpd.in new file mode 100755 index 000000000..bf449455c --- /dev/null +++ b/rt/bin/standalone_httpd.in @@ -0,0 +1,192 @@ +#!@PERL@ -w +# {{{ BEGIN BPS TAGGED BLOCK +# +# COPYRIGHT: +# +# This software is Copyright (c) 1996-2004 Best Practical Solutions, LLC +# <jesse@bestpractical.com> +# +# (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( $_ = <STDIN> ); + 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 (<STDIN>) { + 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(); +} |