yahns 1.14.1 → 1.18.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +5 -5
- data/.document +2 -0
- data/.gitignore +0 -1
- data/.olddoc.yml +3 -2
- data/Documentation/GNUmakefile +1 -1
- data/Documentation/design_notes.txt +6 -3
- data/Documentation/yahns-rackup.pod +7 -3
- data/Documentation/yahns.pod +1 -1
- data/Documentation/yahns_config.pod +10 -10
- data/GIT-VERSION-FILE +1 -1
- data/GIT-VERSION-GEN +3 -3
- data/HACKING +13 -13
- data/NEWS +982 -829
- data/README +11 -12
- data/Rakefile +121 -5
- data/examples/https_proxy_pass.conf.rb +36 -0
- data/examples/logrotate.conf +1 -1
- data/examples/proxy_pass.ru +11 -0
- data/extras/autoindex.rb +20 -4
- data/extras/exec_cgi.rb +38 -24
- data/extras/proxy_pass.rb +7 -6
- data/extras/try_gzip_static.rb +4 -1
- data/lib/yahns/acceptor.rb +3 -3
- data/lib/yahns/chunk_body.rb +2 -1
- data/lib/yahns/config.rb +10 -5
- data/lib/yahns/daemon.rb +0 -1
- data/lib/yahns/http_client.rb +28 -18
- data/lib/yahns/http_response.rb +3 -4
- data/lib/yahns/openssl_client.rb +33 -11
- data/lib/yahns/proxy_http_response.rb +3 -1
- data/lib/yahns/proxy_pass.rb +68 -10
- data/lib/yahns/queue_epoll.rb +4 -0
- data/lib/yahns/queue_kqueue.rb +0 -6
- data/lib/yahns/queue_quitter_pipe.rb +4 -1
- data/lib/yahns/rackup_handler.rb +3 -7
- data/lib/yahns/server.rb +47 -27
- data/lib/yahns/server_mp.rb +3 -4
- data/lib/yahns/sigevent_efd.rb +0 -1
- data/lib/yahns/sigevent_pipe.rb +13 -6
- data/lib/yahns/socket_helper.rb +1 -1
- data/lib/yahns/stream_input.rb +3 -2
- data/lib/yahns/tee_input.rb +1 -3
- data/lib/yahns/version.rb +1 -1
- data/lib/yahns/wbuf.rb +10 -3
- data/lib/yahns/worker.rb +8 -0
- data/lib/yahns.rb +12 -7
- data/man/yahns-rackup.1 +17 -17
- data/man/yahns.1 +11 -15
- data/man/yahns_config.5 +31 -31
- data/test/helper.rb +6 -2
- data/test/server_helper.rb +20 -5
- data/test/test_bin.rb +33 -30
- data/test/test_config.rb +2 -2
- data/test/test_extras_exec_cgi.rb +24 -1
- data/test/test_extras_try_gzip_static.rb +1 -1
- data/test/test_mt_accept.rb +0 -2
- data/test/test_proxy_pass.rb +1 -2
- data/test/test_proxy_pass_no_buffering.rb +1 -1
- data/test/test_rack_env.rb +58 -0
- data/test/test_serve_static.rb +0 -1
- data/test/test_server.rb +1 -4
- data/test/test_ssl.rb +2 -0
- data/test/test_unix_socket.rb +1 -3
- data/test/test_wbuf.rb +1 -1
- data/yahns.gemspec +8 -5
- metadata +12 -9
data/man/yahns-rackup.1
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
.\" Automatically generated by Pod::Man
|
1
|
+
.\" Automatically generated by Pod::Man 4.07 (Pod::Simple 3.32)
|
2
2
|
.\"
|
3
3
|
.\" Standard preamble:
|
4
4
|
.\" ========================================================================
|
@@ -46,7 +46,7 @@
|
|
46
46
|
.ie \n(.g .ds Aq \(aq
|
47
47
|
.el .ds Aq '
|
48
48
|
.\"
|
49
|
-
.\" If the F register is
|
49
|
+
.\" If the F register is >0, we'll generate index entries on stderr for
|
50
50
|
.\" titles (.TH), headers (.SH), subsections (.SS), items (.Ip), and index
|
51
51
|
.\" entries marked with X<> in POD. Of course, you'll have to process the
|
52
52
|
.\" output yourself in some meaningful fashion.
|
@@ -54,20 +54,16 @@
|
|
54
54
|
.\" Avoid warning from groff about undefined register 'F'.
|
55
55
|
.de IX
|
56
56
|
..
|
57
|
-
.nr
|
58
|
-
.if \
|
59
|
-
.
|
60
|
-
.
|
61
|
-
. de IX
|
62
|
-
. tm Index:\\$1\t\\n%\t"\\$2"
|
57
|
+
.if !\nF .nr F 0
|
58
|
+
.if \nF>0 \{\
|
59
|
+
. de IX
|
60
|
+
. tm Index:\\$1\t\\n%\t"\\$2"
|
63
61
|
..
|
64
|
-
.
|
65
|
-
.
|
66
|
-
.
|
67
|
-
. \}
|
62
|
+
. if !\nF==2 \{\
|
63
|
+
. nr % 0
|
64
|
+
. nr F 2
|
68
65
|
. \}
|
69
66
|
.\}
|
70
|
-
.rr rF
|
71
67
|
.\"
|
72
68
|
.\" Accent mark definitions (@(#)ms.acc 1.5 88/02/08 SMI; from UCB 4.2).
|
73
69
|
.\" Fear. Run. Save yourself. No user-serviceable parts.
|
@@ -133,7 +129,7 @@
|
|
133
129
|
.\" ========================================================================
|
134
130
|
.\"
|
135
131
|
.IX Title "YAHNS-RACKUP 1"
|
136
|
-
.TH YAHNS-RACKUP 1 "1994-10-02" "yahns 1.
|
132
|
+
.TH YAHNS-RACKUP 1 "1994-10-02" "yahns 1.16.0.24.g39049" "yahns user manual"
|
137
133
|
.\" For nroff, turn off justification. Always turn off hyphenation; it makes
|
138
134
|
.\" way too many mistakes in technical documents.
|
139
135
|
.if n .ad l
|
@@ -171,6 +167,10 @@ Listens on a given \s-1ADDRESS. ADDRESS\s0 may be in the form of
|
|
171
167
|
and \s-1PATH\s0 is meant to be a path to a \s-1UNIX\s0 domain socket.
|
172
168
|
Defaults to \*(L"0.0.0.0:9292\*(R" (all addresses on \s-1TCP\s0 port 9292).
|
173
169
|
Multiple addresses may be separated with commas.
|
170
|
+
.Sp
|
171
|
+
For systemd users, a special value of \*(L"inherit\*(R" may be specified
|
172
|
+
to inherit FDs using the \s-1LISTEN_FDS\s0 and \s-1LISTEN_PID\s0 environment
|
173
|
+
variables described in \fIsd_listen_fds\fR\|(3)
|
174
174
|
.IP "\-O stderr_path=PATHNAME" 4
|
175
175
|
.IX Item "-O stderr_path=PATHNAME"
|
176
176
|
Allow redirecting \f(CW$stderr\fR to a given path. Unlike doing this from
|
@@ -268,12 +268,12 @@ See rackup documentation for more details.
|
|
268
268
|
.SH "CONTACT"
|
269
269
|
.IX Header "CONTACT"
|
270
270
|
All feedback welcome via plain-text mail to <mailto:yahns\-public@yhbt.net>
|
271
|
-
No subscription is necessary to
|
272
|
-
|
271
|
+
No subscription is necessary to email us.
|
272
|
+
Mail archives are available at <https://yhbt.net/yahns\-public/>
|
273
273
|
.SH "COPYRIGHT"
|
274
274
|
.IX Header "COPYRIGHT"
|
275
275
|
Copyright (C) 2013\-2016 all contributors <mailto:yahns\-public@yhbt.net>
|
276
|
-
License: \s-1GPL\-3.0+ \s0<
|
276
|
+
License: \s-1GPL\-3.0+ \s0<https://www.gnu.org/licenses/gpl\-3.0.txt>
|
277
277
|
.SH "SEE ALSO"
|
278
278
|
.IX Header "SEE ALSO"
|
279
279
|
\&\fIyahns\fR\|(1), \fIyahns_config\fR\|(5),
|
data/man/yahns.1
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
.\" Automatically generated by Pod::Man
|
1
|
+
.\" Automatically generated by Pod::Man 4.07 (Pod::Simple 3.32)
|
2
2
|
.\"
|
3
3
|
.\" Standard preamble:
|
4
4
|
.\" ========================================================================
|
@@ -46,7 +46,7 @@
|
|
46
46
|
.ie \n(.g .ds Aq \(aq
|
47
47
|
.el .ds Aq '
|
48
48
|
.\"
|
49
|
-
.\" If the F register is
|
49
|
+
.\" If the F register is >0, we'll generate index entries on stderr for
|
50
50
|
.\" titles (.TH), headers (.SH), subsections (.SS), items (.Ip), and index
|
51
51
|
.\" entries marked with X<> in POD. Of course, you'll have to process the
|
52
52
|
.\" output yourself in some meaningful fashion.
|
@@ -54,20 +54,16 @@
|
|
54
54
|
.\" Avoid warning from groff about undefined register 'F'.
|
55
55
|
.de IX
|
56
56
|
..
|
57
|
-
.nr
|
58
|
-
.if \
|
59
|
-
.
|
60
|
-
.
|
61
|
-
. de IX
|
62
|
-
. tm Index:\\$1\t\\n%\t"\\$2"
|
57
|
+
.if !\nF .nr F 0
|
58
|
+
.if \nF>0 \{\
|
59
|
+
. de IX
|
60
|
+
. tm Index:\\$1\t\\n%\t"\\$2"
|
63
61
|
..
|
64
|
-
.
|
65
|
-
.
|
66
|
-
.
|
67
|
-
. \}
|
62
|
+
. if !\nF==2 \{\
|
63
|
+
. nr % 0
|
64
|
+
. nr F 2
|
68
65
|
. \}
|
69
66
|
.\}
|
70
|
-
.rr rF
|
71
67
|
.\"
|
72
68
|
.\" Accent mark definitions (@(#)ms.acc 1.5 88/02/08 SMI; from UCB 4.2).
|
73
69
|
.\" Fear. Run. Save yourself. No user-serviceable parts.
|
@@ -133,7 +129,7 @@
|
|
133
129
|
.\" ========================================================================
|
134
130
|
.\"
|
135
131
|
.IX Title "YAHNS 1"
|
136
|
-
.TH YAHNS 1 "1994-10-02" "yahns 1.
|
132
|
+
.TH YAHNS 1 "1994-10-02" "yahns 1.16.0.24.g39049" "yahns user manual"
|
137
133
|
.\" For nroff, turn off justification. Always turn off hyphenation; it makes
|
138
134
|
.\" way too many mistakes in technical documents.
|
139
135
|
.if n .ad l
|
@@ -205,7 +201,7 @@ See \fIyahns_config\fR\|(5) for documentation on the configuration file format.
|
|
205
201
|
.SH "CONTACT"
|
206
202
|
.IX Header "CONTACT"
|
207
203
|
All feedback welcome via plain-text mail to <mailto:yahns\-public@yhbt.net>
|
208
|
-
No subscription is necessary to
|
204
|
+
No subscription is necessary to email us.
|
209
205
|
Mail archives are available at <https://yhbt.net/yahns\-public/>
|
210
206
|
.SH "COPYRIGHT"
|
211
207
|
.IX Header "COPYRIGHT"
|
data/man/yahns_config.5
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
.\" Automatically generated by Pod::Man
|
1
|
+
.\" Automatically generated by Pod::Man 4.10 (Pod::Simple 3.35)
|
2
2
|
.\"
|
3
3
|
.\" Standard preamble:
|
4
4
|
.\" ========================================================================
|
@@ -46,7 +46,7 @@
|
|
46
46
|
.ie \n(.g .ds Aq \(aq
|
47
47
|
.el .ds Aq '
|
48
48
|
.\"
|
49
|
-
.\" If the F register is
|
49
|
+
.\" If the F register is >0, we'll generate index entries on stderr for
|
50
50
|
.\" titles (.TH), headers (.SH), subsections (.SS), items (.Ip), and index
|
51
51
|
.\" entries marked with X<> in POD. Of course, you'll have to process the
|
52
52
|
.\" output yourself in some meaningful fashion.
|
@@ -56,12 +56,12 @@
|
|
56
56
|
..
|
57
57
|
.nr rF 0
|
58
58
|
.if \n(.g .if rF .nr rF 1
|
59
|
-
.if (\n(rF:(\n(.g==0)) \{
|
60
|
-
. if \nF \{
|
59
|
+
.if (\n(rF:(\n(.g==0)) \{\
|
60
|
+
. if \nF \{\
|
61
61
|
. de IX
|
62
62
|
. tm Index:\\$1\t\\n%\t"\\$2"
|
63
63
|
..
|
64
|
-
. if !\nF==2 \{
|
64
|
+
. if !\nF==2 \{\
|
65
65
|
. nr % 0
|
66
66
|
. nr F 2
|
67
67
|
. \}
|
@@ -133,7 +133,7 @@
|
|
133
133
|
.\" ========================================================================
|
134
134
|
.\"
|
135
135
|
.IX Title "YAHNS_CONFIG 5"
|
136
|
-
.TH YAHNS_CONFIG 5 "1994-10-02" "yahns 1.
|
136
|
+
.TH YAHNS_CONFIG 5 "1994-10-02" "yahns 1.17.0.5.g4e5f" "yahns user manual"
|
137
137
|
.\" For nroff, turn off justification. Always turn off hyphenation; it makes
|
138
138
|
.\" way too many mistakes in technical documents.
|
139
139
|
.if n .ad l
|
@@ -174,7 +174,7 @@ For Rack \s-1HTTP\s0 applications, see \*(L"\s-1RACK APP ARGUMENTS\*(R"\s0 for m
|
|
174
174
|
information.
|
175
175
|
.IP "before_exec &BLOCK" 4
|
176
176
|
.IX Item "before_exec &BLOCK"
|
177
|
-
This runs &BLOCK before Kernel#exec (\
|
177
|
+
This runs &BLOCK before Kernel#exec (\fBexecve\fR\|(2) wrapper). The command
|
178
178
|
array to be passed to Kernel#exec may be modified within this hook:
|
179
179
|
.Sp
|
180
180
|
.Vb 3
|
@@ -287,7 +287,7 @@ Default: / if daemonized, current working directory if not
|
|
287
287
|
.IP "max_events \s-1INTEGER\s0" 4
|
288
288
|
.IX Item "max_events INTEGER"
|
289
289
|
This controls the number of events a worker thread will fetch at
|
290
|
-
once via \
|
290
|
+
once via \fBepoll_wait\fR\|(2) or \fBkevent\fR\|(2).
|
291
291
|
There is no good reason to change this
|
292
292
|
unless you use very few (e.g. 1) worker_threads. Leaving this at
|
293
293
|
1 will give the fairest load balancing behavior with epoll or kqueue.
|
@@ -332,7 +332,7 @@ Default: false
|
|
332
332
|
This controls the maximum size of a request body before it is
|
333
333
|
buffered to the filesystem (instead of memory). This has no effect
|
334
334
|
if input_buffering is false. This also governs the size of an
|
335
|
-
individual \
|
335
|
+
individual \fBread\fR\|(2) system call when reading a request body.
|
336
336
|
.Sp
|
337
337
|
There is generally no need to change this value and this directive
|
338
338
|
may be removed in the future.
|
@@ -340,7 +340,7 @@ may be removed in the future.
|
|
340
340
|
Default: 8192 bytes (8 kilobytes)
|
341
341
|
.IP "client_header_buffer_size \s-1INTEGER\s0" 4
|
342
342
|
.IX Item "client_header_buffer_size INTEGER"
|
343
|
-
This controls the size of a single \
|
343
|
+
This controls the size of a single \fBread\fR\|(2) syscall for reading
|
344
344
|
client request headers. Increase this as needed if your application
|
345
345
|
uses large cookies or long URLs. Lowering this may reduce \s-1GC\s0 and
|
346
346
|
memory allocator overhead.
|
@@ -463,12 +463,12 @@ this means Unix domain sockets must not be placed in /tmp
|
|
463
463
|
The following \s-1OPTIONS\s0 may be specified (but are generally not needed):
|
464
464
|
.IP "backlog: \s-1INTEGER\s0" 4
|
465
465
|
.IX Item "backlog: INTEGER"
|
466
|
-
This is the backlog of the \
|
466
|
+
This is the backlog of the \fBlisten\fR\|(2) syscall.
|
467
467
|
.Sp
|
468
468
|
Some operating systems allow negative values here to specify the
|
469
469
|
maximum allowable value. In most cases, this number is only
|
470
470
|
recommendation and there are other OS-specific tunables and
|
471
|
-
variables that can affect this number. See the \
|
471
|
+
variables that can affect this number. See the \fBlisten\fR\|(2)
|
472
472
|
syscall documentation of your \s-1OS\s0 for the exact semantics of
|
473
473
|
this.
|
474
474
|
.Sp
|
@@ -495,7 +495,7 @@ Default: Operating-system dependent
|
|
495
495
|
Maximum receive and send buffer sizes (in bytes) of sockets.
|
496
496
|
.Sp
|
497
497
|
These correspond to the \s-1SO_RCVBUF\s0 and \s-1SO_SNDBUF\s0 settings which
|
498
|
-
can be set via the \
|
498
|
+
can be set via the \fBsetsockopt\fR\|(2) syscall. Some kernels
|
499
499
|
(e.g. Linux 2.4+) have intelligent auto-tuning mechanisms and
|
500
500
|
there is no need (and it is sometimes detrimental) to specify them.
|
501
501
|
.Sp
|
@@ -511,8 +511,8 @@ This enables multiple, independently-started yahns instances to
|
|
511
511
|
bind to the same port (as long as all the processes enable this).
|
512
512
|
.Sp
|
513
513
|
This option must be used when yahns first binds the listen socket.
|
514
|
-
It cannot be enabled when a socket is inherited via \s-1SIGUSR2
|
515
|
-
|
514
|
+
It cannot be enabled when a socket is inherited via \s-1SIGUSR2\s0
|
515
|
+
(but it will remain on if inherited), and it cannot be enabled
|
516
516
|
directly via \s-1SIGHUP.\s0
|
517
517
|
.Sp
|
518
518
|
Note: there is a chance of connections being dropped if
|
@@ -529,7 +529,7 @@ To enable \s-1TLS\s0 connections, you must configure this yourself.
|
|
529
529
|
See documentation for OpenSSL::SSL::SSLContext
|
530
530
|
for more information:
|
531
531
|
.Sp
|
532
|
-
<
|
532
|
+
<https://docs.ruby\-lang.org/en/trunk/OpenSSL/SSL/SSLContext.html>
|
533
533
|
.Sp
|
534
534
|
Default: none
|
535
535
|
.Sp
|
@@ -539,22 +539,22 @@ An example which seems to work is:
|
|
539
539
|
\& require \*(Aqopenssl\*(Aq
|
540
540
|
\& ssl_ctx = OpenSSL::SSL::SSLContext.new
|
541
541
|
\& ssl_ctx.cert = OpenSSL::X509::Certificate.new(
|
542
|
-
\&
|
542
|
+
\& File.read(\*(Aq/etc/ssl/certs/example.crt\*(Aq)
|
543
543
|
\& )
|
544
544
|
\& ssl_ctx.extra_chain_cert = [
|
545
545
|
\& OpenSSL::X509::Certificate.new(
|
546
|
-
\&
|
546
|
+
\& File.read(\*(Aq/etc/ssl/certs/chain.crt\*(Aq)
|
547
547
|
\& )
|
548
548
|
\& ]
|
549
549
|
\& ssl_ctx.key = OpenSSL::PKey::RSA.new(
|
550
|
-
\&
|
550
|
+
\& File.read(\*(Aq/etc/ssl/private/example.key\*(Aq)
|
551
551
|
\& )
|
552
552
|
\&
|
553
553
|
\& # use defaults provided by Ruby on top of OpenSSL,
|
554
|
-
\& # but disable client certificate verification as it is rare:
|
554
|
+
\& # but disable client certificate verification as it is rare for servers:
|
555
555
|
\& ssl_ctx.set_params(verify_mode: OpenSSL::SSL::VERIFY_NONE)
|
556
556
|
\&
|
557
|
-
\& # Built\-in session cache (only
|
557
|
+
\& # Built\-in session cache (only useful if worker_processes is nil or 1)
|
558
558
|
\& ssl_ctx.session_cache_mode = OpenSSL::SSL::SSLContext::SESSION_CACHE_SERVER
|
559
559
|
\&
|
560
560
|
\& app(:rack, "/path/to/my/app/config.ru") do
|
@@ -676,7 +676,7 @@ here means yahns will enable yahns to use a master/worker process
|
|
676
676
|
model instead of a single process.
|
677
677
|
.Sp
|
678
678
|
If an optional &BLOCK is given, it may be used to configure
|
679
|
-
\&\
|
679
|
+
\&\fBpthread_atfork\fR\|(3)\-style hooks.
|
680
680
|
See \*(L"\s-1WORKER_PROCESSES\-LEVEL DIRECTIVES\*(R"\s0 for details.
|
681
681
|
.Sp
|
682
682
|
Using worker_processes is strongly recommended if your application
|
@@ -692,7 +692,7 @@ Note: all of the atfork_* hooks described here are available inside the
|
|
692
692
|
\&\*(L"app\*(R" blocks, too.
|
693
693
|
.IP "atfork_prepare &BLOCK" 4
|
694
694
|
.IX Item "atfork_prepare &BLOCK"
|
695
|
-
This &BLOCK is executed in the parent before \
|
695
|
+
This &BLOCK is executed in the parent before \fBfork\fR\|(2) operation.
|
696
696
|
This may be useful for app directives which specify \*(L"preload: true\*(R"
|
697
697
|
to disconnect from databases or otherwise close open file descriptors
|
698
698
|
to prevent them from being shared with the children.
|
@@ -700,12 +700,12 @@ to prevent them from being shared with the children.
|
|
700
700
|
Default: none
|
701
701
|
.IP "atfork_parent &BLOCK" 4
|
702
702
|
.IX Item "atfork_parent &BLOCK"
|
703
|
-
This &BLOCK is executed in the parent after the \
|
703
|
+
This &BLOCK is executed in the parent after the \fBfork\fR\|(2) operation.
|
704
704
|
.Sp
|
705
705
|
Default: none
|
706
706
|
.IP "atfork_child &BLOCK" 4
|
707
707
|
.IX Item "atfork_child &BLOCK"
|
708
|
-
This &BLOCK is executed in the child after the \
|
708
|
+
This &BLOCK is executed in the child after the \fBfork\fR\|(2) operation.
|
709
709
|
.Sp
|
710
710
|
This may be useful for app directives which specify \*(L"preload: true\*(R"
|
711
711
|
to reconnect to databases or reopen closed file descriptors which
|
@@ -714,7 +714,7 @@ were closed in the atfork_prepare hook.
|
|
714
714
|
Default: none
|
715
715
|
.SH "RACK APP ARGUMENTS"
|
716
716
|
.IX Header "RACK APP ARGUMENTS"
|
717
|
-
Rack applications take a \s-1PATHNAME\s0 to the \
|
717
|
+
Rack applications take a \s-1PATHNAME\s0 to the \fBrackup\fR\|(1) config file
|
718
718
|
(e.g. \*(L"config.ru\*(R") as its first argument.
|
719
719
|
.PP
|
720
720
|
The only supported keyword argument is:
|
@@ -737,17 +737,17 @@ compatibility.
|
|
737
737
|
See the examples/ directory in the git source tree.
|
738
738
|
.PP
|
739
739
|
.Vb 1
|
740
|
-
\& git clone
|
740
|
+
\& git clone https://yhbt.net/yahns.git
|
741
741
|
.Ve
|
742
742
|
.SH "CONTACT"
|
743
743
|
.IX Header "CONTACT"
|
744
744
|
All feedback welcome via plain-text mail to <mailto:yahns\-public@yhbt.net>
|
745
|
-
No subscription is necessary to
|
746
|
-
|
745
|
+
No subscription is necessary to email us.
|
746
|
+
Mail archives are available at <https://yhbt.net/yahns\-public/>
|
747
747
|
.SH "COPYRIGHT"
|
748
748
|
.IX Header "COPYRIGHT"
|
749
749
|
Copyright (C) 2013\-2016 all contributors <mailto:yahns\-public@yhbt.net>
|
750
|
-
License: \s-1GPL\-3.0
|
750
|
+
License: \s-1GPL\-3.0+\s0 <https://www.gnu.org/licenses/gpl\-3.0.txt>
|
751
751
|
.SH "SEE ALSO"
|
752
752
|
.IX Header "SEE ALSO"
|
753
|
-
\&\
|
753
|
+
\&\fByahns\fR\|(1)
|
data/test/helper.rb
CHANGED
@@ -125,7 +125,7 @@ class IO
|
|
125
125
|
end if ! IO.method_defined?(:nread) && RUBY_PLATFORM =~ /linux/
|
126
126
|
|
127
127
|
def cloexec_pipe
|
128
|
-
IO.pipe
|
128
|
+
IO.pipe
|
129
129
|
end
|
130
130
|
|
131
131
|
def require_exec(cmd)
|
@@ -136,6 +136,10 @@ def require_exec(cmd)
|
|
136
136
|
false
|
137
137
|
end
|
138
138
|
|
139
|
+
def xfork
|
140
|
+
GTL.synchronize { fork { yield } }
|
141
|
+
end
|
142
|
+
|
139
143
|
class DieIfUsed
|
140
144
|
@@n = 0
|
141
145
|
def each
|
@@ -154,7 +158,7 @@ def skip_skb_mem
|
|
154
158
|
[ [ '/proc/sys/net/ipv4/tcp_rmem', "4096 87380 6291456\n" ],
|
155
159
|
[ '/proc/sys/net/ipv4/tcp_wmem', "4096 16384 4194304\n" ]
|
156
160
|
].each do |file, expect|
|
157
|
-
val =
|
161
|
+
val = File.read(file)
|
158
162
|
val == expect or skip "#{file} had: #{val}expected: #{expect}"
|
159
163
|
end
|
160
164
|
end
|
data/test/server_helper.rb
CHANGED
@@ -31,7 +31,7 @@ module ServerHelper
|
|
31
31
|
|
32
32
|
def quit_wait(pid)
|
33
33
|
pid or return
|
34
|
-
err = $!
|
34
|
+
err = $! and warn "Terminating on #{err.inspect} (#{err.class})"
|
35
35
|
Process.kill(:QUIT, pid)
|
36
36
|
_, status = Timeout.timeout(10) { Process.waitpid2(pid) }
|
37
37
|
assert status.success?, status.inspect
|
@@ -52,9 +52,7 @@ module ServerHelper
|
|
52
52
|
# only use for newly bound sockets
|
53
53
|
def get_tcp_client(host, port, tries = 500)
|
54
54
|
begin
|
55
|
-
|
56
|
-
c.close_on_exec = true
|
57
|
-
return c
|
55
|
+
return TCPSocket.new(host, port)
|
58
56
|
rescue Errno::ECONNREFUSED
|
59
57
|
raise if tries < 0
|
60
58
|
tries -= 1
|
@@ -65,16 +63,33 @@ module ServerHelper
|
|
65
63
|
@srv.close if defined?(@srv) && !@srv.closed?
|
66
64
|
@ru.close! if defined?(@ru) && @ru
|
67
65
|
check_err if defined?(@err)
|
66
|
+
Timeout.timeout(30) do
|
67
|
+
Process.kill(:TERM, @tail_pid)
|
68
|
+
Process.waitpid(@tail_pid)
|
69
|
+
end if @tail_pid
|
68
70
|
end
|
69
71
|
|
70
72
|
def server_helper_setup
|
71
73
|
@srv = TCPServer.new(ENV["TEST_HOST"] || "127.0.0.1", 0)
|
72
74
|
@err = tmpfile(%w(srv .err))
|
73
75
|
@ru = nil
|
76
|
+
@tail_pid = nil
|
77
|
+
case tail = ENV['TAIL']
|
78
|
+
when '1'
|
79
|
+
tail = 'tail -f' # POSIX
|
80
|
+
when nil, '0'
|
81
|
+
tail = nil
|
82
|
+
# else : allow users to specify 'tail -F' or 'gtail -F' for GNU
|
83
|
+
end
|
84
|
+
if tail
|
85
|
+
cmd = tail.split(/\s+/)
|
86
|
+
cmd << @err.path
|
87
|
+
@tail_pid = spawn(*cmd)
|
88
|
+
end
|
74
89
|
end
|
75
90
|
|
76
91
|
def mkserver(cfg, srv = @srv)
|
77
|
-
|
92
|
+
xfork do
|
78
93
|
ENV["YAHNS_FD"] = srv.fileno.to_s
|
79
94
|
srv.autoclose = false
|
80
95
|
yield if block_given?
|
data/test/test_bin.rb
CHANGED
@@ -9,40 +9,41 @@ class TestBin < Testcase
|
|
9
9
|
|
10
10
|
def setup
|
11
11
|
server_helper_setup
|
12
|
-
@cmd = %W(ruby -I lib bin/yahns)
|
12
|
+
@cmd = %W(#{RbConfig.ruby} -I lib bin/yahns)
|
13
13
|
end
|
14
14
|
|
15
15
|
def test_listen_fd3
|
16
16
|
return unless RUBY_VERSION.to_f > 2.3 # Fixed in ruby/trunk r51209, actually
|
17
|
-
@srv.setsockopt(:SOL_SOCKET, :SO_KEEPALIVE, 0)
|
18
17
|
host, port = @srv.addr[3], @srv.addr[1]
|
19
18
|
|
20
19
|
ru = tmpfile(%w(test_bin_daemon .ru))
|
21
20
|
ru.write("require 'rack/lobster'; run Rack::Lobster.new\n")
|
22
|
-
cmd = %W(ruby -I lib bin/yahns-rackup
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
21
|
+
cmd = %W(#{RbConfig.ruby} -I lib bin/yahns-rackup -E none #{ru.path})
|
22
|
+
[ %w(-O listen=inherit), %W(-p #{port} -o #{host}) ].each do |opt|
|
23
|
+
@srv.setsockopt(:SOL_SOCKET, :SO_KEEPALIVE, 0)
|
24
|
+
begin
|
25
|
+
pid = xfork do # emulate a systemd environment
|
26
|
+
env = { 'LISTEN_PID' => $$.to_s, 'LISTEN_FDS' => '1' }
|
27
|
+
cmd.concat(opt)
|
28
|
+
exec env, *cmd, 3 => @srv, err: @err.path
|
29
|
+
end
|
30
|
+
Net::HTTP.start(host, port) do |http|
|
31
|
+
req = Net::HTTP::Get.new("/")
|
32
|
+
res = http.request(req)
|
33
|
+
assert_equal 200, res.code.to_i
|
34
|
+
assert_equal "keep-alive", res["Connection"]
|
35
|
+
end
|
36
|
+
assert @srv.getsockopt(:SOL_SOCKET, :SO_KEEPALIVE).bool,
|
37
|
+
'ensure the inheriting process applies TCP socket options'
|
38
|
+
ensure
|
39
|
+
if pid
|
40
|
+
Process.kill(:QUIT, pid)
|
41
|
+
_, status = Process.waitpid2(pid)
|
42
|
+
assert status.success?, status.inspect
|
43
|
+
end
|
44
|
+
end
|
36
45
|
end
|
37
|
-
|
38
|
-
assert_equal 1, @srv.getsockopt(:SOL_SOCKET, :SO_KEEPALIVE).int,
|
39
|
-
'ensure the inheriting process applies TCP socket options'
|
40
46
|
ensure
|
41
|
-
if pid
|
42
|
-
Process.kill(:QUIT, pid)
|
43
|
-
_, status = Process.waitpid2(pid)
|
44
|
-
assert status.success?, status.inspect
|
45
|
-
end
|
46
47
|
ru.close! if ru
|
47
48
|
end
|
48
49
|
|
@@ -76,7 +77,7 @@ class TestBin < Testcase
|
|
76
77
|
cfg.puts "end"
|
77
78
|
@cmd.concat(%W(-D -c #{cfg.path}))
|
78
79
|
addr = cloexec_pipe
|
79
|
-
pid =
|
80
|
+
pid = xfork do
|
80
81
|
opts = { close_others: true }
|
81
82
|
addr[0].close
|
82
83
|
if inherit
|
@@ -98,7 +99,10 @@ class TestBin < Testcase
|
|
98
99
|
# Even with a synchronous FD_CLOEXEC, there's a chance of a race
|
99
100
|
# because the server does not bind right away.
|
100
101
|
unless inherit
|
101
|
-
|
102
|
+
begin
|
103
|
+
@srv.shutdown
|
104
|
+
rescue Errno::ENOTCONN
|
105
|
+
end
|
102
106
|
@srv.close
|
103
107
|
end
|
104
108
|
exec(*@cmd)
|
@@ -158,11 +162,10 @@ class TestBin < Testcase
|
|
158
162
|
# need to fork here since tests are MT and the FD can leak out and go to
|
159
163
|
# other processes which fork (but do not exec), causing ETXTBUSY on
|
160
164
|
# Process.spawn
|
161
|
-
pid =
|
162
|
-
ruby = "#!#{`which ruby`}"
|
165
|
+
pid = xfork do
|
163
166
|
File.open(exe, "w") { |y|
|
164
167
|
lines = File.readlines("bin/yahns")
|
165
|
-
lines[0] = ruby
|
168
|
+
lines[0] = "#!#{RbConfig.ruby}\n"
|
166
169
|
y.chmod(0755)
|
167
170
|
y.syswrite(lines.join)
|
168
171
|
}
|
@@ -190,7 +193,7 @@ class TestBin < Testcase
|
|
190
193
|
}
|
191
194
|
cmd = %W(#{exe} -D -c #{cfg.path})
|
192
195
|
cmd << { @srv => @srv, close_others: true }
|
193
|
-
pid =
|
196
|
+
pid = Process.spawn(env, *cmd)
|
194
197
|
res = Net::HTTP.start(host, port) { |h| h.get("/") }
|
195
198
|
assert_equal 200, res.code.to_i
|
196
199
|
orig = res.body
|
data/test/test_config.rb
CHANGED
@@ -13,7 +13,7 @@ class TestConfig < Testcase
|
|
13
13
|
end
|
14
14
|
|
15
15
|
def test_multi_conf_example
|
16
|
-
pid =
|
16
|
+
pid = xfork do
|
17
17
|
tmpdir = yahns_mktmpdir
|
18
18
|
|
19
19
|
# modify the example config file for testing
|
@@ -37,7 +37,7 @@ class TestConfig < Testcase
|
|
37
37
|
end
|
38
38
|
|
39
39
|
def test_rack_basic_conf_example
|
40
|
-
pid =
|
40
|
+
pid = xfork do
|
41
41
|
tmpdir = yahns_mktmpdir
|
42
42
|
|
43
43
|
# modify the example config file for testing
|
@@ -170,7 +170,7 @@ class TestExtrasExecCGI < Testcase
|
|
170
170
|
assert_match %r{\A\d+\n\z}, body
|
171
171
|
exec_pid = body.to_i
|
172
172
|
poke_until_dead exec_pid
|
173
|
-
assert_raises(EOFError) { c.
|
173
|
+
assert_raises(EOFError) { c.readpartial(666) }
|
174
174
|
else
|
175
175
|
raise "BUG in test, bad rtype"
|
176
176
|
end
|
@@ -179,4 +179,27 @@ class TestExtrasExecCGI < Testcase
|
|
179
179
|
c.close if c
|
180
180
|
quit_wait(pid)
|
181
181
|
end
|
182
|
+
|
183
|
+
def test_rlimit_options
|
184
|
+
err, cfg, host, port = @err, Yahns::Config.new, @srv.addr[3], @srv.addr[1]
|
185
|
+
tout = 1
|
186
|
+
opts = { rlimit_cpu: tout, rlimit_core: 0 }
|
187
|
+
cmd = [ '/bin/sh', '-c', 'while :; do :;done', opts ]
|
188
|
+
pid = mkserver(cfg) do
|
189
|
+
require './extras/exec_cgi'
|
190
|
+
cfg.instance_eval do
|
191
|
+
stack = Rack::ContentLength.new(Rack::Chunked.new(ExecCgi.new(*cmd)))
|
192
|
+
app(:rack, stack) { listen "#{host}:#{port}" }
|
193
|
+
stderr_path err.path
|
194
|
+
worker_processes 1
|
195
|
+
end
|
196
|
+
end
|
197
|
+
c = get_tcp_client(host, port)
|
198
|
+
c.write "GET / HTTP/1.0\r\n\r\n"
|
199
|
+
assert_same c, c.wait(tout + 5)
|
200
|
+
assert_match %r{ 500 Internal Server Error\b}, c.readpartial(4096)
|
201
|
+
c.close
|
202
|
+
ensure
|
203
|
+
quit_wait(pid)
|
204
|
+
end
|
182
205
|
end
|
@@ -52,7 +52,7 @@ class TestExtrasTryGzipStatic < Testcase
|
|
52
52
|
File.symlink "COPYING", "#{tmpdir}/COPYING.relsymlink"
|
53
53
|
gplgz = "#{tmpdir}/COPYING.gz"
|
54
54
|
FileUtils.cp("COPYING", gpl)
|
55
|
-
_, status = Process.waitpid2(
|
55
|
+
_, status = Process.waitpid2(xfork do
|
56
56
|
File.open(gplgz, "w") do |fp|
|
57
57
|
Zlib::GzipWriter.wrap(fp.dup) { |io| io.write(GPL_TEXT) }
|
58
58
|
end
|
data/test/test_mt_accept.rb
CHANGED
@@ -14,7 +14,6 @@ class TestMtAccept < Testcase
|
|
14
14
|
skip "Linux kernel required" unless RUBY_PLATFORM =~ /linux/
|
15
15
|
skip "/proc not mounted" unless File.directory?("/proc")
|
16
16
|
err, cfg, host, port = @err, Yahns::Config.new, @srv.addr[3], @srv.addr[1]
|
17
|
-
opts = { threads: 1 }
|
18
17
|
cfg.instance_eval do
|
19
18
|
GTL.synchronize do
|
20
19
|
app(:rack, Rack::Lobster.new) { listen "#{host}:#{port}", threads: 1 }
|
@@ -29,7 +28,6 @@ class TestMtAccept < Testcase
|
|
29
28
|
quit_wait(pid)
|
30
29
|
|
31
30
|
cfg = Yahns::Config.new
|
32
|
-
opts = { threads: 1 }
|
33
31
|
cfg.instance_eval do
|
34
32
|
GTL.synchronize do
|
35
33
|
app(:rack, Rack::Lobster.new) { listen "#{host}:#{port}", threads: 2 }
|
data/test/test_proxy_pass.rb
CHANGED
@@ -6,6 +6,7 @@ require 'json'
|
|
6
6
|
require 'digest'
|
7
7
|
begin
|
8
8
|
require 'kcar'
|
9
|
+
require 'yahns/proxy_pass'
|
9
10
|
rescue LoadError
|
10
11
|
end
|
11
12
|
|
@@ -188,7 +189,6 @@ class TestProxyPass < Testcase
|
|
188
189
|
pid = mkserver(cfg) do
|
189
190
|
@srv.autoclose = @srv2.autoclose = false
|
190
191
|
ENV["YAHNS_FD"] = "#{@srv.fileno},#{@srv2.fileno}"
|
191
|
-
require 'yahns/proxy_pass'
|
192
192
|
cfg.instance_eval do
|
193
193
|
app(:rack, Yahns::ProxyPass.new("unix:#{unix_path}:/$fullpath")) do
|
194
194
|
listen "#{host}:#{port}"
|
@@ -251,7 +251,6 @@ class TestProxyPass < Testcase
|
|
251
251
|
err, cfg, host, port = @err, Yahns::Config.new, @srv.addr[3], @srv.addr[1]
|
252
252
|
host2, port2 = @srv2.addr[3], @srv2.addr[1]
|
253
253
|
pid = mkserver(cfg) do
|
254
|
-
require 'yahns/proxy_pass'
|
255
254
|
@srv2.close
|
256
255
|
cfg.instance_eval do
|
257
256
|
app(:rack, Yahns::ProxyPass.new("http://#{host2}:#{port2}")) do
|
@@ -4,6 +4,7 @@
|
|
4
4
|
require_relative 'server_helper'
|
5
5
|
begin
|
6
6
|
require 'kcar'
|
7
|
+
require 'yahns/proxy_pass'
|
7
8
|
rescue LoadError
|
8
9
|
end
|
9
10
|
require 'digest/md5'
|
@@ -39,7 +40,6 @@ class TestProxyPassNoBuffering < Testcase
|
|
39
40
|
@srv2 = TCPServer.new(ENV["TEST_HOST"] || "127.0.0.1", 0)
|
40
41
|
server_helper_setup
|
41
42
|
skip "kcar missing yahns/proxy_pass" unless defined?(Kcar)
|
42
|
-
require 'yahns/proxy_pass'
|
43
43
|
@tmpdir = yahns_mktmpdir
|
44
44
|
end
|
45
45
|
|