nginx-0.1.45-RELEASE import

    *) Change: the "ssl_engine" directive was canceled in the
       ngx_http_ssl_module and now is introduced at global level.

    *) Bugfix: the responses with SSI subrequests did not transferred via
       SSL connection.

    *) Various bug fixes in the IMAP/POP3 proxy.
diff --git a/src/imap/ngx_imap.c b/src/imap/ngx_imap.c
index aa28b2d..b8a75ad 100644
--- a/src/imap/ngx_imap.c
+++ b/src/imap/ngx_imap.c
@@ -41,8 +41,14 @@
     &ngx_imap_module_ctx,                  /* module context */
     ngx_imap_commands,                     /* module directives */
     NGX_CORE_MODULE,                       /* module type */
+    NULL,                                  /* init master */
     NULL,                                  /* init module */
-    NULL                                   /* init process */
+    NULL,                                  /* init process */
+    NULL,                                  /* init thread */
+    NULL,                                  /* exit thread */
+    NULL,                                  /* exit process */
+    NULL,                                  /* exit master */
+    NGX_MODULE_V1_PADDING
 };
 
 
diff --git a/src/imap/ngx_imap.h b/src/imap/ngx_imap.h
index 5e03774..7bee2ad 100644
--- a/src/imap/ngx_imap.h
+++ b/src/imap/ngx_imap.h
@@ -123,6 +123,12 @@
 } ngx_imap_session_t;
 
 
+typedef struct {
+    ngx_str_t           *client;
+    ngx_imap_session_t  *session;
+} ngx_imap_log_ctx_t;
+
+
 #define NGX_POP3_USER       1
 #define NGX_POP3_PASS       2
 #define NGX_POP3_CAPA       3
diff --git a/src/imap/ngx_imap_auth_http_module.c b/src/imap/ngx_imap_auth_http_module.c
index 2bf0cc9..1e2bc4c 100644
--- a/src/imap/ngx_imap_auth_http_module.c
+++ b/src/imap/ngx_imap_auth_http_module.c
@@ -105,8 +105,14 @@
     &ngx_imap_auth_http_module_ctx,        /* module context */
     ngx_imap_auth_http_commands,           /* module directives */
     NGX_IMAP_MODULE,                       /* module type */
+    NULL,                                  /* init master */
     NULL,                                  /* init module */
-    NULL                                   /* init process */
+    NULL,                                  /* init process */
+    NULL,                                  /* init thread */
+    NULL,                                  /* exit thread */
+    NULL,                                  /* exit process */
+    NULL,                                  /* exit master */
+    NGX_MODULE_V1_PADDING
 };
 
 
@@ -120,6 +126,8 @@
     ngx_imap_auth_http_ctx_t   *ctx;
     ngx_imap_auth_http_conf_t  *ahcf;
 
+    s->connection->log->action = "in http auth state";
+
     ctx = ngx_pcalloc(s->connection->pool, sizeof(ngx_imap_auth_http_ctx_t));
     if (ctx == NULL) {
         ngx_imap_session_internal_server_error(s);
@@ -142,7 +150,7 @@
 
     rc = ngx_event_connect_peer(&ctx->peer);
 
-    if (rc == NGX_ERROR) {
+    if (rc == NGX_ERROR || rc == NGX_CONNECT_ERROR) {
         ngx_imap_session_internal_server_error(s);
         return;
     }
@@ -156,13 +164,13 @@
 
     ctx->handler = ngx_imap_auth_http_ignore_status_line;
 
+    ngx_add_timer(ctx->peer.connection->read, ahcf->timeout);
+    ngx_add_timer(ctx->peer.connection->write, ahcf->timeout);
+
     if (rc == NGX_OK) {
         ngx_imap_auth_http_write_handler(ctx->peer.connection->write);
         return;
     }
-
-    ngx_add_timer(ctx->peer.connection->read, ahcf->timeout);
-    ngx_add_timer(ctx->peer.connection->write, ahcf->timeout);
 }
 
 
@@ -185,7 +193,8 @@
 
     if (wev->timedout) {  
         ngx_log_error(NGX_LOG_ERR, wev->log, NGX_ETIMEDOUT,
-                      "auth http server timed out");
+                      "auth http server %V timed out",
+                      &ctx->peer.peers->peer[0].name);
         ngx_close_connection(ctx->peer.connection);
         ngx_imap_session_internal_server_error(s);
         return;
@@ -240,7 +249,8 @@
 
     if (rev->timedout) {  
         ngx_log_error(NGX_LOG_ERR, rev->log, NGX_ETIMEDOUT,
-                      "auth http server timed out");
+                      "auth http server %V timed out",
+                      &ctx->peer.peers->peer[0].name);
         ngx_close_connection(ctx->peer.connection);
         ngx_imap_session_internal_server_error(s);
         return;
@@ -355,7 +365,8 @@
             }
 
             ngx_log_error(NGX_LOG_ERR, s->connection->log, 0,
-                          "auth http server sent invalid response");
+                          "auth http server &V sent invalid response",
+                          &ctx->peer.peers->peer[0].name);
             ngx_close_connection(ctx->peer.connection);
             ngx_imap_session_internal_server_error(s);
             return;
@@ -520,9 +531,11 @@
 
                 if (ctx->sleep == 0) {
                     s->quit = 1;
-                }
 
-                ngx_imap_send(s->connection->write);
+                    ngx_imap_send(s->connection->write);
+
+                    return;
+                }
 
                 ngx_add_timer(s->connection->read, ctx->sleep * 1000);
 
@@ -533,7 +546,8 @@
 
             if (ctx->addr.len == 0 || ctx->port.len == 0) {
                 ngx_log_error(NGX_LOG_ERR, s->connection->log, 0,
-                              "auth http server did not send server or port");
+                              "auth http server %V did not send server or port",
+                              &ctx->peer.peers->peer[0].name);
                 ngx_imap_session_internal_server_error(s);
                 return;
             }
@@ -555,8 +569,9 @@
             port = ngx_atoi(ctx->port.data, ctx->port.len);
             if (port == NGX_ERROR || port < 1 || port > 65536) {
                 ngx_log_error(NGX_LOG_ERR, s->connection->log, 0,
-                              "auth http server sent invalid server "
-                              "port:\"%V\"", &ctx->port);
+                              "auth http server %V sent invalid server "
+                              "port:\"%V\"",
+                              &ctx->peer.peers->peer[0].name, &ctx->port);
                 ngx_imap_session_internal_server_error(s);
                 return;
             }
@@ -567,8 +582,9 @@
             sin->sin_addr.s_addr = inet_addr((char *) ctx->addr.data);
             if (sin->sin_addr.s_addr == INADDR_NONE) {
                 ngx_log_error(NGX_LOG_ERR, s->connection->log, 0,
-                              "auth http server sent invalid server "
-                              "address:\"%V\"", &ctx->addr);
+                              "auth http server %V sent invalid server "
+                              "address:\"%V\"",
+                              &ctx->peer.peers->peer[0].name, &ctx->addr);
                 ngx_imap_session_internal_server_error(s);
                 return;
             }
@@ -612,7 +628,8 @@
         /* rc == NGX_ERROR */
 
         ngx_log_error(NGX_LOG_ERR, s->connection->log, 0,
-                      "auth http server sent invalid header in response");
+                      "auth http server %V sent invalid header in response",
+                      &ctx->peer.peers->peer[0].name);
         ngx_close_connection(ctx->peer.connection);
         ngx_imap_session_internal_server_error(s);
 
@@ -654,6 +671,8 @@
             ngx_imap_close_connection(s->connection);
         }
 
+        ngx_imap_send(s->connection->write);
+
         return;
     }
 
diff --git a/src/imap/ngx_imap_core_module.c b/src/imap/ngx_imap_core_module.c
index 8225574..0203f44 100644
--- a/src/imap/ngx_imap_core_module.c
+++ b/src/imap/ngx_imap_core_module.c
@@ -114,8 +114,14 @@
     &ngx_imap_core_module_ctx,             /* module context */
     ngx_imap_core_commands,                /* module directives */
     NGX_IMAP_MODULE,                       /* module type */
+    NULL,                                  /* init master */
     NULL,                                  /* init module */
-    NULL                                   /* init process */
+    NULL,                                  /* init process */
+    NULL,                                  /* init thread */
+    NULL,                                  /* exit thread */
+    NULL,                                  /* exit process */
+    NULL,                                  /* exit master */
+    NGX_MODULE_V1_PADDING
 };
 
 
diff --git a/src/imap/ngx_imap_handler.c b/src/imap/ngx_imap_handler.c
index 03dedaf..0ddf51f 100644
--- a/src/imap/ngx_imap_handler.c
+++ b/src/imap/ngx_imap_handler.c
@@ -11,7 +11,9 @@
 
 
 static void ngx_imap_init_session(ngx_event_t *rev);
+static void ngx_imap_init_protocol(ngx_event_t *rev);
 static ngx_int_t ngx_imap_read_command(ngx_imap_session_t *s);
+static u_char *ngx_imap_log_error(ngx_log_t *log, u_char *buf, size_t len);
 
 #if (NGX_IMAP_SSL)
 static void ngx_imap_ssl_close_handler(ngx_event_t *ev);
@@ -40,20 +42,49 @@
 void
 ngx_imap_init_connection(ngx_connection_t *c)
 {
+    ngx_imap_log_ctx_t  *ctx;
+
+    ngx_log_debug0(NGX_LOG_DEBUG_IMAP, c->log, 0, "imap init connection");
+
+    ctx = ngx_palloc(c->pool, sizeof(ngx_imap_log_ctx_t));
+    if (ctx == NULL) {
+        ngx_imap_close_connection(c);
+        return;
+    } 
+
+    ctx->client = &c->addr_text;
+    ctx->session = NULL;
+
+    c->log->connection = c->number;
+    c->log->handler = ngx_imap_log_error;
+    c->log->data = ctx;
+    c->log->action = "sending client greeting line";
+
+    c->log_error = NGX_ERROR_INFO;
+
+    ngx_imap_init_session(c->read);
+}
+
+
+static void
+ngx_imap_init_session(ngx_event_t *rev)
+{
+    ngx_connection_t          *c;
     ngx_imap_session_t        *s;
+    ngx_imap_log_ctx_t        *lctx;
     ngx_imap_conf_ctx_t       *ctx;
+    ngx_imap_core_srv_conf_t  *cscf;
 #if (NGX_IMAP_SSL)
     ngx_int_t                  rc;
     ngx_imap_ssl_conf_t       *sslcf;
 #endif
-    ngx_imap_core_srv_conf_t  *cscf;
 
-    ngx_log_debug0(NGX_LOG_DEBUG_IMAP, c->log, 0, "imap init connection");
-
-    c->log_error = NGX_ERROR_INFO;
+    c = rev->data;
 
     ctx = c->ctx;
 
+    cscf = ngx_imap_get_module_srv_conf(ctx, ngx_imap_core_module);
+
 #if (NGX_IMAP_SSL)
 
     sslcf = ngx_imap_get_module_srv_conf(ctx, ngx_imap_ssl_module);
@@ -74,6 +105,17 @@
             return;
         }
 
+        if (rc == NGX_AGAIN) {
+            ngx_add_timer(rev, cscf->timeout);
+            c->read->handler = ngx_imap_init_session;
+
+            if (ngx_handle_read_event(rev, 0) == NGX_ERROR) {
+                ngx_imap_close_connection(c);
+            }
+
+            return;
+        }
+
         c->recv = ngx_ssl_recv;
         c->send = ngx_ssl_write;
         c->send_chain = ngx_ssl_send_chain;
@@ -90,7 +132,6 @@
     c->data = s;
     s->connection = c;
 
-    cscf = ngx_imap_get_module_srv_conf(ctx, ngx_imap_core_module);
     s->protocol = cscf->protocol;
 
     s->ctx = ngx_pcalloc(c->pool, sizeof(void *) * ngx_imap_max_module);
@@ -104,13 +145,15 @@
 
     s->out = greetings[s->protocol];
 
-    c->read->handler = ngx_imap_init_session;
+    lctx = c->log->data;
+    lctx->session = s;
+
+    c->read->handler = ngx_imap_init_protocol;
     c->write->handler = ngx_imap_send;
 
-    ngx_add_timer(c->write, cscf->timeout);
-    ngx_add_timer(c->read, cscf->timeout);
+    ngx_add_timer(rev, cscf->timeout);
 
-    if (ngx_handle_read_event(c->read, 0) == NGX_ERROR) {
+    if (ngx_handle_read_event(rev, 0) == NGX_ERROR) {
         ngx_imap_close_connection(c);
     }
 
@@ -121,9 +164,10 @@
 void
 ngx_imap_send(ngx_event_t *wev)
 {
-    ngx_int_t            n;
-    ngx_connection_t    *c;
-    ngx_imap_session_t  *s;
+    ngx_int_t                  n;
+    ngx_connection_t          *c;
+    ngx_imap_session_t        *s;
+    ngx_imap_core_srv_conf_t  *cscf;
 
     c = wev->data;
     s = c->data;
@@ -147,6 +191,10 @@
     if (n > 0) {
         s->out.len -= n;
 
+        if (wev->timer_set) {
+            ngx_del_timer(wev);
+        }
+
         if (s->quit) {
             ngx_imap_close_connection(c);
             return;
@@ -166,6 +214,10 @@
 
     /* n == NGX_AGAIN */
 
+    cscf = ngx_imap_get_module_srv_conf(s, ngx_imap_core_module);
+
+    ngx_add_timer(c->write, cscf->timeout);
+
     if (ngx_handle_write_event(c->write, 0) == NGX_ERROR) {
         ngx_imap_close_connection(c);
         return;
@@ -174,7 +226,7 @@
 
 
 static void
-ngx_imap_init_session(ngx_event_t *rev)
+ngx_imap_init_protocol(ngx_event_t *rev)
 {
     size_t                     size;
     ngx_connection_t          *c;
@@ -183,6 +235,8 @@
 
     c = rev->data;
 
+    c->log->action = "in auth state";
+
     if (rev->timedout) {
         ngx_log_error(NGX_LOG_INFO, c->log, NGX_ETIMEDOUT, "client timed out");
         ngx_imap_close_connection(c);
@@ -666,3 +720,52 @@
 }
 
 #endif
+
+
+static u_char *
+ngx_imap_log_error(ngx_log_t *log, u_char *buf, size_t len)
+{
+    u_char                 *p;
+    ngx_imap_session_t     *s;
+    ngx_imap_log_ctx_t     *ctx;
+
+    if (log->action) {
+        p = ngx_snprintf(buf, len, " while %s", log->action);
+        len -= p - buf;
+        buf = p;
+    }
+    
+    ctx = log->data;
+
+    p = ngx_snprintf(buf, len, ", client: %V", ctx->client);
+    len -= p - buf;
+    buf = p;
+
+    s = ctx->session;
+
+    if (s == NULL) {
+        return p;
+    }
+
+    p = ngx_snprintf(buf, len, ", server: %V",
+                     &s->connection->listening->addr_text);
+    len -= p - buf;
+    buf = p;
+
+    if (s->login.len == 0) {
+        return p;
+    }
+
+    p = ngx_snprintf(buf, len, ", login: \"%V\"", &s->login);
+    len -= p - buf;
+    buf = p;
+
+    if (s->proxy == NULL) {
+        return p;
+    }
+
+    p = ngx_snprintf(buf, len, ", upstream: %V",
+                     &s->proxy->upstream.peers->peer[0].name);
+
+    return p;
+}
diff --git a/src/imap/ngx_imap_proxy_module.c b/src/imap/ngx_imap_proxy_module.c
index f9a84ce..5502dc6 100644
--- a/src/imap/ngx_imap_proxy_module.c
+++ b/src/imap/ngx_imap_proxy_module.c
@@ -77,8 +77,14 @@
     &ngx_imap_proxy_module_ctx,            /* module context */
     ngx_imap_proxy_commands,               /* module directives */
     NGX_IMAP_MODULE,                       /* module type */
+    NULL,                                  /* init master */
     NULL,                                  /* init module */
-    NULL                                   /* init process */
+    NULL,                                  /* init process */
+    NULL,                                  /* init thread */
+    NULL,                                  /* exit thread */
+    NULL,                                  /* exit process */
+    NULL,                                  /* exit master */
+    NGX_MODULE_V1_PADDING
 };
 
 
@@ -101,9 +107,11 @@
     p->upstream.log = s->connection->log;
     p->upstream.log_error = NGX_ERROR_ERR;
 
+    s->connection->log->action = "in upstream auth state";
+
     rc = ngx_event_connect_peer(&p->upstream);
 
-    if (rc == NGX_ERROR) {
+    if (rc == NGX_ERROR || rc == NGX_CONNECT_ERROR) {
         ngx_imap_session_internal_server_error(s);
         return;
     }
@@ -284,6 +292,8 @@
         pcf = ngx_imap_get_module_srv_conf(s, ngx_imap_proxy_module);
         ngx_add_timer(s->connection->read, pcf->timeout);
         ngx_del_timer(c->read);
+
+        c->log->action = "proxying";
     }
 }
 
@@ -407,6 +417,8 @@
         pcf = ngx_imap_get_module_srv_conf(s, ngx_imap_proxy_module);
         ngx_add_timer(s->connection->read, pcf->timeout);
         ngx_del_timer(c->read);
+
+        c->log->action = "proxying";
     }
 }
 
diff --git a/src/imap/ngx_imap_ssl_module.c b/src/imap/ngx_imap_ssl_module.c
index e5834a6..b072d91 100644
--- a/src/imap/ngx_imap_ssl_module.c
+++ b/src/imap/ngx_imap_ssl_module.c
@@ -65,8 +65,14 @@
     &ngx_imap_ssl_module_ctx,              /* module context */
     ngx_imap_ssl_commands,                 /* module directives */
     NGX_IMAP_MODULE,                       /* module type */
+    NULL,                                  /* init master */
     NULL,                                  /* init module */
-    NULL                                   /* init process */
+    NULL,                                  /* init process */
+    NULL,                                  /* init thread */
+    NULL,                                  /* exit thread */
+    NULL,                                  /* exit process */
+    NULL,                                  /* exit master */
+    NGX_MODULE_V1_PADDING
 };
 
 
@@ -170,5 +176,7 @@
         return NGX_CONF_ERROR;
     }
 
+    SSL_CTX_set_verify(conf->ssl_ctx, SSL_VERIFY_NONE, NULL);
+
     return NGX_CONF_OK;
 }