diff -ru nginx-1.6.2.dist/src/core/ngx_connection.h nginx-1.6.2/src/core/ngx_connection.h
--- nginx-1.6.2.dist/src/core/ngx_connection.h	2015-01-27 16:22:34.000000000 +1000
+++ nginx-1.6.2/src/core/ngx_connection.h	2015-01-27 16:22:59.000000000 +1000
@@ -176,6 +176,10 @@
 
     unsigned            need_last_buf:1;
 
+#if (NGX_SSL)
+    unsigned            ssl_set:1;
+#endif
+
 #if (NGX_HAVE_IOCP)
     unsigned            accept_context_updated:1;
 #endif
diff -ru nginx-1.6.2.dist/src/http/ngx_http_header_filter_module.c nginx-1.6.2/src/http/ngx_http_header_filter_module.c
--- nginx-1.6.2.dist/src/http/ngx_http_header_filter_module.c	2015-01-27 16:22:34.000000000 +1000
+++ nginx-1.6.2/src/http/ngx_http_header_filter_module.c	2015-01-27 16:24:09.000000000 +1000
@@ -525,7 +525,7 @@
                              sizeof("Location: http") - 1);
 
 #if (NGX_HTTP_SSL)
-        if (c->ssl) {
+        if (c->ssl || c->ssl_set) {
             *b->last++ ='s';
         }
 #endif
diff -ru nginx-1.6.2.dist/src/http/ngx_http_variables.c nginx-1.6.2/src/http/ngx_http_variables.c
--- nginx-1.6.2.dist/src/http/ngx_http_variables.c	2015-01-27 16:22:34.000000000 +1000
+++ nginx-1.6.2/src/http/ngx_http_variables.c	2015-01-28 13:28:55.000000000 +1000
@@ -64,6 +64,8 @@
     ngx_http_variable_value_t *v, uintptr_t data);
 static ngx_int_t ngx_http_variable_https(ngx_http_request_t *r,
     ngx_http_variable_value_t *v, uintptr_t data);
+static void ngx_http_variable_https_set(ngx_http_request_t *r,
+    ngx_http_variable_value_t *v, uintptr_t data);
 static ngx_int_t ngx_http_variable_is_args(ngx_http_request_t *r,
     ngx_http_variable_value_t *v, uintptr_t data);
 static ngx_int_t ngx_http_variable_document_root(ngx_http_request_t *r,
@@ -197,7 +199,10 @@
 
     { ngx_string("scheme"), NULL, ngx_http_variable_scheme, 0, 0, 0 },
 
-    { ngx_string("https"), NULL, ngx_http_variable_https, 0, 0, 0 },
+    { ngx_string("https"),
+      ngx_http_variable_https_set,
+      ngx_http_variable_https, 0,
+      NGX_HTTP_VAR_CHANGEABLE|NGX_HTTP_VAR_NOCACHEABLE, 0 },
 
     { ngx_string("request_uri"), NULL, ngx_http_variable_request,
       offsetof(ngx_http_request_t, unparsed_uri), 0, 0 },
@@ -1314,7 +1319,7 @@
 {
 #if (NGX_HTTP_SSL)
 
-    if (r->connection->ssl) {
+    if (r->connection->ssl || r->connection->ssl_set) {
         v->len = sizeof("https") - 1;
         v->valid = 1;
         v->no_cacheable = 0;
@@ -1342,7 +1347,7 @@
 {
 #if (NGX_HTTP_SSL)
 
-    if (r->connection->ssl) {
+    if (r->connection->ssl || r->connection->ssl_set) {
         v->len = sizeof("on") - 1;
         v->valid = 1;
         v->no_cacheable = 0;
@@ -1360,6 +1365,27 @@
 }
 
 
+static void
+ngx_http_variable_https_set(ngx_http_request_t *r,
+    ngx_http_variable_value_t *v, uintptr_t data)
+{
+#if (NGX_HTTP_SSL)
+    if (v->len == 2 && ngx_strncasecmp(v->data, (u_char *) "on", 2) == 0) {
+        if (!r->connection->ssl)
+            r->connection->ssl_set = 1;
+    } else if (v->len == 3 && ngx_strncasecmp(v->data, (u_char *) "off", 3) == 0) {
+        if (r->connection->ssl_set)
+            r->connection->ssl_set = 0;
+    } else {
+        ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
+                      "invalid value for $https \"%V\"", v);
+        return NGX_ERROR;
+    }
+#endif
+    return NGX_OK;
+}
+
+
 static ngx_int_t
 ngx_http_variable_is_args(ngx_http_request_t *r,
     ngx_http_variable_value_t *v, uintptr_t data)
