rt 4.0.20 (RT#13852)
[freeside.git] / rt / lib / RT / Interface / Web / Handler.pm
index 69eee60..07e7707 100644 (file)
@@ -2,7 +2,7 @@
 #
 # COPYRIGHT:
 #
-# This software is Copyright (c) 1996-2012 Best Practical Solutions, LLC
+# This software is Copyright (c) 1996-2014 Best Practical Solutions, LLC
 #                                          <sales@bestpractical.com>
 #
 # (Except where explicitly superseded by other copyright notices)
@@ -69,12 +69,12 @@ sub DefaultHandlerArgs  { (
     ],
     default_escape_flags => 'h',
     data_dir             => "$RT::MasonDataDir",
-    allow_globals        => [qw(%session)],
+    allow_globals        => [qw(%session $DECODED_ARGS)],
     # Turn off static source if we're in developer mode.
     static_source        => (RT->Config->Get('DevelMode') ? '0' : '1'), 
     use_object_files     => (RT->Config->Get('DevelMode') ? '0' : '1'), 
     autoflush            => 0,
-    error_format         => (RT->Config->Get('DevelMode') ? 'html': 'brief'),
+    error_format         => (RT->Config->Get('DevelMode') ? 'html': 'rt_error'),
     request_class        => 'RT::Interface::Web::Request',
     named_component_subs => $INC{'Devel/Cover.pm'} ? 1 : 0,
 ) };
@@ -116,6 +116,7 @@ sub NewHandler {
   
     $handler->interp->set_escape( h => \&RT::Interface::Web::EscapeUTF8 );
     $handler->interp->set_escape( u => \&RT::Interface::Web::EscapeURI  );
+    $handler->interp->set_escape( j => \&RT::Interface::Web::EscapeJS   );
     return($handler);
 }
 
@@ -202,6 +203,47 @@ sub CleanupRequest {
 }
 
 
+sub HTML::Mason::Exception::as_rt_error {
+    my ($self) = @_;
+    $RT::Logger->error( $self->as_text );
+    return "An internal RT error has occurred.  Your administrator can find more details in RT's log files.";
+}
+
+=head1 CheckModPerlHandler
+
+Make sure we're not running with SetHandler perl-script.
+
+=cut
+
+sub CheckModPerlHandler{
+    my $self = shift;
+    my $env = shift;
+
+    # Plack::Handler::Apache2 masks MOD_PERL, so use MOD_PERL_API_VERSION
+    return unless( $env->{'MOD_PERL_API_VERSION'}
+                   and $env->{'MOD_PERL_API_VERSION'} == 2);
+
+    my $handler = $env->{'psgi.input'}->handler;
+
+    return unless defined $handler && $handler eq 'perl-script';
+
+    $RT::Logger->critical(<<MODPERL);
+RT has problems when SetHandler is set to perl-script.
+Change SetHandler in your in httpd.conf to:
+
+    SetHandler modperl
+
+For a complete example mod_perl configuration, see:
+
+https://bestpractical.com/rt/docs/@{[$RT::VERSION =~ /^(\d\.\d)/]}/web_deployment.html#mod_perl-2.xx
+MODPERL
+
+    my $res = Plack::Response->new(500);
+    $res->content_type("text/plain");
+    $res->body("Server misconfiguration; see error log for details");
+    return $res;
+}
+
 # PSGI App
 
 use RT::Interface::Web::Handler;
@@ -223,6 +265,12 @@ sub PSGIApp {
 
     return sub {
         my $env = shift;
+
+        {
+            my $res = $self->CheckModPerlHandler($env);
+            return $self->_psgi_response_cb( $res->finalize ) if $res;
+        }
+
         RT::ConnectToDatabase() unless RT->InstallMode;
 
         my $req = Plack::Request->new($env);
@@ -230,7 +278,7 @@ sub PSGIApp {
         # CGI.pm normalizes .. out of paths so when you requested
         # /NoAuth/../Ticket/Display.html we saw Ticket/Display.html
         # PSGI doesn't normalize .. so we have to deal ourselves.
-        if ( $req->path_info =~ m{/\.} ) {
+        if ( $req->path_info =~ m{(^|/)\.\.?(/|$)} ) {
             $RT::Logger->crit("Invalid request for ".$req->path_info." aborting");
             my $res = Plack::Response->new(400);
             return $self->_psgi_response_cb($res->finalize,sub { $self->CleanupRequest });