Mercurial > hg > nginx-tests
annotate lib/Test/Nginx/Stream.pm @ 1825:3629eda94c1b
Tests: handling of EWOULDBLOCK from sysread() with IO::Socket::SSL.
With IO::Socket::SSL, when select() reports that the socket is readable,
reading from it might still fail with EWOULDBLOCK, since no application
data is available in the socket. In particular, this might happen with
TLSv1.3 when a session ticket is received after the handshake. Fix is
to explicitly check for EWOULDBLOCK errors.
author | Maxim Dounin <mdounin@mdounin.ru> |
---|---|
date | Tue, 21 Mar 2023 02:57:39 +0300 |
parents | 5d3aee48ed8e |
children | 1197c152215b |
rev | line source |
---|---|
816 | 1 package Test::Nginx::Stream; |
2 | |
3 # (C) Andrey Zelenkov | |
4 # (C) Nginx, Inc. | |
5 | |
6 # Module for nginx stream tests. | |
7 | |
8 ############################################################################### | |
9 | |
10 use warnings; | |
11 use strict; | |
12 | |
13 use base qw/ Exporter /; | |
868
d2cb9ed7412e
Tests: stream udp tests.
Andrey Zelenkov <zelenkov@nginx.com>
parents:
816
diff
changeset
|
14 our @EXPORT_OK = qw/ stream dgram /; |
816 | 15 |
16 use Test::More qw//; | |
17 use IO::Select; | |
18 use IO::Socket; | |
19 | |
20 use Test::Nginx; | |
21 | |
22 sub stream { | |
23 return Test::Nginx::Stream->new(@_); | |
24 } | |
25 | |
868
d2cb9ed7412e
Tests: stream udp tests.
Andrey Zelenkov <zelenkov@nginx.com>
parents:
816
diff
changeset
|
26 sub dgram { |
d2cb9ed7412e
Tests: stream udp tests.
Andrey Zelenkov <zelenkov@nginx.com>
parents:
816
diff
changeset
|
27 unshift(@_, "PeerAddr") if @_ == 1; |
d2cb9ed7412e
Tests: stream udp tests.
Andrey Zelenkov <zelenkov@nginx.com>
parents:
816
diff
changeset
|
28 |
d2cb9ed7412e
Tests: stream udp tests.
Andrey Zelenkov <zelenkov@nginx.com>
parents:
816
diff
changeset
|
29 return Test::Nginx::Stream->new( |
d2cb9ed7412e
Tests: stream udp tests.
Andrey Zelenkov <zelenkov@nginx.com>
parents:
816
diff
changeset
|
30 Proto => "udp", |
d2cb9ed7412e
Tests: stream udp tests.
Andrey Zelenkov <zelenkov@nginx.com>
parents:
816
diff
changeset
|
31 @_ |
d2cb9ed7412e
Tests: stream udp tests.
Andrey Zelenkov <zelenkov@nginx.com>
parents:
816
diff
changeset
|
32 ); |
d2cb9ed7412e
Tests: stream udp tests.
Andrey Zelenkov <zelenkov@nginx.com>
parents:
816
diff
changeset
|
33 } |
d2cb9ed7412e
Tests: stream udp tests.
Andrey Zelenkov <zelenkov@nginx.com>
parents:
816
diff
changeset
|
34 |
816 | 35 sub new { |
36 my $self = {}; | |
37 bless $self, shift @_; | |
38 | |
39 unshift(@_, "PeerAddr") if @_ == 1; | |
40 | |
41 $self->{_socket} = IO::Socket::INET->new( | |
42 Proto => "tcp", | |
951
9361c7eddfc1
Tests: parallel tests support.
Andrey Zelenkov <zelenkov@nginx.com>
parents:
935
diff
changeset
|
43 PeerAddr => '127.0.0.1', |
816 | 44 @_ |
45 ) | |
46 or die "Can't connect to nginx: $!\n"; | |
47 | |
48 if ({@_}->{'SSL'}) { | |
49 require IO::Socket::SSL; | |
50 IO::Socket::SSL->start_SSL($self->{_socket}, @_) | |
51 or die $IO::Socket::SSL::SSL_ERROR . "\n"; | |
52 } | |
53 | |
54 $self->{_socket}->autoflush(1); | |
55 | |
56 return $self; | |
57 } | |
58 | |
59 sub write { | |
935
25a4b2fdd3fb
Tests: I/O timeout options introduced in Stream.
Andrey Zelenkov <zelenkov@nginx.com>
parents:
875
diff
changeset
|
60 my ($self, $message, %extra) = @_; |
816 | 61 my $s = $self->{_socket}; |
62 | |
63 local $SIG{PIPE} = 'IGNORE'; | |
64 | |
65 $s->blocking(0); | |
935
25a4b2fdd3fb
Tests: I/O timeout options introduced in Stream.
Andrey Zelenkov <zelenkov@nginx.com>
parents:
875
diff
changeset
|
66 while (IO::Select->new($s)->can_write($extra{write_timeout} || 1.5)) { |
816 | 67 my $n = $s->syswrite($message); |
68 log_out(substr($message, 0, $n)); | |
69 last unless $n; | |
70 | |
71 $message = substr($message, $n); | |
72 last unless length $message; | |
73 } | |
74 | |
75 if (length $message) { | |
76 $s->close(); | |
77 } | |
78 } | |
79 | |
80 sub read { | |
935
25a4b2fdd3fb
Tests: I/O timeout options introduced in Stream.
Andrey Zelenkov <zelenkov@nginx.com>
parents:
875
diff
changeset
|
81 my ($self, %extra) = @_; |
816 | 82 my ($s, $buf); |
83 | |
84 $s = $self->{_socket}; | |
85 | |
86 $s->blocking(0); | |
1825
3629eda94c1b
Tests: handling of EWOULDBLOCK from sysread() with IO::Socket::SSL.
Maxim Dounin <mdounin@mdounin.ru>
parents:
1824
diff
changeset
|
87 while (IO::Select->new($s)->can_read($extra{read_timeout} || 8)) { |
3629eda94c1b
Tests: handling of EWOULDBLOCK from sysread() with IO::Socket::SSL.
Maxim Dounin <mdounin@mdounin.ru>
parents:
1824
diff
changeset
|
88 my $n = $s->sysread($buf, 1024); |
3629eda94c1b
Tests: handling of EWOULDBLOCK from sysread() with IO::Socket::SSL.
Maxim Dounin <mdounin@mdounin.ru>
parents:
1824
diff
changeset
|
89 next if !defined $n && $!{EWOULDBLOCK}; |
3629eda94c1b
Tests: handling of EWOULDBLOCK from sysread() with IO::Socket::SSL.
Maxim Dounin <mdounin@mdounin.ru>
parents:
1824
diff
changeset
|
90 last; |
1824 | 91 } |
816 | 92 |
93 log_in($buf); | |
94 return $buf; | |
95 } | |
96 | |
97 sub io { | |
98 my $self = shift; | |
99 | |
100 my ($data, %extra) = @_; | |
101 my $length = $extra{length}; | |
868
d2cb9ed7412e
Tests: stream udp tests.
Andrey Zelenkov <zelenkov@nginx.com>
parents:
816
diff
changeset
|
102 my $read = $extra{read}; |
d2cb9ed7412e
Tests: stream udp tests.
Andrey Zelenkov <zelenkov@nginx.com>
parents:
816
diff
changeset
|
103 |
d2cb9ed7412e
Tests: stream udp tests.
Andrey Zelenkov <zelenkov@nginx.com>
parents:
816
diff
changeset
|
104 $read = 1 if !defined $read |
d2cb9ed7412e
Tests: stream udp tests.
Andrey Zelenkov <zelenkov@nginx.com>
parents:
816
diff
changeset
|
105 && $self->{_socket}->socktype() == &SOCK_DGRAM; |
816 | 106 |
935
25a4b2fdd3fb
Tests: I/O timeout options introduced in Stream.
Andrey Zelenkov <zelenkov@nginx.com>
parents:
875
diff
changeset
|
107 $self->write($data, %extra); |
816 | 108 |
109 $data = ''; | |
110 while (1) { | |
868
d2cb9ed7412e
Tests: stream udp tests.
Andrey Zelenkov <zelenkov@nginx.com>
parents:
816
diff
changeset
|
111 last if defined $read && --$read < 0; |
d2cb9ed7412e
Tests: stream udp tests.
Andrey Zelenkov <zelenkov@nginx.com>
parents:
816
diff
changeset
|
112 |
935
25a4b2fdd3fb
Tests: I/O timeout options introduced in Stream.
Andrey Zelenkov <zelenkov@nginx.com>
parents:
875
diff
changeset
|
113 my $buf = $self->read(%extra); |
875
c380b4b7e2e4
Tests: compatibility with perl < 5.12 in Stream.pm.
Andrey Zelenkov <zelenkov@nginx.com>
parents:
868
diff
changeset
|
114 last unless defined $buf and length($buf); |
816 | 115 |
116 $data .= $buf; | |
117 last if defined $length && length($data) >= $length; | |
118 } | |
119 | |
120 return $data; | |
121 } | |
122 | |
1024
91e64c1ceec9
Tests: stream access_log tests.
Sergey Kandaurov <pluknet@nginx.com>
parents:
969
diff
changeset
|
123 sub sockaddr { |
91e64c1ceec9
Tests: stream access_log tests.
Sergey Kandaurov <pluknet@nginx.com>
parents:
969
diff
changeset
|
124 my $self = shift; |
91e64c1ceec9
Tests: stream access_log tests.
Sergey Kandaurov <pluknet@nginx.com>
parents:
969
diff
changeset
|
125 return $self->{_socket}->sockaddr(); |
91e64c1ceec9
Tests: stream access_log tests.
Sergey Kandaurov <pluknet@nginx.com>
parents:
969
diff
changeset
|
126 } |
91e64c1ceec9
Tests: stream access_log tests.
Sergey Kandaurov <pluknet@nginx.com>
parents:
969
diff
changeset
|
127 |
91e64c1ceec9
Tests: stream access_log tests.
Sergey Kandaurov <pluknet@nginx.com>
parents:
969
diff
changeset
|
128 sub sockhost { |
91e64c1ceec9
Tests: stream access_log tests.
Sergey Kandaurov <pluknet@nginx.com>
parents:
969
diff
changeset
|
129 my $self = shift; |
91e64c1ceec9
Tests: stream access_log tests.
Sergey Kandaurov <pluknet@nginx.com>
parents:
969
diff
changeset
|
130 return $self->{_socket}->sockhost(); |
91e64c1ceec9
Tests: stream access_log tests.
Sergey Kandaurov <pluknet@nginx.com>
parents:
969
diff
changeset
|
131 } |
91e64c1ceec9
Tests: stream access_log tests.
Sergey Kandaurov <pluknet@nginx.com>
parents:
969
diff
changeset
|
132 |
816 | 133 sub sockport { |
134 my $self = shift; | |
135 return $self->{_socket}->sockport(); | |
136 } | |
137 | |
138 ############################################################################### | |
139 | |
140 1; | |
141 | |
142 ############################################################################### |