API for allowing cross origin resource sharing.

* Allowed origin whitelist that can be altered by plugins
* Validation of the request origin against the whitelist
* Send Access-Control-Allow-Origin if origin allowed
* get_http_origin(), get_allowed_http_origins(), is_allowed_http_origin(), send_origin_headers()

See #20681



git-svn-id: http://core.svn.wordpress.org/trunk@20794 1a063a9b-81f0-0310-95a4-ce76da25c4cd
This commit is contained in:
ryan 2012-05-15 18:46:03 +00:00
parent 809da11403
commit 9c3ce86280
2 changed files with 78 additions and 11 deletions

View File

@ -71,17 +71,7 @@ final class WP_Customize {
if ( ! isset( $_REQUEST['customize'] ) || 'on' != $_REQUEST['customize'] )
return;
$url = parse_url( admin_url() );
$allowed_origins = array( 'http://' . $url[ 'host' ], 'https://' . $url[ 'host' ] );
// @todo preserve port?
if ( isset( $_SERVER[ 'HTTP_ORIGIN' ] ) && in_array( $_SERVER[ 'HTTP_ORIGIN' ], $allowed_origins ) ) {
$origin = $_SERVER[ 'HTTP_ORIGIN' ];
} else {
$origin = $url[ 'scheme' ] . '://' . $url[ 'host' ];
}
@header( 'Access-Control-Allow-Origin: ' . $origin );
@header( 'Access-Control-Allow-Credentials: true' );
send_origin_headers();
$this->start_previewing_theme();
show_admin_bar( false );

View File

@ -222,3 +222,80 @@ function wp_http_supports( $capabilities = array(), $url = null ) {
return (bool) $objFetchSite->_get_first_available_transport( $capabilities );
}
/**
* Get the HTTP Origin of the current request.
*
* @since 3.4.0
*
* @return string URL of the origin. Empty string if no origin.
*/
function get_http_origin() {
$origin = '';
if ( ! empty ( $_SERVER[ 'HTTP_ORIGIN' ] ) )
$origin = $_SERVER[ 'HTTP_ORIGIN' ];
return apply_filters( 'http_origin', $origin );
}
/**
* Retrieve list of allowed http origins.
*
* @since 3.4.0
*
* @return array Array of origin URLs.
*/
function get_allowed_http_origins() {
$admin_origin = parse_url( admin_url() );
$home_origin = parse_url( home_url() );
// @todo preserve port?
$allowed_origins = array_unique( array(
'http://' . $admin_origin[ 'host' ],
'https://' . $admin_origin[ 'host' ],
'http://' . $home_origin[ 'host' ],
'https://' . $home_origin[ 'host' ],
) );
return apply_filters( 'allowed_http_origins' , $allowed_origins );
}
/**
* Determines if the http origin is an authorized one.
*
* @since 3.4.0
*
* @param string Origin URL. If not provided, the value of get_http_origin() is used.
* @return bool True if the origin is allowed. False otherwise.
*/
function is_allowed_http_origin( $origin = null ) {
$origin_arg = $origin;
if ( null === $origin )
$origin = get_http_origin();
if ( $origin && ! in_array( $origin, get_allowed_http_origins() ) )
$origin = '';
return apply_filters( 'allowed_http_origin', $origin, $origin_arg );
}
/**
* Send Access-Control-Allow-Origin and related headers if the current request
* is from an allowed origin.
*
* @since 3.4.0
*
* @return bool|string Returns the origin URL if headers are sent. Returns false
* if headers are not sent.
*/
function send_origin_headers() {
$origin = get_http_origin();
if ( ! is_allowed_http_origin( $origin ) )
return false;
@header( 'Access-Control-Allow-Origin: ' . $origin );
@header( 'Access-Control-Allow-Credentials: true' );
return $origin;
}