Author: Alexandru Stanoi Date: 2007-01-30 10:58:16 +0100 (Tue, 30 Jan 2007) New Revision: 4595
Log: - Implemented feature request #9292: added SSL support for IMAP and POP3. Based on a patch from Mikko Koppanen. - Modified the tutorial to include the new features. Added: trunk/Mail/docs/tutorial_example_14.php trunk/Mail/docs/tutorial_example_15.php Modified: trunk/Mail/ChangeLog trunk/Mail/docs/tutorial.txt trunk/Mail/src/options/transport_options.php trunk/Mail/src/transports/imap/imap_transport.php trunk/Mail/src/transports/pop3/pop3_transport.php trunk/Mail/src/transports/transport_connection.php trunk/Mail/tests/options/transport_options_test.php trunk/Mail/tests/transports/transport_imap_test.php trunk/Mail/tests/transports/transport_pop3_test.php Modified: trunk/Mail/ChangeLog =================================================================== --- trunk/Mail/ChangeLog 2007-01-30 09:10:39 UTC (rev 4594) +++ trunk/Mail/ChangeLog 2007-01-30 09:58:16 UTC (rev 4595) @@ -22,6 +22,8 @@ - Implemented feature request #9308: added option classes for transports. - Implemented feature request #10082: added options class ezcMailParserOptions and deprecated second parameter of parseMail() in ezcMailParser. +- Implemented feature request #9292: added SSL support for IMAP and POP3. + Based on a patch from Mikko Koppanen. 1.2.1 - [RELEASEDATE] Modified: trunk/Mail/docs/tutorial.txt =================================================================== --- trunk/Mail/docs/tutorial.txt 2007-01-30 09:10:39 UTC (rev 4594) +++ trunk/Mail/docs/tutorial.txt 2007-01-30 09:58:16 UTC (rev 4595) @@ -71,8 +71,8 @@ For mail retrieval we currently support the following protocols: -- POP3 (ezcMailPop3Transport) - old protocol but still used -- IMAP (ezcMailImapTransport) - handles multiple mailboxes +- POP3 (ezcMailPop3Transport) - old protocol but still used. SSL is supported. +- IMAP (ezcMailImapTransport) - handles multiple mailboxes. SSL is supported. - MBOX (ezcMailMboxTransport) - handles Unix mailbox file formats Mail retrieval from other sources: @@ -97,11 +97,12 @@ - ezcMailFile - mail attachment from an existing file - ezcMailStreamFile - mail attachment from an open stream - ezcMailVirtualFile - mail attachment from a string in memory -- ezcMailMultipart - support for all multipart parts - ezcMailMultipartAlternative - used to bundle a group of mail parts where only one should be shown - ezcMailMultipartDigest - used to bundle a list of mail objects - ezcMailMultipartMixed - used to bundle an ordered list of mail parts - ezcMailMultipartRelated - intended for mail parts consisting of several inter-related body parts +- ezcMailMultipartReport - used for sending delivery status notifications +- ezcMailDeliveryStatus - used for sending delivery status notifications - ezcMailRfc822Digest - used to insert mail into mail - ezcMailText - used for plain text @@ -265,6 +266,28 @@ .. include:: tutorial_example_11.php :literal: +Working with transport options +------------------------------ + +The POP3, IMAP and SMTP transports allow options to be specified when calling +the transport constructors. These options are implemented in the classes +ezcMailPop3TransportOptions, ezcMailImapTransportOptions and +ezcMailSmtpTransportOptions. In the following example it is shown how to +specify options when calling the POP3 transport constructor. + +.. include:: tutorial_example_15.php + :literal: + +Using SSL with POP3 and IMAP +---------------------------- + +The POP3 and IMAP transport allow SSL connections, if the mail server supports +them. In the following example it is shown how to connect to an IMAP server +using an SSL connection. + +.. include:: tutorial_example_14.php + :literal: + Retrieving mail from Mbox files ------------------------------- @@ -292,6 +315,11 @@ .. _display example: Mail_display-example.html +For a list of mail-related RFCs that are supported please see the `RFCs list`_. + +.. _RFCs list: Mail_rfcs.html + + Troubleshooting =============== Added: trunk/Mail/docs/tutorial_example_14.php =================================================================== --- trunk/Mail/docs/tutorial_example_14.php 2007-01-30 09:10:39 UTC (rev 4594) +++ trunk/Mail/docs/tutorial_example_14.php 2007-01-30 09:58:16 UTC (rev 4595) @@ -0,0 +1,15 @@ +<?php +require_once 'tutorial_autoload.php'; + +// Create a new IMAP transport with an SSL connection (default port is 993, +// you can specify a different one using the second parameter of the constructor). +$imap = new ezcMailImapTransport( "imap.example.com", null, + array( 'ssl' => true ) ); + +// Authenticate to the IMAP server +$imap->authenticate( "user", "password" ); + +// Select the Inbox mailbox +$imap->selectMailbox( 'Inbox' ); + +?> Property changes on: trunk/Mail/docs/tutorial_example_14.php ___________________________________________________________________ Name: svn:eol-style + native Added: trunk/Mail/docs/tutorial_example_15.php =================================================================== --- trunk/Mail/docs/tutorial_example_15.php 2007-01-30 09:10:39 UTC (rev 4594) +++ trunk/Mail/docs/tutorial_example_15.php 2007-01-30 09:58:16 UTC (rev 4595) @@ -0,0 +1,16 @@ +<?php +require_once 'tutorial_autoload.php'; + +// Create a new POP3 transport with a plain connection (default port is 110, +// you can specify a different one using the second parameter of the constructor). +// A timeout option is specified to be 10 seconds (default is 5). +// Another option to be specified is the authenticationMethod as APOP (default is plain text) +$pop3 = new ezcMailPop3Transport( "imap.example.com", null, + array( 'timeout' => 10, + 'authenticationMethod' => ezcMailPop3Transport::AUTH_APOP + ) ); + +// Authenticate to the POP3 server +$pop3->authenticate( "user", "password" ); + +?> Property changes on: trunk/Mail/docs/tutorial_example_15.php ___________________________________________________________________ Name: svn:eol-style + native Modified: trunk/Mail/src/options/transport_options.php =================================================================== --- trunk/Mail/src/options/transport_options.php 2007-01-30 09:10:39 UTC (rev 4594) +++ trunk/Mail/src/options/transport_options.php 2007-01-30 09:58:16 UTC (rev 4595) @@ -14,6 +14,8 @@ * @property int $timeout * Specifies the time in seconds until the connection is closed if * there is no activity through the connection. + * @property bool $ssl + * Specifies whether to use an SSL connection or not. * * @package Mail * @version //autogen// @@ -28,6 +30,7 @@ public function __construct( array $options = array() ) { $this->timeout = 5; // default value for timeout is 5 seconds + $this->ssl = false; // default value for ssl is false parent::__construct( $options ); } @@ -55,6 +58,14 @@ $this->properties[$name] = (int) $value; break; + case 'ssl': + if ( !is_bool( $value ) ) + { + throw new ezcBaseValueException( $name, $value, 'bool' ); + } + $this->properties[$name] = $value; + break; + default: throw new ezcBasePropertyNotFoundException( $name ); } Modified: trunk/Mail/src/transports/imap/imap_transport.php =================================================================== --- trunk/Mail/src/transports/imap/imap_transport.php 2007-01-30 09:10:39 UTC (rev 4594) +++ trunk/Mail/src/transports/imap/imap_transport.php 2007-01-30 09:58:16 UTC (rev 4595) @@ -16,7 +16,6 @@ * http://www.faqs.org/rfcs/rfc2060.html (IMAP4rev1) * * @todo ignore messages of a certain size? - * @todo // add support for SSL? * @todo // support for signing? * @todo listUniqueIdentifiers(): add UIVALIDITY value to UID (like in POP3). * (if necessary). @@ -186,9 +185,8 @@ * Creates a new IMAP transport and connects to the $server at $port. * * You can specify the $port if the IMAP server is not on the default port - * 143. The constructor just calls the [EMAIL PROTECTED] connect()} method, and sets - * the class variables [EMAIL PROTECTED] $this->server} and [EMAIL PROTECTED] $this->port} to - * the respective parameters values. + * 993 (for SSL connections) or 143 (for plain connections). Use the $options + * parameter to specify an SSL connection. * * @see ezcMailImapTransportOptions for options you can specify for IMAP. * @@ -198,9 +196,13 @@ * @param int $port * @param array(string=>mixed) $options */ - public function __construct( $server, $port = 143, array $options = array() ) + public function __construct( $server, $port = null, array $options = array() ) { $this->options = new ezcMailImapTransportOptions( $options ); + if ( $port === null ) + { + $port = ( $this->options->ssl === true ) ? 993 : 143; + } $this->connection = new ezcMailTransportConnection( $server, $port, $options ); // get the server greeting $response = $this->connection->getLine(); Modified: trunk/Mail/src/transports/pop3/pop3_transport.php =================================================================== --- trunk/Mail/src/transports/pop3/pop3_transport.php 2007-01-30 09:10:39 UTC (rev 4594) +++ trunk/Mail/src/transports/pop3/pop3_transport.php 2007-01-30 09:58:16 UTC (rev 4595) @@ -19,7 +19,6 @@ * http://www.faqs.org/rfc/rfc1734.txt - auth * * @todo ignore messages of a certain size? - * @todo // add support for SSL? * @todo // support for signing? * * @property ezcMailPop3TransportOptions $options @@ -106,7 +105,9 @@ /** * Creates a new POP3 transport and connects to the $server at $port. * - * You can specify the $port if the POP3 server is not on the default port 110. + * You can specify the $port if the POP3 server is not on the default + * port 995 (for SSL connections) or 110 (for plain connections). Use the + * $options parameter to specify an SSL connection. * * @see ezcMailPop3TransportOptions for options you can specify for POP3. * @@ -116,10 +117,13 @@ * @param int $port * @param array(string=>mixed) $options */ - public function __construct( $server, $port = 110, array $options = array() ) + public function __construct( $server, $port = null, array $options = array() ) { $this->options = new ezcMailPop3TransportOptions( $options ); - // open the connection + if ( $port === null ) + { + $port = ( $this->options->ssl === true ) ? 995 : 110; + } $this->connection = new ezcMailTransportConnection( $server, $port, $options ); $this->greeting = $this->connection->getLine(); if ( !$this->isPositiveResponse( $this->greeting ) ) Modified: trunk/Mail/src/transports/transport_connection.php =================================================================== --- trunk/Mail/src/transports/transport_connection.php 2007-01-30 09:10:39 UTC (rev 4594) +++ trunk/Mail/src/transports/transport_connection.php 2007-01-30 09:58:16 UTC (rev 4595) @@ -47,7 +47,6 @@ * @see ezcMailTransportOptions for options you can specify for a transport connection. * * @todo The @ should be removed when PHP doesn't throw warnings for connect problems. - * @todo Implement SSL support * * @throws ezcMailTransportException * if a connection to the server could not be made @@ -60,10 +59,21 @@ $errno = null; $errstr = null; $this->options = new ezcMailTransportOptions( $options ); + if ( $this->options->ssl ) + { + if ( ezcBaseFeatures::hasExtensionSupport( 'openssl' ) !== true ) + { + throw new ezcBaseFeatureNotFoundException( "Failed to connect to the server: {$server}:{$port}. PHP not configured --with-openssl." ); + } + $this->connection = @stream_socket_client( "ssl://{$server}:{$port}", + $errno, $errstr, $this->options->timeout ); + } + else + { + $this->connection = @stream_socket_client( "tcp://{$server}:{$port}", + $errno, $errstr, $this->options->timeout ); + } - $this->connection = @stream_socket_client( "tcp://{$server}:{$port}", - $errno, $errstr, $this->options->timeout ); - if ( is_resource( $this->connection ) ) { stream_set_timeout( $this->connection, $this->options->timeout ); Modified: trunk/Mail/tests/options/transport_options_test.php =================================================================== --- trunk/Mail/tests/options/transport_options_test.php 2007-01-30 09:10:39 UTC (rev 4594) +++ trunk/Mail/tests/options/transport_options_test.php 2007-01-30 09:58:16 UTC (rev 4595) @@ -18,13 +18,16 @@ { $options = new ezcMailTransportOptions(); $this->assertEquals( 5, $options->timeout ); + $this->assertEquals( false, $options->ssl ); } public function testTransportOptionsSet() { $options = new ezcMailTransportOptions(); $options->timeout = 10; + $options->ssl = true; $this->assertEquals( 10, $options->timeout ); + $this->assertEquals( true, $options->ssl ); } public function testTransportOptionsSetInvalid() @@ -47,6 +50,15 @@ catch ( ezcBaseValueException $e ) { } + + try + { + $options->ssl = 'xxx'; + $this->fail( "Expected exception was not thrown" ); + } + catch ( ezcBaseValueException $e ) + { + } } public function testTransportOptionsSetNotExistent() Modified: trunk/Mail/tests/transports/transport_imap_test.php =================================================================== --- trunk/Mail/tests/transports/transport_imap_test.php 2007-01-30 09:10:39 UTC (rev 4594) +++ trunk/Mail/tests/transports/transport_imap_test.php 2007-01-30 09:58:16 UTC (rev 4595) @@ -1404,6 +1404,31 @@ } } + public function testServerSSL() + { + $imap = new ezcMailImapTransport( "ezctest.ez.no", null, array( 'ssl' => true ) ); + $imap->authenticate( "as", "wee123" ); + $imap->selectMailbox( 'inbox' ); + $set = $imap->fetchAll(); + $parser = new ezcMailParser(); + $mail = $parser->parseMail( $set ); + $mail = $mail[0]; + $this->assertEquals( 240, $mail->size ); + } + + public function testServerSSLInvalidPort() + { + try + { + $imap = new ezcMailImapTransport( "ezctest.ez.no", 143, array( 'ssl' => true ) ); + $this->fail( "Didn't get exception when expected" ); + } + catch ( ezcMailTransportException $e ) + { + $this->assertEquals( 'An error occured while sending or receiving mail. Failed to connect to the server: ezctest.ez.no:143.', $e->getMessage() ); + } + } + public static function suite() { self::$ids = array( 15, 16, 17, 18 ); Modified: trunk/Mail/tests/transports/transport_pop3_test.php =================================================================== --- trunk/Mail/tests/transports/transport_pop3_test.php 2007-01-30 09:10:39 UTC (rev 4594) +++ trunk/Mail/tests/transports/transport_pop3_test.php 2007-01-30 09:58:16 UTC (rev 4595) @@ -443,6 +443,30 @@ } } + public function testServerSSL() + { + $pop3 = new ezcMailPop3Transport( "ezctest.ez.no", null, array( 'ssl' => true ) ); + $pop3->authenticate( "as", "wee123" ); + $set = $pop3->fetchAll(); + $parser = new ezcMailParser(); + $mail = $parser->parseMail( $set ); + $mail = $mail[0]; + $this->assertEquals( 240, $mail->size ); + } + + public function testServerSSLInvalidPort() + { + try + { + $pop3 = new ezcMailPop3Transport( "ezctest.ez.no", 110, array( 'ssl' => true ) ); + $this->fail( "Didn't get exception when expected" ); + } + catch ( ezcMailTransportException $e ) + { + $this->assertEquals( 'An error occured while sending or receiving mail. Failed to connect to the server: ezctest.ez.no:110.', $e->getMessage() ); + } + } + public static function suite() { self::$ids = array( '0000000f4420e93a', '000000104420e93a', '000000114420e93a', '000000124420e93a' ); -- svn-components mailing list svn-components@lists.ez.no http://lists.ez.no/mailman/listinfo/svn-components