diff options
-rw-r--r-- | src/go/unit/nxt_cgo_lib.c | 4 | ||||
-rw-r--r-- | src/go/unit/request.go | 7 | ||||
-rw-r--r-- | src/java/nginx/unit/Request.java | 6 | ||||
-rw-r--r-- | src/java/nxt_jni_Request.c | 17 | ||||
-rw-r--r-- | src/nxt_h1proto.c | 17 | ||||
-rw-r--r-- | src/nxt_http.h | 4 | ||||
-rw-r--r-- | src/nxt_http_request.c | 15 | ||||
-rw-r--r-- | src/nxt_php_sapi.c | 4 | ||||
-rw-r--r-- | src/nxt_python_wsgi.c | 27 | ||||
-rw-r--r-- | src/nxt_router.c | 2 | ||||
-rw-r--r-- | src/nxt_unit_request.h | 1 | ||||
-rw-r--r-- | src/perl/nxt_perl_psgi.c | 5 | ||||
-rw-r--r-- | src/ruby/nxt_ruby.c | 4 | ||||
-rw-r--r-- | test/test_tls.py | 21 |
14 files changed, 103 insertions, 31 deletions
diff --git a/src/go/unit/nxt_cgo_lib.c b/src/go/unit/nxt_cgo_lib.c index 98a23482..cc1228f5 100644 --- a/src/go/unit/nxt_cgo_lib.c +++ b/src/go/unit/nxt_cgo_lib.c @@ -83,6 +83,10 @@ nxt_cgo_request_handler(nxt_unit_request_info_t *req) nxt_go_request_set_remote_addr(go_req, nxt_cgo_str_init(&remote_addr, &r->remote, r->remote_length)); + if (r->tls) { + nxt_go_request_set_tls(go_req); + } + nxt_go_request_handler(go_req, (uintptr_t) req->unit->data); } diff --git a/src/go/unit/request.go b/src/go/unit/request.go index 829a2c64..ad56cabb 100644 --- a/src/go/unit/request.go +++ b/src/go/unit/request.go @@ -14,6 +14,7 @@ import ( "io" "net/http" "net/url" + "crypto/tls" "unsafe" ) @@ -125,6 +126,12 @@ func nxt_go_request_set_remote_addr(go_req uintptr, addr *C.nxt_cgo_str_t) { get_request(go_req).req.RemoteAddr = C.GoStringN(addr.start, addr.length) } +//export nxt_go_request_set_tls +func nxt_go_request_set_tls(go_req uintptr) { + + get_request(go_req).req.TLS = &tls.ConnectionState{ } +} + //export nxt_go_request_handler func nxt_go_request_handler(go_req uintptr, h uintptr) { r := get_request(go_req) diff --git a/src/java/nginx/unit/Request.java b/src/java/nginx/unit/Request.java index dc73c656..b46d3f59 100644 --- a/src/java/nginx/unit/Request.java +++ b/src/java/nginx/unit/Request.java @@ -980,11 +980,13 @@ public class Request implements HttpServletRequest, DynamicPathRequest @Override public boolean isSecure() { - log("isSecure"); + trace("isSecure"); - return false; + return isSecure(req_ptr); } + private static native boolean isSecure(long req_ptr); + @Override public void removeAttribute(String name) { diff --git a/src/java/nxt_jni_Request.c b/src/java/nxt_jni_Request.c index 6fb9cb44..a9fbe0e4 100644 --- a/src/java/nxt_jni_Request.c +++ b/src/java/nxt_jni_Request.c @@ -56,6 +56,8 @@ static jstring JNICALL nxt_java_Request_getServerName(JNIEnv *env, jclass cls, jlong req_ptr); static jint JNICALL nxt_java_Request_getServerPort(JNIEnv *env, jclass cls, jlong req_ptr); +static jboolean JNICALL nxt_java_Request_isSecure(JNIEnv *env, jclass cls, + jlong req_ptr); static void JNICALL nxt_java_Request_log(JNIEnv *env, jclass cls, jlong req_info_ptr, jstring msg, jint msg_len); static void JNICALL nxt_java_Request_trace(JNIEnv *env, jclass cls, @@ -166,6 +168,10 @@ nxt_java_initRequest(JNIEnv *env, jobject cl) (char *) "(J)I", nxt_java_Request_getServerPort }, + { (char *) "isSecure", + (char *) "(J)Z", + nxt_java_Request_isSecure }, + { (char *) "log", (char *) "(JLjava/lang/String;I)V", nxt_java_Request_log }, @@ -603,6 +609,17 @@ nxt_java_Request_getServerPort(JNIEnv *env, jclass cls, jlong req_ptr) } +static jboolean JNICALL +nxt_java_Request_isSecure(JNIEnv *env, jclass cls, jlong req_ptr) +{ + nxt_unit_request_t *r; + + r = nxt_jlong2ptr(req_ptr); + + return r->tls != 0; +} + + static void JNICALL nxt_java_Request_log(JNIEnv *env, jclass cls, jlong req_info_ptr, jstring msg, jint msg_len) diff --git a/src/nxt_h1proto.c b/src/nxt_h1proto.c index 07e3c7bc..3a822042 100644 --- a/src/nxt_h1proto.c +++ b/src/nxt_h1proto.c @@ -35,6 +35,7 @@ static void nxt_h1p_request_body_read(nxt_task_t *task, nxt_http_request_t *r); static void nxt_h1p_conn_request_body_read(nxt_task_t *task, void *obj, void *data); static void nxt_h1p_request_local_addr(nxt_task_t *task, nxt_http_request_t *r); +static void nxt_h1p_request_tls(nxt_task_t *task, nxt_http_request_t *r); static void nxt_h1p_request_header_send(nxt_task_t *task, nxt_http_request_t *r); static void nxt_h1p_request_send(nxt_task_t *task, nxt_http_request_t *r, @@ -103,6 +104,13 @@ const nxt_http_proto_local_addr_t nxt_http_proto_local_addr[3] = { }; +const nxt_http_proto_tls_t nxt_http_proto_tls[3] = { + nxt_h1p_request_tls, + NULL, + NULL, +}; + + const nxt_http_proto_header_send_t nxt_http_proto_header_send[3] = { nxt_h1p_request_header_send, NULL, @@ -813,6 +821,15 @@ nxt_h1p_request_local_addr(nxt_task_t *task, nxt_http_request_t *r) } +static void +nxt_h1p_request_tls(nxt_task_t *task, nxt_http_request_t *r) +{ +#if (NXT_TLS) + r->tls = r->proto.h1->conn->u.tls; +#endif +} + + #define NXT_HTTP_LAST_SUCCESS \ (NXT_HTTP_OK + nxt_nitems(nxt_http_success) - 1) diff --git a/src/nxt_http.h b/src/nxt_http.h index 3cf3e38e..00c13599 100644 --- a/src/nxt_http.h +++ b/src/nxt_http.h @@ -131,6 +131,7 @@ struct nxt_http_request_s { nxt_sockaddr_t *remote; nxt_sockaddr_t *local; + void *tls; nxt_timer_t timer; void *timer_data; @@ -169,6 +170,7 @@ typedef void (*nxt_http_proto_body_read_t)(nxt_task_t *task, nxt_http_request_t *r); typedef void (*nxt_http_proto_local_addr_t)(nxt_task_t *task, nxt_http_request_t *r); +typedef void (*nxt_http_proto_tls_t)(nxt_task_t *task, nxt_http_request_t *r); typedef void (*nxt_http_proto_header_send_t)(nxt_task_t *task, nxt_http_request_t *r); typedef void (*nxt_http_proto_send_t)(nxt_task_t *task, nxt_http_request_t *r, @@ -190,7 +192,6 @@ nxt_http_request_t *nxt_http_request_create(nxt_task_t *task); void nxt_http_request_error(nxt_task_t *task, nxt_http_request_t *r, nxt_http_status_t status); void nxt_http_request_read_body(nxt_task_t *task, nxt_http_request_t *r); -void nxt_http_request_local_addr(nxt_task_t *task, nxt_http_request_t *r); void nxt_http_request_header_send(nxt_task_t *task, nxt_http_request_t *r); void nxt_http_request_send(nxt_task_t *task, nxt_http_request_t *r, nxt_buf_t *out); @@ -225,6 +226,7 @@ extern nxt_lvlhsh_t nxt_response_fields_hash; extern const nxt_http_proto_body_read_t nxt_http_proto_body_read[]; extern const nxt_http_proto_local_addr_t nxt_http_proto_local_addr[]; +extern const nxt_http_proto_tls_t nxt_http_proto_tls[]; extern const nxt_http_proto_header_send_t nxt_http_proto_header_send[]; extern const nxt_http_proto_send_t nxt_http_proto_send[]; extern const nxt_http_proto_body_bytes_sent_t nxt_http_proto_body_bytes_sent[]; diff --git a/src/nxt_http_request.c b/src/nxt_http_request.c index 7ba2dfd5..3ba7ffe7 100644 --- a/src/nxt_http_request.c +++ b/src/nxt_http_request.c @@ -11,6 +11,8 @@ static nxt_int_t nxt_http_validate_host(nxt_str_t *host, nxt_mp_t *mp); static void nxt_http_request_start(nxt_task_t *task, void *obj, void *data); static void nxt_http_request_pass(nxt_task_t *task, void *obj, void *data); +static void nxt_http_request_proto_info(nxt_task_t *task, + nxt_http_request_t *r); static void nxt_http_request_mem_buf_completion(nxt_task_t *task, void *obj, void *data); static void nxt_http_request_done(nxt_task_t *task, void *obj, void *data); @@ -338,7 +340,7 @@ nxt_http_request_application(nxt_task_t *task, nxt_http_request_t *r, * TODO: need an application flag to get local address * required by "SERVER_ADDR" in Pyhton and PHP. Not used in Go. */ - nxt_http_request_local_addr(task, r); + nxt_http_request_proto_info(task, r); if (r->host.length != 0) { r->server_name = r->host; @@ -353,20 +355,21 @@ nxt_http_request_application(nxt_task_t *task, nxt_http_request_t *r, } -void -nxt_http_request_read_body(nxt_task_t *task, nxt_http_request_t *r) +static void +nxt_http_request_proto_info(nxt_task_t *task, nxt_http_request_t *r) { if (r->proto.any != NULL) { - nxt_http_proto_body_read[r->protocol](task, r); + nxt_http_proto_local_addr[r->protocol](task, r); + nxt_http_proto_tls[r->protocol](task, r); } } void -nxt_http_request_local_addr(nxt_task_t *task, nxt_http_request_t *r) +nxt_http_request_read_body(nxt_task_t *task, nxt_http_request_t *r) { if (r->proto.any != NULL) { - nxt_http_proto_local_addr[r->protocol](task, r); + nxt_http_proto_body_read[r->protocol](task, r); } } diff --git a/src/nxt_php_sapi.c b/src/nxt_php_sapi.c index 4b71de5c..a6ec6c60 100644 --- a/src/nxt_php_sapi.c +++ b/src/nxt_php_sapi.c @@ -929,6 +929,10 @@ nxt_php_register_variables(zval *track_vars_array TSRMLS_DC) track_vars_array TSRMLS_CC); nxt_php_set_cstr(req, "SERVER_PORT", "80", 2, track_vars_array TSRMLS_CC); + if (r->tls) { + nxt_php_set_cstr(req, "HTTPS", "on", 2, track_vars_array TSRMLS_CC); + } + f_end = r->fields + r->fields_count; for (f = r->fields; f < f_end; f++) { name = nxt_unit_sptr_get(&f->name); diff --git a/src/nxt_python_wsgi.c b/src/nxt_python_wsgi.c index 6478f38c..a6d5f217 100644 --- a/src/nxt_python_wsgi.c +++ b/src/nxt_python_wsgi.c @@ -619,26 +619,6 @@ nxt_python_create_environ(nxt_task_t *task) } - obj = PyString_FromStringAndSize("http", nxt_length("http")); - - if (nxt_slow_path(obj == NULL)) { - nxt_alert(task, - "Python failed to create the \"wsgi.url_scheme\" environ value"); - goto fail; - } - - if (nxt_slow_path(PyDict_SetItemString(environ, "wsgi.url_scheme", obj) - != 0)) - { - nxt_alert(task, - "Python failed to set the \"wsgi.url_scheme\" environ value"); - goto fail; - } - - Py_DECREF(obj); - obj = NULL; - - if (nxt_slow_path(PyType_Ready(&nxt_py_input_type) != 0)) { nxt_alert(task, "Python failed to initialize the \"wsgi.input\" type object"); @@ -726,6 +706,13 @@ nxt_python_get_environ(nxt_python_run_ctx_t *ctx) RC(nxt_python_add_sptr(ctx, "REMOTE_ADDR", &r->remote, r->remote_length)); RC(nxt_python_add_sptr(ctx, "SERVER_ADDR", &r->local, r->local_length)); + if (r->tls) { + RC(nxt_python_add_str(ctx, "wsgi.url_scheme", "https", 5)); + + } else { + RC(nxt_python_add_str(ctx, "wsgi.url_scheme", "http", 4)); + } + RC(nxt_python_add_sptr(ctx, "SERVER_PROTOCOL", &r->version, r->version_length)); diff --git a/src/nxt_router.c b/src/nxt_router.c index f546887b..149a0ff3 100644 --- a/src/nxt_router.c +++ b/src/nxt_router.c @@ -4703,6 +4703,8 @@ nxt_router_prepare_msg(nxt_task_t *task, nxt_http_request_t *r, p = nxt_cpymem(p, nxt_sockaddr_address(r->local), r->local->address_length); *p++ = '\0'; + req->tls = (r->tls != NULL); + req->server_name_length = r->server_name.length; nxt_unit_sptr_set(&req->server_name, p); p = nxt_cpymem(p, r->server_name.start, r->server_name.length); diff --git a/src/nxt_unit_request.h b/src/nxt_unit_request.h index 88d569a6..2207cefa 100644 --- a/src/nxt_unit_request.h +++ b/src/nxt_unit_request.h @@ -19,6 +19,7 @@ struct nxt_unit_request_s { uint8_t version_length; uint8_t remote_length; uint8_t local_length; + uint8_t tls; uint32_t server_name_length; uint32_t target_length; uint32_t path_length; diff --git a/src/perl/nxt_perl_psgi.c b/src/perl/nxt_perl_psgi.c index 0b4b31d7..b99d3269 100644 --- a/src/perl/nxt_perl_psgi.c +++ b/src/perl/nxt_perl_psgi.c @@ -656,8 +656,11 @@ nxt_perl_psgi_env_create(PerlInterpreter *my_perl, RC(nxt_perl_psgi_add_value(my_perl, hash_env, NL("psgi.version"), newRV_noinc((SV *) array_version))); + RC(nxt_perl_psgi_add_value(my_perl, hash_env, NL("psgi.url_scheme"), - newSVpv("http", 4))); + r->tls ? newSVpv("https", 5) + : newSVpv("http", 4))); + RC(nxt_perl_psgi_add_value(my_perl, hash_env, NL("psgi.input"), SvREFCNT_inc(nxt_perl_psgi_arg_input.io))); RC(nxt_perl_psgi_add_value(my_perl, hash_env, NL("psgi.errors"), diff --git a/src/ruby/nxt_ruby.c b/src/ruby/nxt_ruby.c index b2398abe..ab9f7020 100644 --- a/src/ruby/nxt_ruby.c +++ b/src/ruby/nxt_ruby.c @@ -327,7 +327,6 @@ nxt_ruby_rack_env_create(VALUE arg) rb_ary_push(version, UINT2NUM(NXT_RUBY_RACK_API_VERSION_MINOR)); rb_hash_aset(hash_env, rb_str_new2("rack.version"), version); - rb_hash_aset(hash_env, rb_str_new2("rack.url_scheme"), rb_str_new2("http")); rb_hash_aset(hash_env, rb_str_new2("rack.input"), nxt_ruby_io_input); rb_hash_aset(hash_env, rb_str_new2("rack.errors"), nxt_ruby_io_error); rb_hash_aset(hash_env, rb_str_new2("rack.multithread"), Qfalse); @@ -454,6 +453,9 @@ nxt_ruby_read_request(VALUE hash_env) r->server_name_length); nxt_ruby_add_str(hash_env, NL("SERVER_PORT"), "80", 2); + rb_hash_aset(hash_env, rb_str_new2("rack.url_scheme"), + r->tls ? rb_str_new2("https") : rb_str_new2("http")); + for (i = 0; i < r->fields_count; i++) { f = r->fields + i; diff --git a/test/test_tls.py b/test/test_tls.py index 2131bf30..d9b2e512 100644 --- a/test/test_tls.py +++ b/test/test_tls.py @@ -418,5 +418,26 @@ basicConstraints = critical,CA:TRUE""" % { self.assertEqual(resp['status'], 200, 'application respawn status') self.assertEqual(resp['body'], '0123456789', 'application respawn body') + def test_tls_url_scheme(self): + self.load('variables') + + self.assertEqual(self.post(headers={ + 'Host': 'localhost', + 'Content-Type': 'text/html', + 'Custom-Header': '', + 'Connection': 'close' + })['headers']['Wsgi-Url-Scheme'], 'http', 'url scheme http') + + self.certificate() + + self.add_tls(application='variables') + + self.assertEqual(self.post_ssl(headers={ + 'Host': 'localhost', + 'Content-Type': 'text/html', + 'Custom-Header': '', + 'Connection': 'close' + })['headers']['Wsgi-Url-Scheme'], 'https', 'url scheme https') + if __name__ == '__main__': TestUnitTLS.main() |