@@ -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