Index: ngx_http_sticky_misc.h
===================================================================
--- ngx_http_sticky_misc.h	(revision 49)
+++ ngx_http_sticky_misc.h	(working copy)
@@ -15,7 +15,7 @@
 typedef ngx_int_t (*ngx_http_sticky_misc_hmac_pt)(ngx_pool_t *pool, void *in, size_t len, ngx_str_t *key, ngx_str_t *digest);
 typedef ngx_int_t (*ngx_http_sticky_misc_text_pt)(ngx_pool_t *pool, struct sockaddr *in, ngx_str_t *digest);
 
-ngx_int_t ngx_http_sticky_misc_set_cookie (ngx_http_request_t *r, ngx_str_t *name, ngx_str_t *value, ngx_str_t *domain, ngx_str_t *path, time_t expires);
+ngx_int_t ngx_http_sticky_misc_set_cookie (ngx_http_request_t *r, ngx_str_t *name, ngx_str_t *value, ngx_str_t *domain, ngx_str_t *path, time_t expires, unsigned secure, unsigned httponly);
 ngx_int_t ngx_http_sticky_misc_md5(ngx_pool_t *pool, void *in, size_t len, ngx_str_t *digest);
 ngx_int_t ngx_http_sticky_misc_sha1(ngx_pool_t *pool, void *in, size_t len, ngx_str_t *digest);
 ngx_int_t ngx_http_sticky_misc_hmac_md5(ngx_pool_t *pool, void *in, size_t len, ngx_str_t *key, ngx_str_t *digest);
Index: t/basic.t
===================================================================
--- t/basic.t	(revision 0)
+++ t/basic.t	(revision 0)
@@ -0,0 +1,350 @@
+# vi:filetype=
+
+use lib 'lib';
+use Test::Nginx::Socket; # 'no_plan';
+use URI::Escape;
+
+repeat_each(1);
+
+plan tests => repeat_each() * 2 * blocks();
+
+run_tests();
+
+__DATA__
+
+=== TEST 1: hash=md5
+--- http_config
+    upstream backend {
+        server localhost:$TEST_NGINX_SERVER_PORT;
+        server 127.0.0.2:80;
+        server 127.0.0.3:80;
+        server 127.0.0.4:80;
+        server 127.0.0.5:80;
+        sticky name=route hash=md5;
+    }
+--- config
+    location /backend {
+	rewrite /backend /frontend break;
+        proxy_pass http://backend;
+	proxy_set_header Host $host;
+    }
+    location /frontend {
+        echo -n $echo_client_request_headers;
+    }
+--- request
+GET /backend
+--- response_headers
+Set-Cookie: route=908c1a9fb15095f454c085282da20d92
+
+=== TEST 2: hash=sha1
+--- http_config
+    upstream backend {
+        server localhost:$TEST_NGINX_SERVER_PORT;
+        server 127.0.0.2:80;
+        server 127.0.0.3:80;
+        server 127.0.0.4:80;
+        server 127.0.0.5:80;
+        sticky name=route hash=sha1;
+    }
+--- config
+    location /backend {
+	rewrite /backend /frontend break;
+        proxy_pass http://backend;
+	proxy_set_header Host $host;
+    }
+    location /frontend {
+        echo -n $echo_client_request_headers;
+    }
+--- request
+GET /backend
+--- response_headers
+Set-Cookie: route=4262de333a18749d31416a617184734678797276
+
+=== TEST 3: hmac=md5
+--- http_config
+    upstream backend {
+        server localhost:$TEST_NGINX_SERVER_PORT;
+        server 127.0.0.2:80;
+        server 127.0.0.3:80;
+        server 127.0.0.4:80;
+        server 127.0.0.5:80;
+        sticky name=route hmac=md5 hmac_key=secret;
+    }
+--- config
+    location /backend {
+	rewrite /backend /frontend break;
+        proxy_pass http://backend;
+	proxy_set_header Host $host;
+    }
+    location /frontend {
+        echo -n $echo_client_request_headers;
+    }
+--- request
+GET /backend
+--- response_headers
+Set-Cookie: route=d20fd0a9eb6864058781ed6104e4c9fd
+
+=== TEST 4: hmac=sha1
+--- http_config
+    upstream backend {
+        server localhost:$TEST_NGINX_SERVER_PORT;
+        server 127.0.0.2:80;
+        server 127.0.0.3:80;
+        server 127.0.0.4:80;
+        server 127.0.0.5:80;
+        sticky name=route hmac=sha1 hmac_key=secret;
+    }
+--- config
+    location /backend {
+	rewrite /backend /frontend break;
+        proxy_pass http://backend;
+	proxy_set_header Host $host;
+    }
+    location /frontend {
+        echo -n $echo_client_request_headers;
+    }
+--- request
+GET /backend
+--- response_headers
+Set-Cookie: route=34734c8d4b451151897b62db281c0b055e035adc
+
+=== TEST 5: hmac=sha1 hmac_key=secret2
+--- http_config
+    upstream backend {
+        server localhost:$TEST_NGINX_SERVER_PORT;
+        server 127.0.0.2:80;
+        server 127.0.0.3:80;
+        server 127.0.0.4:80;
+        server 127.0.0.5:80;
+        sticky name=route hmac=sha1 hmac_key=secret2;
+    }
+--- config
+    location /backend {
+	rewrite /backend /frontend break;
+        proxy_pass http://backend;
+	proxy_set_header Host $host;
+    }
+    location /frontend {
+        echo -n $echo_client_request_headers;
+    }
+--- request
+GET /backend
+--- response_headers
+Set-Cookie: route=959bfc3973750a198925a3aedf9570f5d9b7e6f8
+
+=== TEST 6: domain=.example.com
+--- http_config
+    upstream backend {
+        server localhost:$TEST_NGINX_SERVER_PORT;
+        server 127.0.0.2:80;
+        server 127.0.0.3:80;
+        server 127.0.0.4:80;
+        server 127.0.0.5:80;
+        sticky domain=.example.com;
+    }
+--- config
+    location /backend {
+	rewrite /backend /frontend break;
+        proxy_pass http://backend;
+	proxy_set_header Host $host;
+    }
+    location /frontend {
+        echo -n $echo_client_request_headers;
+    }
+--- request
+GET /backend
+--- response_headers
+Set-Cookie: route=908c1a9fb15095f454c085282da20d92; Domain=.example.com
+
+=== TEST 7: path=/example
+--- http_config
+    upstream backend {
+        server localhost:$TEST_NGINX_SERVER_PORT;
+        server 127.0.0.2:80;
+        server 127.0.0.3:80;
+        server 127.0.0.4:80;
+        server 127.0.0.5:80;
+        sticky path=/example;
+    }
+--- config
+    location /backend {
+	rewrite /backend /frontend break;
+        proxy_pass http://backend;
+	proxy_set_header Host $host;
+    }
+    location /frontend {
+        echo -n $echo_client_request_headers;
+    }
+--- request
+GET /backend
+--- response_headers
+Set-Cookie: route=908c1a9fb15095f454c085282da20d92; Path=/example
+
+=== TEST 8: expires=1h
+--- http_config
+    upstream backend {
+        server localhost:$TEST_NGINX_SERVER_PORT;
+        server 127.0.0.2:80;
+        server 127.0.0.3:80;
+        server 127.0.0.4:80;
+        server 127.0.0.5:80;
+        sticky expires=1h;
+    }
+--- config
+    location /backend {
+	rewrite /backend /frontend break;
+        proxy_pass http://backend;
+	proxy_set_header Host $host;
+    }
+    location /frontend {
+        echo -n $echo_client_request_headers;
+    }
+--- request
+GET /backend
+--- response_headers
+Set-Cookie: route=908c1a9fb15095f454c085282da20d92; Max-Age=3600
+
+=== TEST 9: text=md5
+--- http_config
+    upstream backend {
+        server localhost:$TEST_NGINX_SERVER_PORT;
+        server 127.0.0.2:80;
+        server 127.0.0.3:80;
+        server 127.0.0.4:80;
+        server 127.0.0.5:80;
+        sticky name=route text=md5;
+    }
+--- config
+    location /backend {
+	rewrite /backend /frontend break;
+        proxy_pass http://backend;
+	proxy_set_header Host $host;
+    }
+    location /frontend {
+        echo -n $echo_client_request_headers;
+    }
+--- request
+GET /backend
+--- response_headers
+Set-Cookie: route=f6082e846954099610d58161bf189f37
+
+=== TEST 10: text=sha1
+--- http_config
+    upstream backend {
+        server localhost:$TEST_NGINX_SERVER_PORT;
+        server 127.0.0.2:80;
+        server 127.0.0.3:80;
+        server 127.0.0.4:80;
+        server 127.0.0.5:80;
+        sticky name=route text=sha1;
+    }
+--- config
+    location /backend {
+	rewrite /backend /frontend break;
+        proxy_pass http://backend;
+	proxy_set_header Host $host;
+    }
+    location /frontend {
+        echo -n $echo_client_request_headers;
+    }
+--- request
+GET /backend
+--- response_headers
+Set-Cookie: route=17305d40bf37f65329da1850efddd32840891e32
+
+=== TEST 11: text=raw
+--- http_config
+    upstream backend {
+        server localhost:$TEST_NGINX_SERVER_PORT;
+        server 127.0.0.2:80;
+        server 127.0.0.3:80;
+        server 127.0.0.4:80;
+        server 127.0.0.5:80;
+        sticky name=route text=raw;
+    }
+--- config
+    location /backend {
+	rewrite /backend /frontend break;
+        proxy_pass http://backend;
+	proxy_set_header Host $host;
+    }
+    location /frontend {
+        echo -n $echo_client_request_headers;
+    }
+--- request
+GET /backend
+--- response_headers
+Set-Cookie: route=127.0.0.1:1984
+
+=== TEST 12: no_fallback
+--- http_config
+    upstream backend {
+        server localhost:$TEST_NGINX_SERVER_PORT;
+        server 127.0.0.2:80;
+        server 127.0.0.3:80;
+        server 127.0.0.4:80;
+        server 127.0.0.5:80;
+        sticky no_fallback;
+    }
+--- config
+    location /backend {
+	rewrite /backend /frontend break;
+        proxy_pass http://backend;
+	proxy_set_header Host $host;
+    }
+    location /frontend {
+        echo -n $echo_client_request_headers;
+    }
+--- request
+GET /backend
+--- response_headers
+Set-Cookie: route=908c1a9fb15095f454c085282da20d92
+
+=== TEST 13: secure
+--- http_config
+    upstream backend {
+        server localhost:$TEST_NGINX_SERVER_PORT;
+        server 127.0.0.2:80;
+        server 127.0.0.3:80;
+        server 127.0.0.4:80;
+        server 127.0.0.5:80;
+        sticky secure;
+    }
+--- config
+    location /backend {
+	rewrite /backend /frontend break;
+        proxy_pass http://backend;
+	proxy_set_header Host $host;
+    }
+    location /frontend {
+        echo -n $echo_client_request_headers;
+    }
+--- request
+GET /backend
+--- response_headers
+Set-Cookie: route=908c1a9fb15095f454c085282da20d92; Secure
+
+=== TEST 14: httponly
+--- http_config
+    upstream backend {
+        server localhost:$TEST_NGINX_SERVER_PORT;
+        server 127.0.0.2:80;
+        server 127.0.0.3:80;
+        server 127.0.0.4:80;
+        server 127.0.0.5:80;
+        sticky httponly;
+    }
+--- config
+    location /backend {
+	rewrite /backend /frontend break;
+        proxy_pass http://backend;
+	proxy_set_header Host $host;
+    }
+    location /frontend {
+        echo -n $echo_client_request_headers;
+    }
+--- request
+GET /backend
+--- response_headers
+Set-Cookie: route=908c1a9fb15095f454c085282da20d92; HttpOnly
+
Index: ngx_http_sticky_module.c
===================================================================
--- ngx_http_sticky_module.c	(revision 49)
+++ ngx_http_sticky_module.c	(working copy)
@@ -23,6 +23,8 @@
 	ngx_str_t                     cookie_domain;
 	ngx_str_t                     cookie_path;
 	time_t                        cookie_expires;
+	unsigned                      cookie_secure:1;
+	unsigned                      cookie_httponly:1;
 	ngx_str_t                     hmac_key;
 	ngx_http_sticky_misc_hash_pt  hash;
 	ngx_http_sticky_misc_hmac_pt  hmac;
@@ -358,7 +360,7 @@
 
 			if (iphp->rrp.peers->peer[i].sockaddr == pc->sockaddr && iphp->rrp.peers->peer[i].socklen == pc->socklen) {
 				if (conf->hash || conf->hmac || conf->text) {
-					ngx_http_sticky_misc_set_cookie(iphp->request, &conf->cookie_name, &conf->peers[i].digest, &conf->cookie_domain, &conf->cookie_path, conf->cookie_expires);
+					ngx_http_sticky_misc_set_cookie(iphp->request, &conf->cookie_name, &conf->peers[i].digest, &conf->cookie_domain, &conf->cookie_path, conf->cookie_expires, conf->cookie_secure, conf->cookie_httponly);
 					ngx_log_debug(NGX_LOG_DEBUG_HTTP, pc->log, 0, "[sticky/get_sticky_peer] set cookie \"%V\" value=\"%V\" index=%ui", &conf->cookie_name, &conf->peers[i].digest, i);
 				} else {
 					ngx_str_t route;
@@ -373,7 +375,7 @@
 					}
 					ngx_snprintf(route.data, route.len, "%d", i);
 					route.len = ngx_strlen(route.data);
-					ngx_http_sticky_misc_set_cookie(iphp->request, &conf->cookie_name, &route, &conf->cookie_domain, &conf->cookie_path, conf->cookie_expires);
+					ngx_http_sticky_misc_set_cookie(iphp->request, &conf->cookie_name, &route, &conf->cookie_domain, &conf->cookie_path, conf->cookie_expires, conf->cookie_secure, conf->cookie_httponly);
 					ngx_log_debug(NGX_LOG_DEBUG_HTTP, pc->log, 0, "[sticky/get_sticky_peer] set cookie \"%V\" value=\"%V\" index=%ui", &conf->cookie_name, &tmp, i);
 				}
 				break; /* found and hopefully the cookie have been set */
@@ -401,6 +403,8 @@
 	ngx_str_t path = ngx_string("");
 	ngx_str_t hmac_key = ngx_string("");
 	time_t expires = NGX_CONF_UNSET;
+	unsigned secure = 0;
+	unsigned httponly = 0;
 	ngx_http_sticky_misc_hash_pt hash = NGX_CONF_UNSET_PTR;
 	ngx_http_sticky_misc_hmac_pt hmac = NULL;
 	ngx_http_sticky_misc_text_pt text = NULL;
@@ -477,6 +481,16 @@
 			continue;
 		}
 
+		if (ngx_strncmp(value[i].data, "secure", 6) == 0 && value[i].len == 6) {
+			secure = 1;
+			continue;
+		}
+
+		if (ngx_strncmp(value[i].data, "httponly", 8) == 0 && value[i].len == 8) {
+			httponly = 1;
+			continue;
+		}
+
 		/* is "text=" is starting the argument ? */
 		if ((u_char *)ngx_strstr(value[i].data, "text=") == value[i].data) {
 
@@ -646,6 +660,8 @@
 	sticky_conf->cookie_domain = domain;
 	sticky_conf->cookie_path = path;
 	sticky_conf->cookie_expires = expires;
+	sticky_conf->cookie_secure = secure;
+	sticky_conf->cookie_httponly = httponly;
 	sticky_conf->hash = hash;
 	sticky_conf->hmac = hmac;
 	sticky_conf->text = text;
Index: ngx_http_sticky_misc.c
===================================================================
--- ngx_http_sticky_misc.c	(revision 49)
+++ ngx_http_sticky_misc.c	(working copy)
@@ -16,7 +16,7 @@
 	#define ngx_str_set(str, text) (str)->len = sizeof(text) - 1; (str)->data = (u_char *) text
 #endif
 
-ngx_int_t ngx_http_sticky_misc_set_cookie(ngx_http_request_t *r, ngx_str_t *name, ngx_str_t *value, ngx_str_t *domain, ngx_str_t *path, time_t expires)
+ngx_int_t ngx_http_sticky_misc_set_cookie(ngx_http_request_t *r, ngx_str_t *name, ngx_str_t *value, ngx_str_t *domain, ngx_str_t *path, time_t expires, unsigned secure, unsigned httponly)
 {
 	u_char  *cookie, *p;
 	size_t  len;
@@ -48,6 +48,16 @@
 		len += sizeof("; Path=") - 1 + path->len;
 	}
 
+	/* ; Secure */
+	if (secure) {
+		len += sizeof("; Secure") - 1;
+	}
+
+	/* ; HttpOnly */
+	if (httponly) {
+		len += sizeof("; HttpOnly") - 1;
+	}
+
 	cookie = ngx_pnalloc(r->pool, len);	
 	if (cookie == NULL) {
 		return NGX_ERROR;
@@ -72,6 +82,14 @@
 		p = ngx_copy(p, path->data, path->len);
 	}
 
+	if (secure) {
+		p = ngx_copy(p, "; Secure", sizeof("; Secure") - 1);	
+	}
+
+	if (httponly) {
+		p = ngx_copy(p, "; HttpOnly", sizeof("; HttpOnly") - 1);	
+	}
+
 	part = &r->headers_out.headers.part;
 	elt = part->elts;
 	set_cookie = NULL;


