如何避免nginx“上游发送过大的标题”错误?

时间:2022-02-04 16:55:24

I'm running nginx, Phusion Passenger and Rails.

我正在运行nginx,Phusion Passenger和Rails。

I am running up against the following error:

我正在遇到以下错误:

upstream sent too big header while reading response header from upstream, client: 87.194.2.18, server: xyz.com, request: "POST /user_session HTTP/1.1", upstream: "passenger://unix:/tmp/passenger.3322/master/helper_server.sock

It is occuring on the callback from an authentication call to Facebook Connect.

它是在从Facebook Connect的身份验证调用的回调中发生的。

After googling, and trying to change nginx settings including proxy_buffer_size and large_client_header_buffers is having no effect.

谷歌搜索后,尝试更改包括proxy_buffer_size和large_client_header_buffers在内的nginx设置无效。

How can I debug this?

我该怎么调试呢?

6 个解决方案

#1


31  

Came across this error recently.

最近碰到了这个错误。

Since Passenger 3.0.8 there is now a setting that allows you to set the buffers and buffer size. So now you can do

从Passenger 3.0.8开始,现在有一个设置允许您设置缓冲区和缓冲区大小。所以现在你可以做到

http {
    ...
    passenger_buffers 8 16k;
    passenger_buffer_size 32k;
}

That resolved the issue for me.

这解决了我的问题。

#2


28  

Try to add this to the config:

尝试将其添加到配置中:

http {
    ...
    proxy_buffers 8 16k;
    proxy_buffer_size 32k;
    }

#3


24  

Maybee adding this will make it work, how are you connecting to upstream? http, fastcgi or something else?

也许添加它会使它工作,你如何连接到上游? http,fastcgi还是其他什么?

http {
    ...
    fastcgi_buffers 8 16k;
    fastcgi_buffer_size 32k;
}

#4


6  

fastcgi_buffers 16 16k;
fastcgi_buffer_size 32k;

#5


1  

This is everything I have come to understand about this error in the last 2 years:

这是我在过去两年中对此错误了解的一切:

upstream sent too big header while reading response header from upstream is nginx's generic way of saying "I don't like what I'm seeing"

上游发送太大的标题,而从上游读取响应标题是nginx的通用方式,说“我不喜欢我所看到的”

  1. Your upstream server thread crashed
  2. 您的上游服务器线程崩溃了
  3. The upstream server sent an invalid header back
  4. 上游服务器发回了无效的头
  5. The Notice/Warnings sent back from STDERR broke their buffer and both it and STDOUT were closed
  6. 从STDERR发回的通知/警告打破了他们的缓冲区,它和STDOUT都关闭了

3: Look at the error logs above the message, is it streaming with logged lines preceding the message? PHP message: PHP Notice: Undefined index: Example snippet from a loop my log file:

3:查看消息上方的错误日志,是否在消息之前使用记录的行进行流式处理? PHP消息:PHP注意:未定义的索引:来自循环的示例片段我的日志文件:

2015/11/23 10:30:02 [error] 32451#0: *580927 FastCGI sent in stderr: "PHP message: PHP Notice:  Undefined index: Firstname in /srv/www/classes/data_convert.php on line 1090
PHP message: PHP Notice:  Undefined index: Lastname in /srv/www/classes/data_convert.php on line 1090
... // 20 lines of same
PHP message: PHP Notice:  Undefined index: Firstname in /srv/www/classes/data_convert.php on line 1090
PHP message: PHP Notice:  Undefined index: Lastname in /srv/www/classes/data_convert.php on line 1090
PHP message: PHP Notice:
2015/11/23 10:30:02 [error] 32451#0: *580927 FastCGI sent in stderr: "ta_convert.php on line 1090
PHP message: PHP Notice:  Undefined index: Firstname

you can see in the 3rd line (from the 20 previous errors) the buffer limit was hit, broke, and the next thread wrote in over it. Nginx then closed the connection and returned 502 to the client.

你可以在第3行看到(从之前的20个错误中)缓冲区限制被击中,破坏,并且下一个线程在其中写入。然后Nginx关闭连接并将502返回给客户端。

2: log all the headers sent per request, review them and make sure they conform to standards (nginx does not permit anything older than 24 hours to delete/expire a cookie, sending invalid content length because error messages were buffered before the content counted...)

2:记录每个请求发送的所有标头,检查它们并确保它们符合标准(nginx不允许任何超过24小时的内容删除/过期cookie,发送无效内容长度,因为错误消息在内容计数之前被缓冲。 ..)

examples include:

例子包括:

<?php
//expire cookie
setcookie ( 'bookmark', '', strtotime('2012-01-01 00:00:00') );
// nginx will refuse this header response, too far past to accept
....
?>

and this:

和这个:

<?php
header('Content-type: image/jpg');
?>

<?php   //a space was injected into the output above this line
header('Content-length: ' . filesize('image.jpg') );
echo file_get_contents('image.jpg');
// error! the response is now 1-byte longer than header!!
?>

1: verify, or make a script log, to ensure your thread is reaching the correct end point and not exiting before completion.

1:验证或制作脚本日志,以确保您的线程到达正确的终点并且在完成之前不退出。

#6


0  

I thought I'd chime in with my solution since I don't see it currently listed. Turns out I was unintentionally putting a large object into the session, as shown below.

我以为我会使用我的解决方案,因为我没有看到它目前列出。结果我无意中将一个大对象放入会话中,如下所示。

session["devise.#{provider}_data"] = env["omniauth.auth"]

This only happened when somebody first authenticated with GitHub OAuth and subsequently tried to authenticate with another social profile that used the same email (why I couldn't originally figure out the issue).

这种情况只发生在有人首次使用GitHub OAuth进行身份验证并随后尝试使用另一个使用相同电子邮件的社交个人资料进行身份验证时(为什么我原本无法找到问题)。

Here's the full OmniauthCallbacksController for contextual reference:

以下是用于上下文参考的完整OmniauthCallbacksController:

class OmniauthCallbacksController < Devise::OmniauthCallbacksController

  def self.provides_callback_for(provider)
    class_eval %Q{
      def #{provider}
        @user = User.from_omniauth(request.env["omniauth.auth"])
        if @user.persisted?
          sign_in_and_redirect @user, event: :authentication
          set_flash_message(:notice, :success, kind: "#{provider}".capitalize) if is_navigational_format?
        else
          auth = request.env["omniauth.auth"]
          if User.exists?(email: auth.info.email)
            set_flash_message(:notice, :failure, kind: "#{provider}".capitalize, reason: "email " + auth.info.email + " already exists") if is_navigational_format?
          else
            set_flash_message(:notice, :error, kind: "#{provider}".capitalize) if is_navigational_format?
          end
          session["devise.#{provider}_data"] = env["omniauth.auth"] <----- Remove this line
          redirect_to new_user_registration_path
        end
      end
    }
  end

  [:github, :linkedin, :google_oauth2].each do |provider|
    provides_callback_for provider
  end
end

All was well once I removed the offending line. I am guessing I had it in there for debugging purposes.

一旦我删除违规行,一切都很好。我猜我在那里用于调试目的。

#1


31  

Came across this error recently.

最近碰到了这个错误。

Since Passenger 3.0.8 there is now a setting that allows you to set the buffers and buffer size. So now you can do

从Passenger 3.0.8开始,现在有一个设置允许您设置缓冲区和缓冲区大小。所以现在你可以做到

http {
    ...
    passenger_buffers 8 16k;
    passenger_buffer_size 32k;
}

That resolved the issue for me.

这解决了我的问题。

#2


28  

Try to add this to the config:

尝试将其添加到配置中:

http {
    ...
    proxy_buffers 8 16k;
    proxy_buffer_size 32k;
    }

#3


24  

Maybee adding this will make it work, how are you connecting to upstream? http, fastcgi or something else?

也许添加它会使它工作,你如何连接到上游? http,fastcgi还是其他什么?

http {
    ...
    fastcgi_buffers 8 16k;
    fastcgi_buffer_size 32k;
}

#4


6  

fastcgi_buffers 16 16k;
fastcgi_buffer_size 32k;

#5


1  

This is everything I have come to understand about this error in the last 2 years:

这是我在过去两年中对此错误了解的一切:

upstream sent too big header while reading response header from upstream is nginx's generic way of saying "I don't like what I'm seeing"

上游发送太大的标题,而从上游读取响应标题是nginx的通用方式,说“我不喜欢我所看到的”

  1. Your upstream server thread crashed
  2. 您的上游服务器线程崩溃了
  3. The upstream server sent an invalid header back
  4. 上游服务器发回了无效的头
  5. The Notice/Warnings sent back from STDERR broke their buffer and both it and STDOUT were closed
  6. 从STDERR发回的通知/警告打破了他们的缓冲区,它和STDOUT都关闭了

3: Look at the error logs above the message, is it streaming with logged lines preceding the message? PHP message: PHP Notice: Undefined index: Example snippet from a loop my log file:

3:查看消息上方的错误日志,是否在消息之前使用记录的行进行流式处理? PHP消息:PHP注意:未定义的索引:来自循环的示例片段我的日志文件:

2015/11/23 10:30:02 [error] 32451#0: *580927 FastCGI sent in stderr: "PHP message: PHP Notice:  Undefined index: Firstname in /srv/www/classes/data_convert.php on line 1090
PHP message: PHP Notice:  Undefined index: Lastname in /srv/www/classes/data_convert.php on line 1090
... // 20 lines of same
PHP message: PHP Notice:  Undefined index: Firstname in /srv/www/classes/data_convert.php on line 1090
PHP message: PHP Notice:  Undefined index: Lastname in /srv/www/classes/data_convert.php on line 1090
PHP message: PHP Notice:
2015/11/23 10:30:02 [error] 32451#0: *580927 FastCGI sent in stderr: "ta_convert.php on line 1090
PHP message: PHP Notice:  Undefined index: Firstname

you can see in the 3rd line (from the 20 previous errors) the buffer limit was hit, broke, and the next thread wrote in over it. Nginx then closed the connection and returned 502 to the client.

你可以在第3行看到(从之前的20个错误中)缓冲区限制被击中,破坏,并且下一个线程在其中写入。然后Nginx关闭连接并将502返回给客户端。

2: log all the headers sent per request, review them and make sure they conform to standards (nginx does not permit anything older than 24 hours to delete/expire a cookie, sending invalid content length because error messages were buffered before the content counted...)

2:记录每个请求发送的所有标头,检查它们并确保它们符合标准(nginx不允许任何超过24小时的内容删除/过期cookie,发送无效内容长度,因为错误消息在内容计数之前被缓冲。 ..)

examples include:

例子包括:

<?php
//expire cookie
setcookie ( 'bookmark', '', strtotime('2012-01-01 00:00:00') );
// nginx will refuse this header response, too far past to accept
....
?>

and this:

和这个:

<?php
header('Content-type: image/jpg');
?>

<?php   //a space was injected into the output above this line
header('Content-length: ' . filesize('image.jpg') );
echo file_get_contents('image.jpg');
// error! the response is now 1-byte longer than header!!
?>

1: verify, or make a script log, to ensure your thread is reaching the correct end point and not exiting before completion.

1:验证或制作脚本日志,以确保您的线程到达正确的终点并且在完成之前不退出。

#6


0  

I thought I'd chime in with my solution since I don't see it currently listed. Turns out I was unintentionally putting a large object into the session, as shown below.

我以为我会使用我的解决方案,因为我没有看到它目前列出。结果我无意中将一个大对象放入会话中,如下所示。

session["devise.#{provider}_data"] = env["omniauth.auth"]

This only happened when somebody first authenticated with GitHub OAuth and subsequently tried to authenticate with another social profile that used the same email (why I couldn't originally figure out the issue).

这种情况只发生在有人首次使用GitHub OAuth进行身份验证并随后尝试使用另一个使用相同电子邮件的社交个人资料进行身份验证时(为什么我原本无法找到问题)。

Here's the full OmniauthCallbacksController for contextual reference:

以下是用于上下文参考的完整OmniauthCallbacksController:

class OmniauthCallbacksController < Devise::OmniauthCallbacksController

  def self.provides_callback_for(provider)
    class_eval %Q{
      def #{provider}
        @user = User.from_omniauth(request.env["omniauth.auth"])
        if @user.persisted?
          sign_in_and_redirect @user, event: :authentication
          set_flash_message(:notice, :success, kind: "#{provider}".capitalize) if is_navigational_format?
        else
          auth = request.env["omniauth.auth"]
          if User.exists?(email: auth.info.email)
            set_flash_message(:notice, :failure, kind: "#{provider}".capitalize, reason: "email " + auth.info.email + " already exists") if is_navigational_format?
          else
            set_flash_message(:notice, :error, kind: "#{provider}".capitalize) if is_navigational_format?
          end
          session["devise.#{provider}_data"] = env["omniauth.auth"] <----- Remove this line
          redirect_to new_user_registration_path
        end
      end
    }
  end

  [:github, :linkedin, :google_oauth2].each do |provider|
    provides_callback_for provider
  end
end

All was well once I removed the offending line. I am guessing I had it in there for debugging purposes.

一旦我删除违规行,一切都很好。我猜我在那里用于调试目的。