Index: program/include/rcmail.php =================================================================== --- program/include/rcmail.php (revision 6138) +++ program/include/rcmail.php (working copy) @@ -550,7 +550,7 @@ $this->output->set_charset(RCMAIL_CHARSET); // add some basic labels to client - $this->output->add_label('loading', 'servererror'); + $this->output->add_label('loading', 'servererror', 'requesttimedout'); return $this->output; } @@ -735,7 +735,7 @@ $this->session->set_keep_alive($keep_alive); } - $this->session->set_secret($this->config->get('des_key') . $_SERVER['HTTP_USER_AGENT']); + $this->session->set_secret($this->config->get('des_key') . dirname($_SERVER['SCRIPT_NAME'])); $this->session->set_ip_check($this->config->get('ip_check')); } Index: program/include/rcube_session.php =================================================================== --- program/include/rcube_session.php (revision 6138) +++ program/include/rcube_session.php (working copy) @@ -40,7 +40,6 @@ private $vars = false; private $key; private $now; - private $prev; private $secret = ''; private $ip_check = false; private $logging = false; @@ -520,7 +519,6 @@ // valid time range is now - 1/2 lifetime to now + 1/2 lifetime $now = time(); $this->now = $now - ($now % ($this->lifetime / 2)); - $this->prev = $this->now - ($this->lifetime / 2); } /** @@ -591,16 +589,23 @@ $this->log("IP check failed for " . $this->key . "; expected " . $this->ip . "; got " . $_SERVER['REMOTE_ADDR']); if ($result && $this->_mkcookie($this->now) != $this->cookie) { - // Check if using id from previous time slot - if ($this->_mkcookie($this->prev) == $this->cookie) { - $this->set_auth_cookie(); + $this->log("Session auth check failed for " . $this->key . "; timeslot = " . date('Y-m-d H:i:s', $this->now)); + $result = false; + + // Check if using id from a previous time slot + for ($i = 1; $i <= 2; $i++) { + $prev = $this->now - ($this->lifetime / 2) * $i; + if ($this->_mkcookie($prev) == $this->cookie) { + $this->log("Send new auth cookie for " . $this->key . ": " . $this->cookie); + $this->set_auth_cookie(); + $result = true; + } } - else { - $result = false; - $this->log("Session authentication failed for " . $this->key . "; invalid auth cookie sent"); - } - } + } + if (!$result) + $this->log("Session authentication failed for " . $this->key . "; invalid auth cookie sent; timeslot = " . date('Y-m-d H:i:s', $prev)); + return $result; } Index: program/localization/en_US/messages.inc =================================================================== --- program/localization/en_US/messages.inc (revision 6138) +++ program/localization/en_US/messages.inc (working copy) @@ -25,6 +25,7 @@ $messages['servererror'] = 'Server Error!'; $messages['servererrormsg'] = 'Server Error: $msg'; $messages['dberror'] = 'Database Error!'; +$messages['requesttimedout'] = 'Request timed out'; $messages['errorreadonly'] = 'Unable to perform operation. Folder is read-only.'; $messages['errornoperm'] = 'Unable to perform operation. Permission denied.'; $messages['invalidrequest'] = 'Invalid request! No data was saved.'; Index: program/js/app.js =================================================================== --- program/js/app.js (revision 6138) +++ program/js/app.js (working copy) @@ -50,9 +50,10 @@ // set jQuery ajax options $.ajaxSetup({ - cache:false, - error:function(request, status, err){ ref.http_error(request, status, err); }, - beforeSend:function(xmlhttp){ xmlhttp.setRequestHeader('X-Roundcube-Request', ref.env.request_token); } + cache: false, + timeout: this.env.request_timeout * 1000, + error: function(request, status, err){ ref.http_error(request, status, err); }, + beforeSend: function(xmlhttp){ xmlhttp.setRequestHeader('X-Roundcube-Request', ref.env.request_token); } }); // set environment variable(s) @@ -926,8 +927,6 @@ form.action = this.add_url(form.action, '_lang', lang); form.submit(); - // clear timeout (sending could take longer) - clearTimeout(this.request_timer); break; case 'send-attachment': @@ -1120,14 +1119,6 @@ if (this.gui_objects.editform) this.lock_form(this.gui_objects.editform, a); - // clear pending timer - if (this.request_timer) - clearTimeout(this.request_timer); - - // set timer for requests - if (a && this.env.request_timeout) - this.request_timer = setTimeout(function(){ ref.request_timed_out(); }, this.env.request_timeout * 1000); - return id; }; @@ -1166,13 +1157,6 @@ return url.replace(/_task=[a-z]+/, '_task='+task); }; - // called when a request timed out - this.request_timed_out = function() - { - this.set_busy(false); - this.display_message('Request timed out!', 'error'); - }; - this.reload = function(delay) { if (this.is_framed()) @@ -5867,7 +5851,7 @@ return $.ajax({ type: 'GET', url: url, data: { _unlock:(lock?lock:0) }, dataType: 'json', success: function(data){ ref.http_response(data); }, - error: function(o, status, err) { rcmail.http_error(o, status, err, lock); } + error: function(o, status, err) { ref.http_error(o, status, err, lock, action); } }); }; @@ -5899,7 +5883,7 @@ return $.ajax({ type: 'POST', url: url, data: postdata, dataType: 'json', success: function(data){ ref.http_response(data); }, - error: function(o, status, err) { rcmail.http_error(o, status, err, lock); } + error: function(o, status, err) { ref.http_error(o, status, err, lock, action); } }); }; @@ -6031,7 +6015,7 @@ }; // handle HTTP request errors - this.http_error = function(request, status, err, lock) + this.http_error = function(request, status, err, lock, action) { var errmsg = request.statusText; @@ -6040,6 +6024,16 @@ if (request.status && errmsg) this.display_message(this.get_label('servererror') + ' (' + errmsg + ')', 'error'); + else if (status == 'timeout') + this.display_message(this.get_label('requesttimedout'), 'error'); + else if (request.status == 0 && status != 'abort') + this.display_message(this.get_label('servererror') + ' (No connection)', 'error'); + + // re-send keep-alive requests after 30 seconds + if (action == 'keep-alive') + setTimeout(function(){ ref.keep_alive(); }, 30000); + else if (action == 'check-recent') + setTimeout(function(){ ref.check_for_recent(false); }, 30000); }; // post the given form to a hidden iframe