Duplicate Headers bei Magento 1.1.3

Bei der aktuellen Magento Version gibt es ein Problem wenn PHP als (Fast-)CGI läuft. Da CGI keine doppelten Status- oder Content-Type-Header akzeptiert, steigt der Server in dem Fall mit einem „500 Server Error“ aus.

Der Bug wurde eigentlich [schon längst behoben](http://www.magentocommerce.com/bug-tracking/issue/?issue=1257), aber leider hat der Fix noch nicht seinen Weg in den aktuellen Magento Core gefunden.

Das Problem liegt in der Datei app/code/core/Mage/Core/Controller/Response/Http.php. Dort wurde bereits versucht, diesen Sonderfall abzufangen, doch leider scheint der verantwortliche Programmierer nicht gewusst zu haben, daß dieser Fehler sowohl bei „Status“, „Http“ als auch bei „Content-Type“ auftritt. Dieser Fix behebt folgende Fehler:

* FastCGI: comm with server aborted: error parsing headers: duplicate header ‚Content-Type‘
* FastCGI: comm with server aborted: error parsing headers: duplicate header ‚Status‘
* SOAP-ERROR: Parsing WSDL: Couldn’t load from ‚http://www.magento.com/api/index/index/wsdl/1/‘

Letzterer ist schwer zu entlarven, da intern die wsdl-Datei für die Webservice-Anbindung geladen wird, dabei aber nur o.g. Fehler zurückkommt – dieser ist in Wirklichkeit aber ein Fehler aufgrund eines doppelten Content-Type Headers.

Hier also die komplette Funktion sendHeaders() mit meinem Fix für Status, HTTP und Content-Type Header:


    /**
     * Fixes CGI only one Status + Content Type header allowed bug
     *
     * @link  http://bugs.php.net/bug.php?id=36705
     * @link  http://www.magentocommerce.com/bug-tracking/issue/?issue=1257
     *
     */
    public function sendHeaders()
    {
        if (!$this->canSendHeaders()) {
            Mage::log('HEADERS ALREADY SENT: '.mageDebugBacktrace(true, true, true));
            return $this;
        }

        if (substr(php_sapi_name(), 0, 3) == 'cgi') {
            $statusSent  = FALSE;
            $contentSent = FALSE;
            foreach ($this->_headersRaw as $i=>$header) {
                if (stripos($header, 'status:')===0 || stripos($header, 'http/1.1')===0) {
                    if ($statusSent) {
                        unset($this->_headersRaw[$i]);
                    } else {
                        $statusSent = true;
                    }
                }
                if (stripos($header, 'content-type')===0) {
                    if ($contentSent) {
                        unset($this->_headersRaw[$i]);
                    } else {
                        $contentSent = true;
                    }
                }
            }
            foreach ($this->_headers as $i=>$header) {
                if (strcasecmp($header['name'], 'status')===0 || strcasecmp($header['name'], 'Http/1.1')===0) {
                    if ($statusSent) {
                        unset($this->_headers[$i]);
                    } else {
                        $statusSent = true;
                    }
                }
                if (strcasecmp($header['name'], 'content-type')===0) {
                    if ($contentSent) {
                        unset($this->_headers[$i]);
                    } else {
                        $contentSent = true;
                    }
                }
            }
        }
        parent::sendHeaders();
    }

Ich hoffe das hilft einigen bis der Fix endlich in den Core gewandert ist.

14 Kommentare

  1. Danke vielmals, jetzt gehts.

    Der Fix ist noch immer nicht im Core drinnen. Ich kann nur jedem raten, die Finger von Magento zu lassen. Es gibt so viele Sachen, die nicht gehen und das 2,5 Jahre nach Release 1. Eine Schande für die Jungs.

  2. Hi,

    I had to modify the above code slightly to allow import/export profiles to work.

    Below is the modified section:

            if (strcasecmp($header['name'], 'content-type')===0) {
    
                if ($contentSent || (substr($header['value'], 0, 9) == 'text/html')) {
                    unset($this->_headers[$i]);
                } else {
                    $contentSent = true;
                }
            }
    
  3. Vielen Danke für den Tipp. Das betraf bei mir die Seitenausgabe für 404-Fehler, sowie die Anzeige der Chart-Grafik im Adminbereich! Jetzt wird wieder alles korrekt angezeigt.

  4. This patch works great but after it my header send me data in incorrect encoding, I need to get it in UTF-8 but I get them in ISO-8859-1.
    Adding AddDefaultCharset UTF-8 in htaccess doesn’t help.
    Could you please help me ?

  5. Strange I added

    Mage::app()->getResponse()->setHeader("Content-Type", "text/html; charset=UTF-8",true);

    to function above and it helped me.

    1. Glad to hear that. If your Apache is configured to deliver in UTF-8 that shouldn’t be an issue, but on a shared environment it may be necessary to force UTF-8 through the Header you added.

  6. We sure appreciate this post. This fix is required for Magento Enterprise Full Page Cache to work with cgi. Except in our case, we’re using ‚fpm‘ so we had to make the following adjustment.

    if (substr(php_sapi_name(), 0, 3) == 'fpm')

  7. hier ist eine erweiterte version des fixes – bei mir gabs nach dem einpflegen des „originalen“ fixes die errors bei api-call weiterhin. offenbar wird dort bereits vor dem outputten ein content-type header via header() gesetzt. die erweiterte version prüft daher nicht nur _headers und _headersRaw (auch gegenseitig), sondern ebenfalls die von php bereits gesendeten bzw gebufferten headers.

    http://www.magentocommerce.com/boards/v/viewthread/229253/#t383462

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert