Index: kernel/classes/ezhttpheader.php
===================================================================
--- kernel/classes/ezhttpheader.php	(revision 22649)
+++ kernel/classes/ezhttpheader.php	(working copy)
@@ -65,6 +65,58 @@
     }
 
     /*!
+     *\static
+     * Returns the header for requested url
+     */
+    private static function checkForMatch( $uriString, $paths )
+    {
+        $headerArray = array();
+
+        foreach ( $paths as $path => $value )
+        {
+            if ( strpos( $uriString, $path ) === 0 )
+            {
+                foreach ( $paths[ $path ] as $header )
+                {
+                    $headerName = $header[ 0 ];
+                    $headerValue = $header[ 1 ];
+                    $depth = $header[ 2 ];
+                    $level = $header[ 3 ];
+
+                    if ( $depth == null )
+                    {
+                        $headerArray[ $headerName ] = $headerValue;
+                    }
+                    else
+                    {
+                        // Depth and level support
+                        $pathLevel = count( explode( '/', $path ) );
+                        $uriLevel = count( explode( '/', $uriString ) );
+                        if ( $level === null )
+                        {
+                            if ( $uriLevel <= $pathLevel + $depth )
+                            {
+                                $headerArray[ $headerName ] = $headerValue;
+                            }
+                        }
+                        else
+                        {
+                            if ( $uriLevel <= $pathLevel + $depth &&
+                                 $uriLevel >= $pathLevel + $level )
+                            {
+                                $headerArray[ $headerName ] = $headerValue;
+                            }
+                        }
+                    }
+                }
+                break;
+            }
+        }
+        return $headerArray;
+    }
+
+
+    /*!
      \static
      Get Header override array by requested URI
     */
@@ -76,94 +128,117 @@
         {
             return $headerArray;
         }
-
         $contentView = false;
 
-        $uriString = eZURLAliasML::cleanURL( $uri->uriString() );
+        $uriString = '/' . eZURLAliasML::cleanURL( $uri->uriString() );
 
-        // If content/view used, get url alias for node
-        if ( strpos( $uriString, 'content/view/' ) === 0 )
+        /*
+          1. Read all custom http headers
+          2. Test direct match for System URL
+          3. Fetch URL Alias for System URL (fallback)
+          4. Test URL Alias
+         */
+
+        /* 1. Read all custom http headers. Path will be used as key for easy matching
+         *
+         *    *depth*, and *level* is optional, and is spesifyed in the configuration file.
+         *
+         *    Example:
+         *    $paths = array(
+         *        '/content/view/full/64' => array(
+         *                                         array(
+         *                                                'Cache-Control',
+         *                                                'no-cache, must-revalidate',
+         *                                                 *depth*,
+         *                                                 *level*
+         *                                              ),
+         *                                         array(
+         *                                                'Expiry',
+         *                                                '-200',
+         *                                                *depth*,
+         *                                                *level*
+         *                                              ),
+         *                                        )
+         *    );
+         *
+         */
+
+        $paths = array();
+        $ini = eZINI::instance();
+        foreach( $ini->variable( 'HTTPHeaderSettings', 'HeaderList' ) as $header )
         {
-            $urlParts = explode( '/', $uriString );
-            $nodeID = $urlParts[3];
-            if ( !$nodeID )
+            if ( !$ini->hasVariable( 'HTTPHeaderSettings', $header ) )
             {
-                return $headerArray;
+                continue;
             }
 
-            $node = eZContentObjectTreeNode::fetch( $nodeID );
-            if ( !$node )
+            $currentHeader = array();
+            foreach( $ini->variable( 'HTTPHeaderSettings', $header ) as $path => $value )
             {
-                return $headerArray;
+                $path = '/' . eZURLAliasML::cleanURL( $path );
+                $currentPath = array();
+                if ( array_key_exists( $path, $paths ) )
+                {
+                    $currentPath = $paths[ $path ];
+                }
+                else
+                {
+                    $paths[ $path ] = $currentPath;
+                }
+
+                @list( $headerValue, $depth, $level ) = explode( ';', $value );
+                if ( $header == 'Expires' )
+                {
+                    $headerValue = gmdate( 'D, d M Y H:i:s', time() + $headerValue ) . ' GMT';
+                }
+
+                $currentPath[] = array( $header, $headerValue, $depth, $level );
+                $paths[ $path ] = $currentPath;
+
             }
+        }
+        krsort( $paths );
 
-            $uriString = $node->pathWithNames();
+        // Set content view flag
+        if ( strpos( $uriString, '/content/view/' ) === 0 )
+        {
             $contentView = true;
         }
-        else
+
+        // 2. Test System URL against path defined
+        if ( $contentView )
         {
-            $uriCopy = clone $uri;
-            eZURLAliasML::translate( $uriCopy );
-            if ( strpos( $uriCopy->uriString(), 'content/view' ) === 0 )
+            $headerArray = self::checkForMatch( $uriString, $paths );
+
+            if ( count ( $headerArray ) > 0 )
             {
-                $contentView = true;
+                return $headerArray;
             }
         }
 
-        $uriString = '/' . eZURLAliasML::cleanURL( $uriString );
-        $ini = eZINI::instance();
-
-        foreach( $ini->variable( 'HTTPHeaderSettings', 'HeaderList' ) as $header )
+        // 3. Fetch URL Alias for System URL for fallback
+        if ( $contentView )
         {
-            foreach( $ini->variable( 'HTTPHeaderSettings', $header ) as $path => $value )
+            $urlParts = explode( '/', $uriString );
+            $nodeID = $urlParts[4];
+            if ( !$nodeID )
             {
-                $path = '/' . eZURLAliasML::cleanURL( $path );
-                if ( strlen( $path ) == 1 &&
-                     !$contentView &&
-                     $uriString != '/' )
-                {
-                    continue;
-                }
+                return $headerArray;
+            }
 
-                if ( strpos( $uriString, $path ) === 0 )
-                {
-                    @list( $headerValue, $depth, $level ) = explode( ';', $value );
-
-                    if ( $header == 'Expires' )
-                    {
-                        $headerValue = gmdate( 'D, d M Y H:i:s', time() + $headerValue ) . ' GMT';
-                    }
-
-                    if ( $depth === null )
-                    {
-                        $headerArray[$header] = $headerValue;
-                    }
-                    else
-                    {
-                        $pathLevel = count( explode( '/', $path ) );
-                        $uriLevel = count( explode( '/', $uriString ) );
-                        if ( $level === null )
-                        {
-                            if ( $uriLevel <= $pathLevel + $depth )
-                            {
-                                $headerArray[$header] = $headerValue;
-                            }
-                        }
-                        else
-                        {
-                            if ( $uriLevel <= $pathLevel + $depth &&
-                                 $uriLevel >= $pathLevel + $level )
-                            {
-                                $headerArray[$header] = $headerValue;
-                            }
-                        }
-                    }
-                }
+            $node = eZContentObjectTreeNode::fetch( $nodeID );
+            if ( !$node )
+            {
+                return $headerArray;
             }
+            $uriString = '/' . eZURLAliasML::cleanURL( $node->pathWithNames() );
         }
 
+        // 4. Test URL Alias
+        $headerArray = self::checkForMatch( $uriString, $paths );
         return $headerArray;
     }
+
 }
 
 ?>
Index: index.php
===================================================================
--- index.php	(revision 22649)
+++ index.php	(working copy)
@@ -466,15 +466,6 @@
                                       'Content-language' => $languageCode ) );
 
 
-$headerOverrideArray = eZHTTPHeader::headerOverrideArray( $uri );
-
-$headerList = array_merge( $headerList, $headerOverrideArray );
-
-foreach( $headerList as $key => $value )
-{
-    header( $key . ': ' . $value );
-}
-
 eZSection::initGlobalID();
 
 // Read role settings
@@ -494,7 +485,6 @@
     }
 }
 
-
 // Start the module loop
 while ( $moduleRunRequired )
 {
@@ -969,6 +959,15 @@
     {
         $http->setSessionVariable( "LastAccessedModifyingURI", $currentURI );
     }
+
+    // Apply custom headers
+    $headerOverrideArray = eZHTTPHeader::headerOverrideArray( $uri );
+    $headerList = array_merge( $headerList, $headerOverrideArray );
+    foreach( $headerList as $key => $value )
+    {
+        header( $key . ': ' . $value );
+    }
+
 }
 
 
