简体   繁体   中英

Nginx prepends response data with post request body content from its' buffer?

For a few days i'm struggling with a strange problem in a laravel application that runs in a docker container on an ubuntu system and uses laravel/rebing-graphql vendor to serve graphql query responses.

So i'm using the GraphiQL interface to send graphql requests to my backend. The result i receive for my request does not only include the valid response, but also the parameters i send along with the post request;

"{\"query\":\"query Users {\\n  users(pagination: {offset: 0, limit: 1}) {\\n    items {\\n      id\\n    }\\n  }\\n}\",\"variables\":null,\"operationName\":\"Users\"}{\"data\":{\"users\":{\"items\":[{\"id\":53}]}}}"

This response does not come with a content-type: application/json but as text/html . It seems like the post request body is prepended to the response data of my API. This results in a JSON parse error on my client. The API data part here itself seems valid.

The most strange thing of this issue is, that it occurs on every second (!) request. So about 50% of my requests are receiving a valid response which does come as json and without any prepended post request body.

I tried to analyse the root cause of this issue and i was not able to find a place in the code where the parameters are echoed as an additional output.

Does an nginx configuration cause a prepending of post request body contents?

During my further investigation, i started to replace the index.php file inside laravels' public directory and created a custom index.php which contains nothing but an exit("test") ; execution . The result was unexpected. I still got my post parameters prepended to the output on every second request:

"{\"query\":\"query Users {\\n  users(pagination: {offset: 0, limit: 1}) {\\n    items {\\n      id\\n    }\\n  }\\n}\",\"variables\":null,\"operationName\":\"Users\"}test"

I'm using a docker image from nginx:alpine and php:7.4-fpm-alpine. The docker container opens a port which gets a proxy from an apache2 server which runs on my root system.

This is my nginx default config:

server {
listen 80;

server_name my-domain.com;
error_log  /var/log/nginx/error.log;
access_log /var/log/nginx/access.log;

root /var/www/html/public;

index index.php index.html;

location / {
    client_max_body_size 100M;

    if ($request_method = 'OPTIONS') {
        add_header Access-Control-Max-Age 1728000;
        add_header Access-Control-Allow-Credentials true;
        add_header Access-Control-Allow-Origin $http_origin;
        add_header Access-Control-Allow-Methods "GET, POST, OPTIONS, PUT, DELETE, HEAD";
        add_header Content-Length 0;
        add_header Content-Type "text/plain; charset=UTF-8";
        add_header Access-Control-Allow-Headers "Origin,X-Requested-With,Content-Type,Accept,X-CSRF-Token,X-XSRF-TOKEN,Authorization";
        return 204;
    }

    try_files $uri $uri/ /index.php?$query_string;
    gzip_static on;
}

location ~ \.php$ {
    client_max_body_size 100M;

    if ($http_origin ~* "^(blob:)?http(s)?://www.my-domain.com(:[0-9]{2,4})?$") {
        add_header Access-Control-Allow-Credentials true;
        add_header Access-Control-Allow-Origin $http_origin;
        add_header Access-Control-Allow-Methods "GET, POST, PUT, DELETE, OPTIONS";
        add_header Access-Control-Allow-Headers "Origin,X-Requested-With,Content-Type,Accept,X-CSRF-Token,X-XSRF-TOKEN,Authorization";
    }

    try_files $uri =404;
    fastcgi_split_path_info ^(.+\.php)(/.+)$;
    fastcgi_pass epapistagephp:9000;
    fastcgi_index index.php;
    include fastcgi_params;
    fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
    fastcgi_param PATH_INFO $fastcgi_path_info;
} 
}

Is there anyone who already experienced this kind of behaviour or do you have a hint on where to start with a further analysation?

Thank you so much in advance!!

Greets Jules

After month of struggling and using work arounds like switching to Apache2 etc... I guess i found a solution.

As described in my original Question, the problem occured after a the nginx server was running for a while already. After a reload of the nginx server the problem disappeared temporarily. With apache2 i did not have this problem. So that way i kind of isolated the issue to nginx itself.

I now tried to disable the request caching of nginx by setting:

proxy_request_buffering off; <===

client_max_body_size 500M;
client_body_buffer_size 500M;

I also raised the buffering size for testing and it works right now. This issue did not seem to be related to Laravel, Graphql or PHP at all. For anyone who may stumble across this topic, i'm going to edit my original question accordingly. I hope this may help someone in the future.

If you use port 9000, you will have this problem. Use port 8000.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM