2
ngx_echo - Brings "echo", "sleep", "time", "exec" and more shell-style
3
goodies to Nginx config file.
5
*This module is not distributed with the Nginx source.* See the
6
installation instructions.
9
This document describes echo-nginx-module v0.34
10
(<http://github.com/agentzh/echo-nginx-module/tarball/v0.34 >) released
11
on September 14, 2010.
23
location /timed_hello {
26
echo "'hello world' takes about $echo_timer_elapsed sec.";
28
echo "'hiya igor' takes about $echo_timer_elapsed sec.";
31
location /echo_with_sleep {
33
echo_flush; # ensure the client can see previous output immediately
34
echo_sleep 2.5; # in sec
38
# in the following example, accessing /echo yields
45
echo_before_body hello;
46
echo_before_body world;
47
proxy_pass $scheme://127.0.0.1:$server_port$request_uri/more;
55
# the output of /main might be
58
# took 0.000 sec for total.
59
# and the whole request would take about 2 sec to complete.
63
# subrequests in parallel
64
echo_location_async /sub1;
65
echo_location_async /sub2;
67
echo "took $echo_timer_elapsed sec for total.";
78
# the output of /main might be
81
# took 3.003 sec for total.
82
# and the whole request would take about 3 sec to complete.
86
# subrequests in series (chained by CPS)
90
echo "took $echo_timer_elapsed sec for total.";
101
# Accessing /dup gives
104
echo_duplicate 3 "--";
105
echo_duplicate 1 " END ";
106
echo_duplicate 3 "--";
110
# /bighello will generate 1000,000,000 hello's.
112
echo_duplicate 1000_000_000 'hello';
115
# echo back the client request
117
echo_duplicate 1 $echo_client_request_headers;
120
echo_read_request_body;
125
# GET /multi will yields
126
# querystring: foo=Foo
131
# querystring: bar=Bar
137
echo_subrequest_async POST '/sub' -q 'foo=Foo' -b 'hi';
138
echo_subrequest_async PUT '/sub' -q 'bar=Bar' -b 'hello';
141
echo "querystring: $query_string";
142
echo "method: $echo_request_method";
143
echo "body: $echo_request_body";
144
echo "content length: $http_content_length";
148
# GET /merge?/foo.js&/bar/blah.js&/yui/baz.js will merge the .js resources together
150
default_type 'text/javascript';
151
echo_foreach_split '&' $query_string;
152
echo "/* JS File $echo_it */";
153
echo_location_async $echo_it;
158
# accessing /if?val=abc yields the "hit" output
159
# while /if?val=bcd yields "miss":
162
if ($arg_val ~* '^a') {
170
This module wraps lots of Nginx internal APIs for streaming input and
171
output, parallel/sequential subrequests, timers and sleeping, as well as
172
various meta data accessing.
174
Basically it provides various utilities that help testing and debugging
175
of other modules by trivially emulating different kinds of faked
176
subrequest locations.
178
People will also find it useful in real-world applications that need to
180
1. serve static contents directly from memory (loading from the Nginx
183
2. wrap the upstream response with custom header and footer (kinda like
184
the addition module but with contents read directly from the config
185
file and Nginx variables).
187
3. merge contents of various "Nginx locations" (i.e., subrequests)
188
together in a single main request (using echo_location and its
191
This is a special dual-role module that can *lazily* serve as a content
192
handler or register itself as an output filter only upon demand. By
193
default, this module does not do anything at all.
195
Use of any of this module's directives (no matter content handler
196
directives or filter directives) will force the chunked encoding to be
197
used for the HTTP response due to the streaming nature of this module
198
(unless HTTP 1.0 is enforced by the client and the Content-Length header
199
will be set to the size of the first handler directive that generates
202
Technially, this module has also demonstrated the following techniques
203
that might be helpful for module writers:
205
1. Issue parallel subreqeusts directly from content handler.
207
2. Issue chained subrequests directly from content handler, by passing
208
continuation along the subrequest chain.
210
3. Issue subrequests with all HTTP 1.1 methods and even an optional
211
faked HTTP request body.
213
4. Interact with the Nginx event model directly from content handler
214
using custom events and timers, and resume the content handler back
217
5. Dual-role module that can (lazily) serve as a content handler or an
218
output filter or both.
220
6. Nginx config file variable creation and interpolation.
222
7. Streaming output control using output_chain, flush and its friends.
224
8. Read client request body from the content handler, and returns back
225
(asynchronously) to the content handler after completion.
227
9. Use Perl-based declarative test suite to drive the development of
230
Content Handler Directives
231
Use of the following directives register this module to the current
232
Nginx location as a content handler. If you want to use another module,
233
like the standard proxy module, as the content handler, use the filter
234
directives provided by this module.
236
All the content handler directives can be mixed together in a single
237
Nginx location and they're supposed to run sequentially just as in the
238
Bash scripting language.
240
Every content handler directive supports variable interpolation in its
243
The MIME type set by the standard default_type directive is respected by
247
default_type text/plain;
251
Then on the client side:
253
$ curl -I 'http://localhost/echo'
256
Date: Sat, 17 Oct 2009 03:40:19 GMT
257
Content-Type: text/plain
258
Connection: keep-alive
260
Since the v0.22 release, all of the directives are allowed in the
261
rewrite module's if directive block, for instance:
265
if ($arg_val ~* '^a') {
273
syntax: *echo [options] <string>...*
279
Sends arguments joined by spaces, along with a trailing newline, out to
282
Note that the data might be buffered by Nginx's underlying buffer. To
283
force the output data flushed immediately, use the echo_flush command
284
just after "echo", as in
289
When no argument is specified, *echo* emits the trailing newline alone,
290
just like the *echo* command in shell.
292
Variables may appear in the arguments. An example is
294
echo The current request uri is $request_uri;
296
where $request_uri is a variable exposed by the [[NginxHttpCoreModule]].
298
This command can be used multiple times in a single location
306
The output on the client side looks like this
308
$ curl 'http://localhost/echo'
312
Special characters like newlines ("\n") and tabs ("\t") can be escaped
313
using C-style escaping sequences. But a notable exception is the dollar
314
sign ("$"). As of Nginx 0.8.20, there's still no clean way to esacpe
315
this characters. (A work-around might be to use a $echo_dollor variable
316
that is always evaluated to the constant "$" character. This feature
317
will possibly be introduced in a future version of this module.)
319
As of the echo v0.28 release, one can suppress the trailing newline
320
character in the output by using the "-n" option, as in
327
Accessing "/echo" gives
329
$ curl 'http://localhost/echo'
332
Leading "-n" in variable values won't take effect and will be emitted
341
This gives the following output
343
$ curl 'http://localhost/echo'
347
One can output leading "-n" literals and other options using the special
348
"--" option like this
351
echo -- -n is an option;
356
$ curl 'http://localhost/echo'
360
syntax: *echo_duplicate <count> <string>*
366
Outputs duplication of a string indicated by the second argument, using
367
the times specified in the first argument.
372
echo_duplicate 3 "abc";
375
will lead to an output of "abcabcabc".
377
Underscores are allowed in the count number, just like in Perl. For
378
example, to emit 1000,000,000 instances of "hello, world":
380
location /many_hellos {
381
echo_duplicate 1000_000_000 "hello, world";
384
The "count" argument could be zero, but not negative. The second
385
"string" argument could be an empty string ("") likewise.
387
Unlike the echo directive, no trailing newline is appended to the
388
result. So it's possible to "abuse" this directive as a
389
no-trailing-newline version of echo by using "count" 1, as in
392
echo_duplicate 2 '---';
393
echo_duplicate 1 ' END '; # we don't want a trailing newline here
394
echo_duplicate 2 '---';
395
echo; # we want a trailing newline here...
402
This directive was first introduced in version 0.11.
411
Forces the data potentially buffered by underlying Nginx output filters
412
to send immediately to the client side via socket.
414
Note that techically the command just emits a ngx_buf_t object with
415
"flush" slot set to 1, so certain weird third-party output filter module
416
could still block it before it reaches Nginx's (last) write filter.
418
This directive does not take any argument.
420
Consider the following example:
431
Then on the client side, using curl to access "/flush", you'll see the
432
"hello" line immediately, but only after 1 second, the last "world"
433
line. Without calling "echo_flush" in the example above, you'll most
434
likely see no output until 1 second is elapsed due to the internal
437
This directive will fail to flush the output buffer in case of
438
subrequests get involved. Consider the following example:
441
echo_location_async /sub;
449
Then the client won't see "hello" appear even if "echo_flush" has been
450
executed before the subrequest to "/sub" has actually started executing.
451
The outputs of "/main" that are sent *after* echo_location_async will be
452
postponed and buffered firmly.
454
This does *not* apply to outputs sent before the subrequest initiated.
455
For a modified version of the example given above:
460
echo_location_async /sub;
466
The client will immediately see "hello" before "/sub" enters sleeping.
468
See also echo, echo_sleep, and echo_location_async.
471
syntax: *echo_sleep <seconds>*
477
Sleeps for the time period specified by the argument, which is in
480
This operation is non-blocking on server side, so unlike the
481
echo_blocking_sleep directive, it won't block the whole Nginx worker
484
The period might takes three digits after the decimal point and must be
489
location /echo_after_sleep {
494
Behind the scene, it sets up a per-request "sleep" ngx_event_t object,
495
and adds a timer using that custom event to the Nginx event model and
496
just waits for a timeout on that event. Because the "sleep" event is
497
per-request, this directive can work in parallel subrequests.
500
syntax: *echo_blocking_sleep <seconds>*
506
This is a blocking version of the echo_sleep directive.
508
See the documentation of echo_sleep for more detail.
510
Behind the curtain, it calls the ngx_msleep macro provided by the Nginx
511
core which maps to usleep on POSIX-compliant systems.
513
Note that this directive will block the current Nginx worker process
514
completely while being executed, so never use it in production
518
syntax: *echo_reset_timer*
524
Reset the timer begin time to *now*, i.e., the time when this command is
525
executed during request.
527
The timer begin time is default to the starting time of the current
528
request and can be overridden by this directive, potentially multiple
529
times in a single location. For example:
531
location /timed_sleep {
533
echo "$echo_timer_elapsed sec elapsed.";
538
echo "$echo_timer_elapsed sec elapsed.";
541
The output on the client side might be
543
$ curl 'http://localhost/timed_sleep'
547
The actual figures you get on your side may vary a bit due to your
548
system's current activities.
550
Invocation of this directive will force the underlying Nginx timer to
551
get updated to the current system time (regardless the timer resolution
552
specified elsewhere in the config file). Furthermore, references of the
553
$echo_timer_elapsed variable will also trigger timer update forcibly.
555
See also echo_sleep and $echo_timer_elapsed.
557
echo_read_request_body
558
Explicitly reads request body so that the $request_body variable will
559
always have non-empty values (unless the body is so big that it has been
560
saved by Nginx to a local temporary file).
562
Note that this might not be the original client request body because the
563
current request might be a subrequest with a "artificial" body specified
566
This directive does not generate any output itself, just like
569
Here's an example for echo'ing back the original HTTP client request
570
(both headers and body are included):
573
echo_duplicate 1 $echo_client_request_headers;
575
echo_read_request_body;
579
The content of "/echoback" looks like this on my side (I was using
580
Perl's LWP utility to access this location on the server):
582
$ (echo hello; echo world) | lwp-request -m POST 'http://localhost/echoback'
583
POST /echoback HTTP/1.1
584
TE: deflate,gzip;q=0.3
585
Connection: TE, close
587
User-Agent: lwp-request/5.818 libwww-perl/5.820
589
Content-Type: application/x-www-form-urlencoded
594
Because "/echoback" is the main request, $request_body holds the
595
original client request body.
597
Before Nginx 0.7.56, it makes no sense to use this directive because
598
$request_body was first introduced in Nginx 0.7.58.
600
This directive itself was first introduced in the echo module's v0.14
604
syntax: *echo_location_async <location> [<url_args>]*
610
Issue GET subrequest to the location specified (first argument) with
611
optional url arguments specified in the second argument.
613
As of Nginx 0.8.20, the "location" argument does *not* support named
614
location, due to a limitation in the "ngx_http_subrequest" function. The
615
same is true for its brother, the echo_location directive.
617
A very simple example is
620
echo_location_async /sub;
627
Accessing "/main" gets
632
Calling multiple locations in parallel is also possible:
636
echo_location_async /sub1;
637
echo_location_async /sub2;
638
echo "took $echo_timer_elapsed sec for total.";
641
echo_sleep 2; # sleeps 2 sec
645
echo_sleep 1; # sleeps 1 sec
649
Accessing "/main" yields
651
$ time curl 'http://localhost/main'
654
took 0.000 sec for total.
660
You can see that the main handler "/main" does *not* wait the
661
subrequests "/sub1" and "/sub2" to complete and quickly goes on, hence
662
the "0.000 sec" timing result. The whole request, however takes
663
approximately 2 sec in total to complete because "/sub1" and "/sub2" run
664
in parallel (or "concurrently" to be more accurate).
666
If you use echo_blocking_sleep in the previous example instead, then
667
you'll get the same output, but with 3 sec total response time, because
668
"blocking sleep" blocks the whole Nginx worker process.
670
Locations can also take an optional querystring argument, for instance
673
echo_location_async /sub 'foo=Foo&bar=Bar';
676
echo $arg_foo $arg_bar;
679
Accessing "/main" yields
681
$ curl 'http://localhost/main'
684
Querystrings is *not* allowed to be concatenated onto the "location"
685
argument with "?" directly, for example, "/sub?foo=Foo&bar=Bar" is an
686
invalid location, and shouldn't be fed as the first argument to this
689
Due to an unknown bug in Nginx (it still exists in Nginx 0.8.20), the
690
standard SSI module is required to ensure that the contents of the
691
subrequests issued by this directive are correctly merged into the
692
output chains of the main one. Fortunately, the SSI module is enabled by
693
default during Nginx's "configure" process.
695
If calling this directive without SSI module enabled, you'll get
696
truncated response without contents of any subrequests and get an alert
697
message in your Nginx's "error.log", like this:
699
[alert] 24212#0: *1 the http output chain is empty, client: 127.0.0.1, ...
701
Technically speaking, this directive is an example that Nginx content
702
handler issues one or more subrequests directly. AFAIK, the fancyindex
703
module (<https://connectical.com/projects/ngx-fancyindex/wiki >) also
704
does such kind of things ;)
706
Nginx named locations like @foo is *not* supported here.
708
This directive is logically equivalent to the GET version of
709
echo_subrequest_async. For example,
711
echo_location_async /foo 'bar=Bar';
713
is logically equivalent to
715
echo_subrequest_async GET /foo -q 'bar=Bar';
717
But calling this directive is slightly faster than calling
718
echo_subrequest_async using "GET" because we don't have to parse the
719
HTTP method names like "GET" and options like "-q".
721
This directive is first introduced in version 0.09 of this module and
722
requires at least Nginx 0.7.46.
725
syntax: *echo_location <location> [<url_args>]*
731
Just like the echo_location_async directive, but "echo_location" issues
732
subrequests *in series* rather than in parallel. That is, the content
733
handler directives following this directive won't be executed until the
734
subrequest issued by this directive completes.
736
The final response body is almost always equivalent to the case when
737
echo_location_async is used instead, only if timing variables is used in
740
Consider the following example:
746
echo "took $echo_timer_elapsed sec for total.";
757
The location "/main" above will take for total 3 sec to complete
758
(compared to 2 sec if echo_location_async is used instead here). Here's
759
the result in action on my machine:
761
$ curl 'http://localhost/main'
764
took 3.003 sec for total.
770
This directive is logically equivalent to the GET version of
771
echo_subrequest. For example,
773
echo_location /foo 'bar=Bar';
775
is logically equivalent to
777
echo_subrequest GET /foo -q 'bar=Bar';
779
But calling this directive is slightly faster than calling
780
echo_subrequest using "GET" because we don't have to parse the HTTP
781
method names like "GET" and options like "-q".
783
Behind the scene, it creates an "ngx_http_post_subrequest_t" object as a
784
*continuation* and passes it into the "ngx_http_subrequest" function
785
call. Nginx will later reopen this "continuation" in the subrequest's
786
"ngx_http_finalize_request" function call. We resumes the execution of
787
the parent-request's content handler and starts to run the next
788
directive (command) if any.
790
Nginx named locations like @foo is *not* supported here.
792
This directive was first introduced in the release v0.12.
794
See also echo_location_async for more details about the meaning of the
797
echo_subrequest_async
798
syntax: *echo_subrequest_async <HTTP_method> <location> [-q <url_args>]
805
Initiate an asynchronous subrequest using HTTP method, an optional url
806
arguments (or querystring), and an option request body.
808
This directive is very much like a generalized version of the
809
echo_location_async directive.
811
Here's a small example demonstrating its usage:
814
echo_subrequest_async POST '/sub' -q 'foo=Foo' -b 'hi';
815
echo_subrequest_async PUT '/sub' -q 'bar=Bar' -b 'hello';
818
echo "querystring: $query_string";
819
echo "method: $echo_request_method";
820
echo "body: $echo_request_body";
821
echo "content length: $http_content_length";
825
Then on the client side:
827
$ curl 'http://localhost/multi'
839
Here's more funny example using the standard proxy module to handle the
843
echo_subrequest_async POST /sub -b 'hello, world';
846
proxy_pass $scheme://127.0.0.1:$server_port/proxied;
849
echo "method: $echo_request_method.";
851
# we need to read body explicitly here...or $echo_request_body
852
# will evaluate to empty ("")
853
echo_read_request_body;
855
echo "body: $echo_request_body.";
858
Then on the client side, we can see that
860
$ curl 'http://localhost/main'
864
Nginx named locations like @foo is *not* supported here.
866
This directive was first introduced in the release v0.15.
868
See also the echo_subrequest and echo_location_async directives.
871
syntax: *echo_subrequest_async <HTTP_method> <location> [-q <url_args>]
878
This is the synchronous version of the echo_subrequest_async directive.
879
And just like echo_location, it does not block the Nginx worker process
880
(while echo_blocking_sleep does), rather, it uses continuation to pass
881
control along the subrequest chain.
883
See echo_subrequest_async for more details.
885
Nginx named locations like @foo is *not* supported here.
887
This directive was first introduced in the release v0.15.
890
syntax: *echo_foreach_split <delimiter> <string>*
896
Split the second argument "string" using the delimiter specified in the
897
first argument, and then iterate through the resulting items. For
901
echo_foreach_split ',' $arg_list;
902
echo "item: $echo_it";
906
Accessing /main yields
908
$ curl 'http://localhost/loop?list=cat,dog,mouse'
913
As seen in the previous example, this directive should always be
914
accompanied by an echo_end directive.
916
Parallel "echo_foreach_split" loops are allowed, but nested ones are
919
The "delimiter" argument could contain *multiple* arbitrary characters,
922
echo_foreach_split '-a-' 'cat-a-dog-a-mouse';
926
Logically speaking, this looping structure is just the "foreach" loop
927
combined with a "split" function call in Perl (using the previous
930
foreach (split ',', $arg_list) {
934
People will also find it useful in merging multiple ".js" or ".css"
935
resources into a whole. Here's an example:
938
default_type 'text/javascript';
940
echo_foreach_split '&' $query_string;
941
echo "/* JS File $echo_it */";
942
echo_location_async $echo_it;
947
Then accessing /merge to merge the ".js" resources specified in the
950
$ curl 'http://localhost/merge?/foo/bar.js&/yui/blah.js&/baz.js'
952
One can also use third-party Nginx cache module to cache the merged
953
response generated by the "/merge" location in the previous example.
955
This directive was first introduced in the release v0.17.
964
This directive is used to terminate the body of looping and conditional
965
control structures like echo_foreach_split.
967
This directive was first introduced in the release v0.17.
970
syntax: *echo_request_body*
976
Outputs the contents of the request body previous read.
978
Behind the scene, it's implemented roughly like this:
980
if (r->request_body && r->request_body->bufs) {
981
return ngx_http_output_filter(r, r->request_body->bufs);
984
Unlike the $echo_request_body and $request_body variables, this
985
directive will show the whole request body even if some parts or all
986
parts of it are saved in temporary files on the disk.
988
It is a "no-op" if no request body has been read yet.
990
This directive was first introduced in the release v0.18.
992
See also echo_read_request_body and the chunkin module.
995
syntax: *echo_exec <location> [<query_string>]*
997
syntax: *echo_exec <named_location>*
1003
Does an internal redirect to the location specified. An optional query
1004
string can be specified for normal locations, as in
1007
echo_exec /bar weight=5;
1016
echo_exec /bar?weight=5;
1022
Named locations are also supported. Here's an example:
1028
# you'll get /foo rather than @bar
1029
# due to a potential bug in nginx.
1030
echo $echo_request_uri;
1033
But query string (if any) will always be ignored for named location
1034
redirects due to a limitation in the "ngx_http_named_location" function.
1036
Never try to echo things before the "echo_exec" directive or you won't
1037
see the proper response of the location you want to redirect to. Because
1038
any echoing will cause the original location handler to send HTTP
1039
headers before the redirection happens.
1041
Technically speaking, this directive exposes the Nginx internal API
1042
functions "ngx_http_internal_redirect" and "ngx_http_named_location".
1044
This directive was first introduced in the v0.21 release.
1047
Use of the following directives trigger the filter registration of this
1048
module. By default, no filter will be registered by this module.
1050
Every filter directive supports variable interpolation in its arguments
1054
syntax: *echo_before_body [options] [argument]...*
1060
It's the filter version of the echo directive, and prepends its output
1061
to the beginning of the original outputs generated by the underlying
1067
echo_before_body hello;
1068
proxy_pass $scheme://127.0.0.1:$server_port$request_uri/more;
1070
location /echo/more {
1074
Accessing "/echo" from the client side yields
1079
In the previous sample, we borrow the standard proxy module to serve as
1080
the underlying content handler that generates the "main contents".
1082
Multiple instances of this filter directive are also allowed, as in:
1085
echo_before_body hello;
1086
echo_before_body world;
1090
On the client side, the output is like
1092
$ curl 'http://localhost/echo'
1097
In this example, we also use the content handler directives provided by
1098
this module as the underlying content handler.
1100
This directive also supports the "-n" and "--" options like the echo
1103
This directive can be mixed with its brother directive echo_after_body.
1106
syntax: *echo_after_body [argument]...*
1112
WARNING this directive does not work for nginx >= 0.7.65.
1114
It's very much like the echo_before_body directive, but *appends* its
1115
output to the end of the original outputs generated by the underlying
1118
Here's a simple example:
1121
echo_after_body hello;
1122
proxy_pass http://127.0.0.1:$server_port$request_uri/more;
1124
location /echo/more {
1128
Accessing "/echo" from the client side yields
1133
Multiple instances are allowed, as in:
1136
echo_after_body hello;
1137
echo_after_body world;
1142
The output on the client side while accessing the "/echo" location looks
1150
This directive also supports the "-n" and "--" options like the echo
1153
When this directive is used in a location accessed by a subrequest, it
1154
replies on the "sync" flag set in a chain buffer to indicate the end of
1155
the output for nginx >= 0.8.7. This is a hack because Nginx does not
1156
provide a reliable way to determine the end of the output chain in a
1157
subrequest's output filter. Use it in subrequests with care.
1159
This directive can be mixed with its brother directive echo_before_body.
1163
This is a "topic variable" used by echo_foreach_split, just like the $_
1167
This variable holds the seconds elapsed since the start of the current
1168
request (might be a subrequest though) or the last invocation of the
1169
echo_reset_timer command.
1171
The timing result takes three digits after the decimal point.
1173
References of this variable will force the underlying Nginx timer to
1174
update to the current system time, regardless the timer resolution
1175
settings elsewhere in the config file, just like the echo_reset_timer
1179
Evaluates to the current (sub)request's request body previously read if
1180
no part of the body has been saved to a temporary file. To always show
1181
the request body even if it's very large, use the echo_request_body
1184
$echo_request_method
1185
Evaluates to the HTTP request method of the current request (it can be a
1188
Behind the scene, it just takes the string data stored in
1191
Compare it to the $echo_client_request_method variable.
1193
At least for Nginx 0.8.20 and older, the $request_method variable
1194
provided by the http core module is actually doing what our
1195
$echo_client_request_method is doing.
1197
This variable was first introduced in our v0.15 release.
1199
$echo_client_request_method
1200
Always evaluates to the main request's HTTP method even if the current
1201
request is a subrequest.
1203
Behind the scene, it just takes the string data stored in
1204
"r->main->method_name".
1206
Compare it to the $echo_request_method variable.
1208
This variable was first introduced in our v0.15 release.
1210
$echo_client_request_headers
1211
Evaluates to the original client request's headers.
1213
Just as the name suggests, it will always take the main request (or the
1214
client request) even if it's currently executed in a subrequest.
1216
A simple example is below:
1218
location /echoback {
1220
echo $echo_client_request_headers;
1223
Accessing "/echoback" yields
1225
$ curl 'http://localhost/echoback'
1227
GET /echoback HTTP/1.1
1228
User-Agent: curl/7.18.2 (i486-pc-linux-gnu) libcurl/7.18.2 OpenSSL/0.9.8g
1229
Host: localhost:1984
1232
Behind the scene, it recovers "r->main->header_in" on the C level and
1233
does not construct the headers itself by traversing parsed results in
1234
the request object, and strips the last (trailing) CRLF.
1236
This variable was first introduced in version 0.15.
1238
$echo_cacheable_request_uri
1239
Evaluates to the parsed form of the URI (usually led by "/") of the
1240
current (sub-)request. Unlike the $echo_request_uri variable, it is
1243
See $echo_request_uri for more details.
1245
This variable was first introduced in version 0.17.
1248
Evaluates to the parsed form of the URI (usually led by "/") of the
1249
current (sub-)request. Unlike the $echo_cacheable_request_uri variable,
1250
it is *not* cacheable.
1252
This is quite different from the $request_uri variable exported by the
1253
[[NginxHttpCoreModule]], because $request_uri is the *unparsed* form of
1254
the current request's URI.
1256
This variable was first introduced in version 0.17.
1259
It is a counter that always generate the current counting number,
1260
starting from 1. The counter is always associated with the main request
1261
even if it is accessed within a subrequest.
1263
Consider the following example
1266
echo "main pre: $echo_incr";
1267
echo_location_async /sub;
1268
echo_location_async /sub;
1269
echo "main post: $echo_incr";
1272
echo "sub: $echo_incr";
1275
Accessing "/main" yields
1282
This directive was first introduced in the v0.18 release.
1284
$echo_response_status
1285
Evaluates to the status code of the current (sub)request, null if not
1288
Behind the scene, it's just the textual representation of
1289
"r->headers_out->status".
1291
This directive was first introduced in the v0.23 release.
1294
Grab the nginx source code from nginx.net (<http://nginx.net/ >), for
1295
example, the version 0.8.41 (see nginx compatibility), and then build
1296
the source with this module:
1298
$ wget 'http://sysoev.ru/nginx/nginx-0.8.41.tar.gz'
1299
$ tar -xzvf nginx-0.8.41.tar.gz
1302
# Here we assume you would install you nginx under /opt/nginx/.
1303
$ ./configure --prefix=/opt/nginx \
1304
--add-module=/path/to/echo-nginx-module
1309
Download the latest version of the release tarball of this module from
1310
echo-nginx-module file list
1311
(<http://github.com/agentzh/echo-nginx-module/downloads >).
1314
The following versions of Nginx should work with this module:
1316
* 0.8.x (last tested version is 0.8.40)
1318
* 0.7.x >= 0.7.21 (last tested version is 0.7.66)
1322
* the directive echo_location_async and its brother
1323
echo_subrequest_async do *not* work with 0.7.x < 0.7.46.
1325
* the echo_after_body directive does *not* work at all with nginx <
1328
* the echo_sleep directive cannot be used after echo_location or
1329
echo_subrequest for nginx < 0.8.11.
1331
Earlier versions of Nginx like 0.6.x and 0.5.x will *not* work at all.
1333
If you find that any particular version of Nginx above 0.7.21 does not
1334
work with this module, please consider reporting a bug.
1336
Modules that use this module for testing
1337
The following modules take advantage of this "echo" module in their test
1340
* The memc module that supports almost the whole memcached TCP
1343
* The chunkin module that adds HTTP 1.1 chunked input support to
1346
* The headers_more module that allows you to add, set, and clear input
1347
and output headers under the conditions that you specify.
1349
* The "echo" module itself.
1351
Please mail me other modules that use "echo" in any form and I'll add
1352
them to the list above :)
1355
Although a lot of effort has been put into testing and code tuning,
1356
there must be some serious bugs lurking somewhere in this module. So
1357
whenever you are bitten by any quirks, please don't hesitate to
1359
1. send a bug report or even patches to <agentzh@gmail.com>,
1361
2. or create a ticket on the issue tracking interface
1362
(<http://github.com/agentzh/echo-nginx-module/issues >) provided by
1366
Available on github at agentzh/echo-nginx-module
1367
(<http://github.com/agentzh/echo-nginx-module >).
1371
* we no longer use the problematic "ngx_strXcmp" macros in our source
1372
because it may cause invalid reads and thus segmentation faults.
1373
thanks Piotr Sikora.
1376
* fixed compatibility with nginx 0.7.66+ because the ngx_time_update
1377
macro's parameter list has changed. Thanks Guang Feng (蔡镜明).
1380
* we should have used "ngx_calloc_buf" instead of "ngx_alloc_buf" for
1381
the last chunk generated for echo_after_body. thanks valgrind's
1384
* we should initialize flags before feeding it into
1385
"ngx_http_parse_unsafe_uri". thanks valgrind's memcheck tool.
1387
* fixed a minor issue in the echo_location/echo_subrequest
1388
implementation, which used to have race conditions.
1391
* the echo wev handler should not proceed if it is still waiting for
1392
some sequential subrequest or has just processed one to avoid
1395
* fixed a segfault for echo_exec for 0.7.x: we should check "r->done"
1398
* no longer explicitly set "r->write_event_handler" to
1399
"ngx_http_request_empty_handler" because it's totally wrong for the
1402
* fixed the sequential subrequest model bugs: we should ensure the
1403
"pr->write_event_handler" gets called immediately after the
1404
"post_subrequest" callback when the subrequest finalizes.
1407
* fixed the echo_exec directive for nginx >= 0.8.11. we didn't get the
1408
"r->main->count" right in the previous version.
1411
* refactored the core of this module. now the implementation of
1412
echo_location, echo_subrequest, echo_sleep, and
1413
echo_read_request_body finally fit well with the nginx event model
1414
and Igor Sysoev's way of thinking.
1417
* added support for the "-n" and "--" options to the echo,
1418
echo_before_body, and echo_after_body directives.
1421
* applied the patch from Sergey A. Osokin to work with nginx 0.8.35.
1424
* bug fix: we should bypass upstream filters in our echo filters. an
1425
output filter should ever call "ngx_http_output_filter" nor
1426
"ngx_http_send_special".
1429
* now we register a request cleanup handler to ensure our sleep
1430
event's timer will always get properly deleted even if the request
1431
is quit prematurely. this affects the echo_sleep directive.
1433
* use ngx_null_string whenever possible in the source.
1435
* sync'd the bundled test scaffold to Test::Nginx 0.07.
1438
* various source file name and coding style fixes. (the code now looks
1439
more like Igor Sysoev's.)
1442
* now the subrequest can read the client request body directly (for
1443
the main request) because we made subrequests inherit its parent's
1444
"r->header_in" as well. This affects the echo_read_request_body
1447
* fixed echo_after_body in subrequests by using a hack (checking
1448
"cl->buf->sync" for the last buf) for nginx 0.8.7+ only.
1450
* added new varaible $echo_response_status to help testing the status
1451
code of a subrequest. (The memc module makes use of it.)
1453
* use the "ngx_calloc_buf" macro to allocate new bufs in the code
1454
rather than explicit "ngx_pcalloc" calls for safety.
1457
* Now we allowed all the directives appear in the rewrite module's if
1458
block. But so far I've only tested the echo directive.
1461
* Added a new directive named echo_exec which does internal redirect
1462
to other (named) locations.
1465
* Fixed a bug in echo_sleep's "r->main->count" handling for nginx
1466
0.8.x. This bug will cause the server to hang when proxing a
1467
location with echo_sleep.
1469
* Applied the "ngx_str3cmp", "ngx_str4cmp", and "ngx_str6cmp"
1470
optimizing macros to the "parse_method_name" function, as suggested
1473
* Added TODO items regarding $echo_random and "echo_repeat" suggested
1477
* Fixed the CPS-style chained subrequest model for the echo_location
1478
and echo_subrequest directives. they are now working perfectly and
1479
will not hang the server with the recent nginx 0.8.21 ~ 0.8.27
1480
releases. To be specifically, the chained subrequest should call
1481
"ngx_http_finalize_request" on its parent request if the content
1482
handler of the parent request does not return "NGX_DONE".
1484
* Undeprecated the echo_location and echo_subrequest directives.
1487
* Fixed the "zero size buf in output" alerts in error.log.
1489
* Added the new directive echo_request_body.
1491
* Now we use the "ngx_http_parse_unsafe_uri" function to check the
1492
locations to echo_location_async and its friends. Thanks Arvind
1493
Jayaprakash for suggesting this fix.
1495
* Deprecated the echo_location and echo_subrequest directives.
1497
* For HTTP 1.0 clients, use the buf length of the first chain link as
1498
the output header Content-Length.
1500
* Implemented new variable $echo_incr.
1503
* Added new directives echo_foreach_split and echo_end. Also
1504
introduced a "topic variable" named $echo_it.
1506
* Added new variables $echo_request_uri and
1507
$echo_cacheable_request_uri.
1510
* Now the subrequests issued by the echo_location_async and
1511
echo_location directives no longer inherit cached variable values
1512
from its parent request. (The underlying "ngx_http_subrequest"
1513
function, however, does automatic cachable variable value
1516
* Added an undocumented variable *echo_cached_request_uri* to help
1517
testing of this module.
1520
* Added new directives echo_subrequest and echo_subrequest_async for
1521
the full nginx subrequest API.
1523
* Removed the "echo_client_request_headers" directive, and provided
1524
the $echo_client_request_headers variable instead.
1526
* Added new variables $echo_request_method and
1527
$echo_client_request_method.
1530
* Added new directive echo_read_request_body to explicitly read client
1531
request body so that the [[NginxHttpCoreModule#$request_body]]
1532
variable will always have non-empty values.
1534
* Now we shuffer test cases automatically in .t files and fixed bugs
1535
in the tests themselves which are hidden by config reload fallback
1539
* Fixed the special cases when the outputs of a echo_duplicate
1542
* Now we explicitly clear content length and accept ranges headers in
1543
the content handler.
1546
* Implemented the echo_location directive, which can issue chained GET
1547
subrequests in the Continuation Passing Style (CPS), rather than the
1548
parallel subrequest issued by the echo_location_async directive.
1551
* Implemented the echo_duplicate directive to help generating large
1552
chunk of data for testing.
1555
* Fixed compilation regression against Nginx 0.7.21. This bug appears
1558
* Refactored the codebase by splitting source into various small
1562
* Reimplement the echo_sleep directive using per-request event and
1563
timer; the old implementation uses the global connection's
1564
read/write event to register timer, so it will break horribly when
1565
multiple subrequests "sleep" at the same time.
1567
* Added the echo_location_async directive which can issue a GET
1568
subrequest and insert its contents herein.
1571
* echo_sleep: now we delete our "write event timer" in the
1572
"post_sleep" handle.
1574
* Added "doc/manpage.wiki" which tracks changes in the wiki page
1575
(<http://wiki.nginx.org/NginxHttpEchoModule >).
1577
* Added the "util/wiki2pod.pl" script to convert "doc/manpage.wiki" to
1580
* Disabled the "DDEBUG" macro in the C source by default.
1583
This module comes with a Perl-driven test suite. The test cases
1584
(<http://github.com/agentzh/echo-nginx-module/tree/master/test/t/ >) are
1586
(<http://github.com/agentzh/echo-nginx-module/blob/master/test/t/echo.t >
1587
) too. Thanks to the Test::Base
1588
(<http://search.cpan.org/perldoc?Test::Base >) module in the Perl world.
1590
To run it on your side:
1593
$ PATH=/path/to/your/nginx-with-echo-module:$PATH prove -r t
1595
You need to terminate any Nginx processes before running the test suite
1596
if you have changed the Nginx server binary.
1598
At the moment, LWP::UserAgent
1599
(<http://search.cpan.org/perldoc?LWP::UserAgent >) is used by the test
1601
(<http://github.com/agentzh/echo-nginx-module/blob/master/test/lib/Test/
1602
Nginx/Echo.pm>) for simplicity and it's rather weak in testing
1603
*streaming* behavior of Nginx (I'm using "curl" to test these aspects
1604
manually for now). I'm considering coding up my own Perl HTTP client
1605
library based on IO::Select
1606
(<http://search.cpan.org/perldoc?IO::Select >) and IO::Socket
1607
(<http://search.cpan.org/perldoc?IO::Socket >) (there might be already
1610
Because a single nginx server (by default, "localhost:1984") is used
1611
across all the test scripts (".t" files), it's meaningless to run the
1612
test suite in parallel by specifying "-jN" when invoking the "prove"
1615
Some parts of the test suite requires standard modules proxy, rewrite
1616
and SSI to be enabled as well when building Nginx.
1619
* Fix the echo_after_body directive in subrequests.
1621
* Add directives *echo_read_client_request_body* and
1622
*echo_request_headers*.
1624
* Add new directive *echo_log* to use Nginx's logging facility
1625
directly from the config file and specific loglevel can be
1628
echo_log debug "I am being called.";
1630
* Add support for options "-h" and "-t" to echo_subrequest_async and
1631
echo_subrequest. For example
1633
echo_subrequest POST /sub -q 'foo=Foo&bar=Bar' -b 'hello' -t 'text/plan' -h 'X-My-Header: blah blah'
1635
* Add options to control whether a subrequest should inherit cached
1636
variables from its parent request (i.e. the current request that is
1637
calling the subrequest in question). Currently none of the
1638
subrequests issued by this module inherit the cached variables from
1641
* Add new variable *$echo_active_subrequests* to show "r->main->count
1644
* Add the *echo_file* and *echo_cached_file* directives.
1646
* Add new varaible *$echo_request_headers* to accompany the existing
1647
$echo_client_request_headers variable.
1649
* Add new directive *echo_foreach*, as in
1651
echo_foreach 'cat' 'dog' 'mouse';
1652
echo_location_async "/animals/$echo_it";
1655
* Add new directive *echo_foreach_range*, as in
1657
echo_foreach_range '[1..100]' '[a-zA-z0-9]';
1658
echo_location_async "/item/$echo_it";
1661
* Add new directive *echo_repeat*, as in
1665
echo_location "/path/to/page/$i";
1668
This is just another way of saying
1670
echo_foreach_range $i [1..10];
1672
echo_location "/path/to/page/$i";
1675
Thanks Marcus Clyne for providing this idea.
1677
* Add new variable $echo_random which always returns a random
1678
non-negative integer with the lower/upper limit specified by the new
1679
directives "echo_random_min" and "echo_random_max". For example,
1683
echo "random number: $echo_random";
1685
Thanks Marcus Clyne for providing this idea.
1688
You'll be very welcomed to submit patches to the author or just ask for
1689
a commit bit to the source repository on GitHub.
1692
agentzh (章亦春) *<agentzh@gmail.com>*
1694
This wiki page is also maintained by the author himself, and everybody
1695
is encouraged to improve this page as well.
1698
Copyright (c) 2009, Taobao Inc., Alibaba Group ( http://www.taobao.com
1701
Copyright (c) 2009, agentzh <agentzh@gmail.com>.
1703
This module is licensed under the terms of the BSD license.
1705
Redistribution and use in source and binary forms, with or without
1706
modification, are permitted provided that the following conditions are
1709
* Redistributions of source code must retain the above copyright
1710
notice, this list of conditions and the following disclaimer.
1712
* Redistributions in binary form must reproduce the above copyright
1713
notice, this list of conditions and the following disclaimer in the
1714
documentation and/or other materials provided with the distribution.
1716
* Neither the name of the Taobao Inc. nor the names of its
1717
contributors may be used to endorse or promote products derived from
1718
this software without specific prior written permission.
1720
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
1721
IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
1722
TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
1723
PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
1724
HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
1725
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
1726
TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
1727
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
1728
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
1729
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
1730
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
1733
* The original blog post
1734
(<http://agentzh.spaces.live.com/blog/cns!FF3A735632E41548!478.entry
1735
>) about this module's initial development.
1737
* The standard addition filter module.
1739
* The standard proxy module.