413:请求实体太大(client_max_body_size被设置)

我真的不知道还有什么地方可以find答案。 网上的每一个指南或问题说检查client_max_body_size并解决它。

然而,对于我来说,我正在尝试对我自己的服务器上的PHP文件执行大的PUT请求。

我有… client_max_body_size 32M;nginx.conf服务器块中。 我知道这是有效的,因为WordPress的正确的上传大小设置为32MB。

除此之外,我发现我需要检查3个PHPvariables,我不记得它们是什么,但它们都足够远(在几百MB)。

也许我需要做一些缓冲区? 我不知道 :(

我正在使用的脚本是与第三方服务进行通信的代理脚本。 它logging所有的数据输出,这是目前为止的日志..不知道这是否可以暗示一个问题。

我认为下面是服务器正在发送的内容(因为它在日志文件中,并且正在写入STDOUT,所以我假定php代理脚本正在尝试写入它想要发送的头文件)。

当我使用chrome开发工具时,我没有看到Expect: 100-continue 。 难道这有什么关系吗?

编辑:查看PHP源代码后,它似乎是一个有100个继续的“错误”,这是搞砸了代理脚本…所以忽略下面的所有输出。 我想我会把它放在其他地方,以防万一。

 "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 " 

不知道这是否有帮助..但这里是代理脚本。

 <?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("\0")', 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

 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/*; } 

staging.site.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; } } 

php.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; } 

wordpress.conf

 client_max_body_size 32M; 

你可以请追加你的相关nginx-conf?

你知道这个请求是否把它交给了php-locations或者它是否停止@ nginx?

所以你可以通过POST上传,但不能通过PUT? 我会开始调查这个问题。 当你把你的PUT改成POST时会发生什么?

当谷歌searchPUT 413: Request Entity Too Large nginx最引用的build议是你已经做了什么,我不会开始搞客户端_ * _温度 – variables和temp_caching(atm)。