date('c')]; // try{ // global $wpdb; // $responses['disconnect_reason'] = $wpdb->get_results("select option_id, option_name from $wpdb->options where option_name in ('rabbitloader_field_disconnect_reason', 'rabbitloader_field_update_time')"); // }catch(Throwable $e){ // RabbitLoader_21_Core::on_exception($e); // } // RabbitLoader_21_Core::sendJsonResponse($responses); // } // }catch(Throwable $e){ // RabbitLoader_21_Core::on_exception($e); // } if (current_user_can( 'manage_options' )) { add_action('admin_bar_menu', 'RabbitLoader_21_Public::adminBarMenu', 50); add_action('wp_enqueue_scripts', 'RabbitLoader_21_Public::adminBarScript'); } RabbitLoader_21_CDN::init(); } public static function shutdown($cache_served = false) { try{ if(!$cache_served){ self::optimized_version_missing(); RabbitLoader_21_Core::clean_orphaned_cached_files(300); }else{ RabbitLoader_21_Core::clean_orphaned_cached_files(3600); } }catch(Throwable $e){ RabbitLoader_21_Core::on_exception($e); } } private static function can_cache_request($request_uri){ if(!empty(self::$skip_reason)){ return false; } if(RabbitLoader_21_Util_Core::get_request_type()!='get'){ //Not a GET request, return self::$skip_reason = 'method-'.RabbitLoader_21_Util_Core::get_request_type(); return false; } if(RabbitLoader_21_Util_WP::is_user_logged_in() || RabbitLoader_21_Util_WP::is_login_page()){ //we are not serving cached content to logged in users self::$skip_reason = 'user-session'; return false; } if(RabbitLoader_21_Util_WP::is_ajax()){ self::$skip_reason = 'ajax'; return false; } if(!empty($_SERVER["HTTP_X_RL_PINGBACK"]) || RabbitLoader_21_Util_Core::isNoOptimization() || !empty($_SERVER["HTTP_X_RL_DIAGNOSIS"])){ //its origin pull form ur own server, let it get the original HTML self::$skip_reason = self::skip_reason_or; self::$is_origin = true; return false; } if(!empty($_COOKIE['woocommerce_items_in_cart'])){ //TBD- user has some items in cart, in future version we will check how to serve a cached page with cart self::$skip_reason = 'cart-items'; return false; } if(empty($_SERVER["HTTP_HOST"]) || RabbitLoader_21_Util_WP::is_cli() || !empty($_GET["mwprid"])){ self::$skip_reason = 'cli'; return false; } global $wp_query; if (isset($wp_query) && $wp_query->is_404()) { self::$skip_reason = '404-not-found'; return false; } if (RabbitLoader_21_Util_WP::is_search()) { self::$skip_reason = 'search'; return false; } if(RabbitLoader_21_Util_WP::is_cart()){ self::$skip_reason = 'cart'; return false; } if(RabbitLoader_21_Util_WP::is_checkout()){ self::$skip_reason = 'checkout'; return false; } RabbitLoader_21_Core::getWpUserOption($user_options); if(!empty($user_options['cart_uri']) && strcasecmp(RabbitLoader_21_Util_Core::serverURINoGet(), $user_options['cart_uri'])==0){ self::$skip_reason = 'cart'; return false; } if(!empty($user_options['checkout_uri']) && strcasecmp(RabbitLoader_21_Util_Core::serverURINoGet(), $user_options['checkout_uri'])==0){ self::$skip_reason = 'checkout'; return false; } if(!empty($user_options['exclude_patterns'])){ $exclude_patterns = explode("\n", $user_options['exclude_patterns']); $matched = false; if(!empty($exclude_patterns)){ foreach($exclude_patterns as $i=>$path_pattern){ if(!empty($path_pattern)){ $matched = fnmatch(trim($path_pattern), $request_uri); if(!$matched){ $matched = fnmatch(trim($path_pattern), rawurldecode($request_uri)); } if(!$matched){ $matched = fnmatch($path_pattern, rawurldecode($request_uri)); } if($matched){break;} } } } if($matched){ self::$skip_reason = self::skip_reason_ep; return false; } } if(!empty($user_options['private_mode_val']) && empty($_GET['rltest'])){ self::$skip_reason = self::skip_reason_pm; return false; } if(!empty(self::$skip_reason)){ self::$skip_reason = self::$skip_reason; return false; } return true; } public static function getSkipReason(){ return self::$skip_reason; } public static function process_incoming_request($mode='ac'){ try{ RabbitLoader_21_Util_Core::get_requested_uri($request_uri, $request_url); if(!self::can_cache_request($request_uri)){ if(empty(self::$skip_reason)){self::$skip_reason='unknown';} RabbitLoader_21_Core::sendHeader('x-rl-cache: skipped-'.self::$skip_reason, true); return; } if(!empty($request_uri) && $request_uri!="/favicon.ico"){ RabbitLoader_21_Core::get_cache_file_path($request_url, $cache_file); if(self::serve_from_cache_if_available($cache_file)){ //ignore buffer and serve from cache self::shutdown(true); exit; } RabbitLoader_21_Core::sendHeader('x-rl-cache: miss/'.$mode, true); } }catch(Throwable $e){ RabbitLoader_21_Core::on_exception($e); } } private static function optimized_version_missing(){ RabbitLoader_21_Util_Core::get_requested_uri($request_uri, $request_url); if(self::can_cache_request($request_uri)){ $request_url.="\n"; RabbitLoader_21_Util_Core::fac('cache_missed', $request_url, WP_DEBUG); }else if(strcmp(self::$skip_reason,self::skip_reason_pm)===0){ if(!RabbitLoader_21_Core::cache_exists_for_url($request_url, 0)){ $request_url.="\n"; RabbitLoader_21_Util_Core::fac('cache_missed', $request_url, WP_DEBUG); } }else{ //error_log($skip_reason.'=>'.$request_uri); } } public static function setup_endpoint(){ if(empty($_SERVER["HTTP_X_RL_PINGBACK_V2"])){ return; } $response = [ 'time'=>date('c') ]; RabbitLoader_21_Core::getWpOption($rl_wp_options); $api_key = empty($_SERVER["HTTP_X_RL_APIKEY"]) ? '' : trim($_SERVER["HTTP_X_RL_APIKEY"]); $push_key = empty($_SERVER["HTTP_X_RL_PUSH_KEY"]) ? '' : trim($_SERVER["HTTP_X_RL_PUSH_KEY"]); $isValidKey1 = (!empty($rl_wp_options['rabbitloader_field_apikey']) && ($rl_wp_options['rabbitloader_field_apikey'] == $api_key)); $isValidKey2 = (!empty($rl_wp_options['push_key']) && wp_check_password($push_key, $rl_wp_options['push_key'])); $isValidKey3 = (function_exists('get_option') && !empty($api_key) && ($api_key == get_option('rabbitloader_field_apikey'))); $isValidKey = $isValidKey1 || $isValidKey2 || $isValidKey3; $rlaction = RabbitLoader_21_Util_Core::get_param('rlaction', true); if(!$isValidKey){ $response['exception'] = 'key mismatch'; http_response_code(200); echo json_encode($response); return; } if(strcasecmp($rlaction, 'warmup')===0){ $queued_offset = intval($_POST['queued_offset']); RabbitLoader_21_Core::run_warmup($queued_offset, $response); }else if(strcasecmp($rlaction, 'purge')===0){ $tp_purge_count = 0; RabbitLoader_21_Core::purge_all($purge_count, 'RL_PANEL', $tp_purge_count); $response['purged'] = 1; $response['purge_count'] = $purge_count; $response['tp_purge_count'] = $tp_purge_count; }else if(strcasecmp($rlaction, 'diagnosis')===0){ RabbitLoader_21_Core::run_diagnosis($response); }else if(empty($rlaction) || strcasecmp($rlaction, 'savepage')===0){ $cur_id = RabbitLoader_21_Util_Core::get_param('cur_id', true); $response['cur_id'] = $cur_id; if(class_exists('ZipArchive')){ try{ $zip = new \ZipArchive(); if (!empty($cur_id) && !empty($_FILES["content_zip"]["tmp_name"]) && $zip->open($_FILES["content_zip"]["tmp_name"]) === TRUE) { $dir = sys_get_temp_dir(); $zip->extractTo($dir); $zip->close(); RabbitLoader_21_Core::get_cache_file_path($_POST['canonical_url'], $cache_file); $saved_count = 0; $tp_purge_count = 0; $html_fn = "$dir/$cur_id.html"; if(file_exists($html_fn)){ $response['zip_opened'] = true; if(self::hasValidClosingTag($html_fn)){ if(RabbitLoader_21_Util_Core::move($html_fn, $cache_file.'_c')){ ++$saved_count; } if(RabbitLoader_21_Util_Core::move("$dir/$cur_id.json", $cache_file.'_h')){ ++$saved_count; } }else{ $response['eof_missing'] = true; } if($saved_count>0){ RabbitLoader_21_TP::purge_url($_POST['canonical_url'], $tp_purge_count); } }else{ $response['zip_extract'] = "$html_fn not found"; } $response['tmp_dir'] = $dir; $response['saved_count'] = $saved_count; $response['tp_purge_count'] = $tp_purge_count; $response['cache_file'] = $cache_file; $response['cache_filesize'] = filesize($cache_file.'_c'); $response['canonical_url'] = $_POST['canonical_url']; }else{ $response['zip_opened'] = false; } }catch(\Throwable $e){ $response['exception'] = $e->getMessage(); } }else{ $response['exception'] = 'ZipArchive not found'; } }else{ $response['exception'] = 'invalid action '.$rlaction; } http_response_code(200); echo json_encode($response); exit; } private static function hasValidClosingTag(string $fn){ $valid = false; $handle = fopen($fn, 'r'); fseek($handle, -8192, SEEK_END); //grab the last 8000 bytes to be safe while (($buffer = fgets($handle)) !== false) { if (stripos($buffer, '') !== false || stripos($buffer, '') !== false) { $valid = true; break; } } fclose($handle); return $valid; } private static function serve_from_cache_if_available($cache_file){ if(RabbitLoader_21_Core::cache_exists_for_hash($cache_file, 0)){ //ignore buffer and serve from cache if(file_exists($cache_file.'_h')){ //header is optional RabbitLoader_21_Util_Core::send_headers(file_get_contents($cache_file.'_h')); } RabbitLoader_21_Core::sendHeader('x-rl-cache: hit', true); echo file_get_contents($cache_file.'_c'); return true; } } public static function adminBarMenu($admin_bar){ $top_menu = array( 'id' => 'rabbitloader_top_menu', 'title' => 'RabbitLoader', 'href' => admin_url( 'options-general.php?page=rabbitloader' ) ); $list_menu = array( 'parent' => 'rabbitloader_top_menu', 'id' => 'rabbitloader_purge_page', 'title' => 'Purge cache for this page', 'href' => "#", 'meta' => array( 'class' => 'rabbitloader_purge_page', ) ); $admin_bar->add_node($top_menu); $admin_bar->add_node($list_menu); } public static function adminBarScript(){ global $post; wp_enqueue_script('rabbitloader-index', RABBITLOADER_PLUG_URL . 'admin/js/index.js', ['jquery'], RABBITLOADER_PLUG_VERSION); wp_localize_script( 'rabbitloader-index', 'rabbitloader_local_vars', [ 'admin_ajax' => admin_url( 'admin-ajax.php' ), 'post_id' => empty($post) ? 0: $post->ID ]); } public static function wp_redirect($location, $status){ if(!empty($location)){ self::$skip_reason = 'redirect-'.$status; } return $location; } public static function redirect_canonical($redirect_url, $requested_url){ if(!empty($redirect_url)){self::$skip_reason = 'redirect-canonical';} return $redirect_url; } public static function pre_handle_404($preempt, $wp_query ){ if($preempt){self::$skip_reason = '404';} return $preempt; } public static function paginate_links($link){ if(!empty($link)){ $link = str_ireplace('rl-no-optimization=1','', $link); $link = rtrim($link, '?'); return $link; } } public static function nonce_life($life){ $referer = empty($_SERVER["HTTP_REFERER"]) ? '' : $_SERVER["HTTP_REFERER"]; if(RabbitLoader_21_Util_WP::is_user_logged_in()){ return $life; }elseif(intval($life)>RabbitLoader_21_Core::ORPHANED_LONG_AGE_SEC){ return $life; }else if(self::$skip_reason==self::skip_reason_or || self::$is_origin){ //this also sets if no_optimization is passed return RabbitLoader_21_Core::ORPHANED_LONG_AGE_SEC; }else if(RabbitLoader_21_Util_WP::is_ajax() && (!empty($_COOKIE["rlCached"]) || stripos($referer, self::no_optimization)!==false)){ //for ajax, if cookie is set, the page was cached who called the ajax //or the referer page had no_optimization that matched the previous else condition return RabbitLoader_21_Core::ORPHANED_LONG_AGE_SEC; }else{ //unhandled scenarios } return $life; } public static function wp_footer(){ if(self::$wp_footer_called){ return; } self::$wp_footer_called = true; echo ""; } } ?>