| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117 |
- package Troglodyne::CGI;
- use strict;
- use warnings;
- # Need to also get POST args, etc.
- sub get_args {
- my $meth = $ENV{'REQUEST_METHOD'};
- die "Unsupported request method: '$meth'" if !grep{ $meth eq $_ } qw{GET POST};
- my $args_hr = {};
- my %handlers = (
- 'GET' => sub { return { map { split( /=/, $_ ) } split( /&/, $ENV{'QUERY_STRING'} ) } },
- 'POST' => sub {
- die "Content length longer than 4096 bytes on a POST. Get lost!" if $ENV{'CONTENT_LENGTH'} > 4096;
- sysread( STDIN, my $line, $ENV{'CONTENT_LENGTH'} );
- return { map { split( /=/, $_ ) } split( /&/, $line ) };
- },
- );
- $args_hr = $handlers{$meth}->();
- return $args_hr;
- }
- our $CP_SECURITY_TOKEN = $ENV{'cp_security_token'} || 'cpsess0000000000';
- our $CP_USER = $ENV{'REMOTE_USER'} || 'nobody';
- # XXX TODO TODO TODO Need to make API calls return 304 unmodified if the data is
- # unchanged! hehehe
- # TODO delete cached templates via cron or hook or something, as the cache files
- # will otherwise begin to pile up.
- # Suggest using Cpanel::Session::is_active_security_token_for_user($user,$token)
- # in a loop and trashing inactive templates.
- # Yay. I now have ~250ms pageloads instead of 350+ms pageloads.
- # XXX Need to check when the chrome updates and pop cache then too?
- # Maybe upcp hook instead?
- sub render_cached_or_process_template {
- my ( $service, $input_hr ) = @_;
- if( $input_hr->{'troglodyne_do_static_render'} ) {
- # Try to print from cache, as Cpanel::Template is slow AF
- my ( $cached, $cache_dir ) = cached( $service, $input_hr->{'template_file'} );
- return if( $cached && render_from_cache($cache_dir) );
- # OK, so no cache. Let's fix that.
- $input_hr->{'print'} = 0;
- require Cpanel::Template;
- my ( $success, $output_sr ) = Cpanel::Template::process_template( $service, $input_hr );
- # TODO: Investigate whether I can send to two filehandles simultaneously -- $output_sr and STDOUT (as we are a CGI).
- # Then we could cache & print without the below step.
- if( $success ) {
- return if render_to_cache_and_print( $cache_dir, $output_sr );
- }
- }
- # Crap, everything failed. Just try to print it, sigh
- require Cpanel::Template;
- Cpanel::Template::process_template( $service, $input_hr );
- return;
- }
- sub render_to_cache_and_print {
- my ( $cache_dir, $content_sr ) = @_;
- local $@;
- require Cpanel::Mkdir;
- Cpanel::Mkdir::ensure_directory_existence_and_mode($cache_dir, 0711);
- my $worked = eval {
- open( my $fh, '>', "$cache_dir/$CP_SECURITY_TOKEN" ) or die "Couldn't open cache file \"$cache_dir/$CP_SECURITY_TOKEN\" for writing: $!";
- print $fh $$content_sr;
- print STDOUT $$content_sr;
- };
- if(my $err = $@) {
- # Require bashes $@, so assign first
- require Cpanel::Debug;
- Cpanel::Debug::log_error($err);
- }
- return $worked;
- }
- sub render_from_cache {
- my ( $cache_dir ) = @_;
- local $@;
- my $worked = eval {
- open( my $fh, '<', "$cache_dir/$CP_SECURITY_TOKEN" ) or die "Couldn't open cache file \"$cache_dir/$CP_SECURITY_TOKEN\" for reading: $!";
- while( <$fh> ) { print $_; }
- 1;
- };
- if(my $err = $@) {
- # Require bashes $@, so assign first
- require Cpanel::Debug;
- Cpanel::Debug::log_error($err);
- }
- return $worked;
- }
- # These MUST be indexed by cp_security_token... sadly
- our $ULC = '/usr/local/cpanel';
- our %TMPL_DIRS_BY_SVC = (
- 'whostmgr' => 'whostmgr/docroot/templates',
- 'cpanel' => 'base/frontend/paper_lantern',
- 'webmail' => 'base/webmail/paper_lantern',
- );
- sub cached {
- my ( $service, $tmpl_file ) = @_;
- my $tmpl_path = "$ULC/$TMPL_DIRS_BY_SVC{$service}/$tmpl_file";
- my $cache_dir = "${tmpl_path}_caches/$CP_USER";
- my $cache_path = "$cache_dir/$CP_SECURITY_TOKEN";
- # If cache mtime is older than template mtime, we are fine to use the cache.
- my $cached = ( -s $cache_path && ( (stat(_))[9] > (stat($tmpl_path))[9] ) );
- return ( $cached, $cache_dir );
- }
- 1;
|