Index: xmlrpc.php
===================================================================
--- xmlrpc.php	(revision 23244)
+++ xmlrpc.php	(working copy)
@@ -52,6 +52,7 @@
 
 include_once(ABSPATH . 'wp-admin/includes/admin.php');
 include_once(ABSPATH . WPINC . '/class-IXR.php');
+include_once(ABSPATH . WPINC . '/class-json-rpc.php');
 include_once(ABSPATH . WPINC . '/class-wp-xmlrpc-server.php');
 
 /**
@@ -83,4 +84,4 @@
 	_deprecated_function( __FUNCTION__, '3.4', 'error_log()' );
 	if ( ! empty( $GLOBALS['xmlrpc_logging'] ) )
 		error_log( $io . ' - ' . $msg );
-}
\ No newline at end of file
+}
Index: wp-includes/class-wp-xmlrpc-server.php
===================================================================
--- wp-includes/class-wp-xmlrpc-server.php	(revision 23244)
+++ wp-includes/class-wp-xmlrpc-server.php	(working copy)
@@ -19,7 +19,7 @@
  * @subpackage Publishing
  * @since 1.5.0
  */
-class wp_xmlrpc_server extends IXR_Server {
+class wp_xmlrpc_server {
 
 	/**
 	 * Register all of the XMLRPC methods that XMLRPC server understands.
@@ -35,94 +35,94 @@
 	function __construct() {
 		$this->methods = array(
 			// WordPress API
-			'wp.getUsersBlogs'		=> 'this:wp_getUsersBlogs',
-			'wp.newPost'			=> 'this:wp_newPost',
-			'wp.editPost'			=> 'this:wp_editPost',
-			'wp.deletePost'			=> 'this:wp_deletePost',
-			'wp.getPost'			=> 'this:wp_getPost',
-			'wp.getPosts'			=> 'this:wp_getPosts',
-			'wp.newTerm'			=> 'this:wp_newTerm',
-			'wp.editTerm'			=> 'this:wp_editTerm',
-			'wp.deleteTerm'			=> 'this:wp_deleteTerm',
-			'wp.getTerm'			=> 'this:wp_getTerm',
-			'wp.getTerms'			=> 'this:wp_getTerms',
-			'wp.getTaxonomy'		=> 'this:wp_getTaxonomy',
-			'wp.getTaxonomies'		=> 'this:wp_getTaxonomies',
-			'wp.getUser'			=> 'this:wp_getUser',
-			'wp.getUsers'			=> 'this:wp_getUsers',
-			'wp.getProfile'			=> 'this:wp_getProfile',
-			'wp.editProfile'		=> 'this:wp_editProfile',
-			'wp.getPage'			=> 'this:wp_getPage',
-			'wp.getPages'			=> 'this:wp_getPages',
-			'wp.newPage'			=> 'this:wp_newPage',
-			'wp.deletePage'			=> 'this:wp_deletePage',
-			'wp.editPage'			=> 'this:wp_editPage',
-			'wp.getPageList'		=> 'this:wp_getPageList',
-			'wp.getAuthors'			=> 'this:wp_getAuthors',
-			'wp.getCategories'		=> 'this:mw_getCategories',		// Alias
-			'wp.getTags'			=> 'this:wp_getTags',
-			'wp.newCategory'		=> 'this:wp_newCategory',
-			'wp.deleteCategory'		=> 'this:wp_deleteCategory',
-			'wp.suggestCategories'	=> 'this:wp_suggestCategories',
-			'wp.uploadFile'			=> 'this:mw_newMediaObject',	// Alias
-			'wp.getCommentCount'	=> 'this:wp_getCommentCount',
-			'wp.getPostStatusList'	=> 'this:wp_getPostStatusList',
-			'wp.getPageStatusList'	=> 'this:wp_getPageStatusList',
-			'wp.getPageTemplates'	=> 'this:wp_getPageTemplates',
-			'wp.getOptions'			=> 'this:wp_getOptions',
-			'wp.setOptions'			=> 'this:wp_setOptions',
-			'wp.getComment'			=> 'this:wp_getComment',
-			'wp.getComments'		=> 'this:wp_getComments',
-			'wp.deleteComment'		=> 'this:wp_deleteComment',
-			'wp.editComment'		=> 'this:wp_editComment',
-			'wp.newComment'			=> 'this:wp_newComment',
-			'wp.getCommentStatusList' => 'this:wp_getCommentStatusList',
-			'wp.getMediaItem'		=> 'this:wp_getMediaItem',
-			'wp.getMediaLibrary'	=> 'this:wp_getMediaLibrary',
-			'wp.getPostFormats'     => 'this:wp_getPostFormats',
-			'wp.getPostType'		=> 'this:wp_getPostType',
-			'wp.getPostTypes'		=> 'this:wp_getPostTypes',
-			'wp.getRevisions'		=> 'this:wp_getRevisions',
-			'wp.restoreRevision'	=> 'this:wp_restoreRevision',
+			'wp.getUsersBlogs'		=> array( $this, 'wp_getUsersBlogs' ),
+			'wp.newPost'			=> array( $this, 'wp_newPost' ),
+			'wp.editPost'			=> array( $this, 'wp_editPost' ),
+			'wp.deletePost'			=> array( $this, 'wp_deletePost' ),
+			'wp.getPost'			=> array( $this, 'wp_getPost' ),
+			'wp.getPosts'			=> array( $this, 'wp_getPosts' ),
+			'wp.newTerm'			=> array( $this, 'wp_newTerm' ),
+			'wp.editTerm'			=> array( $this, 'wp_editTerm' ),
+			'wp.deleteTerm'			=> array( $this, 'wp_deleteTerm' ),
+			'wp.getTerm'			=> array( $this, 'wp_getTerm' ),
+			'wp.getTerms'			=> array( $this, 'wp_getTerms' ),
+			'wp.getTaxonomy'		=> array( $this, 'wp_getTaxonomy' ),
+			'wp.getTaxonomies'		=> array( $this, 'wp_getTaxonomies' ),
+			'wp.getUser'			=> array( $this, 'wp_getUser' ),
+			'wp.getUsers'			=> array( $this, 'wp_getUsers' ),
+			'wp.getProfile'			=> array( $this, 'wp_getProfile' ),
+			'wp.editProfile'		=> array( $this, 'wp_editProfile' ),
+			'wp.getPage'			=> array( $this, 'wp_getPage' ),
+			'wp.getPages'			=> array( $this, 'wp_getPages' ),
+			'wp.newPage'			=> array( $this, 'wp_newPage' ),
+			'wp.deletePage'			=> array( $this, 'wp_deletePage' ),
+			'wp.editPage'			=> array( $this, 'wp_editPage' ),
+			'wp.getPageList'		=> array( $this, 'wp_getPageList' ),
+			'wp.getAuthors'			=> array( $this, 'wp_getAuthors' ),
+			'wp.getCategories'		=> array( $this, 'mw_getCategories' ),		// Alias
+			'wp.getTags'			=> array( $this, 'wp_getTags' ),
+			'wp.newCategory'		=> array( $this, 'wp_newCategory' ),
+			'wp.deleteCategory'		=> array( $this, 'wp_deleteCategory' ),
+			'wp.suggestCategories'	=> array( $this, 'wp_suggestCategories' ),
+			'wp.uploadFile'			=> array( $this, 'mw_newMediaObject' ),	// Alias
+			'wp.getCommentCount'	=> array( $this, 'wp_getCommentCount' ),
+			'wp.getPostStatusList'	=> array( $this, 'wp_getPostStatusList' ),
+			'wp.getPageStatusList'	=> array( $this, 'wp_getPageStatusList' ),
+			'wp.getPageTemplates'	=> array( $this, 'wp_getPageTemplates' ),
+			'wp.getOptions'			=> array( $this, 'wp_getOptions' ),
+			'wp.setOptions'			=> array( $this, 'wp_setOptions' ),
+			'wp.getComment'			=> array( $this, 'wp_getComment' ),
+			'wp.getComments'		=> array( $this, 'wp_getComments' ),
+			'wp.deleteComment'		=> array( $this, 'wp_deleteComment' ),
+			'wp.editComment'		=> array( $this, 'wp_editComment' ),
+			'wp.newComment'			=> array( $this, 'wp_newComment' ),
+			'wp.getCommentStatusList' => array( $this, 'wp_getCommentStatusList' ),
+			'wp.getMediaItem'		=> array( $this, 'wp_getMediaItem' ),
+			'wp.getMediaLibrary'	=> array( $this, 'wp_getMediaLibrary' ),
+			'wp.getPostFormats'     => array( $this, 'wp_getPostFormats' ),
+			'wp.getPostType'		=> array( $this, 'wp_getPostType' ),
+			'wp.getPostTypes'		=> array( $this, 'wp_getPostTypes' ),
+			'wp.getRevisions'		=> array( $this, 'wp_getRevisions' ),
+			'wp.restoreRevision'	=> array( $this, 'wp_restoreRevision' ),
 
 			// Blogger API
-			'blogger.getUsersBlogs' => 'this:blogger_getUsersBlogs',
-			'blogger.getUserInfo' => 'this:blogger_getUserInfo',
-			'blogger.getPost' => 'this:blogger_getPost',
-			'blogger.getRecentPosts' => 'this:blogger_getRecentPosts',
-			'blogger.newPost' => 'this:blogger_newPost',
-			'blogger.editPost' => 'this:blogger_editPost',
-			'blogger.deletePost' => 'this:blogger_deletePost',
+			'blogger.getUsersBlogs' => array( $this, 'blogger_getUsersBlogs' ),
+			'blogger.getUserInfo' => array( $this, 'blogger_getUserInfo' ),
+			'blogger.getPost' => array( $this, 'blogger_getPost' ),
+			'blogger.getRecentPosts' => array( $this, 'blogger_getRecentPosts' ),
+			'blogger.newPost' => array( $this, 'blogger_newPost' ),
+			'blogger.editPost' => array( $this, 'blogger_editPost' ),
+			'blogger.deletePost' => array( $this, 'blogger_deletePost' ),
 
 			// MetaWeblog API (with MT extensions to structs)
-			'metaWeblog.newPost' => 'this:mw_newPost',
-			'metaWeblog.editPost' => 'this:mw_editPost',
-			'metaWeblog.getPost' => 'this:mw_getPost',
-			'metaWeblog.getRecentPosts' => 'this:mw_getRecentPosts',
-			'metaWeblog.getCategories' => 'this:mw_getCategories',
-			'metaWeblog.newMediaObject' => 'this:mw_newMediaObject',
+			'metaWeblog.newPost' => array( $this, 'mw_newPost' ),
+			'metaWeblog.editPost' => array( $this, 'mw_editPost' ),
+			'metaWeblog.getPost' => array( $this, 'mw_getPost' ),
+			'metaWeblog.getRecentPosts' => array( $this, 'mw_getRecentPosts' ),
+			'metaWeblog.getCategories' => array( $this, 'mw_getCategories' ),
+			'metaWeblog.newMediaObject' => array( $this, 'mw_newMediaObject' ),
 
 			// MetaWeblog API aliases for Blogger API
 			// see http://www.xmlrpc.com/stories/storyReader$2460
-			'metaWeblog.deletePost' => 'this:blogger_deletePost',
-			'metaWeblog.getUsersBlogs' => 'this:blogger_getUsersBlogs',
+			'metaWeblog.deletePost' => array( $this, 'blogger_deletePost' ),
+			'metaWeblog.getUsersBlogs' => array( $this, 'blogger_getUsersBlogs' ),
 
 			// MovableType API
-			'mt.getCategoryList' => 'this:mt_getCategoryList',
-			'mt.getRecentPostTitles' => 'this:mt_getRecentPostTitles',
-			'mt.getPostCategories' => 'this:mt_getPostCategories',
-			'mt.setPostCategories' => 'this:mt_setPostCategories',
-			'mt.supportedMethods' => 'this:mt_supportedMethods',
-			'mt.supportedTextFilters' => 'this:mt_supportedTextFilters',
-			'mt.getTrackbackPings' => 'this:mt_getTrackbackPings',
-			'mt.publishPost' => 'this:mt_publishPost',
+			'mt.getCategoryList' => array( $this, 'mt_getCategoryList' ),
+			'mt.getRecentPostTitles' => array( $this, 'mt_getRecentPostTitles' ),
+			'mt.getPostCategories' => array( $this, 'mt_getPostCategories' ),
+			'mt.setPostCategories' => array( $this, 'mt_setPostCategories' ),
+			'mt.supportedMethods' => array( $this, 'mt_supportedMethods' ),
+			'mt.supportedTextFilters' => array( $this, 'mt_supportedTextFilters' ),
+			'mt.getTrackbackPings' => array( $this, 'mt_getTrackbackPings' ),
+			'mt.publishPost' => array( $this, 'mt_publishPost' ),
 
 			// PingBack
-			'pingback.ping' => 'this:pingback_ping',
-			'pingback.extensions.getPingbacks' => 'this:pingback_extensions_getPingbacks',
+			'pingback.ping' => array( $this, 'pingback_ping' ),
+			'pingback.extensions.getPingbacks' => array( $this, 'pingback_extensions_getPingbacks' ),
 
-			'demo.sayHello' => 'this:sayHello',
-			'demo.addTwoNumbers' => 'this:addTwoNumbers'
+			'demo.sayHello' => array( $this, 'sayHello' ),
+			'demo.addTwoNumbers' => array( $this, 'addTwoNumbers' )
 		);
 
 		$this->initialise_blog_option_info();
@@ -130,7 +130,17 @@
 	}
 
 	function serve_request() {
-		$this->IXR_Server($this->methods);
+        // use XML-RPC unless the request is JSON
+        $handler = 'IXR_Server';
+        if ($_SERVER["CONTENT_TYPE"] && $_SERVER["CONTENT_TYPE"] == "application/json") {
+            $handler = 'WP_Json_Rpc_Server';
+        }
+
+        // allow plugin to insert different class to process the request
+        $wp_rpc_request_handler_class = apply_filters( 'wp_rpc_request_handler_class', $handler );
+
+        // the handler class should handle the request, output the response, and exit
+        $wp_rpc_request_handler = new $wp_rpc_request_handler_class($this->methods);
 	}
 
 	/**
Index: wp-includes/class-IXR.php
===================================================================
--- wp-includes/class-IXR.php	(revision 23244)
+++ wp-includes/class-IXR.php	(working copy)
@@ -802,6 +802,7 @@
     var $minute;
     var $second;
     var $timezone;
+    var $timestamp;
 
     function IXR_Date($time)
     {
@@ -811,6 +812,7 @@
         } else {
             $this->parseIso($time);
         }
+        $this->timestamp = $this->getTimestamp();
     }
 
     function parseTimestamp($timestamp)
Index: wp-includes/class-json-rpc.php
===================================================================
--- wp-includes/class-json-rpc.php	(revision 0)
+++ wp-includes/class-json-rpc.php	(working copy)
@@ -0,0 +1,94 @@
+<?php
+
+class WP_Json_Rpc_Server {
+
+    var $callbacks = array();
+    var $id = null;
+
+    function __construct( $callbacks = false ) {
+        if ($callbacks) {
+            $this->callbacks = $callbacks;
+        }
+        $this->serve();
+    }
+
+    function serve() {
+        if ( isset( $_SERVER['REQUEST_METHOD'] ) && $_SERVER['REQUEST_METHOD'] !== 'POST' ) {
+            $this->error( new IXR_Error( 405, 'JSON-RPC server accepts POST requests only.' ) );
+        }
+
+        global $HTTP_RAW_POST_DATA;
+        if (empty($HTTP_RAW_POST_DATA)) {
+            // workaround for a bug in PHP 5.2.2 - http://bugs.php.net/bug.php?id=41293
+            $data = file_get_contents('php://input');
+        } else {
+            $data =& $HTTP_RAW_POST_DATA;
+        }
+
+        $request = json_decode( $data, true );
+
+        if ( $request == null ) {
+            $this->error( new IXR_Error( -32700, 'Parse error' ) );
+        }
+
+        if ( ! isset( $request['jsonrpc'] ) ||
+             $request['jsonrpc'] != '2.0' ||
+             ! isset( $request['method'] ) ) {
+            $this->error( new IXR_Error( -32600, 'Invalid Request' ) );
+        }
+
+        $method = $request['method'];
+        if ( ! array_key_exists( $method, $this->callbacks ) ) {
+            $this->error( new IXR_Error( -32601, 'Method not found' ) );
+        }
+
+        if ( isset( $request['id'] ) ) {
+            $this->id = $request['id'];
+        }
+
+        if ( isset( $request['params'] ) ) {
+            $params = $request['params'];
+        }
+        else {
+            $params = array();
+        }
+
+        $result = call_user_func( $this->callbacks[$method], $params );
+
+        $this->output( $result );
+    }
+
+    function error( $error, $message = false ) {
+        if ( $message && ! is_object( $error ) ) {
+            $error = new IXR_Error($error, $message);
+        }
+
+        $response = array( 'jsonrpc' => '2.0' );
+        $response['error'] = array(
+            'code' => $error->code,
+            'message' => $error->message
+        );
+        $this->output( null, $error );
+    }
+
+    function output( $result = false, $error = false ) {
+        $response = array(
+            'jsonrpc' => '2.0',
+            'id' => $this->id
+        );
+
+        if ( $error ) {
+            $response['error'] = array(
+                'code' => $error->code,
+                'message' => $error->message
+            );
+        }
+        else if ( $result ) {
+            $response['result'] = $result;
+        }
+
+        header( 'Content-Type: application/json' );
+        echo json_encode( $response );
+        exit;
+    }
+}

Property changes on: wp-includes/class-json-rpc.php
___________________________________________________________________
Added: svn:executable
## -0,0 +1 ##
+*
\ No newline at end of property
