Reduce references header in a smart way to avoid "header too long"
authorkink <kink@7612ce4b-ef26-0410-bec9-ea0150e637f0>
Tue, 18 Apr 2006 16:38:38 +0000 (16:38 +0000)
committerkink <kink@7612ce4b-ef26-0410-bec9-ea0150e637f0>
Tue, 18 Apr 2006 16:38:38 +0000 (16:38 +0000)
errors from SMTP servers in really long threads (#1167754, #1465342).

git-svn-id: https://svn.code.sf.net/p/squirrelmail/code/trunk/squirrelmail@11056 7612ce4b-ef26-0410-bec9-ea0150e637f0

ChangeLog
class/deliver/Deliver.class.php

index 75f96ed..969a8fd 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -33,8 +33,10 @@ Version 1.5.2 - CVS
   - Added system locale tests to configtest.php script.
   - Fixed invalid HTML output that caused error notices in compose.php (#1454409).
   - Introduction of centralised initialization file init.php.
-  - Added session regenrate id functionality to prohibit session hyijacking.
+  - Added session regenrate id functionality to prohibit session hijacking.
   - Fixed sqsession_cookie function for setting HttpOnly cookie attribute.
+  - Reduce references header in a smart way to avoid "header too long"
+    errors from SMTP servers in really long threads (#1167754, #1465342).
 
 Version 1.5.1 (branched on 2006-02-12)
 --------------------------------------
index 78e2c6f..f22b5f8 100644 (file)
@@ -719,27 +719,43 @@ class Deliver {
     }
 
     /**
-     * function calculate_references - calculate correct Referer string
+     * function calculate_references - calculate correct References string
+     * Adds the current message ID, and makes sure it doesn't grow forever,
+     * to that extent it drops message-ID's in a smart way until the string
+     * length is under the recommended value of 1000 ("References: <986>\r\n").
+     * It always keeps the first and the last three ID's.
      *
      * @param   Rfc822Header $hdr    message header to calculate from
      *
-     * @return  string       $refer  concatenated and trimmed Referer string
+     * @return  string       $refer  concatenated and trimmed References string
      */
     function calculate_references($hdr) {
-        $refer = $hdr->references;
+        $aReferences = preg_split('/\s+/', $hdr->references);
         $message_id = $hdr->message_id;
         $in_reply_to = $hdr->in_reply_to;
-        if (strlen($refer) > 2) {
-            $refer .= ' ' . $message_id;
-        } else {
-            if ($in_reply_to) {
-                $refer .= $in_reply_to . ' ' . $message_id;
-            } else {
-                $refer .= $message_id;
-            }
+       
+        // if References already exists, add the current message ID at the end.
+        // no References exists; if we know a IRT, add that aswell
+        if (count($aReferences) == 0 && $in_reply_to) {
+            $aReferences[] = $in_reply_to;
+        }
+        $aReferences[] = $message_id;
+
+        // sanitize the array: trim whitespace, remove dupes
+        array_walk($aReferences, 'trim_value');
+        $aReferences = array_unique($aReferences);
+
+        while ( count($aReferences) > 4 && strlen(implode(' ', $aReferences)) >= 986 ) {
+            $aReferences = array_merge(array_slice($aReferences,0,1),array_slice($aReferences,2));
         }
-        trim($refer);
-        return $refer;
+        return implode(' ', $aReferences);
+    }
+
+    /**
+     * Callback function to trim whitespace from a value, to be used in array_walk
+     */
+    function trim_value ( &$value ) {
+        $value = trim($value);
     }
 
     /**