about summary refs log tree commit
path: root/lib/Net/NNTP.pm
diff options
context:
space:
mode:
Diffstat (limited to 'lib/Net/NNTP.pm')
-rw-r--r--lib/Net/NNTP.pm43
1 files changed, 42 insertions, 1 deletions
diff --git a/lib/Net/NNTP.pm b/lib/Net/NNTP.pm
index 979c58e..81e1319 100644
--- a/lib/Net/NNTP.pm
+++ b/lib/Net/NNTP.pm
@@ -49,8 +49,18 @@ my $inet6_class = eval {
 sub can_ssl   { $ssl_class };
 sub can_inet6 { $inet6_class };
 
-our @ISA = ('Net::Cmd', $inet6_class || 'IO::Socket::INET');
 
+my ($nodeflate_warn, $can_deflate);
+
+sub can_deflate {
+  if (!defined $can_deflate) {
+    $can_deflate = eval { require Net::NNTP::Deflate };
+    $nodeflate_warn = "$@";
+  }
+  $can_deflate;
+}
+
+our @ISA = ('Net::Cmd', $inet6_class || 'IO::Socket::INET');
 
 sub new {
   my $self = shift;
@@ -166,6 +176,13 @@ sub postok {
 sub starttls {
   my $self = shift;
   $ssl_class or die $nossl_warn;
+
+  # RFC 8054 8.3 states:
+  # The STARTTLS and AUTHINFO commands MUST NOT be used in the same
+  # session following a successful execution of the COMPRESS command.
+  my $comp = $self->compression;
+  croak "NNTP STARTTLS must be done before COMPRESS ($comp)" if $comp;
+
   $self->_STARTTLS or return;
   Net::NNTP::_SSL->start_SSL($self,
     %{ ${*$self}{'net_nntp_arg'} }, # (ssl) args given in new
@@ -174,6 +191,22 @@ sub starttls {
   return 1;
 }
 
+# XXX: is it worth documenting this?
+sub compression { undef }
+
+sub compress {
+  my ($self, $alg) = @_;
+  $alg = 'DEFLATE' unless defined($alg);
+
+  my $comp = $self->compression;
+
+  croak("NNTP connection already compressed ($comp)") if $comp;
+  croak("$alg not supported (only 'DEFLATE')") if $alg ne 'DEFLATE';
+  can_deflate() or die $nodeflate_warn;
+
+  $self->_COMPRESS($alg) or return undef;
+  Net::NNTP::Deflate->wrap($self);
+}
 
 sub article {
   @_ >= 1 && @_ <= 3 or croak 'usage: $nntp->article( [ MSGID ], [ FH ] )';
@@ -715,6 +748,7 @@ sub _ARTICLE  { shift->command('ARTICLE',  @_)->response == CMD_OK }
 sub _AUTHINFO { shift->command('AUTHINFO', @_)->response }
 sub _BODY     { shift->command('BODY',     @_)->response == CMD_OK }
 sub _DATE      { shift->command('DATE')->response == CMD_INFO }
+sub _COMPRESS  { shift->command('COMPRESS', @_)->response() == CMD_OK }
 sub _GROUP     { shift->command('GROUP', @_)->response == CMD_OK }
 sub _HEAD      { shift->command('HEAD', @_)->response == CMD_OK }
 sub _HELP      { shift->command('HELP', @_)->response == CMD_INFO }
@@ -880,6 +914,13 @@ to connect to the host.
 Upgrade existing plain connection to SSL.
 Any arguments necessary for SSL must be given in C<new> already.
 
+=item compress ()
+
+Upgrade existing connection to use the DEFLATE algorithm in
+accordance with RFC8054.  Not supported by all servers.
+If using C<starttls>, this must be called AFTER enabling
+TLS, not before.
+
 =item article ( [ MSGID|MSGNUM ], [FH] )
 
 Retrieve the header, a blank line, then the body (text) of the