Support for ZIP archives
This commit is contained in:
parent
702a4e4f37
commit
3ffb1c1fd6
@ -113,23 +113,26 @@ class Packet extends FTNBase implements \Iterator, \Countable
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Open a packet file
|
* Process a packet file
|
||||||
*
|
*
|
||||||
* @param File $file
|
* @param mixed $f
|
||||||
|
* @param string $name
|
||||||
|
* @param int $size
|
||||||
* @param System|null $system
|
* @param System|null $system
|
||||||
* @param bool $use_cache
|
* @param bool $use_cache
|
||||||
* @return Packet
|
* @return Packet
|
||||||
* @throws InvalidPacketException
|
* @throws InvalidPacketException
|
||||||
*/
|
*/
|
||||||
public static function open(File $file,System $system=NULL,bool $use_cache=TRUE): self
|
|
||||||
{
|
|
||||||
Log::debug(sprintf('%s:+ Opening Packet [%s]',self::LOGKEY,$file));
|
|
||||||
|
|
||||||
$f = fopen($file,'r');
|
public static function process(mixed $f,string $name,int $size,System $system=NULL,bool $use_cache=TRUE): self
|
||||||
$fstat = fstat($f);
|
{
|
||||||
|
Log::debug(sprintf('%s:+ Opening Packet [%s] with size [%d]',self::LOGKEY,$name,$size));
|
||||||
|
|
||||||
|
$read_ptr = 0;
|
||||||
|
|
||||||
// PKT Header
|
// PKT Header
|
||||||
$header = fread($f,self::HEADER_LEN);
|
$header = fread($f,self::HEADER_LEN);
|
||||||
|
$read_ptr += strlen($header);
|
||||||
|
|
||||||
// Could not read header
|
// Could not read header
|
||||||
if (strlen($header) != self::HEADER_LEN)
|
if (strlen($header) != self::HEADER_LEN)
|
||||||
@ -142,10 +145,11 @@ class Packet extends FTNBase implements \Iterator, \Countable
|
|||||||
|
|
||||||
$o = new self;
|
$o = new self;
|
||||||
$o->use_cache = $use_cache;
|
$o->use_cache = $use_cache;
|
||||||
$o->name = (string)$file;
|
$o->name = $name;
|
||||||
$o->header = unpack(self::unpackheader(self::v2header),$header);
|
$o->header = unpack(self::unpackheader(self::v2header),$header);
|
||||||
|
|
||||||
$x = fread($f,2);
|
$x = fread($f,2);
|
||||||
|
$read_ptr += strlen($x);
|
||||||
|
|
||||||
// End of Packet?
|
// End of Packet?
|
||||||
if (strlen($x) == 2 and $x == "\00\00")
|
if (strlen($x) == 2 and $x == "\00\00")
|
||||||
@ -171,6 +175,8 @@ class Packet extends FTNBase implements \Iterator, \Countable
|
|||||||
$last = '';
|
$last = '';
|
||||||
|
|
||||||
while ($buf_ptr || (! feof($f) && ($readbuf=fread($f,self::BLOCKSIZE)))) {
|
while ($buf_ptr || (! feof($f) && ($readbuf=fread($f,self::BLOCKSIZE)))) {
|
||||||
|
$read_ptr += strlen($readbuf);
|
||||||
|
|
||||||
if (strlen($message) < self::PACKED_MSG_HEADER_LEN) {
|
if (strlen($message) < self::PACKED_MSG_HEADER_LEN) {
|
||||||
$addchars = self::PACKED_MSG_HEADER_LEN-strlen($message);
|
$addchars = self::PACKED_MSG_HEADER_LEN-strlen($message);
|
||||||
$message .= substr($readbuf,$buf_ptr,$addchars);
|
$message .= substr($readbuf,$buf_ptr,$addchars);
|
||||||
@ -204,7 +210,7 @@ class Packet extends FTNBase implements \Iterator, \Countable
|
|||||||
// In case our packet break is at the end of the buffer
|
// In case our packet break is at the end of the buffer
|
||||||
$last = substr($readbuf,-2);
|
$last = substr($readbuf,-2);
|
||||||
|
|
||||||
if ((str_contains($last,"\x00")) && ($fstat['size']-ftell($f) > 2)) {
|
if ((str_contains($last,"\x00")) && ($size-$read_ptr > 2)) {
|
||||||
$message .= substr($readbuf,$buf_ptr);
|
$message .= substr($readbuf,$buf_ptr);
|
||||||
$buf_ptr = 0;
|
$buf_ptr = 0;
|
||||||
|
|
||||||
@ -216,7 +222,7 @@ class Packet extends FTNBase implements \Iterator, \Countable
|
|||||||
}
|
}
|
||||||
|
|
||||||
// See if we have found the end of the packet, if not read more.
|
// See if we have found the end of the packet, if not read more.
|
||||||
if ($end === FALSE && (ftell($f) < $fstat['size'])) {
|
if ($end === FALSE && ($read_ptr < $size)) {
|
||||||
$message .= substr($readbuf,$buf_ptr);
|
$message .= substr($readbuf,$buf_ptr);
|
||||||
$buf_ptr = 0;
|
$buf_ptr = 0;
|
||||||
|
|
||||||
|
92
app/Classes/File.php
Normal file
92
app/Classes/File.php
Normal file
@ -0,0 +1,92 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Classes;
|
||||||
|
|
||||||
|
use Illuminate\Http\UploadedFile;
|
||||||
|
use Illuminate\Support\Arr;
|
||||||
|
use Illuminate\Support\Facades\Log;
|
||||||
|
use Symfony\Component\HttpFoundation\File\File as FileBase;
|
||||||
|
|
||||||
|
class File extends FileBase implements \Iterator
|
||||||
|
{
|
||||||
|
private const LOGKEY = 'F--';
|
||||||
|
private int $counter = 0;
|
||||||
|
private bool $isArchive = FALSE;
|
||||||
|
private bool $canHandle = FALSE;
|
||||||
|
private \ZipArchive $z;
|
||||||
|
private array $zipfile = [];
|
||||||
|
|
||||||
|
public function __construct(mixed $path,bool $checkPath=true)
|
||||||
|
{
|
||||||
|
parent::__construct($path,$checkPath);
|
||||||
|
|
||||||
|
switch($x=$this->guessExtension()) {
|
||||||
|
case 'zip':
|
||||||
|
$this->canHandle = TRUE;
|
||||||
|
$this->isArchive = TRUE;
|
||||||
|
$this->z = new \ZipArchive;
|
||||||
|
$this->z->open($this->getRealPath());
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'bin':
|
||||||
|
if ($this->getExtension() == 'pkt' || ($path instanceof UploadedFile && $path->getClientOriginalExtension() == 'pkt')) {
|
||||||
|
$this->canHandle = TRUE;
|
||||||
|
break;
|
||||||
|
};
|
||||||
|
|
||||||
|
default:
|
||||||
|
Log::alert(sprintf('%s:? Unknown file received: %s',self::LOGKEY,$x));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ITERATOR */
|
||||||
|
|
||||||
|
public function current()
|
||||||
|
{
|
||||||
|
if ($this->isArchive) {
|
||||||
|
$this->zipfile = $this->z->statIndex($this->counter,\ZipArchive::FL_UNCHANGED);
|
||||||
|
|
||||||
|
$f = $this->z->getStream($this->zipfile['name']);
|
||||||
|
if (! $f)
|
||||||
|
throw new \Exception(sprintf('%s:Failed getting ZipArchive::stream (%s)',self::LOGKEY,$this->z->getStatusString()));
|
||||||
|
|
||||||
|
return $f;
|
||||||
|
|
||||||
|
} else {
|
||||||
|
return fopen($this->getRealPath(),'r+');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public function next()
|
||||||
|
{
|
||||||
|
$this->counter++;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function key()
|
||||||
|
{
|
||||||
|
return $this->counter;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function valid()
|
||||||
|
{
|
||||||
|
// If we have a pkt file, then counter can only be 1.
|
||||||
|
return $this->canHandle && (($this->isArchive && ($this->counter < $this->z->numFiles)) || $this->counter === 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function rewind()
|
||||||
|
{
|
||||||
|
$this->counter = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* METHODS */
|
||||||
|
|
||||||
|
public function itemName(): string
|
||||||
|
{
|
||||||
|
return ($this->isArchive && $this->valid()) ? Arr::get(stream_get_meta_data($this->current()),'uri') : $this->getFilename();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function itemSize(): int
|
||||||
|
{
|
||||||
|
return $this->isArchive ? Arr::get($this->zipfile,'size') : $this->getSize();
|
||||||
|
}
|
||||||
|
}
|
@ -3,13 +3,13 @@
|
|||||||
namespace App\Classes\File;
|
namespace App\Classes\File;
|
||||||
|
|
||||||
use Exception;
|
use Exception;
|
||||||
|
use Illuminate\Support\Arr;
|
||||||
use Illuminate\Support\Collection;
|
use Illuminate\Support\Collection;
|
||||||
use Illuminate\Support\Facades\Log;
|
use Illuminate\Support\Facades\Log;
|
||||||
use Symfony\Component\HttpFoundation\File\File;
|
|
||||||
use Symfony\Component\HttpFoundation\File\Exception\FileException;
|
use Symfony\Component\HttpFoundation\File\Exception\FileException;
|
||||||
|
|
||||||
use App\Classes\FTN\InvalidPacketException;
|
use App\Classes\File;
|
||||||
use App\Classes\FTN\Packet;
|
use App\Classes\FTN\{InvalidPacketException,Packet};
|
||||||
use App\Jobs\{MessageProcess,TicProcess};
|
use App\Jobs\{MessageProcess,TicProcess};
|
||||||
use App\Models\Address;
|
use App\Models\Address;
|
||||||
|
|
||||||
@ -54,7 +54,7 @@ final class Receive extends Item
|
|||||||
case 'mtime':
|
case 'mtime':
|
||||||
case 'name':
|
case 'name':
|
||||||
case 'size':
|
case 'size':
|
||||||
return $this->receiving ? $this->receiving->{'file_'.$key} : NULL;
|
return $this->receiving?->{'file_'.$key};
|
||||||
|
|
||||||
case 'name_size_time':
|
case 'name_size_time':
|
||||||
return sprintf('%s %lu %lu',$this->name,$this->size,$this->mtime);
|
return sprintf('%s %lu %lu',$this->name,$this->size,$this->mtime);
|
||||||
@ -108,64 +108,67 @@ final class Receive extends Item
|
|||||||
// If we received a packet, we'll dispatch a job to process it
|
// If we received a packet, we'll dispatch a job to process it
|
||||||
if (! $this->receiving->incomplete)
|
if (! $this->receiving->incomplete)
|
||||||
switch ($this->receiving->file_type) {
|
switch ($this->receiving->file_type) {
|
||||||
|
case self::IS_ARC:
|
||||||
case self::IS_PKT:
|
case self::IS_PKT:
|
||||||
Log::info(sprintf('%s: - Processing mail packet [%s]',self::LOGKEY,$this->file));
|
Log::info(sprintf('%s: - Processing mail %s [%s]',self::LOGKEY,$this->receiving->file_type === self::IS_PKT ? 'PACKET' : 'ARCHIVE',$this->file));
|
||||||
|
|
||||||
try {
|
try {
|
||||||
$po = Packet::open(new File($this->file),$this->ao->system);
|
$f = new File($this->file);
|
||||||
|
|
||||||
|
foreach ($f as $packet) {
|
||||||
|
$po = Packet::process($packet,Arr::get(stream_get_meta_data($packet),'uri'),$f->itemSize(),$this->ao->system);
|
||||||
|
|
||||||
|
// Check the messages are from the uplink
|
||||||
|
if ($this->ao->system->addresses->search(function($item) use ($po) { return $item->id == $po->fftn_o->id; }) === FALSE) {
|
||||||
|
Log::error(sprintf('%s: ! Packet [%s] is not from this link? [%d]',self::LOGKEY,$po->fftn_o->ftn,$this->ao->system_id));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check the packet password
|
||||||
|
if ($this->ao->session('pktpass') != $po->password) {
|
||||||
|
Log::error(sprintf('%s: ! Packet from [%s] with password [%s] is invalid.',self::LOGKEY,$this->ao->ftn,$po->password));
|
||||||
|
// @todo Generate message to system advising invalid password - that message should be sent without a packet password!
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
Log::info(sprintf('%s: - Packet has [%d] messages',self::LOGKEY,$po->count()));
|
||||||
|
|
||||||
|
// Queue messages if there are too many in the packet.
|
||||||
|
if ($queue = ($po->count() > config('app.queue_msgs')))
|
||||||
|
Log::info(sprintf('%s: - Messages will be sent to the queue for processing',self::LOGKEY));
|
||||||
|
|
||||||
|
$error = FALSE;
|
||||||
|
foreach ($po as $msg) {
|
||||||
|
Log::info(sprintf('%s: - Mail from [%s] to [%s]',self::LOGKEY,$msg->fftn,$msg->tftn));
|
||||||
|
|
||||||
|
// @todo Quick check that the packet should be processed by us.
|
||||||
|
// @todo validate that the packet's zone is in the domain.
|
||||||
|
|
||||||
|
try {
|
||||||
|
// Dispatch job.
|
||||||
|
if ($queue)
|
||||||
|
MessageProcess::dispatch($msg);
|
||||||
|
else
|
||||||
|
MessageProcess::dispatchSync($msg);
|
||||||
|
|
||||||
|
} catch (Exception $e) {
|
||||||
|
Log::error(sprintf('%s:! Got error dispatching message [%s] (%d:%s-%s).',self::LOGKEY,$msg->msgid,$e->getLine(),$e->getFile(),$e->getMessage()));
|
||||||
|
$error = TRUE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($po->errors->count() || $error) {
|
||||||
|
Log::info(sprintf('%s: - Not deleting packet [%s], as it has validation errors',self::LOGKEY,$this->file));
|
||||||
|
|
||||||
|
// If we want to keep the packet, we could do that logic here
|
||||||
|
} elseif (! config('app.packet_keep')) {
|
||||||
|
Log::debug(sprintf('%s: - Deleting processed packet [%s]',self::LOGKEY,$this->file));
|
||||||
|
unlink($this->file);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
} catch (InvalidPacketException $e) {
|
} catch (InvalidPacketException $e) {
|
||||||
Log::error(sprintf('%s: - Not deleting packet [%s], as it generated an exception',self::LOGKEY,$this->file));
|
Log::error(sprintf('%s: - Not deleting packet [%s], as it generated an exception',self::LOGKEY,$this->file));
|
||||||
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check the messages are from the uplink
|
|
||||||
if ($this->ao->system->addresses->search(function($item) use ($po) { return $item->id == $po->fftn_o->id; }) === FALSE) {
|
|
||||||
Log::error(sprintf('%s: ! Packet [%s] is not from this link? [%d]',self::LOGKEY,$po->fftn_o->ftn,$this->ao->system_id));
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check the packet password
|
|
||||||
if ($this->ao->session('pktpass') != $po->password) {
|
|
||||||
Log::error(sprintf('%s: ! Packet from [%s] with password [%s] is invalid.',self::LOGKEY,$this->ao->ftn,$po->password));
|
|
||||||
// @todo Generate message to system advising invalid password - that message should be sent without a packet password!
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
Log::info(sprintf('%s: - Packet has [%d] messages',self::LOGKEY,$po->count()));
|
|
||||||
|
|
||||||
// Queue messages if there are too many in the packet.
|
|
||||||
if ($queue = ($po->count() > config('app.queue_msgs')))
|
|
||||||
Log::info(sprintf('%s: - Messages will be sent to the queue for processing',self::LOGKEY));
|
|
||||||
|
|
||||||
$error = FALSE;
|
|
||||||
foreach ($po as $msg) {
|
|
||||||
Log::info(sprintf('%s: - Mail from [%s] to [%s]',self::LOGKEY,$msg->fftn,$msg->tftn));
|
|
||||||
|
|
||||||
// @todo Quick check that the packet should be processed by us.
|
|
||||||
// @todo validate that the packet's zone is in the domain.
|
|
||||||
|
|
||||||
try {
|
|
||||||
// Dispatch job.
|
|
||||||
if ($queue)
|
|
||||||
MessageProcess::dispatch($msg);
|
|
||||||
else
|
|
||||||
MessageProcess::dispatchSync($msg);
|
|
||||||
|
|
||||||
} catch (Exception $e) {
|
|
||||||
Log::error(sprintf('%s:! Got error dispatching message [%s] (%d:%s-%s).',self::LOGKEY,$msg->msgid,$e->getLine(),$e->getFile(),$e->getMessage()));
|
|
||||||
$error = TRUE;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($po->errors->count() || $error) {
|
|
||||||
Log::info(sprintf('%s: - Not deleting packet [%s], as it has validation errors',self::LOGKEY,$this->file));
|
|
||||||
|
|
||||||
// If we want to keep the packet, we could do that logic here
|
|
||||||
} elseif (! config('app.packet_keep')) {
|
|
||||||
Log::debug(sprintf('%s: - Deleting processed packet [%s]',self::LOGKEY,$this->file));
|
|
||||||
unlink($this->file);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
@ -3,8 +3,9 @@
|
|||||||
namespace App\Console\Commands;
|
namespace App\Console\Commands;
|
||||||
|
|
||||||
use Illuminate\Console\Command;
|
use Illuminate\Console\Command;
|
||||||
use Symfony\Component\HttpFoundation\File\File;
|
use Illuminate\Support\Arr;
|
||||||
|
|
||||||
|
use App\Classes\File;
|
||||||
use App\Classes\FTN\Packet;
|
use App\Classes\FTN\Packet;
|
||||||
use App\Models\System;
|
use App\Models\System;
|
||||||
|
|
||||||
@ -16,7 +17,7 @@ class PacketInfo extends Command
|
|||||||
* @var string
|
* @var string
|
||||||
*/
|
*/
|
||||||
protected $signature = 'packet:info'
|
protected $signature = 'packet:info'
|
||||||
.' {pkt : Packet to process}'
|
.' {file : Packet to process}'
|
||||||
.' {system? : Zone the packet is from}';
|
.' {system? : Zone the packet is from}';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -34,42 +35,48 @@ class PacketInfo extends Command
|
|||||||
*/
|
*/
|
||||||
public function handle()
|
public function handle()
|
||||||
{
|
{
|
||||||
$f = new File($this->argument('pkt'));
|
$f = new File($this->argument('file'));
|
||||||
$s = $this->argument('system') ? System::where('name',$this->argument('zone'))->singleOrFail() : NULL;
|
$s = $this->argument('system') ? System::where('name',$this->argument('zone'))->singleOrFail() : NULL;
|
||||||
|
|
||||||
$pkt = Packet::open($f,$s);
|
foreach ($f as $packet) {
|
||||||
|
$pkt = Packet::process($packet,$x=$f->itemName(),$f->itemSize(),$s);
|
||||||
|
|
||||||
$this->info(sprintf('Packet Type: %s',$pkt->type));
|
$this->alert(sprintf('File Name: %s',$x));
|
||||||
$this->info(sprintf('From: %s to %s',$pkt->fftn,$pkt->tftn));
|
|
||||||
$this->info(sprintf('Dated: %s',$pkt->date));
|
|
||||||
$this->info(sprintf('Password: %s (%s)',$pkt->password,$pkt->password ? 'SET' : 'NOT set'));
|
|
||||||
$this->info(sprintf('Messages: %d',$pkt->messages->count()));
|
|
||||||
$this->info(sprintf('Tosser %d (%s) version %s',$pkt->software->code,$pkt->software->name,$pkt->software_ver));
|
|
||||||
$this->info(sprintf('Capabilities: %x',$pkt->capability));
|
|
||||||
$this->info(sprintf('Has Errors: %s',$pkt->errors->count() ? 'YES' : 'No'));
|
|
||||||
$this->info(sprintf('Messages: %d',$pkt->count()));
|
|
||||||
|
|
||||||
foreach ($pkt as $msg) {
|
$this->info(sprintf('Packet Type: %s',$pkt->type));
|
||||||
$this->warn(sprintf('- Date: %s',$msg->date));
|
$this->info(sprintf('From: %s to %s',$pkt->fftn,$pkt->tftn));
|
||||||
$this->warn(sprintf(' - FLAGS: %s',$msg->flags()->filter()->keys()->join(', ')));
|
$this->info(sprintf('Dated: %s',$pkt->date));
|
||||||
$this->warn(sprintf(' - From: %s (%s)',$msg->user_from,$msg->fftn));
|
$this->info(sprintf('Password: %s (%s)',$pkt->password,$pkt->password ? 'SET' : 'NOT set'));
|
||||||
$this->warn(sprintf(' - To: %s (%s)',$msg->user_to,$msg->tftn));
|
$this->info(sprintf('Messages: %d',$pkt->messages->count()));
|
||||||
$this->warn(sprintf(' - Subject: %s',$msg->subject));
|
$this->info(sprintf('Tosser %d (%s) version %s',$pkt->software->code,$pkt->software->name,$pkt->software_ver));
|
||||||
|
$this->info(sprintf('Capabilities: %x',$pkt->capability));
|
||||||
|
$this->info(sprintf('Has Errors: %s',$pkt->errors->count() ? 'YES' : 'No'));
|
||||||
|
$this->info(sprintf('Messages: %d',$pkt->count()));
|
||||||
|
|
||||||
|
foreach ($pkt as $msg) {
|
||||||
|
$this->warn(sprintf('- Date: %s',$msg->date));
|
||||||
|
$this->warn(sprintf(' - FLAGS: %s',$msg->flags()->filter()->keys()->join(', ')));
|
||||||
|
$this->warn(sprintf(' - From: %s (%s)',$msg->user_from,$msg->fftn));
|
||||||
|
$this->warn(sprintf(' - To: %s (%s)',$msg->user_to,$msg->tftn));
|
||||||
|
$this->warn(sprintf(' - Subject: %s',$msg->subject));
|
||||||
|
|
||||||
|
if ($msg->errors)
|
||||||
|
foreach ($msg->errors->errors()->all() as $error)
|
||||||
|
$this->line(' - '.$error);
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach ($pkt->errors as $msg) {
|
||||||
|
$this->error(sprintf('- Date: %s',$msg->date));
|
||||||
|
$this->error(sprintf(' - FLAGS: %s',$msg->flags()->filter()->keys()->join(', ')));
|
||||||
|
$this->error(sprintf(' - From: %s (%s)',$msg->user_from,$msg->fftn));
|
||||||
|
$this->error(sprintf(' - To: %s (%s)',$msg->user_to,$msg->tftn));
|
||||||
|
$this->error(sprintf(' - Subject: %s',$msg->subject));
|
||||||
|
|
||||||
if ($msg->errors)
|
|
||||||
foreach ($msg->errors->errors()->all() as $error)
|
foreach ($msg->errors->errors()->all() as $error)
|
||||||
$this->line(' - '.$error);
|
$this->line(' - '.$error);
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach ($pkt->errors as $msg) {
|
$this->line("\n");
|
||||||
$this->error(sprintf('- Date: %s',$msg->date));
|
|
||||||
$this->error(sprintf(' - FLAGS: %s',$msg->flags()->filter()->keys()->join(', ')));
|
|
||||||
$this->error(sprintf(' - From: %s (%s)',$msg->user_from,$msg->fftn));
|
|
||||||
$this->error(sprintf(' - To: %s (%s)',$msg->user_to,$msg->tftn));
|
|
||||||
$this->error(sprintf(' - Subject: %s',$msg->subject));
|
|
||||||
|
|
||||||
foreach ($msg->errors->errors()->all() as $error)
|
|
||||||
$this->line(' - '.$error);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3,8 +3,9 @@
|
|||||||
namespace App\Console\Commands;
|
namespace App\Console\Commands;
|
||||||
|
|
||||||
use Illuminate\Console\Command;
|
use Illuminate\Console\Command;
|
||||||
use Symfony\Component\HttpFoundation\File\File;
|
use Illuminate\Support\Arr;
|
||||||
|
|
||||||
|
use App\Classes\File;
|
||||||
use App\Classes\FTN\Packet;
|
use App\Classes\FTN\Packet;
|
||||||
use App\Jobs\MessageProcess as Job;
|
use App\Jobs\MessageProcess as Job;
|
||||||
use App\Models\Address;
|
use App\Models\Address;
|
||||||
@ -17,7 +18,7 @@ class PacketProcess extends Command
|
|||||||
* @var string
|
* @var string
|
||||||
*/
|
*/
|
||||||
protected $signature = 'packet:process'
|
protected $signature = 'packet:process'
|
||||||
.' {pkt : Packet to process}'
|
.' {file : Packet to process}'
|
||||||
.' {--N|nobot : Dont process bots}'
|
.' {--N|nobot : Dont process bots}'
|
||||||
.' {ftn? : System the packet is from}';
|
.' {ftn? : System the packet is from}';
|
||||||
|
|
||||||
@ -36,17 +37,19 @@ class PacketProcess extends Command
|
|||||||
*/
|
*/
|
||||||
public function handle()
|
public function handle()
|
||||||
{
|
{
|
||||||
$f = new File($this->argument('pkt'));
|
$f = new File($this->argument('file'));
|
||||||
$s = $this->argument('ftn') ? Address::findFTN($this->argument('ftn'))->system : NULL;
|
$s = $this->argument('ftn') ? Address::findFTN($this->argument('ftn'))->system : NULL;
|
||||||
|
|
||||||
foreach (Packet::open($f,$s) as $msg) {
|
foreach ($f as $packet) {
|
||||||
// @todo Quick check that the packet should be processed by us.
|
foreach (Packet::process($packet,$f->itemName(),$f->itemSize(),$s) as $msg) {
|
||||||
// @todo validate that the packet's zone is in the domain.
|
// @todo Quick check that the packet should be processed by us.
|
||||||
|
// @todo validate that the packet's zone is in the domain.
|
||||||
|
|
||||||
$this->info(sprintf('Processing message from [%s] with msgid [%s]',$msg->fboss,$msg->msgid));
|
$this->info(sprintf('Processing message from [%s] with msgid [%s]',$msg->fboss,$msg->msgid));
|
||||||
|
|
||||||
// Dispatch job.
|
// Dispatch job.
|
||||||
Job::dispatchSync($msg,$this->option('nobot'));
|
Job::dispatchSync($msg,$this->option('nobot'));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -8,6 +8,7 @@ use Illuminate\Support\Facades\Auth;
|
|||||||
use Illuminate\Support\Facades\DB;
|
use Illuminate\Support\Facades\DB;
|
||||||
use Illuminate\Support\Facades\Gate;
|
use Illuminate\Support\Facades\Gate;
|
||||||
|
|
||||||
|
use App\Classes\File;
|
||||||
use App\Classes\FTN\Packet;
|
use App\Classes\FTN\Packet;
|
||||||
use App\Models\{Address,Domain,Echomail,Setup};
|
use App\Models\{Address,Domain,Echomail,Setup};
|
||||||
|
|
||||||
@ -46,8 +47,9 @@ class HomeController extends Controller
|
|||||||
*/
|
*/
|
||||||
public function pkt(Request $request)
|
public function pkt(Request $request)
|
||||||
{
|
{
|
||||||
$pkt = NULL;
|
$pkt = collect();
|
||||||
$file = NULL;
|
$file = NULL;
|
||||||
|
$f = NULL;
|
||||||
|
|
||||||
if ($request->post()) {
|
if ($request->post()) {
|
||||||
$request->validate([
|
$request->validate([
|
||||||
@ -57,10 +59,12 @@ class HomeController extends Controller
|
|||||||
foreach ($request->allFiles() as $key => $filegroup) {
|
foreach ($request->allFiles() as $key => $filegroup) {
|
||||||
if ($key !== 'file')
|
if ($key !== 'file')
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
foreach ($filegroup as $file) {
|
foreach ($filegroup as $file) {
|
||||||
try {
|
try {
|
||||||
$pkt = Packet::open($file);
|
$f = new File($file);
|
||||||
|
|
||||||
|
foreach ($f as $packet)
|
||||||
|
$pkt->push([$f->itemName()=>Packet::process($packet,$f->itemName(),$f->itemSize())]);
|
||||||
|
|
||||||
} catch (\Exception $e) {
|
} catch (\Exception $e) {
|
||||||
return redirect()->back()->withErrors(sprintf('%s (%s:%d)',$e->getMessage(),$e->getFile(),$e->getLine()));
|
return redirect()->back()->withErrors(sprintf('%s (%s:%d)',$e->getMessage(),$e->getFile(),$e->getLine()));
|
||||||
@ -72,8 +76,9 @@ class HomeController extends Controller
|
|||||||
}
|
}
|
||||||
|
|
||||||
return view('pkt')
|
return view('pkt')
|
||||||
->with('file',$file)
|
->with('file',$f)
|
||||||
->with('result',$pkt)
|
->with('filename',$f ? $file->getClientOriginalName() : NULL)
|
||||||
|
->with('results',$pkt)
|
||||||
->with('hexdump',$file ? hex_dump(file_get_contents($file)) : '');
|
->with('hexdump',$file ? hex_dump(file_get_contents($file)) : '');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -36,6 +36,7 @@ trait Import
|
|||||||
return $c;
|
return $c;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// @todo Consider merging this with File::openZipFile
|
||||||
private function openFile(string $file,&$f): \ZipArchive
|
private function openFile(string $file,&$f): \ZipArchive
|
||||||
{
|
{
|
||||||
$z = new \ZipArchive;
|
$z = new \ZipArchive;
|
||||||
|
@ -53,109 +53,126 @@
|
|||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
|
|
||||||
@if($result)
|
@if($results->count())
|
||||||
<h3>Packet Results</h3>
|
<h2>Archive Results: <strong class="highlight">{{ $filename }}</strong></h2>
|
||||||
<p>Packet <strong class="highlight">{{ $file->getClientOriginalName() }}</strong> (type <strong class="highlight">{{ $result->type }}</strong>) is from <strong class="highlight">{{ $result->fftn }}</strong> to <strong class="highlight">{{ $result->tftn }}</strong>, dated <strong class="highlight">{{ $result->date }}</strong>.</p>
|
|
||||||
<p>This packet has <strong class="highlight">{{ $result->messages->count() }}</strong> messages and <strong class="highlight">{{ $result->password ? 'DOES' : 'does NOT' }}</strong> have a password.</p>
|
|
||||||
<p>Tosser: <strong class="highlight">{{ $result->software->code }}</strong> (<strong class="highlight">{{ $result->software->name }}</strong>), version <strong class="highlight">{{ $result->software_ver }}</strong>. Capabilities: <strong class="highlight">{{ $result->capability }}</strong>.</p>
|
|
||||||
@if ($result->messages->count() > 1)
|
|
||||||
<p><small>You can expand each one</small></p>
|
|
||||||
@endif
|
|
||||||
<hr>
|
|
||||||
<div class="accordion accordion-flush" id="accordion_packetdebug">
|
|
||||||
@foreach ($result as $msg)
|
|
||||||
<div class="row">
|
|
||||||
<div class="col-12">
|
|
||||||
<h4 class="accordion-header" id="packetdebug" data-bs-toggle="collapse" data-bs-target="#collapse_msg_{{ $loop->index }}" aria-expanded="false" aria-controls="collapse_addresses">
|
|
||||||
@if($msg->isNetmail()) Netmail @else Echomail <strong>{{ $msg->echoarea }}</strong> @endif : {{ $msg->msgid }}
|
|
||||||
</h4>
|
|
||||||
|
|
||||||
<div id="collapse_msg_{{ $loop->index }}" class="accordion-collapse collapse @if($result->messages->count() == 1 && $loop->first)show @endif" aria-labelledby="packetdebug" data-bs-parent="#accordion_packetdebug">
|
<div class="accordion accordion-flush" id="accordion_packet">
|
||||||
|
@foreach($results as $item)
|
||||||
|
@foreach ($item as $file => $result)
|
||||||
|
<h3 class="accordion-header" data-bs-toggle="collapse" data-bs-target="#collapse_item_{{ $loop->parent->index }}_{{ $loop->index }}" aria-expanded="false">Packet Results <strong class="highlight">{{ $file }}</strong></h3>
|
||||||
|
<div id="collapse_item_{{ $loop->parent->index }}_{{ $loop->index }}" class="accordion-collapse collapse @if($result->messages->count() == 1 && $loop->parent->first)show @endif" aria-labelledby="packetdebug" data-bs-parent="#accordion_packet">
|
||||||
<div class="accordion-body">
|
<div class="accordion-body">
|
||||||
@if ($msg->errors)
|
<p>Packet <strong class="highlight">{{ $file }}</strong> (type <strong class="highlight">{{ $result->type }}</strong>) is from <strong class="highlight">{{ $result->fftn }}</strong> to <strong class="highlight">{{ $result->tftn }}</strong>, dated <strong class="highlight">{{ $result->date }}</strong>.</p>
|
||||||
@foreach ($msg->errors->messages()->all() as $error)
|
<p>This packet has <strong class="highlight">{{ $result->messages->count() }}</strong> messages and <strong class="highlight">{{ $result->password ? 'DOES' : 'does NOT' }}</strong> have a password.</p>
|
||||||
<div class="alert alert-danger">
|
<p>Tosser: <strong class="highlight">{{ $result->software->code }}</strong> (<strong class="highlight">{{ $result->software->name }}</strong>), version <strong class="highlight">{{ $result->software_ver }}</strong>. Capabilities: <strong class="highlight">{{ $result->capability }}</strong>.</p>
|
||||||
{{ $error }}
|
@if ($result->messages->count() > 1)
|
||||||
|
<p><small>You can expand each one</small></p>
|
||||||
|
@endif
|
||||||
|
<hr>
|
||||||
|
<div class="accordion accordion-flush" id="accordion_file_{{ $loop->parent->index }}">
|
||||||
|
@foreach ($result as $msg)
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-12">
|
||||||
|
<h4 class="accordion-header" id="packetdebug" data-bs-toggle="collapse" data-bs-target="#collapse_msg_{{ $loop->parent->index }}_{{ $loop->index }}" aria-expanded="false">
|
||||||
|
@if($msg->isNetmail()) Netmail @else Echomail <strong>{{ $msg->echoarea }}</strong> @endif : {{ $msg->msgid }}
|
||||||
|
</h4>
|
||||||
|
|
||||||
|
<div id="collapse_msg_{{ $loop->parent->index }}_{{ $loop->index }}" class="accordion-collapse collapse @if($result->messages->count() == 1 && $loop->parent->first)show @endif" aria-labelledby="packetdebug" data-bs-parent="#accordion_file_{{ $loop->parent->parent->index }}">
|
||||||
|
<div class="accordion-body">
|
||||||
|
@if ($msg->errors)
|
||||||
|
@foreach ($msg->errors->messages()->all() as $error)
|
||||||
|
<div class="alert alert-danger">
|
||||||
|
{{ $error }}
|
||||||
|
</div>
|
||||||
|
@endforeach
|
||||||
|
@endif
|
||||||
|
|
||||||
|
<div class="row pb-2">
|
||||||
|
<div class="col-4">
|
||||||
|
DATE: <strong class="highlight">{{ $msg->date }}</strong>
|
||||||
|
</div>
|
||||||
|
<div class="col-4">
|
||||||
|
FLAGS: <strong class="highlight">{{ $msg->flags()->filter()->keys()->join(', ') }}</strong>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="row pb-2">
|
||||||
|
<div class="col-4">
|
||||||
|
FROM: <strong class="highlight">{!! \App\Classes\FTN\Message::tr($msg->user_from) !!}</strong> (<strong class="highlight">{{ $msg->fftn }}</strong>)
|
||||||
|
</div>
|
||||||
|
<div class="col-4">
|
||||||
|
TO: <strong class="highlight">{!! \App\Classes\FTN\Message::tr($msg->user_to) !!}</strong>@if($msg->isNetmail()) (<strong class="highlight">{{ $msg->tftn }}</strong>) @endif
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="row pb-2">
|
||||||
|
<div class="col-8">
|
||||||
|
SUBJECT: <strong class="highlight">{!! \App\Classes\FTN\Message::tr($msg->subject) !!}</strong>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="row pb-2">
|
||||||
|
<div class="col-8">
|
||||||
|
<div class="pad pb-0">
|
||||||
|
<pre class="highlight">{!! \App\Classes\FTN\Message::tr($msg->message).sprintf("\r * Origin: %s",$msg->origin) !!}</pre>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
@if($msg->isNetmail())
|
||||||
|
<div class="row pb-2">
|
||||||
|
<div class="col-8">
|
||||||
|
VIA: <br><strong class="highlight">{!! $msg->via->join('</strong><br><strong class="highlight">') !!}</strong>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
@else
|
||||||
|
<div class="row pb-2">
|
||||||
|
<div class="col-8">
|
||||||
|
SEENBY: <br><strong class="highlight">{!! $msg->seenby->join('</strong><br><strong class="highlight">') !!}</strong>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="row pb-2">
|
||||||
|
<div class="col-8">
|
||||||
|
PATH: <br><strong class="highlight">{!! $msg->path->join('</strong><br><strong class="highlight">') !!}</strong>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
@endif
|
||||||
|
|
||||||
|
<div class="row pb-2">
|
||||||
|
<div class="col-8">
|
||||||
|
<strong>KLUDGES:</strong> <br>
|
||||||
|
@foreach ($msg->kludge->sort(function($v,$k) { return $k; })->reverse() as $k => $v)
|
||||||
|
<strong class="highlight">{{ $k }}</strong> {{ $v }}<br>
|
||||||
|
@endforeach
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-12">
|
||||||
|
|
||||||
|
<h4 class="accordion-header" id="packetdebug_{{ $loop->parent->parent->index }}" data-bs-toggle="collapse" data-bs-target="#collapse_hex_{{ $loop->parent->parent->index }}" aria-expanded="false">
|
||||||
|
Packet Dump
|
||||||
|
</h4>
|
||||||
|
<div id="collapse_hex_{{ $loop->parent->parent->index }}" class="accordion-collapse collapse" aria-labelledby="packetdebug_{{ $loop->parent->parent->index }}" data-bs-parent="#accordion_file_{{ $loop->parent->parent->index }}">
|
||||||
|
<div class="accordion-body">
|
||||||
|
<pre>
|
||||||
|
{{ hex_dump($msg) }}
|
||||||
|
</pre>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@endforeach
|
@endforeach
|
||||||
@endif
|
|
||||||
|
|
||||||
<div class="row pb-2">
|
|
||||||
<div class="col-4">
|
|
||||||
DATE: <strong class="highlight">{{ $msg->date }}</strong>
|
|
||||||
</div>
|
|
||||||
<div class="col-4">
|
|
||||||
FLAGS: <strong class="highlight">{{ $msg->flags()->filter()->keys()->join(', ') }}</strong>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="row pb-2">
|
|
||||||
<div class="col-4">
|
|
||||||
FROM: <strong class="highlight">{!! \App\Classes\FTN\Message::tr($msg->user_from) !!}</strong> (<strong class="highlight">{{ $msg->fftn }}</strong>)
|
|
||||||
</div>
|
|
||||||
<div class="col-4">
|
|
||||||
TO: <strong class="highlight">{!! \App\Classes\FTN\Message::tr($msg->user_to) !!}</strong>@if($msg->isNetmail()) (<strong class="highlight">{{ $msg->tftn }}</strong>) @endif
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="row pb-2">
|
|
||||||
<div class="col-8">
|
|
||||||
SUBJECT: <strong class="highlight">{!! \App\Classes\FTN\Message::tr($msg->subject) !!}</strong>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="row pb-2">
|
|
||||||
<div class="col-8">
|
|
||||||
<div class="pad pb-0">
|
|
||||||
<pre class="highlight">{!! \App\Classes\FTN\Message::tr($msg->message).sprintf("\r * Origin: %s",$msg->origin) !!}</pre>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
@if($msg->isNetmail())
|
|
||||||
<div class="row pb-2">
|
|
||||||
<div class="col-8">
|
|
||||||
VIA: <br><strong class="highlight">{!! $msg->via->join('</strong><br><strong class="highlight">') !!}</strong>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
@else
|
|
||||||
<div class="row pb-2">
|
|
||||||
<div class="col-8">
|
|
||||||
SEENBY: <br><strong class="highlight">{!! $msg->seenby->join('</strong><br><strong class="highlight">') !!}</strong>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="row pb-2">
|
|
||||||
<div class="col-8">
|
|
||||||
PATH: <br><strong class="highlight">{!! $msg->path->join('</strong><br><strong class="highlight">') !!}</strong>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
@endif
|
|
||||||
|
|
||||||
<div class="row pb-2">
|
|
||||||
<div class="col-8">
|
|
||||||
<strong>KLUDGES:</strong> <br>
|
|
||||||
@foreach ($msg->kludge->sort(function($v,$k) { return $k; })->reverse() as $k => $v)
|
|
||||||
<strong class="highlight">{{ $k }}</strong> {{ $v }}<br>
|
|
||||||
@endforeach
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
@endforeach
|
||||||
</div>
|
@endforeach
|
||||||
@endforeach
|
|
||||||
|
|
||||||
<h4 class="accordion-header" id="packetdebug" data-bs-toggle="collapse" data-bs-target="#collapse_hex" aria-expanded="false" aria-controls="collapse_hex">
|
|
||||||
Packet Dump
|
|
||||||
</h4>
|
|
||||||
<div id="collapse_hex" class="accordion-collapse collapse" aria-labelledby="packetdebug" data-bs-parent="#accordion_packetdebug">
|
|
||||||
<div class="accordion-body">
|
|
||||||
<pre>
|
|
||||||
{{ $hexdump }}
|
|
||||||
</pre>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
@endif
|
@endif
|
||||||
@endsection
|
@endsection
|
@ -2,9 +2,9 @@
|
|||||||
|
|
||||||
namespace Tests\Feature;
|
namespace Tests\Feature;
|
||||||
|
|
||||||
use Symfony\Component\HttpFoundation\File\File;
|
|
||||||
use Tests\TestCase;
|
use Tests\TestCase;
|
||||||
|
|
||||||
|
use App\Classes\File;
|
||||||
use App\Classes\FTN\Packet;
|
use App\Classes\FTN\Packet;
|
||||||
use App\Models\{Address,Domain,System,Zone};
|
use App\Models\{Address,Domain,System,Zone};
|
||||||
|
|
||||||
@ -34,26 +34,28 @@ class PacketTest extends TestCase
|
|||||||
|
|
||||||
// This packet has an incorrect zone in the Origin
|
// This packet has an incorrect zone in the Origin
|
||||||
$f = new File(__DIR__.'/data/test_nomsgid_origin.pkt');
|
$f = new File(__DIR__.'/data/test_nomsgid_origin.pkt');
|
||||||
$pkt = Packet::open($f,NULL,FALSE);
|
foreach ($f as $packet) {
|
||||||
|
$pkt = Packet::process($packet,$f->itemName(),$f->itemSize(),NULL,FALSE);
|
||||||
|
|
||||||
$this->assertEquals(1,$pkt->count());
|
$this->assertEquals(1,$pkt->count());
|
||||||
|
|
||||||
$messages = FALSE;
|
$messages = FALSE;
|
||||||
foreach ($pkt as $msg) {
|
foreach ($pkt as $msg) {
|
||||||
$messages = TRUE;
|
$messages = TRUE;
|
||||||
$this->assertNotTrue($msg->isNetmail());
|
$this->assertNotTrue($msg->isNetmail());
|
||||||
|
|
||||||
$this->assertNotFalse($msg->pathaddress->search($hub->id));
|
$this->assertNotFalse($msg->pathaddress->search($hub->id));
|
||||||
|
|
||||||
$this->assertCount(1,$msg->rogue_path);
|
$this->assertCount(1,$msg->rogue_path);
|
||||||
$this->assertNotFalse($msg->rogue_path->search('21:999/1'));
|
$this->assertNotFalse($msg->rogue_path->search('21:999/1'));
|
||||||
|
|
||||||
$this->assertCount(3,$msg->rogue_seenby);
|
$this->assertCount(3,$msg->rogue_seenby);
|
||||||
$this->assertNotFalse($msg->rogue_seenby->search('21:999/1'));
|
$this->assertNotFalse($msg->rogue_seenby->search('21:999/1'));
|
||||||
$this->assertNotFalse($msg->rogue_seenby->search('21:999/999'));
|
$this->assertNotFalse($msg->rogue_seenby->search('21:999/999'));
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->assertTrue($messages);
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->assertTrue($messages);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public function test_nomsgid_noorigin()
|
public function test_nomsgid_noorigin()
|
||||||
@ -67,22 +69,24 @@ class PacketTest extends TestCase
|
|||||||
|
|
||||||
// This packet has an incorrect zone in the Origin
|
// This packet has an incorrect zone in the Origin
|
||||||
$f = new File(__DIR__.'/data/test_nomsgid_noorigin.pkt');
|
$f = new File(__DIR__.'/data/test_nomsgid_noorigin.pkt');
|
||||||
$pkt = Packet::open($f,$this->so,FALSE);
|
foreach ($f as $packet) {
|
||||||
|
$pkt = Packet::process($packet,$f->itemName(),$f->itemSize(),$this->so,FALSE);
|
||||||
|
|
||||||
$this->assertEquals(1,$pkt->count());
|
$this->assertEquals(1,$pkt->count());
|
||||||
|
|
||||||
$messages = FALSE;
|
$messages = FALSE;
|
||||||
foreach ($pkt as $msg) {
|
foreach ($pkt as $msg) {
|
||||||
$messages = TRUE;
|
$messages = TRUE;
|
||||||
$this->assertNotTrue($msg->isNetmail());
|
$this->assertNotTrue($msg->isNetmail());
|
||||||
|
|
||||||
$this->assertCount(1,$msg->rogue_path);
|
$this->assertCount(1,$msg->rogue_path);
|
||||||
$this->assertNotFalse($msg->rogue_path->search('10:1/1'));
|
$this->assertNotFalse($msg->rogue_path->search('10:1/1'));
|
||||||
|
|
||||||
$this->assertCount(0,$msg->rogue_seenby);
|
$this->assertCount(0,$msg->rogue_seenby);
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->assertTrue($messages);
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->assertTrue($messages);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public function test_msgid_origin()
|
public function test_msgid_origin()
|
||||||
@ -96,97 +100,105 @@ class PacketTest extends TestCase
|
|||||||
|
|
||||||
// This packet has an incorrect zone in the Origin
|
// This packet has an incorrect zone in the Origin
|
||||||
$f = new File(__DIR__.'/data/test_msgid_origin.pkt');
|
$f = new File(__DIR__.'/data/test_msgid_origin.pkt');
|
||||||
$pkt = Packet::open($f,$this->so,FALSE);
|
foreach ($f as $packet) {
|
||||||
|
$pkt = Packet::process($packet,$f->itemName(),$f->itemSize(),$this->so,FALSE);
|
||||||
|
|
||||||
$this->assertEquals(1,$pkt->count());
|
$this->assertEquals(1,$pkt->count());
|
||||||
|
|
||||||
$messages = FALSE;
|
$messages = FALSE;
|
||||||
foreach ($pkt as $msg) {
|
foreach ($pkt as $msg) {
|
||||||
$messages = TRUE;
|
$messages = TRUE;
|
||||||
$this->assertNotTrue($msg->isNetmail());
|
$this->assertNotTrue($msg->isNetmail());
|
||||||
$this->assertCount(0,$msg->rogue_path);
|
$this->assertCount(0,$msg->rogue_path);
|
||||||
|
|
||||||
$this->assertCount(1,$msg->rogue_seenby);
|
$this->assertCount(1,$msg->rogue_seenby);
|
||||||
$this->assertNotFalse($msg->rogue_seenby->search('10:1/1'));
|
$this->assertNotFalse($msg->rogue_seenby->search('10:1/1'));
|
||||||
|
|
||||||
$this->assertNotFalse($msg->seenaddress->search($src->id));
|
$this->assertNotFalse($msg->seenaddress->search($src->id));
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->assertTrue($messages);
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->assertTrue($messages);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public function test_packet_parse()
|
public function test_packet_parse()
|
||||||
{
|
{
|
||||||
// This packet has a SOH<char>SOH sequence
|
// This packet has a SOH<char>SOH sequence
|
||||||
$f = new File(__DIR__.'/data/test_binary_content-2.pkt');
|
$f = new File(__DIR__.'/data/test_binary_content-2.pkt');
|
||||||
$pkt = Packet::open($f,NULL,FALSE);
|
foreach ($f as $packet) {
|
||||||
|
$pkt = Packet::process($packet,$f->itemName(),$f->itemSize(),NULL,FALSE);
|
||||||
|
|
||||||
$this->assertEquals(1,$pkt->count());
|
$this->assertEquals(1,$pkt->count());
|
||||||
|
|
||||||
$messages = FALSE;
|
$messages = FALSE;
|
||||||
foreach ($pkt as $msg) {
|
foreach ($pkt as $msg) {
|
||||||
$messages = TRUE;
|
$messages = TRUE;
|
||||||
|
|
||||||
$this->assertNotTrue($msg->isNetmail());
|
$this->assertNotTrue($msg->isNetmail());
|
||||||
$this->assertSame('21:1/151 6189F64C',$msg->msgid);
|
$this->assertSame('21:1/151 6189F64C',$msg->msgid);
|
||||||
$this->assertSame('a8791fd3d261734bb524bc5ed929aa4c',md5($msg->message));
|
$this->assertSame('a8791fd3d261734bb524bc5ed929aa4c',md5($msg->message));
|
||||||
$this->assertSame('5b627ab5936b0550a97b738f4deff419',md5($msg->message_src));
|
$this->assertSame('5b627ab5936b0550a97b738f4deff419',md5($msg->message_src));
|
||||||
$this->assertCount(3,$msg->rogue_path);
|
$this->assertCount(3,$msg->rogue_path);
|
||||||
$this->assertCount(170,$msg->rogue_seenby);
|
$this->assertCount(170,$msg->rogue_seenby);
|
||||||
$this->assertContains('3/2744 4/100 106 5/100',$msg->seenby);
|
$this->assertContains('3/2744 4/100 106 5/100',$msg->seenby);
|
||||||
$this->assertContains('1/151 100 3/100',$msg->path);
|
$this->assertContains('1/151 100 3/100',$msg->path);
|
||||||
$this->assertCount(11,$msg->seenby);
|
$this->assertCount(11,$msg->seenby);
|
||||||
$this->assertCount(0,$msg->unknown);
|
$this->assertCount(0,$msg->unknown);
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->assertTrue($messages);
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->assertTrue($messages);
|
|
||||||
|
|
||||||
// This packet has SOH in the message content
|
// This packet has SOH in the message content
|
||||||
$f = new File(__DIR__.'/data/test_binary_content.pkt');
|
$f = new File(__DIR__.'/data/test_binary_content.pkt');
|
||||||
$pkt = Packet::open($f,NULL,FALSE);
|
foreach ($f as $packet) {
|
||||||
|
$pkt = Packet::process($packet,$f->itemName(),$f->itemSize(),NULL,FALSE);
|
||||||
|
|
||||||
$this->assertEquals(1,$pkt->count());
|
$this->assertEquals(1,$pkt->count());
|
||||||
|
|
||||||
$messages = FALSE;
|
$messages = FALSE;
|
||||||
foreach ($pkt as $msg) {
|
foreach ($pkt as $msg) {
|
||||||
$messages = TRUE;
|
$messages = TRUE;
|
||||||
|
|
||||||
$this->assertNotTrue($msg->isNetmail());
|
$this->assertNotTrue($msg->isNetmail());
|
||||||
$this->assertSame('21:1/126 eec6e958',$msg->msgid);
|
$this->assertSame('21:1/126 eec6e958',$msg->msgid);
|
||||||
$this->assertSame('c0b00abfc3eff7e297bf14f5812a7261',md5($msg->message));
|
$this->assertSame('c0b00abfc3eff7e297bf14f5812a7261',md5($msg->message));
|
||||||
$this->assertSame('a3193edcc68521d4ed07da6db2aeb0b6',md5($msg->message_src));
|
$this->assertSame('a3193edcc68521d4ed07da6db2aeb0b6',md5($msg->message_src));
|
||||||
$this->assertCount(3,$msg->rogue_path);
|
$this->assertCount(3,$msg->rogue_path);
|
||||||
$this->assertCount(161,$msg->rogue_seenby);
|
$this->assertCount(161,$msg->rogue_seenby);
|
||||||
$this->assertContains('1/995 2/100 116 1202 3/100 105 107 108 109 110 111 112 113 117 119',$msg->seenby);
|
$this->assertContains('1/995 2/100 116 1202 3/100 105 107 108 109 110 111 112 113 117 119',$msg->seenby);
|
||||||
$this->assertContains('1/126 100 3/100',$msg->path);
|
$this->assertContains('1/126 100 3/100',$msg->path);
|
||||||
$this->assertCount(10,$msg->seenby);
|
$this->assertCount(10,$msg->seenby);
|
||||||
$this->assertCount(0,$msg->unknown);
|
$this->assertCount(0,$msg->unknown);
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->assertTrue($messages);
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->assertTrue($messages);
|
|
||||||
|
|
||||||
// This packet has an incorrect zone in the Origin
|
// This packet has an incorrect zone in the Origin
|
||||||
$f = new File(__DIR__.'/data/test_msgid_origin.pkt');
|
$f = new File(__DIR__.'/data/test_msgid_origin.pkt');
|
||||||
$pkt = Packet::open($f,NULL,FALSE);
|
foreach ($f as $packet) {
|
||||||
|
$pkt = Packet::process($packet,$f->itemName(),$f->itemSize(),NULL,FALSE);
|
||||||
|
|
||||||
$this->assertEquals(1,$pkt->count());
|
$this->assertEquals(1,$pkt->count());
|
||||||
|
|
||||||
$messages = FALSE;
|
$messages = FALSE;
|
||||||
foreach ($pkt as $msg) {
|
foreach ($pkt as $msg) {
|
||||||
$messages = TRUE;
|
$messages = TRUE;
|
||||||
|
|
||||||
$this->assertNotTrue($msg->isNetmail());
|
$this->assertNotTrue($msg->isNetmail());
|
||||||
$this->assertSame('10:999/1 612aecda',$msg->msgid);
|
$this->assertSame('10:999/1 612aecda',$msg->msgid);
|
||||||
$this->assertSame('61078e680cda04c8b5eba0f712582e70',md5($msg->message));
|
$this->assertSame('61078e680cda04c8b5eba0f712582e70',md5($msg->message));
|
||||||
$this->assertSame('b9d65d4f7319ded282f3f1986276ae79',md5($msg->message_src));
|
$this->assertSame('b9d65d4f7319ded282f3f1986276ae79',md5($msg->message_src));
|
||||||
$this->assertCount(1,$msg->pathaddress);
|
$this->assertCount(1,$msg->pathaddress);
|
||||||
$this->assertCount(1,$msg->rogue_seenby);
|
$this->assertCount(1,$msg->rogue_seenby);
|
||||||
$this->assertContains('1/1 999/1 999',$msg->seenby);
|
$this->assertContains('1/1 999/1 999',$msg->seenby);
|
||||||
$this->assertContains('999/1',$msg->path);
|
$this->assertContains('999/1',$msg->path);
|
||||||
$this->assertCount(1,$msg->seenby);
|
$this->assertCount(1,$msg->seenby);
|
||||||
$this->assertCount(0,$msg->unknown);
|
$this->assertCount(0,$msg->unknown);
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->assertTrue($messages);
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->assertTrue($messages);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user