diff src/http/ngx_http_output_filter.c @ 61:4f3e2abcc2c4

nginx-0.0.1-2003-02-11-19:42:23 import
author Igor Sysoev <igor@sysoev.ru>
date Tue, 11 Feb 2003 16:42:23 +0000
parents 50186b49f2ad
children 8ccba41a678e
line wrap: on
line diff
--- a/src/http/ngx_http_output_filter.c
+++ b/src/http/ngx_http_output_filter.c
@@ -57,7 +57,6 @@ ngx_module_t  ngx_http_output_filter_mod
 };
 
 
-#if 1
 
 #define next_filter  ngx_http_output_filter_module_ctx.next_output_body_filter
 
@@ -67,6 +66,7 @@ ngx_module_t  ngx_http_output_filter_mod
             || ((r->filter & NGX_HTTP_FILTER_NEED_TEMP)                   \
                && (hunk->type & (NGX_HUNK_MEMORY|NGX_HUNK_MMAP))))
 
+
 int ngx_http_output_filter(ngx_http_request_t *r, ngx_hunk_t *hunk)
 {
     int                             rc;
@@ -84,8 +84,9 @@ int ngx_http_output_filter(ngx_http_requ
                             sizeof(ngx_http_output_filter_ctx_t));
     }
 
-    /* the incoming chain ctx->in is empty */
-    if (ctx->in == NULL) {
+    /* the short path for the case when the chain ctx->incoming is empty
+       and there is no hunk or the hunk does not require the copy */
+    if (ctx->incoming == NULL) {
 
         if (hunk == NULL) {
             return next_filter(r, NULL);
@@ -98,91 +99,53 @@ int ngx_http_output_filter(ngx_http_requ
 
             return next_filter(r, &ctx->out);
         }
+    }
 
-        /* we need to copy the incoming hunk to our hunk */
+    /* add the incoming hunk to the chain ctx->incoming */
+    if (hunk) {
 
-        /* allocate ctx->hunk if it's needed */
-        if (ctx->hunk == NULL) {
+        /* the output of the only hunk is common case so we have
+           special chain entry ctx->in for it */
+        if (ctx->incoming == NULL) {
+            ctx->in.hunk = hunk;
+            ctx->in.next = NULL;
+            ctx->incoming = &ctx->in;
 
-            conf = (ngx_http_output_filter_conf_t *)
-                   ngx_http_get_module_loc_conf(r->main ? r->main : r,
-                                                ngx_http_output_filter_module);
+        } else {
+            for (ce = ctx->incoming; ce->next; ce = ce->next) {
+                /* void */ ;
+            }
+
+            ngx_add_hunk_to_chain(ce->next, hunk, r->pool, NGX_ERROR);
+        }
+    }
 
-            if (hunk->type & NGX_HUNK_LAST) {
-                size = hunk->last.mem - hunk->pos.mem;
-                if (size > conf->hunk_size) {
-                    size = conf->hunk_size;
-                }
+    /* allocate our hunk if it's needed */
+    if (ctx->hunk == NULL) {
 
-            } else {
+        conf = (ngx_http_output_filter_conf_t *)
+               ngx_http_get_module_loc_conf(r->main ? r->main : r,
+                                            ngx_http_output_filter_module);
+
+        if (hunk->type & NGX_HUNK_LAST) {
+            size = hunk->last.mem - hunk->pos.mem;
+            if (size > conf->hunk_size) {
                 size = conf->hunk_size;
             }
 
-            ngx_test_null(ctx->hunk,
-                          ngx_create_temp_hunk(r->pool, size, 50, 50),
-                          NGX_ERROR);
-
-            ctx->hunk->type |= NGX_HUNK_RECYCLED;
+        } else {
+            size = conf->hunk_size;
         }
 
-        /* copy the incoming hunk or its part to our hunk
-           and pass it to the next filter */
-
-        do {
-            rc = ngx_http_output_filter_copy_hunk(ctx->hunk, hunk);
-
-            if (rc == NGX_ERROR) {
-                return rc;
-            }
-
-#if (NGX_FILE_AIO_READ)
-
-            if (rc == NGX_AGAIN) {
-                /* add the incoming hunk to the incoming chain */
-                ngx_add_hunk_to_chain(ctx->in, hunk, r->pool, NGX_ERROR);
-                return rc;
-            }
-
-#endif
-            ctx->out.hunk = ctx->hunk;
-            ctx->out.next = NULL;
-
-            rc = next_filter(r, &ctx->out);
-
-            if (rc == NGX_ERROR) {
-                return rc;
-            }
+        ngx_test_null(ctx->hunk,
+                      ngx_create_temp_hunk(r->pool, size, 50, 50),
+                      NGX_ERROR);
 
-            if (rc == NGX_AGAIN) {
-                /* add the incoming hunk to the incoming chain */
-                ngx_add_hunk_to_chain(ctx->in, hunk, r->pool, NGX_ERROR);
-                return rc;
-            }
-
-            /* NGX_OK */
-
-            /* set our hunk free */
-            ctx->hunk->pos.mem = ctx->hunk->last.mem = ctx->hunk->start;
-
-        /* repeat until we will have copied the whole incoming hunk */
-        } while (hunk->pos.mem < hunk->last.mem);
+        ctx->hunk->type |= NGX_HUNK_RECYCLED;
 
-        return NGX_OK;
-    }
-
-    /* the incoming chain ctx->in is not empty */
-
-    /* add the incoming hunk to the incoming chain */
-    if (hunk) {
-        for (ce = ctx->in; ce->next; ce = ce->next) {
-            /* void */ ;
-        }
-
-        ngx_add_hunk_to_chain(ce->next, hunk, r->pool, NGX_ERROR);
-    }
 
     /* our hunk is still busy */
-    if (ctx->hunk->pos.mem < ctx->hunk->last.mem) {
+    } else if (ctx->hunk->pos.mem < ctx->hunk->last.mem) {
         rc = next_filter(r, NULL);
 
         if (rc == NGX_ERROR || rc == NGX_AGAIN) {
@@ -190,6 +153,8 @@ int ngx_http_output_filter(ngx_http_requ
         }
 
         /* NGX_OK */
+
+        /* set our hunk free */
         ctx->hunk->pos.mem = ctx->hunk->last.mem = ctx->hunk->start;
     }
 
@@ -197,10 +162,10 @@ int ngx_http_output_filter(ngx_http_requ
     pe = NULL;
 #endif
 
-    /* process the incoming chain ctx->in */
+    /* process the chain ctx->incoming */
     do {
         /* find the hunks that do not need to be copied ... */
-        for (ce = ctx->in; ce; ce = ce->next) {
+        for (ce = ctx->incoming; ce; ce = ce->next) {
             if (need_to_copy(r, ce->hunk)) {
                 break;
             }
@@ -208,11 +173,11 @@ int ngx_http_output_filter(ngx_http_requ
         }
 
         /* ... and pass them to the next filter */
-        if (ctx->in != ce) {
+        if (ctx->incoming != ce) {
 
-            ctx->out.hunk = ctx->in->hunk;
-            ctx->out.next = ctx->in->next;
-            ctx->in = ce;
+            ctx->out.hunk = ctx->incoming->hunk;
+            ctx->out.next = ctx->incoming->next;
+            ctx->incoming = ce;
             pe->next = NULL;
 
             rc = next_filter(r, &ctx->out);
@@ -222,16 +187,16 @@ int ngx_http_output_filter(ngx_http_requ
             }
 
             /* NGX_OK */
-            if (ctx->in == NULL) {
+            if (ctx->incoming == NULL) {
                 return rc;
             }
         }
 
-
-        /* copy the first hunk or its part from the incoming chain ctx->in
+        /* copy the first hunk or its part from the chain ctx->incoming
            to our hunk and pass it to the next filter */
         do {
-            rc = ngx_http_output_filter_copy_hunk(ctx->hunk, ctx->in->hunk);
+            rc = ngx_http_output_filter_copy_hunk(ctx->hunk,
+                                                  ctx->incoming->hunk);
 
             if (rc == NGX_ERROR) {
                 return rc;
@@ -259,243 +224,19 @@ int ngx_http_output_filter(ngx_http_requ
             ctx->hunk->pos.mem = ctx->hunk->last.mem = ctx->hunk->start;
 
         /* repeat until we will have copied the whole first hunk from
-           the incoming chain ctx->in */
-        } while (ctx->in->hunk->pos.mem < ctx->in->hunk->last.mem);
+           the chain ctx->incoming */
+        } while (ctx->incoming->hunk->pos.mem < ctx->incoming->hunk->last.mem);
 
     /* delete the completed hunk from the incoming chain */
-    ctx->in = ctx->in->next;
+    ctx->incoming = ctx->incoming->next;
 
-    /* repeat until we will have processed the whole incoming chain ctx->in */
-    } while (ctx->in);
+    /* repeat until we will have processed the whole chain ctx->incoming */
+    } while (ctx->incoming);
 
     return NGX_OK;
 }
 
 
-#else
-
-
-int ngx_http_output_filter(ngx_http_request_t *r, ngx_hunk_t *hunk)
-{
-    int                             rc, once;
-    u_int                           flags;
-    size_t                          size;
-    ngx_chain_t                    *ce;
-    ngx_http_output_filter_ctx_t   *ctx;
-    ngx_http_output_filter_conf_t  *conf;
-
-    ctx = (ngx_http_output_filter_ctx_t *)
-                    ngx_http_get_module_ctx(r->main ? r->main : r,
-                                            ngx_http_output_filter_module);
-
-    if (ctx == NULL) {
-        ngx_http_create_ctx(r, ctx, ngx_http_output_filter_module,
-                            sizeof(ngx_http_output_filter_ctx_t));
-    }
-
-    if (hunk && (hunk->type & NGX_HUNK_LAST)) {
-        ctx->last = 1;
-    }
-
-#if (NGX_SUPPRESS_WARN)
-    rc = NGX_ALERT;
-#endif
-
-    for (once = 1; once || ctx->in; once = 0) {
-
-         /* input chain is not empty */
-        if (ctx->in) {
-
-            /* add hunk to input chain */
-            if (once && hunk) {
-                for (ce = ctx->in; ce->next; ce = ce->next) {
-                    /* void */ ;
-                }
-
-                ngx_add_hunk_to_chain(ce->next, hunk, r->pool, NGX_ERROR);
-            }
-
-            /* our hunk is still busy */
-            if (ctx->hunk->pos.mem < ctx->hunk->last.mem) {
-                rc = ngx_http_output_filter_module_ctx.
-                                              next_output_body_filter(r, NULL);
-
-            /* our hunk is free */
-            } else {
-                ctx->out.hunk = ctx->hunk;
-
-                /* XXX: should we check hunk type before copy it ? */
-                rc = ngx_http_output_filter_copy_hunk(ctx->hunk, ctx->in->hunk);
-#if (NGX_FILE_AIO_READ)
-                if (rc == NGX_AGAIN) {
-                    return rc;
-                }
-#endif
-                if (rc == NGX_ERROR) {
-                    return rc;
-                }
-
-                /* NGX_OK */
-
-                /* whole hunk is copied so we send to next filter chain part
-                   up to next hunk that need to be copied */
-                if (ctx->in->hunk->pos.mem == ctx->in->hunk->last.mem) {
-                    ctx->out.next = ctx->in->next;
-
-                    for (ce = ctx->in->next; ce; ce = ce->next) {
-                        if (ce->hunk->type & NGX_HUNK_FILE) {
-                            break;
-                        }
-
-                        if ((ce->hunk->type & (NGX_HUNK_MEMORY|NGX_HUNK_MMAP))
-                            && (r->filter & NGX_HTTP_FILTER_NEED_TEMP))
-                        {
-                            break;
-                        }
-                    }
-
-                    ctx->out.next = ce;
-
-                } else {
-                    ctx->out.next = NULL;
-                }
-
-                rc = ngx_http_output_filter_module_ctx.
-                                         next_output_body_filter(r, &ctx->out);
-            }
-
-            /* delete completed hunks from input chain */
-            for (ce = ctx->in; ce; ce = ce->next) {
-                 if (ce->hunk->pos.file == ce->hunk->last.file) {
-                     ctx->in = ce->next;
-                 }
-            }
-
-            if (rc == NGX_OK && ctx->hunk) {
-                ctx->hunk->pos.mem = ctx->hunk->last.mem = ctx->hunk->start;
-            } else {
-                return rc;
-            }
-
-        /* input chain is empty */
-        } else {
-
-            if (hunk == NULL) {
-                rc = ngx_http_output_filter_module_ctx.
-                                              next_output_body_filter(r, NULL);
-
-            } else {
-
-                /* we need to copy hunk to our hunk */
-                if (((r->filter & NGX_HTTP_FILTER_NEED_IN_MEMORY)
-                        && (hunk->type & NGX_HUNK_FILE))
-                    || ((r->filter & NGX_HTTP_FILTER_NEED_TEMP)
-                        && (hunk->type & (NGX_HUNK_MEMORY|NGX_HUNK_MMAP)))
-                   ) {
-
-                    /* out hunk is still busy */
-                    if (ctx->hunk && ctx->hunk->pos.mem < ctx->hunk->last.mem) {
-                        ngx_add_hunk_to_chain(ctx->in, hunk, r->pool,
-                                              NGX_ERROR);
-
-                        rc = ngx_http_output_filter_module_ctx.
-                                              next_output_body_filter(r, NULL);
-
-                    } else {
-                        if (ctx->hunk == NULL) {
-
-                            conf = (ngx_http_output_filter_conf_t *)
-                                            ngx_http_get_module_loc_conf(
-                                                r->main ? r->main : r,
-                                                ngx_http_output_filter_module);
-
-                            if (hunk->type & NGX_HUNK_LAST) {
-                                size = hunk->last.mem - hunk->pos.mem;
-                                if (size > conf->hunk_size) {
-                                    size = conf->hunk_size;
-                                }
-
-                            } else {
-                                size = conf->hunk_size;
-                            }
-
-                            ngx_test_null(ctx->hunk,
-                                          ngx_create_temp_hunk(r->pool, size,
-                                                               50, 50),
-                                          NGX_ERROR);
-                            ctx->hunk->type |= NGX_HUNK_RECYCLED;
-
-                            rc = ngx_http_output_filter_copy_hunk(ctx->hunk,
-                                                                  hunk);
-#if (NGX_FILE_AIO_READ)
-                            if (rc == NGX_AGAIN) {
-                                /* add hunk to input chain */
-                                ngx_add_hunk_to_chain(ctx->in, hunk, r->pool,
-                                                      NGX_ERROR);
-
-                                return rc;
-                            }
-#endif
-                            if (rc == NGX_ERROR) {
-                                return rc;
-                            }
-
-                            if (hunk->pos.mem < hunk->last.mem) {
-                                ngx_add_hunk_to_chain(ctx->in, hunk, r->pool,
-                                                      NGX_ERROR);
-                            }
-
-                            ctx->out.hunk = ctx->hunk;
-                            ctx->out.next = NULL;
-
-                            rc = ngx_http_output_filter_module_ctx.
-                                         next_output_body_filter(r, &ctx->out);
-                        }
-                    }
-
-                } else {
-                    ctx->out.hunk = hunk;
-                    ctx->out.next = NULL;
-
-                    rc = ngx_http_output_filter_module_ctx.
-                                         next_output_body_filter(r, &ctx->out);
-                }
-            }
-        }
-
-        /* set free our hunk if operation has completed */
-        if (rc == NGX_OK && ctx->hunk) {
-            ctx->hunk->pos.mem = ctx->hunk->last.mem = ctx->hunk->start;
-        }
-    }
-
-#if (NGX_SUPPRESS_WARN)
-    if (rc == NGX_ALERT) {
-        ngx_log_error(NGX_LOG_ALERT, r->connection->log, 0,
-                      "ngx_http_output_filter: rc == NGX_ALERT");
-        return NGX_ERROR;
-    }
-#endif
-
-    if (rc == NGX_OK && ctx->last) {
-        return NGX_OK;
-    }
-
-    if (rc == NGX_OK) {
-        if (ctx->hunk) { /* XXX: double upper code ? */
-            ctx->hunk->pos.mem = ctx->hunk->last.mem = ctx->hunk->start;
-        }
-#if (NGX_LEVEL_EVENT)
-        ngx_del_event(r->connection->write, NGX_WRITE_EVENT);
-#endif
-    }
-
-    return rc;
-}
-
-#endif
-
-
 static int ngx_http_output_filter_copy_hunk(ngx_hunk_t *dst, ngx_hunk_t *src)
 {
     ssize_t  n, size;
@@ -510,16 +251,23 @@ static int ngx_http_output_filter_copy_h
 
         if (n == NGX_ERROR) {
             return n;
+        }
 
 #if (NGX_FILE_AIO_READ)
-        } else if (n == NGX_AGAIN) {
+
+        if (n == NGX_AGAIN) {
             return n;
+        }
+
 #endif
 
-        } else {
-            ngx_assert((n == size), /* void */ ; , src->file->log,
-                       ngx_read_file_n " reads only %d of %d" _
-                       n _ size);
+        if (n != size) {
+            ngx_log_error(NGX_LOG_ALERT, src->file->log, 0,
+                          ngx_read_file_n " reads only %d of %d from file",
+                          n, size);
+            if (n == 0) {
+                return NGX_ERROR;
+            }
         }
 
         src->pos.mem += n;