Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Don't prepare the response body for HEAD requests #7970

Open
wants to merge 13 commits into
base: trunk
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 10 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions src/wp-includes/rest-api/class-wp-rest-request.php
Original file line number Diff line number Diff line change
Expand Up @@ -161,6 +161,18 @@ public function get_headers() {
return $this->headers;
}

/**
* Determines if the request is the given method.
*
* @since 6.8.0
*
* @param string $method HTTP method.
* @return bool Whether the request is of the given method.
*/
public function is_method( $method ) {
return $this->get_method() === strtoupper( $method );
}

/**
* Canonicalizes the header name.
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -262,6 +262,12 @@ public function get_items( $request ) {
$prepared_args['offset'] = $prepared_args['number'] * ( absint( $request['page'] ) - 1 );
}

$is_head_request = $request->is_method( 'HEAD' );
if ( $is_head_request ) {
// Force the 'fields' argument. For HEAD requests, only post IDs are required to calculate pagination.
$prepared_args['fields'] = 'ids';
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we avoid priming comment meta here as well?

Copy link
Author

@anton-vlasenko anton-vlasenko Dec 14, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we avoid priming comment meta here as well?

Yes, I think we should avoid priming comment meta here.
Fixed in 294584e

}

/**
* Filters WP_Comment_Query arguments when querying comments via the REST API.
*
Expand All @@ -277,15 +283,17 @@ public function get_items( $request ) {
$query = new WP_Comment_Query();
$query_result = $query->query( $prepared_args );

$comments = array();
if ( ! $is_head_request ) {
$comments = array();

foreach ( $query_result as $comment ) {
if ( ! $this->check_read_permission( $comment, $request ) ) {
continue;
}
foreach ( $query_result as $comment ) {
if ( ! $this->check_read_permission( $comment, $request ) ) {
continue;
}

$data = $this->prepare_item_for_response( $comment, $request );
$comments[] = $this->prepare_response_for_collection( $data );
$data = $this->prepare_item_for_response( $comment, $request );
$comments[] = $this->prepare_response_for_collection( $data );
}
}

$total_comments = (int) $query->found_comments;
Expand All @@ -303,7 +311,7 @@ public function get_items( $request ) {
$max_pages = (int) ceil( $total_comments / $request['per_page'] );
}

$response = rest_ensure_response( $comments );
$response = $is_head_request ? new WP_REST_Response() : rest_ensure_response( $comments );
$response->header( 'X-WP-Total', $total_comments );
$response->header( 'X-WP-TotalPages', $max_pages );

Expand Down Expand Up @@ -427,6 +435,11 @@ public function get_item( $request ) {
return $comment;
}

if ( $request->is_method( 'HEAD' ) ) {
// Don't prepare response body for HEAD requests.
return new WP_REST_Response();
}

$data = $this->prepare_item_for_response( $comment, $request );
$response = rest_ensure_response( $data );

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -402,6 +402,12 @@ static function ( $format ) {
// Force the post_type argument, since it's not a user input variable.
$args['post_type'] = $this->post_type;

$is_head_request = $request->is_method( 'HEAD' );
if ( $is_head_request ) {
// Force the 'fields' argument. For HEAD requests, only post IDs are required to calculate pagination.
$args['fields'] = 'ids';
}

/**
* Filters WP_Query arguments when querying posts via the REST API.
*
Expand Down Expand Up @@ -434,22 +440,24 @@ static function ( $format ) {
add_filter( 'post_password_required', array( $this, 'check_password_required' ), 10, 2 );
}

$posts = array();
if ( ! $is_head_request ) {
$posts = array();

update_post_author_caches( $query_result );
update_post_parent_caches( $query_result );

if ( post_type_supports( $this->post_type, 'thumbnail' ) ) {
update_post_thumbnail_cache( $posts_query );
}
update_post_author_caches( $query_result );
update_post_parent_caches( $query_result );

foreach ( $query_result as $post ) {
if ( ! $this->check_read_permission( $post ) ) {
continue;
if ( post_type_supports( $this->post_type, 'thumbnail' ) ) {
update_post_thumbnail_cache( $posts_query );
}

$data = $this->prepare_item_for_response( $post, $request );
$posts[] = $this->prepare_response_for_collection( $data );
foreach ( $query_result as $post ) {
if ( ! $this->check_read_permission( $post ) ) {
continue;
}

$data = $this->prepare_item_for_response( $post, $request );
$posts[] = $this->prepare_response_for_collection( $data );
}
}

// Reset filter.
Expand Down Expand Up @@ -479,7 +487,7 @@ static function ( $format ) {
);
}

$response = rest_ensure_response( $posts );
$response = $is_head_request ? new WP_REST_Response() : rest_ensure_response( $posts );

$response->header( 'X-WP-Total', (int) $total_posts );
$response->header( 'X-WP-TotalPages', (int) $max_pages );
Expand Down Expand Up @@ -632,8 +640,12 @@ public function get_item( $request ) {
return $post;
}

$data = $this->prepare_item_for_response( $post, $request );
$response = rest_ensure_response( $data );
if ( $request->is_method( 'HEAD' ) ) {
$response = new WP_REST_Response();
} else {
$data = $this->prepare_item_for_response( $post, $request );
$response = rest_ensure_response( $data );
}

if ( is_post_type_viewable( get_post_type_object( $post->post_type ) ) ) {
$response->link_header( 'alternate', get_permalink( $post->ID ), array( 'type' => 'text/html' ) );
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,11 @@ public function get_items_permissions_check( $request ) {
*/
public function get_items( $request ) {

if ( $request->is_method( 'HEAD' ) ) {
// Return early as this method doesn't add any headers.
return new WP_REST_Response();
}

// Retrieve the list of registered collection query parameters.
$registered = $this->get_collection_params();

Expand Down Expand Up @@ -191,6 +196,10 @@ public function get_item( $request ) {
);
}

if ( $request->is_method( 'HEAD' ) ) {
return new WP_REST_Response();
}

$data = $this->prepare_item_for_response( $tax_obj, $request );

return rest_ensure_response( $data );
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -312,6 +312,12 @@ public function get_items( $request ) {
$prepared_args = array_merge( $prepared_args, $taxonomy_obj->args );
}

$is_head_request = $request->is_method( 'HEAD' );
if ( $is_head_request ) {
// Force the 'fields' argument. For HEAD requests, only term IDs are required.
$prepared_args['fields'] = 'ids';
}

/**
* Filters get_terms() arguments when querying terms via the REST API.
*
Expand Down Expand Up @@ -354,14 +360,15 @@ public function get_items( $request ) {
$total_terms = 0;
}

$response = array();

foreach ( $query_result as $term ) {
$data = $this->prepare_item_for_response( $term, $request );
$response[] = $this->prepare_response_for_collection( $data );
if ( ! $is_head_request ) {
$response = array();
foreach ( $query_result as $term ) {
$data = $this->prepare_item_for_response( $term, $request );
$response[] = $this->prepare_response_for_collection( $data );
}
}

$response = rest_ensure_response( $response );
$response = $is_head_request ? new WP_REST_Response() : rest_ensure_response( $response );

// Store pagination values for headers.
$per_page = (int) $prepared_args['number'];
Expand Down Expand Up @@ -468,6 +475,10 @@ public function get_item( $request ) {
return $term;
}

if ( $request->is_method( 'HEAD' ) ) {
return new WP_REST_Response();
}

$response = $this->prepare_item_for_response( $term, $request );

return rest_ensure_response( $response );
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -333,6 +333,12 @@ public function get_items( $request ) {
}
$prepared_args['search'] = '*' . $prepared_args['search'] . '*';
}

$is_head_request = $request->is_method( 'HEAD' );
if ( $is_head_request ) {
// Force the 'fields' argument. For HEAD requests, only user IDs are required.
$prepared_args['fields'] = 'id';
}
/**
* Filters WP_User_Query arguments when querying users via the REST API.
*
Expand All @@ -347,14 +353,16 @@ public function get_items( $request ) {

$query = new WP_User_Query( $prepared_args );

$users = array();
if ( ! $is_head_request ) {
$users = array();

foreach ( $query->get_results() as $user ) {
$data = $this->prepare_item_for_response( $user, $request );
$users[] = $this->prepare_response_for_collection( $data );
foreach ( $query->get_results() as $user ) {
$data = $this->prepare_item_for_response( $user, $request );
$users[] = $this->prepare_response_for_collection( $data );
}
}

$response = rest_ensure_response( $users );
$response = $is_head_request ? new WP_REST_Response() : rest_ensure_response( $users );

// Store pagination values for headers then unset for count query.
$per_page = (int) $prepared_args['number'];
Expand Down Expand Up @@ -480,6 +488,10 @@ public function get_item( $request ) {
return $user;
}

if ( $request->is_method( 'HEAD' ) ) {
return new WP_REST_Response();
}

$user = $this->prepare_item_for_response( $user, $request );
$response = rest_ensure_response( $user );

Expand Down
Loading
Loading