diff src/imap/ngx_imap_handler.c @ 543:511a89da35ad release-0.2.0

nginx-0.2.0-RELEASE import *) The pid-file names used during online upgrade was changed and now is not required a manual rename operation. The old master process adds the ".oldbin" suffix to its pid-file and executes a new binary file. The new master process creates usual pid-file without the ".newbin" suffix. If the master process exits, then old master process renames back its pid-file with the ".oldbin" suffix to the pid-file without suffix. *) Change: the "worker_connections" directive, new name of the "connections" directive; now the directive specifies maximum number of connections, but not maximum socket descriptor number. *) Feature: SSL supports the session cache inside one worker process. *) Feature: the "satisfy_any" directive. *) Change: the ngx_http_access_module and ngx_http_auth_basic_module do not run for subrequests. *) Feature: the "worker_rlimit_nofile" and "worker_rlimit_sigpending" directives. *) Bugfix: if all backend using in load-balancing failed after one error, then nginx did not try do connect to them during 60 seconds. *) Bugfix: in IMAP/POP3 command argument parsing. Thanks to Rob Mueller. *) Bugfix: errors while using SSL in IMAP/POP3 proxy. *) Bugfix: errors while using SSI and gzipping. *) Bugfix: the "Expires" and "Cache-Control" header lines were omitted from the 304 responses. Thanks to Alexandr Kukushkin.
author Igor Sysoev <igor@sysoev.ru>
date Fri, 23 Sep 2005 11:02:22 +0000
parents b09ee85d0ac8
children 818fbd4750b9
line wrap: on
line diff
--- a/src/imap/ngx_imap_handler.c
+++ b/src/imap/ngx_imap_handler.c
@@ -33,6 +33,7 @@ static ngx_str_t  internal_server_errors
 static u_char  pop3_ok[] = "+OK" CRLF;
 static u_char  pop3_invalid_command[] = "-ERR invalid command" CRLF;
 
+static u_char  imap_star[] = "* ";
 static u_char  imap_ok[] = "OK completed" CRLF;
 static u_char  imap_next[] = "+ OK" CRLF;
 static u_char  imap_bye[] = "* BYE" CRLF;
@@ -42,26 +43,48 @@ static u_char  imap_invalid_command[] = 
 void
 ngx_imap_init_connection(ngx_connection_t *c)
 {
-    ngx_imap_log_ctx_t  *ctx;
+    ngx_imap_log_ctx_t   *lctx;
+#if (NGX_IMAP_SSL)
+    ngx_imap_conf_ctx_t  *ctx;
+    ngx_imap_ssl_conf_t  *sslcf;
+#endif
 
     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) {
+    lctx = ngx_palloc(c->pool, sizeof(ngx_imap_log_ctx_t));
+    if (lctx == NULL) {
         ngx_imap_close_connection(c);
         return;
     } 
 
-    ctx->client = &c->addr_text;
-    ctx->session = NULL;
+    lctx->client = &c->addr_text;
+    lctx->session = NULL;
 
     c->log->connection = c->number;
     c->log->handler = ngx_imap_log_error;
-    c->log->data = ctx;
+    c->log->data = lctx;
     c->log->action = "sending client greeting line";
 
     c->log_error = NGX_ERROR_INFO;
 
+#if (NGX_IMAP_SSL)
+
+    ctx = c->ctx;
+    sslcf = ngx_imap_get_module_srv_conf(ctx, ngx_imap_ssl_module);
+
+    if (sslcf->enable) {
+        if (ngx_ssl_create_connection(sslcf->ssl_ctx, c, 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;
+    }
+
+#endif
+
     ngx_imap_init_session(c->read);
 }
 
@@ -76,27 +99,15 @@ ngx_imap_init_session(ngx_event_t *rev)
     ngx_imap_core_srv_conf_t  *cscf;
 #if (NGX_IMAP_SSL)
     ngx_int_t                  rc;
-    ngx_imap_ssl_conf_t       *sslcf;
 #endif
 
     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);
-
-    if (sslcf->enable) {
-
-        if (ngx_ssl_create_session(sslcf->ssl_ctx, c, NGX_SSL_BUFFER)
-            == NGX_ERROR)
-        {
-            ngx_imap_close_connection(c);
-            return;
-        }
+    if (c->ssl) {
 
         rc = ngx_ssl_handshake(c);
 
@@ -116,9 +127,6 @@ ngx_imap_init_session(ngx_event_t *rev)
             return;
         }
 
-        c->recv = ngx_ssl_recv;
-        c->send = ngx_ssl_write;
-        c->send_chain = ngx_ssl_send_chain;
     }
 
 #endif
@@ -275,11 +283,11 @@ ngx_imap_init_protocol(ngx_event_t *rev)
 void
 ngx_imap_auth_state(ngx_event_t *rev)
 {
-    u_char                    *text, *last, *p;
+    u_char                    *text, *last, *p, *dst, *src, *end;
     ssize_t                    text_len, last_len;
     ngx_str_t                 *arg;
     ngx_int_t                  rc;
-    ngx_uint_t                 tag;
+    ngx_uint_t                 tag, i;
     ngx_connection_t          *c;
     ngx_imap_session_t        *s;
     ngx_imap_core_srv_conf_t  *cscf;
@@ -324,6 +332,27 @@ ngx_imap_auth_state(ngx_event_t *rev)
         ngx_log_debug1(NGX_LOG_DEBUG_IMAP, c->log, 0, "imap auth command: %i",
                        s->command);
 
+        if (s->backslash) {
+
+            arg = s->args.elts;
+
+            for (i = 0; i < s->args.nelts; i++) {
+                dst = arg[i].data;
+                end = dst + arg[i].len;
+
+                for (src = dst; src < end; dst++) {
+                    *dst = *src;
+                    if (*src++ == '\\') {
+                        *dst = *src++;
+                    }
+                }
+
+                arg[i].len = dst - arg[i].data;
+            }
+
+            s->backslash = 0;
+        }
+
         switch (s->command) {
 
         case NGX_IMAP_LOGIN:
@@ -405,6 +434,11 @@ ngx_imap_auth_state(ngx_event_t *rev)
     }
 
     if (tag) {
+        if (s->tag.len == 0) {
+            s->tag.len = sizeof(imap_star) - 1;
+            s->tag.data = (u_char *) imap_star;
+        }
+
         if (s->tagged_line.len < s->tag.len + text_len + last_len) {
             s->tagged_line.len = s->tag.len + text_len + last_len;
             s->tagged_line.data = ngx_palloc(c->pool, s->tagged_line.len);
@@ -693,6 +727,8 @@ ngx_imap_close_connection(ngx_connection
 
 #endif
 
+    c->closed = 1;
+
     pool = c->pool;
 
     ngx_close_connection(c);