diff --git a/patches/nginx-1.2.6-allow_request_body_updating.patch b/patches/nginx-1.2.6-allow_request_body_updating.patch
deleted file mode 100644
index 1c51454..0000000
--- a/patches/nginx-1.2.6-allow_request_body_updating.patch
+++ /dev/null
@@ -1,136 +0,0 @@
-diff -ur nginx-1.2.6/src/http/ngx_http_core_module.c nginx-1.2.6-patched/src/http/ngx_http_core_module.c
---- nginx-1.2.6/src/http/ngx_http_core_module.c	2012-08-06 10:31:32.000000000 -0700
-+++ nginx-1.2.6-patched/src/http/ngx_http_core_module.c	2012-08-30 11:37:42.388213974 -0700
-@@ -2420,6 +2420,8 @@
- 
-     sr->request_body = r->request_body;
- 
-+    sr->content_length_n = -1;
-+
-     sr->method = NGX_HTTP_GET;
-     sr->http_version = r->http_version;
- 
-diff -ur nginx-1.2.6/src/http/ngx_http_request_body.c nginx-1.2.6-patched/src/http/ngx_http_request_body.c
---- nginx-1.2.6/src/http/ngx_http_request_body.c	2012-04-12 12:35:41.000000000 -0700
-+++ nginx-1.2.6-patched/src/http/ngx_http_request_body.c	2012-08-30 11:37:42.388213974 -0700
-@@ -39,7 +39,7 @@
- 
-     r->main->count++;
- 
--    if (r->request_body || r->discard_body) {
-+    if (r->request_body || r->discard_body || r->content_length_n == 0) {
-         post_handler(r);
-         return NGX_OK;
-     }
-@@ -441,7 +441,7 @@
-     ssize_t       size;
-     ngx_event_t  *rev;
- 
--    if (r != r->main || r->discard_body) {
-+    if (r != r->main || r->discard_body || r->content_length_n == 0) {
-         return NGX_OK;
-     }
- 
-@@ -457,20 +457,22 @@
-         ngx_del_timer(rev);
-     }
- 
--    if (r->headers_in.content_length_n <= 0 || r->request_body) {
-+    r->content_length_n = r->headers_in.content_length_n;
-+
-+    if (r->content_length_n <= 0 || r->request_body) {
-         return NGX_OK;
-     }
- 
-     size = r->header_in->last - r->header_in->pos;
- 
-     if (size) {
--        if (r->headers_in.content_length_n > size) {
-+        if (r->content_length_n > size) {
-             r->header_in->pos += size;
--            r->headers_in.content_length_n -= size;
-+            r->content_length_n -= size;
- 
-         } else {
--            r->header_in->pos += (size_t) r->headers_in.content_length_n;
--            r->headers_in.content_length_n = 0;
-+            r->header_in->pos += (size_t) r->content_length_n;
-+            r->content_length_n = 0;
-             return NGX_OK;
-         }
-     }
-@@ -569,7 +571,7 @@
-                    "http read discarded body");
- 
-     for ( ;; ) {
--        if (r->headers_in.content_length_n == 0) {
-+        if (r->content_length_n == 0) {
-             r->read_event_handler = ngx_http_block_reading;
-             return NGX_OK;
-         }
-@@ -578,9 +580,9 @@
-             return NGX_AGAIN;
-         }
- 
--        size = (r->headers_in.content_length_n > NGX_HTTP_DISCARD_BUFFER_SIZE) ?
-+        size = (r->content_length_n > NGX_HTTP_DISCARD_BUFFER_SIZE) ?
-                    NGX_HTTP_DISCARD_BUFFER_SIZE:
--                   (size_t) r->headers_in.content_length_n;
-+                   (size_t) r->content_length_n;
- 
-         n = r->connection->recv(r->connection, buffer, size);
- 
-@@ -597,7 +599,7 @@
-             return NGX_OK;
-         }
- 
--        r->headers_in.content_length_n -= n;
-+        r->content_length_n -= n;
-     }
- }
- 
-diff -ur nginx-1.2.6/src/http/ngx_http_request.c nginx-1.2.6-patched/src/http/ngx_http_request.c
---- nginx-1.2.6/src/http/ngx_http_request.c	2012-08-06 10:36:30.000000000 -0700
-+++ nginx-1.2.6-patched/src/http/ngx_http_request.c	2012-08-30 11:37:42.395213999 -0700
-@@ -287,6 +287,8 @@
- 
-         r->pipeline = hc->pipeline;
- 
-+        r->content_length_n = -1;
-+
-         if (hc->nbusy) {
-             r->header_in = hc->busy[0];
-         }
-@@ -298,6 +300,8 @@
-             return;
-         }
- 
-+        r->content_length_n = -1;
-+
-         hc->request = r;
-     }
- 
-diff -ur nginx-1.2.6/src/http/ngx_http_request.h nginx-1.2.6-patched/src/http/ngx_http_request.h
---- nginx-1.2.6/src/http/ngx_http_request.h	2012-07-02 10:41:52.000000000 -0700
-+++ nginx-1.2.6-patched/src/http/ngx_http_request.h	2012-08-30 11:39:37.085644830 -0700
-@@ -9,6 +9,9 @@
- #define _NGX_HTTP_REQUEST_H_INCLUDED_
- 
- 
-+#define HAVE_ALLOW_REQUEST_BODY_UPDATING_PATCH
-+
-+
- #define NGX_HTTP_MAX_URI_CHANGES           10
- #define NGX_HTTP_MAX_SUBREQUESTS           200
- 
-@@ -375,6 +378,9 @@
-     ngx_pool_t                       *pool;
-     ngx_buf_t                        *header_in;
- 
-+    off_t                             content_length_n;
-+                                          /* for discarding request body */
-+
-     ngx_http_headers_in_t             headers_in;
-     ngx_http_headers_out_t            headers_out;
- 
-Only in nginx-1.2.6-patched/src/http: ngx_http_request.h.orig
diff --git a/patches/nginx-1.2.6-dtrace.patch b/patches/nginx-1.2.6-dtrace.patch
index 6d28544..a8bd510 100644
--- a/patches/nginx-1.2.6-dtrace.patch
+++ b/patches/nginx-1.2.6-dtrace.patch
@@ -454,10 +454,10 @@ index efbc244..8d81aab 100644
  
 diff --git a/src/dtrace/nginx.stp b/src/dtrace/nginx.stp
 new file mode 100644
-index 0000000..5bae185
+index 0000000..8a5a54a
 --- /dev/null
 +++ b/src/dtrace/nginx.stp
-@@ -0,0 +1,269 @@
+@@ -0,0 +1,278 @@
 +/* tapset for nginx */
 +
 +
@@ -549,6 +549,10 @@ index 0000000..5bae185
 +    return @cast(cl, "ngx_chain_t", "NGX_SBIN_PATH")->next
 +}
 +
++function ngx_buf_tag(b)
++{
++    return @cast(b, "ngx_buf_t", "NGX_SBIN_PATH")->tag
++}
 +
 +function ngx_buf_in_memory(b)
 +{
@@ -658,9 +662,14 @@ index 0000000..5bae185
 +            out .= "<flush>"
 +        }
 +
++        tag = ngx_buf_tag(buf)
++        if (tag) {
++            out .= sprintf("<tag:%p>", tag)
++        }
++
 +        cl = ngx_chain_next(cl)
 +        if (cl) {
-+            out .= sprintf(" ")
++            out .= " "
 +        }
 +    }
 +    return out
@@ -891,7 +900,7 @@ index f1f8a48..91bdd64 100644
                  return NGX_CONF_ERROR;
              }
 diff --git a/src/http/ngx_http_core_module.c b/src/http/ngx_http_core_module.c
-index 18402df..1487fef 100644
+index e02a251..6371fbc 100644
 --- a/src/http/ngx_http_core_module.c
 +++ b/src/http/ngx_http_core_module.c
 @@ -8,6 +8,7 @@
@@ -911,7 +920,7 @@ index 18402df..1487fef 100644
          ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
                        "subrequests cycle while processing \"%V\"", uri);
          r->main->subrequests = 1;
-@@ -2491,6 +2494,8 @@ ngx_http_subrequest(ngx_http_request_t *r,
+@@ -2489,6 +2492,8 @@ ngx_http_subrequest(ngx_http_request_t *r,
  
      *psr = sr;
  
@@ -1002,7 +1011,7 @@ index 0000000..d7d2d45
 +
 +#endif /* _NGX_HTTP_PROBE_H_INCLUDED_ */
 diff --git a/src/http/ngx_http_request.c b/src/http/ngx_http_request.c
-index c44a2cc..fa3bece 100644
+index ee00fd3..441b5cc 100644
 --- a/src/http/ngx_http_request.c
 +++ b/src/http/ngx_http_request.c
 @@ -8,6 +8,7 @@
@@ -1013,7 +1022,7 @@ index c44a2cc..fa3bece 100644
  
  
  static void ngx_http_init_request(ngx_event_t *ev);
-@@ -865,6 +866,8 @@ ngx_http_process_request_line(ngx_event_t *rev)
+@@ -861,6 +862,8 @@ ngx_http_process_request_line(ngx_event_t *rev)
              }
  #endif
  
@@ -1022,7 +1031,7 @@ index c44a2cc..fa3bece 100644
              ngx_log_debug1(NGX_LOG_DEBUG_HTTP, c->log, 0,
                             "http request line: \"%V\"", &r->request_line);
  
-@@ -1112,6 +1115,8 @@ ngx_http_process_request_headers(ngx_event_t *rev)
+@@ -1108,6 +1111,8 @@ ngx_http_process_request_headers(ngx_event_t *rev)
                  return;
              }
  
@@ -1031,7 +1040,7 @@ index c44a2cc..fa3bece 100644
              ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
                             "http header: \"%V: %V\"",
                             &h->key, &h->value);
-@@ -1962,7 +1967,11 @@ ngx_http_finalize_request(ngx_http_request_t *r, ngx_int_t rc)
+@@ -1958,7 +1963,11 @@ ngx_http_finalize_request(ngx_http_request_t *r, ngx_int_t rc)
      }
  
      if (r != r->main && r->post_subrequest) {
@@ -1043,7 +1052,7 @@ index c44a2cc..fa3bece 100644
      }
  
      if (rc == NGX_ERROR
-@@ -2012,6 +2021,8 @@ ngx_http_finalize_request(ngx_http_request_t *r, ngx_int_t rc)
+@@ -2008,6 +2017,8 @@ ngx_http_finalize_request(ngx_http_request_t *r, ngx_int_t rc)
  
          if (r->buffered || r->postponed) {
  
@@ -1052,7 +1061,7 @@ index c44a2cc..fa3bece 100644
              if (ngx_http_set_write_handler(r) != NGX_OK) {
                  ngx_http_terminate_request(r, 0);
              }
-@@ -2048,10 +2059,14 @@ ngx_http_finalize_request(ngx_http_request_t *r, ngx_int_t rc)
+@@ -2044,10 +2055,14 @@ ngx_http_finalize_request(ngx_http_request_t *r, ngx_int_t rc)
                  pr->postponed = pr->postponed->next;
              }
  
@@ -1067,7 +1076,7 @@ index c44a2cc..fa3bece 100644
              ngx_log_debug2(NGX_LOG_DEBUG_HTTP, c->log, 0,
                             "http finalize non-active request: \"%V?%V\"",
                             &r->uri, &r->args);
-@@ -2063,6 +2078,8 @@ ngx_http_finalize_request(ngx_http_request_t *r, ngx_int_t rc)
+@@ -2059,6 +2074,8 @@ ngx_http_finalize_request(ngx_http_request_t *r, ngx_int_t rc)
              }
          }
  
@@ -1077,7 +1086,7 @@ index c44a2cc..fa3bece 100644
              r->main->count++;
              ngx_http_terminate_request(r, 0);
 diff --git a/src/http/ngx_http_request_body.c b/src/http/ngx_http_request_body.c
-index d0a8ecc..40b2061 100644
+index 3c69d05..89858d0 100644
 --- a/src/http/ngx_http_request_body.c
 +++ b/src/http/ngx_http_request_body.c
 @@ -8,6 +8,7 @@
@@ -1091,7 +1100,7 @@ index d0a8ecc..40b2061 100644
 @@ -40,11 +41,15 @@ ngx_http_read_client_request_body(ngx_http_request_t *r,
      r->main->count++;
  
-     if (r->request_body || r->discard_body || r->content_length_n == 0) {
+     if (r->request_body || r->discard_body) {
 +        ngx_http_probe_read_body_abort(r,
 +                                       r->request_body ? "body exists"
 +                                                       : "body discarded");
diff --git a/patches/nginx-1.3.11-channel-uninit-params.patch b/patches/nginx-1.3.11-channel-uninit-params.patch
new file mode 100644
index 0000000..b43d169
--- /dev/null
+++ b/patches/nginx-1.3.11-channel-uninit-params.patch
@@ -0,0 +1,42 @@
+diff -urp nginx-1.3.11/src/os/unix/ngx_channel.c nginx-1.3.11-patched/src/os/unix/ngx_channel.c
+--- nginx-1.3.11/src/os/unix/ngx_channel.c	2012-01-18 07:07:43.000000000 -0800
++++ nginx-1.3.11-patched/src/os/unix/ngx_channel.c	2012-09-17 11:33:09.215394217 -0700
+@@ -31,6 +31,8 @@ ngx_write_channel(ngx_socket_t s, ngx_ch
+         msg.msg_controllen = 0;
+ 
+     } else {
++        ngx_memzero(&cmsg, sizeof(cmsg));
++
+         msg.msg_control = (caddr_t) &cmsg;
+         msg.msg_controllen = sizeof(cmsg);
+ 
+diff -urp nginx-1.3.11/src/os/unix/ngx_process_cycle.c nginx-1.3.11-patched/src/os/unix/ngx_process_cycle.c
+--- nginx-1.3.11/src/os/unix/ngx_process_cycle.c	2012-07-02 09:23:14.000000000 -0700
++++ nginx-1.3.11-patched/src/os/unix/ngx_process_cycle.c	2012-09-17 11:33:09.214394215 -0700
+@@ -356,6 +356,8 @@ ngx_start_worker_processes(ngx_cycle_t *
+ 
+     ngx_log_error(NGX_LOG_NOTICE, cycle->log, 0, "start worker processes");
+ 
++    ngx_memzero(&ch, sizeof(ngx_channel_t));
++
+     ch.command = NGX_CMD_OPEN_CHANNEL;
+ 
+     for (i = 0; i < n; i++) {
+@@ -463,6 +465,8 @@ ngx_signal_worker_processes(ngx_cycle_t
+     ngx_err_t      err;
+     ngx_channel_t  ch;
+ 
++    ngx_memzero(&ch, sizeof(ngx_channel_t));
++
+ #if (NGX_BROKEN_SCM_RIGHTS)
+ 
+     ch.command = 0;
+@@ -564,6 +568,8 @@ ngx_reap_children(ngx_cycle_t *cycle)
+     ngx_channel_t     ch;
+     ngx_core_conf_t  *ccf;
+ 
++    ngx_memzero(&ch, sizeof(ngx_channel_t));
++
+     ch.command = NGX_CMD_CLOSE_CHANNEL;
+     ch.fd = -1;
+ 
diff --git a/patches/nginx-1.3.11-dtrace.patch b/patches/nginx-1.3.11-dtrace.patch
new file mode 100644
index 0000000..705cc37
--- /dev/null
+++ b/patches/nginx-1.3.11-dtrace.patch
@@ -0,0 +1,1142 @@
+diff --git a/README b/README
+index 2f68e14..4f2c4a7 100644
+--- a/README
++++ b/README
+@@ -1,3 +1,40 @@
++This is an Nginx fork that adds dtrace USDT probes.
+ 
+-Documentation is available at http://nginx.org
++This is still under development and not usable yet.
++
++Installation:
++
++    ./configure --with-dtrace-probes \
++        --with-dtrace=/usr/sbin/dtrace \
++        ...
++    make
++    make install
++
++Usage on Linux (with systemtap):
++
++    # make the stap-nginx script visiable in your PATH
++    export PATH=/usr/local/nginx/sbin:$PATH
++
++    # list all the static probes available in your nginx
++    stap-nginx -L 'process("nginx").mark("*")'
++
++    # run the test.stp file
++    stap-nginx test.stp
++
++Sample test.stp file:
++
++    probe begin
++    {
++        print("Tracing.  Hit CTRL-C to stop.\n")
++    }
++
++    probe process("nginx").mark("http-subrequest-start")
++    {
++        printf("uri: %s?%s\n", ngx_http_req_uri($arg1),
++            ngx_http_req_args($arg1))
++    }
++
++For now, only tested on Solaris 11 Express and Fedora Linux 17.
++
++The original Nginx documentation is available at http://nginx.org
+ 
+diff --git a/auto/install b/auto/install
+index 254f9bc..0252fef 100644
+--- a/auto/install
++++ b/auto/install
+@@ -16,6 +16,20 @@ END
+ fi
+ 
+ 
++case ".$NGX_STAP_NGX_PATH" in
++    ./*)
++    ;;
++
++    .)
++        NGX_STAP_NGX_PATH=$NGX_PREFIX/sbin/stap-nginx
++    ;;
++
++    *)
++        NGX_STAP_NGX_PATH=$NGX_PREFIX/$NGX_STAP_NGX_PATH
++    ;;
++esac
++
++
+ case ".$NGX_SBIN_PATH" in
+     ./*)
+     ;;
+@@ -53,6 +67,16 @@ case ".$NGX_PID_PATH" in
+ esac
+ 
+ 
++case ".$NGX_TAPSET_PREFIX" in
++    ./* | .)
++    ;;
++
++    *)
++        NGX_TAPSET_PREFIX=$NGX_PREFIX/$NGX_TAPSET_PREFIX
++    ;;
++esac
++
++
+ case ".$NGX_ERROR_LOG_PATH" in
+     ./* | .)
+     ;;
+@@ -151,6 +175,36 @@ install:	$NGX_OBJS${ngx_dirsep}nginx${ngx_binext} \
+ 		|| cp -R $NGX_HTML '\$(DESTDIR)$NGX_PREFIX'
+ END
+ 
++if [ $NGX_DTRACE = YES -a $DTRACE_FROM_SYSTEMTAP = YES ]; then
++
++    ngx_tapset_srcs="$NGX_TAPSET_SRCS"
++
++        cat << END                                            >> $NGX_MAKEFILE
++	test -d '\$(DESTDIR)$NGX_TAPSET_PREFIX' || \
++		mkdir -p '\$(DESTDIR)$NGX_TAPSET_PREFIX'
++END
++
++    for ngx_tapset_src in $ngx_tapset_srcs
++    do
++        ngx_tapset_file=`basename $ngx_tapset_src`
++
++        cat << END                                            >> $NGX_MAKEFILE
++
++	sed -e "s|NGX_SBIN_PATH|$NGX_SBIN_PATH|g" $ngx_long_cont \
++                $ngx_tapset_src > '\$(DESTDIR)$NGX_TAPSET_PREFIX/$ngx_tapset_file'
++END
++
++    done
++
++    cat << END                                                >> $NGX_MAKEFILE
++
++	test -d '\$(DESTDIR)`dirname "$NGX_STAP_NGX_PATH"`' || \
++		mkdir -p '\$(DESTDIR)`dirname "$NGX_STAP_NGX_PATH"`'
++	cp $NGX_OBJS/stap-nginx '\$(DESTDIR)$NGX_STAP_NGX_PATH'
++	chmod 0755 '\$(DESTDIR)$NGX_STAP_NGX_PATH'
++END
++
++fi
+ 
+ if test -n "$NGX_ERROR_LOG_PATH"; then
+     cat << END                                                >> $NGX_MAKEFILE
+@@ -162,6 +216,18 @@ END
+ fi
+ 
+ 
++if [ $NGX_DTRACE = YES ]; then
++    cat << END                                                >> $NGX_MAKEFILE
++
++$NGX_OBJS${ngx_dirsep}stap-nginx: src/dtrace/stap-nginx
++	sed -e "s|NGX_TAPSET_PREFIX|$NGX_TAPSET_PREFIX|g" $ngx_long_cont \
++            -e "s|NGX_SBIN_DIR|`dirname $NGX_SBIN_PATH`|g" $ngx_long_cont \
++            -e "s|NGX_SBIN_PATH|$NGX_SBIN_PATH|g" $ngx_long_cont \
++            src/dtrace/stap-nginx > $NGX_OBJS${ngx_dirsep}stap-nginx
++END
++fi
++
++
+ # create Makefile
+ 
+ cat << END >> Makefile
+diff --git a/auto/make b/auto/make
+index 05b7454..aa813b1 100644
+--- a/auto/make
++++ b/auto/make
+@@ -26,6 +26,9 @@ LINK =	$LINK
+ 
+ END
+ 
++if [ $NGX_DTRACE = YES ]; then
++    echo DTRACE = $DTRACE                   >> $NGX_MAKEFILE
++fi
+ 
+ if test -n "$NGX_PERL_CFLAGS"; then
+     echo NGX_PERL_CFLAGS = $NGX_PERL_CFLAGS                   >> $NGX_MAKEFILE
+@@ -177,6 +180,44 @@ ngx_objs=`echo $ngx_all_objs $ngx_modules_obj \
+     | sed -e "s/  *\([^ ][^ ]*\)/$ngx_long_regex_cont\1/g" \
+           -e "s/\//$ngx_regex_dirsep/g"`
+ 
++if [ $NGX_DTRACE = YES ]; then
++
++    ngx_dtrace_obj=$NGX_OBJS${ngx_dirsep}ngx_dtrace_provider.$ngx_objext
++
++    ngx_dtrace_h=$NGX_OBJS${ngx_dirsep}ngx_dtrace_provider.h
++
++    ngx_dtrace_d=$NGX_OBJS${ngx_dirsep}dtrace_providers.d
++
++    ngx_dtrace_providers=`echo $NGX_DTRACE_PROVIDERS \
++        | sed -e "s/  *\([^ ][^ ]*\)/$ngx_long_regex_cont\1/g" \
++              -e "s/\//$ngx_regex_dirsep/g"`
++
++    cat << END                                                >> $NGX_MAKEFILE
++
++all: $NGX_OBJS${ngx_dirsep}nginx${ngx_binext}
++
++$ngx_dtrace_d: $ngx_dtrace_providers
++	cat $ngx_dtrace_providers > $ngx_dtrace_d
++
++$ngx_dtrace_h: $ngx_dtrace_d
++	\$(DTRACE) -xnolibs -h -o $ngx_dtrace_h -s $ngx_dtrace_d
++END
++
++    if [ $DTRACE_PROBE_OBJ = YES ]; then
++        cat << END                                            >> $NGX_MAKEFILE
++$ngx_dtrace_obj: $ngx_dtrace_d $ngx_deps$ngx_spacer
++	\$(DTRACE) -xnolibs -G -o $ngx_dtrace_obj -s $ngx_dtrace_d $ngx_objs
++END
++
++        ngx_deps="$ngx_deps$ngx_long_cont$ngx_dtrace_obj"
++        ngx_objs="$ngx_objs$ngx_long_cont$ngx_dtrace_obj"
++
++        if [ "$DTRACE_FROM_SYSTEMTAP" = YES ]; then
++            ngx_deps="$ngx_deps$ngx_long_cont$NGX_OBJS${ngx_dirsep}stap-nginx"
++        fi
++    fi
++fi
++
+ if test -n "$NGX_LD_OPT$CORE_LIBS"; then
+     ngx_libs=`echo $NGX_LD_OPT $CORE_LIBS \
+         | sed -e "s/\//$ngx_regex_dirsep/g" -e "s/^/$ngx_long_regex_cont/"`
+diff --git a/auto/options b/auto/options
+index a75bead..c006e5e 100644
+--- a/auto/options
++++ b/auto/options
+@@ -12,6 +12,8 @@ NGX_CONF_PATH=
+ NGX_ERROR_LOG_PATH=
+ NGX_PID_PATH=
+ NGX_LOCK_PATH=
++NGX_TAPSET_PREFIX=
++NGX_STAP_NGX_PATH=
+ NGX_USER=
+ NGX_GROUP=
+ 
+@@ -20,6 +22,12 @@ CPP=
+ NGX_OBJS=objs
+ 
+ NGX_DEBUG=NO
++NGX_DTRACE=NO
++DTRACE=dtrace
++
++DTRACE_PROBE_OBJ=YES
++DTRACE_FROM_SYSTEMTAP=NO
++
+ NGX_CC_OPT=
+ NGX_LD_OPT=
+ CPU=NO
+@@ -171,6 +179,8 @@ do
+         --error-log-path=*)              NGX_ERROR_LOG_PATH="$value";;
+         --pid-path=*)                    NGX_PID_PATH="$value"      ;;
+         --lock-path=*)                   NGX_LOCK_PATH="$value"     ;;
++        --tapset-prefix=*)               NGX_TAPSET_PREFIX="$value" ;;
++        --stap-nginx-path=*)             NGX_STAP_NGX_PATH="$value" ;;
+         --user=*)                        NGX_USER="$value"          ;;
+         --group=*)                       NGX_GROUP="$value"         ;;
+ 
+@@ -277,7 +287,8 @@ use the \"--without-http_limit_conn_module\" option instead"
+         --with-ld-opt=*)                 NGX_LD_OPT="$value"        ;;
+         --with-cpu-opt=*)                CPU="$value"               ;;
+         --with-debug)                    NGX_DEBUG=YES              ;;
+-
++        --with-dtrace=*)                 DTRACE="$value"            ;;
++        --with-dtrace-probes)            NGX_DTRACE=YES             ;;
+         --without-pcre)                  USE_PCRE=DISABLED          ;;
+         --with-pcre)                     USE_PCRE=YES               ;;
+         --with-pcre=*)                   PCRE="$value"              ;;
+@@ -331,6 +342,8 @@ cat << END
+   --error-log-path=PATH              set error log pathname
+   --pid-path=PATH                    set nginx.pid pathname
+   --lock-path=PATH                   set nginx.lock pathname
++  --tapset-prefix=PATH               set systemtap tapset directory prefix
++  --stap-nginx-path=PATH             set stap-nginx pathname
+ 
+   --user=USER                        set non-privileged user for
+                                      worker processes
+@@ -458,6 +471,8 @@ cat << END
+   --with-openssl-opt=OPTIONS         set additional build options for OpenSSL
+ 
+   --with-debug                       enable debug logging
++  --with-dtrace-probes               enable dtrace USDT probes
++  --with-dtrace=PATH                 set dtrace utility pathname
+ 
+ END
+ 
+@@ -487,6 +502,7 @@ NGX_CONF_PATH=${NGX_CONF_PATH:-conf/nginx.conf}
+ NGX_CONF_PREFIX=`dirname $NGX_CONF_PATH`
+ NGX_PID_PATH=${NGX_PID_PATH:-logs/nginx.pid}
+ NGX_LOCK_PATH=${NGX_LOCK_PATH:-logs/nginx.lock}
++NGX_TAPSET_PREFIX=${NGX_TAPSET_PREFIX:-tapset}
+ 
+ if [ ".$NGX_ERROR_LOG_PATH" = ".stderr" ]; then
+     NGX_ERROR_LOG_PATH=
+diff --git a/auto/os/darwin b/auto/os/darwin
+index 590e036..af33cf3 100644
+--- a/auto/os/darwin
++++ b/auto/os/darwin
+@@ -114,3 +114,6 @@ ngx_feature_libs=
+ ngx_feature_test="int32_t  lock, n;
+                   n = OSAtomicCompareAndSwap32Barrier(0, 1, lock)"
+ . auto/feature
++
++DTRACE_PROBE_OBJ=NO
++
+diff --git a/auto/os/freebsd b/auto/os/freebsd
+index 6aa823f..ee15166 100644
+--- a/auto/os/freebsd
++++ b/auto/os/freebsd
+@@ -142,3 +142,8 @@ if [ $version -ge 701000 ]; then
+     echo " + cpuset_setaffinity() found"
+     have=NGX_HAVE_CPUSET_SETAFFINITY . auto/have
+ fi
++
++if [ $NGX_DTRACE = YES ]; then
++    NGX_LD_OPT="$NGX_LD_OPT -lelf"
++fi
++
+diff --git a/auto/os/linux b/auto/os/linux
+index c506d3d..cbbfbf1 100644
+--- a/auto/os/linux
++++ b/auto/os/linux
+@@ -151,3 +151,5 @@ ngx_include="sys/vfs.h";     . auto/include
+ 
+ 
+ CC_AUX_FLAGS="$cc_aux_flags -D_GNU_SOURCE -D_FILE_OFFSET_BITS=64"
++
++DTRACE_FROM_SYSTEMTAP=YES
+diff --git a/auto/sources b/auto/sources
+index cc19f8d..dfa0f63 100644
+--- a/auto/sources
++++ b/auto/sources
+@@ -36,7 +36,13 @@ CORE_DEPS="src/core/nginx.h \
+            src/core/ngx_conf_file.h \
+            src/core/ngx_resolver.h \
+            src/core/ngx_open_file_cache.h \
+-           src/core/ngx_crypt.h"
++           src/core/ngx_crypt.h \
++           src/core/ngx_core_probe.h"
++
++
++if [ $NGX_DTRACE = YES ]; then
++    CORE_DEPS="$CORE_DEPS objs/ngx_dtrace_provider.h"
++fi
+ 
+ 
+ CORE_SRCS="src/core/nginx.c \
+@@ -83,14 +89,15 @@ OPENSSL_SRCS="src/event/ngx_event_openssl.c \
+ 
+ EVENT_MODULES="ngx_events_module ngx_event_core_module"
+ 
+-EVENT_INCS="src/event src/event/modules"
++EVENT_INCS="src/event src/event/modules src/http src/http/modules"
+ 
+ EVENT_DEPS="src/event/ngx_event.h \
+             src/event/ngx_event_timer.h \
+             src/event/ngx_event_posted.h \
+             src/event/ngx_event_busy_lock.h \
+             src/event/ngx_event_connect.h \
+-            src/event/ngx_event_pipe.h"
++            src/event/ngx_event_pipe.h \
++            src/event/ngx_event_probe.h"
+ 
+ EVENT_SRCS="src/event/ngx_event.c \
+             src/event/ngx_event_timer.c \
+@@ -292,7 +299,8 @@ HTTP_DEPS="src/http/ngx_http.h \
+            src/http/ngx_http_script.h \
+            src/http/ngx_http_upstream.h \
+            src/http/ngx_http_upstream_round_robin.h \
+-           src/http/ngx_http_busy_lock.h"
++           src/http/ngx_http_busy_lock.h \
++           src/http/ngx_http_probe.h"
+ 
+ HTTP_SRCS="src/http/ngx_http.c \
+            src/http/ngx_http_core_module.c \
+@@ -534,3 +542,8 @@ NGX_GOOGLE_PERFTOOLS_MODULE=ngx_google_perftools_module
+ NGX_GOOGLE_PERFTOOLS_SRCS=src/misc/ngx_google_perftools_module.c
+ 
+ NGX_CPP_TEST_SRCS=src/misc/ngx_cpp_test_module.cpp
++
++NGX_DTRACE_PROVIDERS=src/dtrace/nginx_provider.d
++
++NGX_TAPSET_SRCS=src/dtrace/nginx.stp
++
+diff --git a/auto/summary b/auto/summary
+index dcebec9..3cb269e 100644
+--- a/auto/summary
++++ b/auto/summary
+@@ -92,6 +92,19 @@ else
+     echo "  nginx logs errors to stderr"
+ fi
+ 
++if [ $NGX_DTRACE = YES ]; then
++    cat << END
++  nginx dtrace static probes enabled
++END
++
++    if [ $DTRACE_FROM_SYSTEMTAP = YES ]; then
++        cat << END
++  nginx systemtap tapset prefix: "$NGX_TAPSET_PREFIX"
++  nginx systemtap wrapper script: "$NGX_STAP_NGX_PATH"
++END
++    fi
++fi
++
+ cat << END
+   nginx http access log file: "$NGX_HTTP_LOG_PATH"
+   nginx http client request body temporary files: "$NGX_HTTP_CLIENT_TEMP_PATH"
+diff --git a/configure b/configure
+index d7d8189..05fab87 100755
+--- a/configure
++++ b/configure
+@@ -23,6 +23,9 @@ if [ $NGX_DEBUG = YES ]; then
+     have=NGX_DEBUG . auto/have
+ fi
+ 
++if [ $NGX_DTRACE = YES ]; then
++    have=NGX_DTRACE . auto/have
++fi
+ 
+ if test -z "$NGX_PLATFORM"; then
+     echo "checking for OS"
+diff --git a/src/core/ngx_core_probe.h b/src/core/ngx_core_probe.h
+new file mode 100644
+index 0000000..91bf91e
+--- /dev/null
++++ b/src/core/ngx_core_probe.h
+@@ -0,0 +1,25 @@
++#ifndef _NGX_CORE_PROBE_H_INCLUDED_
++#define _NGX_CORE_PROBE_H_INCLUDED_
++
++
++#include <ngx_config.h>
++#include <ngx_core.h>
++#include <ngx_event.h>
++
++
++#if (NGX_DTRACE)
++
++#include <ngx_http.h>
++#include <ngx_dtrace_provider.h>
++
++#define ngx_core_probe_create_pool_done(pool, size)                             \
++    NGINX_CREATE_POOL_DONE(pool, size)
++
++#else /* !(NGX_DTRACE) */
++
++#define ngx_core_probe_create_pool_done(pool, size)
++
++#endif
++
++
++#endif /* _NGX_CORE_PROBE_H_INCLUDED_ */
+diff --git a/src/core/ngx_palloc.c b/src/core/ngx_palloc.c
+index efbc244..8d81aab 100644
+--- a/src/core/ngx_palloc.c
++++ b/src/core/ngx_palloc.c
+@@ -7,6 +7,7 @@
+ 
+ #include <ngx_config.h>
+ #include <ngx_core.h>
++#include <ngx_core_probe.h>
+ 
+ 
+ static void *ngx_palloc_block(ngx_pool_t *pool, size_t size);
+@@ -37,6 +38,8 @@ ngx_create_pool(size_t size, ngx_log_t *log)
+     p->cleanup = NULL;
+     p->log = log;
+ 
++    ngx_core_probe_create_pool_done(p, size);
++
+     return p;
+ }
+ 
+diff --git a/src/dtrace/nginx.stp b/src/dtrace/nginx.stp
+new file mode 100644
+index 0000000..8a5a54a
+--- /dev/null
++++ b/src/dtrace/nginx.stp
+@@ -0,0 +1,278 @@
++/* tapset for nginx */
++
++
++function ngx_indent(n, delta)
++{
++    s = ""
++    for (i = 0; i < n; i++) {
++        s .= delta
++    }
++
++    return s
++}
++
++
++function ngx_http_subreq_depth(r)
++{
++    depth = 0
++
++    for (pr = @cast(r, "ngx_http_request_t", "NGX_SBIN_PATH")->parent;
++         pr != 0;
++         pr = @cast(pr, "ngx_http_request_t", "NGX_SBIN_PATH")->parent)
++    {
++        depth++
++    }
++
++    return depth
++}
++
++
++function ngx_http_req_parent(r)
++{
++    return @cast(r, "ngx_http_request_s", "NGX_SBIN_PATH")->parent
++}
++
++
++/* retrieve the request uri string from the ngx_http_request_t pointer */
++function ngx_http_req_uri(r)
++{
++    len = @cast(r, "ngx_http_request_s", "NGX_SBIN_PATH")->uri->len
++
++    if (len == 0) {
++        return ""
++    }
++
++    return user_string_n(@cast(r, "ngx_http_request_s", "NGX_SBIN_PATH")->uri->data, len)
++}
++
++
++/* retrieve the request query string from the ngx_http_request_t pointer */
++function ngx_http_req_args(r)
++{
++    len = @cast(r, "ngx_http_request_s", "NGX_SBIN_PATH")->args->len
++
++    if (len == 0) {
++        return ""
++    }
++
++    return user_string_n(@cast(r, "ngx_http_request_s", "NGX_SBIN_PATH")->args->data, len)
++}
++
++
++/* retrieve the first command name (or directive name) from
++ * the ngx_module_t pointer */
++function ngx_http_module_cmd(m)
++{
++    cmds = @cast(m, "ngx_module_t", "NGX_SBIN_PATH")->commands
++    if (cmds == 0) {
++        return ""
++    }
++
++    len = @cast(cmds, "ngx_command_t", "NGX_SBIN_PATH")->name->len
++
++    if (len == 0) {
++        return ""
++    }
++
++    return user_string_n(@cast(cmds, "ngx_command_t", "NGX_SBIN_PATH")->name->data, len)
++}
++
++
++function ngx_chain_buf(cl)
++{
++    return @cast(cl, "ngx_chain_t", "NGX_SBIN_PATH")->buf
++}
++
++
++function ngx_chain_next(cl)
++{
++    return @cast(cl, "ngx_chain_t", "NGX_SBIN_PATH")->next
++}
++
++function ngx_buf_tag(b)
++{
++    return @cast(b, "ngx_buf_t", "NGX_SBIN_PATH")->tag
++}
++
++function ngx_buf_in_memory(b)
++{
++    return @cast(b, "ngx_buf_t", "NGX_SBIN_PATH")->temporary
++        || @cast(b, "ngx_buf_t", "NGX_SBIN_PATH")->memory
++        || @cast(b, "ngx_buf_t", "NGX_SBIN_PATH")->mmap
++}
++
++
++function ngx_buf_pos(b)
++{
++    return @cast(b, "ngx_buf_t", "NGX_SBIN_PATH")->pos
++}
++
++
++function ngx_buf_file_pos(b)
++{
++    return @cast(b, "ngx_buf_t", "NGX_SBIN_PATH")->file_pos
++}
++
++
++function ngx_buf_last(b)
++{
++    return @cast(b, "ngx_buf_t", "NGX_SBIN_PATH")->last
++}
++
++
++function ngx_buf_file_last(b)
++{
++    return @cast(b, "ngx_buf_t", "NGX_SBIN_PATH")->file_last
++}
++
++
++function ngx_buf_end(b)
++{
++    return @cast(b, "ngx_buf_t", "NGX_SBIN_PATH")->end
++}
++
++
++function ngx_buf_last_buf(b)
++{
++    return @cast(b, "ngx_buf_t", "/home/agentzh/git/lua-nginx-module/work/nginx/sbin/nginx")->last_buf
++}
++
++
++function ngx_buf_sync(b)
++{
++    return @cast(b, "ngx_buf_t", "/home/agentzh/git/lua-nginx-module/work/nginx/sbin/nginx")->sync
++}
++
++
++function ngx_buf_flush(b)
++{
++    return @cast(b, "ngx_buf_t", "/home/agentzh/git/lua-nginx-module/work/nginx/sbin/nginx")->flush
++}
++
++
++function ngx_buf_size(b)
++{
++    if (ngx_buf_in_memory(b)) {
++        return ngx_buf_last(b) - ngx_buf_pos(b)
++    }
++
++    return ngx_buf_file_last(b) - ngx_buf_file_pos(b)
++}
++
++
++function ngx_buf_data(b)
++{
++    return user_string_n(ngx_buf_pos(b), ngx_buf_last(b) - ngx_buf_pos(b))
++}
++
++
++function ngx_chain_writer_ctx_out(ctx)
++{
++    return @cast(c, "ngx_chain_writer_ctx_t", "NGX_SBIN_PATH")->out
++}
++
++
++function ngx_chain_dump:string (input)
++{
++    if (input == 0) {
++        return "NULL"
++    }
++
++    out = ""
++    cl = input
++    while (cl) {
++        buf = ngx_chain_buf(cl)
++
++        if (ngx_buf_in_memory(buf)) {
++            out .= sprintf("[%s]", text_str(ngx_buf_data(buf)))
++
++        } else {
++            out .= "\"\""
++        }
++
++        if (ngx_buf_last_buf(buf)) {
++            out .= "<eof>"
++        }
++
++        if (ngx_buf_sync(buf)) {
++            out .= "<sync>"
++        }
++
++        if (ngx_buf_flush(buf)) {
++            out .= "<flush>"
++        }
++
++        tag = ngx_buf_tag(buf)
++        if (tag) {
++            out .= sprintf("<tag:%p>", tag)
++        }
++
++        cl = ngx_chain_next(cl)
++        if (cl) {
++            out .= " "
++        }
++    }
++    return out
++}
++
++
++function ngx_pool_cleanup_file_name(c)
++{
++    return user_string(@cast(c, "ngx_pool_cleanup_file_t", "NGX_SBIN_PATH")->name)
++}
++
++
++function ngx_http_req_content_length(r)
++{
++    return @cast(r, "ngx_http_request_t", "NGX_SBIN_PATH")->headers_in->content_length_n
++}
++
++
++function ngx_http_req_body_temp_file_name(r)
++{
++    rb = @cast(r, "ngx_http_request_t", "NGX_SBIN_PATH")->request_body
++    if (!rb) {
++        return ""
++    }
++
++    tf = @cast(rb, "ngx_http_request_body_t", "NGX_SBIN_PATH")->temp_file
++    if (!tf) {
++        return ""
++    }
++
++    len = @cast(tf, "ngx_temp_file_t", "NGX_SBIN_PATH")->file->name->len
++
++    return user_string_n(@cast(tf, "ngx_temp_file_t", "NGX_SBIN_PATH")->file->name->data, len)
++}
++
++
++function ngx_table_elt_key(e)
++{
++    len = @cast(e, "ngx_table_elt_t", "NGX_SBIN_PATH")->key->len
++
++    return user_string_n(@cast(e, "ngx_table_elt_t", "NGX_SBIN_PATH")->key->data, len)
++}
++
++
++function ngx_table_elt_value(e)
++{
++    len = @cast(e, "ngx_table_elt_t", "NGX_SBIN_PATH")->value->len
++
++    return user_string_n(@cast(e, "ngx_table_elt_t", "NGX_SBIN_PATH")->value->data, len)
++}
++
++
++function ngx_iovec_dump:string (iov, iovcnt) {
++    out = ""
++    for (i = 0; i < iovcnt; i++) {
++        out .= sprintf("\"%s\"(%p)", text_str(user_string_n(
++                @cast(iov, "struct iovec")[i]->iov_base,
++                @cast(iov, "struct iovec")[i]->iov_len)
++            ), @cast(iov, "struct iovec")[i]->iov_base)
++        if (i != iovcnt - 1) {
++            out .= " "
++        }
++    }
++    return out
++}
++
+diff --git a/src/dtrace/nginx_provider.d b/src/dtrace/nginx_provider.d
+new file mode 100644
+index 0000000..147ca12
+--- /dev/null
++++ b/src/dtrace/nginx_provider.d
+@@ -0,0 +1,41 @@
++typedef struct { int dummy; } ngx_http_request_t;
++typedef struct { int dummy; } ngx_str_t;
++typedef int64_t ngx_int_t;
++typedef uint64_t ngx_uint_t;
++typedef ngx_uint_t ngx_msec_t;
++typedef struct { int dummy; } ngx_module_t;
++typedef struct { int dummy; } ngx_http_module_t;
++typedef struct { int dummy; } ngx_table_elt_t;
++typedef struct { int dummy; } ngx_event_t;
++typedef struct { int dummy; } ngx_pool_t;
++typedef char unsigned u_char;
++
++
++provider nginx {
++    /* probes for subrequests */
++    probe http__subrequest__cycle(ngx_http_request_t *pr, ngx_str_t *uri, ngx_str_t *args);
++    probe http__subrequest__start(ngx_http_request_t *r);
++    probe http__subrequest__finalize_writing(ngx_http_request_t *r);
++    probe http__subrequest__finalize_nonactive(ngx_http_request_t *r);
++    probe http__subrequest__wake__parent(ngx_http_request_t *r);
++    probe http__subrequest__done(ngx_http_request_t *r);
++    probe http__subrequest__post__start(ngx_http_request_t *r, ngx_int_t rc);
++    probe http__subrequest__post__done(ngx_http_request_t *r, ngx_int_t rc);
++    probe http__module__post__config(ngx_module_t *m);
++    probe http__read__body__abort(ngx_http_request_t *r, char *reason);
++    probe http__read__body__done(ngx_http_request_t *r);
++    probe http__read__req__line__done(ngx_http_request_t *r);
++    probe http__read__req__header__done(ngx_http_request_t *r, ngx_table_elt_t *h);
++    probe timer__add(ngx_event_t *ev, ngx_msec_t timer);
++    probe timer__del(ngx_event_t *ev);
++    probe timer__expire(ngx_event_t *ev);
++    probe create__pool__done(ngx_pool_t *pool, size_t size);
++};
++
++
++#pragma D attributes Evolving/Evolving/Common      provider nginx provider
++#pragma D attributes Private/Private/Unknown       provider nginx module
++#pragma D attributes Private/Private/Unknown       provider nginx function
++#pragma D attributes Private/Private/Common        provider nginx name
++#pragma D attributes Evolving/Evolving/Common      provider nginx args
++
+diff --git a/src/dtrace/stap-nginx b/src/dtrace/stap-nginx
+new file mode 100755
+index 0000000..1bca4cf
+--- /dev/null
++++ b/src/dtrace/stap-nginx
+@@ -0,0 +1,6 @@
++#!/bin/sh
++
++PATH="NGX_SBIN_DIR:$PATH"
++export PATH
++exec stap -d "NGX_SBIN_PATH" -I "NGX_TAPSET_PREFIX" "$@"
++
+diff --git a/src/event/ngx_event_probe.h b/src/event/ngx_event_probe.h
+new file mode 100644
+index 0000000..5aa0397
+--- /dev/null
++++ b/src/event/ngx_event_probe.h
+@@ -0,0 +1,33 @@
++#ifndef _NGX_EVENT_PROBE_H_INCLUDED_
++#define _NGX_EVENT_PROBE_H_INCLUDED_
++
++
++#include <ngx_config.h>
++#include <ngx_core.h>
++#include <ngx_event.h>
++
++
++#if (NGX_DTRACE)
++
++#include <ngx_http.h>
++#include <ngx_dtrace_provider.h>
++
++#define ngx_event_probe_timer_add(ev, timer)                                 \
++    NGINX_TIMER_ADD(ev, timer)
++
++#define ngx_event_probe_timer_del(ev)                                        \
++    NGINX_TIMER_DEL(ev)
++
++#define ngx_event_probe_timer_expire(ev)                                     \
++    NGINX_TIMER_EXPIRE(ev)
++
++#else /* !(NGX_DTRACE) */
++
++#define ngx_event_probe_timer_add(ev, timer)
++#define ngx_event_probe_timer_del(ev)
++#define ngx_event_probe_timer_expire(ev)
++
++#endif
++
++
++#endif /* _NGX_EVENT_PROBE_H_INCLUDED_ */
+diff --git a/src/event/ngx_event_timer.c b/src/event/ngx_event_timer.c
+index 177ac1c..531cccc 100644
+--- a/src/event/ngx_event_timer.c
++++ b/src/event/ngx_event_timer.c
+@@ -144,6 +144,8 @@ ngx_event_expire_timers(void)
+             }
+ #endif
+ 
++            ngx_event_probe_timer_expire(ev);
++
+             ev->timedout = 1;
+ 
+             ev->handler(ev);
+diff --git a/src/event/ngx_event_timer.h b/src/event/ngx_event_timer.h
+index ec9b316..6095d8c 100644
+--- a/src/event/ngx_event_timer.h
++++ b/src/event/ngx_event_timer.h
+@@ -12,6 +12,7 @@
+ #include <ngx_config.h>
+ #include <ngx_core.h>
+ #include <ngx_event.h>
++#include <ngx_event_probe.h>
+ 
+ 
+ #define NGX_TIMER_INFINITE  (ngx_msec_t) -1
+@@ -35,6 +36,8 @@ extern ngx_thread_volatile ngx_rbtree_t  ngx_event_timer_rbtree;
+ static ngx_inline void
+ ngx_event_del_timer(ngx_event_t *ev)
+ {
++    ngx_event_probe_timer_del(ev);
++
+     ngx_log_debug2(NGX_LOG_DEBUG_EVENT, ev->log, 0,
+                    "event timer del: %d: %M",
+                     ngx_event_ident(ev->data), ev->timer.key);
+@@ -85,6 +88,8 @@ ngx_event_add_timer(ngx_event_t *ev, ngx_msec_t timer)
+ 
+     ev->timer.key = key;
+ 
++    ngx_event_probe_timer_add(ev, timer);
++
+     ngx_log_debug3(NGX_LOG_DEBUG_EVENT, ev->log, 0,
+                    "event timer add: %d: %M:%M",
+                     ngx_event_ident(ev->data), timer, ev->timer.key);
+diff --git a/src/http/ngx_http.c b/src/http/ngx_http.c
+index f1f8a48..91bdd64 100644
+--- a/src/http/ngx_http.c
++++ b/src/http/ngx_http.c
+@@ -8,6 +8,7 @@
+ #include <ngx_config.h>
+ #include <ngx_core.h>
+ #include <ngx_http.h>
++#include <ngx_http_probe.h>
+ 
+ 
+ static char *ngx_http_block(ngx_conf_t *cf, ngx_command_t *cmd, void *conf);
+@@ -307,6 +308,9 @@ ngx_http_block(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
+         module = ngx_modules[m]->ctx;
+ 
+         if (module->postconfiguration) {
++
++            ngx_http_probe_module_post_config(ngx_modules[m]);
++
+             if (module->postconfiguration(cf) != NGX_OK) {
+                 return NGX_CONF_ERROR;
+             }
+diff --git a/src/http/ngx_http_core_module.c b/src/http/ngx_http_core_module.c
+index 96aa3de..71416fe 100644
+--- a/src/http/ngx_http_core_module.c
++++ b/src/http/ngx_http_core_module.c
+@@ -8,6 +8,7 @@
+ #include <ngx_config.h>
+ #include <ngx_core.h>
+ #include <ngx_http.h>
++#include <ngx_http_probe.h>
+ 
+ 
+ typedef struct {
+@@ -2432,6 +2433,8 @@ ngx_http_subrequest(ngx_http_request_t *r,
+     r->main->subrequests--;
+ 
+     if (r->main->subrequests == 0) {
++        ngx_http_probe_subrequest_cycle(r, uri, args);
++
+         ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
+                       "subrequests cycle while processing \"%V\"", uri);
+         r->main->subrequests = 1;
+@@ -2544,6 +2547,8 @@ ngx_http_subrequest(ngx_http_request_t *r,
+ 
+     *psr = sr;
+ 
++    ngx_http_probe_subrequest_start(sr);
++
+     return ngx_http_post_request(sr, NULL);
+ }
+ 
+diff --git a/src/http/ngx_http_probe.h b/src/http/ngx_http_probe.h
+new file mode 100644
+index 0000000..d7d2d45
+--- /dev/null
++++ b/src/http/ngx_http_probe.h
+@@ -0,0 +1,75 @@
++#ifndef _NGX_HTTP_PROBE_H_INCLUDED_
++#define _NGX_HTTP_PROBE_H_INCLUDED_
++
++
++#include <ngx_config.h>
++#include <ngx_core.h>
++#include <ngx_http.h>
++
++
++#if (NGX_DTRACE)
++
++#include <ngx_dtrace_provider.h>
++
++#define ngx_http_probe_subrequest_cycle(pr, uri, args)                       \
++    NGINX_HTTP_SUBREQUEST_CYCLE(pr, uri, args)
++
++#define ngx_http_probe_subrequest_start(r)                                   \
++    NGINX_HTTP_SUBREQUEST_START(r)
++
++#define ngx_http_probe_subrequest_finalize_writing(r)                        \
++    NGINX_HTTP_SUBREQUEST_FINALIZE_WRITING(r)
++
++#define ngx_http_probe_subrequest_finalize_nonactive(r)                      \
++    NGINX_HTTP_SUBREQUEST_FINALIZE_NONACTIVE(r)
++
++#define ngx_http_probe_subrequest_finalize_nonactive(r)                      \
++    NGINX_HTTP_SUBREQUEST_FINALIZE_NONACTIVE(r)
++
++#define ngx_http_probe_subrequest_wake_parent(r)                             \
++    NGINX_HTTP_SUBREQUEST_WAKE_PARENT(r)
++
++#define ngx_http_probe_subrequest_done(r)                                    \
++    NGINX_HTTP_SUBREQUEST_DONE(r)
++
++#define ngx_http_probe_subrequest_post_start(r, rc)                          \
++    NGINX_HTTP_SUBREQUEST_POST_START(r, rc)
++
++#define ngx_http_probe_subrequest_post_done(r, rc)                           \
++    NGINX_HTTP_SUBREQUEST_POST_DONE(r, rc)
++
++#define ngx_http_probe_module_post_config(m)                                 \
++    NGINX_HTTP_MODULE_POST_CONFIG(m)
++
++#define ngx_http_probe_read_body_abort(r, reason)                            \
++    NGINX_HTTP_READ_BODY_ABORT(r, reason)
++
++#define ngx_http_probe_read_body_done(r)                                     \
++    NGINX_HTTP_READ_BODY_DONE(r)
++
++#define ngx_http_probe_read_req_line_done(r)                                 \
++    NGINX_HTTP_READ_REQ_LINE_DONE(r)
++
++#define ngx_http_probe_read_req_header_done(r, h)                               \
++    NGINX_HTTP_READ_REQ_HEADER_DONE(r, h)
++
++#else /* !(NGX_DTRACE) */
++
++#define ngx_http_probe_subrequest_cycle(pr, uri, args)
++#define ngx_http_probe_subrequest_start(r)
++#define ngx_http_probe_subrequest_finalize_writing(r)
++#define ngx_http_probe_subrequest_finalize_nonactive(r)
++#define ngx_http_probe_subrequest_wake_parent(r)
++#define ngx_http_probe_subrequest_done(r)
++#define ngx_http_probe_subrequest_post_start(r, rc)
++#define ngx_http_probe_subrequest_post_done(r, rc)
++#define ngx_http_probe_module_post_config(m)
++#define ngx_http_probe_read_body_abort(r, reason)
++#define ngx_http_probe_read_body_done(r)
++#define ngx_http_probe_read_req_line_done(r)
++#define ngx_http_probe_read_req_header_done(r, h)
++
++#endif /* NGX_DTRACE */
++
++
++#endif /* _NGX_HTTP_PROBE_H_INCLUDED_ */
+diff --git a/src/http/ngx_http_request.c b/src/http/ngx_http_request.c
+index e94e7fc..7d12b0d 100644
+--- a/src/http/ngx_http_request.c
++++ b/src/http/ngx_http_request.c
+@@ -8,6 +8,7 @@
+ #include <ngx_config.h>
+ #include <ngx_core.h>
+ #include <ngx_http.h>
++#include <ngx_http_probe.h>
+ 
+ 
+ static void ngx_http_init_request(ngx_event_t *ev);
+@@ -869,6 +870,8 @@ ngx_http_process_request_line(ngx_event_t *rev)
+             }
+ #endif
+ 
++            ngx_http_probe_read_req_line_done(r);
++
+             ngx_log_debug1(NGX_LOG_DEBUG_HTTP, c->log, 0,
+                            "http request line: \"%V\"", &r->request_line);
+ 
+@@ -1116,6 +1119,8 @@ ngx_http_process_request_headers(ngx_event_t *rev)
+                 return;
+             }
+ 
++            ngx_http_probe_read_req_header_done(r, h);
++
+             ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
+                            "http header: \"%V: %V\"",
+                            &h->key, &h->value);
+@@ -1969,7 +1974,11 @@ ngx_http_finalize_request(ngx_http_request_t *r, ngx_int_t rc)
+     }
+ 
+     if (r != r->main && r->post_subrequest) {
++        ngx_http_probe_subrequest_post_start(r, rc);
++
+         rc = r->post_subrequest->handler(r, r->post_subrequest->data, rc);
++
++        ngx_http_probe_subrequest_post_done(r, rc);
+     }
+ 
+     if (rc == NGX_ERROR
+@@ -2019,6 +2028,8 @@ ngx_http_finalize_request(ngx_http_request_t *r, ngx_int_t rc)
+ 
+         if (r->buffered || r->postponed) {
+ 
++            ngx_http_probe_subrequest_finalize_writing(r);
++
+             if (ngx_http_set_write_handler(r) != NGX_OK) {
+                 ngx_http_terminate_request(r, 0);
+             }
+@@ -2055,10 +2066,14 @@ ngx_http_finalize_request(ngx_http_request_t *r, ngx_int_t rc)
+                 pr->postponed = pr->postponed->next;
+             }
+ 
++            ngx_http_probe_subrequest_done(r);
++
+             c->data = pr;
+ 
+         } else {
+ 
++            ngx_http_probe_subrequest_finalize_nonactive(r);
++
+             ngx_log_debug2(NGX_LOG_DEBUG_HTTP, c->log, 0,
+                            "http finalize non-active request: \"%V?%V\"",
+                            &r->uri, &r->args);
+@@ -2070,6 +2085,8 @@ ngx_http_finalize_request(ngx_http_request_t *r, ngx_int_t rc)
+             }
+         }
+ 
++        ngx_http_probe_subrequest_wake_parent(r);
++
+         if (ngx_http_post_request(pr, NULL) != NGX_OK) {
+             r->main->count++;
+             ngx_http_terminate_request(r, 0);
+diff --git a/src/http/ngx_http_request_body.c b/src/http/ngx_http_request_body.c
+index 749e4ae..076cd74 100644
+--- a/src/http/ngx_http_request_body.c
++++ b/src/http/ngx_http_request_body.c
+@@ -8,6 +8,7 @@
+ #include <ngx_config.h>
+ #include <ngx_core.h>
+ #include <ngx_http.h>
++#include <ngx_http_probe.h>
+ 
+ 
+ static void ngx_http_read_client_request_body_handler(ngx_http_request_t *r);
+@@ -42,11 +43,15 @@ ngx_http_read_client_request_body(ngx_http_request_t *r,
+     r->main->count++;
+ 
+     if (r->request_body || r->discard_body) {
++        ngx_http_probe_read_body_abort(r,
++                                       r->request_body ? "body exists"
++                                                       : "body discarded");
+         post_handler(r);
+         return NGX_OK;
+     }
+ 
+     if (ngx_http_test_expect(r) != NGX_OK) {
++        ngx_http_probe_read_body_abort(r, "test expect failed");
+         rc = NGX_HTTP_INTERNAL_SERVER_ERROR;
+         goto done;
+     }
+@@ -187,6 +192,7 @@ ngx_http_read_client_request_body_handler(ngx_http_request_t *r)
+     ngx_int_t  rc;
+ 
+     if (r->connection->read->timedout) {
++        ngx_http_probe_read_body_abort(r, "timed out");
+         r->connection->timedout = 1;
+         ngx_http_finalize_request(r, NGX_HTTP_REQUEST_TIME_OUT);
+         return;
+@@ -273,6 +279,9 @@ ngx_http_do_read_client_request_body(ngx_http_request_t *r)
+             }
+ 
+             if (n == 0) {
++
++                ngx_http_probe_read_body_abort(r, "connection closed");
++
+                 ngx_log_error(NGX_LOG_INFO, c->log, 0,
+                               "client prematurely closed connection");
+             }
+@@ -356,6 +365,8 @@ ngx_http_do_read_client_request_body(ngx_http_request_t *r)
+ 
+     r->read_event_handler = ngx_http_block_reading;
+ 
++    ngx_http_probe_read_body_done(r);
++
+     rb->post_handler(r);
+ 
+     return NGX_OK;
diff --git a/patches/nginx-1.3.11-location_if_inherits_proxy.patch b/patches/nginx-1.3.11-location_if_inherits_proxy.patch
new file mode 100644
index 0000000..eec5c52
--- /dev/null
+++ b/patches/nginx-1.3.11-location_if_inherits_proxy.patch
@@ -0,0 +1,15 @@
+--- nginx-1.3.11/src/http/modules/ngx_http_proxy_module.c	2012-04-23 18:40:01.000000000 +0800
++++ nginx-1.3.11-patched/src/http/modules/ngx_http_proxy_module.c	2012-06-24 12:48:57.289834450 +0800
+@@ -3023,8 +3023,10 @@
+ 
+     if (conf->upstream.upstream || conf->proxy_lengths) {
+         clcf = ngx_http_conf_get_module_loc_conf(cf, ngx_http_core_module);
+-        if (clcf->handler == NULL && clcf->lmt_excpt) {
+-            clcf->handler = ngx_http_proxy_handler;
++        if (clcf->handler == NULL) {
++            if (clcf->lmt_excpt) {
++                clcf->handler = ngx_http_proxy_handler;
++            }
+             conf->location = prev->location;
+         }
+     }
diff --git a/patches/nginx-1.3.11-log_escape_non_ascii.patch b/patches/nginx-1.3.11-log_escape_non_ascii.patch
new file mode 100644
index 0000000..cc81381
--- /dev/null
+++ b/patches/nginx-1.3.11-log_escape_non_ascii.patch
@@ -0,0 +1,115 @@
+--- nginx-1.3.11/src/http/modules/ngx_http_log_module.c	2011-11-01 21:24:50.000000000 +0800
++++ nginx-1.3.11-patched/src/http/modules/ngx_http_log_module.c	2011-11-10 16:17:29.599039534 +0800
+@@ -61,6 +61,8 @@
+     time_t                      open_file_cache_valid;
+     ngx_uint_t                  open_file_cache_min_uses;
+ 
++    ngx_flag_t                  escape_non_ascii;
++
+     ngx_uint_t                  off;        /* unsigned  off:1 */
+ } ngx_http_log_loc_conf_t;
+ 
+@@ -104,7 +106,8 @@
+     uintptr_t data);
+ static u_char *ngx_http_log_variable(ngx_http_request_t *r, u_char *buf,
+     ngx_http_log_op_t *op);
+-static uintptr_t ngx_http_log_escape(u_char *dst, u_char *src, size_t size);
++static uintptr_t ngx_http_log_escape(ngx_http_log_loc_conf_t *lcf, u_char *dst,
++    u_char *src, size_t size);
+ 
+ 
+ static void *ngx_http_log_create_main_conf(ngx_conf_t *cf);
+@@ -146,6 +149,13 @@
+       0,
+       NULL },
+ 
++    { ngx_string("log_escape_non_ascii"),
++      NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_FLAG,
++      ngx_conf_set_flag_slot,
++      NGX_HTTP_LOC_CONF_OFFSET,
++      offsetof(ngx_http_log_loc_conf_t, escape_non_ascii),
++      NULL },
++
+       ngx_null_command
+ };
+ 
+@@ -637,6 +647,7 @@
+ ngx_http_log_variable_getlen(ngx_http_request_t *r, uintptr_t data)
+ {
+     uintptr_t                   len;
++    ngx_http_log_loc_conf_t    *lcf;
+     ngx_http_variable_value_t  *value;
+ 
+     value = ngx_http_get_indexed_variable(r, data);
+@@ -645,7 +656,9 @@
+         return 1;
+     }
+ 
+-    len = ngx_http_log_escape(NULL, value->data, value->len);
++    lcf = ngx_http_get_module_loc_conf(r, ngx_http_log_module);
++
++    len = ngx_http_log_escape(lcf, NULL, value->data, value->len);
+ 
+     value->escape = len ? 1 : 0;
+ 
+@@ -656,6 +669,7 @@
+ static u_char *
+ ngx_http_log_variable(ngx_http_request_t *r, u_char *buf, ngx_http_log_op_t *op)
+ {
++    ngx_http_log_loc_conf_t    *lcf;
+     ngx_http_variable_value_t  *value;
+ 
+     value = ngx_http_get_indexed_variable(r, op->data);
+@@ -669,16 +683,18 @@
+         return ngx_cpymem(buf, value->data, value->len);
+ 
+     } else {
+-        return (u_char *) ngx_http_log_escape(buf, value->data, value->len);
++        lcf = ngx_http_get_module_loc_conf(r, ngx_http_log_module);
++        return (u_char *) ngx_http_log_escape(lcf, buf, value->data, value->len);
+     }
+ }
+ 
+ 
+ static uintptr_t
+-ngx_http_log_escape(u_char *dst, u_char *src, size_t size)
++ngx_http_log_escape(ngx_http_log_loc_conf_t *lcf, u_char *dst, u_char *src,
++    size_t size)
+ {
+-    ngx_uint_t      n;
+-    static u_char   hex[] = "0123456789ABCDEF";
++    ngx_uint_t                   n;
++    static u_char                hex[] = "0123456789ABCDEF";
+ 
+     static uint32_t   escape[] = {
+         0xffffffff, /* 1111 1111 1111 1111  1111 1111 1111 1111 */
+@@ -698,6 +714,12 @@
+         0xffffffff, /* 1111 1111 1111 1111  1111 1111 1111 1111 */
+     };
+ 
++    if (lcf->escape_non_ascii) {
++        ngx_memset(&escape[4], 0xff, sizeof(uint32_t) * 4);
++
++    } else {
++        ngx_memzero(&escape[4], sizeof(uint32_t) * 4);
++    }
+ 
+     if (dst == NULL) {
+ 
+@@ -781,6 +803,7 @@
+     }
+ 
+     conf->open_file_cache = NGX_CONF_UNSET_PTR;
++    conf->escape_non_ascii = NGX_CONF_UNSET;
+ 
+     return conf;
+ }
+@@ -796,6 +819,8 @@
+     ngx_http_log_fmt_t        *fmt;
+     ngx_http_log_main_conf_t  *lmcf;
+ 
++    ngx_conf_merge_value(conf->escape_non_ascii, prev->escape_non_ascii, 1);
++
+     if (conf->open_file_cache == NGX_CONF_UNSET_PTR) {
+ 
+         conf->open_file_cache = prev->open_file_cache;
diff --git a/patches/nginx-1.3.11-no_Werror.patch b/patches/nginx-1.3.11-no_Werror.patch
new file mode 100644
index 0000000..8b743cb
--- /dev/null
+++ b/patches/nginx-1.3.11-no_Werror.patch
@@ -0,0 +1,24 @@
+diff -ur nginx-1.3.11/auto/cc/gcc nginx-1.3.11-patched/auto/cc/gcc
+--- nginx-1.3.11/auto/cc/gcc	2011-06-27 19:53:00.205737804 +0800
++++ nginx-1.3.11-patched/auto/cc/gcc	2011-06-27 19:53:13.837741087 +0800
+@@ -169,7 +169,7 @@
+ 
+ 
+ # stop on warning
+-CFLAGS="$CFLAGS -Werror"
++#CFLAGS="$CFLAGS -Werror"
+ 
+ # debug
+ CFLAGS="$CFLAGS -g"
+diff -ur nginx-1.3.11/auto/cc/icc nginx-1.3.11-patched/auto/cc/icc
+--- nginx-1.3.11/auto/cc/icc	2011-06-27 19:52:56.370157068 +0800
++++ nginx-1.3.11-patched/auto/cc/icc	2011-06-27 19:53:19.508916811 +0800
+@@ -139,7 +139,7 @@
+ esac
+ 
+ # stop on warning
+-CFLAGS="$CFLAGS -Werror"
++#CFLAGS="$CFLAGS -Werror"
+ 
+ # debug
+ CFLAGS="$CFLAGS -g"
diff --git a/patches/nginx-1.3.11-no_error_pages.patch b/patches/nginx-1.3.11-no_error_pages.patch
new file mode 100644
index 0000000..9070e93
--- /dev/null
+++ b/patches/nginx-1.3.11-no_error_pages.patch
@@ -0,0 +1,90 @@
+--- nginx-1.3.11/src/http/ngx_http_core_module.c	2010-12-14 18:38:42.000000000 +0800
++++ nginx-1.3.11-patched/src/http/ngx_http_core_module.c	2011-01-30 19:24:34.956354518 +0800
+@@ -57,6 +57,8 @@
+     void *conf);
+ static char *ngx_http_core_error_page(ngx_conf_t *cf, ngx_command_t *cmd,
+     void *conf);
++static char *ngx_http_core_no_error_pages(ngx_conf_t *cf, ngx_command_t *cmd,
++    void *conf);
+ static char *ngx_http_core_try_files(ngx_conf_t *cf, ngx_command_t *cmd,
+     void *conf);
+ static char *ngx_http_core_open_file_cache(ngx_conf_t *cf, ngx_command_t *cmd,
+@@ -614,6 +616,14 @@
+       0,
+       NULL },
+ 
++    { ngx_string("no_error_pages"),
++      NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_HTTP_LIF_CONF
++                        |NGX_CONF_NOARGS,
++      ngx_http_core_no_error_pages,
++      NGX_HTTP_LOC_CONF_OFFSET,
++      0,
++      NULL },
++
+     { ngx_string("try_files"),
+       NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_2MORE,
+       ngx_http_core_try_files,
+@@ -3052,7 +3062,6 @@
+      *     clcf->types = NULL;
+      *     clcf->default_type = { 0, NULL };
+      *     clcf->error_log = NULL;
+-     *     clcf->error_pages = NULL;
+      *     clcf->try_files = NULL;
+      *     clcf->client_body_path = NULL;
+      *     clcf->regex = NULL;
+@@ -3062,6 +3071,7 @@
+      *     clcf->gzip_proxied = 0;
+      */
+ 
++    clcf->error_pages = NGX_CONF_UNSET_PTR;
+     clcf->client_max_body_size = NGX_CONF_UNSET;
+     clcf->client_body_buffer_size = NGX_CONF_UNSET_SIZE;
+     clcf->client_body_timeout = NGX_CONF_UNSET_MSEC;
+@@ -3250,9 +3260,7 @@
+         }
+     }
+ 
+-    if (conf->error_pages == NULL && prev->error_pages) {
+-        conf->error_pages = prev->error_pages;
+-    }
++    ngx_conf_merge_ptr_value(conf->error_pages, prev->error_pages, NULL);
+ 
+     ngx_conf_merge_str_value(conf->default_type,
+                               prev->default_type, "text/plain");
+@@ -3988,6 +3996,10 @@
+     ngx_http_compile_complex_value_t   ccv;
+ 
+     if (clcf->error_pages == NULL) {
++        return "conflicts with \"no_error_pages\"";
++    }
++
++    if (clcf->error_pages == NGX_CONF_UNSET_PTR) {
+         clcf->error_pages = ngx_array_create(cf->pool, 4,
+                                              sizeof(ngx_http_err_page_t));
+         if (clcf->error_pages == NULL) {
+@@ -4095,6 +4107,25 @@
+ 
+ 
+ static char *
++ngx_http_core_no_error_pages(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
++{
++    ngx_http_core_loc_conf_t *clcf = conf;
++
++    if (clcf->error_pages == NULL) {
++        return "is duplicate";
++    }
++
++    if (clcf->error_pages != NGX_CONF_UNSET_PTR) {
++        return "conflicts with \"error_page\"";
++    }
++
++    clcf->error_pages = NULL;
++
++    return NGX_CONF_OK;
++}
++
++
++static char *
+ ngx_http_core_try_files(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
+ {
+     ngx_http_core_loc_conf_t *clcf = conf;
diff --git a/patches/nginx-1.3.11-no_pool.patch b/patches/nginx-1.3.11-no_pool.patch
new file mode 100644
index 0000000..c548b34
--- /dev/null
+++ b/patches/nginx-1.3.11-no_pool.patch
@@ -0,0 +1,609 @@
+diff -ur nginx-1.3.11/src/core/nginx.h nginx-1.3.11-patched/src/core/nginx.h
+--- nginx-1.3.11/src/core/nginx.h	2011-08-29 17:30:22.000000000 +0800
++++ nginx-1.3.11-patched/src/core/nginx.h	2011-09-13 12:11:03.135622101 +0800
+@@ -10,7 +10,7 @@
+ 
+ 
+ #define nginx_version      1003011
+ #define NGINX_VERSION      "1.3.11"
+-#define NGINX_VER          "ngx_openresty/" NGINX_VERSION ".unknown"
++#define NGINX_VER          "ngx_openresty/" NGINX_VERSION ".unknown (no pool)"
+ 
+ #define NGINX_VAR          "NGINX"
+diff -urx '*~' -x '*.swp' nginx-1.3.11/src/core/ngx_array.c nginx-1.3.11-patched/src/core/ngx_array.c
+--- nginx-1.3.11/src/core/ngx_array.c	2012-02-06 04:02:59.000000000 +0800
++++ nginx-1.3.11-patched/src/core/ngx_array.c	2012-06-20 23:10:36.870722387 +0800
+@@ -28,6 +28,7 @@
+     a->size = size;
+     a->nalloc = n;
+     a->pool = p;
++    a->old_elts = NULL;
+ 
+     return a;
+ }
+@@ -36,26 +37,30 @@
+ void
+ ngx_array_destroy(ngx_array_t *a)
+ {
+-    ngx_pool_t  *p;
++    ngx_pool_t          *p;
++    ngx_array_link_t    *link;
+ 
+     p = a->pool;
+ 
+-    if ((u_char *) a->elts + a->size * a->nalloc == p->d.last) {
+-        p->d.last -= a->size * a->nalloc;
++    if (a->elts) {
++        ngx_pfree(p, a->elts);
+     }
+ 
+-    if ((u_char *) a + sizeof(ngx_array_t) == p->d.last) {
+-        p->d.last = (u_char *) a;
++    for (link = a->old_elts; link; link = link->next) {
++        ngx_pfree(p, link->elts);
+     }
++
++    ngx_pfree(p, a);
+ }
+ 
+ 
+ void *
+ ngx_array_push(ngx_array_t *a)
+ {
+-    void        *elt, *new;
+-    size_t       size;
+-    ngx_pool_t  *p;
++    void                *elt, *new;
++    size_t               size;
++    ngx_pool_t          *p;
++    ngx_array_link_t    *link;
+ 
+     if (a->nelts == a->nalloc) {
+ 
+@@ -65,29 +70,27 @@
+ 
+         p = a->pool;
+ 
+-        if ((u_char *) a->elts + size == p->d.last
+-            && p->d.last + a->size <= p->d.end)
+-        {
+-            /*
+-             * the array allocation is the last in the pool
+-             * and there is space for new allocation
+-             */
+-
+-            p->d.last += a->size;
+-            a->nalloc++;
+-
+-        } else {
+-            /* allocate a new array */
+-
+-            new = ngx_palloc(p, 2 * size);
+-            if (new == NULL) {
+-                return NULL;
+-            }
+-
+-            ngx_memcpy(new, a->elts, size);
+-            a->elts = new;
+-            a->nalloc *= 2;
++        /* allocate a new array */
++
++        new = ngx_palloc(p, 2 * size);
++        if (new == NULL) {
++            return NULL;
++        }
++
++        ngx_memcpy(new, a->elts, size);
++
++        link = ngx_palloc(p, sizeof(ngx_array_link_t));
++        if (link == NULL) {
++            ngx_pfree(p, new);
++            return NULL;
+         }
++
++        link->next = a->old_elts;
++        link->elts = a->elts;
++        a->old_elts = link;
++
++        a->elts = new;
++        a->nalloc *= 2;
+     }
+ 
+     elt = (u_char *) a->elts + a->size * a->nelts;
+@@ -101,11 +104,10 @@
+ ngx_array_push_n(ngx_array_t *a, ngx_uint_t n)
+ {
+     void        *elt, *new;
+-    size_t       size;
+     ngx_uint_t   nalloc;
+     ngx_pool_t  *p;
+ 
+-    size = n * a->size;
++    ngx_array_link_t    *link;
+ 
+     if (a->nelts + n > a->nalloc) {
+ 
+@@ -113,31 +115,27 @@
+ 
+         p = a->pool;
+ 
+-        if ((u_char *) a->elts + a->size * a->nalloc == p->d.last
+-            && p->d.last + size <= p->d.end)
+-        {
+-            /*
+-             * the array allocation is the last in the pool
+-             * and there is space for new allocation
+-             */
+-
+-            p->d.last += size;
+-            a->nalloc += n;
+-
+-        } else {
+-            /* allocate a new array */
+-
+-            nalloc = 2 * ((n >= a->nalloc) ? n : a->nalloc);
+-
+-            new = ngx_palloc(p, nalloc * a->size);
+-            if (new == NULL) {
+-                return NULL;
+-            }
+-
+-            ngx_memcpy(new, a->elts, a->nelts * a->size);
+-            a->elts = new;
+-            a->nalloc = nalloc;
++        nalloc = 2 * ((n >= a->nalloc) ? n : a->nalloc);
++
++        new = ngx_palloc(p, nalloc * a->size);
++        if (new == NULL) {
++            return NULL;
++        }
++
++        ngx_memcpy(new, a->elts, a->nelts * a->size);
++
++        link = ngx_palloc(p, sizeof(ngx_array_link_t));
++        if (link == NULL) {
++            ngx_pfree(p, new);
++            return NULL;
+         }
++
++        link->next = a->old_elts;
++        link->elts = a->elts;
++        a->old_elts = link;
++
++        a->elts = new;
++        a->nalloc = nalloc;
+     }
+ 
+     elt = (u_char *) a->elts + a->size * a->nelts;
+diff -urx '*~' -x '*.swp' nginx-1.3.11/src/core/ngx_array.h nginx-1.3.11-patched/src/core/ngx_array.h
+--- nginx-1.3.11/src/core/ngx_array.h	2012-02-06 04:02:59.000000000 +0800
++++ nginx-1.3.11-patched/src/core/ngx_array.h	2012-06-20 23:25:38.800624960 +0800
+@@ -13,12 +13,23 @@
+ #include <ngx_core.h>
+ 
+ 
++typedef struct ngx_array_link_s ngx_array_link_t;
++
++
++struct ngx_array_link_s {
++    void                    *elts;
++    ngx_array_link_t        *next;
++};
++
++
+ struct ngx_array_s {
+     void        *elts;
+     ngx_uint_t   nelts;
+     size_t       size;
+     ngx_uint_t   nalloc;
+     ngx_pool_t  *pool;
++
++    ngx_array_link_t *old_elts;
+ };
+ 
+ 
+@@ -40,6 +51,7 @@
+     array->size = size;
+     array->nalloc = n;
+     array->pool = pool;
++    array->old_elts = NULL;
+ 
+     array->elts = ngx_palloc(pool, n * size);
+     if (array->elts == NULL) {
+diff -urx '*~' -x '*.swp' nginx-1.3.11/src/core/ngx_palloc.c nginx-1.3.11-patched/src/core/ngx_palloc.c
+--- nginx-1.3.11/src/core/ngx_palloc.c	2012-02-06 04:02:59.000000000 +0800
++++ nginx-1.3.11-patched/src/core/ngx_palloc.c	2012-06-20 22:56:30.148073066 +0800
+@@ -9,32 +9,23 @@
+ #include <ngx_core.h>
+ 
+ 
+-static void *ngx_palloc_block(ngx_pool_t *pool, size_t size);
+-static void *ngx_palloc_large(ngx_pool_t *pool, size_t size);
+-
+-
+ ngx_pool_t *
+ ngx_create_pool(size_t size, ngx_log_t *log)
+ {
+-    ngx_pool_t  *p;
++    ngx_pool_t        *p;
+ 
+-    p = ngx_memalign(NGX_POOL_ALIGNMENT, size, log);
++    size = sizeof(ngx_pool_t);
++    p = ngx_alloc(size, log);
+     if (p == NULL) {
+         return NULL;
+     }
+ 
+-    p->d.last = (u_char *) p + sizeof(ngx_pool_t);
+-    p->d.end = (u_char *) p + size;
+-    p->d.next = NULL;
+-    p->d.failed = 0;
++    ngx_memzero(p, size);
+ 
+     size = size - sizeof(ngx_pool_t);
+     p->max = (size < NGX_MAX_ALLOC_FROM_POOL) ? size : NGX_MAX_ALLOC_FROM_POOL;
+ 
+     p->current = p;
+-    p->chain = NULL;
+-    p->large = NULL;
+-    p->cleanup = NULL;
+     p->log = log;
+ 
+     return p;
+@@ -44,8 +35,7 @@
+ void
+ ngx_destroy_pool(ngx_pool_t *pool)
+ {
+-    ngx_pool_t          *p, *n;
+-    ngx_pool_large_t    *l;
++    ngx_pool_data_t     *d, *n;
+     ngx_pool_cleanup_t  *c;
+ 
+     for (c = pool->cleanup; c; c = c->next) {
+@@ -56,13 +46,9 @@
+         }
+     }
+ 
+-    for (l = pool->large; l; l = l->next) {
+-
+-        ngx_log_debug1(NGX_LOG_DEBUG_ALLOC, pool->log, 0, "free: %p", l->alloc);
+-
+-        if (l->alloc) {
+-            ngx_free(l->alloc);
+-        }
++    if (pool->d == NULL) {
++        ngx_free(pool);
++        return;
+     }
+ 
+ #if (NGX_DEBUG)
+@@ -72,9 +58,9 @@
+      * so we cannot use this log while free()ing the pool
+      */
+ 
+-    for (p = pool, n = pool->d.next; /* void */; p = n, n = n->d.next) {
++    for (d = pool->d, n = d->next; ; d = n, n = n->next) {
+         ngx_log_debug2(NGX_LOG_DEBUG_ALLOC, pool->log, 0,
+-                       "free: %p, unused: %uz", p, p->d.end - p->d.last);
++                       "free: %p, unused: %d", d, 0);
+ 
+         if (n == NULL) {
+             break;
+@@ -83,172 +69,82 @@
+ 
+ #endif
+ 
+-    for (p = pool, n = pool->d.next; /* void */; p = n, n = n->d.next) {
+-        ngx_free(p);
++    for (d = pool->d, n = d->next; ; d = n, n = n->next) {
++        ngx_free(d->alloc);
++        ngx_free(d);
+ 
+         if (n == NULL) {
+             break;
+         }
+     }
+-}
+ 
++    pool->d = NULL;
+ 
+-void
+-ngx_reset_pool(ngx_pool_t *pool)
+-{
+-    ngx_pool_t        *p;
+-    ngx_pool_large_t  *l;
+-
+-    for (l = pool->large; l; l = l->next) {
+-        if (l->alloc) {
+-            ngx_free(l->alloc);
+-        }
+-    }
+-
+-    pool->large = NULL;
+-
+-    for (p = pool; p; p = p->d.next) {
+-        p->d.last = (u_char *) p + sizeof(ngx_pool_t);
+-    }
++    ngx_free(pool);
+ }
+ 
+ 
+-void *
+-ngx_palloc(ngx_pool_t *pool, size_t size)
++void
++ngx_reset_pool(ngx_pool_t *pool)
+ {
+-    u_char      *m;
+-    ngx_pool_t  *p;
+-
+-    if (size <= pool->max) {
++    ngx_pool_data_t     *d, *n;
++    ngx_pool_data_t     *saved = NULL;
+ 
+-        p = pool->current;
+-
+-        do {
+-            m = ngx_align_ptr(p->d.last, NGX_ALIGNMENT);
+-
+-            if ((size_t) (p->d.end - m) >= size) {
+-                p->d.last = m + size;
+-
+-                return m;
++    if (pool->d) {
++        for (d = pool->d, n = d->next; ; d = n, n = n->next) {
++            if (d->alloc == pool->log) {
++                saved = d;
++                continue;
+             }
+ 
+-            p = p->d.next;
+-
+-        } while (p);
+-
+-        return ngx_palloc_block(pool, size);
+-    }
+-
+-    return ngx_palloc_large(pool, size);
+-}
+-
++            ngx_free(d->alloc);
++            ngx_free(d);
+ 
+-void *
+-ngx_pnalloc(ngx_pool_t *pool, size_t size)
+-{
+-    u_char      *m;
+-    ngx_pool_t  *p;
+-
+-    if (size <= pool->max) {
+-
+-        p = pool->current;
+-
+-        do {
+-            m = p->d.last;
+-
+-            if ((size_t) (p->d.end - m) >= size) {
+-                p->d.last = m + size;
+-
+-                return m;
++            if (n == NULL) {
++                break;
+             }
++        }
+ 
+-            p = p->d.next;
+-
+-        } while (p);
+-
+-        return ngx_palloc_block(pool, size);
++        pool->d = saved;
+     }
+-
+-    return ngx_palloc_large(pool, size);
+ }
+ 
+ 
+-static void *
+-ngx_palloc_block(ngx_pool_t *pool, size_t size)
++void *
++ngx_malloc(ngx_pool_t *pool, size_t size)
+ {
+-    u_char      *m;
+-    size_t       psize;
+-    ngx_pool_t  *p, *new, *current;
++    ngx_pool_data_t     *d;
++    void                *p;
+ 
+-    psize = (size_t) (pool->d.end - (u_char *) pool);
+-
+-    m = ngx_memalign(NGX_POOL_ALIGNMENT, psize, pool->log);
+-    if (m == NULL) {
++    p = ngx_alloc(size, pool->log);
++    if (p == NULL) {
+         return NULL;
+     }
+ 
+-    new = (ngx_pool_t *) m;
+-
+-    new->d.end = m + psize;
+-    new->d.next = NULL;
+-    new->d.failed = 0;
+-
+-    m += sizeof(ngx_pool_data_t);
+-    m = ngx_align_ptr(m, NGX_ALIGNMENT);
+-    new->d.last = m + size;
+-
+-    current = pool->current;
+-
+-    for (p = current; p->d.next; p = p->d.next) {
+-        if (p->d.failed++ > 4) {
+-            current = p->d.next;
+-        }
++    d = ngx_alloc(sizeof(ngx_pool_data_t), pool->log);
++    if (d == NULL){
++        ngx_free(p);
++        return NULL;
+     }
+ 
+-    p->d.next = new;
+-
+-    pool->current = current ? current : new;
+-
+-    return m;
++    d->alloc = p;
++    d->next = pool->d;
++    pool->d = d;
++    return p;
+ }
+ 
+ 
+-static void *
+-ngx_palloc_large(ngx_pool_t *pool, size_t size)
++void *
++ngx_palloc(ngx_pool_t *pool, size_t size)
+ {
+-    void              *p;
+-    ngx_uint_t         n;
+-    ngx_pool_large_t  *large;
+-
+-    p = ngx_alloc(size, pool->log);
+-    if (p == NULL) {
+-        return NULL;
+-    }
+-
+-    n = 0;
+-
+-    for (large = pool->large; large; large = large->next) {
+-        if (large->alloc == NULL) {
+-            large->alloc = p;
+-            return p;
+-        }
+-
+-        if (n++ > 3) {
+-            break;
+-        }
+-    }
+-
+-    large = ngx_palloc(pool, sizeof(ngx_pool_large_t));
+-    if (large == NULL) {
+-        ngx_free(p);
+-        return NULL;
+-    }
++    return ngx_malloc(pool, size);
++}
+ 
+-    large->alloc = p;
+-    large->next = pool->large;
+-    pool->large = large;
+ 
+-    return p;
++void *
++ngx_pnalloc(ngx_pool_t *pool, size_t size)
++{
++    return ngx_malloc(pool, size);
+ }
+ 
+ 
+@@ -256,38 +152,48 @@
+ ngx_pmemalign(ngx_pool_t *pool, size_t size, size_t alignment)
+ {
+     void              *p;
+-    ngx_pool_large_t  *large;
++    ngx_pool_data_t   *d;
+ 
+     p = ngx_memalign(alignment, size, pool->log);
+     if (p == NULL) {
+         return NULL;
+     }
+ 
+-    large = ngx_palloc(pool, sizeof(ngx_pool_large_t));
+-    if (large == NULL) {
++    d = ngx_alloc(sizeof(ngx_pool_data_t), pool->log);
++    if (d == NULL){
+         ngx_free(p);
+         return NULL;
+     }
+ 
+-    large->alloc = p;
+-    large->next = pool->large;
+-    pool->large = large;
+-
++    d->alloc = p;
++    d->next = pool->d;
++    pool->d = d;
+     return p;
+ }
+ 
+ 
+ ngx_int_t
+-ngx_pfree(ngx_pool_t *pool, void *p)
++ngx_pfree(ngx_pool_t *pool, void *data)
+ {
+-    ngx_pool_large_t  *l;
++    ngx_pool_data_t     *p, *d;
+ 
+-    for (l = pool->large; l; l = l->next) {
+-        if (p == l->alloc) {
+-            ngx_log_debug1(NGX_LOG_DEBUG_ALLOC, pool->log, 0,
+-                           "free: %p", l->alloc);
+-            ngx_free(l->alloc);
+-            l->alloc = NULL;
++    p = NULL;
++    for (d = pool->d; d; p = d, d = d->next) {
++        if (data == d->alloc) {
++
++            ngx_log_debug1(NGX_LOG_DEBUG_ALLOC, pool->log, 0, "free: %p", d->alloc);
++
++            ngx_free(d->alloc);
++            d->alloc = NULL;
++
++            if (p) {
++                p->next = d->next;
++
++            } else {
++                pool->d = d->next;
++            }
++
++            ngx_free(d);
+ 
+             return NGX_OK;
+         }
+diff -urx '*~' -x '*.swp' nginx-1.3.11/src/core/ngx_palloc.h nginx-1.3.11-patched/src/core/ngx_palloc.h
+--- nginx-1.3.11/src/core/ngx_palloc.h	2012-02-06 04:02:59.000000000 +0800
++++ nginx-1.3.11-patched/src/core/ngx_palloc.h	2012-06-21 10:35:47.463405863 +0800
+@@ -38,28 +38,21 @@
+ };
+ 
+ 
+-typedef struct ngx_pool_large_s  ngx_pool_large_t;
+-
+-struct ngx_pool_large_s {
+-    ngx_pool_large_t     *next;
+-    void                 *alloc;
+-};
++typedef struct ngx_pool_data_s   ngx_pool_large_t;
++typedef struct ngx_pool_data_s   ngx_pool_data_t;
+ 
+ 
+-typedef struct {
+-    u_char               *last;
+-    u_char               *end;
+-    ngx_pool_t           *next;
+-    ngx_uint_t            failed;
+-} ngx_pool_data_t;
++struct ngx_pool_data_s {
++    ngx_pool_data_t        *next;
++    void                   *alloc;
++};
+ 
+ 
+ struct ngx_pool_s {
+-    ngx_pool_data_t       d;
++    ngx_pool_data_t      *d;
+     size_t                max;
+     ngx_pool_t           *current;
+     ngx_chain_t          *chain;
+-    ngx_pool_large_t     *large;
+     ngx_pool_cleanup_t   *cleanup;
+     ngx_log_t            *log;
+ };
diff --git a/patches/nginx-1.3.11-nonbuffered-upstream-truncation.patch b/patches/nginx-1.3.11-nonbuffered-upstream-truncation.patch
new file mode 100644
index 0000000..bf4a1f9
--- /dev/null
+++ b/patches/nginx-1.3.11-nonbuffered-upstream-truncation.patch
@@ -0,0 +1,63 @@
+--- nginx-1.3.11/src/http/ngx_http_upstream.c	2012-08-06 10:34:08.000000000 -0700
++++ nginx-1.3.11-patched/src/http/ngx_http_upstream.c	2012-09-09 21:58:04.727761891 -0700
+@@ -2383,7 +2383,7 @@
+ 
+     if (c->read->timedout) {
+         ngx_connection_error(c, NGX_ETIMEDOUT, "upstream timed out");
+-        ngx_http_upstream_finalize_request(r, u, 0);
++        ngx_http_upstream_finalize_request(r, u, NGX_HTTP_GATEWAY_TIME_OUT);
+         return;
+     }
+ 
+@@ -2430,13 +2430,17 @@
+             if (u->busy_bufs == NULL) {
+ 
+                 if (u->length == 0
+-                    || upstream->read->eof
+-                    || upstream->read->error)
++                    || (upstream->read->eof && u->headers_in.content_length_n == -1))
+                 {
+                     ngx_http_upstream_finalize_request(r, u, 0);
+                     return;
+                 }
+ 
++                if (upstream->read->eof || upstream->read->error) {
++                    ngx_http_upstream_finalize_request(r, u, NGX_HTTP_BAD_GATEWAY);
++                    return;
++                }
++
+                 b->pos = b->start;
+                 b->last = b->start;
+             }
+@@ -2710,7 +2714,16 @@
+ #if 0
+             ngx_http_busy_unlock(u->conf->busy_lock, &u->busy_lock);
+ #endif
+-            ngx_http_upstream_finalize_request(r, u, 0);
++
++            if (p->upstream_done
++                || (p->upstream_eof && u->headers_in.content_length_n == -1))
++            {
++                ngx_http_upstream_finalize_request(r, u, 0);
++
++            } else {
++                ngx_http_upstream_finalize_request(r, u, NGX_HTTP_BAD_GATEWAY);
++            }
++
+             return;
+         }
+     }
+@@ -3073,6 +3086,13 @@
+         && rc != NGX_HTTP_REQUEST_TIME_OUT
+         && (rc == NGX_ERROR || rc >= NGX_HTTP_SPECIAL_RESPONSE))
+     {
++        if (rc == NGX_ERROR) {
++            r->headers_out.status = NGX_HTTP_INTERNAL_SERVER_ERROR;
++
++        } else {
++            r->headers_out.status = rc;
++        }
++
+         rc = 0;
+     }
+ 
diff --git a/patches/nginx-1.3.11-resolver_wev_handler_segfault_with_poll.patch b/patches/nginx-1.3.11-resolver_wev_handler_segfault_with_poll.patch
new file mode 100644
index 0000000..f99758c
--- /dev/null
+++ b/patches/nginx-1.3.11-resolver_wev_handler_segfault_with_poll.patch
@@ -0,0 +1,31 @@
+--- nginx-1.3.11/src/event/modules/ngx_poll_module.c	2012-01-18 07:07:43.000000000 -0800
++++ nginx-1.3.11-patched/src/event/modules/ngx_poll_module.c	2013-01-23 12:34:13.990781456 -0800
+@@ -367,11 +367,18 @@ ngx_poll_process_events(ngx_cycle_t *cyc
+              */
+ 
+             revents |= POLLIN|POLLOUT;
++            if (c->read->active) {
++                revents |= POLLIN;
++            }
++
++            if (c->write->active) {
++                revents |= POLLOUT;
++            }
+         }
+ 
+         found = 0;
+ 
+-        if (revents & POLLIN) {
++        if ((revents & POLLIN) && c->read->active) {
+             found = 1;
+ 
+             ev = c->read;
+@@ -388,7 +395,7 @@ ngx_poll_process_events(ngx_cycle_t *cyc
+             ngx_locked_post_event(ev, queue);
+         }
+ 
+-        if (revents & POLLOUT) {
++        if ((revents & POLLOUT) && c->write->active) {
+             found = 1;
+             ev = c->write;
+ 
diff --git a/patches/nginx-1.3.11-server_header.patch b/patches/nginx-1.3.11-server_header.patch
new file mode 100644
index 0000000..bf6cef5
--- /dev/null
+++ b/patches/nginx-1.3.11-server_header.patch
@@ -0,0 +1,26 @@
+diff -ur lz-nginx-1.3.11/nginx-1.3.11/src/core/nginx.h lz-nginx-1.3.11-patched/nginx-1.3.11/src/core/nginx.h
+--- lz-nginx-1.3.11/nginx-1.3.11/src/core/nginx.h	2010-02-12 17:31:01.000000000 +0800
++++ lz-nginx-1.3.11-patched/nginx-1.3.11/src/core/nginx.h	2010-03-30 10:52:13.240702627 +0800
+@@ -10,7 +10,7 @@
+ 
+ #define nginx_version         1003011
+ #define NGINX_VERSION      "1.3.11"
+-#define NGINX_VER          "nginx/" NGINX_VERSION
++#define NGINX_VER          "ngx_openresty/" NGINX_VERSION ".unknown"
+ 
+ #define NGINX_VAR          "NGINX"
+ #define NGX_OLDPID_EXT     ".oldbin"
+Only in lz-nginx-1.3.11-patched/nginx-1.3.11/src/core: nginx.h.orig
+Only in lz-nginx-1.3.11-patched/nginx-1.3.11/src/core: nginx.h.rej
+diff -ur lz-nginx-1.3.11/nginx-1.3.11/src/http/ngx_http_header_filter_module.c lz-nginx-1.3.11-patched/nginx-1.3.11/src/http/ngx_http_header_filter_module.c
+--- lz-nginx-1.3.11/nginx-1.3.11/src/http/ngx_http_header_filter_module.c	2010-03-03 23:14:04.000000000 +0800
++++ lz-nginx-1.3.11-patched/nginx-1.3.11/src/http/ngx_http_header_filter_module.c	2010-03-30 10:52:53.670909405 +0800
+@@ -45,7 +45,7 @@
+ };
+ 
+ 
+-static char ngx_http_server_string[] = "Server: nginx" CRLF;
++static char ngx_http_server_string[] = "Server: ngx_openresty" CRLF;
+ static char ngx_http_server_full_string[] = "Server: " NGINX_VER CRLF;
+ 
+ 
diff --git a/patches/nginx-1.3.11-slab_alloc_no_memory_as_info.patch b/patches/nginx-1.3.11-slab_alloc_no_memory_as_info.patch
new file mode 100644
index 0000000..e7c80ad
--- /dev/null
+++ b/patches/nginx-1.3.11-slab_alloc_no_memory_as_info.patch
@@ -0,0 +1,11 @@
+--- nginx-1.3.11/src/core/ngx_slab.c	2012-09-24 11:34:04.000000000 -0700
++++ nginx-1.3.11-patched/src/core/ngx_slab.c	2012-12-05 20:47:07.296694952 -0800
+@@ -657,7 +657,7 @@ ngx_slab_alloc_pages(ngx_slab_pool_t *po
+         }
+     }
+ 
+-    ngx_slab_error(pool, NGX_LOG_CRIT, "ngx_slab_alloc() failed: no memory");
++    ngx_slab_error(pool, NGX_LOG_INFO, "ngx_slab_alloc() failed: no memory");
+ 
+     return NULL;
+ }
diff --git a/patches/nginx-1.3.11-upstream_pipelining.patch b/patches/nginx-1.3.11-upstream_pipelining.patch
new file mode 100644
index 0000000..7b2fc89
--- /dev/null
+++ b/patches/nginx-1.3.11-upstream_pipelining.patch
@@ -0,0 +1,40 @@
+diff -rudp nginx-1.3.11/src/http/ngx_http_upstream.c nginx-1.3.11-patched/src/http/ngx_http_upstream.c
+--- nginx-1.3.11/src/http/ngx_http_upstream.c	2012-08-06 10:34:08.000000000 -0700
++++ nginx-1.3.11-patched/src/http/ngx_http_upstream.c	2012-12-05 14:46:41.741173058 -0800
+@@ -1216,6 +1216,7 @@ ngx_http_upstream_connect(ngx_http_reque
+     }
+ 
+     u->request_sent = 0;
++    u->request_all_sent = 0;
+ 
+     if (rc == NGX_AGAIN) {
+         ngx_add_timer(c->write, u->conf->connect_timeout);
+@@ -1418,6 +1419,8 @@ ngx_http_upstream_send_request(ngx_http_
+ 
+     /* rc == NGX_OK */
+ 
++    u->request_all_sent = 1;
++
+     if (c->tcp_nopush == NGX_TCP_NOPUSH_SET) {
+         if (ngx_tcp_push(c->fd) == NGX_ERROR) {
+             ngx_log_error(NGX_LOG_CRIT, c->log, ngx_socket_errno,
+@@ -1484,7 +1487,7 @@ ngx_http_upstream_send_request_handler(n
+ 
+ #endif
+ 
+-    if (u->header_sent) {
++    if (u->request_all_sent) {
+         u->write_event_handler = ngx_http_upstream_dummy_handler;
+ 
+         (void) ngx_handle_write_event(c->write, 0);
+diff -rudp nginx-1.3.11/src/http/ngx_http_upstream.h nginx-1.3.11-patched/src/http/ngx_http_upstream.h
+--- nginx-1.3.11/src/http/ngx_http_upstream.h	2012-02-13 03:01:58.000000000 -0800
++++ nginx-1.3.11-patched/src/http/ngx_http_upstream.h	2012-12-05 14:41:09.763514741 -0800
+@@ -324,6 +324,7 @@ struct ngx_http_upstream_s {
+     unsigned                         keepalive:1;
+ 
+     unsigned                         request_sent:1;
++    unsigned                         request_all_sent:1;
+     unsigned                         header_sent:1;
+ };
+ 
diff --git a/patches/nginx-1.3.11-upstream_test_connect_kqueue.patch b/patches/nginx-1.3.11-upstream_test_connect_kqueue.patch
new file mode 100644
index 0000000..48a564c
--- /dev/null
+++ b/patches/nginx-1.3.11-upstream_test_connect_kqueue.patch
@@ -0,0 +1,26 @@
+--- nginx-1.3.11/src/http/ngx_http_upstream.c	2012-08-06 10:34:08.000000000 -0700
++++ nginx-1.3.11-patched/src/http/ngx_http_upstream.c	2012-11-05 21:17:38.000000000 -0800
+@@ -1808,10 +1808,22 @@ ngx_http_upstream_test_connect(ngx_conne
+ 
+ #if (NGX_HAVE_KQUEUE)
+ 
++    ngx_event_t *ev;
++
+     if (ngx_event_flags & NGX_USE_KQUEUE_EVENT)  {
+         if (c->write->pending_eof) {
++            ev = c->write;
++
++        } else if (c->read->pending_eof) {
++            ev = c->read;
++
++        } else {
++            ev = NULL;
++        }
++
++        if (ev) {
+             c->log->action = "connecting to upstream";
+-            (void) ngx_connection_error(c, c->write->kq_errno,
++            (void) ngx_connection_error(c, ev->kq_errno,
+                                     "kevent() reported that connect() failed");
+             return NGX_ERROR;
+         }
diff --git a/util/mirror-tarballs b/util/mirror-tarballs
index efde468..e3e9942 100755
--- a/util/mirror-tarballs
+++ b/util/mirror-tarballs
@@ -71,9 +71,9 @@ echo
 #echo "applying the named_location_clear_mods_ctx patch"
 #patch -p1 < $root/patches/nginx-$main_ver-named_location_clear_mods_ctx.patch || exit 1
 
-echo "$info_txt applying the allow_request_body_updating patch for nginx"
-patch -p1 < $root/patches/nginx-$main_ver-allow_request_body_updating.patch || exit 1
-echo
+#echo "$info_txt applying the allow_request_body_updating patch for nginx"
+#patch -p1 < $root/patches/nginx-$main_ver-allow_request_body_updating.patch || exit 1
+#echo
 
 echo "$info_txt applying the log_escape_non_ascii patch for nginx"
 patch -p1 < $root/patches/nginx-$main_ver-log_escape_non_ascii.patch || exit 1
diff --git a/util/ver b/util/ver
index 78c7c56..49d1c78 100755
--- a/util/ver
+++ b/util/ver
@@ -1,9 +1,8 @@
 #!/bin/bash
 
-#main_ver=1.3.7
-#main_ver=1.2.5
+#main_ver=1.3.11
 main_ver=1.2.6
-minor_ver=1
+minor_ver=3rc1
 version=$main_ver.$minor_ver
 echo $version