Possible bug in SSI include handling

Maxim Dounin mdounin at mdounin.ru
Sun Jan 3 07:15:02 MSK 2010


Hello!

On Thu, Dec 31, 2009 at 05:58:40PM +0300, Maxim Dounin wrote:

> Hello!
> 
> On Wed, Dec 30, 2009 at 02:42:16PM -0500, Maxim Khitrov wrote:
> 
> > This file structure required to duplicate this bug is a bit complex to
> > explain. Therefore, I put the required files into a tiny archive,
> > which you can download from [1].
> 
> [...]
> 
> > I started looking through the source code for ssi module, but I'm
> > hoping that someone more familiar with nginx internals would be able
> > to find a solution quicker. It seems that adding wait="yes" to the
> > virtual include in bad.html also fixes the problem, so I suspect that
> > the issue is with requests being performed in parallel.
> 
> I'm able to reproduce it here, thanks.  I'll take a look (but most 
> likely after New Year).

Patch.

Maxim Dounin
-------------- next part --------------
# HG changeset patch
# User Maxim Dounin <mdounin at mdounin.ru>
# Date 1262491809 -10800
# Node ID d1cebb46a883d150ea462ab6a83f7d56aa441406
# Parent  dd6dac3907850953f28375525d4a3c79fdc83588
SSI: response might be truncated after include with wait="yes".

In 0.7.29+ this also affects include file="..." (as it has wait="yes"
implicitly in 0.7.29+).  The bug had appeared in 0.7.25.

Reported by:	Maxim Khitrov

diff --git a/src/http/modules/ngx_http_ssi_filter_module.c b/src/http/modules/ngx_http_ssi_filter_module.c
--- a/src/http/modules/ngx_http_ssi_filter_module.c
+++ b/src/http/modules/ngx_http_ssi_filter_module.c
@@ -71,6 +71,8 @@ typedef enum {
 
 static ngx_int_t ngx_http_ssi_output(ngx_http_request_t *r,
     ngx_http_ssi_ctx_t *ctx);
+static void ngx_http_ssi_buffering(ngx_http_request_t *r,
+    ngx_http_ssi_ctx_t *ctx);
 static ngx_int_t ngx_http_ssi_parse(ngx_http_request_t *r,
     ngx_http_ssi_ctx_t *ctx);
 static ngx_str_t *ngx_http_ssi_get_variable(ngx_http_request_t *r,
@@ -798,6 +800,7 @@ ngx_http_ssi_body_filter(ngx_http_reques
                 }
 
                 if (rc == NGX_DONE || rc == NGX_AGAIN || rc == NGX_ERROR) {
+                    ngx_http_ssi_buffering(r, ctx);
                     return rc;
                 }
             }
@@ -950,14 +953,21 @@ ngx_http_ssi_output(ngx_http_request_t *
         }
     }
 
+    ngx_http_ssi_buffering(r, ctx);
+
+    return rc;
+}
+
+
+static void
+ngx_http_ssi_buffering(ngx_http_request_t *r, ngx_http_ssi_ctx_t *ctx)
+{
     if (ctx->in || ctx->buf) {
         r->buffered |= NGX_HTTP_SSI_BUFFERED;
 
     } else {
         r->buffered &= ~NGX_HTTP_SSI_BUFFERED;
     }
-
-    return rc;
 }
 
 


More information about the nginx mailing list