Finalized new message parsing. Attention: changes in database schema

release-0.6
thomascube 18 years ago
parent 5f56a5bfa9
commit f7bfec96be

@ -1,6 +1,13 @@
CHANGELOG RoundCube Webmail
---------------------------
2006/08/25 (thomasb)
----------
- Fixed folder renaming: unsubscribe before rename (Bug #1483920)
- Finalized new message parsing (+ chaching)
- Updated SQL scripts and UPGRADING instructions
2006/08/23 (thomasb)
----------
- Updated Polish, Portuguese, Latvian, Chinese and Japanese localization
@ -16,6 +23,7 @@ CHANGELOG RoundCube Webmail
2006/08/18 (thomasb)
----------
- Re-built message parsing (Bug #1327068)
Now based on the message structure delivered by the IMAP server.
- Fixed some XSS and SQL injection issues

@ -40,7 +40,7 @@ importing the table layout and granting the proper permissions to the
roundcube user. Here is an example of that procedure:
# mysql
> CREATE DATABASE 'roundcubemail';
> CREATE DATABASE roundcubemail;
> GRANT ALL PRIVILEGES ON roundcubemail.* TO roundcube@localhost
IDENTIFIED BY 'password';
> quit
@ -53,7 +53,7 @@ For MySQL version 4.1 and up, it's recommended to create the database for
RoundCube with utf-8 charset. Here's an example of the init procedure:
# mysql
> CREATE DATABASE 'roundcubemail' DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci;
> CREATE DATABASE roundcubemail DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci;
> GRANT ALL PRIVILEGES ON roundcubemail.* TO roundcube@localhost
IDENTIFIED BY 'password';
> quit

@ -1,5 +1,5 @@
-- RoundCube Webmail initial database structure
-- Version 0.1beta2
-- Version 0.1-beta2
--
-- --------------------------------------------------------
@ -116,12 +116,12 @@ CREATE TABLE `messages` (
`date` datetime NOT NULL default '0000-00-00 00:00:00',
`size` int(11) unsigned NOT NULL default '0',
`headers` text NOT NULL,
`body` longtext,
`structure` text,
PRIMARY KEY (`message_id`),
KEY `user_id` (`user_id`),
KEY `cache_key` (`cache_key`),
KEY `idx` (`idx`),
KEY `uid` (`uid`)
KEY `uid` (`uid`),
UNIQUE `uniqueness` (`cache_key`, `uid`)
);

@ -0,0 +1,51 @@
-- RoundCube Webmail update script for MySQL databases
-- Updates from version 0.1-20051007
ALTER TABLE `session` ADD `ip` VARCHAR(15) NOT NULL AFTER changed;
ALTER TABLE `users` ADD `alias` VARCHAR(128) NOT NULL AFTER mail_host;
-- RoundCube Webmail update script for MySQL databases
-- Updates from version 0.1-20051021
ALTER TABLE `session` CHANGE `sess_id` `sess_id` VARCHAR(40) NOT NULL;
ALTER TABLE `contacts` CHANGE `del` `del` TINYINT(1) NOT NULL;
ALTER TABLE `contacts` ADD `changed` DATETIME NOT NULL AFTER `user_id`;
UPDATE `contacts` SET `del`=0 WHERE `del`=1;
UPDATE `contacts` SET `del`=1 WHERE `del`=2;
ALTER TABLE `identities` CHANGE `default` `standard` TINYINT(1) NOT NULL;
ALTER TABLE `identities` CHANGE `del` `del` TINYINT(1) NOT NULL;
UPDATE `identities` SET `del`=0 WHERE `del`=1;
UPDATE `identities` SET `del`=1 WHERE `del`=2;
UPDATE `identities` SET `standard`=0 WHERE `standard`=1;
UPDATE `identities` SET `standard`=1 WHERE `standard`=2;
CREATE TABLE `messages` (
`message_id` int(11) unsigned NOT NULL auto_increment,
`user_id` int(11) unsigned NOT NULL default '0',
`del` tinyint(1) NOT NULL default '0',
`cache_key` varchar(128) NOT NULL default '',
`created` datetime NOT NULL default '0000-00-00 00:00:00',
`idx` int(11) unsigned NOT NULL default '0',
`uid` int(11) unsigned NOT NULL default '0',
`subject` varchar(255) NOT NULL default '',
`from` varchar(255) NOT NULL default '',
`to` varchar(255) NOT NULL default '',
`cc` varchar(255) NOT NULL default '',
`date` datetime NOT NULL default '0000-00-00 00:00:00',
`size` int(11) unsigned NOT NULL default '0',
`headers` text NOT NULL,
`structure` text,
PRIMARY KEY (`message_id`),
KEY `user_id` (`user_id`),
KEY `idx` (`idx`),
KEY `uid` (`uid`),
UNIQUE `uniqueness` (`cache_key`, `uid`)
) TYPE=MyISAM;

@ -1,57 +1,9 @@
-- RoundCube Webmail update script for MySQL databases
-- Updates from version 0.1-20051007
-- Updates from version 0.1-beta and 0.1-beta2
ALTER TABLE `messages`
DROP `body`,
DROP INDEX `cache_key`,
ADD `structure` TEXT,
ADD UNIQUE `uniqueness` (`cache_key`, `uid`);
ALTER TABLE `session` ADD `ip` VARCHAR(15) NOT NULL AFTER changed;
ALTER TABLE `users` ADD `alias` VARCHAR(128) NOT NULL AFTER mail_host;
-- RoundCube Webmail update script for MySQL databases
-- Updates from version 0.1-20051021
ALTER TABLE `session` CHANGE `sess_id` `sess_id` VARCHAR(40) NOT NULL;
ALTER TABLE `contacts` CHANGE `del` `del` TINYINT(1) NOT NULL;
ALTER TABLE `contacts` ADD `changed` DATETIME NOT NULL AFTER `user_id`;
UPDATE `contacts` SET `del`=0 WHERE `del`=1;
UPDATE `contacts` SET `del`=1 WHERE `del`=2;
ALTER TABLE `identities` CHANGE `default` `standard` TINYINT(1) NOT NULL;
ALTER TABLE `identities` CHANGE `del` `del` TINYINT(1) NOT NULL;
UPDATE `identities` SET `del`=0 WHERE `del`=1;
UPDATE `identities` SET `del`=1 WHERE `del`=2;
UPDATE `identities` SET `standard`=0 WHERE `standard`=1;
UPDATE `identities` SET `standard`=1 WHERE `standard`=2;
CREATE TABLE `messages` (
`message_id` int(11) unsigned NOT NULL auto_increment,
`user_id` int(11) unsigned NOT NULL default '0',
`del` tinyint(1) NOT NULL default '0',
`cache_key` varchar(128) NOT NULL default '',
`created` datetime NOT NULL default '0000-00-00 00:00:00',
`idx` int(11) unsigned NOT NULL default '0',
`uid` int(11) unsigned NOT NULL default '0',
`subject` varchar(255) NOT NULL default '',
`from` varchar(255) NOT NULL default '',
`to` varchar(255) NOT NULL default '',
`cc` varchar(255) NOT NULL default '',
`date` datetime NOT NULL default '0000-00-00 00:00:00',
`size` int(11) unsigned NOT NULL default '0',
`headers` text NOT NULL,
`body` longtext,
PRIMARY KEY (`message_id`),
KEY `user_id` (`user_id`),
KEY `cache_key` (`cache_key`),
KEY `idx` (`idx`),
KEY `uid` (`uid`)
) TYPE=MyISAM;
-- RoundCube Webmail update script for MySQL databases
-- Updates from version 0.1-20051216
ALTER TABLE `messages` ADD `created` DATETIME NOT NULL AFTER `cache_key` ;

@ -1,5 +1,5 @@
-- RoundCube Webmail initial database structure
-- Version 0.1beta2
-- Version 0.1-beta2
--
-- --------------------------------------------------------
@ -16,7 +16,7 @@ CREATE TABLE `session` (
`ip` varchar(15) NOT NULL,
`vars` text NOT NULL,
PRIMARY KEY(`sess_id`)
) TYPE=MYISAM CHARACTER SET utf8 COLLATE utf8_general_ci;
) TYPE=MYISAM CHARACTER SET ascii COLLATE ascii_general_ci;
-- Table structure for table `users`
@ -31,15 +31,16 @@ CREATE TABLE `users` (
`language` varchar(5) NOT NULL DEFAULT 'en',
`preferences` text NOT NULL,
PRIMARY KEY(`user_id`)
) TYPE=MYISAM CHARACTER SET utf8 COLLATE utf8_general_ci;
) TYPE=MYISAM CHARACTER SET ascii COLLATE ascii_general_ci;
-- Table structure for table `messages`
CREATE TABLE `messages` (
`message_id` int(11) UNSIGNED NOT NULL AUTO_INCREMENT,
`user_id` int(10) UNSIGNED NOT NULL DEFAULT '0',
`del` tinyint(1) NOT NULL DEFAULT '0',
`cache_key` varchar(128) NOT NULL,
`cache_key` varchar(128) CHARACTER SET ascii COLLATE ascii_general_ci NOT NULL,
`created` datetime NOT NULL DEFAULT '0000-00-00 00:00:00',
`idx` int(11) UNSIGNED NOT NULL DEFAULT '0',
`uid` int(11) UNSIGNED NOT NULL DEFAULT '0',
@ -50,12 +51,11 @@ CREATE TABLE `messages` (
`date` datetime NOT NULL DEFAULT '0000-00-00 00:00:00',
`size` int(11) UNSIGNED NOT NULL DEFAULT '0',
`headers` text NOT NULL,
`body` longtext,
`user_id` int(10) UNSIGNED NOT NULL DEFAULT '0',
`structure` text,
PRIMARY KEY(`message_id`),
INDEX `cache_key`(`cache_key`),
INDEX `idx`(`idx`),
INDEX `uid`(`uid`),
UNIQUE `uniqueness` (`cache_key`, `uid`),
CONSTRAINT `User_ID_FK_messages` FOREIGN KEY (`user_id`)
REFERENCES `users`(`user_id`)
ON DELETE CASCADE
@ -67,8 +67,8 @@ CREATE TABLE `messages` (
CREATE TABLE `cache` (
`cache_id` int(10) UNSIGNED NOT NULL AUTO_INCREMENT,
`session_id` varchar(40),
`cache_key` varchar(128) NOT NULL,
`session_id` varchar(40) CHARACTER SET ascii COLLATE ascii_general_ci,
`cache_key` varchar(128) CHARACTER SET ascii COLLATE ascii_general_ci NOT NULL,
`created` datetime NOT NULL DEFAULT '0000-00-00 00:00:00',
`data` longtext NOT NULL,
`user_id` int(10) UNSIGNED NOT NULL DEFAULT '0',

@ -163,6 +163,7 @@ CREATE TABLE "messages" (
date timestamp with time zone NOT NULL,
size integer DEFAULT 0 NOT NULL,
headers text NOT NULL,
body text
structure text
);
ALTER TABLE "messages" ADD UNIQUE (cache_key, uid);

@ -0,0 +1,7 @@
-- RoundCube Webmail update script for Postres databases
-- Updates from version 0.1-beta and older
ALTER TABLE "messages" DROP body;
ALTER TABLE "messages" ADD structure TEXT;
ALTER TABLE "messages" ADD UNIQUE (cache_key, uid);

@ -1,5 +1,5 @@
-- RoundCube Webmail initial database structure
-- Version 0.1a
-- Version 0.1-beta2
--
-- --------------------------------------------------------
@ -118,7 +118,7 @@ CREATE TABLE messages (
date datetime NOT NULL default '0000-00-00 00:00:00',
size integer NOT NULL default '0',
headers text NOT NULL,
body text
structure text
);
CREATE INDEX ix_messages_user_id ON messages(user_id);

@ -0,0 +1,27 @@
-- RoundCube Webmail update script for SQLite databases
-- Updates from version 0.1-beta2 and older
DROP TABLE messages;
CREATE TABLE messages (
message_id integer NOT NULL PRIMARY KEY,
user_id integer NOT NULL default '0',
del tinyint NOT NULL default '0',
cache_key varchar(128) NOT NULL default '',
created datetime NOT NULL default '0000-00-00 00:00:00',
idx integer NOT NULL default '0',
uid integer NOT NULL default '0',
subject varchar(255) NOT NULL default '',
"from" varchar(255) NOT NULL default '',
"to" varchar(255) NOT NULL default '',
cc varchar(255) NOT NULL default '',
date datetime NOT NULL default '0000-00-00 00:00:00',
size integer NOT NULL default '0',
headers text NOT NULL,
structure text
);
CREATE INDEX ix_messages_user_id ON messages(user_id);
CREATE INDEX ix_messages_cache_key ON messages(cache_key);
CREATE INDEX ix_messages_idx ON messages(idx);
CREATE INDEX ix_messages_uid ON messages(uid);

@ -5,64 +5,72 @@ Follow these instructions if upgrading from a previous version
of RoundCube Webmail.
from versions 0.1-alpha and 0.1-20050811
from version 1.0-beta2
----------------------------------------
- replace index.php
- replace all files in folder /program/
- replace all files in folder /skins/default/
- run all commands in SQL/*.update.sql or re-initalize database with *.initial.sql
- add these line to /config/main.inc.php
$rcmail_config['trash_mbox'] = 'Trash';
$rcmail_config['default_imap_folders'] = array('INBOX', 'Drafts', 'Sent', 'Junk', 'Trash');
$rcmail_config['prefer_html'] = TRUE;
$rcmail_config['prettydate'] = TRUE;
$rcmail_config['smtp_port'] = 25;
$rcmail_config['default_port'] = 143;
$rcmail_config['session_lifetime'] = 20;
$rcmail_config['skip_deleted'] = FALSE;
$rcmail_config['message_sort_col'] = 'date';
$rcmail_config['message_sort_order'] = 'DESC';
$rcmail_config['log_dir'] = 'logs/';
$rcmail_config['temp_dir'] = 'temp/';
$rcmail_config['message_cache_lifetime'] = '10d';
- replace database properties (db_type, db_host, db_user, db_pass, $d_name)
in /config/db.inc.php with the following line:
$rcmail_config['db_dsnw'] = 'mysql://roundcube:pass@localhost/roundcubemail';
- add these lines to /config/db.inc.php
$rcmail_config['db_max_length'] = 512000;
* replace index.php
* replace all files in folder /program/
* replace all files in folder /skins/default/
* run all commands in SQL/*.update.sql or re-initalize database with *.initial.sql
from version 0.1-20050820
form version 0.1-beta
----------------------------------------
- replace index.php
- replace all files in folder /program/
- replace all files in folder /skins/default/
- run all commands in SQL/*.update.sql or re-initalize database with *.initial.sql
- add these line to /config/main.inc.php
$rcmail_config['prettydate'] = TRUE;
$rcmail_config['smtp_port'] = 25;
$rcmail_config['default_port'] = 143;
$rcmail_config['session_lifetime'] = 20;
* replace index.php
* replace all files in folder /program/
* replace all files in folder /skins/default/
* run all commands in SQL/*.update.sql or re-initalize database with *.initial.sql
* add these line to /config/db.inc.php
$rcmail_config['db_persistent'] = TRUE;
* add these lines to /config/main.inc.php
$rcmail_config['drafts_mbox'] = 'Drafts';
$rcmail_config['junk_mbox'] = 'Junk';
$rcmail_config['product_name'] = 'RoundCube Webmail';
$rcmail_config['read_when_deleted'] = TRUE;
$rcmail_config['enable_spellcheck'] = TRUE;
$rcmail_config['protect_default_folders'] = TRUE;
* replace the following line from /config/main.inc.php
@include($_SERVER['HTTP_HOST'].'.inc.php');
with
$rcmail_config['include_host_config'] = TRUE;
from version 0.1-20051021
----------------------------------------
* replace index.php
* replace all files in folder /program/
* replace all files in folder /skins/default/
* run all commands in SQL/*.update-0.1a.sql or re-initalize database with *.initial.sql
* add these lines to /config/main.inc.php
$rcmail_config['skip_deleted'] = FALSE;
$rcmail_config['message_sort_col'] = 'date';
$rcmail_config['message_sort_order'] = 'DESC';
$rcmail_config['log_dir'] = 'logs/';
$rcmail_config['temp_dir'] = 'temp/';
$rcmail_config['message_cache_lifetime'] = '10d';
- replace database properties (db_type, db_host, db_user, db_pass, $d_name)
in /config/db.inc.php with the following line:
$rcmail_config['db_dsnw'] = 'mysql://roundcube:pass@localhost/roundcubemail';
- add these lines to /config/db.inc.php
$rcmail_config['drafts_mbox'] = 'Drafts';
$rcmail_config['product_name'] = 'RoundCube Webmail';
$rcmail_config['read_when_deleted'] = TRUE;
$rcmail_config['enable_spellcheck'] = TRUE;
* add these lines to /config/db.inc.php
$rcmail_config['db_max_length'] = 512000;
$rcmail_config['db_sequence_user_ids'] = 'user_ids';
$rcmail_config['db_sequence_identity_ids'] = 'identity_ids';
$rcmail_config['db_sequence_contact_ids'] = 'contact_ids';
$rcmail_config['db_sequence_cache_ids'] = 'cache_ids';
$rcmail_config['db_sequence_message_ids'] = 'message_ids';
$rcmail_config['db_persistent'] = TRUE;
from version 0.1-20051007
----------------------------------------
- replace index.php
- replace all files in folder /program/
- replace all files in folder /skins/default/
- run all commands in SQL/*.update.sql or re-initalize database with *.initial.sql
- add these lines to /config/main.inc.php
* replace index.php
* replace all files in folder /program/
* replace all files in folder /skins/default/
* run all commands in SQL/*.update-0.1a.sql or re-initalize database with *.initial.sql
* add these lines to /config/main.inc.php
$rcmail_config['smtp_auth_type'] = ''; // if you need to specify an auth method for SMTP
$rcmail_config['session_lifetime'] = 20; // to specify the session lifetime in minutes
$rcmail_config['skip_deleted'] = FALSE;
@ -75,7 +83,7 @@ from version 0.1-20051007
$rcmail_config['product_name'] = 'RoundCube Webmail';
$rcmail_config['read_when_deleted'] = TRUE;
$rcmail_config['enable_spellcheck'] = TRUE;
- add these lines to /config/db.inc.php
* add these lines to /config/db.inc.php
$rcmail_config['db_max_length'] = 512000;
$rcmail_config['db_sequence_user_ids'] = 'user_ids';
$rcmail_config['db_sequence_identity_ids'] = 'identity_ids';
@ -84,50 +92,56 @@ from version 0.1-20051007
$rcmail_config['db_sequence_message_ids'] = 'message_ids';
$rcmail_config['db_persistent'] = TRUE;
from version 0.1-20051021
from version 0.1-20050820
----------------------------------------
- replace index.php
- replace all files in folder /program/
- replace all files in folder /skins/default/
- run all commands in SQL/*.update.sql or re-initalize database with *.initial.sql
- add these lines to /config/main.inc.php
* replace index.php
* replace all files in folder /program/
* replace all files in folder /skins/default/
* run all commands in SQL/*.update-0.1a.sql or re-initalize database with *.initial.sql
* add these line to /config/main.inc.php
$rcmail_config['prettydate'] = TRUE;
$rcmail_config['smtp_port'] = 25;
$rcmail_config['default_port'] = 143;
$rcmail_config['session_lifetime'] = 20;
$rcmail_config['skip_deleted'] = FALSE;
$rcmail_config['message_sort_col'] = 'date';
$rcmail_config['message_sort_order'] = 'DESC';
$rcmail_config['log_dir'] = 'logs/';
$rcmail_config['temp_dir'] = 'temp/';
$rcmail_config['message_cache_lifetime'] = '10d';
$rcmail_config['drafts_mbox'] = 'Drafts';
$rcmail_config['product_name'] = 'RoundCube Webmail';
$rcmail_config['read_when_deleted'] = TRUE;
$rcmail_config['enable_spellcheck'] = TRUE;
- add these lines to /config/db.inc.php
* replace database properties (db_type, db_host, db_user, db_pass, $d_name)
in /config/db.inc.php with the following line:
$rcmail_config['db_dsnw'] = 'mysql://roundcube:pass@localhost/roundcubemail';
* add these lines to /config/db.inc.php
$rcmail_config['db_max_length'] = 512000;
$rcmail_config['db_sequence_user_ids'] = 'user_ids';
$rcmail_config['db_sequence_identity_ids'] = 'identity_ids';
$rcmail_config['db_sequence_contact_ids'] = 'contact_ids';
$rcmail_config['db_sequence_cache_ids'] = 'cache_ids';
$rcmail_config['db_sequence_message_ids'] = 'message_ids';
$rcmail_config['db_persistent'] = TRUE;
form version 0.1-beta
from versions 0.1-alpha and 0.1-20050811
----------------------------------------
- replace index.php
- replace all files in folder /program/
- replace all files in folder /skins/default/
- add these line to /config/db.inc.php
$rcmail_config['db_persistent'] = TRUE;
- add these lines to /config/main.inc.php
$rcmail_config['drafts_mbox'] = 'Drafts';
$rcmail_config['junk_mbox'] = 'Junk';
$rcmail_config['product_name'] = 'RoundCube Webmail';
$rcmail_config['read_when_deleted'] = TRUE;
$rcmail_config['enable_spellcheck'] = TRUE;
$rcmail_config['protect_default_folders'] = TRUE;
- replace the following line from /config/main.inc.php
@include($_SERVER['HTTP_HOST'].'.inc.php');
with
$rcmail_config['include_host_config'] = TRUE;
* replace index.php
* replace all files in folder /program/
* replace all files in folder /skins/default/
* run all commands in SQL/*.update-0.1a.sql or re-initalize database with *.initial.sql
* add these line to /config/main.inc.php
$rcmail_config['trash_mbox'] = 'Trash';
$rcmail_config['default_imap_folders'] = array('INBOX', 'Drafts', 'Sent', 'Junk', 'Trash');
$rcmail_config['prefer_html'] = TRUE;
$rcmail_config['prettydate'] = TRUE;
$rcmail_config['smtp_port'] = 25;
$rcmail_config['default_port'] = 143;
$rcmail_config['session_lifetime'] = 20;
$rcmail_config['skip_deleted'] = FALSE;
$rcmail_config['message_sort_col'] = 'date';
$rcmail_config['message_sort_order'] = 'DESC';
$rcmail_config['log_dir'] = 'logs/';
$rcmail_config['temp_dir'] = 'temp/';
$rcmail_config['message_cache_lifetime'] = '10d';
* replace database properties (db_type, db_host, db_user, db_pass, $d_name)
in /config/db.inc.php with the following line:
$rcmail_config['db_dsnw'] = 'mysql://roundcube:pass@localhost/roundcubemail';
* add these lines to /config/db.inc.php
$rcmail_config['db_max_length'] = 512000;

@ -35,7 +35,7 @@ require_once('lib/mime.inc');
*
* @package RoundCube Webmail
* @author Thomas Bruederli <roundcube@gmail.com>
* @version 1.31
* @version 1.34
* @link http://ilohamail.org
*/
class rcube_imap
@ -132,11 +132,10 @@ class rcube_imap
'message' => $GLOBALS['iil_error']), TRUE, FALSE);
}
// get account namespace
// get server properties
if ($this->conn)
{
$this->_parse_capability($this->conn->capability);
iil_C_NameSpace($this->conn);
if (!empty($this->conn->delimiter))
$this->delimiter = $this->conn->delimiter;
@ -883,15 +882,19 @@ class rcube_imap
$uid = $is_uid ? $id : $this->_id2uid($id);
// get cached headers
if ($uid && ($headers = $this->get_cached_message($mailbox.'.msg', $uid)))
if ($uid && ($headers = &$this->get_cached_message($mailbox.'.msg', $uid)))
return $headers;
$msg_id = $is_uid ? $this->_uid2id($id) : $id;
$headers = iil_C_FetchHeader($this->conn, $mailbox, $msg_id);
$headers = iil_C_FetchHeader($this->conn, $mailbox, $id, $is_uid);
// write headers cache
if ($headers)
$this->add_message_cache($mailbox.'.msg', $msg_id, $headers);
{
if ($is_uid)
$this->uid_id_map[$mbox_name][$uid] = $headers->id;
$this->add_message_cache($mailbox.'.msg', $headers->id, $headers);
}
return $headers;
}
@ -906,6 +909,14 @@ class rcube_imap
*/
function &get_structure($uid)
{
$cache_key = $this->mailbox.'.msg';
$headers = &$this->get_cached_message($cache_key, $uid, true);
// return cached message structure
if (is_object($headers) && is_object($headers->structure))
return $headers->structure;
// resolve message sequence number
if (!($msg_id = $this->_uid2id($uid)))
return FALSE;
@ -929,6 +940,10 @@ class rcube_imap
$struct->mimetype = strtolower($struct->headers['ctype']);
list($struct->ctype_primary, $struct->ctype_secondary) = explode('/', $struct->mimetype);
}
// write structure to cache
if ($this->caching_enabled)
$this->add_message_cache($cache_key, $msg_id, $headers, $struct);
}
return $struct;
@ -1109,8 +1124,14 @@ class rcube_imap
$body = $this->mime_decode($body, $o_part->encoding);
// convert charset (if text or message part)
if (!empty($o_part->charset) && ($o_part->ctype_primary=='text' || $o_part->ctype_primary=='message') && !stristr($body, 'charset='))
if ($o_part->ctype_primary=='text' || $o_part->ctype_primary=='message')
{
// assume ISO-8859-1 if no charset specified
if (empty($o_part->charset))
$o_part->charset = 'ISO-8859-1';
$body = rcube_charset_convert($body, $o_part->charset);
}
}
return $body;
@ -1533,6 +1554,14 @@ class rcube_imap
// make absolute path
$mailbox = $this->_mod_mailbox($mbox_name);
$abs_name = $this->_mod_mailbox($name);
// check if mailbox is subscribed
$a_subscribed = $this->_list_mailboxes();
$subscribed = in_array($mailbox, $a_subscribed);
// unsubscribe folder
if ($subscribed)
iil_C_UnSubscribe($this->conn, $mailbox);
if (strlen($abs_name))
$result = iil_C_RenameFolder($this->conn, $mailbox, $abs_name);
@ -1541,11 +1570,12 @@ class rcube_imap
if ($result)
{
$this->clear_message_cache($mailbox.'.msg');
$this->clear_cache('mailboxes');
$this->clear_cache('mailboxes');
}
// try to subscribe it
$this->subscribe($name);
if ($result && $subscribed)
iil_C_Subscribe($this->conn, $abs_name);
return $result ? $name : FALSE;
}
@ -1842,18 +1872,16 @@ class rcube_imap
}
function &get_cached_message($key, $uid, $body=FALSE)
function &get_cached_message($key, $uid, $struct=false)
{
if (!$this->caching_enabled)
return FALSE;
$internal_key = '__single_msg';
if ($this->caching_enabled && (!isset($this->cache[$internal_key][$uid]) || $body))
if ($this->caching_enabled && (!isset($this->cache[$internal_key][$uid]) ||
($struct && empty($this->cache[$internal_key][$uid]->structure))))
{
$sql_select = "idx, uid, headers";
if ($body)
$sql_select .= ", body";
$sql_select = "idx, uid, headers" . ($struct ? ", structure" : '');
$sql_result = $this->db->query(
"SELECT $sql_select
FROM ".get_table_name('messages')."
@ -1863,14 +1891,12 @@ class rcube_imap
$_SESSION['user_id'],
$key,
$uid);
if ($sql_arr = $this->db->fetch_assoc($sql_result))
{
$headers = unserialize($sql_arr['headers']);
if (is_object($headers) && !empty($sql_arr['body']))
$headers->body = $sql_arr['body'];
$this->cache[$internal_key][$uid] = $headers;
$this->cache[$internal_key][$uid] = unserialize($sql_arr['headers']);
if (is_object($this->cache[$internal_key][$uid]) && !empty($sql_arr['structure']))
$this->cache[$internal_key][$uid]->structure = unserialize($sql_arr['structure']);
}
}
@ -1906,25 +1932,55 @@ class rcube_imap
}
function add_message_cache($key, $index, $headers)
function add_message_cache($key, $index, $headers, $struct=null)
{
if (!$key || !is_object($headers) || empty($headers->uid))
if (empty($key) || !is_object($headers) || empty($headers->uid))
return;
// check for an existing record (probly headers are cached but structure not)
$sql_result = $this->db->query(
"SELECT message_id
FROM ".get_table_name('messages')."
WHERE user_id=?
AND cache_key=?
AND uid=?
AND del<>1",
$_SESSION['user_id'],
$key,
$headers->uid);
$this->db->query(
"INSERT INTO ".get_table_name('messages')."
(user_id, del, cache_key, created, idx, uid, subject, ".$this->db->quoteIdentifier('from').", ".$this->db->quoteIdentifier('to').", cc, date, size, headers)
VALUES (?, 0, ?, now(), ?, ?, ?, ?, ?, ?, ".$this->db->fromunixtime($headers->timestamp).", ?, ?)",
$_SESSION['user_id'],
$key,
$index,
$headers->uid,
(string)substr($this->decode_header($headers->subject, TRUE), 0, 128),
(string)substr($this->decode_header($headers->from, TRUE), 0, 128),
(string)substr($this->decode_header($headers->to, TRUE), 0, 128),
(string)substr($this->decode_header($headers->cc, TRUE), 0, 128),
(int)$headers->size,
serialize($headers));
// update cache record
if ($sql_arr = $this->db->fetch_assoc($sql_result))
{
$this->db->query(
"UPDATE ".get_table_name('messages')."
SET idx=?, headers=?, structure=?
WHERE message_id=?",
$index,
serialize($headers),
is_object($struct) ? serialize($struct) : NULL,
$sql_arr['message_id']
);
}
else // insert new record
{
$this->db->query(
"INSERT INTO ".get_table_name('messages')."
(user_id, del, cache_key, created, idx, uid, subject, ".$this->db->quoteIdentifier('from').", ".$this->db->quoteIdentifier('to').", cc, date, size, headers, structure)
VALUES (?, 0, ?, now(), ?, ?, ?, ?, ?, ?, ".$this->db->fromunixtime($headers->timestamp).", ?, ?, ?)",
$_SESSION['user_id'],
$key,
$index,
$headers->uid,
(string)substr($this->decode_header($headers->subject, TRUE), 0, 128),
(string)substr($this->decode_header($headers->from, TRUE), 0, 128),
(string)substr($this->decode_header($headers->to, TRUE), 0, 128),
(string)substr($this->decode_header($headers->cc, TRUE), 0, 128),
(int)$headers->size,
serialize($headers),
is_object($struct) ? serialize($struct) : NULL
);
}
}

@ -46,6 +46,7 @@
- Casting date parts in iil_StrToTime() to avoid mktime() warnings
- Also acceppt LIST responses in iil_C_ListSubscribed()
- Sanity check of $message_set in iil_C_FetchHeaders(), iil_C_FetchHeaderIndex(), iil_C_FetchThreadHeaders()
- Implemented UID FETCH in iil_C_FetchHeaders()
- Removed some debuggers (echo ...)
********************************************************/
@ -1195,7 +1196,7 @@ function iil_IndexThreads(&$tree){
return $t_index;
}
function iil_C_FetchHeaders(&$conn, $mailbox, $message_set){
function iil_C_FetchHeaders(&$conn, $mailbox, $message_set, $uidfetch=false){
global $IMAP_USE_INTERNAL_DATE;
$c=0;
@ -1231,7 +1232,8 @@ function iil_C_FetchHeaders(&$conn, $mailbox, $message_set){
/* FETCH date,from,subject headers */
$key="fh".($c++);
$request=$key." FETCH $message_set (BODY.PEEK[HEADER.FIELDS (DATE FROM TO SUBJECT REPLY-TO IN-REPLY-TO CC BCC CONTENT-TRANSFER-ENCODING CONTENT-TYPE MESSAGE-ID REFERENCE)])\r\n";
$prefix=$uidfetch?" UID":"";
$request=$key.$prefix." FETCH $message_set (BODY.PEEK[HEADER.FIELDS (DATE FROM TO SUBJECT REPLY-TO IN-REPLY-TO CC BCC CONTENT-TRANSFER-ENCODING CONTENT-TYPE MESSAGE-ID REFERENCE)])\r\n";
if (!fputs($fp, $request)) return false;
do{
@ -1309,7 +1311,7 @@ function iil_C_FetchHeaders(&$conn, $mailbox, $message_set){
Sample reply line: "* 3 FETCH (UID 2417 RFC822.SIZE 2730 FLAGS (\Seen \Deleted))"
*/
$command_key="fh".($c++);
$request= $command_key." FETCH $message_set (UID RFC822.SIZE FLAGS INTERNALDATE)\r\n";
$request= $command_key.$prefix." FETCH $message_set (UID RFC822.SIZE FLAGS INTERNALDATE)\r\n";
if (!fputs($fp, $request)) return false;
do{
$line=chop(iil_ReadLine($fp, 200));
@ -1401,10 +1403,10 @@ function iil_C_FetchHeaders(&$conn, $mailbox, $message_set){
}
function iil_C_FetchHeader(&$conn, $mailbox, $id){
function iil_C_FetchHeader(&$conn, $mailbox, $id, $uidfetch=false){
$fp = $conn->fp;
$a=iil_C_FetchHeaders($conn, $mailbox, $id);
if (is_array($a)) return $a[$id];
$a=iil_C_FetchHeaders($conn, $mailbox, $id, $uidfetch);
if (is_array($a)) return array_shift($a);
else return false;
}

@ -671,6 +671,9 @@ function rcmail_print_body($part, $safe=FALSE, $plain=FALSE)
// text/html
if ($part->ctype_secondary=='html')
{
// remove charset specification in HTML message
$body = preg_replace('/charset=[a-z0-9\-]+/i', '', $body);
if (!$safe) // remove remote images and scripts
{
$remote_patterns = array('/(src|background)=(["\']?)([hftps]{3,5}:\/{2}[^"\'\s]+)(\2|\s|>)/Ui',
@ -1247,94 +1250,6 @@ function rcmail_first_text_part($message_struct)
}
// get source code of a specific message and cache it
// deprecated
function rcmail_message_source($uid)
{
global $IMAP, $DB, $CONFIG;
// get message ID if uid is given
$cache_key = $IMAP->mailbox.'.msg';
$cached = $IMAP->get_cached_message($cache_key, $uid, FALSE);
// message is cached in database
if ($cached && !empty($cached->body))
return $cached->body;
if (!$cached)
$headers = $IMAP->get_headers($uid);
else
$headers = &$cached;
// create unique identifier based on message_id
if (!empty($headers->messageID))
$message_id = md5($headers->messageID);
else
$message_id = md5($headers->uid.'@'.$_SESSION['imap_host']);
$temp_dir = $CONFIG['temp_dir'].(!eregi('\/$', $CONFIG['temp_dir']) ? '/' : '');
$cache_dir = $temp_dir.$_SESSION['client_id'];
$cache_path = $cache_dir.'/'.$message_id;
// message is cached in temp dir
if ($CONFIG['enable_caching'] && is_dir($cache_dir) && is_file($cache_path))
{
if ($fp = fopen($cache_path, 'r'))
{
$msg_source = fread($fp, filesize($cache_path));
fclose($fp);
return $msg_source;
}
}
// get message from server
$msg_source = $IMAP->get_raw_body($uid);
// return message source without caching
if (!$CONFIG['enable_caching'])
return $msg_source;
// let's cache the message body within the database
if ($cached && ($CONFIG['db_max_length'] -300) > $headers->size)
{
$DB->query("UPDATE ".get_table_name('messages')."
SET body=?
WHERE user_id=?
AND cache_key=?
AND uid=?",
$msg_source,
$_SESSION['user_id'],
$cache_key,
$uid);
return $msg_source;
}
// create dir for caching
if (!is_dir($cache_dir))
$dir = mkdir($cache_dir);
else
$dir = true;
// attempt to write a file with the message body
if ($dir && ($fp = fopen($cache_path, 'w')))
{
fwrite($fp, $msg_source);
fclose($fp);
}
else
{
raise_error(array('code' => 403, 'type' => 'php', 'line' => __LINE__, 'file' => __FILE__,
'message' => "Failed to write to temp dir"), TRUE, FALSE);
}
return $msg_source;
}
// decode address string and re-format it as HTML links
function rcmail_address_string($input, $max=NULL, $addicon=NULL)
{
@ -1412,7 +1327,7 @@ function rcmail_message_part_controls()
{
$out .= sprintf('<tr><td class="title">%s</td><td>%s</td><td>[<a href="./?%s">%s</a>]</tr>'."\n",
rcube_label('filename'),
rep_specialchars_output($filename),
rep_specialchars_output(rcube_imap::decode_mime_string($filename)),
str_replace('_frame=', '_download=', $_SERVER['QUERY_STRING']),
rcube_label('download'));
}

@ -69,12 +69,12 @@ else if ($pid = get_input_value('_part', RCUBE_INPUT_GET))
// send download headers
header("Content-Type: application/octet-stream");
header(sprintf('Content-Disposition: attachment; filename="%s"',
$filename ? $filename : "roundcube.$ctype_secondary"));
$filename ? rcube_imap::decode_mime_string($filename) : "roundcube.$ctype_secondary"));
}
else
{
header("Content-Type: $mimetype");
header(sprintf('Content-Disposition: inline; filename="%s"', $filename));
header(sprintf('Content-Disposition: inline; filename="%s"', rcube_imap::decode_mime_string($filename)));
}
// We need to set the following headers to make downloads work using IE in HTTPS mode.
@ -89,14 +89,15 @@ else if ($pid = get_input_value('_part', RCUBE_INPUT_GET))
{
// get part body if not available
if (!$part->body)
$part->body = $IMAP->get_message_part($MESSAGE['UID'], $part->mime_id, $part);
$part->body = $IMAP->get_message_part($MESSAGE['UID'], $part->mime_id, $part);
list($MESSAGE['parts']) = rcmail_parse_message($part,
array('safe' => (bool)$_GET['_safe'],
'prefer_html' => TRUE,
'get_url' => $GET_URL.'&_part=%s'));
print rcmail_print_body($MESSAGE['parts'][0], (bool)$_GET['_safe']);
$OUTPUT = new rcube_html_page();
$OUTPUT->write(rcmail_print_body($MESSAGE['parts'][0], (bool)$_GET['_safe']));
}
else
{

Loading…
Cancel
Save