choosing the right title for this article was a bit tricky, but the essence is this: nginx offers a module that allows you to modify the http response body with custom values directly in the nginx configuration. this functionality is similar to the mod_substitute
module in apache, and can be incredibly powerful when you need to modify responses dynamically without altering the source application.
introducing ngx_http_sub_module
nginx comes with a built-in module called ngx_http_sub_module
, which acts as a filter, enabling us to substitute one string with another in the response body. this can be particularly useful in scenarios where you want to replace certain parts of the response content before delivering it to the client.
however, this module is not enabled by default. you need to compile nginx with the --with-http_sub_module
configuration flag to activate it. for users running nginx through ubuntu or debian repositories, this module is included in the nginx-extras
package.
the sub_filter
directive can be placed within the http
, server
, or location
blocks of your nginx configuration, giving you flexibility in how you apply it.
here’s an example configuration:
location / {
sub_filter 'change me!' 'hello from https://$host/';
try_files $uri $uri/ =404;
}
in this case, nginx will replace any instance of the string change me!
in the response body with hello from https://$host/
. additionally, you can tweak the sub_filter
to target specific mime types or headers for more advanced scenarios.
advanced filtering with nginx_substitutions_filter
for those requiring more complex substitution logic, such as using regular expressions (regex) for matching, there’s another option: the nginx_substitutions_filter
module. unlike the built-in ngx_http_sub_module
, this third-party module provides regex-based filtering and more nuanced control over substitutions.
although this module is not distributed with nginx, you can install it by cloning the repository and compiling it alongside nginx.
to install it, run:
git clone git://github.com/yaoweibin/ngx_http_substitutions_filter_module.git
then, compile nginx with the additional module:
./configure --add-module=/path/to/module
the syntax for substitutions is as follows:
subs_filter source_str destination_str [gior]
- g: replace all matching instances (default behavior)
- i: case-insensitive matching
- o: replace only the first occurrence
- r: use regex-based matching (by default, it uses fixed-string matching like
ngx_http_sub_module
)
you can place these substitutions in the server
, http
, or location
blocks.
here’s an example configuration with nginx_substitutions_filter
:
location / {
subs_filter_types text/html text/css text/xml;
subs_filter st(\d*).example.com $1.example.com ir;
subs_filter a.example.com s.example.com;
}
in this case:
- the first substitution uses regex to match any subdomain of
example.com
that starts with "st" followed by any digits and replaces it with$1.example.com
(where$1
is the matched digit sequence). - the second substitution replaces
a.example.com
withs.example.com
.
why use these modules instead of modifying the backend directly?
you might wonder why it’s necessary to use nginx modules like these when you could simply modify the output directly at the source. the answer is that these features become incredibly useful when you are using nginx as a reverse proxy. in this scenario, nginx serves as an intermediary between the client and a backend server (which could be an external ip or domain), and you might not have control over the backend's source code.
by using the ngx_http_sub_module
or nginx_substitutions_filter
, you can intercept and modify the content returned from the proxied server before passing it along to the client, giving you full control over the final output even if the origin server is outside your control.
these modules provide powerful tools to adapt and customize responses in real-time, without needing to alter the core web server or backend application.