413: Request Entity Too Large (client_max_body_size está definido)

2

Eu realmente não tenho certeza onde mais procurar a resposta. Cada guia ou pergunta on-line diz para verificar client_max_body_size e isso resolve.

Para mim, no entanto, estou tentando fazer uma grande solicitação PUT para um arquivo PHP que está em meu próprio servidor.

Eu tenho ... client_max_body_size 32M; no bloco do servidor nginx.conf. Eu sei que funciona porque o wordpress corretamente tem o tamanho do upload definido para 32MB.

Além disso, descobri que preciso verificar 3 variáveis PHP, não me lembro exatamente o que elas eram, mas elas são grandes o bastante (em centenas de MB).

Talvez eu precise fazer algo com buffers? Eu não tenho ideia: (

O script que estou usando é um script de proxy para se comunicar com o serviço de terceiros. Ele registra todos os seus dados para a saída, e este é o log até agora ... não tenho certeza se isso poderia aludir a um problema.

Acho que isso abaixo é o que o servidor está tentando para enviar (porque está no arquivo de log e está gravando em STDOUT, então presumo que o script do proxy php esteja tentando gravar um arquivo de log de os cabeçalhos que está querendo enviar).

No entanto, quando uso as ferramentas de desenvolvimento do Chrome, não vejo Expect: 100-continue . Isso poderia ter alguma coisa a ver com isso?

Editar: Depois de ver o código fonte do PHP, parece que foi um 'bug' com 100-continue e isso estava bagunçando o script do proxy ... Então ignore toda a saída abaixo. Eu suponho que vou colocá-lo de qualquer maneira apenas no caso de ter outros bits úteis.

"PUT /rest/cart HTTP/1.1"                                                                                                             
"HOST: staging.site.com"                                                                                                              
"CONNECTION: keep-alive"                                                                                                              
"CONTENT-LENGTH: 2695"                                                                                                                
"ACCEPT: application/json, text/javascript, */*; q=0.01"                                                                              
"CACHE-CONTROL: no-cache"                                                                                                             
"ORIGIN: http://staging.site.com"                                                                                                     
"X-REQUESTED-WITH: XMLHttpRequest"                                                                                                    
"USER-AGENT: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_8_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/30.0.1599.37 Safari/537.36    " 
"CONTENT-TYPE: application/json; charset=UTF-8    "                                                                                       
"REFERER: http://staging.site.com/order/    "                                                                                             
"ACCEPT-ENCODING: gzip,deflate,sdch    "                                                                                                  
"ACCEPT-LANGUAGE: en-US,en;q=0.8    "                                                                                                     
"COOKIE: XXX"                                                                                                                           
"Content-Type: application/json; charset=UTF-8    "                                                                                       
"Content-Length: 2695    "                                                                                                                
"X-UC-Forwarded-For: XXX    "                                                                                                  
"Expect: 100-continue    "     

Não tenho certeza se isso ajuda ... mas aqui está o script de proxy.

<?php
// Version 0.7.  08/15/2013
//   Some of the PUT/POST requests were returning back 100 Continues.  That was wrecking havoc with the parser below causing aborted calls.
// Version 0.6.  06/22/2013
//   Headers weren't being handled correctly.  Server http status wasn't being passed along.
//   Headers with multiple values weren't iterated correctly and were being mangled (think multiple 'Set-Cookie')
// Version 0.5.  02/07/2013  Initial Version.

function http_parse_headers($header)
{
    $retVal = array();
    $fields = explode("\r\n", preg_replace('/\x0D\x0A[\x09\x20]+/', ' ', $header));
    foreach ($fields as $field) {
        if (preg_match('/([^:]+): (.+)/m', $field, $match)) {
            $match[1] = preg_replace('/(?<=^|[\x09\x20\x2D])./e', 'strtoupper("
user  www www;
worker_processes  4;
error_log  /var/log/nginx/error.log warn;
pid        /var/run/nginx.pid;

worker_rlimit_nofile  200000;

events {
    worker_connections  32768;
    use                 epoll;
    multi_accept        on;
}

http {

    #auth_basic "Restricted";
    #auth_basic_user_file /home/www/.htpasswd;

    include       /etc/nginx/mime.types;
    default_type  application/octet-stream;

    access_log  off;

    log_format  main '$remote_addr - $remote_user [$time_local] "$request" '
                     '$status $body_bytes_sent "$http_referer" '
                     '"$http_user_agent" "$http_x_forwarded_for"';

    ssl_prefer_server_ciphers  on;
    ssl_session_timeout        10m;
    ssl_session_cache          builtin:1000 shared:SSL:20m;
    ssl_protocols              SSLv3 TLSv1;
    ssl_ciphers                ECDHE-RSA-AES128-SHA256:AES128-GCM-SHA256:RC4:HIGH:!MD5:!aNULL:!EDH;

    sendfile       on;
    tcp_nopush     on;
    tcp_nodelay    on; 
    server_tokens  off;

    gzip               on;
    gzip_http_version  1.0;
    gzip_disable       "msie6";
    gzip_comp_level    1;
    gzip_buffers       16 8k;
    gzip_min_length    256;
    gzip_proxied       any;
    gzip_vary          on;
    gzip_types
      # text/html is always compressed by HttpGzipModule
      text/css
      text/plain
      text/x-component
      application/javascript
      application/json
      application/xml
      application/xhtml+xml
      application/x-font-ttf
      application/x-font-opentype
      application/vnd.ms-fontobject
      image/svg+xml
      image/x-icon;

    include sites-enabled/*;
}
")', strtolower(trim($match[1]))); if (isset($retVal[$match[1]])) { $retVal[$match[1]] = array($retVal[$match[1]], $match[2]); } else { $retVal[$match[1]] = trim($match[2]); } } } return $retVal; } function gzdecode($data) { $g = tempnam('/tmp', 'ff'); @file_put_contents($g, $data); ob_start(); readgzfile($g); $d = ob_get_clean(); unlink($g); return $d; } if (isset($_GET["_url"])) { $path = $_GET["_url"]; // get the url parameter } else { die("UltraCart rest proxy script called incorrectly. _url query parameter is required."); } $path = preg_replace('#[^a-z0-9/]#i', '', $path); // strip off any junk $path = preg_replace('#/+#', '/', $path); // remove duplicate slashes if any if (strncmp($path, '/', 1) != 0) { // if the path doesn't start with a slash, add one. $path = '/' . $path; } $additional_parameters = ''; foreach ($_GET as $k => $v) { if ($k != '_url') { if ($additional_parameters) { $additional_parameters = $additional_parameters . '&' . $k . "=" . urlencode($v); } else { $additional_parameters = $additional_parameters . '?' . $k . "=" . urlencode($v); } } } // the above filtering should remove any malicious attempts, but no worries, UltraCart has some insane firewalls to boot. $server_get_url = "https://secure.ultracart.com" . $path . $additional_parameters; $post_data = file_get_contents('php://input'); foreach ($_SERVER as $i => $val) { if (strpos($i, 'HTTP_') === 0) { if ($i == 'HTTP_X_UC_MERCHANT_ID') { $header[] = "X-UC-Merchant-Id: $val"; } else if ($i == 'HTTP_X_UC_SHOPPING_CART_ID') { $header[] = "X-UC-Shopping-Cart-Id: $val"; } else { $name = str_replace(array('HTTP_', '_'), array('', '-'), $i); $header[] = "$name: $val"; } } } if (isset($_SERVER['CONTENT_TYPE'])) { $content_type = $_SERVER['CONTENT_TYPE']; } else { $content_type = 'application/json'; } $header[] = "Content-Type: " . $content_type; $header[] = "Content-Length: " . strlen($post_data); $header[] = "X-UC-Forwarded-For: " . $_SERVER['REMOTE_ADDR']; $ch = curl_init($server_get_url); curl_setopt($ch, CURLOPT_CUSTOMREQUEST, $_SERVER['REQUEST_METHOD']); curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); curl_setopt($ch, CURLOPT_TIMEOUT, 100); curl_setopt($ch, CURLOPT_HTTPHEADER, $header); curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE); curl_setopt($ch, CURLOPT_VERBOSE, 1); curl_setopt($ch, CURLOPT_HEADER, 1); curl_setopt($ch, CURLOPT_ENCODING, 1); if (strlen($post_data) > 0) { curl_setopt($ch, CURLOPT_POSTFIELDS, $post_data); } $response = curl_exec($ch); //error_log("start response ==========================================="); //error_log("start raw response ==============="); //error_log($response); //error_log("end raw response ==============="); // grab the status code and set the proxy request result to that. $first_line = ''; $beginning_of_real_http_status = 0; // a index marker for the second http status if the server returns 100 Continue (PUTS/POSTS) if (strlen($response) > 0) { $first_line = substr($response, 0, strpos($response, "\n") - 1); $first_line = trim($first_line); // Is the first line an HTTP/1.1 100 Continue? // If so, search for the next empty line and begin there. preg_match("/100\s+Continue/i", $first_line, $output_array); if (count($output_array) > 0) { // we have an HTTP Continue. Skip down to the next status code. if (preg_match('#^\s*$#m', $response, $matches, PREG_OFFSET_CAPTURE)) { $beginning_of_real_http_status = $matches[0][1] + 2; } $real_headers = explode("\n", substr($response, $beginning_of_real_http_status)); $first_line = $real_headers[0]; // $first_line = substr($response, $beginning_of_real_http_status, strpos($response, "\n", $beginning_of_real_http_status) - 1); $first_line = trim($first_line); } //error_log('$first_line:[' . $first_line . ']'); header($first_line); } //error_log('$beginning_of_real_http_status:' . $beginning_of_real_http_status); if (curl_errno($ch)) { print curl_error($ch); } else { $header_size = curl_getinfo($ch, CURLINFO_HEADER_SIZE); $header = substr($response, $beginning_of_real_http_status, $header_size - $beginning_of_real_http_status); $response_headers = http_parse_headers($header); foreach ($response_headers as $header_key => $header_value) { if ($header_key != 'Content-Encoding' && $header_key != 'Vary' && $header_key != 'Connection' && $header_key != 'Transfer-Encoding') { if ($header_key == 'Content-Length' && $header_value == "0") { /* ignore this, it's from an HTTP 1.1 100 Continue and will destroy the result if passed along. */ } else { if (is_array($header_value)) { foreach ($header_value as $val) { //error_log("$header_key: $val"); header("$header_key: $val", false); } } else { //error_log("$header_key: $header_value"); header("$header_key: $header_value", false); } } } } $body = substr($response, $header_size); echo $body; curl_close($ch); } //error_log("end response ==========================================="); ?>

nginx.conf

server {

    listen       80 deferred;
    server_name  staging.site.com;
    root         /var/www/html/site.com;

    index   index.html index.htm index.php;
    charset utf-8;

    access_log /var/log/nginx/site.com-access_log;

    include conf/wordpress.conf;
    include conf/bwp-security.conf;
    include conf/base.conf;
    include conf/php.conf;    

    location / {
      include conf/allowed-ips.conf;    
      try_files $uri $uri/ /index.php?$args;
    }
}

staging.site.conf

location ~ \.php$ {
    try_files $uri =404;
    fastcgi_split_path_info ^(.+\.php)(/.+)$;
    include         fastcgi_params;
    fastcgi_index   index.php;
    fastcgi_param   SCRIPT_FILENAME  $document_root$fastcgi_script_name;
    fastcgi_buffers 32 32k;
    fastcgi_buffer_size 32k;
    fastcgi_intercept_errors off;
    fastcgi_pass   unix:/tmp/php5-fpm.sock;
}

php.conf

client_max_body_size 32M;

wordpress.conf

"PUT /rest/cart HTTP/1.1"                                                                                                             
"HOST: staging.site.com"                                                                                                              
"CONNECTION: keep-alive"                                                                                                              
"CONTENT-LENGTH: 2695"                                                                                                                
"ACCEPT: application/json, text/javascript, */*; q=0.01"                                                                              
"CACHE-CONTROL: no-cache"                                                                                                             
"ORIGIN: http://staging.site.com"                                                                                                     
"X-REQUESTED-WITH: XMLHttpRequest"                                                                                                    
"USER-AGENT: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_8_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/30.0.1599.37 Safari/537.36    " 
"CONTENT-TYPE: application/json; charset=UTF-8    "                                                                                       
"REFERER: http://staging.site.com/order/    "                                                                                             
"ACCEPT-ENCODING: gzip,deflate,sdch    "                                                                                                  
"ACCEPT-LANGUAGE: en-US,en;q=0.8    "                                                                                                     
"COOKIE: XXX"                                                                                                                           
"Content-Type: application/json; charset=UTF-8    "                                                                                       
"Content-Length: 2695    "                                                                                                                
"X-UC-Forwarded-For: XXX    "                                                                                                  
"Expect: 100-continue    "     
    
por Tallboy 17.09.2013 / 08:36

1 resposta

1

você pode por favor anexar o seu nginx-conf relacionado?

você sabe se o pedido é transferido para os locais do php ou está parado @ nginx?

Então você pode fazer o upload via POST, mas não via PUT? Eu começaria a investigar esse problema; O que acontece quando você muda seu PUT para POST?

quando googling PUT 413: Request Entity Too Large nginx o mais referenciado é o que você já fez, e eu não começaria a mexer no cliente _ * _ temp-vars e temp_caching (atm).

    
por 17.09.2013 / 09:28