Make WordPress Core


Ignore:
Timestamp:
10/27/2020 04:42:38 PM (6 years ago)
Author:
TimothyBlynJacobs
Message:

REST API: Support a broader range of JSON media types.

Previously, we only supported application/json which prevented using subtypes like application/activity+json. This allows for the REST API to json_decode the body of requests using a JSON subtype Content-Type. Additionally, wp_die() now properly sends the error as JSON when a JSON subtype is specified in the Accept header.

Props pfefferle.
Fixes #49404.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/tests/phpunit/tests/rest-api/rest-request.php

    r48945 r49329  
    177177                // JSON shouldn't be parsed.
    178178                $this->assertEmpty( $this->request->get_param( 'has_json_params' ) );
     179        }
     180
     181        public static function alternate_json_content_type_provider() {
     182                return array(
     183                        array( 'application/ld+json', 'json', true ),
     184                        array( 'application/ld+json; profile="https://www.w3.org/ns/activitystreams"', 'json', true ),
     185                        array( 'application/activity+json', 'json', true ),
     186                        array( 'application/json+oembed', 'json', true ),
     187                        array( 'application/nojson', 'body', false ),
     188                        array( 'application/no.json', 'body', false ),
     189                );
     190        }
     191
     192        /**
     193         * @ticket 49404
     194         * @dataProvider alternate_json_content_type_provider
     195         *
     196         * @param string  $content_type The content-type
     197         * @param string  $source The source value.
     198         * @param boolean $accept_json The accept_json value.
     199         */
     200        public function test_alternate_json_content_type( $content_type, $source, $accept_json ) {
     201                $this->request_with_parameters();
     202
     203                $this->request->set_method( 'POST' );
     204                $this->request->set_header( 'Content-Type', $content_type );
     205                $this->request->set_attributes( array( 'accept_json' => true ) );
     206
     207                // Check that JSON takes precedence.
     208                $this->assertEquals( $source, $this->request->get_param( 'source' ) );
     209                $this->assertEquals( $accept_json, $this->request->get_param( 'has_json_params' ) );
     210        }
     211
     212        public static function is_json_content_type_provider() {
     213                return array(
     214                        array( 'application/ld+json', true ),
     215                        array( 'application/ld+json; profile="https://www.w3.org/ns/activitystreams"', true ),
     216                        array( 'application/activity+json', true ),
     217                        array( 'application/json+oembed', true ),
     218                        array( 'application/nojson', false ),
     219                        array( 'application/no.json', false ),
     220                );
     221        }
     222
     223        /**
     224         * @ticket 49404
     225         * @dataProvider is_json_content_type_provider
     226         *
     227         * @param string  $content_type The content-type
     228         * @param boolean $is_json The is_json value.
     229         */
     230        public function test_is_json_content_type( $content_type, $is_json ) {
     231                $this->request_with_parameters();
     232
     233                $this->request->set_header( 'Content-Type', $content_type );
     234
     235                // Check for JSON content-type.
     236                $this->assertEquals( $is_json, $this->request->is_json_content_type() );
     237        }
     238
     239        /**
     240         * @ticket 49404
     241         */
     242        public function test_content_type_cache() {
     243                $this->request_with_parameters();
     244                $this->assertFalse( $this->request->is_json_content_type() );
     245
     246                $this->request->set_header( 'Content-Type', 'application/json' );
     247                $this->assertTrue( $this->request->is_json_content_type() );
     248
     249                $this->request->set_header( 'Content-Type', 'application/activity+json' );
     250                $this->assertTrue( $this->request->is_json_content_type() );
     251
     252                $this->request->set_header( 'Content-Type', 'application/nojson' );
     253                $this->assertFalse( $this->request->is_json_content_type() );
     254
     255                $this->request->set_header( 'Content-Type', 'application/json' );
     256                $this->assertTrue( $this->request->is_json_content_type() );
     257
     258                $this->request->remove_header( 'Content-Type' );
     259                $this->assertFalse( $this->request->is_json_content_type() );
    179260        }
    180261
Note: See TracChangeset for help on using the changeset viewer.