import rt 3.4.6
[freeside.git] / rt / lib / RT / Interface / Web / Handler.pm
1 # BEGIN BPS TAGGED BLOCK {{{
2
3 # COPYRIGHT:
4 #  
5 # This software is Copyright (c) 1996-2005 Best Practical Solutions, LLC 
6 #                                          <jesse@bestpractical.com>
7
8 # (Except where explicitly superseded by other copyright notices)
9
10
11 # LICENSE:
12
13 # This work is made available to you under the terms of Version 2 of
14 # the GNU General Public License. A copy of that license should have
15 # been provided with this software, but in any event can be snarfed
16 # from www.gnu.org.
17
18 # This work is distributed in the hope that it will be useful, but
19 # WITHOUT ANY WARRANTY; without even the implied warranty of
20 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
21 # General Public License for more details.
22
23 # You should have received a copy of the GNU General Public License
24 # along with this program; if not, write to the Free Software
25 # Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
26
27
28 # CONTRIBUTION SUBMISSION POLICY:
29
30 # (The following paragraph is not intended to limit the rights granted
31 # to you to modify and distribute this software under the terms of
32 # the GNU General Public License and is only of importance to you if
33 # you choose to contribute your changes and enhancements to the
34 # community by submitting them to Best Practical Solutions, LLC.)
35
36 # By intentionally submitting any modifications, corrections or
37 # derivatives to this work, or any other work intended for use with
38 # Request Tracker, to Best Practical Solutions, LLC, you confirm that
39 # you are the copyright holder for those contributions and you grant
40 # Best Practical Solutions,  LLC a nonexclusive, worldwide, irrevocable,
41 # royalty-free, perpetual, license to use, copy, create derivative
42 # works based on those contributions, and sublicense and distribute
43 # those contributions and any derivatives thereof.
44
45 # END BPS TAGGED BLOCK }}}
46
47 package RT::Interface::Web::Handler;
48
49 use CGI qw/-private_tempfiles/;
50 use MIME::Entity;
51 use Text::Wrapper;
52 use CGI::Cookie;
53 use Time::ParseDate;
54 use Time::HiRes;
55 use HTML::Entities;
56 use HTML::Scrubber;
57 use Text::Quoted;
58 use RT::Interface::Web::Handler;
59 use File::Path qw( rmtree );
60 use File::Glob qw( bsd_glob );
61 use File::Spec::Unix;
62
63 sub DefaultHandlerArgs  { (
64     comp_root => [
65         [ local    => $RT::MasonLocalComponentRoot ],
66         [ standard => $RT::MasonComponentRoot ]
67     ],
68     default_escape_flags => 'h',
69     data_dir             => "$RT::MasonDataDir",
70     allow_globals        => [qw(%session)],
71     # Turn off static source if we're in developer mode.
72     static_source        => ($RT::DevelMode ? '0' : '1'), 
73     use_object_files     => ($RT::DevelMode ? '0' : '1'), 
74     autoflush            => 0
75 ) };
76
77 # {{{ sub new 
78
79 =head2 new
80
81   Constructs a web handler of the appropriate class.
82   Takes options to pass to the constructor.
83
84 =cut
85
86 sub new {
87     my $class = shift;
88     $class->InitSessionDir;
89
90     if ( $mod_perl::VERSION && $mod_perl::VERSION >= 1.9908 ) {
91 #        require Apache::RequestUtil;
92 #        no warnings 'redefine';
93 #        my $sub = *Apache::request{CODE};
94 #        *Apache::request = sub {
95 #            my $r;
96 #            eval { $r = $sub->('Apache'); };
97 #
98 #            # warn $@ if $@;
99 #            return $r;
100 #        };
101         goto &NewApacheHandler;
102     }
103     elsif ($CGI::MOD_PERL) {
104         goto &NewApacheHandler;
105     }
106     else {
107         goto &NewCGIHandler;
108     }
109 }
110
111 sub InitSessionDir {
112     # Activate the following if running httpd as root (the normal case).
113     # Resets ownership of all files created by Mason at startup.
114     # Note that mysql uses DB for sessions, so there's no need to do this.
115     unless ( $RT::DatabaseType =~ /(?:mysql|Pg)/ ) {
116
117         # Clean up our umask to protect session files
118         umask(0077);
119
120         if ($CGI::MOD_PERL and $CGI::MOD_PERL < 1.9908 ) {
121
122             chown( Apache->server->uid, Apache->server->gid,
123                 $RT::MasonSessionDir )
124             if Apache->server->can('uid');
125         }
126
127         # Die if WebSessionDir doesn't exist or we can't write to it
128         stat($RT::MasonSessionDir);
129         die "Can't read and write $RT::MasonSessionDir"
130         unless ( ( -d _ ) and ( -r _ ) and ( -w _ ) );
131     }
132
133 }
134
135 # }}}
136
137 # {{{ sub NewApacheHandler 
138
139 =head2 NewApacheHandler
140
141   Takes extra options to pass to HTML::Mason::ApacheHandler->new
142   Returns a new Mason::ApacheHandler object
143
144 =cut
145
146 sub NewApacheHandler {
147     require HTML::Mason::ApacheHandler;
148     return NewHandler('HTML::Mason::ApacheHandler', args_method => "CGI", @_);
149 }
150
151 # }}}
152
153 # {{{ sub NewApache2Handler 
154
155 =head2 NewApache2Handler
156
157   Takes extra options to pass to MasonX::Apache2Handler->new
158   Returns a new MasonX::Apache2Handler object
159
160 =cut
161
162 sub NewApache2Handler {
163     require MasonX::Apache2Handler;
164     return NewHandler('MasonX::Apache2Handler', args_method => "CGI", @_);
165 }
166
167 # }}}
168
169 # {{{ sub NewCGIHandler 
170
171 =head2 NewCGIHandler
172
173   Returns a new Mason::CGIHandler object
174
175 =cut
176
177 sub NewCGIHandler {
178     require HTML::Mason::CGIHandler;
179     return NewHandler('HTML::Mason::CGIHandler', @_);
180 }
181
182 sub NewHandler {
183     my $class = shift;
184     my $handler = $class->new(
185         DefaultHandlerArgs(),
186         @_
187     );
188   
189     $handler->interp->set_escape( h => \&RT::Interface::Web::EscapeUTF8 );
190     $handler->interp->set_escape( u => \&RT::Interface::Web::EscapeURI  );
191     return($handler);
192 }
193
194 =head2 CleanupRequest
195
196 Rollback any uncommitted transaction.
197 Flush the ACL cache
198 Flush the searchbuilder query cache
199
200 =cut
201
202 sub CleanupRequest {
203
204     if ( $RT::Handle->TransactionDepth ) {
205         $RT::Handle->ForceRollback;
206         $RT::Logger->crit(
207             "Transaction not committed. Usually indicates a software fault."
208             . "Data loss may have occurred" );
209     }
210
211     # Clean out the ACL cache. the performance impact should be marginal.
212     # Consistency is imprived, too.
213     RT::Principal->InvalidateACLCache();
214     DBIx::SearchBuilder::Record::Cachable->FlushCache
215       if ( $RT::WebFlushDbCacheEveryRequest
216         and UNIVERSAL::can(
217             'DBIx::SearchBuilder::Record::Cachable' => 'FlushCache' ) );
218
219 }
220 # }}}
221
222 1;