nginx-0.3.8-RELEASE import

    *) Security: nginx now checks URI got from a backend in
       "X-Accel-Redirect" header line or in SSI file for the "/../" paths
       and zeroes.

    *) Change: nginx now does not treat the empty user name in the
       "Authorization" header line as valid one.

    *) Feature: the "ssl_session_timeout" directives of the
       ngx_http_ssl_module and ngx_imap_ssl_module.

    *) Feature: the "auth_http_header" directive of the
       ngx_imap_auth_http_module.

    *) Feature: the "add_header" directive.

    *) Feature: the ngx_http_realip_module.

    *) Feature: the new variables to use in the "log_format" directive:
       $bytes_sent, $apache_bytes_sent, $status, $time_gmt, $uri,
       $request_time, $request_length, $upstream_status,
       $upstream_response_time, $gzip_ratio, $uid_got, $uid_set,
       $connection, $pipe, and $msec. The parameters in the "%name" form
       will be canceled soon.

    *) Change: now the false variable values in the "if" directive are the
       empty string "" and string starting with "0".

    *) Bugfix: while using proxied or FastCGI-server nginx may leave
       connections and temporary files with client requests in open state.

    *) Bugfix: the worker processes did not flush the buffered logs on
       graceful exit.

    *) Bugfix: if the request URI was changes by the "rewrite" directive
       and the request was proxied in location given by regular expression,
       then the incorrect request was transferred to backend; the bug had
       appeared in 0.2.6.

    *) Bugfix: the "expires" directive did not remove the previous
       "Expires" header.

    *) Bugfix: nginx may stop to accept requests if the "rtsig" method and
       several worker processes were used.

    *) Bugfix: the "\"" and "\'" escape symbols were incorrectly handled in
       SSI commands.

    *) Bugfix: if the response was ended just after the SSI command and
       gzipping was used, then the response did not transferred complete or
       did not transferred at all.
diff --git a/src/imap/ngx_imap_auth_http_module.c b/src/imap/ngx_imap_auth_http_module.c
index 4b8584d..dfe0c20 100644
--- a/src/imap/ngx_imap_auth_http_module.c
+++ b/src/imap/ngx_imap_auth_http_module.c
@@ -18,6 +18,9 @@
 
     ngx_str_t                       host_header;
     ngx_str_t                       uri;
+    ngx_str_t                       header;
+
+    ngx_array_t                    *headers;
 } ngx_imap_auth_http_conf_t;
 
 
@@ -70,6 +73,8 @@
 static char *ngx_imap_auth_http_merge_conf(ngx_conf_t *cf, void *parent,
     void *child);
 static char *ngx_imap_auth_http(ngx_conf_t *cf, ngx_command_t *cmd, void *conf);
+static char *ngx_imap_auth_http_header(ngx_conf_t *cf, ngx_command_t *cmd,
+    void *conf);
 
 
 static ngx_command_t  ngx_imap_auth_http_commands[] = {
@@ -88,6 +93,13 @@
       offsetof(ngx_imap_auth_http_conf_t, timeout),
       NULL },
 
+    { ngx_string("auth_http_header"),
+      NGX_IMAP_MAIN_CONF|NGX_IMAP_SRV_CONF|NGX_CONF_TAKE2,
+      ngx_imap_auth_http_header,
+      NGX_IMAP_SRV_CONF_OFFSET,
+      0,
+      NULL },
+
       ngx_null_command
 };
 
@@ -991,12 +1003,12 @@
     }
 
     b->last = ngx_cpymem(b->last, "GET ", sizeof("GET ") - 1);
-    b->last = ngx_cpymem(b->last, ahcf->uri.data, ahcf->uri.len);
+    b->last = ngx_copy(b->last, ahcf->uri.data, ahcf->uri.len);
     b->last = ngx_cpymem(b->last, " HTTP/1.0" CRLF,
                          sizeof(" HTTP/1.0" CRLF) - 1);
 
     b->last = ngx_cpymem(b->last, "Host: ", sizeof("Host: ") - 1);
-    b->last = ngx_cpymem(b->last, ahcf->host_header.data,
+    b->last = ngx_copy(b->last, ahcf->host_header.data,
                          ahcf->host_header.len);
     *b->last++ = CR; *b->last++ = LF;
 
@@ -1004,11 +1016,11 @@
                          sizeof("Auth-Method: plain" CRLF) - 1);
 
     b->last = ngx_cpymem(b->last, "Auth-User: ", sizeof("Auth-User: ") - 1);
-    b->last = ngx_cpymem(b->last, s->login.data, s->login.len);
+    b->last = ngx_copy(b->last, s->login.data, s->login.len);
     *b->last++ = CR; *b->last++ = LF;
 
     b->last = ngx_cpymem(b->last, "Auth-Pass: ", sizeof("Auth-Pass: ") - 1);
-    b->last = ngx_cpymem(b->last, s->passwd.data, s->passwd.len);
+    b->last = ngx_copy(b->last, s->passwd.data, s->passwd.len);
     *b->last++ = CR; *b->last++ = LF;
 
     b->last = ngx_cpymem(b->last, "Auth-Protocol: ",
@@ -1021,10 +1033,14 @@
                           s->login_attempt);
 
     b->last = ngx_cpymem(b->last, "Client-IP: ", sizeof("Client-IP: ") - 1);
-    b->last = ngx_cpymem(b->last, s->connection->addr_text.data,
+    b->last = ngx_copy(b->last, s->connection->addr_text.data,
                          s->connection->addr_text.len);
     *b->last++ = CR; *b->last++ = LF;
 
+    if (ahcf->header.len) {
+        b->last = ngx_copy(b->last, ahcf->header.data, ahcf->header.len);
+    }
+
     /* add "\r\n" at the header end */
     *b->last++ = CR; *b->last++ = LF;
 
@@ -1065,6 +1081,11 @@
     ngx_imap_auth_http_conf_t *prev = parent;
     ngx_imap_auth_http_conf_t *conf = child;
 
+    u_char           *p;
+    size_t            len;
+    ngx_uint_t        i;
+    ngx_table_elt_t  *header;
+
     if (conf->peers == NULL) {
         conf->peers = prev->peers;
         conf->host_header = prev->host_header;
@@ -1073,6 +1094,34 @@
 
     ngx_conf_merge_msec_value(conf->timeout, prev->timeout, 60000);
 
+    if (conf->headers == NULL) {
+        conf->headers = prev->headers;
+        conf->header = prev->header;
+    }
+
+    if (conf->headers && conf->header.len == 0) {
+        len = 0;
+        header = conf->headers->elts;
+        for (i = 0; i < conf->headers->nelts; i++) {
+            len += header[i].key.len + 2 + header[i].value.len + 2;
+        }
+
+        p = ngx_palloc(cf->pool, len);
+        if (p == NULL) {
+            return NGX_CONF_ERROR;
+        }
+
+        conf->header.len = len;
+        conf->header.data = p;
+
+        for (i = 0; i < conf->headers->nelts; i++) {
+            p = ngx_cpymem(p, header[i].key.data, header[i].key.len);
+            *p++ = ':'; *p++ = ' ';
+            p = ngx_cpymem(p, header[i].value.data, header[i].value.len);
+            *p++ = CR; *p++ = LF;
+        }
+    }
+
     return NGX_CONF_OK;
 }
 
@@ -1087,7 +1136,7 @@
 #if (NGX_HAVE_UNIX_DOMAIN)
     ngx_unix_domain_upstream_t   unix_upstream;
 #endif
-    
+
     value = cf->args->elts;
 
     url = &value[1];
@@ -1143,3 +1192,32 @@
 
     return NGX_CONF_OK;
 }
+
+
+static char *
+ngx_imap_auth_http_header(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
+{   
+    ngx_imap_auth_http_conf_t *ahcf = conf;
+
+    ngx_str_t        *value;
+    ngx_table_elt_t  *header;
+
+    if (ahcf->headers == NULL) {
+        ahcf->headers = ngx_array_create(cf->pool, 1, sizeof(ngx_table_elt_t));
+        if (ahcf->headers == NULL) {
+            return NGX_CONF_ERROR;
+        }
+    }
+
+    header = ngx_array_push(ahcf->headers);
+    if (header == NULL) {
+        return NGX_CONF_ERROR;
+    }
+
+    value = cf->args->elts;
+
+    header->key = value[1];
+    header->value = value[2];
+
+    return NGX_CONF_OK;
+}
diff --git a/src/imap/ngx_imap_ssl_module.c b/src/imap/ngx_imap_ssl_module.c
index d663e88..f92dba6 100644
--- a/src/imap/ngx_imap_ssl_module.c
+++ b/src/imap/ngx_imap_ssl_module.c
@@ -83,6 +83,12 @@
       ngx_imap_ssl_nosupported, 0, 0, ngx_imap_ssl_openssl097 },
 #endif
 
+    { ngx_string("ssl_session_timeout"),
+      NGX_IMAP_MAIN_CONF|NGX_IMAP_SRV_CONF|NGX_CONF_TAKE1,
+      ngx_conf_set_sec_slot,
+      NGX_IMAP_SRV_CONF_OFFSET,
+      offsetof(ngx_imap_ssl_conf_t, session_timeout),
+      NULL },
 
       ngx_null_command
 };
@@ -140,6 +146,7 @@
      */
 
     scf->enable = NGX_CONF_UNSET;
+    scf->session_timeout = NGX_CONF_UNSET;
     scf->prefer_server_ciphers = NGX_CONF_UNSET;
 
     return scf;
@@ -160,6 +167,9 @@
         return NGX_CONF_OK;
     }
 
+    ngx_conf_merge_value(conf->session_timeout,
+                         prev->session_timeout, 300);
+
     ngx_conf_merge_value(conf->prefer_server_ciphers,
                          prev->prefer_server_ciphers, 0);
 
@@ -225,6 +235,8 @@
     SSL_CTX_set_session_id_context(conf->ssl.ctx, ngx_imap_session_id_ctx,
                                    sizeof(ngx_imap_session_id_ctx) - 1);
 
+    SSL_CTX_set_timeout(conf->ssl.ctx, conf->session_timeout);
+
     return NGX_CONF_OK;
 }
 
diff --git a/src/imap/ngx_imap_ssl_module.h b/src/imap/ngx_imap_ssl_module.h
index fd0ccad..2ac9f11 100644
--- a/src/imap/ngx_imap_ssl_module.h
+++ b/src/imap/ngx_imap_ssl_module.h
@@ -22,6 +22,8 @@
 
     ngx_uint_t      protocols;
 
+    time_t          session_timeout;
+
     ngx_str_t       certificate;
     ngx_str_t       certificate_key;