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.


Built from https://develop.svn.wordpress.org/trunk@50954


git-svn-id: http://core.svn.wordpress.org/trunk@50563 1a063a9b-81f0-0310-95a4-ce76da25c4cd
This commit is contained in:
Peter Wilson 2021-05-24 02:18:58 +00:00
parent 7670b7dca8
commit 5ce6da1a31
3 changed files with 79 additions and 40 deletions

View File

@ -130,10 +130,6 @@ EOD;
$error = new IXR_Error($error, $message);
}
if ( function_exists( 'status_header' ) ) {
status_header( $error->code );
}
$this->output($error->getXml());
}

View File

@ -14,7 +14,7 @@
* options, etc.
*
* As of WordPress 3.5.0, XML-RPC is enabled by default. It can be disabled
* via the {@see 'xmlrpc_enabled'} filter found in wp_xmlrpc_server::login().
* via the {@see 'xmlrpc_enabled'} filter found in wp_xmlrpc_server::set_is_enabled().
*
* @since 1.5.0
*
@ -49,6 +49,13 @@ class wp_xmlrpc_server extends IXR_Server {
*/
protected $auth_failed = false;
/**
* Flags that XML-RPC is enabled
*
* @var bool
*/
private $is_enabled;
/**
* Registers all of the XMLRPC methods that XMLRPC server understands.
*
@ -164,6 +171,51 @@ class wp_xmlrpc_server extends IXR_Server {
* @param string[] $methods An array of XML-RPC methods, keyed by their methodName.
*/
$this->methods = apply_filters( 'xmlrpc_methods', $this->methods );
$this->set_is_enabled();
}
/**
* Set wp_xmlrpc_server::$is_enabled property.
*
* Determine whether the xmlrpc server is enabled on this WordPress install
* and set the is_enabled property accordingly.
*
* @since 5.7.3
*/
private function set_is_enabled() {
/*
* Respect old get_option() filters left for back-compat when the 'enable_xmlrpc'
* option was deprecated in 3.5.0. Use the 'xmlrpc_enabled' hook instead.
*/
$is_enabled = apply_filters( 'pre_option_enable_xmlrpc', false );
if ( false === $is_enabled ) {
$is_enabled = apply_filters( 'option_enable_xmlrpc', true );
}
/**
* Filters whether XML-RPC methods requiring authentication are enabled.
*
* Contrary to the way it's named, this filter does not control whether XML-RPC is *fully*
* enabled, rather, it only controls whether XML-RPC methods requiring authentication - such
* as for publishing purposes - are enabled.
*
* Further, the filter does not control whether pingbacks or other custom endpoints that don't
* require authentication are enabled. This behavior is expected, and due to how parity was matched
* with the `enable_xmlrpc` UI option the filter replaced when it was introduced in 3.5.
*
* To disable XML-RPC methods that require authentication, use:
*
* add_filter( 'xmlrpc_enabled', '__return_false' );
*
* For more granular control over all XML-RPC methods and requests, see the {@see 'xmlrpc_methods'}
* and {@see 'xmlrpc_element_limit'} hooks.
*
* @since 3.5.0
*
* @param bool $is_enabled Whether XML-RPC is enabled. Default true.
*/
$this->is_enabled = apply_filters( 'xmlrpc_enabled', $is_enabled );
}
/**
@ -231,40 +283,7 @@ class wp_xmlrpc_server extends IXR_Server {
* @return WP_User|false WP_User object if authentication passed, false otherwise
*/
public function login( $username, $password ) {
/*
* Respect old get_option() filters left for back-compat when the 'enable_xmlrpc'
* option was deprecated in 3.5.0. Use the 'xmlrpc_enabled' hook instead.
*/
$enabled = apply_filters( 'pre_option_enable_xmlrpc', false );
if ( false === $enabled ) {
$enabled = apply_filters( 'option_enable_xmlrpc', true );
}
/**
* Filters whether XML-RPC methods requiring authentication are enabled.
*
* Contrary to the way it's named, this filter does not control whether XML-RPC is *fully*
* enabled, rather, it only controls whether XML-RPC methods requiring authentication - such
* as for publishing purposes - are enabled.
*
* Further, the filter does not control whether pingbacks or other custom endpoints that don't
* require authentication are enabled. This behavior is expected, and due to how parity was matched
* with the `enable_xmlrpc` UI option the filter replaced when it was introduced in 3.5.
*
* To disable XML-RPC methods that require authentication, use:
*
* add_filter( 'xmlrpc_enabled', '__return_false' );
*
* For more granular control over all XML-RPC methods and requests, see the {@see 'xmlrpc_methods'}
* and {@see 'xmlrpc_element_limit'} hooks.
*
* @since 3.5.0
*
* @param bool $enabled Whether XML-RPC is enabled. Default true.
*/
$enabled = apply_filters( 'xmlrpc_enabled', $enabled );
if ( ! $enabled ) {
if ( ! $this->is_enabled ) {
$this->error = new IXR_Error( 405, sprintf( __( 'XML-RPC services are disabled on this site.' ) ) );
return false;
}
@ -335,6 +354,30 @@ class wp_xmlrpc_server extends IXR_Server {
}
}
/**
* Send error response to client.
*
* Send an XML error response to the client. If the endpoint is enabled
* an HTTP 200 response is always sent per the XML-RPC specification.
*
* @since 5.7.3
*
* @param IXR_Error|string $error Error code or an error object.
* @param false $message Error message. Optional.
*/
public function error( $error, $message = false ) {
// Accepts either an error object or an error code and message
if ( $message && ! is_object( $error ) ) {
$error = new IXR_Error( $error, $message );
}
if ( ! $this->is_enabled ) {
status_header( $error->code );
}
$this->output( $error->getXml() );
}
/**
* Retrieve custom fields for post.
*

View File

@ -13,7 +13,7 @@
*
* @global string $wp_version
*/
$wp_version = '5.8-alpha-50953';
$wp_version = '5.8-alpha-50954';
/**
* Holds the WordPress DB revision, increments when changes are made to the WordPress DB schema.