Index: trunk/lib/App.inc.php
===================================================================
--- trunk/lib/App.inc.php	(revision 734)
+++ trunk/lib/App.inc.php	(revision 735)
@@ -962,7 +962,11 @@
         }
 
-        // Make sure to log in the system's locale.
+        // Use the system's locale for log messages (return to previous setting below).
         $locale = setlocale(LC_TIME, 0);
         setlocale(LC_TIME, 'C');
+
+        // Logs should always be in UTC (return to previous setting below).
+        $tz = date_default_timezone_get();
+        date_default_timezone_set('UTC');
 
         // Data to be stored for a log event.
@@ -1017,4 +1021,7 @@
         // Restore original locale.
         setlocale(LC_TIME, $locale);
+
+        // Restore original timezone.
+        date_default_timezone_set($tz);
 
         return true;
Index: trunk/lib/Auth_SQL.inc.php
===================================================================
--- trunk/lib/Auth_SQL.inc.php	(revision 734)
+++ trunk/lib/Auth_SQL.inc.php	(revision 735)
@@ -728,5 +728,5 @@
                     // Only raise message if last session is less than 12 hours old.
                     // Notify user why they were logged out if they haven't yet been given a reason.
-                    $user_notified || $app->raiseMsg(sprintf(_("For your security we logged you out after being idle for %s. Please log in again."), humanTime($this->_params['idle_timeout'], 'hour', '%01.0f')), MSG_NOTICE, __FILE__, __LINE__);
+                    $user_notified || $app->raiseMsg(sprintf(_("For your security, we logged you out after being idle for %s. Please log in again."), humanTime($this->_params['idle_timeout'], 'hour', '%01.0f')), MSG_NOTICE, __FILE__, __LINE__);
                     $user_notified = true;
                 }
@@ -740,5 +740,5 @@
                     $expire_reasons[] = sprintf('remote_ip not matched (%s != %s)', $_SESSION['_auth_sql'][$this->_ns]['remote_ip'], getRemoteAddr());
                     // Notify user why they were logged out if they haven't yet been given a reason.
-                    $user_notified || $app->raiseMsg(sprintf(_("For your security we logged you out because your IP address has changed. Please log in again."), null), MSG_NOTICE, __FILE__, __LINE__);
+                    $user_notified || $app->raiseMsg(sprintf(_("For your security, we logged you out because your IP address changed. Please log in again."), null), MSG_NOTICE, __FILE__, __LINE__);
                     $user_notified = true;
                 } else {
Index: trunk/lib/Email.inc.php
===================================================================
--- trunk/lib/Email.inc.php	(revision 734)
+++ trunk/lib/Email.inc.php	(revision 735)
@@ -112,9 +112,9 @@
         . '((?:[^.<>\s@",\[\]]+[^<>\s@",\[\]])*[^.<>\s@",\[\]]+)'       // Local-part
         . '@'                                                           // @
-        . '((?:(\[)|[A-Z0-9]?)'                                         // Domain, first char
+        . '((?:(\[)|[a-z0-9]?)'                                         // Domain, first char
         . '(?(4)'                                                       // Domain conditional for if first domain char is [
         . '(?:[0-9]{1,3}\.){3}[0-9]{1,3}\]'                             // TRUE, matches IP address
         . '|'
-        . '[.-]?(?:[A-Z0-9]+[-.])*(?:[A-Z0-9]+\.)+[A-Z]{2,6}))'         // FALSE, matches domain name
+        . '[.-]?(?:[a-z0-9]+[-.])*(?:[a-z0-9]+\.)+[a-z]{2,19}))'        // FALSE, matches domain name
         . '(?(1)'                                                       // Comment conditional for if initial < exists
         . '(?:\s*>\s*|>\s+\([^,@]+\)\s*)'                               // TRUE, ensure ending >
@@ -398,5 +398,5 @@
             $envelope_sender_address = sprintf('<%s>', trim($this->_params['envelope_sender_address'], '<>'));
         } else {
-            $envelope_sender_address = preg_replace('/^.*<?([^\s@\[\]<>()]+\@[A-Za-z0-9.-]{1,}\.[A-Za-z]{2,5})>?$/iU' . $app->getParam('preg_u'), '$1', $this->_params['from']);
+            $envelope_sender_address = preg_replace('/^.*<?([^\s@\[\]<>()]+\@[A-Za-z0-9.-]{1,}\.[A-Za-z]{2,19})>?$/iU' . $app->getParam('preg_u'), '$1', $this->_params['from']);
         }
         if ('' != $envelope_sender_address && $this->validEmail($envelope_sender_address)) {
Index: trunk/lib/Utilities.inc.php
===================================================================
--- trunk/lib/Utilities.inc.php	(revision 734)
+++ trunk/lib/Utilities.inc.php	(revision 735)
@@ -1519,8 +1519,8 @@
 * @since    02 May 2015 15:10:09
 */
-function httpExists($url)
+function httpExists($url, $timeout=5)
 {
     $ch = curl_init($url);
-    curl_setopt($ch, CURLOPT_TIMEOUT, 5);
+    curl_setopt($ch, CURLOPT_TIMEOUT, $timeout);
     curl_setopt($ch, CURLOPT_IPRESOLVE, CURL_IPRESOLVE_V4);
     curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
@@ -1547,4 +1547,30 @@
     $http_code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
     return preg_match('/^[23]\d\d$/', $http_code);
+}
+
+/*
+* Get a HTTP response header.
+*
+* @access   public
+* @param    string  $url    URL to hit.
+* @param    string  $key    Name of the header to return.
+* @param    array   $valid_response_codes   Array of acceptable HTTP return codes.
+* @return   string  Value of the http header.
+* @author   Quinn Comendant <quinn@strangecode.com>
+* @since    28 Oct 2020 20:00:36
+*/
+function getHttpHeader($url, $key, Array $valid_response_codes=[200])
+{
+    $headers = @get_headers($url, 1);
+
+    if ($headers && preg_match(sprintf('/\b(%s)\b/', join('|', $valid_response_codes)), $headers[0])) {
+        $headers = array_change_key_case($headers, CASE_LOWER);
+        $key = strtolower($key);
+        if (isset($headers[$key])) {
+            return $headers[$key];
+        }
+    }
+
+    return false;
 }
 
