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
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
816
77359b849cd5 Tests: stream package.
Andrey Zelenkov <zelenkov@nginx.com>
parents:
diff changeset
1 package Test::Nginx::Stream;
77359b849cd5 Tests: stream package.
Andrey Zelenkov <zelenkov@nginx.com>
parents:
diff changeset
2
77359b849cd5 Tests: stream package.
Andrey Zelenkov <zelenkov@nginx.com>
parents:
diff changeset
3 # (C) Andrey Zelenkov
77359b849cd5 Tests: stream package.
Andrey Zelenkov <zelenkov@nginx.com>
parents:
diff changeset
4 # (C) Nginx, Inc.
77359b849cd5 Tests: stream package.
Andrey Zelenkov <zelenkov@nginx.com>
parents:
diff changeset
5
77359b849cd5 Tests: stream package.
Andrey Zelenkov <zelenkov@nginx.com>
parents:
diff changeset
6 # Module for nginx stream tests.
77359b849cd5 Tests: stream package.
Andrey Zelenkov <zelenkov@nginx.com>
parents:
diff changeset
7
77359b849cd5 Tests: stream package.
Andrey Zelenkov <zelenkov@nginx.com>
parents:
diff changeset
8 ###############################################################################
77359b849cd5 Tests: stream package.
Andrey Zelenkov <zelenkov@nginx.com>
parents:
diff changeset
9
77359b849cd5 Tests: stream package.
Andrey Zelenkov <zelenkov@nginx.com>
parents:
diff changeset
10 use warnings;
77359b849cd5 Tests: stream package.
Andrey Zelenkov <zelenkov@nginx.com>
parents:
diff changeset
11 use strict;
77359b849cd5 Tests: stream package.
Andrey Zelenkov <zelenkov@nginx.com>
parents:
diff changeset
12
77359b849cd5 Tests: stream package.
Andrey Zelenkov <zelenkov@nginx.com>
parents:
diff changeset
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
77359b849cd5 Tests: stream package.
Andrey Zelenkov <zelenkov@nginx.com>
parents:
diff changeset
15
77359b849cd5 Tests: stream package.
Andrey Zelenkov <zelenkov@nginx.com>
parents:
diff changeset
16 use Test::More qw//;
77359b849cd5 Tests: stream package.
Andrey Zelenkov <zelenkov@nginx.com>
parents:
diff changeset
17 use IO::Select;
77359b849cd5 Tests: stream package.
Andrey Zelenkov <zelenkov@nginx.com>
parents:
diff changeset
18 use IO::Socket;
77359b849cd5 Tests: stream package.
Andrey Zelenkov <zelenkov@nginx.com>
parents:
diff changeset
19
77359b849cd5 Tests: stream package.
Andrey Zelenkov <zelenkov@nginx.com>
parents:
diff changeset
20 use Test::Nginx;
77359b849cd5 Tests: stream package.
Andrey Zelenkov <zelenkov@nginx.com>
parents:
diff changeset
21
77359b849cd5 Tests: stream package.
Andrey Zelenkov <zelenkov@nginx.com>
parents:
diff changeset
22 sub stream {
77359b849cd5 Tests: stream package.
Andrey Zelenkov <zelenkov@nginx.com>
parents:
diff changeset
23 return Test::Nginx::Stream->new(@_);
77359b849cd5 Tests: stream package.
Andrey Zelenkov <zelenkov@nginx.com>
parents:
diff changeset
24 }
77359b849cd5 Tests: stream package.
Andrey Zelenkov <zelenkov@nginx.com>
parents:
diff changeset
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
77359b849cd5 Tests: stream package.
Andrey Zelenkov <zelenkov@nginx.com>
parents:
diff changeset
35 sub new {
77359b849cd5 Tests: stream package.
Andrey Zelenkov <zelenkov@nginx.com>
parents:
diff changeset
36 my $self = {};
77359b849cd5 Tests: stream package.
Andrey Zelenkov <zelenkov@nginx.com>
parents:
diff changeset
37 bless $self, shift @_;
77359b849cd5 Tests: stream package.
Andrey Zelenkov <zelenkov@nginx.com>
parents:
diff changeset
38
77359b849cd5 Tests: stream package.
Andrey Zelenkov <zelenkov@nginx.com>
parents:
diff changeset
39 unshift(@_, "PeerAddr") if @_ == 1;
77359b849cd5 Tests: stream package.
Andrey Zelenkov <zelenkov@nginx.com>
parents:
diff changeset
40
77359b849cd5 Tests: stream package.
Andrey Zelenkov <zelenkov@nginx.com>
parents:
diff changeset
41 $self->{_socket} = IO::Socket::INET->new(
77359b849cd5 Tests: stream package.
Andrey Zelenkov <zelenkov@nginx.com>
parents:
diff changeset
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
77359b849cd5 Tests: stream package.
Andrey Zelenkov <zelenkov@nginx.com>
parents:
diff changeset
44 @_
77359b849cd5 Tests: stream package.
Andrey Zelenkov <zelenkov@nginx.com>
parents:
diff changeset
45 )
77359b849cd5 Tests: stream package.
Andrey Zelenkov <zelenkov@nginx.com>
parents:
diff changeset
46 or die "Can't connect to nginx: $!\n";
77359b849cd5 Tests: stream package.
Andrey Zelenkov <zelenkov@nginx.com>
parents:
diff changeset
47
77359b849cd5 Tests: stream package.
Andrey Zelenkov <zelenkov@nginx.com>
parents:
diff changeset
48 if ({@_}->{'SSL'}) {
77359b849cd5 Tests: stream package.
Andrey Zelenkov <zelenkov@nginx.com>
parents:
diff changeset
49 require IO::Socket::SSL;
77359b849cd5 Tests: stream package.
Andrey Zelenkov <zelenkov@nginx.com>
parents:
diff changeset
50 IO::Socket::SSL->start_SSL($self->{_socket}, @_)
77359b849cd5 Tests: stream package.
Andrey Zelenkov <zelenkov@nginx.com>
parents:
diff changeset
51 or die $IO::Socket::SSL::SSL_ERROR . "\n";
77359b849cd5 Tests: stream package.
Andrey Zelenkov <zelenkov@nginx.com>
parents:
diff changeset
52 }
77359b849cd5 Tests: stream package.
Andrey Zelenkov <zelenkov@nginx.com>
parents:
diff changeset
53
77359b849cd5 Tests: stream package.
Andrey Zelenkov <zelenkov@nginx.com>
parents:
diff changeset
54 $self->{_socket}->autoflush(1);
77359b849cd5 Tests: stream package.
Andrey Zelenkov <zelenkov@nginx.com>
parents:
diff changeset
55
77359b849cd5 Tests: stream package.
Andrey Zelenkov <zelenkov@nginx.com>
parents:
diff changeset
56 return $self;
77359b849cd5 Tests: stream package.
Andrey Zelenkov <zelenkov@nginx.com>
parents:
diff changeset
57 }
77359b849cd5 Tests: stream package.
Andrey Zelenkov <zelenkov@nginx.com>
parents:
diff changeset
58
77359b849cd5 Tests: stream package.
Andrey Zelenkov <zelenkov@nginx.com>
parents:
diff changeset
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
77359b849cd5 Tests: stream package.
Andrey Zelenkov <zelenkov@nginx.com>
parents:
diff changeset
61 my $s = $self->{_socket};
77359b849cd5 Tests: stream package.
Andrey Zelenkov <zelenkov@nginx.com>
parents:
diff changeset
62
77359b849cd5 Tests: stream package.
Andrey Zelenkov <zelenkov@nginx.com>
parents:
diff changeset
63 local $SIG{PIPE} = 'IGNORE';
77359b849cd5 Tests: stream package.
Andrey Zelenkov <zelenkov@nginx.com>
parents:
diff changeset
64
77359b849cd5 Tests: stream package.
Andrey Zelenkov <zelenkov@nginx.com>
parents:
diff changeset
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
77359b849cd5 Tests: stream package.
Andrey Zelenkov <zelenkov@nginx.com>
parents:
diff changeset
67 my $n = $s->syswrite($message);
77359b849cd5 Tests: stream package.
Andrey Zelenkov <zelenkov@nginx.com>
parents:
diff changeset
68 log_out(substr($message, 0, $n));
77359b849cd5 Tests: stream package.
Andrey Zelenkov <zelenkov@nginx.com>
parents:
diff changeset
69 last unless $n;
77359b849cd5 Tests: stream package.
Andrey Zelenkov <zelenkov@nginx.com>
parents:
diff changeset
70
77359b849cd5 Tests: stream package.
Andrey Zelenkov <zelenkov@nginx.com>
parents:
diff changeset
71 $message = substr($message, $n);
77359b849cd5 Tests: stream package.
Andrey Zelenkov <zelenkov@nginx.com>
parents:
diff changeset
72 last unless length $message;
77359b849cd5 Tests: stream package.
Andrey Zelenkov <zelenkov@nginx.com>
parents:
diff changeset
73 }
77359b849cd5 Tests: stream package.
Andrey Zelenkov <zelenkov@nginx.com>
parents:
diff changeset
74
77359b849cd5 Tests: stream package.
Andrey Zelenkov <zelenkov@nginx.com>
parents:
diff changeset
75 if (length $message) {
77359b849cd5 Tests: stream package.
Andrey Zelenkov <zelenkov@nginx.com>
parents:
diff changeset
76 $s->close();
77359b849cd5 Tests: stream package.
Andrey Zelenkov <zelenkov@nginx.com>
parents:
diff changeset
77 }
77359b849cd5 Tests: stream package.
Andrey Zelenkov <zelenkov@nginx.com>
parents:
diff changeset
78 }
77359b849cd5 Tests: stream package.
Andrey Zelenkov <zelenkov@nginx.com>
parents:
diff changeset
79
77359b849cd5 Tests: stream package.
Andrey Zelenkov <zelenkov@nginx.com>
parents:
diff changeset
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
77359b849cd5 Tests: stream package.
Andrey Zelenkov <zelenkov@nginx.com>
parents:
diff changeset
82 my ($s, $buf);
77359b849cd5 Tests: stream package.
Andrey Zelenkov <zelenkov@nginx.com>
parents:
diff changeset
83
77359b849cd5 Tests: stream package.
Andrey Zelenkov <zelenkov@nginx.com>
parents:
diff changeset
84 $s = $self->{_socket};
77359b849cd5 Tests: stream package.
Andrey Zelenkov <zelenkov@nginx.com>
parents:
diff changeset
85
77359b849cd5 Tests: stream package.
Andrey Zelenkov <zelenkov@nginx.com>
parents:
diff changeset
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
5d3aee48ed8e Tests: style.
Maxim Dounin <mdounin@mdounin.ru>
parents: 1423
diff changeset
91 }
816
77359b849cd5 Tests: stream package.
Andrey Zelenkov <zelenkov@nginx.com>
parents:
diff changeset
92
77359b849cd5 Tests: stream package.
Andrey Zelenkov <zelenkov@nginx.com>
parents:
diff changeset
93 log_in($buf);
77359b849cd5 Tests: stream package.
Andrey Zelenkov <zelenkov@nginx.com>
parents:
diff changeset
94 return $buf;
77359b849cd5 Tests: stream package.
Andrey Zelenkov <zelenkov@nginx.com>
parents:
diff changeset
95 }
77359b849cd5 Tests: stream package.
Andrey Zelenkov <zelenkov@nginx.com>
parents:
diff changeset
96
77359b849cd5 Tests: stream package.
Andrey Zelenkov <zelenkov@nginx.com>
parents:
diff changeset
97 sub io {
77359b849cd5 Tests: stream package.
Andrey Zelenkov <zelenkov@nginx.com>
parents:
diff changeset
98 my $self = shift;
77359b849cd5 Tests: stream package.
Andrey Zelenkov <zelenkov@nginx.com>
parents:
diff changeset
99
77359b849cd5 Tests: stream package.
Andrey Zelenkov <zelenkov@nginx.com>
parents:
diff changeset
100 my ($data, %extra) = @_;
77359b849cd5 Tests: stream package.
Andrey Zelenkov <zelenkov@nginx.com>
parents:
diff changeset
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
77359b849cd5 Tests: stream package.
Andrey Zelenkov <zelenkov@nginx.com>
parents:
diff changeset
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
77359b849cd5 Tests: stream package.
Andrey Zelenkov <zelenkov@nginx.com>
parents:
diff changeset
108
77359b849cd5 Tests: stream package.
Andrey Zelenkov <zelenkov@nginx.com>
parents:
diff changeset
109 $data = '';
77359b849cd5 Tests: stream package.
Andrey Zelenkov <zelenkov@nginx.com>
parents:
diff changeset
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
77359b849cd5 Tests: stream package.
Andrey Zelenkov <zelenkov@nginx.com>
parents:
diff changeset
115
77359b849cd5 Tests: stream package.
Andrey Zelenkov <zelenkov@nginx.com>
parents:
diff changeset
116 $data .= $buf;
77359b849cd5 Tests: stream package.
Andrey Zelenkov <zelenkov@nginx.com>
parents:
diff changeset
117 last if defined $length && length($data) >= $length;
77359b849cd5 Tests: stream package.
Andrey Zelenkov <zelenkov@nginx.com>
parents:
diff changeset
118 }
77359b849cd5 Tests: stream package.
Andrey Zelenkov <zelenkov@nginx.com>
parents:
diff changeset
119
77359b849cd5 Tests: stream package.
Andrey Zelenkov <zelenkov@nginx.com>
parents:
diff changeset
120 return $data;
77359b849cd5 Tests: stream package.
Andrey Zelenkov <zelenkov@nginx.com>
parents:
diff changeset
121 }
77359b849cd5 Tests: stream package.
Andrey Zelenkov <zelenkov@nginx.com>
parents:
diff changeset
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
77359b849cd5 Tests: stream package.
Andrey Zelenkov <zelenkov@nginx.com>
parents:
diff changeset
133 sub sockport {
77359b849cd5 Tests: stream package.
Andrey Zelenkov <zelenkov@nginx.com>
parents:
diff changeset
134 my $self = shift;
77359b849cd5 Tests: stream package.
Andrey Zelenkov <zelenkov@nginx.com>
parents:
diff changeset
135 return $self->{_socket}->sockport();
77359b849cd5 Tests: stream package.
Andrey Zelenkov <zelenkov@nginx.com>
parents:
diff changeset
136 }
77359b849cd5 Tests: stream package.
Andrey Zelenkov <zelenkov@nginx.com>
parents:
diff changeset
137
77359b849cd5 Tests: stream package.
Andrey Zelenkov <zelenkov@nginx.com>
parents:
diff changeset
138 ###############################################################################
77359b849cd5 Tests: stream package.
Andrey Zelenkov <zelenkov@nginx.com>
parents:
diff changeset
139
77359b849cd5 Tests: stream package.
Andrey Zelenkov <zelenkov@nginx.com>
parents:
diff changeset
140 1;
77359b849cd5 Tests: stream package.
Andrey Zelenkov <zelenkov@nginx.com>
parents:
diff changeset
141
77359b849cd5 Tests: stream package.
Andrey Zelenkov <zelenkov@nginx.com>
parents:
diff changeset
142 ###############################################################################