Make WordPress Core


Ignore:
Timestamp:
03/02/2025 10:05:08 PM (3 months ago)
Author:
TimothyBlynJacobs
Message:

REST API: Improve performance for HEAD requests.

By default, the REST API responds to HEAD rqeuests by calling the GET handler and omitting the body from the response. While convenient, this ends up performing needless work that slows down the API response time.

This commit adjusts the Core controllers to specifically handle HEAD requests by not preparing the response body.

Fixes #56481.
Props antonvlasenko, janusdev, ironprogrammer, swissspidy, spacedmonkey, mukesh27, mamaduka, timothyblynjacobs.

File:
1 edited

Legend:

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

    r57839 r59899  
    162162
    163163    /**
     164     * Test pagination headers.
     165     *
     166     * @dataProvider data_readable_http_methods
     167     * @ticket 56481
     168     *
     169     * @param string $method HTTP method to use.
     170     */
     171    public function test_get_items_pagination_headers( $method ) {
     172        $total_posts = count( self::$my_title_post_ids ) + count( self::$my_title_page_ids ) + count( self::$my_content_post_ids );
     173        $per_page    = 3;
     174        $total_pages = (int) ceil( $total_posts / $per_page );
     175
     176        // Start of the index.
     177        $response = $this->do_request_with_params(
     178            array(
     179                'per_page' => $per_page,
     180            ),
     181            $method
     182        );
     183        $headers  = $response->get_headers();
     184        $this->assertSame( $total_posts, $headers['X-WP-Total'] );
     185        $this->assertSame( $total_pages, $headers['X-WP-TotalPages'] );
     186
     187        $next_link = add_query_arg(
     188            array(
     189                'per_page' => $per_page,
     190                'page'     => 2,
     191            ),
     192            rest_url( '/wp/v2/search' )
     193        );
     194        $this->assertStringNotContainsString( 'rel="prev"', $headers['Link'] );
     195        $this->assertStringContainsString( '<' . $next_link . '>; rel="next"', $headers['Link'] );
     196
     197        $response = $this->do_request_with_params(
     198            array(
     199                'per_page' => $per_page,
     200                'page'     => 3,
     201            ),
     202            $method
     203        );
     204        $headers  = $response->get_headers();
     205        $this->assertSame( $total_posts, $headers['X-WP-Total'] );
     206        $this->assertSame( $total_pages, $headers['X-WP-TotalPages'] );
     207        $prev_link = add_query_arg(
     208            array(
     209                'per_page' => $per_page,
     210                'page'     => 2,
     211            ),
     212            rest_url( '/wp/v2/search' )
     213        );
     214        $this->assertStringContainsString( '<' . $prev_link . '>; rel="prev"', $headers['Link'] );
     215        $next_link = add_query_arg(
     216            array(
     217                'per_page' => $per_page,
     218                'page'     => 4,
     219            ),
     220            rest_url( '/wp/v2/search' )
     221        );
     222        $this->assertStringContainsString( '<' . $next_link . '>; rel="next"', $headers['Link'] );
     223
     224        // Last page.
     225        $response = $this->do_request_with_params(
     226            array(
     227                'per_page' => $per_page,
     228                'page'     => $total_pages,
     229            ),
     230            $method
     231        );
     232        $headers  = $response->get_headers();
     233        $this->assertSame( $total_posts, $headers['X-WP-Total'] );
     234        $this->assertSame( $total_pages, $headers['X-WP-TotalPages'] );
     235        $prev_link = add_query_arg(
     236            array(
     237                'per_page' => $per_page,
     238                'page'     => $total_pages - 1,
     239            ),
     240            rest_url( '/wp/v2/search' )
     241        );
     242        $this->assertStringContainsString( '<' . $prev_link . '>; rel="prev"', $headers['Link'] );
     243        $this->assertStringNotContainsString( 'rel="next"', $headers['Link'] );
     244    }
     245
     246    /**
     247     * Data provider intended to provide HTTP method names for testing GET and HEAD requests.
     248     *
     249     * @return array
     250     */
     251    public static function data_readable_http_methods() {
     252        return array(
     253            'GET request'  => array( 'GET' ),
     254            'HEAD request' => array( 'HEAD' ),
     255        );
     256    }
     257
     258    /**
    164259     * Search through all content with a low limit.
    165260     */
     
    240335    /**
    241336     * Search through an invalid type
    242      */
    243     public function test_get_items_search_type_invalid() {
     337     *
     338     * @dataProvider data_readable_http_methods
     339     * @ticket 56481
     340     *
     341     * @param string $method HTTP method to use.
     342     */
     343    public function test_get_items_search_type_invalid( $method ) {
    244344        $response = $this->do_request_with_params(
    245345            array(
    246346                'per_page' => 100,
    247347                'type'     => 'invalid',
    248             )
     348            ),
     349            $method
    249350        );
    250351
     
    254355    /**
    255356     * Search through posts of an invalid post type.
     357     *
     358     * @dataProvider data_readable_http_methods
     359     * @ticket 56481
     360     *
     361     * @param string $method HTTP method to use.
    256362     */
    257363    public function test_get_items_search_type_post_subtype_invalid() {
     
    463569    /**
    464570     * Tests that non-public post types are not allowed.
    465      */
    466     public function test_non_public_post_type() {
     571     *
     572     * @dataProvider data_readable_http_methods
     573     * @ticket 56481
     574     *
     575     * @param string $method HTTP method to use.
     576     */
     577    public function test_non_public_post_type( $method ) {
    467578        $response = $this->do_request_with_params(
    468579            array(
    469580                'type'    => 'post',
    470581                'subtype' => 'post,nav_menu_item',
    471             )
     582            ),
     583            $method
    472584        );
    473585        $this->assertErrorResponse( 'rest_invalid_param', $response, 400 );
     
    633745     * Search through posts of an invalid post type.
    634746     *
     747     *
     748     * @dataProvider data_readable_http_methods
    635749     * @ticket 51458
    636      */
    637     public function test_get_items_search_term_subtype_invalid() {
     750     * @ticket 56481
     751     *
     752     * @param string $method HTTP method to use.
     753     */
     754    public function test_get_items_search_term_subtype_invalid( $method ) {
    638755        $response = $this->do_request_with_params(
    639756            array(
     
    641758                'type'     => 'term',
    642759                'subtype'  => 'invalid',
    643             )
     760            ),
     761            $method
    644762        );
    645763
     
    8911009
    8921010    /**
     1011     * @dataProvider data_readable_http_methods
    8931012     * @ticket 60771
    894      */
    895     public function test_sanitize_subtypes_validates_type() {
     1013     * @ticket 56481
     1014     *
     1015     * @param string $method HTTP method to use.
     1016     */
     1017    public function test_sanitize_subtypes_validates_type( $method ) {
    8961018        $response = $this->do_request_with_params(
    8971019            array(
    8981020                'subtype' => 'page',
    8991021                'type'    => array( 'invalid' ),
    900             )
     1022            ),
     1023            $method
    9011024        );
    9021025
Note: See TracChangeset for help on using the changeset viewer.