(bug 19907) Adds support for cross-domain AJAX requests to the API.
authorAlex Z <mrzman@users.mediawiki.org>
Fri, 31 Jul 2009 21:56:34 +0000 (21:56 +0000)
committerAlex Z <mrzman@users.mediawiki.org>
Fri, 31 Jul 2009 21:56:34 +0000 (21:56 +0000)
Uses the Access-Control-Allow-Origin header for browsers that support it.
<http://dev.w3.org/2006/waf/access-control/>
$wgCrossSiteAJAXdomains can be set to '*' to allow requests from any domain,
an array of domains to allow, or, if $wgCrossSiteAJAXdomainsRegex is true,
an array of regexes to match against the request origin

RELEASE-NOTES
api.php
includes/DefaultSettings.php

index bb31d58..0e26549 100644 (file)
@@ -76,6 +76,8 @@ this. Was used when mwEmbed was going to be an extension.
   PHP and database version.
 * $wgSecondaryGoNamespaces allows an arry of namespaces to be checked when the
   GO button is pressed, in addition to the main namespace.
+* (bug 19907) $wgCrossSiteAJAXdomains and $wgCrossSiteAJAXdomainsRegex added 
+  to control which external domains may access the API via cross-site AJAX.
 
 === New features in 1.16 ===
 
@@ -403,6 +405,9 @@ this. Was used when mwEmbed was going to be an extension.
 * Added fields to list=search output: size, wordcount, timestamp, snippet
 * Where supported by backend, list=search adds a 'searchinfo' element with
   optional info: 'totalhits' count and 'suggestion' alternate query term
+* (bug 19907) $wgCrossSiteAJAXdomains added to allow specified (or all)
+  external domains to access api.php via AJAX, if the browser supports the 
+  Access-Control-Allow-Origin HTTP header
 
 === Languages updated in 1.16 ===
 
diff --git a/api.php b/api.php
index e031dfa..ec805fc 100644 (file)
--- a/api.php
+++ b/api.php
@@ -69,6 +69,25 @@ if (!$wgEnableAPI) {
        die(1);
 }
 
+// Selectively allow cross-site AJAX
+if ( $wgCrossSiteAJAXdomains && isset($_SERVER['HTTP_ORIGIN']) ) {
+       if ( $wgCrossSiteAJAXdomains == '*' ) {
+               header( "Access-Control-Allow-Origin: {$_SERVER['HTTP_ORIGIN']}" );
+               header( 'Access-Control-Allow-Credentials: true' );
+       } elseif ( $wgCrossSiteAJAXdomainsRegex ) {
+               foreach ( $wgCrossSiteAJAXdomains as $regex ) {
+                       if ( preg_match( $regex, $_SERVER['HTTP_ORIGIN'] ) ) {
+                               header( "Access-Control-Allow-Origin: {$_SERVER['HTTP_ORIGIN']}" );
+                               header( 'Access-Control-Allow-Credentials: true' );
+                               break;
+                       }
+               }
+       } elseif ( in_array( $_SERVER['HTTP_ORIGIN'], $wgCrossSiteAJAXdomains ) ) {
+               header( "Access-Control-Allow-Origin: {$_SERVER['HTTP_ORIGIN']}" );
+               header( 'Access-Control-Allow-Credentials: true' );
+       }
+}
+
 // So extensions can check whether they're running in API mode
 define('MW_API', true);
 
index 0944a1e..8f50dda 100644 (file)
@@ -4121,3 +4121,25 @@ $wgAllowPrefChange = array();
  * Array: Ids of namespaces to attempt match in, in desired order.
  */
 $wgSecondaryGoNamespaces = null;
+
+
+/**
+ * Settings for incoming cross-site AJAX requests:
+ * Newer browsers support cross-site AJAX when the target resource allows requests
+ * from the origin domain by the Access-Control-Allow-Origin header.
+ * This is currently only used by the API (requests to api.php)
+ * $wgCrossSiteAJAXdomains can be set as follows:
+ * 
+ * - the string '*' to allow requests from any domain
+ * - an array of domains to allow AJAX requests from, e.g.
+ *   array( 'http://en.wikipedia.org', 'http://en.wikibooks.org' );
+ * - if $wgCrossSiteAJAXdomainsRegex is true, an array of regexes to be
+ *   matched against the request origin. Anything that matches will be allowed
+ */
+$wgCrossSiteAJAXdomains = array();
+
+/**
+ * Set to true to treat $wgCrossSiteAJAXdomains as regexes instead of strings
+ */
+$wgCrossSiteAJAXdomainsRegex = false;
+