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.