nginx-0.0.7-2004-06-21-19:59:32 import
diff --git a/src/http/modules/proxy/ngx_http_proxy_upstream.c b/src/http/modules/proxy/ngx_http_proxy_upstream.c
index 643f7fa..83af1ad 100644
--- a/src/http/modules/proxy/ngx_http_proxy_upstream.c
+++ b/src/http/modules/proxy/ngx_http_proxy_upstream.c
@@ -605,6 +605,7 @@
     writer->out = NULL;
     writer->last = &writer->out;
     writer->connection = c;
+    writer->limit = OFF_T_MAX_VALUE;
 
     if (p->upstream->peer.tries > 1 && p->request_sent) {
         ngx_http_proxy_reinit_upstream(p);
diff --git a/src/http/ngx_http_core_module.h b/src/http/ngx_http_core_module.h
index d0539e0..84617e2 100644
--- a/src/http/ngx_http_core_module.h
+++ b/src/http/ngx_http_core_module.h
@@ -125,9 +125,9 @@
     ngx_str_t     default_type;
 
     size_t        client_max_body_size;    /* client_max_body_size */
-    size_t        send_lowat;              /* send_lowat */
     size_t        discarded_buffer_size;   /* discarded_buffer_size */
     size_t        client_body_buffer_size; /* client_body_buffer_size */
+    size_t        send_lowat;              /* send_lowat */
 
     ngx_msec_t    client_body_timeout;     /* client_body_timeout */
     ngx_msec_t    send_timeout;            /* send_timeout */
diff --git a/src/http/ngx_http_request.c b/src/http/ngx_http_request.c
index 814e582..e935afb 100644
--- a/src/http/ngx_http_request.c
+++ b/src/http/ngx_http_request.c
@@ -1050,13 +1050,13 @@
     wev = r->connection->write;
     wev->event_handler = ngx_http_writer;
 
-    if (wev->ready && r->delayed) {
+    if (wev->ready && wev->delayed) {
         return;
     }
 
     clcf = ngx_http_get_module_loc_conf(r->main ? r->main : r,
                                         ngx_http_core_module);
-    if (!r->delayed) {
+    if (!wev->delayed) {
         ngx_add_timer(wev, clcf->send_timeout);
     }
 
@@ -1083,13 +1083,13 @@
     r = c->data;
 
     if (wev->timedout) {
-        if (!r->delayed) {
+        if (!wev->delayed) {
             ngx_http_client_error(r, 0, NGX_HTTP_REQUEST_TIME_OUT);
             return;
         }
 
         wev->timedout = 0;
-        r->delayed = 0;
+        wev->delayed = 0;
 
         if (!wev->ready) {
             clcf = ngx_http_get_module_loc_conf(r->main ? r->main : r,
@@ -1107,9 +1107,19 @@
         }
 
     } else {
-        if (r->delayed) {
+        if (wev->delayed) {
             ngx_log_debug0(NGX_LOG_DEBUG_HTTP, wev->log, 0,
                            "http writer delayed");
+
+            clcf = ngx_http_get_module_loc_conf(r->main ? r->main : r,
+                                                ngx_http_core_module);
+            wev->available = clcf->send_lowat;
+
+            if (ngx_handle_write_event(wev, NGX_LOWAT_EVENT) == NGX_ERROR) {
+                ngx_http_close_request(r, 0);
+                ngx_http_close_connection(r->connection);
+            }
+
             return;
         }
     }
@@ -1122,7 +1132,7 @@
     if (rc == NGX_AGAIN) {
         clcf = ngx_http_get_module_loc_conf(r->main ? r->main : r,
                                             ngx_http_core_module);
-        if (!wev->ready && !r->delayed) {
+        if (!wev->ready && !wev->delayed) {
             ngx_add_timer(wev, clcf->send_timeout);
         }
 
diff --git a/src/http/ngx_http_request.h b/src/http/ngx_http_request.h
index 7054d92..52e110a 100644
--- a/src/http/ngx_http_request.h
+++ b/src/http/ngx_http_request.h
@@ -284,7 +284,6 @@
     /* can we use sendfile ? */
     unsigned             sendfile:1;
 
-    unsigned             delayed:1;
     unsigned             chunked:1;
     unsigned             header_only:1;
     unsigned             keepalive:1;
diff --git a/src/http/ngx_http_write_filter.c b/src/http/ngx_http_write_filter.c
index bdef48b..f82bdae 100644
--- a/src/http/ngx_http_write_filter.c
+++ b/src/http/ngx_http_write_filter.c
@@ -6,7 +6,8 @@
 
 
 typedef struct {
-    size_t  postpone_output;
+    size_t  postpone_output;         /* postpone_output */
+    size_t  limit_rate;              /* limit_rate */
 } ngx_http_write_filter_conf_t;
 
 
@@ -23,19 +24,18 @@
 
 static ngx_command_t  ngx_http_write_filter_commands[] = {
 
-    /* STUB */
-    { ngx_string("buffer_output"),
+    { 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("postpone_output"),
+    { 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, postpone_output),
+      offsetof(ngx_http_write_filter_conf_t, limit_rate),
       NULL },
 
       ngx_null_command
@@ -138,7 +138,7 @@
         return NGX_OK;
     }
 
-    if (r->delayed) {
+    if (r->connection->write->delayed) {
         return NGX_AGAIN;
     }
 
@@ -152,16 +152,18 @@
 
     sent = r->connection->sent;
 
-    chain = ngx_write_chain(r->connection, ctx->out);
+    chain = ngx_write_chain(r->connection, ctx->out,
+                            conf->limit_rate ? conf->limit_rate:
+                                               OFF_T_MAX_VALUE);
 
     ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
                    "http write filter %X", chain);
 
-#if 1
-    sent = r->connection->sent - sent;
-    r->delayed = 1;
-    ngx_add_timer(r->connection->write, sent * 1000 / (4 * 1024));
-#endif
+    if (conf->limit_rate) {
+        sent = r->connection->sent - sent;
+        r->connection->write->delayed = 1;
+        ngx_add_timer(r->connection->write, sent * 1000 / conf->limit_rate);
+    }
 
     if (chain == NGX_CHAIN_ERROR) {
         return NGX_ERROR;
@@ -186,6 +188,7 @@
                   NULL);
 
     conf->postpone_output = NGX_CONF_UNSET_SIZE;
+    conf->limit_rate = NGX_CONF_UNSET_SIZE;
 
     return conf;
 }
@@ -200,6 +203,8 @@
     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;
 }