Make WordPress Core

Changeset 50954


Ignore:
Timestamp:
05/24/2021 02:17:36 AM (3 years ago)
Author:
peterwilsoncc
Message:

XML-RPC: Set HTTP status code in accordance with the spec.

When the XML-RPC endpoint is enabled, always return a HTTP 200 OK status code in accordance with the XML-RPC specification. Continue to return an HTTP 405 Method Not Allowed status code when the endpoint is disabled.

Props ariskataoka, johnbillion.
Fixes #52958.

Location:
trunk
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/wp-includes/IXR/class-IXR-server.php

    r49862 r50954  
    130130            $error = new IXR_Error($error, $message);
    131131        }
    132 
    133         if ( function_exists( 'status_header' ) ) {
    134             status_header( $error->code );
    135         }
    136132
    137133        $this->output($error->getXml());
  • trunk/src/wp-includes/class-wp-xmlrpc-server.php

    r50499 r50954  
    1515 *
    1616 * As of WordPress 3.5.0, XML-RPC is enabled by default. It can be disabled
    17  * via the {@see 'xmlrpc_enabled'} filter found in wp_xmlrpc_server::login().
     17 * via the {@see 'xmlrpc_enabled'} filter found in wp_xmlrpc_server::set_is_enabled().
    1818 *
    1919 * @since 1.5.0
     
    4949     */
    5050    protected $auth_failed = false;
     51
     52    /**
     53     * Flags that XML-RPC is enabled
     54     *
     55     * @var bool
     56     */
     57    private $is_enabled;
    5158
    5259    /**
     
    165172         */
    166173        $this->methods = apply_filters( 'xmlrpc_methods', $this->methods );
    167     }
    168 
    169     /**
    170      * Make private/protected methods readable for backward compatibility.
    171      *
    172      * @since 4.0.0
    173      *
    174      * @param string $name      Method to call.
    175      * @param array  $arguments Arguments to pass when calling.
    176      * @return array|IXR_Error|false Return value of the callback, false otherwise.
    177      */
    178     public function __call( $name, $arguments ) {
    179         if ( '_multisite_getUsersBlogs' === $name ) {
    180             return $this->_multisite_getUsersBlogs( ...$arguments );
    181         }
    182         return false;
    183     }
    184 
    185     /**
    186      * Serves the XML-RPC request.
    187      *
    188      * @since 2.9.0
    189      */
    190     public function serve_request() {
    191         $this->IXR_Server( $this->methods );
    192     }
    193 
    194     /**
    195      * Test XMLRPC API by saying, "Hello!" to client.
    196      *
    197      * @since 1.5.0
    198      *
    199      * @return string Hello string response.
    200      */
    201     public function sayHello() {
    202         return 'Hello!';
    203     }
    204 
    205     /**
    206      * Test XMLRPC API by adding two numbers for client.
    207      *
    208      * @since 1.5.0
    209      *
    210      * @param array $args {
    211      *     Method arguments. Note: arguments must be ordered as documented.
    212      *
    213      *     @type int $number1 A number to add.
    214      *     @type int $number2 A second number to add.
    215      * }
    216      * @return int Sum of the two given numbers.
    217      */
    218     public function addTwoNumbers( $args ) {
    219         $number1 = $args[0];
    220         $number2 = $args[1];
    221         return $number1 + $number2;
    222     }
    223 
    224     /**
    225      * Log user in.
    226      *
    227      * @since 2.8.0
    228      *
    229      * @param string $username User's username.
    230      * @param string $password User's password.
    231      * @return WP_User|false WP_User object if authentication passed, false otherwise
    232      */
    233     public function login( $username, $password ) {
     174
     175        $this->set_is_enabled();
     176    }
     177
     178    /**
     179     * Set wp_xmlrpc_server::$is_enabled property.
     180     *
     181     * Determine whether the xmlrpc server is enabled on this WordPress install
     182     * and set the is_enabled property accordingly.
     183     *
     184     * @since 5.7.3
     185     */
     186    private function set_is_enabled() {
    234187        /*
    235188         * Respect old get_option() filters left for back-compat when the 'enable_xmlrpc'
    236189         * option was deprecated in 3.5.0. Use the 'xmlrpc_enabled' hook instead.
    237190         */
    238         $enabled = apply_filters( 'pre_option_enable_xmlrpc', false );
    239         if ( false === $enabled ) {
    240             $enabled = apply_filters( 'option_enable_xmlrpc', true );
     191        $is_enabled = apply_filters( 'pre_option_enable_xmlrpc', false );
     192        if ( false === $is_enabled ) {
     193            $is_enabled = apply_filters( 'option_enable_xmlrpc', true );
    241194        }
    242195
     
    261214         * @since 3.5.0
    262215         *
    263          * @param bool $enabled Whether XML-RPC is enabled. Default true.
     216         * @param bool $is_enabled Whether XML-RPC is enabled. Default true.
    264217         */
    265         $enabled = apply_filters( 'xmlrpc_enabled', $enabled );
    266 
    267         if ( ! $enabled ) {
     218        $this->is_enabled = apply_filters( 'xmlrpc_enabled', $is_enabled );
     219    }
     220
     221    /**
     222     * Make private/protected methods readable for backward compatibility.
     223     *
     224     * @since 4.0.0
     225     *
     226     * @param string $name      Method to call.
     227     * @param array  $arguments Arguments to pass when calling.
     228     * @return array|IXR_Error|false Return value of the callback, false otherwise.
     229     */
     230    public function __call( $name, $arguments ) {
     231        if ( '_multisite_getUsersBlogs' === $name ) {
     232            return $this->_multisite_getUsersBlogs( ...$arguments );
     233        }
     234        return false;
     235    }
     236
     237    /**
     238     * Serves the XML-RPC request.
     239     *
     240     * @since 2.9.0
     241     */
     242    public function serve_request() {
     243        $this->IXR_Server( $this->methods );
     244    }
     245
     246    /**
     247     * Test XMLRPC API by saying, "Hello!" to client.
     248     *
     249     * @since 1.5.0
     250     *
     251     * @return string Hello string response.
     252     */
     253    public function sayHello() {
     254        return 'Hello!';
     255    }
     256
     257    /**
     258     * Test XMLRPC API by adding two numbers for client.
     259     *
     260     * @since 1.5.0
     261     *
     262     * @param array $args {
     263     *     Method arguments. Note: arguments must be ordered as documented.
     264     *
     265     *     @type int $number1 A number to add.
     266     *     @type int $number2 A second number to add.
     267     * }
     268     * @return int Sum of the two given numbers.
     269     */
     270    public function addTwoNumbers( $args ) {
     271        $number1 = $args[0];
     272        $number2 = $args[1];
     273        return $number1 + $number2;
     274    }
     275
     276    /**
     277     * Log user in.
     278     *
     279     * @since 2.8.0
     280     *
     281     * @param string $username User's username.
     282     * @param string $password User's password.
     283     * @return WP_User|false WP_User object if authentication passed, false otherwise
     284     */
     285    public function login( $username, $password ) {
     286        if ( ! $this->is_enabled ) {
    268287            $this->error = new IXR_Error( 405, sprintf( __( 'XML-RPC services are disabled on this site.' ) ) );
    269288            return false;
     
    334353            }
    335354        }
     355    }
     356
     357    /**
     358     * Send error response to client.
     359     *
     360     * Send an XML error response to the client. If the endpoint is enabled
     361     * an HTTP 200 response is always sent per the XML-RPC specification.
     362     *
     363     * @since 5.7.3
     364     *
     365     * @param IXR_Error|string $error   Error code or an error object.
     366     * @param false            $message Error message. Optional.
     367     */
     368    public function error( $error, $message = false ) {
     369        // Accepts either an error object or an error code and message
     370        if ( $message && ! is_object( $error ) ) {
     371            $error = new IXR_Error( $error, $message );
     372        }
     373
     374        if ( ! $this->is_enabled ) {
     375            status_header( $error->code );
     376        }
     377
     378        $this->output( $error->getXml() );
    336379    }
    337380
  • trunk/tests/phpunit/tests/xmlrpc/basic.php

    r49862 r50954  
    1717    }
    1818
    19     function test_disabled() {
    20         add_filter( 'xmlrpc_enabled', '__return_false' );
    21 
    22         $result = $this->myxmlrpcserver->wp_getOptions( array( 1, 'username', 'password' ) );
    23 
    24         $this->assertIXRError( $result );
    25         $this->assertSame( 405, $result->code );
    26     }
    27 
    2819    function test_login_pass_ok() {
    29         $user_id = $this->make_user_by_role( 'subscriber' );
     20        $this->make_user_by_role( 'subscriber' );
    3021
    3122        $this->assertTrue( $this->myxmlrpcserver->login_pass_ok( 'subscriber', 'subscriber' ) );
     
    3425
    3526    function test_login_pass_bad() {
    36         $user_id = $this->make_user_by_role( 'subscriber' );
     27        $this->make_user_by_role( 'subscriber' );
    3728
    3829        $this->assertFalse( $this->myxmlrpcserver->login_pass_ok( 'username', 'password' ) );
     
    118109        $this->assertXmlStringEqualsXmlString( $return, $value->getXML() );
    119110    }
     111
     112    function test_disabled() {
     113        add_filter( 'xmlrpc_enabled', '__return_false' );
     114        $testcase_xmlrpc_server = new wp_xmlrpc_server();
     115        $result                 = $testcase_xmlrpc_server->wp_getOptions( array( 1, 'username', 'password' ) );
     116
     117        $this->assertIXRError( $result );
     118        $this->assertSame( 405, $result->code );
     119    }
    120120}
Note: See TracChangeset for help on using the changeset viewer.