Make WordPress Core


Ignore:
Timestamp:
10/27/2020 04:42:38 PM (4 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.