I've tried doing this with headers and cookies, but haven't had any luck yet. What I think is happening is that these things are set after the request is made.
You are correct.
fastcgi_cache is basically a switch, is it on or off. Your backend has no say in that because nginx doesn't look to the backend at all to figure out whether it should serve the request via cache or fire up FPM. It looks via the things it does have access to at the time... location, query_string, user_agent, etc.
How often does your client need to update?
One of the things that makes nginx fast is config files are only read into memory once. Apache, by contrast, looks for
.htaccess files inside every directory in the tree on every request being served.
To make changes to a config requires nginx to be reloaded (or restarted). Complicating things, port 80 is a privileged port which means to open it up/listen on it, you need to have root permissions. That's not something you would want to give to a user via a web interface.
However, there are some workarounds.
- If you are able to name your slugs differently in advance (e.g. append or prefix "-form" or "-dyn" or something like that to the URL), you can use that to tell nginx not to load from cache. You could even have Craft generate part of the URL for you based on the value of a "Does this have dynamic content?" lightswitch.
- Generate part of the nginx config dynamically by using a cron job which runs a shell script every 15 mins or so to check if there are configuration changes. If there are changes, reload nginx. I'd recommend using a map, put that in a separate file, and then include it so you're not touching of the main config files.
- Use the lua module. Lua is a scripting language that lets you run dynamic code on every request. I haven't used it so I don't know how performant it would be but it could work to set variables, etc.
Caching is super tricky. Varnish has a lot more options when it comes to dynamic content but it's potentially another dameon you need to setup and maintain. nginx is great because of its simplicity, however, that simplicity comes at a cost of flexibility.