ПРОЕКТЫ 


  АРХИВ 


Apache-Talk @lexa.ru 

Inet-Admins @info.east.ru 

Filmscanners @halftone.co.uk 

Security-alerts @yandex-team.ru 

nginx-ru @sysoev.ru 


  СТАТЬИ 


  ПЕРСОНАЛЬНОЕ 


  ПРОГРАММЫ 



ПИШИТЕ
ПИСЬМА












     АРХИВ :: nginx-ru
Nginx-ru mailing list archive (nginx-ru@sysoev.ru)

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Fwd: nginx FR: fcgi error handling


  • To: nginx-ru@xxxxxxxxx
  • Subject: Fwd: nginx FR: fcgi error handling
  • From: "Nick S. Grechukh" <gns@xxxxxxxxxxx>
  • Date: Fri, 13 Apr 2007 15:08:50 +0200
  • Dkim-signature: a=rsa-sha1; c=relaxed/relaxed; d=gmail.com; s=beta; h=domainkey-signature:received:received:message-id:date:from:sender:to:subject:in-reply-to:mime-version:content-type:references:x-google-sender-auth; b=h/MBbMWwz19coQfZJhLz/NVc3iz2qB0GbZOxYKn8JxNfUVeTx4FLcCBu7qFRz2STjcFKZLWbGOKe+zDI6YIKuw41VLwh23t7DHu8Edb+VRQp9AF0LYJieQX2RY/+iivdSdnJUQ0TUvz0iFv7B3gzXn1s+5U3/AagE5OZa/B+o2U=
  • Domainkey-signature: a=rsa-sha1; c=nofws; d=gmail.com; s=beta; h=received:message-id:date:from:sender:to:subject:in-reply-to:mime-version:content-type:references:x-google-sender-auth; b=XGMiYWcSrNR06u27Hrp9Ls8VVB1nxNo9utKkh7Z9+wfHirU1sboIolzxaCSjcAJtJZActIIvzhHpC0cx8+Pf+xCQF/nu4OWS2eQB5/7/CMxTXz2rhzQqr8GYimvi/NkZb75g3Vlm8KK0/sQmvA9kB3ZQc1Wq9dmOYE65M2U9Hmg=
  • In-reply-to: <a4ab440f0704121024t7b81febg96a46926163981f5@xxxxxxxxxxxxxx>
  • References: <a4ab440f0704121024t7b81febg96a46926163981f5@xxxxxxxxxxxxxx>

---------- Forwarded message ----------
From: "Nick S. Grechukh" <gns@>
Date: Thu, 12 Apr 2007 20:24:14 +0300
Subject: nginx FR: fcgi error handling
To: mithraen@

предлагаю патчик для fastcgi модуля nginx, решающий следующую проблему:

Перехватить и обработать php fatal error средствами PHP в случае
фатальной ошибки невозможно - php уже умер, успев выдать сообщение в
stderr. в результате пользователь получает пустую страницу (или при
display_errors=on - сообщение от php), однако с кодом 200.

Во многих случаях это неприемлемо; под апачем mod_php выдает 500
Internal server error, что гораздо лучше. Насколько мне известно,
штатными средствами добиться от fastcgi+anywebserver поведения,
аналогичного модулю апача невозможно (intercept_errors здесь совсем ни
при чем).

Предлагается отлавливать эти ситуации анализируя stderr от fastcgi;
для этого введена директива fastcgi_catch_stderr, в которой можно
указать, какие строки в stderr следует обрабатывать как internal
server error. Мы используем fastcgi_catch_stderr "PHP Fatal error:",
но в принципе я постарался сделать не-пхп-специфичное решение.

Проблему я вижу только одну - если контент формируется постепенно и
часть ответа  уже попала клиенту, выставить код ошибки невозможно. Но
это понятно, с этим в любом случае ничего не сделаешь кроме полного
кэширования ответов fcgi (эксперименты показали, что в буфере nginx
помещается кусок до 4килобайт). А во-вторых, часто ответ кэшируется на
стороне php и в самом конце работы скрипта выдается целиком.

с уважением,
Nick S. Grechukh
diff -Naur nginx-0.5.14/src/http/modules/ngx_http_fastcgi_module.c 
nginx-0.5.14.gns/src/http/modules/ngx_http_fastcgi_module.c
--- nginx-0.5.14/src/http/modules/ngx_http_fastcgi_module.c     2007-03-18 
13:13:33 +0200
+++ nginx-0.5.14.gns/src/http/modules/ngx_http_fastcgi_module.c 2007-04-12 
17:03:25 +0300
@@ -19,6 +19,7 @@
     ngx_array_t                   *params_len;
     ngx_array_t                   *params;
     ngx_array_t                   *params_source;
+    ngx_array_t                   *catch_stderr;
 } ngx_http_fastcgi_loc_conf_t;
 
 
@@ -345,6 +346,13 @@
       offsetof(ngx_http_fastcgi_loc_conf_t, upstream.hide_headers),
       NULL },
 
+    { ngx_string("fastcgi_catch_stderr"),
+      NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_FLAG,
+      ngx_conf_set_str_array_slot,
+      NGX_HTTP_LOC_CONF_OFFSET,
+      offsetof(ngx_http_fastcgi_loc_conf_t, catch_stderr),
+      NULL },
+
       ngx_null_command
 };
 
@@ -835,16 +843,18 @@
     u_char                         *start, *last;
     ngx_str_t                      *status_line, line;
     ngx_int_t                       rc, status;
-    ngx_uint_t                      i;
+    ngx_uint_t                      i,j;
     ngx_table_elt_t                *h;
     ngx_http_upstream_t            *u;
     ngx_http_fastcgi_ctx_t         *f;
     ngx_http_upstream_header_t     *hh;
     ngx_http_upstream_main_conf_t  *umcf;
+    ngx_http_fastcgi_loc_conf_t    *flcf;
 
     f = ngx_http_get_module_ctx(r, ngx_http_fastcgi_module);
 
     umcf = ngx_http_get_module_main_conf(r, ngx_http_upstream_module);
+    flcf = ngx_http_get_module_loc_conf(r, ngx_http_fastcgi_module);
 
     if (f == NULL) {
         f = ngx_pcalloc(r->pool, sizeof(ngx_http_fastcgi_ctx_t));
@@ -948,6 +958,13 @@
                 ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
                               "FastCGI sent in stderr: \"%V\"", &line);
 
+               ngx_str_t* catch_them  = flcf->catch_stderr->elts;
+               for (j = 0; j < flcf->catch_stderr->nelts; j++) {
+                       if (ngx_strstr(line.data,catch_them[j].data)) {
+                               return NGX_HTTP_INTERNAL_SERVER_ERROR;
+                       }
+               }
+
                 if (u->buffer.pos == u->buffer.last) {
 
                     if (!f->fastcgi_stdout) {


 




Copyright © Lexa Software, 1996-2009.