Adjusting request schema value according to connection tls state.

This closes #223 issue on GitHub.
This commit is contained in:
Max Romanov
2019-03-21 13:55:57 +03:00
parent 39e147a858
commit 452ce0789e
14 changed files with 103 additions and 31 deletions

View File

@@ -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);
}

View File

@@ -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)

View File

@@ -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)
{

View File

@@ -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)

View File

@@ -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)

View File

@@ -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[];

View File

@@ -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);
}
}

View File

@@ -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);

View File

@@ -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));

View File

@@ -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);

View File

@@ -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;

View File

@@ -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"),

View File

@@ -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;

View File

@@ -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()