summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authoralecpl <alec@alec.pl>2010-10-17 13:17:52 +0000
committeralecpl <alec@alec.pl>2010-10-17 13:17:52 +0000
commitd8335117e27e9a81caa5f655b2c6357960849418 (patch)
treed00348167757e8460f00b93904a96119f573eff3
parentbde4219e0d0dc545a92e0c4689edb4a829596522 (diff)
- Add LITERAL+ support (RFC2088)
-rw-r--r--CHANGELOG1
-rw-r--r--program/include/rcube_imap_generic.php68
2 files changed, 48 insertions, 21 deletions
diff --git a/CHANGELOG b/CHANGELOG
index 19290c7ff..037eec5a1 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -30,6 +30,7 @@ CHANGELOG Roundcube Webmail
- Improve displaying of UI messages (#1486977)
- Fix double e-mail filed in identity form (#1487054)
- Display IMAP errors for LIST/THREAD/SEARCH commands (#1486905)
+- Add LITERAL+ (IMAP4 non-synchronizing literals) support (RFC2088)
RELEASE 0.4.2
-------------
diff --git a/program/include/rcube_imap_generic.php b/program/include/rcube_imap_generic.php
index ee5638e46..80f25b928 100644
--- a/program/include/rcube_imap_generic.php
+++ b/program/include/rcube_imap_generic.php
@@ -158,15 +158,23 @@ class rcube_imap_generic
if ($parts = preg_split('/(\{[0-9]+\}\r\n)/m', $string, -1, PREG_SPLIT_DELIM_CAPTURE)) {
for ($i=0, $cnt=count($parts); $i<$cnt; $i++) {
if (preg_match('/^\{[0-9]+\}\r\n$/', $parts[$i+1])) {
+ // LITERAL+ support
+ if ($this->prefs['literal+'])
+ $parts[$i+1] = preg_replace('/([0-9]+)/', '\\1+', $parts[$i+1]);
+
$bytes = $this->putLine($parts[$i].$parts[$i+1], false);
if ($bytes === false)
return false;
$res += $bytes;
- $line = $this->readLine(1000);
- // handle error in command
- if ($line[0] != '+')
- return false;
- $i++;
+
+ // don't wait if server supports LITERAL+ capability
+ if (!$this->prefs['literal+']) {
+ $line = $this->readLine(1000);
+ // handle error in command
+ if ($line[0] != '+')
+ return false;
+ }
+ $i++;
}
else {
$bytes = $this->putLine($parts[$i], false);
@@ -348,7 +356,7 @@ class rcube_imap_generic
do {
$line = trim($this->readLine(1024));
if (preg_match('/^\* CAPABILITY (.+)/i', $line, $matches)) {
- $this->capability = explode(' ', strtoupper($matches[1]));
+ $this->parseCapability($matches[1]);
}
} while (!$this->startsWith($line, 'cp01', true));
@@ -413,7 +421,7 @@ class rcube_imap_generic
// re-set capabilities list if untagged CAPABILITY response provided
if (preg_match('/\* CAPABILITY (.+)/i', $untagged, $matches)) {
- $this->capability = explode(' ', strtoupper($matches[1]));
+ $this->parseCapability($matches[1]);
}
// process result
@@ -624,7 +632,7 @@ class rcube_imap_generic
// RFC3501 [7.1] optional CAPABILITY response
if (preg_match('/\[CAPABILITY ([^]]+)\]/i', $line, $matches)) {
- $this->capability = explode(' ', strtoupper($matches[1]));
+ $this->parseCapability($matches[1]);
}
$this->message .= $line;
@@ -1989,15 +1997,19 @@ class rcube_imap_generic
return false;
}
- $request = 'a APPEND "' . $this->escape($folder) .'" (\\Seen) {' . $len . '}';
+ $request = sprintf("a APPEND \"%s\" (\\Seen) {%d%s}", $this->escape($folder),
+ $len, ($this->prefs['literal+'] ? '+' : ''));
if ($this->putLine($request)) {
- $line = $this->readLine(512);
-
- if ($line[0] != '+') {
- $this->parseResult($line, 'APPEND: ');
- return false;
- }
+ // Don't wait when LITERAL+ is supported
+ if (!$this->prefs['literal+']) {
+ $line = $this->readLine(512);
+
+ if ($line[0] != '+') {
+ $this->parseResult($line, 'APPEND: ');
+ return false;
+ }
+ }
if (!$this->putLine($message)) {
return false;
@@ -2045,14 +2057,19 @@ class rcube_imap_generic
}
// send APPEND command
- $request = 'a APPEND "' . $this->escape($folder) . '" (\\Seen) {' . $len . '}';
+ $request = sprintf("a APPEND \"%s\" (\\Seen) {%d%s}", $this->escape($folder),
+ $len, ($this->prefs['literal+'] ? '+' : ''));
+
if ($this->putLine($request)) {
- $line = $this->readLine(512);
+ // Don't wait when LITERAL+ is supported
+ if (!$this->prefs['literal+']) {
+ $line = $this->readLine(512);
- if ($line[0] != '+') {
- $this->parseResult($line, 'APPEND: ');
- return false;
- }
+ if ($line[0] != '+') {
+ $this->parseResult($line, 'APPEND: ');
+ return false;
+ }
+ }
// send headers with body separator
if ($headers) {
@@ -2241,6 +2258,15 @@ class rcube_imap_generic
return $data;
}
+ private function parseCapability($str)
+ {
+ $this->capability = explode(' ', strtoupper($str));
+
+ if (!isset($this->prefs['literal+']) && in_array('LITERAL+', $this->capability)) {
+ $this->prefs['literal+'] = true;
+ }
+ }
+
private function escape($string)
{
return strtr($string, array('"'=>'\\"', '\\' => '\\\\'));