<html><head><meta name="color-scheme" content="light dark"></head><body><pre style="word-wrap: break-word; white-space: pre-wrap;">#
# $Id: nntp.pm,v 1.10 2005/10/31 15:10:33 gisle Exp $

# Implementation of the Network News Transfer Protocol (RFC 977)
#

package LWP::Protocol::nntp;

require LWP::Protocol;
@ISA = qw(LWP::Protocol);

require LWP::Debug;
require HTTP::Response;
require HTTP::Status;
require Net::NNTP;

use strict;


sub request
{
    my($self, $request, $proxy, $arg, $size, $timeout) = @_;

    LWP::Debug::trace('()');

    $size = 4096 unless $size;

    # Check for proxy
    if (defined $proxy) {
	return HTTP::Response-&gt;new(&amp;HTTP::Status::RC_BAD_REQUEST,
				   'You can not proxy through NNTP');
    }

    # Check that the scheme is as expected
    my $url = $request-&gt;url;
    my $scheme = $url-&gt;scheme;
    unless ($scheme eq 'news' || $scheme eq 'nntp') {
	return HTTP::Response-&gt;new(&amp;HTTP::Status::RC_INTERNAL_SERVER_ERROR,
				   "LWP::Protocol::nntp::request called for '$scheme'");
    }

    # check for a valid method
    my $method = $request-&gt;method;
    unless ($method eq 'GET' || $method eq 'HEAD' || $method eq 'POST') {
	return HTTP::Response-&gt;new(&amp;HTTP::Status::RC_BAD_REQUEST,
				   'Library does not allow method ' .
				   "$method for '$scheme:' URLs");
    }

    # extract the identifier and check against posting to an article
    my $groupart = $url-&gt;_group;
    my $is_art = $groupart =~ /@/;

    if ($is_art &amp;&amp; $method eq 'POST') {
	return HTTP::Response-&gt;new(&amp;HTTP::Status::RC_BAD_REQUEST,
				   "Can't post to an article &lt;$groupart&gt;");
    }

    my $nntp = Net::NNTP-&gt;new($url-&gt;host,
			      #Port    =&gt; 18574,
			      Timeout =&gt; $timeout,
			      #Debug   =&gt; 1,
			     );
    die "Can't connect to nntp server" unless $nntp;

    # Check the initial welcome message from the NNTP server
    if ($nntp-&gt;status != 2) {
	return HTTP::Response-&gt;new(&amp;HTTP::Status::RC_SERVICE_UNAVAILABLE,
				   $nntp-&gt;message);
    }
    my $response = HTTP::Response-&gt;new(&amp;HTTP::Status::RC_OK, "OK");

    my $mess = $nntp-&gt;message;
    LWP::Debug::debug($mess);

    # Try to extract server name from greeting message.
    # Don't know if this works well for a large class of servers, but
    # this works for our server.
    $mess =~ s/\s+ready\b.*//;
    $mess =~ s/^\S+\s+//;
    $response-&gt;header(Server =&gt; $mess);

    # First we handle posting of articles
    if ($method eq 'POST') {
	$nntp-&gt;quit; $nntp = undef;
	$response-&gt;code(&amp;HTTP::Status::RC_NOT_IMPLEMENTED);
	$response-&gt;message("POST not implemented yet");
	return $response;
    }

    # The method must be "GET" or "HEAD" by now
    if (!$is_art) {
	if (!$nntp-&gt;group($groupart)) {
	    $response-&gt;code(&amp;HTTP::Status::RC_NOT_FOUND);
	    $response-&gt;message($nntp-&gt;message);
	}
	$nntp-&gt;quit; $nntp = undef;
	# HEAD: just check if the group exists
	if ($method eq 'GET' &amp;&amp; $response-&gt;is_success) {
	    $response-&gt;code(&amp;HTTP::Status::RC_NOT_IMPLEMENTED);
	    $response-&gt;message("GET newsgroup not implemented yet");
	}
	return $response;
    }

    # Send command to server to retrieve an article (or just the headers)
    my $get = $method eq 'HEAD' ? "head" : "article";
    my $art = $nntp-&gt;$get("&lt;$groupart&gt;");
    unless ($art) {
	$nntp-&gt;quit; $nntp = undef;
	$response-&gt;code(&amp;HTTP::Status::RC_NOT_FOUND);
	$response-&gt;message($nntp-&gt;message);
	return $response;
    }
    LWP::Debug::debug($nntp-&gt;message);

    # Parse headers
    my($key, $val);
    while ($_ = shift @$art) {
	if (/^\s+$/) {
	    last;  # end of headers
	}
	elsif (/^(\S+):\s*(.*)/) {
	    $response-&gt;push_header($key, $val) if $key;
	    ($key, $val) = ($1, $2);
	}
	elsif (/^\s+(.*)/) {
	    next unless $key;
	    $val .= $1;
	}
	else {
	    unshift(@$art, $_);
	    last;
	}
    }
    $response-&gt;push_header($key, $val) if $key;

    # Ensure that there is a Content-Type header
    $response-&gt;header("Content-Type", "text/plain")
	unless $response-&gt;header("Content-Type");

    # Collect the body
    $response = $self-&gt;collect_once($arg, $response, join("", @$art))
      if @$art;

    # Say goodbye to the server
    $nntp-&gt;quit;
    $nntp = undef;

    $response;
}

1;
</pre></body></html>