Adjusting request schema value according to connection tls state.
This closes #223 issue on GitHub.
This commit is contained in:
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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)
|
||||
|
||||
|
||||
@@ -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[];
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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));
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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"),
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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()
|
||||
|
||||
Reference in New Issue
Block a user