fix ticketing system error on bootstrap of new install
[freeside.git] / htetc / handler.pl
index 9f2a483..2fe5d37 100644 (file)
@@ -1,13 +1,40 @@
 #!/usr/bin/perl
-#
-# This is a basic, fairly fuctional Mason handler.pl.
-#
-# For something a little more involved, check out session_handler.pl
 
 package HTML::Mason;
 
-# Bring in main Mason package.
-use HTML::Mason;
+use strict;
+use warnings;
+use FS::Mason qw( mason_interps );
+use FS::Trace;
+use FS::access_user_log;
+use FS::Conf;
+
+$FS::Conf::conf_cache_enabled = 1; # enable FS::Conf caching for performance
+
+# Preload to share in mod_perl parent for performance
+use FS::UID qw(load_schema);
+load_schema();
+use FS::Record qw(fk_methods_init);
+fk_methods_init;
+
+if ( %%%RT_ENABLED%%% ) {
+
+  require RT;
+
+  $> = scalar(getpwnam('freeside'));
+
+  RT::LoadConfig();
+  RT::Init();
+
+  # disconnect DB before fork:
+  #   (avoid 'prepared statement "dbdpg_p\d+_\d+" already exists' errors?)
+  $RT::Handle->dbh(undef);
+  undef $RT::Handle;
+
+  $> = $<;
+}
+
+#use vars qw($r);
 
 # Bring in ApacheHandler, necessary for mod_perl integration.
 # Uncomment the second line (and comment the first) to use
@@ -15,32 +42,16 @@ use HTML::Mason;
 use HTML::Mason::ApacheHandler;
 # use HTML::Mason::ApacheHandler (args_method=>'mod_perl');
 
-# Uncomment the next line if you plan to use the Mason previewer.
-#use HTML::Mason::Preview;
-
-use strict;
-
-# List of modules that you want to use from components (see Admin
-# manual for details)
-#{  package HTML::Mason::Commands;
-#   use CGI;
-#}
+###use Module::Refresh;###
 
 # Create Mason objects
-#
 
-#my $parser = new HTML::Mason::Parser;
-#my $interp = new HTML::Mason::Interp (parser=>$parser,
-#                                      comp_root=>'/var/www/masondocs',
-#                                      data_dir=>'/usr/local/etc/freeside/masondata',
-#                                      out_mode=>'stream',
-#                                     );
+my( $fs_interp, $rt_interp ) = mason_interps('apache');
+
 my $ah = new HTML::Mason::ApacheHandler (
-  #interp => $interp,
-  #auto_send_headers => 0,
-  comp_root=>'/var/www/masonside',
-  data_dir=>'/usr/local/etc/freeside/masondata',
-  #out_mode=>'stream',
+  interp        => $fs_interp,
+  request_class => 'FS::Mason::Request',
+  args_method   => 'CGI', #(and FS too)
 );
 
 # Activate the following if running httpd as root (the normal case).
@@ -48,9 +59,33 @@ my $ah = new HTML::Mason::ApacheHandler (
 #
 #chown (Apache->server->uid, Apache->server->gid, $interp->files_written);
 
+my $protect_fds;
+
 sub handler
 {
-    my ($r) = @_;
+    #($r) = @_;
+    my $r = shift;
+
+    my $start_time = time;
+
+    FS::Trace->log('protecting fds');
+
+    #from rt/bin/webmux.pl(.in)
+    if ( !$protect_fds && $ENV{'MOD_PERL'} && exists $ENV{'MOD_PERL_API_VERSION'}
+        && $ENV{'MOD_PERL_API_VERSION'} >= 2
+    ) {
+        # under mod_perl2, STDIN and STDOUT get closed and re-opened,
+        # however they are not on FD 0 and 1.  In this case, the next
+        # socket that gets opened will occupy one of these FDs, and make
+        # all system() and open "|-" calls dangerous; for example, the
+        # DBI handle can get this FD, which later system() calls will
+        # close by putting garbage into the socket.
+        $protect_fds = [];
+        push @{$protect_fds}, IO::Handle->new_from_fd(0, "r")
+            if fileno(STDIN) != 0;
+        push @{$protect_fds}, IO::Handle->new_from_fd(1, "w")
+            if fileno(STDOUT) != 1;
+    }
 
     # If you plan to intermix images in the same directory as
     # components, activate the following to prevent Mason from
@@ -58,109 +93,98 @@ sub handler
     #
     #return -1 if $r->content_type && $r->content_type !~ m|^text/|i;
 
-    #rar
-    { package HTML::Mason::Commands;
-      use strict;
-      use vars qw( $cgi $p );
-      use CGI;
-      #use CGI::Carp qw(fatalsToBrowser);
-      use Date::Format;
-      use Date::Parse;
-      use Time::Local;
-      use Tie::IxHash;
-      use HTML::Entities;
-      use IO::Handle;
-      use IO::File;
-      use String::Approx qw(amatch);
-      use Chart::LinesPoints;
-      use HTML::Widgets::SelectLayers 0.02;
-      use FS::UID qw(cgisuidsetup dbh getotaker datasrc driver_name);
-      use FS::Record qw(qsearch qsearchs fields dbdef);
-      use FS::Conf;
-      use FS::CGI qw(header menubar popurl table itable ntable idiot eidiot
-                     small_custview myexit http_header);
-      use FS::Msgcat qw(gettext geterror);
-
-      use FS::agent;
-      use FS::agent_type;
-      use FS::domain_record;
-      use FS::cust_bill;
-      use FS::cust_bill_pay;
-      use FS::cust_credit;
-      use FS::cust_credit_bill;
-      use FS::cust_main;
-      use FS::cust_main_county;
-      use FS::cust_pay;
-      use FS::cust_pkg;
-      use FS::cust_refund;
-      use FS::cust_svc;
-      use FS::nas;
-      use FS::part_bill_event;
-      use FS::part_pkg;
-      use FS::part_referral;
-      use FS::part_svc;
-      use FS::part_svc_router;
-      use FS::pkg_svc;
-      use FS::port;
-      use FS::queue qw(joblisting);
-      use FS::raddb;
-      use FS::session;
-      use FS::svc_acct;
-      use FS::svc_acct_pop qw(popselector);
-      use FS::svc_acct_sm;
-      use FS::svc_domain;
-      use FS::svc_forward;
-      use FS::svc_www;
-      use FS::router;
-      use FS::part_router_field;
-      use FS::router_field;
-      use FS::addr_block;
-      use FS::part_sb_field;
-      use FS::sb_field;
-      use FS::svc_broadband;
-      use FS::type_pkgs;
-      use FS::part_export;
-      use FS::part_export_option;
-      use FS::export_svc;
-      use FS::msgcat;
-
-      *CGI::redirect = sub {
-        my( $self, $location ) = @_;
-        use vars qw($m);
-        #http://www.masonhq.com/docs/faq/#how_do_i_do_an_external_redirect
-        $m->clear_buffer;
-        # The next two lines are necessary to stop Apache from re-reading
-        # POSTed data.
-        $r->method('GET');
-        $r->headers_in->unset('Content-length');
-        $r->content_type('text/html');
-        #$r->err_header_out('Location' => $location);
-        $r->header_out('Location' => $location);
-         $r->header_out('Content-Type' => 'text/html');
-         $m->abort(302);
-
-        '';
-      };
-
-      $cgi = new CGI;
-      &cgisuidsetup($cgi);
-      #&cgisuidsetup($r);
-      $p = popurl(2);
-    }
+    ###Module::Refresh->refresh;###
+
+    FS::Trace->log('setting content_type / headers');
 
-    $r->content_type('text/html');
+    $r->content_type('text/html; charset=utf-8');
+    #$r->content_type('text/html; charset=iso-8859-1');
     #eorar
 
     my $headers = $r->headers_out;
-    $headers->{'Pragma'} = $headers->{'Cache-control'} = 'no-cache';
+    $headers->{'Cache-control'} = 'no-cache';
     #$r->no_cache(1);
     $headers->{'Expires'} = '0';
 
 #    $r->send_http_header;
 
-    my $status = $ah->handle_request($r);
+    if ( $r->filename =~ /\/rt\// ) { #RT
+
+      FS::Trace->log('handling RT file');
+
+      # We don't need to handle non-text, non-xml items
+      return -1 if defined( $r->content_type )
+                && $r->content_type !~ m!(^text/|\bxml\b)!io;
+
+      local $SIG{__WARN__};
+      local $SIG{__DIE__};
+
+      FS::Trace->log('initializing RT');
+      my_rt_init();
+
+      FS::Trace->log('setting RT interpreter');
+      $ah->interp($rt_interp);
+
+    } else {
+
+      FS::Trace->log('handling Freeside file');
+
+      local $SIG{__WARN__};
+      local $SIG{__DIE__};
+
+      FS::Trace->log('initializing RT');
+      my_rt_init();
+
+      #we don't want the RT error handlers under FS
+      {
+        no warnings 'uninitialized';
+        undef($SIG{__WARN__}) if defined($SIG{__WARN__});
+        undef($SIG{__DIE__})  if defined($SIG{__DIE__} );
+      }
+
+      FS::Trace->log('setting Freeside interpreter');
+      $ah->interp($fs_interp);
+
+    }
+
+    FS::Trace->log('handling request');
+    my %session;
+    my $status;
+    eval { $status = $ah->handle_request($r); };
+#!!
+#    if ( $@ ) {
+#      $RT::Logger->crit($@);
+#    }
+    warn $@ if $@;
+
+    undef %session;
+
+#!!
+#    if ($RT::Handle->TransactionDepth) {
+#      $RT::Handle->ForceRollback;
+#      $RT::Logger->crit(
+#"Transaction not committed. Usually indicates a software fault. Data loss may have occurred"
+#       );
+#    }
+
+    FS::access_user_log->insert_new_path( $r->filename, time-$start_time );
+
+    FS::Trace->log('done');
+
+    FS::Trace->dumpfile( "%%%FREESIDE_EXPORT%%%/profile/$$.".time,
+                         FS::Trace->total. ' '. $r->filename
+                       )
+      if FS::Trace->total > 5; #10?
+
+    FS::Trace->reset;
 
     $status;
 }
 
+sub my_rt_init {
+  return unless $RT::VERSION;
+  RT::ConnectToDatabase();
+  RT::InitSignalHandlers();
+}
+
 1;