0

sorry for asking this question, I have got error on Magento 2, in this case I send a simple post request and then magento just printed it out just like this:

unique=9d4a1d6e-7db3-4137-b3ea-6039aafb67df&selected_index=2&form_key=SC2ykvP7FKeWbaYil exception(s): Exception #0 (Exception): Warning: Cannot modify header information - headers already sent by (output started at php://input:1) in /var/www/html/vendor/magento/framework/Stdlib/Cookie/PhpCookieManager.php on line 152

#1 setcookie() called at [vendor/magento/framework/Stdlib/Cookie/PhpCookieManager.php:152]
#2 Magento\\Framework\\Stdlib\\Cookie\\PhpCookieManager->setCookie() called at [vendor/magento/framework/Stdlib/Cookie/PhpCookieManager.php:123]
#3 Magento\\Framework\\Stdlib\\Cookie\\PhpCookieManager->setPublicCookie() called at [vendor/magento/framework/App/PageCache/Version.php:87]
#4 Magento\\Framework\\App\\PageCache\\Version->process() called at [vendor/magento/module-page-cache/Model/App/FrontController/BuiltinPlugin.php:69]
#5 Magento\\PageCache\\Model\\App\\FrontController\\BuiltinPlugin->aroundDispatch() called at [vendor/magento/framework/Interception/Interceptor.php:135]
#6 Magento\\Framework\\App\\FrontController\\Interceptor->Magento\\Framework\\Interception\\{closure}() called at [vendor/magento/framework/Interception/Interceptor.php:153]
#7 Magento\\Framework\\App\\FrontController\\Interceptor->___callPlugins() called at [generated/code/Magento/Framework/App/FrontController/Interceptor.php:23]
#8 Magento\\Framework\\App\\FrontController\\Interceptor->dispatch() called at [vendor/magento/framework/App/Http.php:116]
#9 Magento\\Framework\\App\\Http->launch() called at [generated/code/Magento/Framework/App/Http/Interceptor.php:23]
#10 Magento\\Framework\\App\\Http\\Interceptor->launch() called at [vendor/magento/framework/App/Bootstrap.php:263]
#11 Magento\\Framework\\App\\Bootstrap->run() called at [pub/index.php:29]

As far as i know is the reason why i've got this error that becauase my apps is printing something else before setcookie method called, in this case:

unique=9d4a1d6e-7db3-4137-b3ea-6039aafb67df&selected_index=2&form_key=SC2ykvP7FKeWbaYil

But, i have never print that post data in any controller helper that I have been created and also i have been check it manually from all controller that used by that pages, and if I refresh that pages or press back and resubmit that form, that error message will not shown up and and this error is happened in random way. Does anyone have occured this problem before?

This is my nginx config and as always

upstream fastcgi_backend {
    server phpfpm:9000;
}

server {
    listen 80;
    listen 443;
    server_name XXXXXXXXXXXXXXXX.XXX XXX.XXXXXXXXXXXXXXXX.XXX;

    # create variable
    set $MAGE_ROOT /var/www/html;
    set $MAGE_DEBUG_SHOW_ARGS 1;
    access_log /var/log/nginx/access.log;
    error_log /var/log/nginx/error.log;
    
    include /var/www/html/nginx.conf.sample;

    # Hide PHP headers
    fastcgi_hide_header X-Powered-By;
    fastcgi_hide_header X-CF-Powered-By;

    # access control
    add_header Access-Control-Allow-Origin "*.cloudflare.com www.google-analytics.com *.gstatic.com *.trustedshops.com *.usercentrics.eu *.fontawesome.com *.google.com *.unpkg.com *.mapbox.com *.chimpstatic.com *.typekit.net *.ytimg.com *.services.mozilla.com *.settings.services.mozilla.com *.qiscus.com *.amazonaws.com *.googletagmanager.com";
    
    aws_sign;
    aws_access_key XXXXXXXXXXXXXXXXXXXX;
    aws_key_scope XXXXXXXX/XX-XXXXXXXXX-X/XX/XXXX_XXXXXXX;
    aws_signing_key XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX;
    aws_s3_bucket XXXXXX-XXXXXXXXXXXX;

    location ~* \.(ico|jpg|jpeg|png|gif|svg|js|css|swf|eot|ttf|otf|woff|woff2)$ {
        # Proxying to AWS S3 storage.
        aws_sign;
        aws_endpoint XX-XXXXXXXXX-X.XXXXXXXXX.XXX;
        aws_access_key XXXXXXXXXXXXXXXXXXXX;
        aws_key_scope XXXXXXXX/XX-XXXXXXXXX-X/XX/XXXX_XXXXXXX;
        aws_signing_key XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX;
        aws_s3_bucket XXXXXX-XXXXXXXXXXXX;
        
        resolver 8.8.8.8;
        set $bucket "XXXXXX-XXXXXXXXXXXX";
        proxy_pass https://XXXXXX-XXXXXXXXXXXX.XX.XXXXXXXXX.XXX/$uri;
        proxy_pass_request_body off;
        proxy_pass_request_headers off;
        proxy_intercept_errors on;
        
        proxy_hide_header "x-amz-id-2";
        proxy_hide_header "x-amz-request-id";
        proxy_hide_header "x-amz-storage-class";
        proxy_hide_header "Set-Cookie";
        proxy_ignore_headers "Set-Cookie";
    }
}

And this is my Magento 2 nginx include config:

## Example configuration:
# upstream fastcgi_backend {
#    # use tcp connection
#    # server  127.0.0.1:9000;
#    # or socket
#    server   unix:/var/run/php/php7.4-fpm.sock;
# }
# server {
#    listen 80;
#    server_name mage.dev;
#    set $MAGE_ROOT /var/www/magento2;
#    set $MAGE_DEBUG_SHOW_ARGS 0;
#    include /vagrant/magento2/nginx.conf.sample;
# }
#
## Optional override of deployment mode. We recommend you use the
## command 'bin/magento deploy:mode:set' to switch modes instead.
##
## set $MAGE_MODE default; # or production or developer
##
## If you set MAGE_MODE in server config, you must pass the variable into the
## PHP entry point blocks, which are indicated below. You can pass
## it in using:
##
## fastcgi_param  MAGE_MODE $MAGE_MODE;
##
## In production mode, you should uncomment the 'expires' directive in the /static/ location block

# Modules can be loaded only at the very beginning of the Nginx config file, please move the line below to the main config file
# load_module /etc/nginx/modules/ngx_http_image_filter_module.so;

root $MAGE_ROOT/pub;

index index.php;
autoindex off;
charset UTF-8;
error_page 404 403 = /errors/404.php;
#add_header "X-UA-Compatible" "IE=Edge";


# Deny access to sensitive files
location /.user.ini {
    deny all;
}

# PHP entry point for setup application
location ~* ^/setup($|/) {
    root $MAGE_ROOT;
    location ~ ^/setup/index.php {
        fastcgi_pass   fastcgi_backend;

        fastcgi_param  PHP_FLAG  "session.auto_start=off \n suhosin.session.cryptua=off";
        fastcgi_param  PHP_VALUE "memory_limit=756M \n max_execution_time=600";
        fastcgi_read_timeout 600s;
        fastcgi_connect_timeout 600s;

        fastcgi_index  index.php;
        fastcgi_param  SCRIPT_FILENAME  $document_root$fastcgi_script_name;
        include        fastcgi_params;
    }

    location ~ ^/setup/(?!pub/). {
        deny all;
    }

    location ~ ^/setup/pub/ {
        add_header X-Frame-Options "SAMEORIGIN";
    }
}

# PHP entry point for update application
location ~* ^/update($|/) {
    root $MAGE_ROOT;

    location ~ ^/update/index.php {
        fastcgi_split_path_info ^(/update/index.php)(/.+)$;
        fastcgi_pass   fastcgi_backend;
        fastcgi_index  index.php;
        fastcgi_param  SCRIPT_FILENAME  $document_root$fastcgi_script_name;
        fastcgi_param  PATH_INFO        $fastcgi_path_info;
        include        fastcgi_params;
    }

    # Deny everything but index.php
    location ~ ^/update/(?!pub/). {
        deny all;
    }

    location ~ ^/update/pub/ {
        add_header X-Frame-Options "SAMEORIGIN";
    }
}

location / {
    try_files $uri $uri/ /index.php$is_args$args;
}

location /pub/ {
    location ~ ^/pub/media/(downloadable|customer|import|custom_options|theme_customization/.*\.xml) {
        deny all;
    }
    alias $MAGE_ROOT/pub/;
    add_header X-Frame-Options "SAMEORIGIN";
}

location /static/ {
    # Uncomment the following line in production mode
    # expires max;

    # Remove signature of the static files that is used to overcome the browser cache
    location ~ ^/static/version {
        rewrite ^/static/(version\d*/)?(.*)$ /static/$2 last;
    }

    location ~* \.(ico|jpg|jpeg|png|gif|svg|js|css|swf|eot|ttf|otf|woff|woff2|html|json)$ {
        add_header Cache-Control "public";
        add_header X-Frame-Options "SAMEORIGIN";
        expires +1y;

        if (!-f $request_filename) {
            rewrite ^/static/(version\d*/)?(.*)$ /static.php?resource=$2 last;
        }
    }
    location ~* \.(zip|gz|gzip|bz2|csv|xml)$ {
        add_header Cache-Control "no-store";
        add_header X-Frame-Options "SAMEORIGIN";
        expires    off;

        if (!-f $request_filename) {
           rewrite ^/static/(version\d*/)?(.*)$ /static.php?resource=$2 last;
        }
    }
    if (!-f $request_filename) {
        rewrite ^/static/(version\d*/)?(.*)$ /static.php?resource=$2 last;
    }
    add_header X-Frame-Options "SAMEORIGIN";
}

location /media/ {

## The following section allows to offload image resizing from Magento instance to the Nginx.
## Catalog image URL format should be set accordingly.
## See https://docs.magento.com/user-guide/configuration/general/web.html#url-options
#   location ~* ^/media/catalog/.* {
#
#       # Replace placeholders and uncomment the line below to serve product images from public S3
#       # See examples of S3 authentication at https://github.com/anomalizer/ngx_aws_auth
#       # resolver 8.8.8.8;
#       # proxy_pass https://<bucket-name>.<region-name>.amazonaws.com;
#
#       set $width "-";
#       set $height "-";
#       if ($arg_width != '') {
#           set $width $arg_width;
#       }
#       if ($arg_height != '') {
#           set $height $arg_height;
#       }
#       image_filter resize $width $height;
#       image_filter_jpeg_quality 90;
#   }

    try_files $uri $uri/ /get.php$is_args$args;

    location ~ ^/media/theme_customization/.*\.xml {
        deny all;
    }

    location ~* \.(ico|jpg|jpeg|png|gif|svg|js|css|swf|eot|ttf|otf|woff|woff2)$ {
        add_header Cache-Control "public";
        add_header X-Frame-Options "SAMEORIGIN";
        expires +1y;
        try_files $uri $uri/ /get.php$is_args$args;
    }
    location ~* \.(zip|gz|gzip|bz2|csv|xml)$ {
        add_header Cache-Control "no-store";
        add_header X-Frame-Options "SAMEORIGIN";
        expires    off;
        try_files $uri $uri/ /get.php$is_args$args;
    }
    add_header X-Frame-Options "SAMEORIGIN";
}

location /media/customer/ {
    deny all;
}

location /media/downloadable/ {
    deny all;
}

location /media/import/ {
    deny all;
}

location /media/custom_options/ {
    deny all;
}

location /errors/ {
    location ~* \.xml$ {
        deny all;
    }
}

# PHP entry point for main application
location ~ ^/(index|get|static|errors/report|errors/404|errors/503|health_check)\.php$ {
    try_files $uri =404;
    fastcgi_pass   fastcgi_backend;
    fastcgi_buffers 16 16k;
    fastcgi_buffer_size 32k;

    fastcgi_param  PHP_FLAG  "session.auto_start=off \n suhosin.session.cryptua=off";
    fastcgi_param  PHP_VALUE "memory_limit=756M \n max_execution_time=18000";
    fastcgi_read_timeout 600s;
    fastcgi_connect_timeout 600s;

    fastcgi_index  index.php;
    fastcgi_param  SCRIPT_FILENAME  $document_root$fastcgi_script_name;
    include        fastcgi_params;
}

gzip on;
gzip_disable "msie6";

gzip_comp_level 6;
gzip_min_length 1100;
gzip_buffers 16 8k;
gzip_proxied any;
gzip_types
    text/plain
    text/css
    text/js
    text/xml
    text/javascript
    application/javascript
    application/x-javascript
    application/json
    application/xml
    application/xml+rss
    image/svg+xml;
gzip_vary on;

# Banned locations (only reached if the earlier PHP entry point regexes don't match)
location ~* (\.php$|\.phtml$|\.htaccess$|\.git) {
    deny all;
}

Anyway, i have my own temporary fix using this simple script in magento 2 vendor file vendor/magento/framework/Stdlib/Cookie/PhpCookieManager.php:

<?php
/**
 * Copyright © Magento, Inc. All rights reserved.
 * See COPYING.txt for license details.
 */
declare(strict_types=1);

namespace Magento\Framework\Stdlib\Cookie;

use Magento\Framework\App\ObjectManager;
use Magento\Framework\Exception\InputException;
use Magento\Framework\Stdlib\CookieManagerInterface;
use Magento\Framework\Phrase;
use Magento\Framework\HTTP\Header as HttpHeader;
use Psr\Log\LoggerInterface;

/**
 * CookieManager helps manage the setting, retrieving and deleting of cookies.
 *
 * To aid in security, the cookie manager will make it possible for the application to indicate if the cookie contains
 * sensitive data so that extra protection can be added to the contents of the cookie as well as how the browser
 * stores the cookie.
 *
 * @SuppressWarnings(PHPMD.CouplingBetweenObjects)
 * @SuppressWarnings(PHPMD.CookieAndSessionMisuse)
 */
class PhpCookieManager implements CookieManagerInterface
{
    ...
    
    /**
     * Set a value in a cookie with the given $name $value pairing.
     *
     * @param string $name
     * @param string $value
     * @param array $metadataArray
     * @return void
     * @throws FailureToSendException If cookie couldn't be sent to the browser.
     * @throws CookieSizeLimitReachedException Thrown when the cookie is too big to store any additional data.
     * @throws InputException If the cookie name is empty or contains invalid characters.
     */
    protected function setCookie($name, $value, array $metadataArray)
    {
        $expire = $this->computeExpirationTime($metadataArray);
        $this->checkAbilityToSendCookie($name, $value);
        
        try {
            $phpSetcookieSuccess = setcookie($name, $value, [
                'expires' => $expire,
                'path' => $this->extractValue(CookieMetadata::KEY_PATH, $metadataArray, ''),
                'domain' => $this->extractValue(CookieMetadata::KEY_DOMAIN, $metadataArray, ''),
                'secure' => $this->extractValue(CookieMetadata::KEY_SECURE, $metadataArray, false),
                'httponly' => $this->extractValue(CookieMetadata::KEY_HTTP_ONLY, $metadataArray, false),
                'samesite' => $this->extractValue(CookieMetadata::KEY_SAME_SITE, $metadataArray, 'Lax')
            ]);
            
            if (!$phpSetcookieSuccess) {
                $params['name'] = $name;
                if ($value == '') {
                    throw new FailureToSendException(
                        new Phrase('The cookie with "%name" cookieName couldn\'t be deleted.', $params)
                    );
                } else {
                    throw new FailureToSendException(
                        new Phrase('The cookie with "%name" cookieName couldn\'t be sent. Please try again later.', $params)
                    );
                }
            }
        }  catch(\Exception $e){
            ?>
                <script type='text/javascript'>
                  document.getElementsByTagName("body")[0].innerHTML = ""
                  history.go(-1);
                </script>
            <?php
            exit();
        }
    }
    
    ...
}

Thanks for helping me out, and sorry for my bad english :)

  • _"output started at php://input:1"_... well that's not very helpful (not your fault). I'd take this to the [product support channel](https://github.com/magento/magento2/issues) – Phil Mar 14 '22 at 05:05

0 Answers0