diff common.php @ 12:7917bd536187 draft

Added hook for new articles, detect send/write failures, fixed handling of multiline headers, add Date header if it doesn't exist, add option to disable peers, fixes for synchronization with INN, added streaming mode support, small fixes
author Ivo Smits <Ivo@UCIS.nl>
date Wed, 12 Jun 2013 22:22:07 +0200
parents e0807e0b1a67
children cccd73f72bf6
line wrap: on
line diff
--- a/common.php	Sat Jun 18 15:59:11 2011 +0200
+++ b/common.php	Wed Jun 12 22:22:07 2013 +0200
@@ -24,6 +24,8 @@
    authors and should not be interpreted as representing official policies, either expressed
    or implied, of Ivo Smits.*/
 
+$pnewss_hooks = array('article_stored' => array());
+
 require_once './pdo.php';
 require_once './config.php';
 
@@ -40,7 +42,12 @@
 }
 function nntp_writeline($socket, $line) {
 	writelog('W: '.$line);
-	fwrite($socket, $line."\r\n");
+	$line .= "\r\n";
+	while (strlen($line)) {
+		$written = fwrite($socket, $line);
+		if ($written === FALSE || $written <= 0) throw new Exception('Write operation failed');
+		$line = substr($line, $written);
+	}
 }
 function nntp_readlines($socket) {
 	$line = nntp_readline($socket);
@@ -54,8 +61,12 @@
 	return $lines;
 }
 
+function pnewss_call_hooks($hooks, $args) {
+	foreach ($hooks as $hook) call_user_func_array($hook, $args);
+}
+
 function nntp_article_store($lines, $header = array()) {
-	global $db;
+	global $db, $pnewss_hooks;
 	$headers = array();
 	if (!count($header)) {
 		while (count($lines)) {
@@ -64,9 +75,15 @@
 			$header[] = $line;
 		}
 	}
+	$headername = NULL;
 	foreach ($header as $headerid => $line) {
 		if (!strlen($line) || $line == '.') throw new Exception('Empty or terminating header line');
 		if (strpos($line, "\r") !== FALSE || strpos($line, "\n") !== FALSE || strpos($line, "\0")) throw new Exception('Invalid newline or NUL character in header line');
+		if (strlen($line) && strlen($headername) && ($line[0] == ' ' || $line[0] == "\t") && isset($headers[$headername])) {
+			$headers[$headername] .= ' '.trim($line, " \t");
+			unset($header[$headerid]);
+			continue;
+		}
 		$parts = explode(': ', $line, 2);
 		$headername = strtoupper($parts[0]);
 		switch ($headername) {
@@ -86,6 +103,7 @@
 				$line = NULL;
 				break;
 			default:
+				if ($headername[0] == 'X' && $headername[1] == '-') break;
 				writelog("Received unknown header $headername");
 		}
 	}
@@ -102,6 +120,7 @@
 	}
 	if (!count($newsgroups)) throw new Exception('No known newsgroups listed');
 	if (!isset($headers['MESSAGE-ID'])) $headers['MESSAGE-ID'] = '<'.md5(time().rand()).'@pNewss.Core.UCIS.nl>';
+	if (!isset($headers['DATE'])) $headers['DATE'] = gmdate('r');
 	$messageid = $headers['MESSAGE-ID'];
 	if (strlen($messageid) < 3 || strlen($messageid) > 250 || $messageid[0] != '<' || strpos($messageid, '>') !== strlen($messageid) - 1) throw new Exception('Bad Message-ID');
 	$messageid = substr($messageid, 1, -1);
@@ -113,5 +132,6 @@
 	}
 	$id = $db->insert('INSERT INTO `messages` (`messageid`, `header`, `body`) VALUES (?, ?, ?)', array($messageid, implode("\r\n", $header), implode("\r\n", $lines)));
 	foreach ($newsgroups as $groupid) $db->insert('INSERT INTO `groupmessages` (`group`, `message`) VALUES (?, ?)', array($groupid, $id));
+	pnewss_call_hooks($pnewss_hooks['article_stored'], array(array('messageid' => $messageid, 'headers' => $headers, 'body' => $lines, 'dbid' => $id)));
 	return $messageid;
 }