nginx-0.0.7-2004-07-14-20:01:42 import
diff --git a/src/http/modules/ngx_http_ssl_filter.c b/src/http/modules/ngx_http_ssl_filter.c
index 742c293..344577b 100644
--- a/src/http/modules/ngx_http_ssl_filter.c
+++ b/src/http/modules/ngx_http_ssl_filter.c
@@ -22,12 +22,12 @@
 
 typedef struct {
     SSL       *ssl;
-
-    unsigned   accepted;
 } ngx_http_ssl_ctx_t;
 
 
 static ngx_http_ssl_ctx_t *ngx_http_ssl_create_ctx(ngx_http_request_t *r);
+static ngx_chain_t *ngx_http_ssl_write(ngx_http_request_t *r, ngx_chain_t *in,
+                                       off_t limit);
 static void ngx_http_ssl_error(ngx_uint_t level, ngx_log_t *log, int err,
                                char *fmt, ...);
 static void *ngx_http_ssl_create_srv_conf(ngx_conf_t *cf);
@@ -152,7 +152,7 @@
     }
 
     ngx_http_ssl_error(NGX_LOG_ALERT, r->connection->log, rc,
-                       "SSL_accept() failed");
+                       "SSL_read() failed");
 
     SSL_set_shutdown(ctx->ssl, SSL_RECEIVED_SHUTDOWN);
 
@@ -160,11 +160,8 @@
 }
 
 
-ngx_int_t ngx_http_ssl_write(ngx_http_request_t *r, ngx_chain_t *in,
-                             off_t limit)
+ngx_int_t ngx_http_ssl_writer(ngx_http_request_t *r, ngx_chain_t *in)
 {
-    int                  rc;
-    size_t               send, size;
     ngx_http_ssl_ctx_t  *ctx;
 
     ctx = ngx_http_get_module_ctx(r, ngx_http_ssl_filter_module);
@@ -175,7 +172,12 @@
         ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
                        "SSL_shutdown: %d", rc);
 
+        if (rc == 0) {
+            return NGX_AGAIN;
+        }
+
         if (rc == 1) {
+            SSL_free(ctx->ssl);
             return NGX_OK;
         }
 
@@ -188,9 +190,28 @@
             return NGX_AGAIN;
         }
 
+        ngx_http_ssl_error(NGX_LOG_ALERT, r->connection->log, rc,
+                           "SSL_shutdown() failed");
+
         return NGX_ERROR;
     }
 
+    ch = ngx_http_ssl_write(r, ctx, in, 0);
+
+    return NGX_OK;
+}
+
+
+static ngx_chain_t *ngx_http_ssl_write(ngx_http_request_t *r,
+                                       ngx_http_ssl_ctx_t *ctx,
+                                       ngx_chain_t *in,
+                                       off_t limit)
+{
+    int                  rc;
+    size_t               send, size;
+
+    ctx = ngx_http_get_module_ctx(r, ngx_http_ssl_filter_module);
+
     send = 0;
 
     for (/* void */; in; in = in->next) {
@@ -205,9 +226,20 @@
         }
 
         rc = SSL_write(ctx->ssl, in->buf->pos, size);
+
+        if (rc > 0) {
+            in->buf->pos += rc;
+
+            if (rc == size) {
+                continue;
+            }
+
+            r->connection->write->ready = 0;
+            return in;
+        }
     }
 
-    return NGX_OK;
+    return in;
 }
 
 
diff --git a/src/http/modules/ngx_http_ssl_filter.h b/src/http/modules/ngx_http_ssl_filter.h
index b94b367..9bbe65a 100644
--- a/src/http/modules/ngx_http_ssl_filter.h
+++ b/src/http/modules/ngx_http_ssl_filter.h
@@ -14,6 +14,8 @@
 
 
 ngx_int_t ngx_http_ssl_read(ngx_http_request_t *r, u_char *buf, size_t n);
+ngx_int_t ngx_http_ssl_writer(ngx_http_request_t *r, ngx_chain_t *in);
+
 void ngx_http_ssl_close_connection(SSL *ssl, ngx_log_t *log);
 
 
diff --git a/src/http/ngx_http_core_module.c b/src/http/ngx_http_core_module.c
index 2e96785..001ed89 100644
--- a/src/http/ngx_http_core_module.c
+++ b/src/http/ngx_http_core_module.c
@@ -206,6 +206,20 @@
       offsetof(ngx_http_core_loc_conf_t, send_lowat),
       &ngx_http_lowat_post },
 
+    { ngx_string("postpone_output"),
+      NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
+      ngx_conf_set_size_slot,
+      NGX_HTTP_LOC_CONF_OFFSET,
+      offsetof(ngx_http_core_loc_conf_t, postpone_output),
+      NULL },
+
+    { ngx_string("limit_rate"),
+      NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
+      ngx_conf_set_size_slot,
+      NGX_HTTP_LOC_CONF_OFFSET,
+      offsetof(ngx_http_core_loc_conf_t, limit_rate),
+      NULL },
+
     { ngx_string("keepalive_timeout"),
       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
       ngx_conf_set_msec_slot,
@@ -1251,6 +1265,8 @@
     lcf->tcp_nopush = NGX_CONF_UNSET;
     lcf->send_timeout = NGX_CONF_UNSET_MSEC;
     lcf->send_lowat = NGX_CONF_UNSET_SIZE;
+    lcf->postpone_output = NGX_CONF_UNSET_SIZE;
+    lcf->limit_rate = NGX_CONF_UNSET_SIZE;
     lcf->discarded_buffer_size = NGX_CONF_UNSET_SIZE;
     lcf->keepalive_timeout = NGX_CONF_UNSET_MSEC;
     lcf->lingering_time = NGX_CONF_UNSET_MSEC;
@@ -1334,6 +1350,9 @@
     ngx_conf_merge_value(conf->tcp_nopush, prev->tcp_nopush, 0);
     ngx_conf_merge_msec_value(conf->send_timeout, prev->send_timeout, 60000);
     ngx_conf_merge_size_value(conf->send_lowat, prev->send_lowat, 0);
+    ngx_conf_merge_size_value(conf->postpone_output, prev->postpone_output,
+                              1460);
+    ngx_conf_merge_size_value(conf->limit_rate, prev->limit_rate, 0);
     ngx_conf_merge_size_value(conf->discarded_buffer_size,
                               prev->discarded_buffer_size, 1500);
     ngx_conf_merge_msec_value(conf->keepalive_timeout,
diff --git a/src/http/ngx_http_core_module.h b/src/http/ngx_http_core_module.h
index 834cf58..051486a 100644
--- a/src/http/ngx_http_core_module.h
+++ b/src/http/ngx_http_core_module.h
@@ -134,6 +134,8 @@
     size_t        discarded_buffer_size;   /* discarded_buffer_size */
     size_t        client_body_buffer_size; /* client_body_buffer_size */
     size_t        send_lowat;              /* send_lowat */
+    size_t        postpone_output;         /* postpone_output */
+    size_t        limit_rate;              /* limit_rate */
 
     ngx_msec_t    client_body_timeout;     /* client_body_timeout */
     ngx_msec_t    send_timeout;            /* send_timeout */
diff --git a/src/http/ngx_http_header_filter.c b/src/http/ngx_http_header_filter.c
index 738f1eb..f565d2f 100644
--- a/src/http/ngx_http_header_filter.c
+++ b/src/http/ngx_http_header_filter.c
@@ -33,6 +33,9 @@
 };
 
 
+static ngx_http_output_body_filter_pt    write_filter;
+
+
 static char server_string[] = "Server: " NGINX_VER CRLF;
 
 
@@ -355,7 +358,7 @@
     ln->buf = b;
     ln->next = NULL;
 
-    return ngx_http_write_filter(r, ln);
+    return write_filter(r, ln);
 }
 
 
@@ -363,5 +366,7 @@
 {
     ngx_http_top_header_filter = ngx_http_header_filter;
 
+    write_filter = ngx_http_top_body_filter;
+
     return NGX_OK;
 }
diff --git a/src/http/ngx_http_write_filter.c b/src/http/ngx_http_write_filter.c
index 2d4ba23..2d4c1ef 100644
--- a/src/http/ngx_http_write_filter.c
+++ b/src/http/ngx_http_write_filter.c
@@ -6,42 +6,13 @@
 
 
 typedef struct {
-    size_t  postpone_output;         /* postpone_output */
-    size_t  limit_rate;              /* limit_rate */
-} ngx_http_write_filter_conf_t;
-
-
-typedef struct {
     ngx_chain_t  *out;
 } ngx_http_write_filter_ctx_t;
 
 
-static void *ngx_http_write_filter_create_conf(ngx_conf_t *cf);
-static char *ngx_http_write_filter_merge_conf(ngx_conf_t *cf,
-                                              void *parent, void *child);
 static ngx_int_t ngx_http_write_filter_init(ngx_cycle_t *cycle);
 
 
-static ngx_command_t  ngx_http_write_filter_commands[] = {
-
-    { ngx_string("postpone_output"),
-      NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
-      ngx_conf_set_size_slot,
-      NGX_HTTP_LOC_CONF_OFFSET,
-      offsetof(ngx_http_write_filter_conf_t, postpone_output),
-      NULL },
-
-    { ngx_string("limit_rate"),
-      NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
-      ngx_conf_set_size_slot,
-      NGX_HTTP_LOC_CONF_OFFSET,
-      offsetof(ngx_http_write_filter_conf_t, limit_rate),
-      NULL },
-
-      ngx_null_command
-};
-
-
 ngx_http_module_t  ngx_http_write_filter_module_ctx = {
     NULL,                                  /* pre conf */
 
@@ -51,15 +22,15 @@
     NULL,                                  /* create server configuration */
     NULL,                                  /* merge server configuration */
 
-    ngx_http_write_filter_create_conf,     /* create location configuration */
-    ngx_http_write_filter_merge_conf       /* merge location configuration */
+    NULL,                                  /* create location configuration */
+    NULL,                                  /* merge location configuration */
 };
 
 
 ngx_module_t  ngx_http_write_filter_module = {
     NGX_MODULE,
     &ngx_http_write_filter_module_ctx,     /* module context */
-    ngx_http_write_filter_commands,        /* module directives */
+    NULL,                                  /* module directives */
     NGX_HTTP_MODULE,                       /* module type */
     ngx_http_write_filter_init,            /* init module */
     NULL                                   /* init process */
@@ -68,11 +39,11 @@
 
 ngx_int_t ngx_http_write_filter(ngx_http_request_t *r, ngx_chain_t *in)
 {
-    int                            last;
-    off_t                          size, flush, sent;
-    ngx_chain_t                   *cl, *ln, **ll, *chain;
-    ngx_http_write_filter_ctx_t   *ctx;
-    ngx_http_write_filter_conf_t  *conf;
+    int                           last;
+    off_t                         size, flush, sent;
+    ngx_chain_t                  *cl, *ln, **ll, *chain;
+    ngx_http_core_loc_conf_t     *clcf;
+    ngx_http_write_filter_ctx_t  *ctx;
 
     ctx = ngx_http_get_module_ctx(r->main ? r->main : r,
                                   ngx_http_write_filter_module);
@@ -125,8 +96,8 @@
                    "http write filter: l:%d f:" OFF_T_FMT " s:" OFF_T_FMT,
                    last, flush, size);
 
-    conf = ngx_http_get_module_loc_conf(r->main ? r->main : r,
-                                        ngx_http_write_filter_module);
+    clcf = ngx_http_get_module_loc_conf(r->main ? r->main : r,
+                                        ngx_http_core_module);
 
     /*
      * avoid the output if there is no last buf, no flush point,
@@ -134,7 +105,7 @@
      * is smaller than "postpone_output" directive
      */
 
-    if (!last && flush == 0 && in && size < (off_t) conf->postpone_output) {
+    if (!last && flush == 0 && in && size < (off_t) clcf->postpone_output) {
         return NGX_OK;
     }
 
@@ -153,17 +124,17 @@
     sent = r->connection->sent;
 
     chain = ngx_write_chain(r->connection, ctx->out,
-                            conf->limit_rate ? conf->limit_rate:
+                            clcf->limit_rate ? clcf->limit_rate:
                                                OFF_T_MAX_VALUE);
 
     ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
                    "http write filter %X", chain);
 
-    if (conf->limit_rate) {
+    if (clcf->limit_rate) {
         sent = r->connection->sent - sent;
         r->connection->write->delayed = 1;
         ngx_add_timer(r->connection->write,
-                      (ngx_msec_t) sent * 1000 / conf->limit_rate);
+                      (ngx_msec_t) (sent * 1000 / clcf->limit_rate));
     }
 
     if (chain == NGX_CHAIN_ERROR) {
@@ -180,36 +151,6 @@
 }
 
 
-static void *ngx_http_write_filter_create_conf(ngx_conf_t *cf)
-{
-    ngx_http_write_filter_conf_t *conf;
-
-    ngx_test_null(conf,
-                  ngx_palloc(cf->pool, sizeof(ngx_http_write_filter_conf_t)),
-                  NULL);
-
-    conf->postpone_output = NGX_CONF_UNSET_SIZE;
-    conf->limit_rate = NGX_CONF_UNSET_SIZE;
-
-    return conf;
-}
-
-
-static char *ngx_http_write_filter_merge_conf(ngx_conf_t *cf,
-                                              void *parent, void *child)
-{
-    ngx_http_write_filter_conf_t *prev = parent;
-    ngx_http_write_filter_conf_t *conf = child;
-
-    ngx_conf_merge_size_value(conf->postpone_output, prev->postpone_output,
-                              1460);
-
-    ngx_conf_merge_size_value(conf->limit_rate, prev->limit_rate, 0);
-
-    return NULL;
-}
-
-
 static ngx_int_t ngx_http_write_filter_init(ngx_cycle_t *cycle)
 {
     ngx_http_top_body_filter = ngx_http_write_filter;