Re: Net_NNTP patch
| From: | nicos@php.net | Date: | Thu, 02 Jan 2003 14:07:12 +0000 |
| Subject: | Re: Net_NNTP patch | ||
| References: | 1 | Groups: | php.pear.dev |
| Request: | Send a blank email to pear-dev+get-12022@lists.php.net to get a copy of this message | ||
Looks fine to me.
--
Regards.
M.CHAILLAN Nicolas
nicos@php.net
www.WorldAKT.com Hébergement de sites internets.
"Radek Maciaszek" <chief@php.net> a écrit dans le message de news:
3E1444C7.7050305@php.net...
> Hi,
>
> Here is patch for Net_NNTP - added support rfc822 for parse headers in
> splitHeaders() and getOverview() and some other small changes.
> _parseHeaders() and _decodeHeader() i took from PEAR::Mail_mimeDecode.
>
> Cheers,
> Chief
>
----------------------------------------------------------------------------
----
> Index: NNTP.php
> ===================================================================
> RCS file: /repository/pear/Net_NNTP/NNTP.php,v
> retrieving revision 1.13
> diff -u -r1.13 NNTP.php
> --- NNTP.php 25 Jul 2002 04:06:20 -0000 1.13
> +++ NNTP.php 2 Jan 2003 13:50:13 -0000
> @@ -49,6 +49,18 @@
> var $pass = null;
> var $authmode = null;
>
> + /**
> + * Flag to determine whether to decode headers
> + * @var boolean
> + */
> + var $_decode_headers = true;
> +
> + /**
> + * Variable to hold the line end type.
> + * @var string
> + */
> + var $_crlf = "\n";
> +
> /** File pointer of the nntp-connection */
> var $fp = null;
>
> @@ -252,7 +264,7 @@
> */
> function post($subject, $newsgroup, $from, $body, $aditional = "")
> {
> - if (!@is_resource($this->fp)) {
> + if (!$this->isConnected()) {
> return $this->raiseError('Not connected');
> }
>
> @@ -292,15 +304,13 @@
> if (PEAR::isError($r) || $this->responseCode($r) > 299) {
> return $this->raiseError($r);
> }
> -
> $headers = '';
> while(!feof($this->fp)) {
> - $line = trim(fgets($this->fp, 256));
> -
> - if ($line == '.') {
> + $line = fgets($this->fp, 256);
> + if (trim($line) == '.') {
> break;
> } else {
> - $headers .= $line . "\n";
> + $headers .= $line;
> }
> }
> return $headers;
> @@ -333,19 +343,7 @@
> if (PEAR::isError($headers)) {
> return $headers;
> }
> -
> - $lines = explode("\n", $headers);
> - foreach ($lines as $line) {
> - $line = trim($line);
> - if (($pos = strpos($line, ':')) !== false) {
> - $head = substr($line, 0, $pos);
> - $ret[$head] = ltrim(substr($line, $pos+1));
> - // if the field was longer than 256 chars, look also in the
next line
> - // XXX a better way to discover that than strpos?
> - } else {
> - $ret[$head] .= $line;
> - }
> - }
> + $ret = $this->_parseHeaders($headers);
> if (isset($ret['References']) &&
> preg_match_all('|<.+>|U', $ret['References'], $matches))
> {
> @@ -362,6 +360,81 @@
> }
>
> /**
> + * Parse headers given in $input and return
> + * as assoc array.
> + *
> + * @param string Headers to parse
> + * @return array Contains parsed headers
> + * @access private
> + * @author Richard Heyes <richard@phpguru.org>
> + */
> + function _parseHeaders($input)
> + {
> +
> + if ($input !== '') {
> + // Unfold the input
> + $input = preg_replace('/' . $this->_crlf . "(\t| )/",
> ' ',
$input);
> + $headers = explode($this->_crlf, trim($input));
> + foreach ($headers as $value) {
> + $hdr_name = substr($value, 0, $pos = strpos($value,
':'));
> + $hdr_value = substr($value, $pos+1);
> + if($hdr_value[0] == ' ')
> + $hdr_value = substr($hdr_value, 1);
> +
> + $return[$hdr_name] = $this->_decode_headers
> + ? $this->_decodeHeader($hdr_value) : $hdr_value;
> + }
> + } else {
> + $return = array();
> + }
> +
> + return $return;
> + }
> +
> + /**
> + * Given a header, this function will decode it
> + * according to RFC2047. Probably not *exactly*
> + * conformant, but it does pass all the given
> + * examples (in RFC2047).
> + *
> + * @param string Input header value to decode
> + * @return string Decoded header value
> + * @access private
> + * @author Richard Heyes <richard@phpguru.org>
> + */
> + function _decodeHeader($input)
> + {
> + // Remove white space between encoded-words
> + $input = preg_replace('/(=\?[^?]+\?(Q|B)\?[^?]*\?=)( |' . "\t|" .
$this->_crlf . ')+=\?/', '\1=?', $input);
> +
> + // For each encoded-word...
> + while (preg_match('/(=\?([^?]+)\?(Q|B)\?([^?]*)\?=)/', $input,
$matches)) {
> +
> + $encoded = $matches[1];
> + $charset = $matches[2];
> + $encoding = $matches[3];
> + $text = $matches[4];
> +
> + switch ($encoding) {
> + case 'B':
> + $text = base64_decode($text);
> + break;
> +
> + case 'Q':
> + $text = str_replace('_', ' ', $text);
> + preg_match_all('/=([a-f0-9]{2})/i', $text, $matches);
> + foreach($matches[1] as $value)
> + $text = str_replace('='.$value,
chr(hexdec($value)), $text);
> + break;
> + }
> +
> + $input = str_replace($encoded, $text, $input);
> + }
> +
> + return $input;
> + }
> +
> + /**
> * Get the body of an article from the currently open connection.
> * To get the body of an article from another newsgroup, a new
> * prepare_connection()-call has to be made with apropriate
parameters
> @@ -408,7 +481,7 @@
> {
> $body = array();
> while(!feof($this->fp)) {
> - $line = trim(fgets($this->fp, 256));
> + $line = trim(fgets($this->fp, 1024));
> if ($line == '.') {
> break;
> } else {
> @@ -536,7 +609,8 @@
> foreach($this->_getData() as $line) {
> $i=0;
> foreach(explode("\t",$line) as $line) {
> - $message[$format[$i++]] = $line;
> + $message[$format[$i++]] = $this->_decode_headers
> + ? $this->_decodeHeader($line) : $line;
> }
> $messages[$message["Message-ID"]] = $message;
> }
> @@ -546,7 +620,7 @@
> if ($code == 500) {
> return $messages;
> }
> - foreach($this->_getData() as $line) {
> + foreach($this->_getData() as $line) {
> $i=0;
> foreach(explode("\t",$line) as $line) {
> $message[$format[$i++]] = $line;
> @@ -594,7 +668,7 @@
> */
> function max()
> {
> - if (!@is_resource($this->fp)) {
> + if (!$this->isConnected()) {
> return $this->raiseError('Not connected');
> }
> return $this->max;
> @@ -608,7 +682,7 @@
> */
> function min()
> {
> - if (!@is_resource($this->fp)) {
> + if (!$this->isConnected()) {
> return $this->raiseError('Not connected');
> }
> return $this->min;
> @@ -688,7 +762,7 @@
> */
> function command($cmd, $testauth = true)
> {
> - if (!@is_resource($this->fp)) {
> + if (!$this->isConnected()) {
> return $this->raiseError('Not connected');
> }
> fputs($this->fp, "$cmd\r\n");
> @@ -715,4 +789,4 @@
> return $response;
> }
> }
> -?>
> +?>
> \ No newline at end of file
>