-
Notifications
You must be signed in to change notification settings - Fork 581
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Closing TLS connections #1876
Comments
It looks like the problem is that you're cutting off the whole connection when you call This cutting off of the stream is preventing the normal wrap-up of the TLS connection. The HTTP communication is encapsulated in TLS, so that needs to be handled correctly, and that is what Mojo is doing. You can't just |
I don't know. Imagine a client and server, messages flowing back and forth. This is not HTTP but some other protocol. What happens if the server decides that the connection needs to be closed? Here's a client and a server. As long as the server is getting a number, it sends back that number + 1 and the client prints it. But at some point the client sends a non-number and the server does what? My idea is that the server closes the connection. How else would you handle this? use strict;
use Mojo::IOLoop;
# The +1 server
Mojo::IOLoop->server(
{port => 3000, tls => 1} =>
sub {
my ($loop, $stream) = @_;
$stream->on(
read => sub {
my ($stream, $bytes) = @_;
if ($bytes =~ /^(\d+)/) {
$stream->write($1 + 1);
$stream->write("\n");
} else {
warn "The +1 server did not get a number!\n";
$stream->close_gracefully;
}
});
});
my $handle;
Mojo::IOLoop->client(
{port => 3000, tls => 1, tls_options => { SSL_verify_mode => 0x00 }} =>
sub {
my ($loop, $err, $stream) = @_;
$stream->on(
read =>
sub {
my ($stream, $bytes) = @_;
print "$bytes";
$handle = $stream->{handle};
if ($bytes < 10) {
$stream->write($bytes);
} else {
$stream->write("error!");
}
$stream->write("\r\n");
});
$stream->on(
close =>
sub {
my ($stream) = @_;
print "Closed\n";
print $handle . "\n";
my $ssl = ${*$handle}{_SSL_object};
print "$ssl\n";
# Returns the shutdown mode of $ssl.
# to decode the return value (bitmask) use:
# 0 - No shutdown setting, yet
# 1 - SSL_SENT_SHUTDOWN
# 2 - SSL_RECEIVED_SHUTDOWN
# See <http://www.openssl.org/docs/ssl/SSL_set_shutdown.html>
print "Shutdown: " . ((Net::SSLeay::get_shutdown($ssl) & 2) ? "yes" : "no") . "\n";
});
$stream->write("1\r\n");
});
Mojo::IOLoop->timer(3 => sub { Mojo::IOLoop->stop });
Mojo::IOLoop->start unless Mojo::IOLoop->is_running; Output:
|
So instead of |
@gordon-fish Interesting, thank you. When I replace
So I rewrote that little +1 echo server: use strict;
use Mojo::IOLoop;
# The +1 server
Mojo::IOLoop->server(
{port => 3000, tls => 1} =>
sub {
my ($loop, $stream) = @_;
$stream->on(
read => sub {
my ($stream, $bytes) = @_;
if ($bytes =~ /^(\d+)/) {
$stream->write("> ");
$stream->write($1 + 1);
$stream->write("\n");
} else {
warn "The +1 server did not get a number!\n";
$stream->stop;
}
});
});
print("gnutls-cli --insecure 127.0.0.1:3000 and type lines starting with numbers\n");
Mojo::IOLoop->start unless Mojo::IOLoop->is_running; I start it, and it prints the line about using
When I send
But the client doesn't get notified. I can keep typing, except there is no effect. So it seems that something is still amiss. And adding a
|
Steps to reproduce the behavior
Here's a small server using TLS, assuming you have
cert.pem
andkey.pem
in the working directory:Test it using
gnutls-cli
, using--insecure
because it's self-signed:Expected behavior
Actual behavior
Potential fix
I assume the connection is not closed correctly because the server is not sending a close_notify message; IO::Socket::SSL does that if you close it explicitly. We could explicitly close the handle in Mojo::IOLoop::Stream close, as suggested in #1875.
The text was updated successfully, but these errors were encountered: