nginx-0.1.19-RELEASE import

    *) Bugfix: now, if request contains the zero, then the 404 error is
       returned for the local requests.

    *) Bugfix: nginx could not be built on NetBSD 2.0.

    *) Bugfix: the timeout may occur while reading of the the client
       request body via SSL connections.
diff --git a/src/event/modules/ngx_kqueue_module.c b/src/event/modules/ngx_kqueue_module.c
index 49c22a9..49770fd 100644
--- a/src/event/modules/ngx_kqueue_module.c
+++ b/src/event/modules/ngx_kqueue_module.c
@@ -390,7 +390,7 @@
     kev->ident = c->fd;
     kev->filter = filter;
     kev->flags = flags;
-    kev->udata = (void *) ((uintptr_t) ev | ev->instance);
+    kev->udata = NGX_KQUEUE_UDATA_T ((uintptr_t) ev | ev->instance);
 
     if (filter == EVFILT_VNODE) {
         kev->fflags = NOTE_DELETE|NOTE_WRITE|NOTE_EXTEND
diff --git a/src/event/ngx_event_openssl.c b/src/event/ngx_event_openssl.c
index 15a25d1..cadd0aa 100644
--- a/src/event/ngx_event_openssl.c
+++ b/src/event/ngx_event_openssl.c
@@ -11,12 +11,14 @@
 #include <openssl/engine.h>
 
 
+static ngx_int_t ngx_ssl_handle_recv(ngx_connection_t *c, int n);
 static void ngx_ssl_write_handler(ngx_event_t *wev);
 static ssize_t ngx_ssl_write(ngx_connection_t *c, u_char *data, size_t size);
 static void ngx_ssl_read_handler(ngx_event_t *rev);
 
 
-ngx_int_t ngx_ssl_init(ngx_log_t *log)
+ngx_int_t
+ngx_ssl_init(ngx_log_t *log)
 {
     ENGINE  *engine;
 
@@ -28,8 +30,9 @@
 }
 
 
-ngx_int_t ngx_ssl_create_session(ngx_ssl_ctx_t *ssl_ctx, ngx_connection_t *c,
-                                 ngx_uint_t flags)
+ngx_int_t
+ngx_ssl_create_session(ngx_ssl_ctx_t *ssl_ctx, ngx_connection_t *c,
+    ngx_uint_t flags)
 {   
     ngx_ssl_t  *ssl;
 
@@ -65,58 +68,105 @@
 }
 
 
-ssize_t ngx_ssl_recv(ngx_connection_t *c, u_char *buf, size_t size)
+ssize_t
+ngx_ssl_recv(ngx_connection_t *c, u_char *buf, size_t size)
 {
-    int         n, sslerr;
-    ngx_err_t   err;
-    char       *handshake;
+    int  n, bytes;
 
-    n = SSL_read(c->ssl->ssl, buf, size);
+    if (c->ssl->last == NGX_ERROR) {
+        return NGX_ERROR;
+    }
 
-    ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0, "SSL_read: %d", n); 
+    bytes = 0;
 
-    if (n > 0) {
+    /*
+     * SSL_read() may return data in parts, so try to read
+     * until SSL_read() would return no data
+     */
+
+    for ( ;; ) {
+
+        n = SSL_read(c->ssl->ssl, buf, size);
+
+        ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0, "SSL_read: %d", n); 
+
+        if (n > 0) {
+
+            bytes += n;
 
 #if (NGX_DEBUG)
 
-        if (!c->ssl->handshaked && SSL_is_init_finished(c->ssl->ssl)) {
-            char         buf[129], *s, *d;
-            SSL_CIPHER  *cipher;
+            if (!c->ssl->handshaked && SSL_is_init_finished(c->ssl->ssl)) {
+                char         buf[129], *s, *d;
+                SSL_CIPHER  *cipher;
 
-            c->ssl->handshaked = 1;
+                c->ssl->handshaked = 1;
 
-            cipher = SSL_get_current_cipher(c->ssl->ssl);
+                cipher = SSL_get_current_cipher(c->ssl->ssl);
 
-            if (cipher) {
-                SSL_CIPHER_description(cipher, &buf[1], 128);
+                if (cipher) {
+                    SSL_CIPHER_description(cipher, &buf[1], 128);
 
-                for (s = &buf[1], d = buf; *s; s++) {
-                    if (*s == ' ' && *d == ' ') {
-                        continue;
+                    for (s = &buf[1], d = buf; *s; s++) {
+                        if (*s == ' ' && *d == ' ') {
+                            continue;
+                        }
+
+                        if (*s == '\n' || *s == '\r') {
+                            continue;
+                        }
+
+                        *++d = *s;
                     }
 
-                    if (*s == '\n' || *s == '\r') {
-                        continue;
+                    if (*d != ' ') {
+                        d++;
                     }
 
-                    *++d = *s;
+                    *d = '\0';
+
+                    ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0,
+                                   "SSL cipher: \"%s\"", &buf[1]); 
+                } else {
+                    ngx_log_debug0(NGX_LOG_DEBUG_EVENT, c->log, 0,
+                                   "SSL no shared ciphers"); 
                 }
+            }
+#endif
 
-                if (*d != ' ') {
-                    d++;
-                }
+        }
 
-                *d = '\0';
+        c->ssl->last = ngx_ssl_handle_recv(c, n);
 
-                ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0,
-                               "SSL cipher: \"%s\"", &buf[1]); 
+        if (c->ssl->last != NGX_OK) {
+
+            if (bytes) {
+                return bytes;
+
             } else {
-                ngx_log_debug0(NGX_LOG_DEBUG_EVENT, c->log, 0,
-                               "SSL no shared ciphers"); 
+                return c->ssl->last;
             }
         }
 
-#endif
+        size -= n;
+
+        if (size == 0) {
+            return bytes;
+        }
+
+        buf += n;
+    }
+}
+
+
+static ngx_int_t
+ngx_ssl_handle_recv(ngx_connection_t *c, int n)
+{
+    int         sslerr;
+    ngx_err_t   err;
+    char       *handshake;
+
+    if (n > 0) {
 
         if (c->ssl->saved_write_handler) {
 
@@ -137,7 +187,7 @@
             ngx_mutex_unlock(ngx_posted_events_mutex);
         }
 
-        return n;
+        return NGX_OK;
     }
 
     if (!SSL_is_init_finished(c->ssl->ssl)) {
@@ -197,7 +247,8 @@
 }
 
 
-static void ngx_ssl_write_handler(ngx_event_t *wev)
+static void
+ngx_ssl_write_handler(ngx_event_t *wev)
 {
     ngx_connection_t  *c;
 
@@ -214,8 +265,8 @@
  * the output to decrease a SSL overhead some more.
  */
 
-ngx_chain_t *ngx_ssl_send_chain(ngx_connection_t *c, ngx_chain_t *in,
-                                off_t limit)
+ngx_chain_t *
+ngx_ssl_send_chain(ngx_connection_t *c, ngx_chain_t *in, off_t limit)
 {
     int          n;
     ngx_uint_t   flush;
@@ -338,7 +389,8 @@
 }
 
 
-static ssize_t ngx_ssl_write(ngx_connection_t *c, u_char *data, size_t size)
+static ssize_t
+ngx_ssl_write(ngx_connection_t *c, u_char *data, size_t size)
 {
     int         n, sslerr;
     ngx_err_t   err;
@@ -424,7 +476,8 @@
 }
 
 
-static void ngx_ssl_read_handler(ngx_event_t *rev)
+static void
+ngx_ssl_read_handler(ngx_event_t *rev)
 {
     ngx_connection_t  *c;
 
@@ -433,7 +486,8 @@
 }
 
 
-ngx_int_t ngx_ssl_shutdown(ngx_connection_t *c)
+ngx_int_t
+ngx_ssl_shutdown(ngx_connection_t *c)
 {
     int         n, sslerr, mode;
     ngx_uint_t  again;
@@ -520,8 +574,8 @@
 }
 
 
-void ngx_ssl_error(ngx_uint_t level, ngx_log_t *log, ngx_err_t err,
-                   char *fmt, ...)
+void
+ngx_ssl_error(ngx_uint_t level, ngx_log_t *log, ngx_err_t err, char *fmt, ...)
 {   
     u_char   errstr[NGX_MAX_CONF_ERRSTR], *p, *last;
     va_list  args;
diff --git a/src/event/ngx_event_openssl.h b/src/event/ngx_event_openssl.h
index 224cc84..afebde6 100644
--- a/src/event/ngx_event_openssl.h
+++ b/src/event/ngx_event_openssl.h
@@ -17,6 +17,7 @@
 
 typedef struct {
     SSL                   *ssl;
+    ngx_int_t              last;
     ngx_buf_t             *buf;
     ngx_event_handler_pt   saved_read_handler;
     ngx_event_handler_pt   saved_write_handler;
@@ -49,10 +50,10 @@
 
 ssize_t ngx_ssl_recv(ngx_connection_t *c, u_char *buf, size_t size);
 ngx_chain_t *ngx_ssl_send_chain(ngx_connection_t *c, ngx_chain_t *in,
-                                off_t limit);
+    off_t limit);
 ngx_int_t ngx_ssl_shutdown(ngx_connection_t *c);
 void ngx_ssl_error(ngx_uint_t level, ngx_log_t *log, ngx_err_t err,
-                   char *fmt, ...);
+    char *fmt, ...);
 
 
 #endif /* _NGX_EVENT_OPENSSL_H_INCLUDED_ */