Plugin Directory

Changeset 3081974


Ignore:
Timestamp:
05/06/2024 01:43:27 PM (21 months ago)
Author:
veppa
Message:

Added MU plugin feature. php 8.3 support

Location:
http-requests-manager
Files:
3 added
13 edited
6 copied

Legend:

Unmodified
Added
Removed
  • http-requests-manager/tags/1.3.0/assets/js/admin.js

    r3003727 r3081974  
    193193                status = 'blocked';
    194194            }
    195             else if (row.status_code == '200')
    196             {
    197 
     195            else if (row.status_code == '200' || !request_args.blocking)
     196            {
    198197                status = 'success';
    199198            }
     
    652651                stats.req_type_summary = VPHRM.summarize_data(stats.req_types, 0);
    653652                stats.req_source_summary = VPHRM.summarize_data(stats.req_sources, 10);
     653                stats.num_allowed = stats.requests - stats.num_blocked;
     654                stats.num_performance = stats.num_allowed ? (stats.requests / stats.num_allowed).toFixed(1) * 1 : 10;
    654655                stats.message = [
     656                    '<span class="vphrm-card" title="' + (stats.num_blocked ? stats.num_performance + '×' : '-') + ' performance improvement">'
     657                            + '<span class="vphrm-card-val">'
     658                            + (stats.num_blocked ? stats.num_performance + '×' : '-')
     659                            + '</span>'
     660                            + '<span class="vphrm-card-name">'
     661                            + 'Performance imp.'
     662                            + '</span>'
     663                            + '</span>',
    655664                    '<span class="vphrm-card" title="' + stats.num_blocked + ' requests blocked out of ' + stats.requests + "\nRequest sources:\n" + stats.req_source_summary + '">'
    656665                            + '<span class="vphrm-card-val">'
     
    968977        };
    969978
     979
     980        VPHRM.change_load_must_use = function ()
     981        {
     982            var $me = $(this);
     983            var checked = $me.is(':checked');
     984            $me.attr('disabled', 'disabled');
     985            $.post(ajaxurl, {
     986                'action': 'vphrm_load_must_use',
     987                '_wpnonce': VPHRM.nonce,
     988                'load_must_use': checked ? 1 : 0
     989            }, function (data)
     990            {
     991                if (data.status == 'ok')
     992                {
     993                    // saved
     994                }
     995                else
     996                {
     997                    // data error
     998                    alert(data.message);
     999                    // revert to old cheched/unchecked state
     1000                    $me.prop('checked', !checked);
     1001
     1002                }
     1003
     1004            }, 'json')
     1005                    .fail(function (jqXHR, textStatus, error)
     1006                    {
     1007                        console.log(VPHRM.message_save_error + ": " + error);
     1008                        alert(VPHRM.message_save_error + ": " + error);
     1009                        // revert to old cheched/unchecked state
     1010                        $me.prop('checked', !checked);
     1011                    })
     1012                    .always(function ()
     1013                    {
     1014                        $me.removeAttr('disabled');
     1015                    });
     1016        };
     1017
     1018
     1019
    9701020        VPHRM.view_save = function ()
    9711021        {
     
    12181268            //
    12191269            $(document).on('change', 'input#disable_logging[type="checkbox"]', VPHRM.change_logging);
     1270            $(document).on('change', 'input#load_must_use[type="checkbox"]', VPHRM.change_load_must_use);
    12201271
    12211272            // change view group
  • http-requests-manager/tags/1.3.0/http-requests-manager.php

    r3034389 r3081974  
    55  Plugin URI:   https://veppa.com/http-requests-manager/
    66  Description: Limit, disable, block, log all WP HTTP requests. Limit by request count, page load time or lower timeout for each request. Speed up login and admin pages.
    7   Version: 1.2.4
     7  Version: 1.3.0
    88  Author: veppa
    99  Author URI: https://veppa.com/
     
    3232 * TODO:
    3333 *  - show 47% requests blocked in dashboard at a glance. with option to remove from there.
    34  *  - disable wp_get_http_headers inside do_enclose  called inside do_all_pings. it checks if links inside content has audio or video to enclose. it is slow inside cron call.
     34 *
    3535 */
    3636defined('ABSPATH') or exit;
     
    3939{
    4040
    41     const VERSION = '1.2.4';
     41    const VERSION = '1.3.0';
    4242    const ID = 'http-requests-manager';
     43    const TIMEOUT = 2;
    4344
    4445    public static $instance;
     
    5758    private static $custom_rules_limit = 10;
    5859    private static $page_id;
     60    private static $mu_plugin_file_name = '/a-http-requests-manager.php';
    5961    private static $requests = array();
    6062    private static $cron_status;
     
    6870        'cron',
    6971        'ajax',
    70         'rest_api'
     72        'rest_api',
     73        'xmlrpc'
    7174    );
    7275
     
    8285
    8386        add_action('init', [$this, 'init']);
    84         add_action('admin_menu', [$this, 'admin_menu']);
    85         add_action('admin_enqueue_scripts', [$this, 'admin_scripts']);
    8687        add_filter('http_request_args', [$this, 'start_timer']);
    8788        add_action('http_api_debug', [$this, 'db_capture_request'], 10, 5);
     
    8990        add_action('pre_get_ready_cron_jobs', [$this, 'cron_prevent_in_my_ajax']);
    9091        add_action('shutdown', [$this, 'db_update_page']);
    91         add_filter('plugin_action_links', [$this, 'plugin_action_links'], 10, 2);
     92
     93        // admin page actions only. for optimisation purpose these are used only on admin pages
     94        if(is_admin())
     95        {
     96            add_action('admin_menu', [$this, 'admin_menu']);
     97            add_action('admin_enqueue_scripts', [$this, 'admin_scripts']);
     98            add_action('admin_notices', [$this, 'admin_notice_show']);
     99            add_filter('plugin_action_links', [$this, 'plugin_action_links'], 10, 2);
     100        }
     101
     102
    92103
    93104        /* ajax actions add only in ajax page */
     
    98109            add_action('wp_ajax_vphrm_mode_change', [$this, 'vphrm_mode_change']);
    99110            add_action('wp_ajax_vphrm_disable_logging', [$this, 'vphrm_disable_logging']);
     111            add_action('wp_ajax_vphrm_load_must_use', [$this, 'vphrm_load_must_use']);
    100112            add_action('wp_ajax_vphrm_save_view', [$this, 'vphrm_save_view']);
    101113            add_action('wp_ajax_vphrm_custom_rule_save', [$this, 'vphrm_custom_rule_save']);
     
    107119        // plugin uninstallation. ALWAYS USE STATIC METHOD
    108120        register_uninstall_hook(__FILE__, ['HTTP_Requests_Manager', 'db_uninstall']);
     121        register_activation_hook(__FILE__, ['HTTP_Requests_Manager', 'plugin_activate']);
     122        register_deactivation_hook(__FILE__, ['HTTP_Requests_Manager', 'plugin_deactivate']);
    109123
    110124        $this->manage();
     
    158172    static public function current_page_is_my_ajax()
    159173    {
    160         $arr_prevent_for_actions = array(
     174        $arr_my_ajax_actions = array(
    161175            'vphrm_query'                => true,
    162176            'vphrm_clear'                => true,
    163177            'vphrm_disable_logging'      => true,
     178            'vphrm_load_must_use'        => true,
    164179            'vphrm_save_view'            => true,
    165180            'vphrm_custom_rule_save'     => true,
     
    171186        $action = empty($_POST['action']) ? '' : sanitize_text_field($_POST['action']);
    172187
    173         if(wp_doing_ajax() && !empty($action) && !empty($arr_prevent_for_actions[$action]))
     188        if(wp_doing_ajax() && !empty($action) && !empty($arr_my_ajax_actions[$action]))
    174189        {
    175190            // ajax page with my own requet
     
    300315    }
    301316
     317    function admin_notice_show()
     318    {
     319        $screen = get_current_screen();
     320
     321        // show only on plugin page
     322        //To get the exact your screen ID just do var_dump($screen)
     323        if($screen->id === 'tools_page_http-requests-manager')
     324        {
     325            // check MU plugin and show notification if needed
     326            // fix if option and MU file do not match
     327            $check = self::load_must_use_check();
     328            if($check['status'] === 'error')
     329            {
     330                // show notification
     331                echo '<div class="notice notice-warning is-dismissible">'
     332                . '<p>' . esc_html($check['message']) . '</p>'
     333                . '</div>';
     334            }
     335        }
     336    }
     337
    302338    function admin_scripts($hook)
    303339    {
     
    403439        }
    404440
     441
     442        wp_send_json($output);
     443    }
     444
     445    /**
     446     * copy MU file to MU plugin folder
     447     */
     448    private static function load_must_use_set()
     449    {
     450        $src = VPHRM_DIR . self::$mu_plugin_file_name;
     451        $dest = WPMU_PLUGIN_DIR . self::$mu_plugin_file_name;
     452
     453        $output = array();
     454
     455        // create mu dir
     456        if(!is_dir(WPMU_PLUGIN_DIR) && !wp_mkdir_p(WPMU_PLUGIN_DIR))
     457        {
     458            $output['status'] = 'error';
     459            $output['message'] = __('Error creating MU plugins directory.', 'http-requests-manager');
     460
     461            return $output;
     462        }
     463
     464        // remove old file if exists
     465        if(file_exists($dest) && !unlink($dest))
     466        {
     467            $output['status'] = 'error';
     468            $output['message'] = __('Error deleting old MU file', 'http-requests-manager');
     469
     470            return $output;
     471        }
     472
     473        // copy new MU file
     474        if(!file_exists($src) || !copy($src, $dest))
     475        {
     476            $output['status'] = 'error';
     477            $output['message'] = __('Error copying plugin file to MU plugins directory.', 'http-requests-manager');
     478
     479            return $output;
     480        }
     481
     482
     483        // file copied
     484        $output['status'] = 'ok';
     485        $output['message'] = __('MU plugin file set.', 'http-requests-manager');
     486        return $output;
     487    }
     488
     489    /**
     490     * remove MU file from MU plugin folder
     491     */
     492    private static function load_must_use_remove()
     493    {
     494        $dest = WPMU_PLUGIN_DIR . self::$mu_plugin_file_name;
     495
     496        $output = array();
     497
     498        // remove old file if exists
     499        if(file_exists($dest) && !unlink($dest))
     500        {
     501            $output['status'] = 'error';
     502            $output['message'] = __('Error deleting old MU file', 'http-requests-manager');
     503
     504            return $output;
     505        }
     506
     507        // file removed
     508        $output['status'] = 'ok';
     509        $output['message'] = __('MU file deleted.', 'http-requests-manager');
     510        return $output;
     511    }
     512
     513    /**
     514     * check if MU file matches selected loading option
     515     */
     516    private static function load_must_use_check()
     517    {
     518        // current status of must use
     519        $load_must_use_status = '';
     520        if(defined('VPHRM_MODE_INIT') && VPHRM_MODE_INIT)
     521        {
     522            // set
     523            $load_must_use_status = 'set';
     524        }
     525        if(defined('VPHRM_MODE') && VPHRM_MODE)
     526        {
     527            // loaded
     528            $load_must_use_status = 'loaded';
     529        }
     530
     531        // instruction
     532        $instruction = __('Please update "Load before other plugins" option in "Settings" tab.', 'http-requests-manager');
     533
     534        $output = array();
     535
     536        //  check option to priority loading and add MU file
     537        if(self::get_option('load_must_use'))
     538        {
     539            // option enabled: set must use plugin if not already set and running
     540            if($load_must_use_status === 'loaded')
     541            {
     542                // it is set and loaded. no problem
     543            }
     544            elseif($load_must_use_status === 'set')
     545            {
     546                // it is set but not loaded probably error loading plugin. just show warning message
     547                $output['status'] = 'error';
     548                $output['message'] = __('"Load before other plugins" option enabled but not loaded.', 'http-requests-manager') . ' ' . $instruction;
     549            }
     550            else
     551            {
     552                // set it and check for error
     553                $set = self::load_must_use_set();
     554                if($set['status'] === 'error')
     555                {
     556                    // remove option
     557                    self::update_option('load_must_use', 0);
     558
     559                    $output['status'] = 'error';
     560                    $output['message'] = __('Error setting "Load before other plugins" option.', 'http-requests-manager') . ' ' . $instruction;
     561                }
     562            }
     563        }
     564        else
     565        {
     566            // option diabled: MU should not be used
     567            if($load_must_use_status === 'set' || $load_must_use_status === 'loaded')
     568            {
     569                // remove MU if it exists
     570                $removed = self::load_must_use_remove();
     571                if($removed['status'] === 'error')
     572                {
     573                    $output['status'] = 'error';
     574                    $output['message'] = __('"Load before other plugins" option is not disabled.', 'http-requests-manager') . ' ' . $instruction;
     575                }
     576            }
     577        }
     578
     579
     580        // no error then ok
     581        if(empty($output))
     582        {
     583            $output['status'] = 'ok';
     584            $output['message'] = __('"Load before other plugins" option works as expected', 'http-requests-manager');
     585        }
     586
     587        return $output;
     588    }
     589
     590    /**
     591     * remove MU file from MU plugin folder
     592     */
     593    private static function load_must_use_apply()
     594    {
     595        //  check option to priority loading and add MU file
     596        if(self::get_option('load_must_use'))
     597        {
     598            // set must use plugin
     599            self::load_must_use_set();
     600        }
     601        else
     602        {
     603            // remove must use plugin if it exists
     604            self::load_must_use_remove();
     605        }
     606    }
     607
     608    function vphrm_load_must_use()
     609    {
     610        $this->validate();
     611
     612        $load_must_use = empty($_POST['load_must_use']) ? 0 : 1;
     613
     614        // depending on $load_must_use value add or remove a-http-requests-manager.php file from mu-plugins folder
     615        if($load_must_use)
     616        {
     617            $file_output = self::load_must_use_set();
     618        }
     619        else
     620        {
     621            $file_output = self::load_must_use_remove();
     622        }
     623
     624        if($file_output['status'] === 'ok')
     625        {
     626            // file operation ok. save option
     627            $output = array();
     628            if(self::update_option('load_must_use', $load_must_use))
     629            {
     630                $output['status'] = 'ok';
     631                $output['message'] = __('Option saved', 'http-requests-manager');
     632                $output['load_must_use'] = $load_must_use;
     633            }
     634            else
     635            {
     636                $output['status'] = 'error';
     637                $output['message'] = __('Error saving option. Please try again.', 'http-requests-manager');
     638            }
     639        }
     640        else
     641        {
     642            // pass error message to json
     643            $output = $file_output;
     644        }
    405645
    406646        wp_send_json($output);
     
    609849            $this->append_request_info($parsed_args, $url);
    610850
    611             // cron|ajax|rest_api|login|admin|frontend
     851            // cron|ajax|rest_api|xmlrpc|login|admin|frontend
    612852            $current_where = self::current_page_type();
    613853
     
    7831023    }
    7841024
    785     function start_timer($args)
     1025    function start_timer($args = array())
    7861026    {
    7871027        self::cp('[start] request');
     
    13341574        add_action('plugins_loaded', ['HTTP_Requests_Manager', 'cp_hook_start'], 0);
    13351575        add_action('plugins_loaded', ['HTTP_Requests_Manager', 'cp_hook_plugins_loaded'], PHP_INT_MAX);
     1576        add_action('muplugins_loaded', ['HTTP_Requests_Manager', 'cp_hook_plugins_loaded'], PHP_INT_MAX);
    13361577    }
    13371578
     
    15871828    {
    15881829        //echo '<!-- manage_timeout ('.$time.','.$url.') -->';
    1589         return min(1, $time);
     1830        return min(self::TIMEOUT, $time);
    15901831    }
    15911832
     
    15991840    {
    16001841        // fix request time and retries count here as well
    1601         $default_time = 1;
    1602 
    1603         // custom timings
     1842        $default_time = self::TIMEOUT;
     1843
     1844        // custom timings. add custom timeout per url here.
    16041845        $custom_time = array(
    1605             'api.wordpress.org/plugins/info/' => 2
     1846                /* 'api.wordpress.org/plugins/info/' => 2  */
    16061847        );
    16071848
     
    17181959        if(self::$request_action === 'block')
    17191960        {
    1720             $response = new WP_Error('http_request_not_executed', __('User has blocked requests through HTTP. (HTTP Requests Manager plugin: ' . self::$request_action_info . ')'));
    1721             /** This action is documented in wp-includes/class-wp-http.php */
    1722             do_action('http_api_debug', $response, 'response', 'WpOrg\Requests\Requests', $parsed_args, $url);
    1723             return $response;
     1961            return $this->manage_perform_request_blocking($parsed_args, $url);
    17241962        }
    17251963
    17261964        // pass without blocking
    17271965        return $pre;
     1966    }
     1967
     1968    /**
     1969     * Create error response for blocked request.
     1970     * Initiate recording to DB by calling action http_api_debug
     1971     * Return response error WP_Error.
     1972     * Used to record and response error message.
     1973     *
     1974     * Also can be used to prevent pingbacks and enclosure checking calls without even starting any request. 
     1975     *
     1976     * @param type $parsed_args
     1977     * @param type $url
     1978     * @return \WP_Error
     1979     */
     1980    function manage_perform_request_blocking($parsed_args, $url)
     1981    {
     1982        $response = new WP_Error('http_request_not_executed', __('User has blocked requests through HTTP. (HTTP Requests Manager plugin: ' . self::$request_action_info . ')'));
     1983
     1984        /** This action is documented in wp-includes/class-wp-http.php */
     1985        do_action('http_api_debug', $response, 'response', 'WpOrg\Requests\Requests', $parsed_args, $url);
     1986
     1987        return $response;
     1988    }
     1989
     1990    /**
     1991     * Capture prevented requests before initiating any WP_HTTP calls.
     1992     *
     1993     * Used in disable_self_ping() and disable_not_obvious_enclosure_links() when removing urls from initiating request.
     1994     *
     1995     * @param type $url
     1996     * @return type
     1997     */
     1998    function manage_perform_request_blocking_by_url($url, $info = '')
     1999    {
     2000        $this->start_timer();
     2001
     2002        self::$request_action = 'block';
     2003        self::$request_action_info = 'prevented';
     2004
     2005        if(!empty($info))
     2006        {
     2007            self::$request_action_info .= ' ' . $info;
     2008        }
     2009
     2010        return $this->manage_perform_request_blocking(array(), $url);
    17282011    }
    17292012
     
    17722055            }
    17732056
    1774            
     2057
    17752058            self::$page_info['manager_mode'] = self::get_mode();
    17762059            self::$page_info['timer_before'] = self::$timer_before;
    17772060        }
    1778        
     2061
    17792062        // is_user_logged_in() is pluggable function and will be loaded before init event. use it only if it is already loaded.
    17802063        if(!isset(self::$page_info['is_user_logged_in']) && function_exists('is_user_logged_in'))
     
    17822065            self::$page_info['is_user_logged_in'] = is_user_logged_in();
    17832066        }
    1784        
     2067
    17852068
    17862069        // updated data
     
    20892372    /**
    20902373     * Return current page type.
    2091      *
    2092      * @return string cron|ajax|rest_api|login|admin|frontend
     2374     * Id adding new page type update self::$page_types array with new page type group
     2375     *
     2376     * @return string cron|ajax|rest_api|xmlrpc|login|admin|frontend
    20932377     */
    20942378    static public function current_page_type()
     
    21122396            {
    21132397                $return = 'rest_api';
     2398            }
     2399
     2400            if(is_null($return) && (defined('XMLRPC_REQUEST') && XMLRPC_REQUEST ))
     2401            {
     2402                $return = 'xmlrpc';
    21142403            }
    21152404
     
    21672456        // disable self ping. disable ping to internal images and urls when publishing post. useless and takes long for page with 20+ internal links/images
    21682457        add_action('pre_ping', [$this, 'disable_self_ping']);
     2458
     2459        // prevent enclosure requests to non video/music files
     2460        add_filter('enclosure_links', [$this, 'disable_not_obvious_enclosure_links'], 10, 2);
    21692461
    21702462        // disable maybe update checks in admin
     
    23432635
    23442636    /**
     2637     * disable non audio/video enclosure links
     2638     *
     2639     * @param type $post_links
     2640     * @param type $post_id
     2641     * @return type
     2642     */
     2643    function disable_not_obvious_enclosure_links($post_links, $post_id)
     2644    {
     2645        $post_links_new = array();
     2646        // allow only mp3, mp4 urls
     2647        if($post_links)
     2648        {
     2649            // enclosures can be audio or video. keep them.
     2650            // use only: ext -> audio/video mime types
     2651            $mime_types = wp_get_mime_types();
     2652            $mime_types_allowed = array();
     2653            foreach($mime_types as $exts => $mime)
     2654            {
     2655                if(strpos($mime, 'audio/') === 0 || strpos($mime, 'video/') === 0)
     2656                {
     2657                    $mime_types_allowed[$exts] = $mime;
     2658                }
     2659            }
     2660
     2661
     2662            // make unique post links
     2663            $post_links_unique = array();
     2664            foreach($post_links as $url)
     2665            {
     2666                $url = strip_fragment_from_url($url);
     2667                $post_links_unique[$url] = true;
     2668            }
     2669            $post_links = array_keys($post_links_unique);
     2670            unset($post_links_unique);
     2671
     2672            // check extension of url and keep mp3,mp4 urls only. other types are not enclosed anyway.
     2673            foreach($post_links as $url)
     2674            {
     2675                // check if it is not already added
     2676                if(!isset($post_links_new[$url]))
     2677                {
     2678                    $url_parts = parse_url($url);
     2679
     2680                    if(false !== $url_parts && !empty($url_parts['path']))
     2681                    {
     2682                        $extension = pathinfo($url_parts['path'], PATHINFO_EXTENSION);
     2683                        if(!empty($extension))
     2684                        {
     2685                            foreach($mime_types_allowed as $exts => $mime)
     2686                            {
     2687                                if(preg_match('!^(' . $exts . ')$!i', $extension))
     2688                                {
     2689                                    // allowed extension. can be enclosed
     2690                                    $post_links_new[$url] = true;
     2691                                    break;
     2692                                }
     2693                            }
     2694                        }
     2695                    }
     2696                }
     2697
     2698                // record as prevented request if not enclosable
     2699                if(!isset($post_links_new[$url]))
     2700                {
     2701                    $this->manage_perform_request_blocking_by_url($url, 'enclosure_links');
     2702                }
     2703            }
     2704        }
     2705
     2706        // return unique urls
     2707        return array_keys($post_links_new);
     2708    }
     2709
     2710    /**
    23452711     *  add settings link to plugin listing
    23462712     */
     
    23592725        }
    23602726        return $links;
     2727    }
     2728
     2729    /**
     2730     *  remove some features on deactivation
     2731     */
     2732    public static function plugin_deactivate()
     2733    {
     2734        //  remove MU Must-Use plugin file if exists
     2735        self::load_must_use_remove();
     2736    }
     2737
     2738    /**
     2739     *  perform on plugin activation
     2740     */
     2741    public static function plugin_activate()
     2742    {
     2743        self::load_must_use_apply();
    23612744    }
    23622745
     
    27933176                // unset later because unsetting here will skip some links as array size changes inside this loop.
    27943177                // unset($links[$l]);
     3178
     3179                $this->manage_perform_request_blocking_by_url($link, 'pre_ping');
    27953180            }
    27963181        }
  • http-requests-manager/tags/1.3.0/readme.txt

    r3034389 r3081974  
    55Requires at least: 4.9
    66Tested up to: 6.4
    7 Stable tag: 1.2.4
     7Stable tag: 1.3.0
    88License: GPLv2
    99
     
    1212== Description ==
    1313
    14 = Prevent WP HTTP request to slow down your WordPress website and admin interface =
     14= Prevent WP HTTP requests from slowing down your WordPress website and admin interface =
    1515
    1616Do you have a slow WordPress admin that takes longer than usual to load? Sometime longer than 5 seconds to load admin or login pages. In rare occasions WordPress may even timeout and show 504 page.
    1717
    18 Reason may be slow external WP_HTTP requests. [HTTP Requests Manager plugin](https://veppa.com/http-requests-manager/) will log all WP HTTP requests with time taken to complete each request. If there are multiple request per page they will be color grouped.
    19 
    20 Plugin tested  with PHP version 5.6, 7.x and up to 8.2.
     18Reason may be slow external WP_HTTP requests. [HTTP Requests Manager plugin](https://veppa.com/http-requests-manager/) will log all WP HTTP requests with time taken to complete for each request. If there are multiple requests per page they will be color grouped.
     19
     20Plugin tested with PHP version 5.6, 7.x and up to 8.3.
    2121
    2222= Do not confuse WP_HTTP request with HTML requests that loads page assets like js, css, image, font =
     
    2626Plugin will not detect any requests made by other WordPress classes like WP_Http_Curl or PHP functions like curl_exec, fsockopen, file_get_contents etc.
    2727
    28 Do not confuse it with HTML requests (loading assets like css, js, image) done by HTML page.  WP_Http requests are performed only inside PHP files and not visible in web browser.
     28Do not confuse it with HTML requests (loading assets like css, js, image) done by HTML page. WP_Http requests are performed only inside PHP files and not visible in web browser.
    2929
    3030[Learn more about difference between WP_Http requests and HTML requests](https://veppa.com/http-requests-manager/#what_is_detected_with_http_requests_manager)
    3131
    32 = How plugin prevents slow pages containing WP_HTTP requests?  =
     32= How plugin prevents slow pages containing WP_HTTP requests? =
    3333
    3434Plugin helps to prevent website slowdown by:
    3535
    36 * Sets request timeout period to 1 second. Where default is 5.
     36* Sets request timeout period to 2 second. Where default is 5.
    3737* Limit number of request per page by 3. Default is unlimited.
    3838* Limit WP HTTP request if page load time is longer than 3 seconds. Default is unlimited.
     
    4949    1. Page processing time exceeded 3 seconds.
    5050    2. Number of request for single page reached 3.
    51     3. Sets timeout for each request to 1 second.
     51    3. Sets timeout for each request to 2 second.
    5252    4. Sets number of redirects for request to 1.
    5353    5. Apply custom rules for "Smart block" defined in settings.
    54     6. Prevent some built in requests: happy browser, maybe update, self pings.
    55     7. Skip limitations listed above for: file downloads (plugin, theme, other), requests inside cron jobs.
     54    6. Prevent some built in requests: happy browser, maybe update, self pings, do_enclose.
     55    7. Skip some limitations listed above for: file downloads (plugin, theme, other), requests inside cron jobs.
    5656- **Block external requests** — all requests not matching your current domain will be blocked. No updates for WordPress core, plugins and themes. (+ Smart block features.)
    5757- **Block external requests (allow WordPress.org only)** — all requests not matching your current domain and wordpress.org will be blocked. Allows updates for WordPress core, plugins and themes coming from wordpress.org website. (+ Smart block features.)
     
    6363After using plugin for some time and knowing which requests are performed you can disable logging. Operation mode will remain unchanged. Request blocking will remain in tact. No new logs will be recorded. You can analyze old logs, they will not be deleted.
    6464
     65= Load before other plugins  =
     66
     67In order to catch more requests you can enable "Load before other plugins" option. It uses Must-Use plugin feature and load before other regular plugins. This way you will make sure to detect all WP_HTTP requests by other plugins.
    6568
    6669= Custom rules for "Smart Block" mode =
     
    7275= Features =
    7376
     77* View performance improvement of your WordPress website due to blocking some remote HTTP requests.
    7478* View blocked requests by this plugin. Show reason why it was blocked.
    7579* View failed requests with error message.
    7680* View what initiated HTTP request: WordPress core, plugin or theme.
    77 * View on which page request was made. Also view page type is frontend, admin, login, cron, ajax or rest_api.
     81* View on which page request was made. Also view page type is frontend, admin, login, cron, ajax, xmlrpc or rest_api.
    7882* View list of other requests made on same page view.
    7983* View sent and received data.
     
    125129== Screenshots ==
    126130
    127 1. Screenshot shows latest HTTP requests and reason why they are blocked. Also summary show at the top with total percentage of blocked requests (63% in current view). Hosts card shows that there are 7 different hosts were requests sent. When you hover over card tooltip will show breakdown of hosts in percentage. We can see that 73% or requests were made to api.wordpress.org website. Also we can see that plugins actively using external requests to load data and some promotions from their servers.
    128 
    129 2. WP_HTTP request and response data. Popup opens when you click on request from table. Page and request times shows as well.
    130 
    131 3. Blocked request due to page time exceeding 3 seconds. Additional information regarding page shown with currently active manager mode.
    132 
    133 4. Check point shows how plugins and requests effect page time and memory usage.
    134 
    135 5. Group requests to simplify report. You can group by request domain, page type, initiator, response status etc. Bar colors will visually indicate requests by response status as blocked orange, success green, error red.
    136 
    137 6. Requests grouped by initiator core / theme / plugin. Clicking on group will reveal requests inside that group.
    138 
    139 7. Settings page to select operation mode, disable logging and adding custom rules. Settings will be saved each time when you change any option.
    140 
    141 8. Select operation mode to fit your need. Only blocking modes will speed up WordPress admin pages. Be aware that blocking modes may break functionality of some plugins that rely on external API requests.
    142 
    143 9. Define custom rules to always allow some plugins or domains only in "Smart block" mode. Custom rules will be ordered by high priority. First matching rule will be applied.
     1311. Screenshot shows latest HTTP requests and reason why they are blocked. Summary cards at the top show total percentage of blocked requests (54% in current view). You can also see estimated performance improvement 2.2x because of blocking some remote requests. Hosts card shows that there are 3 different hosts were requests sent. When you hover over card tooltip will show breakdown of hosts in percentage. We can see that 31% or requests were made to api.wordpress.org website. Also we can see that plugins actively using external requests to load data and some promotions from their servers.
     132
     1332. When Smart Block enabled total page generation time will be limited to 3 seconds. Page with 10 requests, will improve from 11-12 seconds to 3 seconds, regardless of web hosting resources. 
     134
     1353. WP_HTTP request and response data. Popup opens when you click on request from table. Page and request times shows as well.
     136
     1374. Blocked request due to page time exceeding 3 seconds. Additional information regarding page shown with currently active manager mode.
     138
     1395. Check point shows how plugins and requests effect page time and memory usage.
     140
     1416. Group requests to simplify report. You can group by request domain, page type, initiator, response status etc. Bar colors will visually indicate requests by response status as blocked orange, success green, error red.
     142
     1437. Requests grouped by initiator core / theme / plugin. Clicking on group will reveal requests inside that group.
     144
     1458. Settings page to select operation mode, disable logging and adding custom rules. Settings will be saved each time when you change any option.
     146
     1479. Select operation mode to fit your need. Only blocking modes will speed up WordPress admin pages. Be aware that blocking modes may break functionality of some plugins that rely on external API requests.
     148
     14910. Define custom rules to always allow some plugins or domains only in "Smart block" mode. Custom rules will be ordered by high priority. First matching rule will be applied.
    144150
    145151
     
    162168All pages with WP_HTTP requests are recorded. Slow pages without any WP_HTTP requests are not recorded.
    163169
     170= Which remote requests are not detected? =
     171
     172This plugin detects only requests made using [WP_HTTP](https://developer.wordpress.org/reference/classes/wp_http/) class defined by WordPress. It is preferred way of doing remote requests. WordPress core and most plugins/themes use it.
     173
     174Plugin will not detect requests made using other classes and functions. For example remote requests made with WordPress class [WP_Http_Curl](https://developer.wordpress.org/reference/classes/wp_http_curl/) (deprecated starting from WordPress version 6.4) or PHP functions like curl_exec, fsockopen, file_get_contents are not detected by this plugin.  Because they do not have hooks similar to WordPress to manage requests before making them.
     175
     176Unfortunately when plugin/theme uses other functions (not WP_HTTP class) they will not be detected by this plugin. 
     177
     178= How much performance improvement can be gained? =
     179
     180Performance gain on pages with WP_HTTP requests can be up to 5x. It all depends on which blocking method used and how heavyly remote requests are used by core and pugins.
     181
     182= Are all WordPress pages have WP_HTTP requests? =
     183
     184No. WP_HTTP requests are performed periodically or on certain action. When you check logged requests, there will be around 50-100 pages with requests per day. On website with 10k daily page views (human and bot traffic) it will make around 1% of all pages.
     185
     186= How can I feel speed improvement provided by this plugin? =
     187
     188You will most likely feel speed difference in admin area. Pages previously loading slowly or timing out regularly should load much faster.
     189
    164190== Changelog ==
    165191
     192= 1.3.0 - 6 May 2024 =
     193
     194* Added: priority loading mode using MU plugin feature. Plugin will load as Must-Use plugin before other plugins for catching as many requests as possible.
     195* Added: Prevent requests initiated by do_enclose function after adding/updating post with images and links. Every time when post saved all links inside post will be requested for checking their file type. For example post with 20 links and 10 images will make 30 requests to check file type for each URL. Only audio and video URLs are saved as enclosure. Other requests are not used and wastes server resources. This request prevention will eliminate tens of requests to non audio/video URLs. When enabled related cron request for post with 30 URLs will finish in 1 second instead of 30 seconds.
     196* Added: Log prevented requests for better understanding what is changed after enabling some blocking mode. Previously prevented self pings and do_enclose requests were not logged.
     197* Added: Calls from xmlrpc.php file are moved to new page group called "xmlrpc" from previous "frontend".
     198* Added: Summary card showing average performance improvement occurred due to blocking some remote API/HTTP requests.
     199* Fixed: increased request timeout from 1 second to 2 seconds for allowing enough time to complete CURL calls made to HTTPS servers.
     200* Fixed: responses to non streaming requests will be grouped as "success" instead of "error".
     201
    166202= 1.2.4 - 12 February 2024 =
    167203
    168 *  Fixed: prevent calling is_user_logged_in function when it is not declared.
     204* Fixed: prevent calling is_user_logged_in function when it is not declared.
    169205
    170206= 1.2.3 - 30 November 2023 =
    171207
    172 *  Fixed: Domain select box population when adding new Custom Rule.
     208* Fixed: Domain select box population when adding new Custom Rule.
    173209
    174210= 1.2.2 - 29 November 2023 =
    175211
    176 *  Fixed: Variable name typo inside get_arr_val function.
     212* Fixed: Variable name typo inside get_arr_val function.
    177213
    178214
    179215= 1.2.1 - 29 November 2023 =
    180216
    181  * Fixed: Incorrect links in options page.
     217* Fixed: Incorrect links in options page.
    182218
    183219
    184220= 1.2.0 - 28 November 2023 =
    185221
    186  *  Added: Separate tabs for log, settings, more tools
    187  *  Added: Group request logs by URL, domain, page, page type, plugin, response status etc. Better for viewing important information.
    188  * Added: Custom rules to block/allow by all/domain/plugin in everywhere/admin/frontend/ajax/cron/rest_api/login. Maximum 10 custom rules can be added. Custom rules apply only in smart block mode.
    189  *  Added: Option to disable logging. Old logs can be viewed. Plugin will work a bit faster when logging disabled.
    190  *  Added: Disable self ping (only when blocking in "smart block+" mode). Self ping sends pings to images and links on same domain. Post with 20+ links and images will take 10+ seconds to send self pings.
    191  *  Added: Disable auto update check on admin page in "smart block+" mode. _maybe_update_core, _maybe_update_themes, _maybe_update_plugins slows down admin pages up to 5+ seconds on first visit after 12 hours and can even timeout. Update checks via cron is not effected.
    192  * Fixed: Undefined array key "file" error
    193  *  Update: Store last 1k records
     222* Added: Separate tabs for log, settings, more tools
     223* Added: Group request logs by URL, domain, page, page type, plugin, response status etc. Better for viewing important information.
     224* Added: Custom rules to block/allow by all/domain/plugin in everywhere/admin/frontend/ajax/cron/rest_api/login. Maximum 10 custom rules can be added. Custom rules apply only in smart block mode.
     225* Added: Option to disable logging. Old logs can be viewed. Plugin will work a bit faster when logging disabled.
     226* Added: Disable self ping (only when blocking in "smart block+" mode). Self ping sends pings to images and links on same domain. Post with 20+ links and images will take 10+ seconds to send self pings.
     227* Added: Disable auto update check on admin page in "smart block+" mode. _maybe_update_core, _maybe_update_themes, _maybe_update_plugins slows down admin pages up to 5+ seconds on first visit after 12 hours and can even timeout. Update checks via cron is not effected.
     228* Fixed: Undefined array key "file" error
     229* Update: Store last 1k records
    194230
    195231= 1.1.0 - 12 June 2023 =
  • http-requests-manager/tags/1.3.0/templates/page-settings.php

    r3003727 r3081974  
    5353                                — <a href="#help"><?php echo __('Which one to choose?', 'http-requests-manager'); ?></a>
    5454                            </p>
     55                        </td>
     56                    </tr>
     57                    <tr>
     58                        <th scope="row"><label><?php _e('Load before other plugins', 'http-requests-manager'); ?></label></th>
     59                        <td>
     60                            <input type="checkbox" name="load_must_use" value="1" id="load_must_use" <?php echo (HTTP_Requests_Manager::get_option('load_must_use') ? ' checked="checked"' : '') ?> />
     61                            <label for="load_must_use">Enable priority loading with Must-Use plugin feature.</label>
    5562                        </td>
    5663                    </tr>
     
    152159                            <li><?php _e('Page processing time exceeded 3 seconds.', 'http-requests-manager'); ?></li>
    153160                            <li><?php _e('Number of request for single page reached 3.', 'http-requests-manager'); ?></li>
    154                             <li><?php _e('Sets timeout for each request (except file downloads) to 1 second.', 'http-requests-manager'); ?></li>
     161                            <li><?php _e('Sets timeout for each request (except file downloads) to 2 second.', 'http-requests-manager'); ?></li>
    155162                            <li><?php _e('Sets number of redirects for request to 1.', 'http-requests-manager'); ?></li>               
    156163                            <li><?php _e('Apply custom rules for "Smart block" defined in settings.', 'http-requests-manager'); ?></li>             
    157                             <li><?php _e('Prevent some built in requests: happy browser, maybe update, self pings.', 'http-requests-manager'); ?></li>             
     164                            <li><?php _e('Prevent some built in requests: happy browser, maybe update, self pings, do_enclose.', 'http-requests-manager'); ?></li> 
     165                            <li><?php _e('Skip some limitations listed above for: file downloads (plugin, theme, other), requests inside cron jobs.', 'http-requests-manager'); ?></li>
    158166                        </ol>
    159167                    </li>
  • http-requests-manager/trunk/assets/js/admin.js

    r3003727 r3081974  
    193193                status = 'blocked';
    194194            }
    195             else if (row.status_code == '200')
    196             {
    197 
     195            else if (row.status_code == '200' || !request_args.blocking)
     196            {
    198197                status = 'success';
    199198            }
     
    652651                stats.req_type_summary = VPHRM.summarize_data(stats.req_types, 0);
    653652                stats.req_source_summary = VPHRM.summarize_data(stats.req_sources, 10);
     653                stats.num_allowed = stats.requests - stats.num_blocked;
     654                stats.num_performance = stats.num_allowed ? (stats.requests / stats.num_allowed).toFixed(1) * 1 : 10;
    654655                stats.message = [
     656                    '<span class="vphrm-card" title="' + (stats.num_blocked ? stats.num_performance + '×' : '-') + ' performance improvement">'
     657                            + '<span class="vphrm-card-val">'
     658                            + (stats.num_blocked ? stats.num_performance + '×' : '-')
     659                            + '</span>'
     660                            + '<span class="vphrm-card-name">'
     661                            + 'Performance imp.'
     662                            + '</span>'
     663                            + '</span>',
    655664                    '<span class="vphrm-card" title="' + stats.num_blocked + ' requests blocked out of ' + stats.requests + "\nRequest sources:\n" + stats.req_source_summary + '">'
    656665                            + '<span class="vphrm-card-val">'
     
    968977        };
    969978
     979
     980        VPHRM.change_load_must_use = function ()
     981        {
     982            var $me = $(this);
     983            var checked = $me.is(':checked');
     984            $me.attr('disabled', 'disabled');
     985            $.post(ajaxurl, {
     986                'action': 'vphrm_load_must_use',
     987                '_wpnonce': VPHRM.nonce,
     988                'load_must_use': checked ? 1 : 0
     989            }, function (data)
     990            {
     991                if (data.status == 'ok')
     992                {
     993                    // saved
     994                }
     995                else
     996                {
     997                    // data error
     998                    alert(data.message);
     999                    // revert to old cheched/unchecked state
     1000                    $me.prop('checked', !checked);
     1001
     1002                }
     1003
     1004            }, 'json')
     1005                    .fail(function (jqXHR, textStatus, error)
     1006                    {
     1007                        console.log(VPHRM.message_save_error + ": " + error);
     1008                        alert(VPHRM.message_save_error + ": " + error);
     1009                        // revert to old cheched/unchecked state
     1010                        $me.prop('checked', !checked);
     1011                    })
     1012                    .always(function ()
     1013                    {
     1014                        $me.removeAttr('disabled');
     1015                    });
     1016        };
     1017
     1018
     1019
    9701020        VPHRM.view_save = function ()
    9711021        {
     
    12181268            //
    12191269            $(document).on('change', 'input#disable_logging[type="checkbox"]', VPHRM.change_logging);
     1270            $(document).on('change', 'input#load_must_use[type="checkbox"]', VPHRM.change_load_must_use);
    12201271
    12211272            // change view group
  • http-requests-manager/trunk/http-requests-manager.php

    r3034389 r3081974  
    55  Plugin URI:   https://veppa.com/http-requests-manager/
    66  Description: Limit, disable, block, log all WP HTTP requests. Limit by request count, page load time or lower timeout for each request. Speed up login and admin pages.
    7   Version: 1.2.4
     7  Version: 1.3.0
    88  Author: veppa
    99  Author URI: https://veppa.com/
     
    3232 * TODO:
    3333 *  - show 47% requests blocked in dashboard at a glance. with option to remove from there.
    34  *  - disable wp_get_http_headers inside do_enclose  called inside do_all_pings. it checks if links inside content has audio or video to enclose. it is slow inside cron call.
     34 *
    3535 */
    3636defined('ABSPATH') or exit;
     
    3939{
    4040
    41     const VERSION = '1.2.4';
     41    const VERSION = '1.3.0';
    4242    const ID = 'http-requests-manager';
     43    const TIMEOUT = 2;
    4344
    4445    public static $instance;
     
    5758    private static $custom_rules_limit = 10;
    5859    private static $page_id;
     60    private static $mu_plugin_file_name = '/a-http-requests-manager.php';
    5961    private static $requests = array();
    6062    private static $cron_status;
     
    6870        'cron',
    6971        'ajax',
    70         'rest_api'
     72        'rest_api',
     73        'xmlrpc'
    7174    );
    7275
     
    8285
    8386        add_action('init', [$this, 'init']);
    84         add_action('admin_menu', [$this, 'admin_menu']);
    85         add_action('admin_enqueue_scripts', [$this, 'admin_scripts']);
    8687        add_filter('http_request_args', [$this, 'start_timer']);
    8788        add_action('http_api_debug', [$this, 'db_capture_request'], 10, 5);
     
    8990        add_action('pre_get_ready_cron_jobs', [$this, 'cron_prevent_in_my_ajax']);
    9091        add_action('shutdown', [$this, 'db_update_page']);
    91         add_filter('plugin_action_links', [$this, 'plugin_action_links'], 10, 2);
     92
     93        // admin page actions only. for optimisation purpose these are used only on admin pages
     94        if(is_admin())
     95        {
     96            add_action('admin_menu', [$this, 'admin_menu']);
     97            add_action('admin_enqueue_scripts', [$this, 'admin_scripts']);
     98            add_action('admin_notices', [$this, 'admin_notice_show']);
     99            add_filter('plugin_action_links', [$this, 'plugin_action_links'], 10, 2);
     100        }
     101
     102
    92103
    93104        /* ajax actions add only in ajax page */
     
    98109            add_action('wp_ajax_vphrm_mode_change', [$this, 'vphrm_mode_change']);
    99110            add_action('wp_ajax_vphrm_disable_logging', [$this, 'vphrm_disable_logging']);
     111            add_action('wp_ajax_vphrm_load_must_use', [$this, 'vphrm_load_must_use']);
    100112            add_action('wp_ajax_vphrm_save_view', [$this, 'vphrm_save_view']);
    101113            add_action('wp_ajax_vphrm_custom_rule_save', [$this, 'vphrm_custom_rule_save']);
     
    107119        // plugin uninstallation. ALWAYS USE STATIC METHOD
    108120        register_uninstall_hook(__FILE__, ['HTTP_Requests_Manager', 'db_uninstall']);
     121        register_activation_hook(__FILE__, ['HTTP_Requests_Manager', 'plugin_activate']);
     122        register_deactivation_hook(__FILE__, ['HTTP_Requests_Manager', 'plugin_deactivate']);
    109123
    110124        $this->manage();
     
    158172    static public function current_page_is_my_ajax()
    159173    {
    160         $arr_prevent_for_actions = array(
     174        $arr_my_ajax_actions = array(
    161175            'vphrm_query'                => true,
    162176            'vphrm_clear'                => true,
    163177            'vphrm_disable_logging'      => true,
     178            'vphrm_load_must_use'        => true,
    164179            'vphrm_save_view'            => true,
    165180            'vphrm_custom_rule_save'     => true,
     
    171186        $action = empty($_POST['action']) ? '' : sanitize_text_field($_POST['action']);
    172187
    173         if(wp_doing_ajax() && !empty($action) && !empty($arr_prevent_for_actions[$action]))
     188        if(wp_doing_ajax() && !empty($action) && !empty($arr_my_ajax_actions[$action]))
    174189        {
    175190            // ajax page with my own requet
     
    300315    }
    301316
     317    function admin_notice_show()
     318    {
     319        $screen = get_current_screen();
     320
     321        // show only on plugin page
     322        //To get the exact your screen ID just do var_dump($screen)
     323        if($screen->id === 'tools_page_http-requests-manager')
     324        {
     325            // check MU plugin and show notification if needed
     326            // fix if option and MU file do not match
     327            $check = self::load_must_use_check();
     328            if($check['status'] === 'error')
     329            {
     330                // show notification
     331                echo '<div class="notice notice-warning is-dismissible">'
     332                . '<p>' . esc_html($check['message']) . '</p>'
     333                . '</div>';
     334            }
     335        }
     336    }
     337
    302338    function admin_scripts($hook)
    303339    {
     
    403439        }
    404440
     441
     442        wp_send_json($output);
     443    }
     444
     445    /**
     446     * copy MU file to MU plugin folder
     447     */
     448    private static function load_must_use_set()
     449    {
     450        $src = VPHRM_DIR . self::$mu_plugin_file_name;
     451        $dest = WPMU_PLUGIN_DIR . self::$mu_plugin_file_name;
     452
     453        $output = array();
     454
     455        // create mu dir
     456        if(!is_dir(WPMU_PLUGIN_DIR) && !wp_mkdir_p(WPMU_PLUGIN_DIR))
     457        {
     458            $output['status'] = 'error';
     459            $output['message'] = __('Error creating MU plugins directory.', 'http-requests-manager');
     460
     461            return $output;
     462        }
     463
     464        // remove old file if exists
     465        if(file_exists($dest) && !unlink($dest))
     466        {
     467            $output['status'] = 'error';
     468            $output['message'] = __('Error deleting old MU file', 'http-requests-manager');
     469
     470            return $output;
     471        }
     472
     473        // copy new MU file
     474        if(!file_exists($src) || !copy($src, $dest))
     475        {
     476            $output['status'] = 'error';
     477            $output['message'] = __('Error copying plugin file to MU plugins directory.', 'http-requests-manager');
     478
     479            return $output;
     480        }
     481
     482
     483        // file copied
     484        $output['status'] = 'ok';
     485        $output['message'] = __('MU plugin file set.', 'http-requests-manager');
     486        return $output;
     487    }
     488
     489    /**
     490     * remove MU file from MU plugin folder
     491     */
     492    private static function load_must_use_remove()
     493    {
     494        $dest = WPMU_PLUGIN_DIR . self::$mu_plugin_file_name;
     495
     496        $output = array();
     497
     498        // remove old file if exists
     499        if(file_exists($dest) && !unlink($dest))
     500        {
     501            $output['status'] = 'error';
     502            $output['message'] = __('Error deleting old MU file', 'http-requests-manager');
     503
     504            return $output;
     505        }
     506
     507        // file removed
     508        $output['status'] = 'ok';
     509        $output['message'] = __('MU file deleted.', 'http-requests-manager');
     510        return $output;
     511    }
     512
     513    /**
     514     * check if MU file matches selected loading option
     515     */
     516    private static function load_must_use_check()
     517    {
     518        // current status of must use
     519        $load_must_use_status = '';
     520        if(defined('VPHRM_MODE_INIT') && VPHRM_MODE_INIT)
     521        {
     522            // set
     523            $load_must_use_status = 'set';
     524        }
     525        if(defined('VPHRM_MODE') && VPHRM_MODE)
     526        {
     527            // loaded
     528            $load_must_use_status = 'loaded';
     529        }
     530
     531        // instruction
     532        $instruction = __('Please update "Load before other plugins" option in "Settings" tab.', 'http-requests-manager');
     533
     534        $output = array();
     535
     536        //  check option to priority loading and add MU file
     537        if(self::get_option('load_must_use'))
     538        {
     539            // option enabled: set must use plugin if not already set and running
     540            if($load_must_use_status === 'loaded')
     541            {
     542                // it is set and loaded. no problem
     543            }
     544            elseif($load_must_use_status === 'set')
     545            {
     546                // it is set but not loaded probably error loading plugin. just show warning message
     547                $output['status'] = 'error';
     548                $output['message'] = __('"Load before other plugins" option enabled but not loaded.', 'http-requests-manager') . ' ' . $instruction;
     549            }
     550            else
     551            {
     552                // set it and check for error
     553                $set = self::load_must_use_set();
     554                if($set['status'] === 'error')
     555                {
     556                    // remove option
     557                    self::update_option('load_must_use', 0);
     558
     559                    $output['status'] = 'error';
     560                    $output['message'] = __('Error setting "Load before other plugins" option.', 'http-requests-manager') . ' ' . $instruction;
     561                }
     562            }
     563        }
     564        else
     565        {
     566            // option diabled: MU should not be used
     567            if($load_must_use_status === 'set' || $load_must_use_status === 'loaded')
     568            {
     569                // remove MU if it exists
     570                $removed = self::load_must_use_remove();
     571                if($removed['status'] === 'error')
     572                {
     573                    $output['status'] = 'error';
     574                    $output['message'] = __('"Load before other plugins" option is not disabled.', 'http-requests-manager') . ' ' . $instruction;
     575                }
     576            }
     577        }
     578
     579
     580        // no error then ok
     581        if(empty($output))
     582        {
     583            $output['status'] = 'ok';
     584            $output['message'] = __('"Load before other plugins" option works as expected', 'http-requests-manager');
     585        }
     586
     587        return $output;
     588    }
     589
     590    /**
     591     * remove MU file from MU plugin folder
     592     */
     593    private static function load_must_use_apply()
     594    {
     595        //  check option to priority loading and add MU file
     596        if(self::get_option('load_must_use'))
     597        {
     598            // set must use plugin
     599            self::load_must_use_set();
     600        }
     601        else
     602        {
     603            // remove must use plugin if it exists
     604            self::load_must_use_remove();
     605        }
     606    }
     607
     608    function vphrm_load_must_use()
     609    {
     610        $this->validate();
     611
     612        $load_must_use = empty($_POST['load_must_use']) ? 0 : 1;
     613
     614        // depending on $load_must_use value add or remove a-http-requests-manager.php file from mu-plugins folder
     615        if($load_must_use)
     616        {
     617            $file_output = self::load_must_use_set();
     618        }
     619        else
     620        {
     621            $file_output = self::load_must_use_remove();
     622        }
     623
     624        if($file_output['status'] === 'ok')
     625        {
     626            // file operation ok. save option
     627            $output = array();
     628            if(self::update_option('load_must_use', $load_must_use))
     629            {
     630                $output['status'] = 'ok';
     631                $output['message'] = __('Option saved', 'http-requests-manager');
     632                $output['load_must_use'] = $load_must_use;
     633            }
     634            else
     635            {
     636                $output['status'] = 'error';
     637                $output['message'] = __('Error saving option. Please try again.', 'http-requests-manager');
     638            }
     639        }
     640        else
     641        {
     642            // pass error message to json
     643            $output = $file_output;
     644        }
    405645
    406646        wp_send_json($output);
     
    609849            $this->append_request_info($parsed_args, $url);
    610850
    611             // cron|ajax|rest_api|login|admin|frontend
     851            // cron|ajax|rest_api|xmlrpc|login|admin|frontend
    612852            $current_where = self::current_page_type();
    613853
     
    7831023    }
    7841024
    785     function start_timer($args)
     1025    function start_timer($args = array())
    7861026    {
    7871027        self::cp('[start] request');
     
    13341574        add_action('plugins_loaded', ['HTTP_Requests_Manager', 'cp_hook_start'], 0);
    13351575        add_action('plugins_loaded', ['HTTP_Requests_Manager', 'cp_hook_plugins_loaded'], PHP_INT_MAX);
     1576        add_action('muplugins_loaded', ['HTTP_Requests_Manager', 'cp_hook_plugins_loaded'], PHP_INT_MAX);
    13361577    }
    13371578
     
    15871828    {
    15881829        //echo '<!-- manage_timeout ('.$time.','.$url.') -->';
    1589         return min(1, $time);
     1830        return min(self::TIMEOUT, $time);
    15901831    }
    15911832
     
    15991840    {
    16001841        // fix request time and retries count here as well
    1601         $default_time = 1;
    1602 
    1603         // custom timings
     1842        $default_time = self::TIMEOUT;
     1843
     1844        // custom timings. add custom timeout per url here.
    16041845        $custom_time = array(
    1605             'api.wordpress.org/plugins/info/' => 2
     1846                /* 'api.wordpress.org/plugins/info/' => 2  */
    16061847        );
    16071848
     
    17181959        if(self::$request_action === 'block')
    17191960        {
    1720             $response = new WP_Error('http_request_not_executed', __('User has blocked requests through HTTP. (HTTP Requests Manager plugin: ' . self::$request_action_info . ')'));
    1721             /** This action is documented in wp-includes/class-wp-http.php */
    1722             do_action('http_api_debug', $response, 'response', 'WpOrg\Requests\Requests', $parsed_args, $url);
    1723             return $response;
     1961            return $this->manage_perform_request_blocking($parsed_args, $url);
    17241962        }
    17251963
    17261964        // pass without blocking
    17271965        return $pre;
     1966    }
     1967
     1968    /**
     1969     * Create error response for blocked request.
     1970     * Initiate recording to DB by calling action http_api_debug
     1971     * Return response error WP_Error.
     1972     * Used to record and response error message.
     1973     *
     1974     * Also can be used to prevent pingbacks and enclosure checking calls without even starting any request. 
     1975     *
     1976     * @param type $parsed_args
     1977     * @param type $url
     1978     * @return \WP_Error
     1979     */
     1980    function manage_perform_request_blocking($parsed_args, $url)
     1981    {
     1982        $response = new WP_Error('http_request_not_executed', __('User has blocked requests through HTTP. (HTTP Requests Manager plugin: ' . self::$request_action_info . ')'));
     1983
     1984        /** This action is documented in wp-includes/class-wp-http.php */
     1985        do_action('http_api_debug', $response, 'response', 'WpOrg\Requests\Requests', $parsed_args, $url);
     1986
     1987        return $response;
     1988    }
     1989
     1990    /**
     1991     * Capture prevented requests before initiating any WP_HTTP calls.
     1992     *
     1993     * Used in disable_self_ping() and disable_not_obvious_enclosure_links() when removing urls from initiating request.
     1994     *
     1995     * @param type $url
     1996     * @return type
     1997     */
     1998    function manage_perform_request_blocking_by_url($url, $info = '')
     1999    {
     2000        $this->start_timer();
     2001
     2002        self::$request_action = 'block';
     2003        self::$request_action_info = 'prevented';
     2004
     2005        if(!empty($info))
     2006        {
     2007            self::$request_action_info .= ' ' . $info;
     2008        }
     2009
     2010        return $this->manage_perform_request_blocking(array(), $url);
    17282011    }
    17292012
     
    17722055            }
    17732056
    1774            
     2057
    17752058            self::$page_info['manager_mode'] = self::get_mode();
    17762059            self::$page_info['timer_before'] = self::$timer_before;
    17772060        }
    1778        
     2061
    17792062        // is_user_logged_in() is pluggable function and will be loaded before init event. use it only if it is already loaded.
    17802063        if(!isset(self::$page_info['is_user_logged_in']) && function_exists('is_user_logged_in'))
     
    17822065            self::$page_info['is_user_logged_in'] = is_user_logged_in();
    17832066        }
    1784        
     2067
    17852068
    17862069        // updated data
     
    20892372    /**
    20902373     * Return current page type.
    2091      *
    2092      * @return string cron|ajax|rest_api|login|admin|frontend
     2374     * Id adding new page type update self::$page_types array with new page type group
     2375     *
     2376     * @return string cron|ajax|rest_api|xmlrpc|login|admin|frontend
    20932377     */
    20942378    static public function current_page_type()
     
    21122396            {
    21132397                $return = 'rest_api';
     2398            }
     2399
     2400            if(is_null($return) && (defined('XMLRPC_REQUEST') && XMLRPC_REQUEST ))
     2401            {
     2402                $return = 'xmlrpc';
    21142403            }
    21152404
     
    21672456        // disable self ping. disable ping to internal images and urls when publishing post. useless and takes long for page with 20+ internal links/images
    21682457        add_action('pre_ping', [$this, 'disable_self_ping']);
     2458
     2459        // prevent enclosure requests to non video/music files
     2460        add_filter('enclosure_links', [$this, 'disable_not_obvious_enclosure_links'], 10, 2);
    21692461
    21702462        // disable maybe update checks in admin
     
    23432635
    23442636    /**
     2637     * disable non audio/video enclosure links
     2638     *
     2639     * @param type $post_links
     2640     * @param type $post_id
     2641     * @return type
     2642     */
     2643    function disable_not_obvious_enclosure_links($post_links, $post_id)
     2644    {
     2645        $post_links_new = array();
     2646        // allow only mp3, mp4 urls
     2647        if($post_links)
     2648        {
     2649            // enclosures can be audio or video. keep them.
     2650            // use only: ext -> audio/video mime types
     2651            $mime_types = wp_get_mime_types();
     2652            $mime_types_allowed = array();
     2653            foreach($mime_types as $exts => $mime)
     2654            {
     2655                if(strpos($mime, 'audio/') === 0 || strpos($mime, 'video/') === 0)
     2656                {
     2657                    $mime_types_allowed[$exts] = $mime;
     2658                }
     2659            }
     2660
     2661
     2662            // make unique post links
     2663            $post_links_unique = array();
     2664            foreach($post_links as $url)
     2665            {
     2666                $url = strip_fragment_from_url($url);
     2667                $post_links_unique[$url] = true;
     2668            }
     2669            $post_links = array_keys($post_links_unique);
     2670            unset($post_links_unique);
     2671
     2672            // check extension of url and keep mp3,mp4 urls only. other types are not enclosed anyway.
     2673            foreach($post_links as $url)
     2674            {
     2675                // check if it is not already added
     2676                if(!isset($post_links_new[$url]))
     2677                {
     2678                    $url_parts = parse_url($url);
     2679
     2680                    if(false !== $url_parts && !empty($url_parts['path']))
     2681                    {
     2682                        $extension = pathinfo($url_parts['path'], PATHINFO_EXTENSION);
     2683                        if(!empty($extension))
     2684                        {
     2685                            foreach($mime_types_allowed as $exts => $mime)
     2686                            {
     2687                                if(preg_match('!^(' . $exts . ')$!i', $extension))
     2688                                {
     2689                                    // allowed extension. can be enclosed
     2690                                    $post_links_new[$url] = true;
     2691                                    break;
     2692                                }
     2693                            }
     2694                        }
     2695                    }
     2696                }
     2697
     2698                // record as prevented request if not enclosable
     2699                if(!isset($post_links_new[$url]))
     2700                {
     2701                    $this->manage_perform_request_blocking_by_url($url, 'enclosure_links');
     2702                }
     2703            }
     2704        }
     2705
     2706        // return unique urls
     2707        return array_keys($post_links_new);
     2708    }
     2709
     2710    /**
    23452711     *  add settings link to plugin listing
    23462712     */
     
    23592725        }
    23602726        return $links;
     2727    }
     2728
     2729    /**
     2730     *  remove some features on deactivation
     2731     */
     2732    public static function plugin_deactivate()
     2733    {
     2734        //  remove MU Must-Use plugin file if exists
     2735        self::load_must_use_remove();
     2736    }
     2737
     2738    /**
     2739     *  perform on plugin activation
     2740     */
     2741    public static function plugin_activate()
     2742    {
     2743        self::load_must_use_apply();
    23612744    }
    23622745
     
    27933176                // unset later because unsetting here will skip some links as array size changes inside this loop.
    27943177                // unset($links[$l]);
     3178
     3179                $this->manage_perform_request_blocking_by_url($link, 'pre_ping');
    27953180            }
    27963181        }
  • http-requests-manager/trunk/readme.txt

    r3034389 r3081974  
    55Requires at least: 4.9
    66Tested up to: 6.4
    7 Stable tag: 1.2.4
     7Stable tag: 1.3.0
    88License: GPLv2
    99
     
    1212== Description ==
    1313
    14 = Prevent WP HTTP request to slow down your WordPress website and admin interface =
     14= Prevent WP HTTP requests from slowing down your WordPress website and admin interface =
    1515
    1616Do you have a slow WordPress admin that takes longer than usual to load? Sometime longer than 5 seconds to load admin or login pages. In rare occasions WordPress may even timeout and show 504 page.
    1717
    18 Reason may be slow external WP_HTTP requests. [HTTP Requests Manager plugin](https://veppa.com/http-requests-manager/) will log all WP HTTP requests with time taken to complete each request. If there are multiple request per page they will be color grouped.
    19 
    20 Plugin tested  with PHP version 5.6, 7.x and up to 8.2.
     18Reason may be slow external WP_HTTP requests. [HTTP Requests Manager plugin](https://veppa.com/http-requests-manager/) will log all WP HTTP requests with time taken to complete for each request. If there are multiple requests per page they will be color grouped.
     19
     20Plugin tested with PHP version 5.6, 7.x and up to 8.3.
    2121
    2222= Do not confuse WP_HTTP request with HTML requests that loads page assets like js, css, image, font =
     
    2626Plugin will not detect any requests made by other WordPress classes like WP_Http_Curl or PHP functions like curl_exec, fsockopen, file_get_contents etc.
    2727
    28 Do not confuse it with HTML requests (loading assets like css, js, image) done by HTML page.  WP_Http requests are performed only inside PHP files and not visible in web browser.
     28Do not confuse it with HTML requests (loading assets like css, js, image) done by HTML page. WP_Http requests are performed only inside PHP files and not visible in web browser.
    2929
    3030[Learn more about difference between WP_Http requests and HTML requests](https://veppa.com/http-requests-manager/#what_is_detected_with_http_requests_manager)
    3131
    32 = How plugin prevents slow pages containing WP_HTTP requests?  =
     32= How plugin prevents slow pages containing WP_HTTP requests? =
    3333
    3434Plugin helps to prevent website slowdown by:
    3535
    36 * Sets request timeout period to 1 second. Where default is 5.
     36* Sets request timeout period to 2 second. Where default is 5.
    3737* Limit number of request per page by 3. Default is unlimited.
    3838* Limit WP HTTP request if page load time is longer than 3 seconds. Default is unlimited.
     
    4949    1. Page processing time exceeded 3 seconds.
    5050    2. Number of request for single page reached 3.
    51     3. Sets timeout for each request to 1 second.
     51    3. Sets timeout for each request to 2 second.
    5252    4. Sets number of redirects for request to 1.
    5353    5. Apply custom rules for "Smart block" defined in settings.
    54     6. Prevent some built in requests: happy browser, maybe update, self pings.
    55     7. Skip limitations listed above for: file downloads (plugin, theme, other), requests inside cron jobs.
     54    6. Prevent some built in requests: happy browser, maybe update, self pings, do_enclose.
     55    7. Skip some limitations listed above for: file downloads (plugin, theme, other), requests inside cron jobs.
    5656- **Block external requests** — all requests not matching your current domain will be blocked. No updates for WordPress core, plugins and themes. (+ Smart block features.)
    5757- **Block external requests (allow WordPress.org only)** — all requests not matching your current domain and wordpress.org will be blocked. Allows updates for WordPress core, plugins and themes coming from wordpress.org website. (+ Smart block features.)
     
    6363After using plugin for some time and knowing which requests are performed you can disable logging. Operation mode will remain unchanged. Request blocking will remain in tact. No new logs will be recorded. You can analyze old logs, they will not be deleted.
    6464
     65= Load before other plugins  =
     66
     67In order to catch more requests you can enable "Load before other plugins" option. It uses Must-Use plugin feature and load before other regular plugins. This way you will make sure to detect all WP_HTTP requests by other plugins.
    6568
    6669= Custom rules for "Smart Block" mode =
     
    7275= Features =
    7376
     77* View performance improvement of your WordPress website due to blocking some remote HTTP requests.
    7478* View blocked requests by this plugin. Show reason why it was blocked.
    7579* View failed requests with error message.
    7680* View what initiated HTTP request: WordPress core, plugin or theme.
    77 * View on which page request was made. Also view page type is frontend, admin, login, cron, ajax or rest_api.
     81* View on which page request was made. Also view page type is frontend, admin, login, cron, ajax, xmlrpc or rest_api.
    7882* View list of other requests made on same page view.
    7983* View sent and received data.
     
    125129== Screenshots ==
    126130
    127 1. Screenshot shows latest HTTP requests and reason why they are blocked. Also summary show at the top with total percentage of blocked requests (63% in current view). Hosts card shows that there are 7 different hosts were requests sent. When you hover over card tooltip will show breakdown of hosts in percentage. We can see that 73% or requests were made to api.wordpress.org website. Also we can see that plugins actively using external requests to load data and some promotions from their servers.
    128 
    129 2. WP_HTTP request and response data. Popup opens when you click on request from table. Page and request times shows as well.
    130 
    131 3. Blocked request due to page time exceeding 3 seconds. Additional information regarding page shown with currently active manager mode.
    132 
    133 4. Check point shows how plugins and requests effect page time and memory usage.
    134 
    135 5. Group requests to simplify report. You can group by request domain, page type, initiator, response status etc. Bar colors will visually indicate requests by response status as blocked orange, success green, error red.
    136 
    137 6. Requests grouped by initiator core / theme / plugin. Clicking on group will reveal requests inside that group.
    138 
    139 7. Settings page to select operation mode, disable logging and adding custom rules. Settings will be saved each time when you change any option.
    140 
    141 8. Select operation mode to fit your need. Only blocking modes will speed up WordPress admin pages. Be aware that blocking modes may break functionality of some plugins that rely on external API requests.
    142 
    143 9. Define custom rules to always allow some plugins or domains only in "Smart block" mode. Custom rules will be ordered by high priority. First matching rule will be applied.
     1311. Screenshot shows latest HTTP requests and reason why they are blocked. Summary cards at the top show total percentage of blocked requests (54% in current view). You can also see estimated performance improvement 2.2x because of blocking some remote requests. Hosts card shows that there are 3 different hosts were requests sent. When you hover over card tooltip will show breakdown of hosts in percentage. We can see that 31% or requests were made to api.wordpress.org website. Also we can see that plugins actively using external requests to load data and some promotions from their servers.
     132
     1332. When Smart Block enabled total page generation time will be limited to 3 seconds. Page with 10 requests, will improve from 11-12 seconds to 3 seconds, regardless of web hosting resources. 
     134
     1353. WP_HTTP request and response data. Popup opens when you click on request from table. Page and request times shows as well.
     136
     1374. Blocked request due to page time exceeding 3 seconds. Additional information regarding page shown with currently active manager mode.
     138
     1395. Check point shows how plugins and requests effect page time and memory usage.
     140
     1416. Group requests to simplify report. You can group by request domain, page type, initiator, response status etc. Bar colors will visually indicate requests by response status as blocked orange, success green, error red.
     142
     1437. Requests grouped by initiator core / theme / plugin. Clicking on group will reveal requests inside that group.
     144
     1458. Settings page to select operation mode, disable logging and adding custom rules. Settings will be saved each time when you change any option.
     146
     1479. Select operation mode to fit your need. Only blocking modes will speed up WordPress admin pages. Be aware that blocking modes may break functionality of some plugins that rely on external API requests.
     148
     14910. Define custom rules to always allow some plugins or domains only in "Smart block" mode. Custom rules will be ordered by high priority. First matching rule will be applied.
    144150
    145151
     
    162168All pages with WP_HTTP requests are recorded. Slow pages without any WP_HTTP requests are not recorded.
    163169
     170= Which remote requests are not detected? =
     171
     172This plugin detects only requests made using [WP_HTTP](https://developer.wordpress.org/reference/classes/wp_http/) class defined by WordPress. It is preferred way of doing remote requests. WordPress core and most plugins/themes use it.
     173
     174Plugin will not detect requests made using other classes and functions. For example remote requests made with WordPress class [WP_Http_Curl](https://developer.wordpress.org/reference/classes/wp_http_curl/) (deprecated starting from WordPress version 6.4) or PHP functions like curl_exec, fsockopen, file_get_contents are not detected by this plugin.  Because they do not have hooks similar to WordPress to manage requests before making them.
     175
     176Unfortunately when plugin/theme uses other functions (not WP_HTTP class) they will not be detected by this plugin. 
     177
     178= How much performance improvement can be gained? =
     179
     180Performance gain on pages with WP_HTTP requests can be up to 5x. It all depends on which blocking method used and how heavyly remote requests are used by core and pugins.
     181
     182= Are all WordPress pages have WP_HTTP requests? =
     183
     184No. WP_HTTP requests are performed periodically or on certain action. When you check logged requests, there will be around 50-100 pages with requests per day. On website with 10k daily page views (human and bot traffic) it will make around 1% of all pages.
     185
     186= How can I feel speed improvement provided by this plugin? =
     187
     188You will most likely feel speed difference in admin area. Pages previously loading slowly or timing out regularly should load much faster.
     189
    164190== Changelog ==
    165191
     192= 1.3.0 - 6 May 2024 =
     193
     194* Added: priority loading mode using MU plugin feature. Plugin will load as Must-Use plugin before other plugins for catching as many requests as possible.
     195* Added: Prevent requests initiated by do_enclose function after adding/updating post with images and links. Every time when post saved all links inside post will be requested for checking their file type. For example post with 20 links and 10 images will make 30 requests to check file type for each URL. Only audio and video URLs are saved as enclosure. Other requests are not used and wastes server resources. This request prevention will eliminate tens of requests to non audio/video URLs. When enabled related cron request for post with 30 URLs will finish in 1 second instead of 30 seconds.
     196* Added: Log prevented requests for better understanding what is changed after enabling some blocking mode. Previously prevented self pings and do_enclose requests were not logged.
     197* Added: Calls from xmlrpc.php file are moved to new page group called "xmlrpc" from previous "frontend".
     198* Added: Summary card showing average performance improvement occurred due to blocking some remote API/HTTP requests.
     199* Fixed: increased request timeout from 1 second to 2 seconds for allowing enough time to complete CURL calls made to HTTPS servers.
     200* Fixed: responses to non streaming requests will be grouped as "success" instead of "error".
     201
    166202= 1.2.4 - 12 February 2024 =
    167203
    168 *  Fixed: prevent calling is_user_logged_in function when it is not declared.
     204* Fixed: prevent calling is_user_logged_in function when it is not declared.
    169205
    170206= 1.2.3 - 30 November 2023 =
    171207
    172 *  Fixed: Domain select box population when adding new Custom Rule.
     208* Fixed: Domain select box population when adding new Custom Rule.
    173209
    174210= 1.2.2 - 29 November 2023 =
    175211
    176 *  Fixed: Variable name typo inside get_arr_val function.
     212* Fixed: Variable name typo inside get_arr_val function.
    177213
    178214
    179215= 1.2.1 - 29 November 2023 =
    180216
    181  * Fixed: Incorrect links in options page.
     217* Fixed: Incorrect links in options page.
    182218
    183219
    184220= 1.2.0 - 28 November 2023 =
    185221
    186  *  Added: Separate tabs for log, settings, more tools
    187  *  Added: Group request logs by URL, domain, page, page type, plugin, response status etc. Better for viewing important information.
    188  * Added: Custom rules to block/allow by all/domain/plugin in everywhere/admin/frontend/ajax/cron/rest_api/login. Maximum 10 custom rules can be added. Custom rules apply only in smart block mode.
    189  *  Added: Option to disable logging. Old logs can be viewed. Plugin will work a bit faster when logging disabled.
    190  *  Added: Disable self ping (only when blocking in "smart block+" mode). Self ping sends pings to images and links on same domain. Post with 20+ links and images will take 10+ seconds to send self pings.
    191  *  Added: Disable auto update check on admin page in "smart block+" mode. _maybe_update_core, _maybe_update_themes, _maybe_update_plugins slows down admin pages up to 5+ seconds on first visit after 12 hours and can even timeout. Update checks via cron is not effected.
    192  * Fixed: Undefined array key "file" error
    193  *  Update: Store last 1k records
     222* Added: Separate tabs for log, settings, more tools
     223* Added: Group request logs by URL, domain, page, page type, plugin, response status etc. Better for viewing important information.
     224* Added: Custom rules to block/allow by all/domain/plugin in everywhere/admin/frontend/ajax/cron/rest_api/login. Maximum 10 custom rules can be added. Custom rules apply only in smart block mode.
     225* Added: Option to disable logging. Old logs can be viewed. Plugin will work a bit faster when logging disabled.
     226* Added: Disable self ping (only when blocking in "smart block+" mode). Self ping sends pings to images and links on same domain. Post with 20+ links and images will take 10+ seconds to send self pings.
     227* Added: Disable auto update check on admin page in "smart block+" mode. _maybe_update_core, _maybe_update_themes, _maybe_update_plugins slows down admin pages up to 5+ seconds on first visit after 12 hours and can even timeout. Update checks via cron is not effected.
     228* Fixed: Undefined array key "file" error
     229* Update: Store last 1k records
    194230
    195231= 1.1.0 - 12 June 2023 =
  • http-requests-manager/trunk/templates/page-settings.php

    r3003727 r3081974  
    5353                                — <a href="#help"><?php echo __('Which one to choose?', 'http-requests-manager'); ?></a>
    5454                            </p>
     55                        </td>
     56                    </tr>
     57                    <tr>
     58                        <th scope="row"><label><?php _e('Load before other plugins', 'http-requests-manager'); ?></label></th>
     59                        <td>
     60                            <input type="checkbox" name="load_must_use" value="1" id="load_must_use" <?php echo (HTTP_Requests_Manager::get_option('load_must_use') ? ' checked="checked"' : '') ?> />
     61                            <label for="load_must_use">Enable priority loading with Must-Use plugin feature.</label>
    5562                        </td>
    5663                    </tr>
     
    152159                            <li><?php _e('Page processing time exceeded 3 seconds.', 'http-requests-manager'); ?></li>
    153160                            <li><?php _e('Number of request for single page reached 3.', 'http-requests-manager'); ?></li>
    154                             <li><?php _e('Sets timeout for each request (except file downloads) to 1 second.', 'http-requests-manager'); ?></li>
     161                            <li><?php _e('Sets timeout for each request (except file downloads) to 2 second.', 'http-requests-manager'); ?></li>
    155162                            <li><?php _e('Sets number of redirects for request to 1.', 'http-requests-manager'); ?></li>               
    156163                            <li><?php _e('Apply custom rules for "Smart block" defined in settings.', 'http-requests-manager'); ?></li>             
    157                             <li><?php _e('Prevent some built in requests: happy browser, maybe update, self pings.', 'http-requests-manager'); ?></li>             
     164                            <li><?php _e('Prevent some built in requests: happy browser, maybe update, self pings, do_enclose.', 'http-requests-manager'); ?></li> 
     165                            <li><?php _e('Skip some limitations listed above for: file downloads (plugin, theme, other), requests inside cron jobs.', 'http-requests-manager'); ?></li>
    158166                        </ol>
    159167                    </li>
Note: See TracChangeset for help on using the changeset viewer.