Skip to content

Commit b80fd51

Browse files
Don't prepare the response body for HEAD requests in WP_Test_REST_Post_Types_Controller.
1 parent 3bd2742 commit b80fd51

File tree

2 files changed

+79
-6
lines changed

2 files changed

+79
-6
lines changed

src/wp-includes/rest-api/endpoints/class-wp-rest-post-types-controller.php

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,11 @@ public function get_items_permissions_check( $request ) {
109109
* @return WP_REST_Response|WP_Error Response object on success, or WP_Error object on failure.
110110
*/
111111
public function get_items( $request ) {
112+
if ( $request->is_method( 'HEAD' ) ) {
113+
// Return early as this handler doesn't add any response headers.
114+
return new WP_REST_Response();
115+
}
116+
112117
$data = array();
113118
$types = get_post_types( array( 'show_in_rest' => true ), 'objects' );
114119

@@ -159,6 +164,10 @@ public function get_item( $request ) {
159164
);
160165
}
161166

167+
if ( $request->is_method( 'HEAD' ) ) {
168+
return new WP_REST_Response();
169+
}
170+
162171
$data = $this->prepare_item_for_response( $obj, $request );
163172

164173
return rest_ensure_response( $data );

tests/phpunit/tests/rest-api/rest-post-types-controller.php

Lines changed: 70 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -44,14 +44,32 @@ public function test_get_items() {
4444
$this->assertArrayNotHasKey( 'revision', $data );
4545
}
4646

47-
public function test_get_items_invalid_permission_for_context() {
47+
/**
48+
* @dataProvider data_readable_http_methods
49+
* @ticket 56481
50+
*
51+
* @param string $method HTTP method to use.
52+
*/
53+
public function test_get_items_invalid_permission_for_context( $method ) {
4854
wp_set_current_user( 0 );
49-
$request = new WP_REST_Request( 'GET', '/wp/v2/types' );
55+
$request = new WP_REST_Request( $method, '/wp/v2/types' );
5056
$request->set_param( 'context', 'edit' );
5157
$response = rest_get_server()->dispatch( $request );
5258
$this->assertErrorResponse( 'rest_cannot_view', $response, 401 );
5359
}
5460

61+
/**
62+
* Data provider intended to provide HTTP method names for testing GET and HEAD requests.
63+
*
64+
* @return array
65+
*/
66+
public static function data_readable_http_methods() {
67+
return array(
68+
'GET request' => array( 'GET' ),
69+
'HEAD request' => array( 'HEAD' ),
70+
);
71+
}
72+
5573
public function test_get_item() {
5674
$request = new WP_REST_Request( 'GET', '/wp/v2/types/post' );
5775
$response = rest_get_server()->dispatch( $request );
@@ -60,6 +78,24 @@ public function test_get_item() {
6078
$this->assertSame( array( 'category', 'post_tag' ), $data['taxonomies'] );
6179
}
6280

81+
/**
82+
* @ticket 56481
83+
*/
84+
public function test_get_item_with_head_request_should_not_prepare_post_type_data() {
85+
$request = new WP_REST_Request( 'HEAD', '/wp/v2/types/post' );
86+
$hook_name = 'rest_prepare_post_type';
87+
$filter = new MockAction();
88+
$callback = array( $filter, 'filter' );
89+
add_filter( $hook_name, $callback );
90+
$response = rest_get_server()->dispatch( $request );
91+
remove_filter( $hook_name, $callback );
92+
93+
$this->assertSame( 200, $response->get_status(), 'The response status should be 200.' );
94+
95+
$this->assertSame( 0, $filter->get_call_count(), 'The "' . $hook_name . '" filter was called when it should not be for HEAD requests.' );
96+
$this->assertNull( $response->get_data(), 'The server should not generate a body in response to a HEAD request.' );
97+
}
98+
6399
/**
64100
* @ticket 53656
65101
*/
@@ -106,8 +142,14 @@ public function test_get_item_page() {
106142
$this->assertSame( array(), $data['taxonomies'] );
107143
}
108144

109-
public function test_get_item_invalid_type() {
110-
$request = new WP_REST_Request( 'GET', '/wp/v2/types/invalid' );
145+
/**
146+
* @dataProvider data_readable_http_methods
147+
* @ticket 56481
148+
*
149+
* @param string $method HTTP method to use.
150+
*/
151+
public function test_get_item_invalid_type( $method ) {
152+
$request = new WP_REST_Request( $method, '/wp/v2/types/invalid' );
111153
$response = rest_get_server()->dispatch( $request );
112154
$this->assertErrorResponse( 'rest_type_invalid', $response, 404 );
113155
}
@@ -121,9 +163,15 @@ public function test_get_item_edit_context() {
121163
$this->check_post_type_object_response( 'edit', $response );
122164
}
123165

124-
public function test_get_item_invalid_permission_for_context() {
166+
/**
167+
* @dataProvider data_readable_http_methods
168+
* @ticket 56481
169+
*
170+
* @param string $method HTTP method to use.
171+
*/
172+
public function test_get_item_invalid_permission_for_context( $method ) {
125173
wp_set_current_user( 0 );
126-
$request = new WP_REST_Request( 'GET', '/wp/v2/types/post' );
174+
$request = new WP_REST_Request( $method, '/wp/v2/types/post' );
127175
$request->set_param( 'context', 'edit' );
128176
$response = rest_get_server()->dispatch( $request );
129177
$this->assertErrorResponse( 'rest_forbidden_context', $response, 401 );
@@ -245,6 +293,22 @@ public function additional_field_get_callback( $response_data ) {
245293
return 123;
246294
}
247295

296+
/**
297+
* @ticket 56481
298+
*/
299+
public function test_get_items_with_head_request_should_not_prepare_post_types_data() {
300+
$request = new WP_REST_Request( 'HEAD', '/wp/v2/types' );
301+
$hook_name = 'rest_prepare_post_type';
302+
$filter = new MockAction();
303+
$callback = array( $filter, 'filter' );
304+
add_filter( $hook_name, $callback );
305+
$response = rest_get_server()->dispatch( $request );
306+
remove_filter( $hook_name, $callback );
307+
$this->assertSame( 200, $response->get_status(), 'The response status should be 200.' );
308+
$this->assertSame( 0, $filter->get_call_count(), 'The "' . $hook_name . '" filter was called when it should not be for HEAD requests.' );
309+
$this->assertNull( $response->get_data(), 'The server should not generate a body in response to a HEAD request.' );
310+
}
311+
248312
protected function check_post_type_obj( $context, $post_type_obj, $data, $links ) {
249313
$this->assertSame( $post_type_obj->label, $data['name'] );
250314
$this->assertSame( $post_type_obj->name, $data['slug'] );

0 commit comments

Comments
 (0)