-
Notifications
You must be signed in to change notification settings - Fork 0
Running Behind Cloudflare or a CDN
If your site sits behind Cloudflare, a load balancer, or any reverse proxy, read this before going live. Without a small amount of configuration the widget will work fine in testing and then fail for most visitors once there is traffic.
The plugin identifies visitors by REMOTE_ADDR, the address PHP sees the request coming from. Behind a proxy, that is the proxy's address, not the visitor's.
Every visitor therefore looks like the same person. The per-IP ceiling of 15 generations per minute stops being a per-visitor protection and becomes a limit on your entire audience. The sixteenth visitor in any given minute sees:
Please wait before requesting another question.
On a quiet site you will never notice. On a site with real traffic the widget looks broken to most people, most of the time.
The ai_fq_client_ip filter tells the plugin which address to trust. For Cloudflare:
add_filter( 'ai_fq_client_ip', function ( $ip ) {
if ( ! empty( $_SERVER['HTTP_CF_CONNECTING_IP'] ) ) {
return sanitize_text_field( wp_unslash( $_SERVER['HTTP_CF_CONNECTING_IP'] ) );
}
return $ip;
} );Put it in a small must-use plugin or your theme's functions.php.
This is the important caveat, and it is why the plugin does not read forwarded headers by default.
HTTP_CF_CONNECTING_IP, X-Forwarded-For and friends are just request headers. Anyone can send them. If your site is not behind Cloudflare — or is reachable directly on its origin address, bypassing it — then trusting that header hands every caller a free way to look like a different visitor on every request, which is exactly the rate-limit bypass the per-IP ceiling exists to prevent.
Only trust a header that a proxy you control is guaranteed to set and overwrite. If visitors can reach your origin directly, lock that down first.
The pattern is the same, with a different header. For a proxy that sets X-Forwarded-For, take the first entry, since the header is a comma-separated chain that downstream clients can prepend to:
add_filter( 'ai_fq_client_ip', function ( $ip ) {
if ( empty( $_SERVER['HTTP_X_FORWARDED_FOR'] ) ) {
return $ip;
}
$chain = explode( ',', wp_unslash( $_SERVER['HTTP_X_FORWARDED_FOR'] ) );
return sanitize_text_field( trim( $chain[0] ) );
} );Again: only if your proxy overwrites that header rather than appending to whatever the client sent.
There is no admin screen for this. The straightforward test is to load a page with the widget from two devices on different networks — a laptop on wifi and a phone on mobile data — and confirm both get questions rather than the wait message.
For a firmer check, temporarily log what the filter returns and confirm you see real visitor addresses rather than a single repeated proxy address. Remove the logging afterwards.
If your CDN or a caching plugin serves cached HTML, the widget still works. It fetches its question over a REST call at runtime, so cached markup does not mean a cached question — every visitor gets a fresh one.
One detail if you go looking: the widget token embedded in the page is generated when the HTML is rendered, so all visitors served the same cached page share a token. That is harmless. The token is a per-instance correlation value, not authentication, and the punchline is protected by other means. See How the Punchline Stays Hidden.
Getting started
- Home
- What AI Fun Questions Does
- Installing the Plugin
- The Settings Screen
- Adding the Widget to Your Site
Provider setup
Running it
- Keeping API Keys Out of the Database
- Rate Limits Explained
- Running Behind Cloudflare or a CDN
- What It Costs to Run
Troubleshooting
- Error Messages Reference
- Please Wait Before Requesting Another Question
- Could Not Generate a Question
Privacy and security
Extending