I think it should work, however it needs to be tested. In practice I used $request_body only for logging, not sure if it is available at the rewrite stage of request processing. Here is an official description which says:
The variable’s value is made available in locations processed by the proxy_pass, fastcgi_pass, uwsgi_pass, and scgi_pass directives when the request body was read to a memory buffer.
Additionally, you don't need those capture groups to check a variable for substring presence if you don't use them later (in fact you just wasting resources to keep them in memory), just if ($request_body ~* "specialstudent") { ... } should be enough.
Update
Here is another approach that has more chances to work since proxy_add_header directive is definitely executed later than the rewrite stage of request processing:
map $request_body $special {
~*"specialstudent" "special";
# otherwise '$special' variable value will be empty
}
server {
...
location /students-api {
...
proxy_set_header X-Student-Status $special;
...
}
}
Update 2
After testing all of this, I can confirm that the if approach does not work:
server {
...
location /students-api {
if ($request_body ~* "specialstudent") {
set $student_status "special";
}
proxy_set_header X-Student-Status $student_status;
...
}
}
As being expected, the $request_body variable doesn't get initialized at the rewrite stage of request processing. However, the map approach work as expected:
map $request_body $student_status {
~*"specialstudent" "special";
# otherwise '$special' variable value will be empty
}
server {
...
location /students-api {
proxy_set_header X-Student-Status $student_status;
...
}
}
What really surprises me is that the following example doesn't set any of two headers:
map $request_body $student_status {
~*"specialstudent" "special";
# otherwise '$special' variable value will be empty
}
server {
...
location /students-api {
if ($request_body ~* "specialstudent") {
set $student_special "special";
}
proxy_set_header X-Student-Status $student_status;
proxy_set_header X-Student-Special $student_special;
...
}
}
Somehow accessing the $request_body variable at the early rewrite stage of request processing leads the map translation to stop working too. I didn't have an explanation of this behavior for now and would be grateful if someone could explain what happened here.
Update 3
I think I'm finally found an explanation of what happened with the last example in the Nginx Tutorials written by Yichun Zhang, the author of famous lua-nginx-module and the OpenResty bundle:
Some Nginx variables choose to use their value containers as a data cache when the "get handler" is configured. In this setting, the "get handler" is run only once, i.e., at the first time the variable is read, which reduces overhead when the variable is read multiple times during its lifetime.
Looks like the $request_body variable behaves exactly this way, if being accessed at the early NGX_HTTP_REWRITE_PHASE (see the request processing phases description). Its value, if being read during that phase, gets cached as an empty value and became useless during the later request processing phases.