2010-02-21 1 views
29

Я бегу nginx, Phusion Passenger и Rails.Как избежать ошибок nginx «upstream sent too large header»?

Я бегу против следующей ошибки:

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 

Он встречающийся на обратный вызов от вызова аутентификации на Facebook Connect.

После поиска в Интернете и попытки изменить настройки nginx, включая proxy_buffer_size и large_client_header_buffers, не имеют никакого эффекта.

Как я могу отладить это?

ответ

31

Последнее изменение этой ошибки.

С Passenger 3.0.8 теперь есть настройка, позволяющая установить буферы и размер буфера. Итак, теперь вы можете сделать

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

Это решило проблему для меня.

+2

+1 Это должен быть принятый ответ. –

28

Попробуйте добавить это к конфигурации:

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

Поскольку он использует Phusion Passenger поверх nginx, ваше решение НЕ поможет ему. потому что его цитированное сообщение об ошибке выше происходит от самого пассажира и почти наверняка не от nginx напрямую. Тем не менее, было бы безопасно продолжать делать то, что вы сказали, но также добавить два пассажирских подвески (пассажирские_буферы и пассажир_баффер_размер), как указано ниже. – christianparpart

+2

@trapni Не может ответить на этот вопрос, но также является решением для других людей, использующих прокси nginx. –

+4

Это определенно помогло при использовании единорога за nginx. – Lloeki

24

Maybee добавляя, что это сделает его работу, как вы подключаете вверх по течению? http, fastcgi или что-то еще?

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

phusion пассажир вообще не использует fastcgi, это прямая часть процесса nginx, так что это НЕ поможет в его случае. – christianparpart

+0

О, дерьмо! Ты абсолютно прав, глупая ошибка с моей стороны :) –

+7

Спасибо. Он отлично справился с моей реализацией fastcgi. –

1

Это все, что я пришел к пониманию об этой ошибке в последние 2 года:

upstream sent too big header while reading response header from upstream является универсальным способом Nginx сказать «мне не нравится то, что я вижу»

  1. вышестоящая нить сервера упала
  2. вышестоящий сервер послал неверный заголовок назад
  3. Уведомления/предупреждение, посланный от STDERR нарушила буфер А как он, так и STDOUT были закрыты

3: Посмотрите на журналы ошибок над сообщением, транслируется ли строка, предшествующая сообщению? PHP message: PHP Notice: Undefined index: Пример фрагмента из петли мой лог-файл:

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 

вы можете увидеть в 3-й линии (от 20 предыдущих ошибок) предел буфера был подбит, сломался, и следующий поток написал над ним. Затем Nginx закрыл соединение и вернул 502 клиенту.

2: зарегистрируйте все заголовки, отправленные по запросу, просмотрите их и убедитесь, что они соответствуют стандартам (nginx не разрешает что-либо старше 24 часов для удаления/истечения срока действия cookie, отправляя недопустимую длину содержимого, поскольку сообщения об ошибках буферизуются до содержание подсчитывается ...)

примеров включают в себя:

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

и это:

<?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: проверить, или сделать журнал сценария, чтобы обеспечить ваш поток достигает правильную конечную точку и не выходя до завершения ,

0

Я думал, что перезвоню с моим решением, так как я не вижу его в настоящее время. Оказывается, я непреднамеренно помещал большой объект в сеанс, как показано ниже.

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

Это произошло только тогда, когда кто-то первый заверено GitHub OAuth, а затем попыталось проверить подлинность с другим социальным профилем, который используется один и тот же адрес электронной почты (почему я не мог изначально выяснить вопрос).

Вот полный 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 

Все было хорошо, когда я извлекал обижая линию. Я предполагаю, что у меня было это там для целей отладки.