Skip to content

Commit 199db1a

Browse files
committed
Add Cache-Control headers for WordPress REST API responses. Implemented a conservative caching policy for GET/HEAD requests, with provisions for logged-in users and a filter for allowed routes.
1 parent 6de7ea4 commit 199db1a

1 file changed

Lines changed: 70 additions & 0 deletions

File tree

default-cache-control.php

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -231,3 +231,73 @@ function cache_control_send_robots_headers() {
231231
}
232232

233233
\add_action( 'do_robots', __NAMESPACE__ . '\\cache_control_send_robots_headers', 1 );
234+
235+
/**
236+
* Sends Cache-Control HTTP headers for WordPress REST API responses.
237+
*
238+
* Applies a conservative caching policy (1 hour) for GET/HEAD requests.
239+
* No header is sent for logged-in users to avoid caching personalized responses.
240+
*
241+
* @since 2.1.0
242+
*
243+
* @param mixed $result Response to send.
244+
* @param \WP_REST_Server $server Server instance.
245+
* @param \WP_REST_Request $request Request used to generate the response.
246+
* @return mixed Modified response.
247+
*/
248+
function cache_control_send_rest_api_headers( $result, $server, $request ) {
249+
$method = $request->get_method();
250+
251+
if ( ! \in_array( $method, [ 'GET', 'HEAD' ], true ) ) {
252+
return $result;
253+
}
254+
255+
if ( \is_user_logged_in() ) {
256+
return $result;
257+
}
258+
259+
if ( ! $result instanceof \WP_REST_Response ) {
260+
return $result;
261+
}
262+
263+
$route = $request->get_route();
264+
265+
/**
266+
* Filter the REST routes allowed to receive Cache-Control headers.
267+
*
268+
* Return an empty array (default) to allow all routes.
269+
*
270+
* @param string[] $whitelist List of allowed routes.
271+
* @param \WP_REST_Request $request Current REST request.
272+
* @param \WP_REST_Server $server REST server instance.
273+
*/
274+
$whitelist = \apply_filters(
275+
'cache_control_rest_route_whitelist',
276+
[],
277+
$request,
278+
$server
279+
);
280+
281+
if ( ! empty( $whitelist ) ) {
282+
if ( ! \is_array( $whitelist ) || ! \in_array( $route, $whitelist, true ) ) {
283+
return $result;
284+
}
285+
}
286+
287+
$s_maxage = \HOUR_IN_SECONDS;
288+
289+
$result->header(
290+
'Cache-Control',
291+
sprintf(
292+
'public, max-age=%d, s-maxage=%d, stale-while-revalidate=%d, stale-if-error=%d',
293+
$s_maxage,
294+
$s_maxage,
295+
$s_maxage * 5,
296+
$s_maxage * 3
297+
)
298+
);
299+
300+
return $result;
301+
}
302+
303+
\add_filter( 'rest_post_dispatch', __NAMESPACE__ . '\\cache_control_send_rest_api_headers', 10, 3 );

0 commit comments

Comments
 (0)