summaryrefslogtreecommitdiffhomepage
path: root/src
diff options
context:
space:
mode:
authorKonstantin Pavlov <thresh@nginx.com>2022-06-02 16:51:49 +0400
committerKonstantin Pavlov <thresh@nginx.com>2022-06-02 16:51:49 +0400
commitd9fddee1dbfc1f5d49c8f40386289d7188030952 (patch)
tree842a62b343ac33eba10e7a426a10b55bb1c46aed /src
parent420395ee2e7cd464e157c49bea3d74f15bf25f30 (diff)
parent0d48fe73c4450901622373e35f6ff3a944ec13d6 (diff)
downloadunit-d9fddee1dbfc1f5d49c8f40386289d7188030952.tar.gz
unit-d9fddee1dbfc1f5d49c8f40386289d7188030952.tar.bz2
Merged with the default branch.1.27.0-1
Diffstat (limited to 'src')
-rw-r--r--src/java/nginx/unit/Context.java19
-rw-r--r--src/java/nginx/unit/websocket/WsRemoteEndpointImplBase.java2
-rw-r--r--src/nodejs/unit-http/loader.mjs4
-rw-r--r--src/nxt_application.c3
-rw-r--r--src/nxt_application.h3
-rw-r--r--src/nxt_array.h9
-rw-r--r--src/nxt_atomic.h60
-rw-r--r--src/nxt_buf.h84
-rw-r--r--src/nxt_buf_pool.h15
-rw-r--r--src/nxt_cache.c3
-rw-r--r--src/nxt_cert.c1
-rw-r--r--src/nxt_clang.h77
-rw-r--r--src/nxt_clone.c2
-rw-r--r--src/nxt_conf.c29
-rw-r--r--src/nxt_conf.h6
-rw-r--r--src/nxt_conf_validation.c13
-rw-r--r--src/nxt_djb_hash.h3
-rw-r--r--src/nxt_dyld.h3
-rw-r--r--src/nxt_errno.h12
-rw-r--r--src/nxt_event_engine.h36
-rw-r--r--src/nxt_external.c12
-rw-r--r--src/nxt_fastcgi_source.c3
-rw-r--r--src/nxt_fd_event.h6
-rw-r--r--src/nxt_fiber.c3
-rw-r--r--src/nxt_file.h39
-rw-r--r--src/nxt_gnutls.c4
-rw-r--r--src/nxt_h1proto.c10
-rw-r--r--src/nxt_http.h29
-rw-r--r--src/nxt_http_chunk_parse.c3
-rw-r--r--src/nxt_http_parse.c3
-rw-r--r--src/nxt_http_request.c276
-rw-r--r--src/nxt_http_return.c177
-rw-r--r--src/nxt_http_route.c354
-rw-r--r--src/nxt_http_static.c78
-rw-r--r--src/nxt_http_variables.c20
-rw-r--r--src/nxt_job.h9
-rw-r--r--src/nxt_list.h12
-rw-r--r--src/nxt_log.h21
-rw-r--r--src/nxt_log_moderation.h6
-rw-r--r--src/nxt_lvlhsh.c69
-rw-r--r--src/nxt_lvlhsh.h6
-rw-r--r--src/nxt_main_process.c32
-rw-r--r--src/nxt_malloc.c13
-rw-r--r--src/nxt_malloc.h27
-rw-r--r--src/nxt_mem_map.h9
-rw-r--r--src/nxt_mem_zone.c27
-rw-r--r--src/nxt_mem_zone.h3
-rw-r--r--src/nxt_mp.c16
-rw-r--r--src/nxt_openssl.c32
-rw-r--r--src/nxt_port.c5
-rw-r--r--src/nxt_queue.h60
-rw-r--r--src/nxt_router.c85
-rw-r--r--src/nxt_service.h3
-rw-r--r--src/nxt_signal.h6
-rw-r--r--src/nxt_socket.h6
-rw-r--r--src/nxt_source.h3
-rw-r--r--src/nxt_sprintf.c41
-rw-r--r--src/nxt_string.h69
-rw-r--r--src/nxt_thread.h33
-rw-r--r--src/nxt_thread_id.h6
-rw-r--r--src/nxt_thread_time.h9
-rw-r--r--src/nxt_time.h12
-rw-r--r--src/nxt_time_parse.c6
-rw-r--r--src/nxt_unit.c84
-rw-r--r--src/nxt_unit.h2
-rw-r--r--src/nxt_unix.h12
-rw-r--r--src/nxt_var.c3
-rw-r--r--src/nxt_vector.h9
-rw-r--r--src/nxt_work_queue.h7
-rw-r--r--src/perl/nxt_perl_psgi.c190
-rw-r--r--src/perl/nxt_perl_psgi_layer.c64
-rw-r--r--src/perl/nxt_perl_psgi_layer.h28
-rw-r--r--src/python/nxt_python.c13
-rw-r--r--src/python/nxt_python_asgi.c19
-rw-r--r--src/ruby/nxt_ruby.c45
-rw-r--r--src/ruby/nxt_ruby.h1
-rw-r--r--src/ruby/nxt_ruby_stream_io.c10
-rw-r--r--src/test/nxt_rbtree1_test.c6
78 files changed, 1218 insertions, 1302 deletions
diff --git a/src/java/nginx/unit/Context.java b/src/java/nginx/unit/Context.java
index 0197858b..e1245e1f 100644
--- a/src/java/nginx/unit/Context.java
+++ b/src/java/nginx/unit/Context.java
@@ -422,7 +422,7 @@ public class Context implements ServletContext, InitParams
processWebXml(root);
- loader_ = new AppClassLoader(urls,
+ loader_ = new UnitClassLoader(urls,
Context.class.getClassLoader().getParent());
Class wsSession_class = WsSession.class;
@@ -531,7 +531,7 @@ public class Context implements ServletContext, InitParams
}
}
- private static class AppClassLoader extends URLClassLoader
+ private static class UnitClassLoader extends URLClassLoader
{
static {
ClassLoader.registerAsParallelCapable();
@@ -547,7 +547,7 @@ public class Context implements ServletContext, InitParams
private ClassLoader system_loader;
- public AppClassLoader(URL[] urls, ClassLoader parent)
+ public UnitClassLoader(URL[] urls, ClassLoader parent)
{
super(urls, parent);
@@ -1514,6 +1514,18 @@ public class Context implements ServletContext, InitParams
{
trace("loadInitializer: initializer: " + sci.getClass().getName());
+ /*
+ Unit WebSocket container is a copy of Tomcat WsSci with own
+ transport implementation. Tomcat implementation will not work in
+ Unit and should be ignored here.
+ */
+ if (sci.getClass().getName()
+ .equals("org.apache.tomcat.websocket.server.WsSci"))
+ {
+ trace("loadInitializer: ignore");
+ return;
+ }
+
HandlesTypes ann = sci.getClass().getAnnotation(HandlesTypes.class);
if (ann == null) {
trace("loadInitializer: no HandlesTypes annotation");
@@ -1558,7 +1570,6 @@ public class Context implements ServletContext, InitParams
try {
sci.onStartup(handles_classes, this);
- metadata_complete_ = true;
} catch(Exception e) {
System.err.println("loadInitializer: exception caught: " + e.toString());
}
diff --git a/src/java/nginx/unit/websocket/WsRemoteEndpointImplBase.java b/src/java/nginx/unit/websocket/WsRemoteEndpointImplBase.java
index 776124fd..d451db7d 100644
--- a/src/java/nginx/unit/websocket/WsRemoteEndpointImplBase.java
+++ b/src/java/nginx/unit/websocket/WsRemoteEndpointImplBase.java
@@ -1175,7 +1175,7 @@ public abstract class WsRemoteEndpointImplBase implements RemoteEndpoint {
} else if (state == State.WRITER_WRITING) {
// NO-OP. Leave state as is.
} else if (state == State.STREAM_WRITING) {
- // NO-OP. Leave state as is.
+ // NO-OP. Leave state as is.
} else {
// Should never happen
// The if ... else ... blocks above should cover all states
diff --git a/src/nodejs/unit-http/loader.mjs b/src/nodejs/unit-http/loader.mjs
index 067d63d4..546548f5 100644
--- a/src/nodejs/unit-http/loader.mjs
+++ b/src/nodejs/unit-http/loader.mjs
@@ -4,13 +4,13 @@ export async function resolve(specifier, context, defaultResolver) {
case "websocket":
return {
url: new URL("./websocket.js", import.meta.url).href,
- format: "cjs"
+ format: "commonjs"
}
case "http":
return {
url: new URL("./http.js", import.meta.url).href,
- format: "cjs"
+ format: "commonjs"
}
}
diff --git a/src/nxt_application.c b/src/nxt_application.c
index 82385ec4..594574b1 100644
--- a/src/nxt_application.c
+++ b/src/nxt_application.c
@@ -1052,6 +1052,9 @@ nxt_unit_default_init(nxt_task_t *task, nxt_unit_init_t *init,
init->read_port.in_fd = my_port->pair[0];
init->read_port.out_fd = my_port->pair[1];
+ init->shared_port_fd = conf->shared_port_fd;
+ init->shared_queue_fd = conf->shared_queue_fd;
+
init->log_fd = 2;
init->shm_limit = conf->shm_limit;
diff --git a/src/nxt_application.h b/src/nxt_application.h
index 4612f072..30a1a12f 100644
--- a/src/nxt_application.h
+++ b/src/nxt_application.h
@@ -103,6 +103,9 @@ struct nxt_common_app_conf_s {
size_t shm_limit;
uint32_t request_limit;
+ nxt_fd_t shared_port_fd;
+ nxt_fd_t shared_queue_fd;
+
union {
nxt_external_app_conf_t external;
nxt_python_app_conf_t python;
diff --git a/src/nxt_array.h b/src/nxt_array.h
index 8318fccd..f06ff14c 100644
--- a/src/nxt_array.h
+++ b/src/nxt_array.h
@@ -35,18 +35,15 @@ NXT_EXPORT void nxt_array_remove(nxt_array_t *array, void *elt);
NXT_EXPORT nxt_array_t *nxt_array_copy(nxt_mp_t *mp, nxt_array_t *dst,
nxt_array_t *src);
-#define \
-nxt_array_last(array) \
+#define nxt_array_last(array) \
nxt_pointer_to((array)->elts, (array)->size * ((array)->nelts - 1))
-#define \
-nxt_array_reset(array) \
+#define nxt_array_reset(array) \
(array)->nelts = 0;
-#define \
-nxt_array_is_empty(array) \
+#define nxt_array_is_empty(array) \
((array)->nelts == 0)
diff --git a/src/nxt_atomic.h b/src/nxt_atomic.h
index 9e2e5ec1..cd2e7253 100644
--- a/src/nxt_atomic.h
+++ b/src/nxt_atomic.h
@@ -26,28 +26,23 @@ typedef volatile nxt_atomic_uint_t nxt_atomic_t;
* __sync_lock_release() is a release barrier.
*/
-#define \
-nxt_atomic_cmp_set(lock, cmp, set) \
+#define nxt_atomic_cmp_set(lock, cmp, set) \
__sync_bool_compare_and_swap(lock, cmp, set)
-#define \
-nxt_atomic_xchg(lock, set) \
+#define nxt_atomic_xchg(lock, set) \
__sync_lock_test_and_set(lock, set)
-#define \
-nxt_atomic_fetch_add(value, add) \
+#define nxt_atomic_fetch_add(value, add) \
__sync_fetch_and_add(value, add)
-#define \
-nxt_atomic_try_lock(lock) \
+#define nxt_atomic_try_lock(lock) \
nxt_atomic_cmp_set(lock, 0, 1)
-#define \
-nxt_atomic_release(lock) \
+#define nxt_atomic_release(lock) \
__sync_lock_release(lock)
@@ -60,13 +55,11 @@ nxt_atomic_release(lock) \
#if (__i386__ || __i386 || __amd64__ || __amd64)
-#define \
-nxt_cpu_pause() \
+#define nxt_cpu_pause() \
__asm__ ("pause")
#else
-#define \
-nxt_cpu_pause()
+#define nxt_cpu_pause()
#endif
@@ -79,18 +72,15 @@ typedef ulong_t nxt_atomic_uint_t;
typedef volatile nxt_atomic_uint_t nxt_atomic_t;
-#define \
-nxt_atomic_cmp_set(lock, cmp, set) \
+#define nxt_atomic_cmp_set(lock, cmp, set) \
(atomic_cas_ulong(lock, cmp, set) == (ulong_t) cmp)
-#define \
-nxt_atomic_xchg(lock, set) \
+#define nxt_atomic_xchg(lock, set) \
atomic_add_swap(lock, set)
-#define \
-nxt_atomic_fetch_add(value, add) \
+#define nxt_atomic_fetch_add(value, add) \
(atomic_add_long_nv(value, add) - add)
@@ -124,13 +114,11 @@ nxt_atomic_fetch_add(value, add) \
* barrier.
*/
-#define \
-nxt_atomic_try_lock(lock) \
+#define nxt_atomic_try_lock(lock) \
nxt_atomic_cmp_set(lock, 0, 1)
-#define \
-nxt_atomic_release(lock) \
+#define nxt_atomic_release(lock) \
*lock = 0;
@@ -142,13 +130,11 @@ nxt_atomic_release(lock) \
*/
#if (__i386__ || __i386 || __amd64__ || __amd64)
-#define \
-nxt_cpu_pause() \
+#define nxt_cpu_pause() \
__asm__ ("rep; nop")
#else
-#define \
-nxt_cpu_pause()
+#define nxt_cpu_pause()
#endif
@@ -192,13 +178,11 @@ nxt_atomic_cmp_set(nxt_atomic_t *lock, nxt_atomic_int_t cmp,
}
-#define \
-nxt_atomic_xchg(lock, set) \
+#define nxt_atomic_xchg(lock, set) \
__fetch_and_swaplp(lock, set)
-#define \
-nxt_atomic_fetch_add(value, add) \
+#define nxt_atomic_fetch_add(value, add) \
__fetch_and_addlp(value, add)
@@ -221,13 +205,11 @@ nxt_atomic_cmp_set(nxt_atomic_t *lock, nxt_atomic_int_t cmp,
}
-#define \
-nxt_atomic_xchg(lock, set) \
+#define nxt_atomic_xchg(lock, set) \
__fetch_and_swap(lock, set)
-#define \
-nxt_atomic_fetch_add(value, add) \
+#define nxt_atomic_fetch_add(value, add) \
__fetch_and_add(value, add)
@@ -270,13 +252,11 @@ nxt_atomic_try_lock(nxt_atomic_t *lock)
}
-#define \
-nxt_atomic_release(lock) \
+#define nxt_atomic_release(lock) \
do { __lwsync(); *lock = 0; } while (0)
-#define \
-nxt_cpu_pause()
+#define nxt_cpu_pause()
#endif /* NXT_HAVE_XLC_ATOMIC */
diff --git a/src/nxt_buf.h b/src/nxt_buf.h
index 5121d659..f1e2879f 100644
--- a/src/nxt_buf.h
+++ b/src/nxt_buf.h
@@ -113,127 +113,100 @@ struct nxt_buf_s {
#define NXT_BUF_SYNC_LAST 4
-#define \
-nxt_buf_is_mem(b) \
+#define nxt_buf_is_mem(b) \
((b)->mem.pos != NULL)
-#define \
-nxt_buf_is_file(b) \
+#define nxt_buf_is_file(b) \
((b)->is_file)
-#define \
-nxt_buf_set_file(b) \
+#define nxt_buf_set_file(b) \
(b)->is_file = 1
-#define \
-nxt_buf_clear_file(b) \
+#define nxt_buf_clear_file(b) \
(b)->is_file = 0
-#define \
-nxt_buf_is_mmap(b) \
+#define nxt_buf_is_mmap(b) \
((b)->is_mmap)
-#define \
-nxt_buf_set_mmap(b) \
+#define nxt_buf_set_mmap(b) \
(b)->is_mmap = 1
-#define \
-nxt_buf_clear_mmap(b) \
+#define nxt_buf_clear_mmap(b) \
(b)->is_mmap = 0
-#define \
-nxt_buf_is_port_mmap(b) \
+#define nxt_buf_is_port_mmap(b) \
((b)->is_port_mmap)
-#define \
-nxt_buf_set_port_mmap(b) \
+#define nxt_buf_set_port_mmap(b) \
(b)->is_port_mmap = 1
-#define \
-nxt_buf_clear_port_mmap(b) \
+#define nxt_buf_clear_port_mmap(b) \
(b)->is_port_mmap = 0
-#define \
-nxt_buf_is_sync(b) \
+#define nxt_buf_is_sync(b) \
((b)->is_sync)
-#define \
-nxt_buf_set_sync(b) \
+#define nxt_buf_set_sync(b) \
(b)->is_sync = 1
-#define \
-nxt_buf_clear_sync(b) \
+#define nxt_buf_clear_sync(b) \
(b)->is_sync = 0
-#define \
-nxt_buf_is_nobuf(b) \
+#define nxt_buf_is_nobuf(b) \
((b)->is_nobuf)
-#define \
-nxt_buf_set_nobuf(b) \
+#define nxt_buf_set_nobuf(b) \
(b)->is_nobuf = 1
-#define \
-nxt_buf_clear_nobuf(b) \
+#define nxt_buf_clear_nobuf(b) \
(b)->is_nobuf = 0
-#define \
-nxt_buf_is_flush(b) \
+#define nxt_buf_is_flush(b) \
((b)->is_flush)
-#define \
-nxt_buf_set_flush(b) \
+#define nxt_buf_set_flush(b) \
(b)->is_flush = 1
-#define \
-nxt_buf_clear_flush(b) \
+#define nxt_buf_clear_flush(b) \
(b)->is_flush = 0
-#define \
-nxt_buf_is_last(b) \
+#define nxt_buf_is_last(b) \
((b)->is_last)
-#define \
-nxt_buf_set_last(b) \
+#define nxt_buf_set_last(b) \
(b)->is_last = 1
-#define \
-nxt_buf_clear_last(b) \
+#define nxt_buf_clear_last(b) \
(b)->is_last = 0
-#define \
-nxt_buf_mem_set_size(bm, size) \
+#define nxt_buf_mem_set_size(bm, size) \
do { \
(bm)->start = 0; \
(bm)->end = (void *) size; \
} while (0)
-#define \
-nxt_buf_mem_size(bm) \
+#define nxt_buf_mem_size(bm) \
((bm)->end - (bm)->start)
-#define \
-nxt_buf_mem_used_size(bm) \
+#define nxt_buf_mem_used_size(bm) \
((bm)->free - (bm)->pos)
-#define \
-nxt_buf_mem_free_size(bm) \
+#define nxt_buf_mem_free_size(bm) \
((bm)->end - (bm)->free)
-#define \
-nxt_buf_used_size(b) \
+#define nxt_buf_used_size(b) \
(nxt_buf_is_file(b) ? (b)->file_end - (b)->file_pos: \
nxt_buf_mem_used_size(&(b)->mem))
@@ -264,8 +237,7 @@ nxt_buf_chk_make_plain(nxt_mp_t *mp, nxt_buf_t *src, size_t size)
return src;
}
-#define \
-nxt_buf_free(mp, b) \
+#define nxt_buf_free(mp, b) \
nxt_mp_free((mp), (b))
diff --git a/src/nxt_buf_pool.h b/src/nxt_buf_pool.h
index 6a04fd7e..3d22d7fa 100644
--- a/src/nxt_buf_pool.h
+++ b/src/nxt_buf_pool.h
@@ -42,8 +42,7 @@ NXT_EXPORT void nxt_buf_pool_destroy(nxt_buf_pool_t *bp);
/* There is ready free buffer. */
-#define \
-nxt_buf_pool_ready(bp) \
+#define nxt_buf_pool_ready(bp) \
((bp)->free != NULL \
|| ((bp)->current != NULL \
&& (bp)->current->mem.free < (bp)->current->mem.end))
@@ -51,29 +50,25 @@ nxt_buf_pool_ready(bp) \
/* A free buffer is allowed to be allocated. */
-#define \
-nxt_buf_pool_obtainable(bp) \
+#define nxt_buf_pool_obtainable(bp) \
((bp)->num < (bp)->max)
/* There is ready free buffer or it is allowed to be allocated. */
-#define \
-nxt_buf_pool_available(bp) \
+#define nxt_buf_pool_available(bp) \
(nxt_buf_pool_obtainable(bp) || nxt_buf_pool_ready(bp))
/* Reserve allocation of "n" free buffers as they were allocated. */
-#define \
-nxt_buf_pool_reserve(bp, n) \
+#define nxt_buf_pool_reserve(bp, n) \
(bp)->num += (n)
/* Release a reservation. */
-#define \
-nxt_buf_pool_release(bp, n) \
+#define nxt_buf_pool_release(bp, n) \
(bp)->num -= (n)
diff --git a/src/nxt_cache.c b/src/nxt_cache.c
index 409ba301..e81d63dc 100644
--- a/src/nxt_cache.c
+++ b/src/nxt_cache.c
@@ -8,8 +8,7 @@
/* A cache time resolution is 10ms. */
-#define \
-nxt_cache_time(thr) \
+#define nxt_cache_time(thr) \
(uint64_t) (nxt_thread_time(thr) * 100)
diff --git a/src/nxt_cert.c b/src/nxt_cert.c
index 01d413e0..4a1f1496 100644
--- a/src/nxt_cert.c
+++ b/src/nxt_cert.c
@@ -241,7 +241,6 @@ nxt_cert_bio(nxt_task_t *task, BIO *bio)
goto fail;
}
- nxt_free(cert);
cert = new_cert;
}
diff --git a/src/nxt_clang.h b/src/nxt_clang.h
index a10de08a..94638346 100644
--- a/src/nxt_clang.h
+++ b/src/nxt_clang.h
@@ -16,45 +16,37 @@
#if (NXT_CLANG)
/* Any __asm__ directive disables loop vectorization in GCC and Clang. */
-#define \
-nxt_pragma_loop_disable_vectorization \
+#define nxt_pragma_loop_disable_vectorization \
__asm__("")
#else
-#define \
-nxt_pragma_loop_disable_vectorization
+#define nxt_pragma_loop_disable_vectorization
#endif
#if (NXT_HAVE_BUILTIN_EXPECT)
-#define \
-nxt_expect(c, x) \
+#define nxt_expect(c, x) \
__builtin_expect((long) (x), (c))
-#define \
-nxt_fast_path(x) \
+#define nxt_fast_path(x) \
nxt_expect(1, x)
-#define \
-nxt_slow_path(x) \
+#define nxt_slow_path(x) \
nxt_expect(0, x)
#else
-#define \
-nxt_expect(c, x) \
+#define nxt_expect(c, x) \
(x)
-#define \
-nxt_fast_path(x) \
+#define nxt_fast_path(x) \
(x)
-#define \
-nxt_slow_path(x) \
+#define nxt_slow_path(x) \
(x)
#endif
@@ -62,28 +54,24 @@ nxt_slow_path(x) \
#if (NXT_HAVE_BUILTIN_UNREACHABLE)
-#define \
-nxt_unreachable() \
+#define nxt_unreachable() \
__builtin_unreachable()
#else
-#define \
-nxt_unreachable()
+#define nxt_unreachable()
#endif
#if (NXT_HAVE_BUILTIN_PREFETCH)
-#define \
-nxt_prefetch(a) \
+#define nxt_prefetch(a) \
__builtin_prefetch(a)
#else
-#define \
-nxt_prefetch(a)
+#define nxt_prefetch(a)
#endif
@@ -132,6 +120,17 @@ nxt_prefetch(a)
#endif
+#if (NXT_HAVE_GCC_ATTRIBUTE_UNUSED)
+
+#define NXT_MAYBE_UNUSED __attribute__((__unused__))
+
+#else
+
+#define NXT_MAYBE_UNUSED
+
+#endif
+
+
#if (NXT_HAVE_BUILTIN_POPCOUNT)
#define nxt_popcount __builtin_popcount
@@ -195,13 +194,11 @@ nxt_popcount(unsigned int x)
#endif
-#define \
-nxt_alloca(size) \
+#define nxt_alloca(size) \
alloca(size)
-#define \
-nxt_container_of(p, type, field) \
+#define nxt_container_of(p, type, field) \
(type *) ((u_char *) (p) - offsetof(type, field))
@@ -213,30 +210,25 @@ nxt_container_of(p, type, field) \
*(type *) ((u_char *) p + offset)
-#define \
-nxt_nitems(x) \
+#define nxt_nitems(x) \
(sizeof(x) / sizeof((x)[0]))
/* GCC and Clang use __builtin_abs() instead of libc abs(). */
-#define \
-nxt_abs(val) \
+#define nxt_abs(val) \
abs(val)
-#define \
-nxt_max(val1, val2) \
+#define nxt_max(val1, val2) \
((val1 < val2) ? (val2) : (val1))
-#define \
-nxt_min(val1, val2) \
+#define nxt_min(val1, val2) \
((val1 > val2) ? (val2) : (val1))
-#define \
-nxt_bswap32(val) \
+#define nxt_bswap32(val) \
( ((val) >> 24) \
| (((val) & 0x00FF0000) >> 8) \
| (((val) & 0x0000FF00) << 8) \
@@ -247,18 +239,15 @@ nxt_bswap32(val) \
((((value) - 1) & (value)) == 0)
-#define \
-nxt_align_size(d, a) \
+#define nxt_align_size(d, a) \
(((d) + ((size_t) (a) - 1)) & ~((size_t) (a) - 1))
-#define \
-nxt_align_ptr(p, a) \
+#define nxt_align_ptr(p, a) \
(u_char *) (((uintptr_t) (p) + ((uintptr_t) (a) - 1)) \
& ~((uintptr_t) (a) - 1))
-#define \
-nxt_trunc_ptr(p, a) \
+#define nxt_trunc_ptr(p, a) \
(u_char *) ((uintptr_t) (p) & ~((uintptr_t) (a) - 1))
diff --git a/src/nxt_clone.c b/src/nxt_clone.c
index 9ee3c012..aa952a54 100644
--- a/src/nxt_clone.c
+++ b/src/nxt_clone.c
@@ -384,7 +384,7 @@ nxt_clone_vldt_credential_gidmap(nxt_task_t *task,
}
return NXT_OK;
- }
+ }
base_ok = 0;
gids_ok = 0;
diff --git a/src/nxt_conf.c b/src/nxt_conf.c
index 1aca0a7e..79e776a0 100644
--- a/src/nxt_conf.c
+++ b/src/nxt_conf.c
@@ -192,7 +192,8 @@ nxt_conf_set_string(nxt_conf_value_t *value, nxt_str_t *str)
nxt_int_t
-nxt_conf_set_string_dup(nxt_conf_value_t *value, nxt_mp_t *mp, nxt_str_t *str)
+nxt_conf_set_string_dup(nxt_conf_value_t *value, nxt_mp_t *mp,
+ const nxt_str_t *str)
{
nxt_str_t tmp, *ptr;
@@ -392,6 +393,13 @@ nxt_conf_array_elements_count(nxt_conf_value_t *value)
nxt_uint_t
+nxt_conf_array_elements_count_or_1(nxt_conf_value_t *value)
+{
+ return (value->type == NXT_CONF_VALUE_ARRAY) ? value->u.array->count : 1;
+}
+
+
+nxt_uint_t
nxt_conf_type(nxt_conf_value_t *value)
{
switch (value->type) {
@@ -749,6 +757,25 @@ nxt_conf_get_array_element(nxt_conf_value_t *value, uint32_t index)
}
+nxt_conf_value_t *
+nxt_conf_get_array_element_or_itself(nxt_conf_value_t *value, uint32_t index)
+{
+ nxt_conf_array_t *array;
+
+ if (value->type != NXT_CONF_VALUE_ARRAY) {
+ return (index == 0) ? value : NULL;
+ }
+
+ array = value->u.array;
+
+ if (index >= array->count) {
+ return NULL;
+ }
+
+ return &array->elements[index];
+}
+
+
void
nxt_conf_array_qsort(nxt_conf_value_t *value,
int (*compare)(const void *, const void *))
diff --git a/src/nxt_conf.h b/src/nxt_conf.h
index 8b3565fd..cfbc5991 100644
--- a/src/nxt_conf.h
+++ b/src/nxt_conf.h
@@ -87,6 +87,8 @@ NXT_EXPORT nxt_conf_value_t *nxt_conf_next_object_member(
nxt_conf_value_t *value, nxt_str_t *name, uint32_t *next);
NXT_EXPORT nxt_conf_value_t *nxt_conf_get_array_element(nxt_conf_value_t *value,
uint32_t index);
+NXT_EXPORT nxt_conf_value_t *nxt_conf_get_array_element_or_itself(
+ nxt_conf_value_t *value, uint32_t index);
NXT_EXPORT nxt_int_t nxt_conf_map_object(nxt_mp_t *mp, nxt_conf_value_t *value,
nxt_conf_map_t *map, nxt_uint_t n, void *data);
@@ -115,7 +117,7 @@ nxt_int_t nxt_conf_validate(nxt_conf_validation_t *vldt);
NXT_EXPORT void nxt_conf_get_string(nxt_conf_value_t *value, nxt_str_t *str);
NXT_EXPORT void nxt_conf_set_string(nxt_conf_value_t *value, nxt_str_t *str);
NXT_EXPORT nxt_int_t nxt_conf_set_string_dup(nxt_conf_value_t *value,
- nxt_mp_t *mp, nxt_str_t *str);
+ nxt_mp_t *mp, const nxt_str_t *str);
NXT_EXPORT double nxt_conf_get_number(nxt_conf_value_t *value);
NXT_EXPORT uint8_t nxt_conf_get_boolean(nxt_conf_value_t *value);
@@ -139,6 +141,8 @@ void nxt_conf_set_element(nxt_conf_value_t *array, nxt_uint_t index,
nxt_int_t nxt_conf_set_element_string_dup(nxt_conf_value_t *array, nxt_mp_t *mp,
nxt_uint_t index, nxt_str_t *value);
NXT_EXPORT nxt_uint_t nxt_conf_array_elements_count(nxt_conf_value_t *value);
+NXT_EXPORT nxt_uint_t nxt_conf_array_elements_count_or_1(
+ nxt_conf_value_t *value);
void nxt_conf_array_qsort(nxt_conf_value_t *value,
int (*compare)(const void *, const void *));
diff --git a/src/nxt_conf_validation.c b/src/nxt_conf_validation.c
index 3f068bbb..ee7ebe44 100644
--- a/src/nxt_conf_validation.c
+++ b/src/nxt_conf_validation.c
@@ -77,7 +77,8 @@ static nxt_int_t nxt_conf_vldt_error(nxt_conf_validation_t *vldt,
static nxt_int_t nxt_conf_vldt_var(nxt_conf_validation_t *vldt, nxt_str_t *name,
nxt_str_t *value);
nxt_inline nxt_int_t nxt_conf_vldt_unsupported(nxt_conf_validation_t *vldt,
- nxt_conf_value_t *value, void *data);
+ nxt_conf_value_t *value, void *data)
+ NXT_MAYBE_UNUSED;
static nxt_int_t nxt_conf_vldt_mtypes(nxt_conf_validation_t *vldt,
nxt_conf_value_t *value, void *data);
@@ -114,7 +115,7 @@ static nxt_int_t nxt_conf_vldt_pass(nxt_conf_validation_t *vldt,
static nxt_int_t nxt_conf_vldt_return(nxt_conf_validation_t *vldt,
nxt_conf_value_t *value, void *data);
static nxt_int_t nxt_conf_vldt_share(nxt_conf_validation_t *vldt,
- nxt_conf_value_t *value, void *data);
+ nxt_conf_value_t *value, void *data);
static nxt_int_t nxt_conf_vldt_share_element(nxt_conf_validation_t *vldt,
nxt_conf_value_t *value);
static nxt_int_t nxt_conf_vldt_proxy(nxt_conf_validation_t *vldt,
@@ -194,7 +195,7 @@ static nxt_int_t nxt_conf_vldt_java_classpath(nxt_conf_validation_t *vldt,
static nxt_int_t nxt_conf_vldt_java_option(nxt_conf_validation_t *vldt,
nxt_conf_value_t *value);
static nxt_int_t nxt_conf_vldt_upstream(nxt_conf_validation_t *vldt,
- nxt_str_t *name, nxt_conf_value_t *value);
+ nxt_str_t *name, nxt_conf_value_t *value);
static nxt_int_t nxt_conf_vldt_server(nxt_conf_validation_t *vldt,
nxt_str_t *name, nxt_conf_value_t *value);
static nxt_int_t nxt_conf_vldt_server_weight(nxt_conf_validation_t *vldt,
@@ -634,6 +635,7 @@ static nxt_conf_vldt_object_t nxt_conf_vldt_return_action_members[] = {
}, {
.name = nxt_string("location"),
.type = NXT_CONF_VLDT_STRING,
+ .flags = NXT_CONF_VLDT_VAR,
},
NXT_CONF_VLDT_END
@@ -646,6 +648,9 @@ static nxt_conf_vldt_object_t nxt_conf_vldt_share_action_members[] = {
.type = NXT_CONF_VLDT_STRING | NXT_CONF_VLDT_ARRAY,
.validator = nxt_conf_vldt_share,
}, {
+ .name = nxt_string("index"),
+ .type = NXT_CONF_VLDT_STRING,
+ }, {
.name = nxt_string("types"),
.type = NXT_CONF_VLDT_STRING | NXT_CONF_VLDT_ARRAY,
.validator = nxt_conf_vldt_match_patterns,
@@ -2448,7 +2453,7 @@ nxt_conf_vldt_object(nxt_conf_validation_t *vldt, nxt_conf_value_t *value,
break;
}
- }
+ }
ret = nxt_conf_vldt_type(vldt, &name, member, vals->type);
if (ret != NXT_OK) {
diff --git a/src/nxt_djb_hash.h b/src/nxt_djb_hash.h
index c7ba6fdb..43395e6a 100644
--- a/src/nxt_djb_hash.h
+++ b/src/nxt_djb_hash.h
@@ -18,8 +18,7 @@ NXT_EXPORT uint32_t nxt_djb_hash_lowcase(const void *data, size_t len);
#define NXT_DJB_HASH_INIT 5381
-#define \
-nxt_djb_hash_add(hash, val) \
+#define nxt_djb_hash_add(hash, val) \
((uint32_t) ((((hash) << 5) + (hash)) ^ (uint32_t) (val)))
diff --git a/src/nxt_dyld.h b/src/nxt_dyld.h
index a0cbeda3..65ce1874 100644
--- a/src/nxt_dyld.h
+++ b/src/nxt_dyld.h
@@ -17,8 +17,7 @@ typedef struct {
#define NXT_DYLD_ANY RTLD_DEFAULT
-#define \
-nxt_dyld_is_valid(dyld) \
+#define nxt_dyld_is_valid(dyld) \
((dyld)->handle != NULL)
diff --git a/src/nxt_errno.h b/src/nxt_errno.h
index ec700537..f19d50ba 100644
--- a/src/nxt_errno.h
+++ b/src/nxt_errno.h
@@ -65,20 +65,16 @@ typedef int nxt_err_t;
#define NXT_DONE (-4)
-#define \
-nxt_errno \
+#define nxt_errno \
errno
-#define \
-nxt_socket_errno \
+#define nxt_socket_errno \
errno
-#define \
-nxt_set_errno(err) \
+#define nxt_set_errno(err) \
errno = err
-#define \
-nxt_set_socket_errno(err) \
+#define nxt_set_socket_errno(err) \
errno = err
diff --git a/src/nxt_event_engine.h b/src/nxt_event_engine.h
index 6b05d510..91cfc0aa 100644
--- a/src/nxt_event_engine.h
+++ b/src/nxt_event_engine.h
@@ -351,43 +351,35 @@ void nxt_fd_event_hash_delete(nxt_task_t *task, nxt_lvlhsh_t *lvlhsh,
void nxt_fd_event_hash_destroy(nxt_lvlhsh_t *lvlhsh);
-#define \
-nxt_fd_event_disable(engine, ev) \
+#define nxt_fd_event_disable(engine, ev) \
(engine)->event.disable(engine, ev)
-#define \
-nxt_fd_event_delete(engine, ev) \
+#define nxt_fd_event_delete(engine, ev) \
(engine)->event.delete(engine, ev)
-#define \
-nxt_fd_event_close(engine, ev) \
+#define nxt_fd_event_close(engine, ev) \
(engine)->event.close(engine, ev)
-#define \
-nxt_fd_event_enable_read(engine, ev) \
+#define nxt_fd_event_enable_read(engine, ev) \
(engine)->event.enable_read(engine, ev)
-#define \
-nxt_fd_event_enable_write(engine, ev) \
+#define nxt_fd_event_enable_write(engine, ev) \
(engine)->event.enable_write(engine, ev)
-#define \
-nxt_fd_event_disable_read(engine, ev) \
+#define nxt_fd_event_disable_read(engine, ev) \
(engine)->event.disable_read(engine, ev)
-#define \
-nxt_fd_event_disable_write(engine, ev) \
+#define nxt_fd_event_disable_write(engine, ev) \
(engine)->event.disable_write(engine, ev)
-#define \
-nxt_fd_event_block_read(engine, ev) \
+#define nxt_fd_event_block_read(engine, ev) \
do { \
if (nxt_fd_event_is_active((ev)->read)) { \
(engine)->event.block_read(engine, ev); \
@@ -395,8 +387,7 @@ nxt_fd_event_block_read(engine, ev) \
} while (0)
-#define \
-nxt_fd_event_block_write(engine, ev) \
+#define nxt_fd_event_block_write(engine, ev) \
do { \
if (nxt_fd_event_is_active((ev)->write)) { \
(engine)->event.block_write(engine, ev); \
@@ -404,18 +395,15 @@ nxt_fd_event_block_write(engine, ev) \
} while (0)
-#define \
-nxt_fd_event_oneshot_read(engine, ev) \
+#define nxt_fd_event_oneshot_read(engine, ev) \
(engine)->event.oneshot_read(engine, ev)
-#define \
-nxt_fd_event_oneshot_write(engine, ev) \
+#define nxt_fd_event_oneshot_write(engine, ev) \
(engine)->event.oneshot_write(engine, ev)
-#define \
-nxt_fd_event_enable_accept(engine, ev) \
+#define nxt_fd_event_enable_accept(engine, ev) \
(engine)->event.enable_accept(engine, ev)
diff --git a/src/nxt_external.c b/src/nxt_external.c
index b41ca51b..c724b9bd 100644
--- a/src/nxt_external.c
+++ b/src/nxt_external.c
@@ -106,6 +106,16 @@ nxt_external_start(nxt_task_t *task, nxt_process_data_t *data)
return NXT_ERROR;
}
+ rc = nxt_external_fd_no_cloexec(task, conf->shared_port_fd);
+ if (nxt_slow_path(rc != NXT_OK)) {
+ return NXT_ERROR;
+ }
+
+ rc = nxt_external_fd_no_cloexec(task, conf->shared_queue_fd);
+ if (nxt_slow_path(rc != NXT_OK)) {
+ return NXT_ERROR;
+ }
+
end = buf + sizeof(buf);
p = nxt_sprintf(buf, end,
@@ -113,12 +123,14 @@ nxt_external_start(nxt_task_t *task, nxt_process_data_t *data)
"%PI,%ud,%d;"
"%PI,%ud,%d;"
"%PI,%ud,%d,%d;"
+ "%d,%d;"
"%d,%z,%uD,%Z",
NXT_VERSION, my_port->process->stream,
proto_port->pid, proto_port->id, proto_port->pair[1],
router_port->pid, router_port->id, router_port->pair[1],
my_port->pid, my_port->id, my_port->pair[0],
my_port->pair[1],
+ conf->shared_port_fd, conf->shared_queue_fd,
2, conf->shm_limit, conf->request_limit);
if (nxt_slow_path(p == end)) {
diff --git a/src/nxt_fastcgi_source.c b/src/nxt_fastcgi_source.c
index b1be3303..b2424292 100644
--- a/src/nxt_fastcgi_source.c
+++ b/src/nxt_fastcgi_source.c
@@ -18,8 +18,7 @@ typedef struct {
} nxt_fastcgi_param_t;
-#define \
-nxt_fastcgi_set_record_length(p, length) \
+#define nxt_fastcgi_set_record_length(p, length) \
do { \
uint32_t len = length; \
\
diff --git a/src/nxt_fd_event.h b/src/nxt_fd_event.h
index 762fdf25..3a8d9460 100644
--- a/src/nxt_fd_event.h
+++ b/src/nxt_fd_event.h
@@ -44,13 +44,11 @@ typedef enum {
} nxt_fd_event_state_t;
-#define \
-nxt_fd_event_is_disabled(state) \
+#define nxt_fd_event_is_disabled(state) \
((state) < NXT_EVENT_ONESHOT)
-#define \
-nxt_fd_event_is_active(state) \
+#define nxt_fd_event_is_active(state) \
((state) >= NXT_EVENT_ONESHOT)
diff --git a/src/nxt_fiber.c b/src/nxt_fiber.c
index 2312c855..d6cac893 100644
--- a/src/nxt_fiber.c
+++ b/src/nxt_fiber.c
@@ -14,8 +14,7 @@ static void nxt_fiber_switch(nxt_task_t *task, nxt_fiber_t *fib);
static void nxt_fiber_timer_handler(nxt_task_t *task, void *obj, void *data);
-#define \
-nxt_fiber_enqueue(thr, task, fib) \
+#define nxt_fiber_enqueue(thr, task, fib) \
nxt_work_queue_add(&(thr)->engine->fast_work_queue, \
nxt_fiber_switch_handler, task, fib, NULL)
diff --git a/src/nxt_file.h b/src/nxt_file.h
index 4846305b..07c7a22b 100644
--- a/src/nxt_file.h
+++ b/src/nxt_file.h
@@ -27,23 +27,19 @@ typedef struct {
} nxt_file_name_str_t;
-#define \
-nxt_file_name_str_set(file_name, mem_pool, name) \
+#define nxt_file_name_str_set(file_name, mem_pool, name) \
((file_name) = (nxt_file_name_t *) (name), NXT_OK)
-#define \
-nxt_file_name_alloc(mem_pool, len) \
+#define nxt_file_name_alloc(mem_pool, len) \
nxt_mp_nget(mem_pool, len)
-#define \
-nxt_file_name_copy(dst, src, len) \
+#define nxt_file_name_copy(dst, src, len) \
nxt_cpymem(dst, src, len)
-#define \
-nxt_file_name_add(dst, src, len) \
+#define nxt_file_name_add(dst, src, len) \
nxt_cpymem(dst, src, len)
@@ -51,21 +47,18 @@ nxt_file_name_add(dst, src, len) \
/* MacOSX, Cygwin. */
-#define \
-nxt_file_name_eq(fn1, fn2) \
+#define nxt_file_name_eq(fn1, fn2) \
(nxt_strcasecmp(fn1, fn2) == 0)
#else
-#define \
-nxt_file_name_eq(fn1, fn2) \
+#define nxt_file_name_eq(fn1, fn2) \
(nxt_strcmp(fn1, fn2) == 0)
#endif
-#define \
-nxt_file_name_is_absolute(name) \
+#define nxt_file_name_is_absolute(name) \
(name[0] == '/')
@@ -168,20 +161,16 @@ NXT_EXPORT void nxt_file_read_ahead(nxt_file_t *file, nxt_off_t offset,
NXT_EXPORT nxt_int_t nxt_file_info(nxt_file_t *file, nxt_file_info_t *fi);
-#define \
-nxt_is_dir(fi) \
+#define nxt_is_dir(fi) \
(S_ISDIR((fi)->st_mode))
-#define \
-nxt_is_file(fi) \
+#define nxt_is_file(fi) \
(S_ISREG((fi)->st_mode))
-#define \
-nxt_file_size(fi) \
+#define nxt_file_size(fi) \
(fi)->st_size
-#define \
-nxt_file_mtime(fi) \
+#define nxt_file_mtime(fi) \
(fi)->st_mtime
@@ -206,12 +195,10 @@ NXT_EXPORT nxt_int_t nxt_stderr_start(void);
#define nxt_stderr STDERR_FILENO
-#define \
-nxt_write_console(fd, buf, size) \
+#define nxt_write_console(fd, buf, size) \
write(fd, buf, size)
-#define \
-nxt_write_syslog(priority, message) \
+#define nxt_write_syslog(priority, message) \
syslog(priority, "%s", message)
diff --git a/src/nxt_gnutls.c b/src/nxt_gnutls.c
index 4618dce9..aab4699c 100644
--- a/src/nxt_gnutls.c
+++ b/src/nxt_gnutls.c
@@ -708,11 +708,11 @@ nxt_gnutls_log_error_level(nxt_event_conn_t *c, ssize_t err)
case GNUTLS_E_UNKNOWN_CIPHER_SUITE: /* -21 */
- /* Disable gnutls_bye(), because it returns GNUTLS_E_INTERNAL_ERROR. */
+ /* Disable gnutls_bye(), because it returns GNUTLS_E_INTERNAL_ERROR. */
ssltls = c->u.ssltls;
ssltls->no_shutdown = 1;
- /* Fall through. */
+ /* Fall through. */
case GNUTLS_E_UNEXPECTED_PACKET_LENGTH: /* -9 */
c->socket.error = 1000; /* Nonexistent errno code. */
diff --git a/src/nxt_h1proto.c b/src/nxt_h1proto.c
index b683cb22..d3340774 100644
--- a/src/nxt_h1proto.c
+++ b/src/nxt_h1proto.c
@@ -1881,11 +1881,11 @@ nxt_h1p_idle_timeout(nxt_task_t *task, void *obj, void *data)
#define NXT_H1P_IDLE_TIMEOUT \
- "HTTP/1.1 408 Request Timeout\r\n" \
- "Server: " NXT_SERVER "\r\n" \
- "Connection: close\r\n" \
- "Content-Length: 0\r\n" \
- "Date: "
+ "HTTP/1.1 408 Request Timeout\r\n" \
+ "Server: " NXT_SERVER "\r\n" \
+ "Connection: close\r\n" \
+ "Content-Length: 0\r\n" \
+ "Date: "
static void
diff --git a/src/nxt_http.h b/src/nxt_http.h
index 02d66f58..d299fdd4 100644
--- a/src/nxt_http.h
+++ b/src/nxt_http.h
@@ -90,17 +90,17 @@ typedef union {
#define nxt_http_field_name_set(_field, _name) \
do { \
- (_field)->name_length = nxt_length(_name); \
- (_field)->name = (u_char *) _name; \
+ (_field)->name_length = nxt_length(_name); \
+ (_field)->name = (u_char *) _name; \
} while (0)
#define nxt_http_field_set(_field, _name, _value) \
do { \
- (_field)->name_length = nxt_length(_name); \
- (_field)->value_length = nxt_length(_value); \
- (_field)->name = (u_char *) _name; \
- (_field)->value = (u_char *) _value; \
+ (_field)->name_length = nxt_length(_name); \
+ (_field)->value_length = nxt_length(_value); \
+ (_field)->name = (u_char *) _name; \
+ (_field)->value = (u_char *) _value; \
} while (0)
@@ -198,6 +198,15 @@ struct nxt_http_request_s {
};
+typedef struct {
+ uint16_t hash;
+ uint16_t name_length;
+ uint32_t value_length;
+ u_char *name;
+ u_char *value;
+} nxt_http_name_value_t;
+
+
typedef struct nxt_http_route_s nxt_http_route_t;
typedef struct nxt_http_route_rule_s nxt_http_route_rule_t;
typedef struct nxt_http_route_addr_rule_s nxt_http_route_addr_rule_t;
@@ -206,9 +215,10 @@ typedef struct nxt_http_route_addr_rule_s nxt_http_route_addr_rule_t;
typedef struct {
nxt_conf_value_t *pass;
nxt_conf_value_t *ret;
- nxt_str_t location;
+ nxt_conf_value_t *location;
nxt_conf_value_t *proxy;
nxt_conf_value_t *share;
+ nxt_conf_value_t *index;
nxt_str_t chroot;
nxt_conf_value_t *follow_symlinks;
nxt_conf_value_t *traverse_mounts;
@@ -238,7 +248,7 @@ typedef struct {
void (*body_read)(nxt_task_t *task, nxt_http_request_t *r);
void (*local_addr)(nxt_task_t *task, nxt_http_request_t *r);
void (*header_send)(nxt_task_t *task, nxt_http_request_t *r,
- nxt_work_handler_t body_handler, void *data);
+ nxt_work_handler_t body_handler, void *data);
void (*send)(nxt_task_t *task, nxt_http_request_t *r, nxt_buf_t *out);
nxt_off_t (*body_bytes_sent)(nxt_task_t *task, nxt_http_proto_t proto);
void (*discard)(nxt_task_t *task, nxt_http_request_t *r, nxt_buf_t *last);
@@ -311,6 +321,9 @@ nxt_int_t nxt_http_request_field(void *ctx, nxt_http_field_t *field,
nxt_int_t nxt_http_request_content_length(void *ctx, nxt_http_field_t *field,
uintptr_t data);
+nxt_array_t *nxt_http_arguments_parse(nxt_http_request_t *r);
+nxt_array_t *nxt_http_cookies_parse(nxt_http_request_t *r);
+
nxt_http_routes_t *nxt_http_routes_create(nxt_task_t *task,
nxt_router_temp_conf_t *tmcf, nxt_conf_value_t *routes_conf);
nxt_http_action_t *nxt_http_action_create(nxt_task_t *task,
diff --git a/src/nxt_http_chunk_parse.c b/src/nxt_http_chunk_parse.c
index deab116d..b60bc801 100644
--- a/src/nxt_http_chunk_parse.c
+++ b/src/nxt_http_chunk_parse.c
@@ -12,8 +12,7 @@
#define NXT_HTTP_CHUNK_END 2
-#define \
-nxt_size_is_sufficient(cs) \
+#define nxt_size_is_sufficient(cs) \
(cs < ((__typeof__(cs)) 1 << (sizeof(cs) * 8 - 4)))
diff --git a/src/nxt_http_parse.c b/src/nxt_http_parse.c
index 338b0a90..1ab6cc90 100644
--- a/src/nxt_http_parse.c
+++ b/src/nxt_http_parse.c
@@ -827,8 +827,7 @@ nxt_http_parse_field_end(nxt_http_request_parse_t *rp, u_char **pos,
}
-#define \
-nxt_http_is_normal(c) \
+#define nxt_http_is_normal(c) \
(nxt_fast_path((nxt_http_normal[c / 8] & (1 << (c & 7))) != 0))
diff --git a/src/nxt_http_request.c b/src/nxt_http_request.c
index ac614df6..04a6f7f3 100644
--- a/src/nxt_http_request.c
+++ b/src/nxt_http_request.c
@@ -24,6 +24,25 @@ static void nxt_http_request_done(nxt_task_t *task, void *obj, void *data);
static u_char *nxt_http_date_cache_handler(u_char *buf, nxt_realtime_t *now,
struct tm *tm, size_t size, const char *format);
+static nxt_http_name_value_t *nxt_http_argument(nxt_array_t *array,
+ u_char *name, size_t name_length, uint32_t hash, u_char *start,
+ u_char *end);
+static nxt_int_t nxt_http_cookie_parse(nxt_array_t *cookies, u_char *start,
+ u_char *end);
+static nxt_http_name_value_t *nxt_http_cookie(nxt_array_t *array, u_char *name,
+ size_t name_length, u_char *start, u_char *end);
+
+
+#define NXT_HTTP_COOKIE_HASH \
+ (nxt_http_field_hash_end( \
+ nxt_http_field_hash_char( \
+ nxt_http_field_hash_char( \
+ nxt_http_field_hash_char( \
+ nxt_http_field_hash_char( \
+ nxt_http_field_hash_char( \
+ nxt_http_field_hash_char(NXT_HTTP_FIELD_HASH_INIT, \
+ 'c'), 'o'), 'o'), 'k'), 'i'), 'e')) & 0xFFFF)
+
static const nxt_http_request_state_t nxt_http_request_init_state;
static const nxt_http_request_state_t nxt_http_request_body_state;
@@ -748,3 +767,260 @@ nxt_http_date_cache_handler(u_char *buf, nxt_realtime_t *now, struct tm *tm,
{
return nxt_http_date(buf, tm);
}
+
+
+nxt_array_t *
+nxt_http_arguments_parse(nxt_http_request_t *r)
+{
+ size_t name_length;
+ u_char *p, *dst, *dst_start, *start, *end, *name;
+ uint8_t d0, d1;
+ uint32_t hash;
+ nxt_array_t *args;
+ nxt_http_name_value_t *nv;
+
+ if (r->arguments != NULL) {
+ return r->arguments;
+ }
+
+ args = nxt_array_create(r->mem_pool, 2, sizeof(nxt_http_name_value_t));
+ if (nxt_slow_path(args == NULL)) {
+ return NULL;
+ }
+
+ hash = NXT_HTTP_FIELD_HASH_INIT;
+ name = NULL;
+ name_length = 0;
+
+ dst_start = nxt_mp_nget(r->mem_pool, r->args->length);
+ if (nxt_slow_path(dst_start == NULL)) {
+ return NULL;
+ }
+
+ r->args_decoded.start = dst_start;
+
+ start = r->args->start;
+ end = start + r->args->length;
+
+ for (p = start, dst = dst_start; p < end; p++, dst++) {
+ *dst = *p;
+
+ switch (*p) {
+ case '=':
+ if (name == NULL) {
+ name_length = dst - dst_start;
+ name = dst_start;
+ dst_start = dst + 1;
+ }
+
+ continue;
+
+ case '&':
+ if (name_length != 0 || dst != dst_start) {
+ nv = nxt_http_argument(args, name, name_length, hash, dst_start,
+ dst);
+ if (nxt_slow_path(nv == NULL)) {
+ return NULL;
+ }
+ }
+
+ hash = NXT_HTTP_FIELD_HASH_INIT;
+ name_length = 0;
+ name = NULL;
+ dst_start = dst + 1;
+
+ continue;
+
+ case '+':
+ *dst = ' ';
+
+ break;
+
+ case '%':
+ if (nxt_slow_path(end - p <= 2)) {
+ break;
+ }
+
+ d0 = nxt_hex2int[p[1]];
+ d1 = nxt_hex2int[p[2]];
+
+ if (nxt_slow_path((d0 | d1) >= 16)) {
+ break;
+ }
+
+ p += 2;
+ *dst = (d0 << 4) + d1;
+
+ break;
+ }
+
+ if (name == NULL) {
+ hash = nxt_http_field_hash_char(hash, *dst);
+ }
+ }
+
+ r->args_decoded.length = dst - r->args_decoded.start;
+
+ if (name_length != 0 || dst != dst_start) {
+ nv = nxt_http_argument(args, name, name_length, hash, dst_start, dst);
+ if (nxt_slow_path(nv == NULL)) {
+ return NULL;
+ }
+ }
+
+ r->arguments = args;
+
+ return args;
+}
+
+
+static nxt_http_name_value_t *
+nxt_http_argument(nxt_array_t *array, u_char *name, size_t name_length,
+ uint32_t hash, u_char *start, u_char *end)
+{
+ size_t length;
+ nxt_http_name_value_t *nv;
+
+ nv = nxt_array_add(array);
+ if (nxt_slow_path(nv == NULL)) {
+ return NULL;
+ }
+
+ nv->hash = nxt_http_field_hash_end(hash) & 0xFFFF;
+
+ length = end - start;
+
+ if (name == NULL) {
+ name_length = length;
+ name = start;
+ length = 0;
+ }
+
+ nv->name_length = name_length;
+ nv->value_length = length;
+ nv->name = name;
+ nv->value = start;
+
+ return nv;
+}
+
+
+nxt_array_t *
+nxt_http_cookies_parse(nxt_http_request_t *r)
+{
+ nxt_int_t ret;
+ nxt_array_t *cookies;
+ nxt_http_field_t *f;
+
+ if (r->cookies != NULL) {
+ return r->cookies;
+ }
+
+ cookies = nxt_array_create(r->mem_pool, 2, sizeof(nxt_http_name_value_t));
+ if (nxt_slow_path(cookies == NULL)) {
+ return NULL;
+ }
+
+ nxt_list_each(f, r->fields) {
+
+ if (f->hash != NXT_HTTP_COOKIE_HASH
+ || f->name_length != 6
+ || nxt_strncasecmp(f->name, (u_char *) "Cookie", 6) != 0)
+ {
+ continue;
+ }
+
+ ret = nxt_http_cookie_parse(cookies, f->value,
+ f->value + f->value_length);
+ if (ret != NXT_OK) {
+ return NULL;
+ }
+
+ } nxt_list_loop;
+
+ r->cookies = cookies;
+
+ return cookies;
+}
+
+
+static nxt_int_t
+nxt_http_cookie_parse(nxt_array_t *cookies, u_char *start, u_char *end)
+{
+ size_t name_length;
+ u_char c, *p, *name;
+ nxt_http_name_value_t *nv;
+
+ name = NULL;
+ name_length = 0;
+
+ for (p = start; p < end; p++) {
+ c = *p;
+
+ if (c == '=') {
+ while (start[0] == ' ') { start++; }
+
+ name_length = p - start;
+
+ if (name_length != 0) {
+ name = start;
+ }
+
+ start = p + 1;
+
+ } else if (c == ';') {
+ if (name != NULL) {
+ nv = nxt_http_cookie(cookies, name, name_length, start, p);
+ if (nxt_slow_path(nv == NULL)) {
+ return NXT_ERROR;
+ }
+ }
+
+ name = NULL;
+ start = p + 1;
+ }
+ }
+
+ if (name != NULL) {
+ nv = nxt_http_cookie(cookies, name, name_length, start, p);
+ if (nxt_slow_path(nv == NULL)) {
+ return NXT_ERROR;
+ }
+ }
+
+ return NXT_OK;
+}
+
+
+static nxt_http_name_value_t *
+nxt_http_cookie(nxt_array_t *array, u_char *name, size_t name_length,
+ u_char *start, u_char *end)
+{
+ u_char c, *p;
+ uint32_t hash;
+ nxt_http_name_value_t *nv;
+
+ nv = nxt_array_add(array);
+ if (nxt_slow_path(nv == NULL)) {
+ return NULL;
+ }
+
+ nv->name_length = name_length;
+ nv->name = name;
+
+ hash = NXT_HTTP_FIELD_HASH_INIT;
+
+ for (p = name; p < name + name_length; p++) {
+ c = *p;
+ hash = nxt_http_field_hash_char(hash, c);
+ }
+
+ nv->hash = nxt_http_field_hash_end(hash) & 0xFFFF;
+
+ while (start < end && end[-1] == ' ') { end--; }
+
+ nv->value_length = end - start;
+ nv->value = start;
+
+ return nv;
+}
diff --git a/src/nxt_http_return.c b/src/nxt_http_return.c
index 18fd490d..82c91568 100644
--- a/src/nxt_http_return.c
+++ b/src/nxt_http_return.c
@@ -8,13 +8,24 @@
typedef struct {
- nxt_http_status_t status;
- nxt_str_t location;
+ nxt_http_status_t status;
+ nxt_var_t *location;
+ nxt_str_t encoded;
} nxt_http_return_conf_t;
+typedef struct {
+ nxt_str_t location;
+ nxt_str_t encoded;
+} nxt_http_return_ctx_t;
+
+
static nxt_http_action_t *nxt_http_return(nxt_task_t *task,
nxt_http_request_t *r, nxt_http_action_t *action);
+static nxt_int_t nxt_http_return_encode(nxt_mp_t *mp, nxt_str_t *encoded,
+ const nxt_str_t *location);
+static void nxt_http_return_send_ready(nxt_task_t *task, void *obj, void *data);
+static void nxt_http_return_var_error(nxt_task_t *task, void *obj, void *data);
static const nxt_http_request_state_t nxt_http_return_send_state;
@@ -24,8 +35,7 @@ nxt_int_t
nxt_http_return_init(nxt_mp_t *mp, nxt_http_action_t *action,
nxt_http_action_conf_t *acf)
{
- nxt_str_t *loc;
- nxt_uint_t encode;
+ nxt_str_t str;
nxt_http_return_conf_t *conf;
conf = nxt_mp_zget(mp, sizeof(nxt_http_return_conf_t));
@@ -38,30 +48,20 @@ nxt_http_return_init(nxt_mp_t *mp, nxt_http_action_t *action,
conf->status = nxt_conf_get_number(acf->ret);
- if (acf->location.length > 0) {
- if (nxt_is_complex_uri_encoded(acf->location.start,
- acf->location.length))
- {
- loc = nxt_str_dup(mp, &conf->location, &acf->location);
- if (nxt_slow_path(loc == NULL)) {
- return NXT_ERROR;
- }
-
- } else {
- loc = &conf->location;
+ if (acf->location == NULL) {
+ return NXT_OK;
+ }
- encode = nxt_encode_complex_uri(NULL, acf->location.start,
- acf->location.length);
- loc->length = acf->location.length + encode * 2;
+ nxt_conf_get_string(acf->location, &str);
- loc->start = nxt_mp_nget(mp, loc->length);
- if (nxt_slow_path(loc->start == NULL)) {
- return NXT_ERROR;
- }
+ conf->location = nxt_var_compile(&str, mp, 0);
+ if (nxt_slow_path(conf->location == NULL)) {
+ return NXT_ERROR;
+ }
- nxt_encode_complex_uri(loc->start, acf->location.start,
- acf->location.length);
- }
+ if (nxt_var_is_const(conf->location)) {
+ nxt_var_raw(conf->location, &str);
+ return nxt_http_return_encode(mp, &conf->encoded, &str);
}
return NXT_OK;
@@ -72,13 +72,24 @@ nxt_http_action_t *
nxt_http_return(nxt_task_t *task, nxt_http_request_t *r,
nxt_http_action_t *action)
{
- nxt_http_field_t *field;
+ nxt_int_t ret;
+ nxt_http_return_ctx_t *ctx;
nxt_http_return_conf_t *conf;
conf = action->u.conf;
- nxt_debug(task, "http return: %d (loc: \"%V\")",
- conf->status, &conf->location);
+#if (NXT_DEBUG)
+ nxt_str_t loc;
+
+ if (conf->location == NULL) {
+ nxt_str_set(&loc, "");
+
+ } else {
+ nxt_var_raw(conf->location, &loc);
+ }
+
+ nxt_debug(task, "http return: %d (loc: \"%V\")", conf->status, &loc);
+#endif
if (conf->status >= NXT_HTTP_BAD_REQUEST
&& conf->status <= NXT_HTTP_SERVER_ERROR_MAX)
@@ -87,27 +98,125 @@ nxt_http_return(nxt_task_t *task, nxt_http_request_t *r,
return NULL;
}
+ if (conf->location == NULL) {
+ ctx = NULL;
+
+ } else {
+ ctx = nxt_mp_zget(r->mem_pool, sizeof(nxt_http_return_ctx_t));
+ if (nxt_slow_path(ctx == NULL)) {
+ goto fail;
+ }
+ }
+
r->status = conf->status;
r->resp.content_length_n = 0;
- if (conf->location.length > 0) {
+ if (ctx == NULL || nxt_var_is_const(conf->location)) {
+ if (ctx != NULL) {
+ ctx->encoded = conf->encoded;
+ }
+
+ nxt_http_return_send_ready(task, r, ctx);
+
+ } else {
+ ret = nxt_var_query_init(&r->var_query, r, r->mem_pool);
+ if (nxt_slow_path(ret != NXT_OK)) {
+ goto fail;
+ }
+
+ nxt_var_query(task, r->var_query, conf->location, &ctx->location);
+
+ nxt_var_query_resolve(task, r->var_query, ctx,
+ nxt_http_return_send_ready,
+ nxt_http_return_var_error);
+ }
+
+ return NULL;
+
+fail:
+
+ nxt_http_request_error(task, r, NXT_HTTP_INTERNAL_SERVER_ERROR);
+ return NULL;
+}
+
+
+static nxt_int_t
+nxt_http_return_encode(nxt_mp_t *mp, nxt_str_t *encoded,
+ const nxt_str_t *location)
+{
+ nxt_uint_t encode;
+
+ if (nxt_is_complex_uri_encoded(location->start, location->length)) {
+ *encoded = *location;
+
+ return NXT_OK;
+ }
+
+ encode = nxt_encode_complex_uri(NULL, location->start, location->length);
+ encoded->length = location->length + encode * 2;
+
+ encoded->start = nxt_mp_nget(mp, encoded->length);
+ if (nxt_slow_path(encoded->start == NULL)) {
+ return NXT_ERROR;
+ }
+
+ nxt_encode_complex_uri(encoded->start, location->start, location->length);
+
+ return NXT_OK;
+}
+
+
+static void
+nxt_http_return_send_ready(nxt_task_t *task, void *obj, void *data)
+{
+ nxt_int_t ret;
+ nxt_http_field_t *field;
+ nxt_http_request_t *r;
+ nxt_http_return_ctx_t *ctx;
+
+ r = obj;
+ ctx = data;
+
+ if (ctx != NULL) {
+ if (ctx->location.length > 0) {
+ ret = nxt_http_return_encode(r->mem_pool, &ctx->encoded,
+ &ctx->location);
+ if (nxt_slow_path(ret == NXT_ERROR)) {
+ goto fail;
+ }
+ }
+
field = nxt_list_zero_add(r->resp.fields);
if (nxt_slow_path(field == NULL)) {
- nxt_http_request_error(task, r, NXT_HTTP_INTERNAL_SERVER_ERROR);
- return NULL;
+ goto fail;
}
nxt_http_field_name_set(field, "Location");
- field->value = conf->location.start;
- field->value_length = conf->location.length;
+ field->value = ctx->encoded.start;
+ field->value_length = ctx->encoded.length;
}
r->state = &nxt_http_return_send_state;
nxt_http_request_header_send(task, r, NULL, NULL);
- return NULL;
+ return;
+
+fail:
+
+ nxt_http_request_error(task, r, NXT_HTTP_INTERNAL_SERVER_ERROR);
+}
+
+
+static void
+nxt_http_return_var_error(nxt_task_t *task, void *obj, void *data)
+{
+ nxt_http_request_t *r;
+
+ r = obj;
+
+ nxt_http_request_error(task, r, NXT_HTTP_INTERNAL_SERVER_ERROR);
}
diff --git a/src/nxt_http_route.c b/src/nxt_http_route.c
index 606bf266..9200dc52 100644
--- a/src/nxt_http_route.c
+++ b/src/nxt_http_route.c
@@ -92,15 +92,6 @@ typedef struct {
uint32_t value_length;
u_char *name;
u_char *value;
-} nxt_http_name_value_t;
-
-
-typedef struct {
- uint16_t hash;
- uint16_t name_length;
- uint32_t value_length;
- u_char *name;
- u_char *value;
} nxt_http_cookie_t;
@@ -172,17 +163,6 @@ struct nxt_http_routes_s {
};
-#define NXT_COOKIE_HASH \
- (nxt_http_field_hash_end( \
- nxt_http_field_hash_char( \
- nxt_http_field_hash_char( \
- nxt_http_field_hash_char( \
- nxt_http_field_hash_char( \
- nxt_http_field_hash_char( \
- nxt_http_field_hash_char(NXT_HTTP_FIELD_HASH_INIT, \
- 'c'), 'o'), 'o'), 'k'), 'i'), 'e')) & 0xFFFF)
-
-
static nxt_http_route_t *nxt_http_route_create(nxt_task_t *task,
nxt_router_temp_conf_t *tmcf, nxt_conf_value_t *cv);
static nxt_http_route_match_t *nxt_http_route_match_create(nxt_task_t *task,
@@ -241,10 +221,6 @@ static nxt_int_t nxt_http_route_header(nxt_http_request_t *r,
nxt_http_route_rule_t *rule);
static nxt_int_t nxt_http_route_arguments(nxt_http_request_t *r,
nxt_http_route_rule_t *rule);
-static nxt_array_t *nxt_http_route_arguments_parse(nxt_http_request_t *r);
-static nxt_http_name_value_t *nxt_http_route_argument(nxt_array_t *array,
- u_char *name, size_t name_length, uint32_t hash, u_char *start,
- u_char *end);
static nxt_int_t nxt_http_route_test_argument(nxt_http_request_t *r,
nxt_http_route_rule_t *rule, nxt_array_t *array);
static nxt_int_t nxt_http_route_scheme(nxt_http_request_t *r,
@@ -253,11 +229,6 @@ static nxt_int_t nxt_http_route_query(nxt_http_request_t *r,
nxt_http_route_rule_t *rule);
static nxt_int_t nxt_http_route_cookies(nxt_http_request_t *r,
nxt_http_route_rule_t *rule);
-static nxt_array_t *nxt_http_route_cookies_parse(nxt_http_request_t *r);
-static nxt_int_t nxt_http_route_cookie_parse(nxt_array_t *cookies,
- u_char *start, u_char *end);
-static nxt_http_name_value_t *nxt_http_route_cookie(nxt_array_t *array,
- u_char *name, size_t name_length, u_char *start, u_char *end);
static nxt_int_t nxt_http_route_test_cookie(nxt_http_request_t *r,
nxt_http_route_rule_t *rule, nxt_array_t *array);
static nxt_int_t nxt_http_route_pattern(nxt_http_request_t *r,
@@ -626,7 +597,7 @@ static nxt_conf_map_t nxt_http_route_action_conf[] = {
},
{
nxt_string("location"),
- NXT_CONF_MAP_STR,
+ NXT_CONF_MAP_PTR,
offsetof(nxt_http_action_conf_t, location)
},
{
@@ -640,6 +611,11 @@ static nxt_conf_map_t nxt_http_route_action_conf[] = {
offsetof(nxt_http_action_conf_t, share)
},
{
+ nxt_string("index"),
+ NXT_CONF_MAP_PTR,
+ offsetof(nxt_http_action_conf_t, index)
+ },
+ {
nxt_string("chroot"),
NXT_CONF_MAP_STR,
offsetof(nxt_http_action_conf_t, chroot)
@@ -718,13 +694,11 @@ nxt_http_route_table_create(nxt_task_t *task, nxt_mp_t *mp,
{
size_t size;
uint32_t i, n;
- nxt_bool_t array;
nxt_conf_value_t *ruleset_cv;
nxt_http_route_table_t *table;
nxt_http_route_ruleset_t *ruleset;
- array = (nxt_conf_type(table_cv) == NXT_CONF_ARRAY);
- n = array ? nxt_conf_array_elements_count(table_cv) : 1;
+ n = nxt_conf_array_elements_count_or_1(table_cv);
size = sizeof(nxt_http_route_table_t)
+ n * sizeof(nxt_http_route_ruleset_t *);
@@ -736,20 +710,8 @@ nxt_http_route_table_create(nxt_task_t *task, nxt_mp_t *mp,
table->items = n;
table->object = NXT_HTTP_ROUTE_TABLE;
- if (!array) {
- ruleset = nxt_http_route_ruleset_create(task, mp, table_cv, object,
- case_sensitive, encoding);
- if (nxt_slow_path(ruleset == NULL)) {
- return NULL;
- }
-
- table->ruleset[0] = ruleset;
-
- return table;
- }
-
for (i = 0; i < n; i++) {
- ruleset_cv = nxt_conf_get_array_element(table_cv, i);
+ ruleset_cv = nxt_conf_get_array_element_or_itself(table_cv, i);
ruleset = nxt_http_route_ruleset_create(task, mp, ruleset_cv, object,
case_sensitive, encoding);
@@ -911,13 +873,11 @@ nxt_http_route_rule_create(nxt_task_t *task, nxt_mp_t *mp,
size_t size;
uint32_t i, n;
nxt_int_t ret;
- nxt_bool_t string;
nxt_conf_value_t *value;
nxt_http_route_rule_t *rule;
nxt_http_route_pattern_t *pattern;
- string = (nxt_conf_type(cv) != NXT_CONF_ARRAY);
- n = string ? 1 : nxt_conf_array_elements_count(cv);
+ n = nxt_conf_array_elements_count_or_1(cv);
size = sizeof(nxt_http_route_rule_t) + n * sizeof(nxt_http_route_pattern_t);
rule = nxt_mp_alloc(mp, size);
@@ -929,22 +889,11 @@ nxt_http_route_rule_create(nxt_task_t *task, nxt_mp_t *mp,
pattern = &rule->pattern[0];
- if (string) {
- pattern[0].case_sensitive = case_sensitive;
- ret = nxt_http_route_pattern_create(task, mp, cv, &pattern[0],
- pattern_case, encoding);
- if (nxt_slow_path(ret != NXT_OK)) {
- return NULL;
- }
-
- return rule;
- }
-
nxt_conf_array_qsort(cv, nxt_http_pattern_compare);
for (i = 0; i < n; i++) {
pattern[i].case_sensitive = case_sensitive;
- value = nxt_conf_get_array_element(cv, i);
+ value = nxt_conf_get_array_element_or_itself(cv, i);
ret = nxt_http_route_pattern_create(task, mp, value, &pattern[i],
pattern_case, encoding);
@@ -959,17 +908,15 @@ nxt_http_route_rule_create(nxt_task_t *task, nxt_mp_t *mp,
nxt_http_route_addr_rule_t *
nxt_http_route_addr_rule_create(nxt_task_t *task, nxt_mp_t *mp,
- nxt_conf_value_t *cv)
+ nxt_conf_value_t *cv)
{
size_t size;
uint32_t i, n;
- nxt_bool_t array;
nxt_conf_value_t *value;
nxt_http_route_addr_rule_t *addr_rule;
nxt_http_route_addr_pattern_t *pattern;
- array = (nxt_conf_type(cv) == NXT_CONF_ARRAY);
- n = array ? nxt_conf_array_elements_count(cv) : 1;
+ n = nxt_conf_array_elements_count_or_1(cv);
size = sizeof(nxt_http_route_addr_rule_t)
+ n * sizeof(nxt_http_route_addr_pattern_t);
@@ -981,19 +928,9 @@ nxt_http_route_addr_rule_create(nxt_task_t *task, nxt_mp_t *mp,
addr_rule->items = n;
- if (!array) {
- pattern = &addr_rule->addr_pattern[0];
-
- if (nxt_http_route_addr_pattern_parse(mp, pattern, cv) != NXT_OK) {
- return NULL;
- }
-
- return addr_rule;
- }
-
for (i = 0; i < n; i++) {
pattern = &addr_rule->addr_pattern[i];
- value = nxt_conf_get_array_element(cv, i);
+ value = nxt_conf_get_array_element_or_itself(cv, i);
if (nxt_http_route_addr_pattern_parse(mp, pattern, value) != NXT_OK) {
return NULL;
@@ -2034,7 +1971,7 @@ nxt_http_route_arguments(nxt_http_request_t *r, nxt_http_route_rule_t *rule)
{
nxt_array_t *arguments;
- arguments = nxt_http_route_arguments_parse(r);
+ arguments = nxt_http_arguments_parse(r);
if (nxt_slow_path(arguments == NULL)) {
return -1;
}
@@ -2043,143 +1980,6 @@ nxt_http_route_arguments(nxt_http_request_t *r, nxt_http_route_rule_t *rule)
}
-static nxt_array_t *
-nxt_http_route_arguments_parse(nxt_http_request_t *r)
-{
- size_t name_length;
- u_char *p, *dst, *dst_start, *start, *end, *name;
- uint8_t d0, d1;
- uint32_t hash;
- nxt_array_t *args;
- nxt_http_name_value_t *nv;
-
- if (r->arguments != NULL) {
- return r->arguments;
- }
-
- args = nxt_array_create(r->mem_pool, 2, sizeof(nxt_http_name_value_t));
- if (nxt_slow_path(args == NULL)) {
- return NULL;
- }
-
- hash = NXT_HTTP_FIELD_HASH_INIT;
- name = NULL;
- name_length = 0;
-
- dst_start = nxt_mp_nget(r->mem_pool, r->args->length);
- if (nxt_slow_path(dst_start == NULL)) {
- return NULL;
- }
-
- r->args_decoded.start = dst_start;
-
- start = r->args->start;
- end = start + r->args->length;
-
- for (p = start, dst = dst_start; p < end; p++, dst++) {
- *dst = *p;
-
- switch (*p) {
- case '=':
- if (name == NULL) {
- name_length = dst - dst_start;
- name = dst_start;
- dst_start = dst + 1;
- }
-
- continue;
-
- case '&':
- if (name_length != 0 || dst != dst_start) {
- nv = nxt_http_route_argument(args, name, name_length, hash,
- dst_start, dst);
- if (nxt_slow_path(nv == NULL)) {
- return NULL;
- }
- }
-
- hash = NXT_HTTP_FIELD_HASH_INIT;
- name_length = 0;
- name = NULL;
- dst_start = dst + 1;
-
- continue;
-
- case '+':
- *dst = ' ';
-
- break;
-
- case '%':
- if (nxt_slow_path(end - p <= 2)) {
- break;
- }
-
- d0 = nxt_hex2int[p[1]];
- d1 = nxt_hex2int[p[2]];
-
- if (nxt_slow_path((d0 | d1) >= 16)) {
- break;
- }
-
- p += 2;
- *dst = (d0 << 4) + d1;
-
- break;
- }
-
- if (name == NULL) {
- hash = nxt_http_field_hash_char(hash, *dst);
- }
- }
-
- r->args_decoded.length = dst - r->args_decoded.start;
-
- if (name_length != 0 || dst != dst_start) {
- nv = nxt_http_route_argument(args, name, name_length, hash, dst_start,
- dst);
- if (nxt_slow_path(nv == NULL)) {
- return NULL;
- }
- }
-
- r->arguments = args;
-
- return args;
-}
-
-
-static nxt_http_name_value_t *
-nxt_http_route_argument(nxt_array_t *array, u_char *name, size_t name_length,
- uint32_t hash, u_char *start, u_char *end)
-{
- size_t length;
- nxt_http_name_value_t *nv;
-
- nv = nxt_array_add(array);
- if (nxt_slow_path(nv == NULL)) {
- return NULL;
- }
-
- nv->hash = nxt_http_field_hash_end(hash) & 0xFFFF;
-
- length = end - start;
-
- if (name == NULL) {
- name_length = length;
- name = start;
- length = 0;
- }
-
- nv->name_length = name_length;
- nv->value_length = length;
- nv->name = name;
- nv->value = start;
-
- return nv;
-}
-
-
static nxt_int_t
nxt_http_route_test_argument(nxt_http_request_t *r,
nxt_http_route_rule_t *rule, nxt_array_t *array)
@@ -2235,7 +2035,7 @@ nxt_http_route_query(nxt_http_request_t *r, nxt_http_route_rule_t *rule)
{
nxt_array_t *arguments;
- arguments = nxt_http_route_arguments_parse(r);
+ arguments = nxt_http_arguments_parse(r);
if (nxt_slow_path(arguments == NULL)) {
return -1;
}
@@ -2250,7 +2050,7 @@ nxt_http_route_cookies(nxt_http_request_t *r, nxt_http_route_rule_t *rule)
{
nxt_array_t *cookies;
- cookies = nxt_http_route_cookies_parse(r);
+ cookies = nxt_http_cookies_parse(r);
if (nxt_slow_path(cookies == NULL)) {
return -1;
}
@@ -2259,128 +2059,6 @@ nxt_http_route_cookies(nxt_http_request_t *r, nxt_http_route_rule_t *rule)
}
-static nxt_array_t *
-nxt_http_route_cookies_parse(nxt_http_request_t *r)
-{
- nxt_int_t ret;
- nxt_array_t *cookies;
- nxt_http_field_t *f;
-
- if (r->cookies != NULL) {
- return r->cookies;
- }
-
- cookies = nxt_array_create(r->mem_pool, 2, sizeof(nxt_http_name_value_t));
- if (nxt_slow_path(cookies == NULL)) {
- return NULL;
- }
-
- nxt_list_each(f, r->fields) {
-
- if (f->hash != NXT_COOKIE_HASH
- || f->name_length != 6
- || nxt_strncasecmp(f->name, (u_char *) "Cookie", 6) != 0)
- {
- continue;
- }
-
- ret = nxt_http_route_cookie_parse(cookies, f->value,
- f->value + f->value_length);
- if (ret != NXT_OK) {
- return NULL;
- }
-
- } nxt_list_loop;
-
- r->cookies = cookies;
-
- return cookies;
-}
-
-
-static nxt_int_t
-nxt_http_route_cookie_parse(nxt_array_t *cookies, u_char *start, u_char *end)
-{
- size_t name_length;
- u_char c, *p, *name;
- nxt_http_name_value_t *nv;
-
- name = NULL;
- name_length = 0;
-
- for (p = start; p < end; p++) {
- c = *p;
-
- if (c == '=') {
- while (start[0] == ' ') { start++; }
-
- name_length = p - start;
-
- if (name_length != 0) {
- name = start;
- }
-
- start = p + 1;
-
- } else if (c == ';') {
- if (name != NULL) {
- nv = nxt_http_route_cookie(cookies, name, name_length,
- start, p);
- if (nxt_slow_path(nv == NULL)) {
- return NXT_ERROR;
- }
- }
-
- name = NULL;
- start = p + 1;
- }
- }
-
- if (name != NULL) {
- nv = nxt_http_route_cookie(cookies, name, name_length, start, p);
- if (nxt_slow_path(nv == NULL)) {
- return NXT_ERROR;
- }
- }
-
- return NXT_OK;
-}
-
-
-static nxt_http_name_value_t *
-nxt_http_route_cookie(nxt_array_t *array, u_char *name, size_t name_length,
- u_char *start, u_char *end)
-{
- u_char c, *p;
- uint32_t hash;
- nxt_http_name_value_t *nv;
-
- nv = nxt_array_add(array);
- if (nxt_slow_path(nv == NULL)) {
- return NULL;
- }
-
- nv->name_length = name_length;
- nv->name = name;
-
- hash = NXT_HTTP_FIELD_HASH_INIT;
-
- for (p = name; p < name + name_length; p++) {
- c = *p;
- hash = nxt_http_field_hash_char(hash, c);
- }
-
- nv->hash = nxt_http_field_hash_end(hash) & 0xFFFF;
-
- while (start < end && end[-1] == ' ') { end--; }
-
- nv->value_length = end - start;
- nv->value = start;
-
- return nv;
-}
-
-
static nxt_int_t
nxt_http_route_test_cookie(nxt_http_request_t *r,
nxt_http_route_rule_t *rule, nxt_array_t *array)
diff --git a/src/nxt_http_static.c b/src/nxt_http_static.c
index 36c1ebc9..61dd0cb3 100644
--- a/src/nxt_http_static.c
+++ b/src/nxt_http_static.c
@@ -19,6 +19,7 @@ typedef struct {
typedef struct {
nxt_uint_t nshares;
nxt_http_static_share_t *shares;
+ nxt_str_t index;
#if (NXT_HAVE_OPENAT2)
nxt_var_t *chroot;
nxt_uint_t resolve;
@@ -33,7 +34,7 @@ typedef struct {
#if (NXT_HAVE_OPENAT2)
nxt_str_t chroot;
#endif
- uint32_t index;
+ uint32_t share_idx;
uint8_t need_body; /* 1 bit */
} nxt_http_static_ctx_t;
@@ -75,9 +76,8 @@ nxt_http_static_init(nxt_task_t *task, nxt_router_temp_conf_t *tmcf,
{
uint32_t i;
nxt_mp_t *mp;
- nxt_str_t str;
+ nxt_str_t str, *ret;
nxt_var_t *var;
- nxt_bool_t array;
nxt_conf_value_t *cv;
nxt_http_static_conf_t *conf;
@@ -91,39 +91,36 @@ nxt_http_static_init(nxt_task_t *task, nxt_router_temp_conf_t *tmcf,
action->handler = nxt_http_static;
action->u.conf = conf;
- array = (nxt_conf_type(acf->share) == NXT_CONF_ARRAY);
- conf->nshares = array ? nxt_conf_array_elements_count(acf->share) : 1;
-
+ conf->nshares = nxt_conf_array_elements_count_or_1(acf->share);
conf->shares = nxt_mp_zget(mp, sizeof(nxt_http_static_share_t)
* conf->nshares);
if (nxt_slow_path(conf->shares == NULL)) {
return NXT_ERROR;
}
- if (array) {
- for (i = 0; i < conf->nshares; i++) {
- cv = nxt_conf_get_array_element(acf->share, i);
- nxt_conf_get_string(cv, &str);
-
- var = nxt_var_compile(&str, mp, 1);
- if (nxt_slow_path(var == NULL)) {
- return NXT_ERROR;
- }
+ for (i = 0; i < conf->nshares; i++) {
+ cv = nxt_conf_get_array_element_or_itself(acf->share, i);
+ nxt_conf_get_string(cv, &str);
- conf->shares[i].var = var;
- conf->shares[i].is_const = nxt_var_is_const(var);
+ var = nxt_var_compile(&str, mp, 1);
+ if (nxt_slow_path(var == NULL)) {
+ return NXT_ERROR;
}
+ conf->shares[i].var = var;
+ conf->shares[i].is_const = nxt_var_is_const(var);
+ }
+
+ if (acf->index == NULL) {
+ nxt_str_set(&conf->index, "index.html");
+
} else {
- nxt_conf_get_string(acf->share, &str);
+ nxt_conf_get_string(acf->index, &str);
- var = nxt_var_compile(&str, mp, 1);
- if (nxt_slow_path(var == NULL)) {
+ ret = nxt_str_dup(mp, &conf->index, &str);
+ if (nxt_slow_path(ret == NULL)) {
return NXT_ERROR;
}
-
- conf->shares[0].var = var;
- conf->shares[0].is_const = nxt_var_is_const(var);
}
#if (NXT_HAVE_OPENAT2)
@@ -234,12 +231,14 @@ nxt_http_static_iterate(nxt_task_t *task, nxt_http_request_t *r,
conf = ctx->action->u.conf;
- share = &conf->shares[ctx->index];
+ share = &conf->shares[ctx->share_idx];
#if (NXT_DEBUG)
nxt_str_t shr;
+ nxt_str_t idx;
nxt_var_raw(share->var, &shr);
+ idx = conf->index;
#if (NXT_HAVE_OPENAT2)
nxt_str_t chr;
@@ -251,9 +250,10 @@ nxt_http_static_iterate(nxt_task_t *task, nxt_http_request_t *r,
nxt_str_set(&chr, "");
}
- nxt_debug(task, "http static: \"%V\" (chroot: \"%V\")", &shr, &chr);
+ nxt_debug(task, "http static: \"%V\", index: \"%V\" (chroot: \"%V\")",
+ &shr, &idx, &chr);
#else
- nxt_debug(task, "http static: \"%V\"", &shr);
+ nxt_debug(task, "http static: \"%V\", index: \"%V\"", &shr, &idx);
#endif
#endif /* NXT_DEBUG */
@@ -261,7 +261,7 @@ nxt_http_static_iterate(nxt_task_t *task, nxt_http_request_t *r,
nxt_var_raw(share->var, &ctx->share);
#if (NXT_HAVE_OPENAT2)
- if (conf->chroot != NULL && ctx->index == 0) {
+ if (conf->chroot != NULL && ctx->share_idx == 0) {
nxt_var_raw(conf->chroot, &ctx->chroot);
}
#endif
@@ -278,7 +278,7 @@ nxt_http_static_iterate(nxt_task_t *task, nxt_http_request_t *r,
nxt_var_query(task, r->var_query, share->var, &ctx->share);
#if (NXT_HAVE_OPENAT2)
- if (conf->chroot != NULL && ctx->index == 0) {
+ if (conf->chroot != NULL && ctx->share_idx == 0) {
nxt_var_query(task, r->var_query, conf->chroot, &ctx->chroot);
}
#endif
@@ -298,7 +298,7 @@ nxt_http_static_send_ready(nxt_task_t *task, void *obj, void *data)
struct tm tm;
nxt_buf_t *fb;
nxt_int_t ret;
- nxt_str_t *shr, exten, *mtype;
+ nxt_str_t *shr, *index, exten, *mtype;
nxt_uint_t level;
nxt_file_t *f, file;
nxt_file_info_t fi;
@@ -311,8 +311,6 @@ nxt_http_static_send_ready(nxt_task_t *task, void *obj, void *data)
nxt_http_static_ctx_t *ctx;
nxt_http_static_conf_t *conf;
- static const nxt_str_t index = nxt_string("index.html");
-
r = obj;
ctx = data;
action = ctx->action;
@@ -323,12 +321,12 @@ nxt_http_static_send_ready(nxt_task_t *task, void *obj, void *data)
mtype = NULL;
shr = &ctx->share;
+ index = &conf->index;
if (shr->start[shr->length - 1] == '/') {
- /* TODO: dynamic index setting. */
- nxt_str_set(&exten, ".html");
+ nxt_http_static_extract_extension(index, &exten);
- length = shr->length + index.length;
+ length = shr->length + index->length;
fname = nxt_mp_nget(r->mem_pool, length + 1);
if (nxt_slow_path(fname == NULL)) {
@@ -337,7 +335,7 @@ nxt_http_static_send_ready(nxt_task_t *task, void *obj, void *data)
p = fname;
p = nxt_cpymem(p, shr->start, shr->length);
- p = nxt_cpymem(p, index.start, index.length);
+ p = nxt_cpymem(p, index->start, index->length);
*p = '\0';
} else {
@@ -373,7 +371,7 @@ nxt_http_static_send_ready(nxt_task_t *task, void *obj, void *data)
nxt_uint_t resolve;
nxt_http_static_share_t *share;
- share = &conf->shares[ctx->index];
+ share = &conf->shares[ctx->share_idx];
resolve = conf->resolve;
chr = &ctx->chroot;
@@ -587,7 +585,9 @@ nxt_http_static_send_ready(nxt_task_t *task, void *obj, void *data)
/* Not a file. */
nxt_file_close(task, f);
- if (nxt_slow_path(!nxt_is_dir(&fi))) {
+ if (nxt_slow_path(!nxt_is_dir(&fi)
+ || shr->start[shr->length - 1] == '/'))
+ {
nxt_log(task, NXT_LOG_ERR, "\"%FN\" is not a regular file",
f->name);
@@ -675,9 +675,9 @@ nxt_http_static_next(nxt_task_t *task, nxt_http_request_t *r,
action = ctx->action;
conf = action->u.conf;
- ctx->index++;
+ ctx->share_idx++;
- if (ctx->index < conf->nshares) {
+ if (ctx->share_idx < conf->nshares) {
nxt_http_static_iterate(task, r, ctx);
return;
}
diff --git a/src/nxt_http_variables.c b/src/nxt_http_variables.c
index 1c0b561d..b765e177 100644
--- a/src/nxt_http_variables.c
+++ b/src/nxt_http_variables.c
@@ -9,6 +9,8 @@
static nxt_int_t nxt_http_var_method(nxt_task_t *task, nxt_var_query_t *query,
nxt_str_t *str, void *ctx);
+static nxt_int_t nxt_http_var_request_uri(nxt_task_t *task,
+ nxt_var_query_t *query, nxt_str_t *str, void *ctx);
static nxt_int_t nxt_http_var_uri(nxt_task_t *task, nxt_var_query_t *query,
nxt_str_t *str, void *ctx);
static nxt_int_t nxt_http_var_host(nxt_task_t *task, nxt_var_query_t *query,
@@ -20,6 +22,10 @@ static nxt_var_decl_t nxt_http_vars[] = {
&nxt_http_var_method,
0 },
+ { nxt_string("request_uri"),
+ &nxt_http_var_request_uri,
+ 0 },
+
{ nxt_string("uri"),
&nxt_http_var_uri,
0 },
@@ -52,6 +58,20 @@ nxt_http_var_method(nxt_task_t *task, nxt_var_query_t *query, nxt_str_t *str,
static nxt_int_t
+nxt_http_var_request_uri(nxt_task_t *task, nxt_var_query_t *query,
+ nxt_str_t *str, void *ctx)
+{
+ nxt_http_request_t *r;
+
+ r = ctx;
+
+ *str = r->target;
+
+ return NXT_OK;
+}
+
+
+static nxt_int_t
nxt_http_var_uri(nxt_task_t *task, nxt_var_query_t *query, nxt_str_t *str,
void *ctx)
{
diff --git a/src/nxt_job.h b/src/nxt_job.h
index d308c35d..0495c484 100644
--- a/src/nxt_job.h
+++ b/src/nxt_job.h
@@ -67,21 +67,18 @@ NXT_EXPORT void nxt_job_return(nxt_task_t *task, nxt_job_t *job,
nxt_work_handler_t handler);
-#define \
-nxt_job_cancel(job) \
+#define nxt_job_cancel(job) \
(job)->cancel = 1
#if (NXT_DEBUG)
-#define \
-nxt_job_set_name(job, text) \
+#define nxt_job_set_name(job, text) \
(job)->name = text
#else
-#define \
-nxt_job_set_name(job, text)
+#define nxt_job_set_name(job, text)
#endif
diff --git a/src/nxt_list.h b/src/nxt_list.h
index ecbb67a9..dc948e03 100644
--- a/src/nxt_list.h
+++ b/src/nxt_list.h
@@ -37,18 +37,15 @@ typedef struct {
} nxt_list_next_t;
-#define \
-nxt_list_part(list) \
+#define nxt_list_part(list) \
(&(list)->part)
-#define \
-nxt_list_data(part) \
+#define nxt_list_data(part) \
((void *) part->data)
-#define \
-nxt_list_first(list) \
+#define nxt_list_first(list) \
nxt_list_data(nxt_list_part(list))
@@ -102,8 +99,7 @@ NXT_EXPORT void *nxt_list_zero_add(nxt_list_t *list);
NXT_EXPORT void *nxt_list_next(nxt_list_t *list, nxt_list_next_t *next);
-#define \
-nxt_list_next_value(list, next) \
+#define nxt_list_next_value(list, next) \
(nxt_pointer_to(nxt_list_data((next)->part), (next)->elt * (list)->size))
diff --git a/src/nxt_log.h b/src/nxt_log.h
index 0cf10b5c..aa2fe673 100644
--- a/src/nxt_log.h
+++ b/src/nxt_log.h
@@ -41,8 +41,7 @@ NXT_EXPORT void nxt_cdecl nxt_log_handler(nxt_uint_t level, nxt_log_t *log,
const char *fmt, ...);
-#define \
-nxt_log_level_enough(log, level) \
+#define nxt_log_level_enough(log, level) \
((log)->level >= (level))
@@ -83,8 +82,7 @@ nxt_log_level_enough(log, level) \
} while (0)
-#define \
-nxt_log_error(_level, _log, ...) \
+#define nxt_log_error(_level, _log, ...) \
do { \
nxt_log_t *_log_ = (_log); \
nxt_uint_t _level_ = (_level); \
@@ -107,8 +105,7 @@ nxt_log_error(_level, _log, ...) \
} while (0)
-#define \
-nxt_log_debug(_log, ...) \
+#define nxt_log_debug(_log, ...) \
do { \
nxt_log_t *_log_ = (_log); \
\
@@ -131,8 +128,7 @@ nxt_log_debug(_log, ...) \
#define nxt_debug(...)
-#define \
-nxt_log_debug(...)
+#define nxt_log_debug(...)
#define nxt_assert(c)
@@ -151,18 +147,15 @@ nxt_log_debug(...)
#endif
-#define \
-nxt_main_log_alert(...) \
+#define nxt_main_log_alert(...) \
nxt_log_alert(&nxt_main_log, __VA_ARGS__)
-#define \
-nxt_main_log_error(level, ...) \
+#define nxt_main_log_error(level, ...) \
nxt_log_error(level, &nxt_main_log, __VA_ARGS__)
-#define \
-nxt_main_log_debug(...) \
+#define nxt_main_log_debug(...) \
nxt_log_debug(&nxt_main_log, __VA_ARGS__)
diff --git a/src/nxt_log_moderation.h b/src/nxt_log_moderation.h
index 0a53594d..c6033201 100644
--- a/src/nxt_log_moderation.h
+++ b/src/nxt_log_moderation.h
@@ -23,8 +23,7 @@ typedef struct {
#define NXT_LOG_MODERATION 0, -1, 0, 0, NXT_TIMER
-#define \
-nxt_log_alert_moderate(_mod, _log, ...) \
+#define nxt_log_alert_moderate(_mod, _log, ...) \
do { \
nxt_log_t *_log_ = _log; \
\
@@ -34,8 +33,7 @@ nxt_log_alert_moderate(_mod, _log, ...) \
} while (0)
-#define \
-nxt_log_moderate(_mod, _level, _log, ...) \
+#define nxt_log_moderate(_mod, _level, _log, ...) \
do { \
nxt_log_t *_log_ = _log; \
\
diff --git a/src/nxt_lvlhsh.c b/src/nxt_lvlhsh.c
index d10dbc58..7a8b3dda 100644
--- a/src/nxt_lvlhsh.c
+++ b/src/nxt_lvlhsh.c
@@ -43,121 +43,98 @@
* several levels.
*/
-#define \
-nxt_lvlhsh_is_bucket(p) \
+#define nxt_lvlhsh_is_bucket(p) \
((uintptr_t) (p) & 1)
-#define \
-nxt_lvlhsh_count_inc(n) \
+#define nxt_lvlhsh_count_inc(n) \
n = (void *) ((uintptr_t) (n) + 2)
-#define \
-nxt_lvlhsh_count_dec(n) \
+#define nxt_lvlhsh_count_dec(n) \
n = (void *) ((uintptr_t) (n) - 2)
-#define \
-nxt_lvlhsh_level_size(proto, nlvl) \
+#define nxt_lvlhsh_level_size(proto, nlvl) \
((uintptr_t) 1 << proto->shift[nlvl])
-#define \
-nxt_lvlhsh_level(lvl, mask) \
+#define nxt_lvlhsh_level(lvl, mask) \
(void **) ((uintptr_t) lvl & (~mask << 2))
-#define \
-nxt_lvlhsh_level_entries(lvl, mask) \
+#define nxt_lvlhsh_level_entries(lvl, mask) \
((uintptr_t) lvl & (mask << 1))
-#define \
-nxt_lvlhsh_store_bucket(slot, bkt) \
+#define nxt_lvlhsh_store_bucket(slot, bkt) \
slot = (void **) ((uintptr_t) bkt | 2 | 1)
-#define \
-nxt_lvlhsh_bucket_size(proto) \
+#define nxt_lvlhsh_bucket_size(proto) \
proto->bucket_size
-#define \
-nxt_lvlhsh_bucket(proto, bkt) \
+#define nxt_lvlhsh_bucket(proto, bkt) \
(uint32_t *) ((uintptr_t) bkt & ~(uintptr_t) proto->bucket_mask)
-#define \
-nxt_lvlhsh_bucket_entries(proto, bkt) \
+#define nxt_lvlhsh_bucket_entries(proto, bkt) \
(((uintptr_t) bkt & (uintptr_t) proto->bucket_mask) >> 1)
-#define \
-nxt_lvlhsh_bucket_end(proto, bkt) \
+#define nxt_lvlhsh_bucket_end(proto, bkt) \
&bkt[proto->bucket_end]
-#define \
-nxt_lvlhsh_free_entry(e) \
+#define nxt_lvlhsh_free_entry(e) \
(!(nxt_lvlhsh_valid_entry(e)))
-#define \
-nxt_lvlhsh_next_bucket(proto, bkt) \
+#define nxt_lvlhsh_next_bucket(proto, bkt) \
((void **) &bkt[proto->bucket_end])
#if (NXT_64BIT)
-#define \
-nxt_lvlhsh_valid_entry(e) \
+#define nxt_lvlhsh_valid_entry(e) \
(((e)[0] | (e)[1]) != 0)
-#define \
-nxt_lvlhsh_entry_value(e) \
+#define nxt_lvlhsh_entry_value(e) \
(void *) (((uintptr_t) (e)[1] << 32) + (e)[0])
-#define \
-nxt_lvlhsh_set_entry_value(e, n) \
+#define nxt_lvlhsh_set_entry_value(e, n) \
(e)[0] = (uint32_t) (uintptr_t) n; \
(e)[1] = (uint32_t) ((uintptr_t) n >> 32)
-#define \
-nxt_lvlhsh_entry_key(e) \
+#define nxt_lvlhsh_entry_key(e) \
(e)[2]
-#define \
-nxt_lvlhsh_set_entry_key(e, n) \
+#define nxt_lvlhsh_set_entry_key(e, n) \
(e)[2] = n
#else
-#define \
-nxt_lvlhsh_valid_entry(e) \
+#define nxt_lvlhsh_valid_entry(e) \
((e)[0] != 0)
-#define \
-nxt_lvlhsh_entry_value(e) \
+#define nxt_lvlhsh_entry_value(e) \
(void *) (e)[0]
-#define \
-nxt_lvlhsh_set_entry_value(e, n) \
+#define nxt_lvlhsh_set_entry_value(e, n) \
(e)[0] = (uint32_t) n
-#define \
-nxt_lvlhsh_entry_key(e) \
+#define nxt_lvlhsh_entry_key(e) \
(e)[1]
-#define \
-nxt_lvlhsh_set_entry_key(e, n) \
+#define nxt_lvlhsh_set_entry_key(e, n) \
(e)[1] = n
#endif
diff --git a/src/nxt_lvlhsh.h b/src/nxt_lvlhsh.h
index 7127c0d0..c051081c 100644
--- a/src/nxt_lvlhsh.h
+++ b/src/nxt_lvlhsh.h
@@ -114,13 +114,11 @@ typedef struct {
} nxt_lvlhsh_each_t;
-#define \
-nxt_lvlhsh_is_empty(lh) \
+#define nxt_lvlhsh_is_empty(lh) \
((lh)->slot == NULL)
-#define \
-nxt_lvlhsh_init(lh) \
+#define nxt_lvlhsh_init(lh) \
(lh)->slot = NULL
/*
diff --git a/src/nxt_main_process.c b/src/nxt_main_process.c
index 61521854..03761a10 100644
--- a/src/nxt_main_process.c
+++ b/src/nxt_main_process.c
@@ -382,25 +382,25 @@ nxt_main_start_process_handler(nxt_task_t *task, nxt_port_recv_msg_t *msg)
port = rt->port_by_type[NXT_PROCESS_ROUTER];
if (nxt_slow_path(port == NULL)) {
nxt_alert(task, "router port not found");
- return;
+ goto close_fds;
}
if (nxt_slow_path(port->pid != nxt_recv_msg_cmsg_pid(msg))) {
nxt_alert(task, "process %PI cannot start processes",
nxt_recv_msg_cmsg_pid(msg));
- return;
+ goto close_fds;
}
process = nxt_process_new(rt);
if (nxt_slow_path(process == NULL)) {
- return;
+ goto close_fds;
}
process->mem_pool = nxt_mp_create(1024, 128, 256, 32);
if (process->mem_pool == NULL) {
nxt_process_use(task, process, -1);
- return;
+ goto close_fds;
}
process->parent_port = rt->port_by_type[NXT_PROCESS_MAIN];
@@ -422,6 +422,9 @@ nxt_main_start_process_handler(nxt_task_t *task, nxt_port_recv_msg_t *msg)
goto failed;
}
+ app_conf->shared_port_fd = msg->fd[0];
+ app_conf->shared_queue_fd = msg->fd[1];
+
start = b->mem.pos;
app_conf->name.start = start;
@@ -509,6 +512,17 @@ nxt_main_start_process_handler(nxt_task_t *task, nxt_port_recv_msg_t *msg)
ret = nxt_process_start(task, process);
if (nxt_fast_path(ret == NXT_OK || ret == NXT_AGAIN)) {
+
+ /* Close shared port fds only in main process. */
+ if (ret == NXT_OK) {
+ nxt_fd_close(app_conf->shared_port_fd);
+ nxt_fd_close(app_conf->shared_queue_fd);
+ }
+
+ /* Avoid fds close in caller. */
+ msg->fd[0] = -1;
+ msg->fd[1] = -1;
+
return;
}
@@ -523,6 +537,14 @@ failed:
nxt_port_socket_write(task, port, NXT_PORT_MSG_RPC_ERROR,
-1, msg->port_msg.stream, 0, NULL);
}
+
+close_fds:
+
+ nxt_fd_close(msg->fd[0]);
+ msg->fd[0] = -1;
+
+ nxt_fd_close(msg->fd[1]);
+ msg->fd[1] = -1;
}
@@ -557,7 +579,7 @@ nxt_main_process_created_handler(nxt_task_t *task, nxt_port_recv_msg_t *msg)
-1, msg->port_msg.stream, 0, NULL);
return;
}
- }
+ }
#endif
diff --git a/src/nxt_malloc.c b/src/nxt_malloc.c
index fed58e96..5ea7322f 100644
--- a/src/nxt_malloc.c
+++ b/src/nxt_malloc.c
@@ -64,17 +64,24 @@ nxt_zalloc(size_t size)
void *
nxt_realloc(void *p, size_t size)
{
- void *n;
+ void *n;
+ uintptr_t ptr;
+
+ /*
+ * Workaround for a warning on GCC 12 about using "p" pointer in debug log
+ * after realloc().
+ */
+ ptr = (uintptr_t) p;
n = realloc(p, size);
if (nxt_fast_path(n != NULL)) {
- nxt_log_debug(nxt_malloc_log(), "realloc(%p, %uz): %p", p, size, n);
+ nxt_log_debug(nxt_malloc_log(), "realloc(%p, %uz): %p", ptr, size, n);
} else {
nxt_log_alert_moderate(&nxt_malloc_log_moderation, nxt_malloc_log(),
"realloc(%p, %uz) failed %E",
- p, size, nxt_errno);
+ ptr, size, nxt_errno);
}
return n;
diff --git a/src/nxt_malloc.h b/src/nxt_malloc.h
index ccc3e1ef..fd5493a5 100644
--- a/src/nxt_malloc.h
+++ b/src/nxt_malloc.h
@@ -24,8 +24,7 @@ NXT_EXPORT void nxt_free(void *p);
#else
-#define \
-nxt_free(p) \
+#define nxt_free(p) \
free(p)
#endif
@@ -54,12 +53,10 @@ nxt_free(p) \
* Glibc malloc_usable_size() is fast operation.
*/
-#define \
-nxt_malloc_usable_size(p, size) \
+#define nxt_malloc_usable_size(p, size) \
size = malloc_usable_size(p)
-#define \
-nxt_malloc_cutback(cutback, size) \
+#define nxt_malloc_cutback(cutback, size) \
size = ((cutback) && size > 127 * 1024) ? size - 32 : size
#elif (NXT_FREEBSD)
@@ -81,12 +78,10 @@ nxt_malloc_cutback(cutback, size) \
* are lesser than 1M. Larger allocations require mutex acquiring.
*/
-#define \
-nxt_malloc_usable_size(p, size) \
+#define nxt_malloc_usable_size(p, size) \
size = malloc_usable_size(p)
-#define \
-nxt_malloc_cutback(cutback, size)
+#define nxt_malloc_cutback(cutback, size)
#endif
@@ -103,20 +98,16 @@ nxt_malloc_cutback(cutback, size)
* malloc_good_size() is faster than malloc_size()
*/
-#define \
-nxt_malloc_usable_size(p, size) \
+#define nxt_malloc_usable_size(p, size) \
size = malloc_good_size(size)
-#define \
-nxt_malloc_cutback(cutback, size)
+#define nxt_malloc_cutback(cutback, size)
#else
-#define \
-nxt_malloc_usable_size(p, size)
+#define nxt_malloc_usable_size(p, size)
-#define \
-nxt_malloc_cutback(cutback, size)
+#define nxt_malloc_cutback(cutback, size)
#endif
diff --git a/src/nxt_mem_map.h b/src/nxt_mem_map.h
index a4a10cc4..e529aff8 100644
--- a/src/nxt_mem_map.h
+++ b/src/nxt_mem_map.h
@@ -43,17 +43,14 @@
#define NXT_MEM_MAP_FILE (MAP_SHARED | NXT_MEM_MAP_PREFAULT)
-#define \
- nxt_mem_map_file_ctx_t(ctx)
+#define nxt_mem_map_file_ctx_t(ctx)
-#define \
-nxt_mem_map(addr, ctx, len, protection, flags, fd, offset) \
+#define nxt_mem_map(addr, ctx, len, protection, flags, fd, offset) \
nxt_mem_mmap(addr, len, protection, flags, fd, offset)
-#define \
-nxt_mem_unmap(addr, ctx, len) \
+#define nxt_mem_unmap(addr, ctx, len) \
nxt_mem_munmap(addr, len)
diff --git a/src/nxt_mem_zone.c b/src/nxt_mem_zone.c
index 67c6d746..f8ab09d9 100644
--- a/src/nxt_mem_zone.c
+++ b/src/nxt_mem_zone.c
@@ -87,48 +87,39 @@ struct nxt_mem_zone_s {
};
-#define \
-nxt_mem_zone_page_addr(zone, page) \
+#define nxt_mem_zone_page_addr(zone, page) \
(void *) (zone->start + ((page - zone->pages) << zone->page_size_shift))
-#define \
-nxt_mem_zone_addr_page(zone, addr) \
+#define nxt_mem_zone_addr_page(zone, addr) \
&zone->pages[((u_char *) addr - zone->start) >> zone->page_size_shift]
-#define \
-nxt_mem_zone_page_is_free(page) \
+#define nxt_mem_zone_page_is_free(page) \
(page->size < NXT_MEM_ZONE_PAGE_USED)
-#define \
-nxt_mem_zone_page_is_chunked(page) \
+#define nxt_mem_zone_page_is_chunked(page) \
(page->size >= 16)
-#define \
-nxt_mem_zone_page_bitmap(zone, slot) \
+#define nxt_mem_zone_page_bitmap(zone, slot) \
(slot->size < zone->small_bitmap_min_size)
-#define \
-nxt_mem_zone_set_chunk_free(map, chunk) \
+#define nxt_mem_zone_set_chunk_free(map, chunk) \
map[chunk / 8] &= ~(0x80 >> (chunk & 7))
-#define \
-nxt_mem_zone_chunk_is_free(map, chunk) \
+#define nxt_mem_zone_chunk_is_free(map, chunk) \
((map[chunk / 8] & (0x80 >> (chunk & 7))) == 0)
-#define \
-nxt_mem_zone_fresh_junk(p, size) \
+#define nxt_mem_zone_fresh_junk(p, size) \
nxt_memset((p), 0xA5, size)
-#define \
-nxt_mem_zone_free_junk(p, size) \
+#define nxt_mem_zone_free_junk(p, size) \
nxt_memset((p), 0x5A, size)
diff --git a/src/nxt_mem_zone.h b/src/nxt_mem_zone.h
index 3f078c2d..89d73ca2 100644
--- a/src/nxt_mem_zone.h
+++ b/src/nxt_mem_zone.h
@@ -14,8 +14,7 @@ typedef struct nxt_mem_zone_s nxt_mem_zone_t;
NXT_EXPORT nxt_mem_zone_t *nxt_mem_zone_init(u_char *start, size_t zone_size,
nxt_uint_t page_size);
-#define \
-nxt_mem_zone_alloc(zone, size) \
+#define nxt_mem_zone_alloc(zone, size) \
nxt_mem_zone_align((zone), 1, (size))
NXT_EXPORT void *nxt_mem_zone_align(nxt_mem_zone_t *zone, size_t alignment,
diff --git a/src/nxt_mp.c b/src/nxt_mp.c
index 4eaa16d0..d0de2c0e 100644
--- a/src/nxt_mp.c
+++ b/src/nxt_mp.c
@@ -939,12 +939,12 @@ nxt_mp_chunk_free(nxt_mp_t *mp, nxt_mp_block_t *cluster, u_char *p)
page = cluster->pages;
do {
- if (page->size != 0) {
- return NULL;
- }
+ if (page->size != 0) {
+ return NULL;
+ }
- page++;
- n--;
+ page++;
+ n--;
} while (n != 0);
/* Free cluster. */
@@ -953,9 +953,9 @@ nxt_mp_chunk_free(nxt_mp_t *mp, nxt_mp_block_t *cluster, u_char *p)
page = cluster->pages;
do {
- nxt_queue_remove(&page->link);
- page++;
- n--;
+ nxt_queue_remove(&page->link);
+ page++;
+ n--;
} while (n != 0);
nxt_rbtree_delete(&mp->blocks, &cluster->node);
diff --git a/src/nxt_openssl.c b/src/nxt_openssl.c
index 1e08015e..e19b1381 100644
--- a/src/nxt_openssl.c
+++ b/src/nxt_openssl.c
@@ -6,6 +6,9 @@
#include <nxt_main.h>
#include <nxt_conf.h>
+
+#define OPENSSL_SUPPRESS_DEPRECATED
+
#include <openssl/ssl.h>
#include <openssl/conf.h>
#include <openssl/err.h>
@@ -323,6 +326,11 @@ nxt_openssl_server_init(nxt_task_t *task, nxt_mp_t *mp,
SSL_CTX_set_options(ctx, SSL_OP_NO_COMPRESSION);
#endif
+#ifdef SSL_OP_IGNORE_UNEXPECTED_EOF
+ /* Request SSL_ERROR_ZERO_RETURN on EOF. */
+ SSL_CTX_set_options(ctx, SSL_OP_IGNORE_UNEXPECTED_EOF);
+#endif
+
#ifdef SSL_MODE_RELEASE_BUFFERS
if (nxt_openssl_version >= 10001078) {
@@ -644,16 +652,10 @@ nxt_tls_ticket_keys(nxt_task_t *task, SSL_CTX *ctx, nxt_tls_init_t *tls_init,
return NXT_OK;
}
- if (nxt_conf_type(tickets_conf) == NXT_CONF_ARRAY) {
- count = nxt_conf_array_elements_count(tickets_conf);
-
- if (count == 0) {
- goto no_ticket;
- }
+ count = nxt_conf_array_elements_count_or_1(tickets_conf);
- } else {
- /* nxt_conf_type(tickets_conf) == NXT_CONF_STRING */
- count = 1;
+ if (count == 0) {
+ goto no_ticket;
}
#ifdef SSL_CTRL_SET_TLSEXT_TICKET_KEY_CB
@@ -673,15 +675,9 @@ nxt_tls_ticket_keys(nxt_task_t *task, SSL_CTX *ctx, nxt_tls_init_t *tls_init,
i++;
- if (nxt_conf_type(tickets_conf) == NXT_CONF_ARRAY) {
- member = nxt_conf_get_array_element(tickets_conf, count - i);
- if (member == NULL) {
- break;
- }
-
- } else {
- /* nxt_conf_type(tickets_conf) == NXT_CONF_STRING */
- member = tickets_conf;
+ member = nxt_conf_get_array_element_or_itself(tickets_conf, count - i);
+ if (member == NULL) {
+ break;
}
nxt_conf_get_string(member, &value);
diff --git a/src/nxt_port.c b/src/nxt_port.c
index a5b64695..ed7050f3 100644
--- a/src/nxt_port.c
+++ b/src/nxt_port.c
@@ -176,8 +176,9 @@ nxt_port_handler(nxt_task_t *task, nxt_port_recv_msg_t *msg)
if (nxt_fast_path(msg->port_msg.type < NXT_PORT_MSG_MAX)) {
- nxt_debug(task, "port %d: message type:%uD",
- msg->port->socket.fd, msg->port_msg.type);
+ nxt_debug(task, "port %d: message type:%uD fds:%d,%d",
+ msg->port->socket.fd, msg->port_msg.type,
+ msg->fd[0], msg->fd[1]);
handlers = msg->port->data;
handlers[msg->port_msg.type](task, msg);
diff --git a/src/nxt_queue.h b/src/nxt_queue.h
index 44e9ad61..6b7f5d57 100644
--- a/src/nxt_queue.h
+++ b/src/nxt_queue.h
@@ -21,16 +21,14 @@ typedef struct {
} nxt_queue_t;
-#define \
-nxt_queue_init(queue) \
+#define nxt_queue_init(queue) \
do { \
(queue)->head.prev = &(queue)->head; \
(queue)->head.next = &(queue)->head; \
} while (0)
-#define \
-nxt_queue_sentinel(link) \
+#define nxt_queue_sentinel(link) \
do { \
(link)->prev = (link); \
(link)->next = (link); \
@@ -42,13 +40,11 @@ nxt_queue_sentinel(link) \
* using nxt_queue_remove().
*/
-#define \
-nxt_queue_self(link) \
+#define nxt_queue_self(link) \
nxt_queue_sentinel(link)
-#define \
-nxt_queue_is_empty(queue) \
+#define nxt_queue_is_empty(queue) \
(&(queue)->head == (queue)->head.prev)
/*
@@ -73,38 +69,31 @@ nxt_queue_is_empty(queue) \
* tp = nxt_queue_link_data(lnk, nxt_type_t, link);
*/
-#define \
-nxt_queue_first(queue) \
+#define nxt_queue_first(queue) \
(queue)->head.next
-#define \
-nxt_queue_last(queue) \
+#define nxt_queue_last(queue) \
(queue)->head.prev
-#define \
-nxt_queue_head(queue) \
+#define nxt_queue_head(queue) \
(&(queue)->head)
-#define \
-nxt_queue_tail(queue) \
+#define nxt_queue_tail(queue) \
(&(queue)->head)
-#define \
-nxt_queue_next(link) \
+#define nxt_queue_next(link) \
(link)->next
-#define \
-nxt_queue_prev(link) \
+#define nxt_queue_prev(link) \
(link)->prev
-#define \
-nxt_queue_insert_head(queue, link) \
+#define nxt_queue_insert_head(queue, link) \
do { \
(link)->next = (queue)->head.next; \
(link)->next->prev = (link); \
@@ -113,8 +102,7 @@ nxt_queue_insert_head(queue, link) \
} while (0)
-#define \
-nxt_queue_insert_tail(queue, link) \
+#define nxt_queue_insert_tail(queue, link) \
do { \
(link)->prev = (queue)->head.prev; \
(link)->prev->next = (link); \
@@ -123,8 +111,7 @@ nxt_queue_insert_tail(queue, link) \
} while (0)
-#define \
-nxt_queue_insert_after(target, link) \
+#define nxt_queue_insert_after(target, link) \
do { \
(link)->next = (target)->next; \
(link)->next->prev = (link); \
@@ -133,8 +120,7 @@ nxt_queue_insert_after(target, link) \
} while (0)
-#define \
-nxt_queue_insert_before(target, link) \
+#define nxt_queue_insert_before(target, link) \
do { \
(link)->next = (target); \
(link)->prev = (target)->prev; \
@@ -145,8 +131,7 @@ nxt_queue_insert_before(target, link) \
#if (NXT_DEBUG)
-#define \
-nxt_queue_remove(link) \
+#define nxt_queue_remove(link) \
do { \
(link)->next->prev = (link)->prev; \
(link)->prev->next = (link)->next; \
@@ -156,8 +141,7 @@ nxt_queue_remove(link) \
#else
-#define \
-nxt_queue_remove(link) \
+#define nxt_queue_remove(link) \
do { \
(link)->next->prev = (link)->prev; \
(link)->prev->next = (link)->next; \
@@ -171,8 +155,7 @@ nxt_queue_remove(link) \
* the "tail" is the new tail queue.
*/
-#define \
-nxt_queue_split(queue, link, tail) \
+#define nxt_queue_split(queue, link, tail) \
do { \
(tail)->head.prev = (queue)->head.prev; \
(tail)->head.prev->next = &(tail)->head; \
@@ -185,8 +168,7 @@ nxt_queue_split(queue, link, tail) \
/* Truncate the queue "queue" starting at element "link". */
-#define \
-nxt_queue_truncate(queue, link) \
+#define nxt_queue_truncate(queue, link) \
do { \
(queue)->head.prev = (link)->prev; \
(queue)->head.prev->next = &(queue)->head; \
@@ -199,8 +181,7 @@ nxt_queue_truncate(queue, link) \
* it must be initiated with nxt_queue_init(tail).
*/
-#define \
-nxt_queue_add(queue, tail) \
+#define nxt_queue_add(queue, tail) \
do { \
(queue)->head.prev->next = (tail)->head.next; \
(tail)->head.next->prev = (queue)->head.prev; \
@@ -209,8 +190,7 @@ nxt_queue_add(queue, tail) \
} while (0)
-#define \
-nxt_queue_link_data(lnk, type, link) \
+#define nxt_queue_link_data(lnk, type, link) \
nxt_container_of(lnk, type, link)
diff --git a/src/nxt_router.c b/src/nxt_router.c
index 85556a72..3a32a363 100644
--- a/src/nxt_router.c
+++ b/src/nxt_router.c
@@ -223,8 +223,6 @@ static void nxt_router_access_log_reopen_error(nxt_task_t *task,
static void nxt_router_app_port_ready(nxt_task_t *task,
nxt_port_recv_msg_t *msg, void *data);
-static nxt_int_t nxt_router_app_shared_port_send(nxt_task_t *task,
- nxt_port_t *app_port);
static void nxt_router_app_port_error(nxt_task_t *task,
nxt_port_recv_msg_t *msg, void *data);
@@ -396,6 +394,7 @@ nxt_router_start_app_process_handler(nxt_task_t *task, nxt_port_t *port,
{
size_t size;
uint32_t stream;
+ nxt_fd_t port_fd, queue_fd;
nxt_int_t ret;
nxt_app_t *app;
nxt_buf_t *b;
@@ -415,6 +414,8 @@ nxt_router_start_app_process_handler(nxt_task_t *task, nxt_port_t *port,
nxt_debug(task, "app '%V' %p start process", &app->name, app);
b = NULL;
+ port_fd = -1;
+ queue_fd = -1;
} else {
if (app->proto_port_requests > 0) {
@@ -441,6 +442,9 @@ nxt_router_start_app_process_handler(nxt_task_t *task, nxt_port_t *port,
nxt_buf_cpystr(b, &app->name);
*b->mem.free++ = '\0';
nxt_buf_cpystr(b, &app->conf);
+
+ port_fd = app->shared_port->pair[0];
+ queue_fd = app->shared_port->queue_fd;
}
app_joint_rpc = nxt_port_rpc_register_handler_ex(task, port,
@@ -453,8 +457,8 @@ nxt_router_start_app_process_handler(nxt_task_t *task, nxt_port_t *port,
stream = nxt_port_rpc_ex_stream(app_joint_rpc);
- ret = nxt_port_socket_write(task, dport, NXT_PORT_MSG_START_PROCESS,
- -1, stream, port->id, b);
+ ret = nxt_port_socket_write2(task, dport, NXT_PORT_MSG_START_PROCESS,
+ port_fd, queue_fd, stream, port->id, b);
if (nxt_slow_path(ret != NXT_OK)) {
nxt_port_rpc_cancel(task, port, stream);
@@ -1920,25 +1924,15 @@ nxt_router_conf_create(nxt_task_t *task, nxt_router_temp_conf_t *tmcf,
tls_init->tickets_conf = nxt_conf_get_path(listener,
&conf_tickets);
- if (nxt_conf_type(certificate) == NXT_CONF_ARRAY) {
- n = nxt_conf_array_elements_count(certificate);
-
- for (i = 0; i < n; i++) {
- value = nxt_conf_get_array_element(certificate, i);
-
- nxt_assert(value != NULL);
+ n = nxt_conf_array_elements_count_or_1(certificate);
- ret = nxt_router_conf_tls_insert(tmcf, value, skcf,
- tls_init, i == 0);
- if (nxt_slow_path(ret != NXT_OK)) {
- goto fail;
- }
- }
+ for (i = 0; i < n; i++) {
+ value = nxt_conf_get_array_element_or_itself(certificate,
+ i);
+ nxt_assert(value != NULL);
- } else {
- /* NXT_CONF_STRING */
- ret = nxt_router_conf_tls_insert(tmcf, certificate, skcf,
- tls_init, 1);
+ ret = nxt_router_conf_tls_insert(tmcf, value, skcf,
+ tls_init, i == 0);
if (nxt_slow_path(ret != NXT_OK)) {
goto fail;
}
@@ -2779,6 +2773,7 @@ nxt_router_app_rpc_create(nxt_task_t *task,
{
size_t size;
uint32_t stream;
+ nxt_fd_t port_fd, queue_fd;
nxt_int_t ret;
nxt_buf_t *b;
nxt_port_t *router_port, *dport;
@@ -2807,10 +2802,15 @@ nxt_router_app_rpc_create(nxt_task_t *task,
dport = rt->port_by_type[NXT_PROCESS_MAIN];
+ port_fd = app->shared_port->pair[0];
+ queue_fd = app->shared_port->queue_fd;
+
} else {
nxt_debug(task, "app '%V' prefork", &app->name);
b = NULL;
+ port_fd = -1;
+ queue_fd = -1;
}
router_port = rt->port_by_type[NXT_PROCESS_ROUTER];
@@ -2829,9 +2829,8 @@ nxt_router_app_rpc_create(nxt_task_t *task,
stream = nxt_port_rpc_ex_stream(rpc);
- ret = nxt_port_socket_write(task, dport,
- NXT_PORT_MSG_START_PROCESS,
- -1, stream, router_port->id, b);
+ ret = nxt_port_socket_write2(task, dport, NXT_PORT_MSG_START_PROCESS,
+ port_fd, queue_fd, stream, router_port->id, b);
if (nxt_slow_path(ret != NXT_OK)) {
nxt_port_rpc_cancel(task, router_port, stream);
goto fail;
@@ -2906,7 +2905,7 @@ nxt_router_app_prefork_ready(nxt_task_t *task, nxt_port_recv_msg_t *msg,
nxt_port_inc_use(port);
- nxt_router_app_shared_port_send(task, port);
+ nxt_port_socket_write(task, port, NXT_PORT_MSG_PORT_ACK, -1, 0, 0, NULL);
nxt_work_queue_add(&engine->fast_work_queue,
nxt_router_conf_apply, task, rpc->temp_conf, NULL);
@@ -4618,46 +4617,12 @@ nxt_router_app_port_ready(nxt_task_t *task, nxt_port_recv_msg_t *msg,
nxt_debug(task, "app '%V' new port ready, pid %PI, %d/%d",
&app->name, port->pid, app->processes, app->pending_processes);
- nxt_router_app_shared_port_send(task, port);
+ nxt_port_socket_write(task, port, NXT_PORT_MSG_PORT_ACK, -1, 0, 0, NULL);
nxt_router_app_port_release(task, app, port, NXT_APR_NEW_PORT);
}
-static nxt_int_t
-nxt_router_app_shared_port_send(nxt_task_t *task, nxt_port_t *app_port)
-{
- nxt_buf_t *b;
- nxt_port_t *port;
- nxt_port_msg_new_port_t *msg;
-
- b = nxt_buf_mem_ts_alloc(task, task->thread->engine->mem_pool,
- sizeof(nxt_port_data_t));
- if (nxt_slow_path(b == NULL)) {
- return NXT_ERROR;
- }
-
- port = app_port->app->shared_port;
-
- nxt_debug(task, "send port %FD to process %PI",
- port->pair[0], app_port->pid);
-
- b->mem.free += sizeof(nxt_port_msg_new_port_t);
- msg = (nxt_port_msg_new_port_t *) b->mem.pos;
-
- msg->id = port->id;
- msg->pid = port->pid;
- msg->max_size = port->max_size;
- msg->max_share = port->max_share;
- msg->type = port->type;
-
- return nxt_port_socket_write2(task, app_port,
- NXT_PORT_MSG_NEW_PORT,
- port->pair[0], port->queue_fd,
- 0, 0, b);
-}
-
-
static void
nxt_router_app_port_error(nxt_task_t *task, nxt_port_recv_msg_t *msg,
void *data)
diff --git a/src/nxt_service.h b/src/nxt_service.h
index 55d98351..c43d5394 100644
--- a/src/nxt_service.h
+++ b/src/nxt_service.h
@@ -15,8 +15,7 @@ typedef struct {
} nxt_service_t;
-#define \
-nxt_service_is_module(s) \
+#define nxt_service_is_module(s) \
((s)->type == NULL)
diff --git a/src/nxt_signal.h b/src/nxt_signal.h
index 900a9e16..bc61eb2f 100644
--- a/src/nxt_signal.h
+++ b/src/nxt_signal.h
@@ -36,12 +36,10 @@ typedef struct {
nxt_event_signals_t *nxt_event_engine_signals(const nxt_sig_event_t *sigev);
-#define \
-nxt_event_engine_signals_start(engine) \
+#define nxt_event_engine_signals_start(engine) \
nxt_signal_thread_start(engine)
-#define \
-nxt_event_engine_signals_stop(engine) \
+#define nxt_event_engine_signals_stop(engine) \
nxt_signal_thread_stop(engine)
diff --git a/src/nxt_socket.h b/src/nxt_socket.h
index ec21d779..69b09039 100644
--- a/src/nxt_socket.h
+++ b/src/nxt_socket.h
@@ -118,12 +118,10 @@ NXT_EXPORT ssize_t nxt_socketpair_recv(nxt_fd_event_t *ev,
nxt_iobuf_t *iob, nxt_uint_t niob, void *oob);
-#define \
-nxt_socket_nonblocking(task, fd) \
+#define nxt_socket_nonblocking(task, fd) \
nxt_fd_nonblocking(task, fd)
-#define \
-nxt_socket_blocking(task, fd) \
+#define nxt_socket_blocking(task, fd) \
nxt_fd_blocking(task, fd)
diff --git a/src/nxt_source.h b/src/nxt_source.h
index 976cc8f9..0b4658dd 100644
--- a/src/nxt_source.h
+++ b/src/nxt_source.h
@@ -22,8 +22,7 @@ typedef void (*nxt_source_handler_t)(void *source_context,
nxt_source_hook_t *query);
-#define \
-nxt_source_filter(thr, wq, task, next, out) \
+#define nxt_source_filter(thr, wq, task, next, out) \
do { \
if (thr->engine->batch != 0) { \
nxt_thread_work_queue_add(thr, wq, nxt_source_filter_handler, \
diff --git a/src/nxt_sprintf.c b/src/nxt_sprintf.c
index 9557b327..9c8e27ed 100644
--- a/src/nxt_sprintf.c
+++ b/src/nxt_sprintf.c
@@ -90,15 +90,13 @@ static u_char *nxt_number(nxt_sprintf_t *spf, u_char *buf, double n);
/* A right way of "f == 0.0". */
-#define \
-nxt_double_is_zero(f) \
+#define nxt_double_is_zero(f) \
(fabs(f) <= FLT_EPSILON)
u_char *
nxt_vsprintf(u_char *buf, u_char *end, const char *fmt, va_list args)
{
- u_char *p;
int d;
double f, i;
size_t length;
@@ -110,12 +108,14 @@ nxt_vsprintf(u_char *buf, u_char *end, const char *fmt, va_list args)
nxt_msec_t ms;
nxt_nsec_t ns;
nxt_bool_t sign;
+ const u_char *p;
nxt_sprintf_t spf;
nxt_file_name_t *fn;
static const u_char hexadecimal[16] = "0123456789abcdef";
static const u_char HEXADECIMAL[16] = "0123456789ABCDEF";
static const u_char nan[] = "[nan]";
+ static const u_char null[] = "[null]";
static const u_char infinity[] = "[infinity]";
spf.end = end;
@@ -151,15 +151,18 @@ nxt_vsprintf(u_char *buf, u_char *end, const char *fmt, va_list args)
continue;
case 's':
- p = va_arg(args, u_char *);
+ fmt++;
- if (nxt_fast_path(p != NULL)) {
- while (*p != '\0' && buf < end) {
- *buf++ = *p++;
- }
+ p = va_arg(args, const u_char *);
+
+ if (nxt_slow_path(p == NULL)) {
+ goto copy;
+ }
+
+ while (*p != '\0' && buf < end) {
+ *buf++ = *p++;
}
- fmt++;
continue;
case '*':
@@ -169,11 +172,9 @@ nxt_vsprintf(u_char *buf, u_char *end, const char *fmt, va_list args)
if (*fmt == 's') {
fmt++;
- p = va_arg(args, u_char *);
+ p = va_arg(args, const u_char *);
- if (nxt_fast_path(p != NULL)) {
- goto copy;
- }
+ goto copy;
}
continue;
@@ -379,13 +380,13 @@ nxt_vsprintf(u_char *buf, u_char *end, const char *fmt, va_list args)
}
if (nxt_slow_path(isnan(f))) {
- p = (u_char *) nan;
+ p = nan;
length = nxt_length(nan);
goto copy;
} else if (nxt_slow_path(isinf(f))) {
- p = (u_char *) infinity;
+ p = infinity;
length = nxt_length(infinity);
goto copy;
@@ -555,7 +556,15 @@ nxt_vsprintf(u_char *buf, u_char *end, const char *fmt, va_list args)
copy:
- buf = nxt_cpymem(buf, p, nxt_min((size_t) (end - buf), length));
+ if (nxt_slow_path(p == NULL)) {
+ p = null;
+ length = nxt_length(null);
+
+ } else {
+ length = nxt_min((size_t) (end - buf), length);
+ }
+
+ buf = nxt_cpymem(buf, p, length);
continue;
}
diff --git a/src/nxt_string.h b/src/nxt_string.h
index 4d565e87..80cdbb59 100644
--- a/src/nxt_string.h
+++ b/src/nxt_string.h
@@ -8,50 +8,40 @@
#define _NXT_STRING_H_INCLUDED_
-#define \
-nxt_lowcase(c) \
+#define nxt_lowcase(c) \
(u_char) ((c >= 'A' && c <= 'Z') ? c | 0x20 : c)
-#define \
-nxt_upcase(c) \
+#define nxt_upcase(c) \
(u_char) ((c >= 'a' && c <= 'z') ? c & ~0x20 : c)
-#define \
-nxt_isdigit(c) \
+#define nxt_isdigit(c) \
((u_char) ((c) - '0') <= 9)
-#define \
-nxt_strtod(s, endptr) \
+#define nxt_strtod(s, endptr) \
strtod((char *) s, (char **) endptr)
-#define \
-nxt_strlen(s) \
+#define nxt_strlen(s) \
strlen((char *) s)
-#define \
-nxt_strdup(s) \
+#define nxt_strdup(s) \
strdup((char *) s)
-#define \
-nxt_strchr(buf, delim) \
+#define nxt_strchr(buf, delim) \
(u_char *) strchr((char *) buf, delim)
-#define \
-nxt_memzero(buf, length) \
+#define nxt_memzero(buf, length) \
(void) memset(buf, 0, length)
-#define \
-nxt_memset(buf, c, length) \
+#define nxt_memset(buf, c, length) \
(void) memset(buf, c, length)
-#define \
-nxt_memcpy(dst, src, length) \
+#define nxt_memcpy(dst, src, length) \
(void) memcpy(dst, src, length)
@@ -72,28 +62,23 @@ nxt_cpymem(void *dst, const void *src, size_t length)
}
-#define \
-nxt_memmove(dst, src, length) \
+#define nxt_memmove(dst, src, length) \
(void) memmove(dst, src, length)
-#define \
-nxt_memcmp(s1, s2, length) \
+#define nxt_memcmp(s1, s2, length) \
memcmp((char *) s1, (char *) s2, length)
-#define \
-nxt_memchr(s, c, length) \
+#define nxt_memchr(s, c, length) \
memchr((char *) s, c, length)
-#define \
-nxt_strcmp(s1, s2) \
+#define nxt_strcmp(s1, s2) \
strcmp((char *) s1, (char *) s2)
-#define \
-nxt_strncmp(s1, s2, length) \
+#define nxt_strncmp(s1, s2, length) \
strncmp((char *) s1, (char *) s2, length)
@@ -125,16 +110,14 @@ typedef struct {
#define nxt_null_string { 0, NULL }
-#define \
-nxt_str_set(str, text) \
+#define nxt_str_set(str, text) \
do { \
(str)->length = nxt_length(text); \
(str)->start = (u_char *) text; \
} while (0)
-#define \
-nxt_str_null(str) \
+#define nxt_str_null(str) \
do { \
(str)->length = 0; \
(str)->start = NULL; \
@@ -147,35 +130,29 @@ NXT_EXPORT nxt_str_t *nxt_str_dup(nxt_mp_t *mp, nxt_str_t *dst,
NXT_EXPORT char *nxt_str_cstrz(nxt_mp_t *mp, const nxt_str_t *src);
-#define \
-nxt_strstr_eq(s1, s2) \
+#define nxt_strstr_eq(s1, s2) \
(((s1)->length == (s2)->length) \
&& (nxt_memcmp((s1)->start, (s2)->start, (s1)->length) == 0))
-#define \
-nxt_strcasestr_eq(s1, s2) \
+#define nxt_strcasestr_eq(s1, s2) \
(((s1)->length == (s2)->length) \
&& (nxt_memcasecmp((s1)->start, (s2)->start, (s1)->length) == 0))
-#define \
-nxt_str_eq(s, p, _length) \
+#define nxt_str_eq(s, p, _length) \
(((s)->length == _length) && (nxt_memcmp((s)->start, p, _length) == 0))
-#define \
-nxt_str_start(s, p, _length) \
+#define nxt_str_start(s, p, _length) \
(((s)->length >= _length) && (nxt_memcmp((s)->start, p, _length) == 0))
-#define \
-nxt_strchr_eq(s, c) \
+#define nxt_strchr_eq(s, c) \
(((s)->length == 1) && ((s)->start[0] == c))
-#define \
-nxt_strchr_start(s, c) \
+#define nxt_strchr_start(s, c) \
(((s)->length != 0) && ((s)->start[0] == c))
diff --git a/src/nxt_thread.h b/src/nxt_thread.h
index 2ebc331d..53b2d8c0 100644
--- a/src/nxt_thread.h
+++ b/src/nxt_thread.h
@@ -30,19 +30,15 @@
#if (NXT_HAVE_THREAD_STORAGE_CLASS)
-#define \
-nxt_thread_extern_data(type, tsd) \
+#define nxt_thread_extern_data(type, tsd) \
NXT_EXPORT extern __thread type tsd
-#define \
-nxt_thread_declare_data(type, tsd) \
+#define nxt_thread_declare_data(type, tsd) \
__thread type tsd
-#define \
-nxt_thread_init_data(tsd)
+#define nxt_thread_init_data(tsd)
-#define \
-nxt_thread_get_data(tsd) \
+#define nxt_thread_get_data(tsd) \
&tsd
@@ -67,18 +63,15 @@ typedef struct {
} nxt_thread_specific_data_t[1];
-#define \
-nxt_thread_extern_data(type, tsd) \
+#define nxt_thread_extern_data(type, tsd) \
NXT_EXPORT extern nxt_thread_specific_data_t tsd
-#define \
-nxt_thread_declare_data(type, tsd) \
+#define nxt_thread_declare_data(type, tsd) \
nxt_thread_specific_data_t tsd = { { (nxt_atomic_int_t) -1, sizeof(type) } }
NXT_EXPORT void nxt_thread_init_data(nxt_thread_specific_data_t tsd);
-#define \
-nxt_thread_get_data(tsd) \
+#define nxt_thread_get_data(tsd) \
pthread_getspecific((pthread_key_t) tsd->key)
#endif
@@ -101,8 +94,7 @@ NXT_EXPORT void nxt_thread_cancel(nxt_thread_handle_t handle);
NXT_EXPORT void nxt_thread_wait(nxt_thread_handle_t handle);
-#define \
-nxt_thread_handle() \
+#define nxt_thread_handle() \
pthread_self()
@@ -125,18 +117,15 @@ NXT_EXPORT nxt_err_t nxt_thread_cond_wait(nxt_thread_cond_t *cond,
#if (NXT_HAVE_PTHREAD_YIELD)
-#define \
-nxt_thread_yield() \
+#define nxt_thread_yield() \
pthread_yield()
#elif (NXT_HAVE_PTHREAD_YIELD_NP)
-#define \
-nxt_thread_yield() \
+#define nxt_thread_yield() \
pthread_yield_np()
#else
-#define \
-nxt_thread_yield() \
+#define nxt_thread_yield() \
nxt_sched_yield()
#endif
diff --git a/src/nxt_thread_id.h b/src/nxt_thread_id.h
index 3263a47a..764c9934 100644
--- a/src/nxt_thread_id.h
+++ b/src/nxt_thread_id.h
@@ -179,12 +179,10 @@ NXT_EXPORT nxt_tid_t nxt_thread_tid(nxt_thread_t *thr);
typedef pthread_t nxt_thread_handle_t;
-#define \
-nxt_thread_handle_clear(th) \
+#define nxt_thread_handle_clear(th) \
th = (pthread_t) 0
-#define \
-nxt_thread_handle_equal(th0, th1) \
+#define nxt_thread_handle_equal(th0, th1) \
pthread_equal(th0, th1)
diff --git a/src/nxt_thread_time.h b/src/nxt_thread_time.h
index 05ecd938..77eaea49 100644
--- a/src/nxt_thread_time.h
+++ b/src/nxt_thread_time.h
@@ -70,21 +70,18 @@ NXT_EXPORT u_char *nxt_thread_time_string(nxt_thread_t *thr,
void nxt_time_thread_start(nxt_msec_t interval);
-#define \
-nxt_thread_monotonic_time(thr) \
+#define nxt_thread_monotonic_time(thr) \
(thr)->time.now.monotonic
#if (NXT_DEBUG)
-#define \
-nxt_thread_time_debug_update(thr) \
+#define nxt_thread_time_debug_update(thr) \
nxt_thread_time_update(thr)
#else
-#define \
-nxt_thread_time_debug_update(thr)
+#define nxt_thread_time_debug_update(thr)
#endif
diff --git a/src/nxt_time.h b/src/nxt_time.h
index d6785eb2..9617b3d4 100644
--- a/src/nxt_time.h
+++ b/src/nxt_time.h
@@ -74,20 +74,17 @@ NXT_EXPORT void nxt_timezone_update(void);
#if (NXT_HAVE_TM_GMTOFF)
-#define \
-nxt_timezone(tm) \
+#define nxt_timezone(tm) \
((tm)->tm_gmtoff)
#elif (NXT_HAVE_ALTZONE)
-#define \
-nxt_timezone(tm) \
+#define nxt_timezone(tm) \
(-(((tm)->tm_isdst > 0) ? altzone : timezone))
#else
-#define \
-nxt_timezone(tm) \
+#define nxt_timezone(tm) \
(-(((tm)->tm_isdst > 0) ? timezone + 3600 : timezone))
#endif
@@ -103,8 +100,7 @@ typedef int32_t nxt_msec_int_t;
* every 49 days. This signed subtraction takes into account that overflow.
* "nxt_msec_diff(m1, m2) < 0" means that m1 is lesser than m2.
*/
-#define \
-nxt_msec_diff(m1, m2) \
+#define nxt_msec_diff(m1, m2) \
((int32_t) ((m1) - (m2)))
diff --git a/src/nxt_time_parse.c b/src/nxt_time_parse.c
index 5a32b213..94c43289 100644
--- a/src/nxt_time_parse.c
+++ b/src/nxt_time_parse.c
@@ -282,9 +282,9 @@ nxt_time_parse(const u_char *p, size_t len)
days = days - 719527 + 31 + 28;
s = (uint64_t) days * 86400
- + (nxt_uint_t) hour * 3600
- + (nxt_uint_t) min * 60
- + (nxt_uint_t) sec;
+ + (nxt_uint_t) hour * 3600
+ + (nxt_uint_t) min * 60
+ + (nxt_uint_t) sec;
#if (NXT_TIME_T_SIZE <= 4)
diff --git a/src/nxt_unit.c b/src/nxt_unit.c
index 135c06ed..32bb07ab 100644
--- a/src/nxt_unit.c
+++ b/src/nxt_unit.c
@@ -55,6 +55,7 @@ nxt_inline void nxt_unit_mmap_buf_insert_tail(nxt_unit_mmap_buf_t **prev,
nxt_inline void nxt_unit_mmap_buf_unlink(nxt_unit_mmap_buf_t *mmap_buf);
static int nxt_unit_read_env(nxt_unit_port_t *ready_port,
nxt_unit_port_t *router_port, nxt_unit_port_t *read_port,
+ int *shared_port_fd, int *shared_queue_fd,
int *log_fd, uint32_t *stream, uint32_t *shm_limit,
uint32_t *request_limit);
static int nxt_unit_ready(nxt_unit_ctx_t *ctx, int ready_fd, uint32_t stream,
@@ -424,12 +425,12 @@ static pid_t nxt_unit_pid;
nxt_unit_ctx_t *
nxt_unit_init(nxt_unit_init_t *init)
{
- int rc, queue_fd;
+ int rc, queue_fd, shared_queue_fd;
void *mem;
uint32_t ready_stream, shm_limit, request_limit;
nxt_unit_ctx_t *ctx;
nxt_unit_impl_t *lib;
- nxt_unit_port_t ready_port, router_port, read_port;
+ nxt_unit_port_t ready_port, router_port, read_port, shared_port;
nxt_unit_pid = getpid();
@@ -440,6 +441,8 @@ nxt_unit_init(nxt_unit_init_t *init)
queue_fd = -1;
mem = MAP_FAILED;
+ shared_port.out_fd = -1;
+ shared_port.data = NULL;
if (init->ready_port.id.pid != 0
&& init->ready_stream != 0
@@ -458,8 +461,12 @@ nxt_unit_init(nxt_unit_init_t *init)
nxt_unit_port_id_init(&read_port.id, read_port.id.pid,
read_port.id.id);
+ shared_port.in_fd = init->shared_port_fd;
+ shared_queue_fd = init->shared_queue_fd;
+
} else {
rc = nxt_unit_read_env(&ready_port, &router_port, &read_port,
+ &shared_port.in_fd, &shared_queue_fd,
&lib->log_fd, &ready_stream, &shm_limit,
&request_limit);
if (nxt_slow_path(rc != NXT_UNIT_OK)) {
@@ -525,6 +532,27 @@ nxt_unit_init(nxt_unit_init_t *init)
goto fail;
}
+ nxt_unit_port_id_init(&shared_port.id, read_port.id.pid,
+ NXT_UNIT_SHARED_PORT_ID);
+
+ mem = mmap(NULL, sizeof(nxt_app_queue_t), PROT_READ | PROT_WRITE,
+ MAP_SHARED, shared_queue_fd, 0);
+ if (nxt_slow_path(mem == MAP_FAILED)) {
+ nxt_unit_alert(ctx, "mmap(%d) failed: %s (%d)", shared_queue_fd,
+ strerror(errno), errno);
+
+ goto fail;
+ }
+
+ nxt_unit_close(shared_queue_fd);
+
+ lib->shared_port = nxt_unit_add_port(ctx, &shared_port, mem);
+ if (nxt_slow_path(lib->shared_port == NULL)) {
+ nxt_unit_alert(NULL, "failed to add shared_port");
+
+ goto fail;
+ }
+
rc = nxt_unit_ready(ctx, ready_port.out_fd, ready_stream, queue_fd);
if (nxt_slow_path(rc != NXT_UNIT_OK)) {
nxt_unit_alert(NULL, "failed to send READY message");
@@ -799,7 +827,8 @@ nxt_unit_mmap_buf_unlink(nxt_unit_mmap_buf_t *mmap_buf)
static int
nxt_unit_read_env(nxt_unit_port_t *ready_port, nxt_unit_port_t *router_port,
- nxt_unit_port_t *read_port, int *log_fd, uint32_t *stream,
+ nxt_unit_port_t *read_port, int *shared_port_fd, int *shared_queue_fd,
+ int *log_fd, uint32_t *stream,
uint32_t *shm_limit, uint32_t *request_limit)
{
int rc;
@@ -845,11 +874,13 @@ nxt_unit_read_env(nxt_unit_port_t *ready_port, nxt_unit_port_t *router_port,
"%"PRId64",%"PRIu32",%d;"
"%"PRId64",%"PRIu32",%d;"
"%"PRId64",%"PRIu32",%d,%d;"
+ "%d,%d;"
"%d,%"PRIu32",%"PRIu32,
&ready_stream,
&ready_pid, &ready_id, &ready_fd,
&router_pid, &router_id, &router_fd,
&read_pid, &read_id, &read_in_fd, &read_out_fd,
+ shared_port_fd, shared_queue_fd,
log_fd, shm_limit, request_limit);
if (nxt_slow_path(rc == EOF)) {
@@ -859,9 +890,9 @@ nxt_unit_read_env(nxt_unit_port_t *ready_port, nxt_unit_port_t *router_port,
return NXT_UNIT_ERROR;
}
- if (nxt_slow_path(rc != 14)) {
+ if (nxt_slow_path(rc != 16)) {
nxt_unit_alert(NULL, "invalid number of variables in %s env: "
- "found %d of %d in %s", NXT_UNIT_INIT_ENV, rc, 14, vars);
+ "found %d of %d in %s", NXT_UNIT_INIT_ENV, rc, 16, vars);
return NXT_UNIT_ERROR;
}
@@ -1137,7 +1168,6 @@ static int
nxt_unit_process_new_port(nxt_unit_ctx_t *ctx, nxt_unit_recv_msg_t *recv_msg)
{
void *mem;
- nxt_unit_impl_t *lib;
nxt_unit_port_t new_port, *port;
nxt_port_msg_new_port_t *new_port_msg;
@@ -1162,33 +1192,17 @@ nxt_unit_process_new_port(nxt_unit_ctx_t *ctx, nxt_unit_recv_msg_t *recv_msg)
recv_msg->stream, (int) new_port_msg->pid,
(int) new_port_msg->id, recv_msg->fd[0], recv_msg->fd[1]);
- lib = nxt_container_of(ctx->unit, nxt_unit_impl_t, unit);
-
- if (new_port_msg->id == NXT_UNIT_SHARED_PORT_ID) {
- nxt_unit_port_id_init(&new_port.id, lib->pid, new_port_msg->id);
-
- new_port.in_fd = recv_msg->fd[0];
- new_port.out_fd = -1;
-
- mem = mmap(NULL, sizeof(nxt_app_queue_t), PROT_READ | PROT_WRITE,
- MAP_SHARED, recv_msg->fd[1], 0);
-
- } else {
- if (nxt_slow_path(nxt_unit_fd_blocking(recv_msg->fd[0])
- != NXT_UNIT_OK))
- {
- return NXT_UNIT_ERROR;
- }
+ if (nxt_slow_path(nxt_unit_fd_blocking(recv_msg->fd[0]) != NXT_UNIT_OK)) {
+ return NXT_UNIT_ERROR;
+ }
- nxt_unit_port_id_init(&new_port.id, new_port_msg->pid,
- new_port_msg->id);
+ nxt_unit_port_id_init(&new_port.id, new_port_msg->pid, new_port_msg->id);
- new_port.in_fd = -1;
- new_port.out_fd = recv_msg->fd[0];
+ new_port.in_fd = -1;
+ new_port.out_fd = recv_msg->fd[0];
- mem = mmap(NULL, sizeof(nxt_port_queue_t), PROT_READ | PROT_WRITE,
- MAP_SHARED, recv_msg->fd[1], 0);
- }
+ mem = mmap(NULL, sizeof(nxt_port_queue_t), PROT_READ | PROT_WRITE,
+ MAP_SHARED, recv_msg->fd[1], 0);
if (nxt_slow_path(mem == MAP_FAILED)) {
nxt_unit_alert(ctx, "mmap(%d) failed: %s (%d)", recv_msg->fd[1],
@@ -1206,12 +1220,6 @@ nxt_unit_process_new_port(nxt_unit_ctx_t *ctx, nxt_unit_recv_msg_t *recv_msg)
return NXT_UNIT_ERROR;
}
- if (new_port_msg->id == NXT_UNIT_SHARED_PORT_ID) {
- lib->shared_port = port;
-
- return nxt_unit_ctx_ready(ctx);
- }
-
nxt_unit_port_release(port);
return NXT_UNIT_OK;
@@ -5106,9 +5114,9 @@ nxt_unit_ctx_alloc(nxt_unit_ctx_t *ctx, void *data)
rc = nxt_unit_ctx_init(lib, new_ctx, data);
if (nxt_slow_path(rc != NXT_UNIT_OK)) {
- nxt_unit_free(ctx, new_ctx);
+ nxt_unit_free(ctx, new_ctx);
- return NULL;
+ return NULL;
}
queue_fd = -1;
diff --git a/src/nxt_unit.h b/src/nxt_unit.h
index 1b5280af..35f9fa55 100644
--- a/src/nxt_unit.h
+++ b/src/nxt_unit.h
@@ -176,6 +176,8 @@ struct nxt_unit_init_s {
uint32_t ready_stream;
nxt_unit_port_t router_port;
nxt_unit_port_t read_port;
+ int shared_port_fd;
+ int shared_queue_fd;
int log_fd;
};
diff --git a/src/nxt_unix.h b/src/nxt_unix.h
index 393f61d9..d8eaabc3 100644
--- a/src/nxt_unix.h
+++ b/src/nxt_unix.h
@@ -275,23 +275,19 @@
typedef struct iovec nxt_iobuf_t;
-#define \
-nxt_iobuf_data(iob) \
+#define nxt_iobuf_data(iob) \
(iob)->iov_base
-#define \
-nxt_iobuf_size(iob) \
+#define nxt_iobuf_size(iob) \
(iob)->iov_len
-#define \
-nxt_iobuf_set(iob, p, size) \
+#define nxt_iobuf_set(iob, p, size) \
do { \
(iob)->iov_base = (void *) p; \
(iob)->iov_len = size; \
} while (0)
-#define \
-nxt_iobuf_add(iob, size) \
+#define nxt_iobuf_add(iob, size) \
(iob)->iov_len += size
diff --git a/src/nxt_var.c b/src/nxt_var.c
index 60650ef4..0a722d17 100644
--- a/src/nxt_var.c
+++ b/src/nxt_var.c
@@ -627,7 +627,8 @@ nxt_var_query_finish(nxt_task_t *task, nxt_var_query_t *query)
nxt_array_reset(&query->parts);
- nxt_debug(task, "var: \"%*s\" -> \"%V\"", length, src, val[i].value);
+ nxt_debug(task, "var: \"%*s\" -> \"%V\"", var->length, src,
+ val[i].value);
}
done:
diff --git a/src/nxt_vector.h b/src/nxt_vector.h
index e8836dbf..dcac53d4 100644
--- a/src/nxt_vector.h
+++ b/src/nxt_vector.h
@@ -41,19 +41,16 @@ NXT_EXPORT void *nxt_vector_zero_add(nxt_vector_t *vector,
NXT_EXPORT void nxt_vector_remove(nxt_vector_t *vector, void *item);
-#define \
-nxt_vector_last(vector) \
+#define nxt_vector_last(vector) \
nxt_pointer_to((vector)->start, \
(vector)->item_size * ((vector)->items - 1))
-#define \
-nxt_vector_reset(vector) \
+#define nxt_vector_reset(vector) \
(vector)->items = 0;
-#define \
-nxt_vector_is_empty(vector) \
+#define nxt_vector_is_empty(vector) \
((vector)->items == 0)
diff --git a/src/nxt_work_queue.h b/src/nxt_work_queue.h
index 6c2d6c23..b6aa4d4c 100644
--- a/src/nxt_work_queue.h
+++ b/src/nxt_work_queue.h
@@ -16,12 +16,12 @@ struct nxt_task_s {
uint32_t ident;
nxt_work_t *next_work;
- /* TODO: exception_handler, prev/next task, subtasks. */
+ /* TODO: exception_handler, prev/next task, subtasks. */
};
#define nxt_task_next_ident() \
- ((uint32_t) nxt_atomic_fetch_add(&nxt_task_ident, 1) & 0x3FFFFFFF)
+ ((uint32_t) nxt_atomic_fetch_add(&nxt_task_ident, 1) & 0x3FFFFFFF)
/*
@@ -109,8 +109,7 @@ NXT_EXPORT void nxt_work_queue_thread_adopt(nxt_work_queue_t *wq);
#else
-#define \
-nxt_work_queue_name(_wq, _name)
+#define nxt_work_queue_name(_wq, _name)
#define nxt_work_queue_thread_adopt(_wq)
diff --git a/src/perl/nxt_perl_psgi.c b/src/perl/nxt_perl_psgi.c
index 02555c96..08a6f29e 100644
--- a/src/perl/nxt_perl_psgi.c
+++ b/src/perl/nxt_perl_psgi.c
@@ -28,19 +28,15 @@ typedef struct {
} nxt_perl_psgi_ctx_t;
-static long nxt_perl_psgi_io_input_read(PerlInterpreter *my_perl,
+static SSize_t nxt_perl_psgi_io_input_read(PerlInterpreter *my_perl,
nxt_perl_psgi_io_arg_t *arg, void *vbuf, size_t length);
-static long nxt_perl_psgi_io_input_write(PerlInterpreter *my_perl,
+static SSize_t nxt_perl_psgi_io_input_write(PerlInterpreter *my_perl,
nxt_perl_psgi_io_arg_t *arg, const void *vbuf, size_t length);
-static long nxt_perl_psgi_io_input_flush(PerlInterpreter *my_perl,
- nxt_perl_psgi_io_arg_t *arg);
-static long nxt_perl_psgi_io_error_read(PerlInterpreter *my_perl,
+static SSize_t nxt_perl_psgi_io_error_read(PerlInterpreter *my_perl,
nxt_perl_psgi_io_arg_t *arg, void *vbuf, size_t length);
-static long nxt_perl_psgi_io_error_write(PerlInterpreter *my_perl,
+static SSize_t nxt_perl_psgi_io_error_write(PerlInterpreter *my_perl,
nxt_perl_psgi_io_arg_t *arg, const void *vbuf, size_t length);
-static long nxt_perl_psgi_io_error_flush(PerlInterpreter *my_perl,
- nxt_perl_psgi_io_arg_t *arg);
/*
static void nxt_perl_psgi_xs_core_global_changes(PerlInterpreter *my_perl,
@@ -57,10 +53,8 @@ static SV *nxt_perl_psgi_call_method(PerlInterpreter *my_perl, SV *obj,
/* For currect load XS modules */
EXTERN_C void boot_DynaLoader(pTHX_ CV *cv);
-static nxt_int_t nxt_perl_psgi_io_input_init(PerlInterpreter *my_perl,
- nxt_perl_psgi_io_arg_t *arg);
-static nxt_int_t nxt_perl_psgi_io_error_init(PerlInterpreter *my_perl,
- nxt_perl_psgi_io_arg_t *arg);
+static int nxt_perl_psgi_io_init(PerlInterpreter *my_perl,
+ nxt_perl_psgi_io_arg_t *arg, const char *mode, void *req);
static int nxt_perl_psgi_ctx_init(const char *script,
nxt_perl_psgi_ctx_t *pctx);
@@ -125,20 +119,26 @@ NXT_EXPORT nxt_app_module_t nxt_app_module = {
nxt_perl_psgi_start,
};
+const nxt_perl_psgi_io_tab_t nxt_perl_psgi_io_tab_input = {
+ .read = nxt_perl_psgi_io_input_read,
+ .write = nxt_perl_psgi_io_input_write,
+};
+
+const nxt_perl_psgi_io_tab_t nxt_perl_psgi_io_tab_error = {
+ .read = nxt_perl_psgi_io_error_read,
+ .write = nxt_perl_psgi_io_error_write,
+};
-static long
+
+static SSize_t
nxt_perl_psgi_io_input_read(PerlInterpreter *my_perl,
nxt_perl_psgi_io_arg_t *arg, void *vbuf, size_t length)
{
- nxt_perl_psgi_ctx_t *pctx;
-
- pctx = arg->pctx;
-
- return nxt_unit_request_read(pctx->req, vbuf, length);
+ return nxt_unit_request_read(arg->req, vbuf, length);
}
-static long
+static SSize_t
nxt_perl_psgi_io_input_write(PerlInterpreter *my_perl,
nxt_perl_psgi_io_arg_t *arg, const void *vbuf, size_t length)
{
@@ -146,15 +146,7 @@ nxt_perl_psgi_io_input_write(PerlInterpreter *my_perl,
}
-static long
-nxt_perl_psgi_io_input_flush(PerlInterpreter *my_perl,
- nxt_perl_psgi_io_arg_t *arg)
-{
- return 0;
-}
-
-
-static long
+static SSize_t
nxt_perl_psgi_io_error_read(PerlInterpreter *my_perl,
nxt_perl_psgi_io_arg_t *arg, void *vbuf, size_t length)
{
@@ -162,25 +154,13 @@ nxt_perl_psgi_io_error_read(PerlInterpreter *my_perl,
}
-static long
+static SSize_t
nxt_perl_psgi_io_error_write(PerlInterpreter *my_perl,
nxt_perl_psgi_io_arg_t *arg, const void *vbuf, size_t length)
{
- nxt_perl_psgi_ctx_t *pctx;
-
- pctx = arg->pctx;
-
- nxt_unit_req_error(pctx->req, "Perl: %s", (const char*) vbuf);
-
- return (long) length;
-}
-
+ nxt_unit_req_error(arg->req, "Perl: %s", (const char*) vbuf);
-static long
-nxt_perl_psgi_io_error_flush(PerlInterpreter *my_perl,
- nxt_perl_psgi_io_arg_t *arg)
-{
- return 0;
+ return (SSize_t) length;
}
@@ -461,70 +441,49 @@ nxt_perl_psgi_module_create(const char *script)
}
-static nxt_int_t
-nxt_perl_psgi_io_input_init(PerlInterpreter *my_perl,
- nxt_perl_psgi_io_arg_t *arg)
+static int
+nxt_perl_psgi_io_init(PerlInterpreter *my_perl,
+ nxt_perl_psgi_io_arg_t *arg, const char *mode, void *req)
{
SV *io;
PerlIO *fp;
- fp = nxt_perl_psgi_layer_stream_fp_create(aTHX_ arg, "r");
-
- if (nxt_slow_path(fp == NULL)) {
- return NXT_ERROR;
- }
+ if (arg->io == NULL) {
+ fp = nxt_perl_psgi_layer_stream_fp_create(aTHX_ arg->rv, mode);
+ if (nxt_slow_path(fp == NULL)) {
+ return NXT_UNIT_ERROR;
+ }
- io = nxt_perl_psgi_layer_stream_io_create(aTHX_ fp);
+ io = nxt_perl_psgi_layer_stream_io_create(aTHX_ fp);
+ if (nxt_slow_path(io == NULL)) {
+ nxt_perl_psgi_layer_stream_fp_destroy(aTHX_ fp);
+ return NXT_UNIT_ERROR;
+ }
- if (nxt_slow_path(io == NULL)) {
- nxt_perl_psgi_layer_stream_fp_destroy(aTHX_ fp);
- return NXT_ERROR;
+ arg->io = io;
+ arg->fp = fp;
}
- arg->io = io;
- arg->fp = fp;
- arg->flush = nxt_perl_psgi_io_input_flush;
- arg->read = nxt_perl_psgi_io_input_read;
- arg->write = nxt_perl_psgi_io_input_write;
+ arg->req = req;
- return NXT_OK;
+ return NXT_UNIT_OK;
}
-static nxt_int_t
-nxt_perl_psgi_io_error_init(PerlInterpreter *my_perl,
- nxt_perl_psgi_io_arg_t *arg)
+static void
+nxt_perl_psgi_io_release(PerlInterpreter *my_perl, nxt_perl_psgi_io_arg_t *arg)
{
- SV *io;
- PerlIO *fp;
-
- fp = nxt_perl_psgi_layer_stream_fp_create(aTHX_ arg, "w");
-
- if (nxt_slow_path(fp == NULL)) {
- return NXT_ERROR;
+ if (arg->io != NULL) {
+ SvREFCNT_dec(arg->io);
+ arg->io = NULL;
}
-
- io = nxt_perl_psgi_layer_stream_io_create(aTHX_ fp);
-
- if (nxt_slow_path(io == NULL)) {
- nxt_perl_psgi_layer_stream_fp_destroy(aTHX_ fp);
- return NXT_ERROR;
- }
-
- arg->io = io;
- arg->fp = fp;
- arg->flush = nxt_perl_psgi_io_error_flush;
- arg->read = nxt_perl_psgi_io_error_read;
- arg->write = nxt_perl_psgi_io_error_write;
-
- return NXT_OK;
}
static int
nxt_perl_psgi_ctx_init(const char *script, nxt_perl_psgi_ctx_t *pctx)
{
- int status;
+ int status, res;
char *run_module;
PerlInterpreter *my_perl;
@@ -577,19 +536,27 @@ nxt_perl_psgi_ctx_init(const char *script, nxt_perl_psgi_ctx_t *pctx)
goto fail;
}
- pctx->arg_input.pctx = pctx;
+ pctx->arg_input.rv = newSV_type(SVt_RV);
+ sv_setptrref(pctx->arg_input.rv, &pctx->arg_input);
+ SvSETMAGIC(pctx->arg_input.rv);
- status = nxt_perl_psgi_io_input_init(my_perl, &pctx->arg_input);
- if (nxt_slow_path(status != NXT_OK)) {
+ pctx->arg_input.io_tab = &nxt_perl_psgi_io_tab_input;
+
+ res = nxt_perl_psgi_io_init(my_perl, &pctx->arg_input, "r", NULL);
+ if (nxt_slow_path(res != NXT_UNIT_OK)) {
nxt_unit_alert(NULL, "PSGI: Failed to init io.psgi.input");
goto fail;
}
- pctx->arg_error.pctx = pctx;
+ pctx->arg_error.rv = newSV_type(SVt_RV);
+ sv_setptrref(pctx->arg_error.rv, &pctx->arg_error);
+ SvSETMAGIC(pctx->arg_error.rv);
+
+ pctx->arg_error.io_tab = &nxt_perl_psgi_io_tab_error;
- status = nxt_perl_psgi_io_error_init(my_perl, &pctx->arg_error);
- if (nxt_slow_path(status != NXT_OK)) {
- nxt_unit_alert(NULL, "PSGI: Failed to init io.psgi.errors");
+ res = nxt_perl_psgi_io_init(my_perl, &pctx->arg_error, "w", NULL);
+ if (nxt_slow_path(res != NXT_UNIT_OK)) {
+ nxt_unit_alert(NULL, "PSGI: Failed to init io.psgi.error");
goto fail;
}
@@ -607,6 +574,9 @@ nxt_perl_psgi_ctx_init(const char *script, nxt_perl_psgi_ctx_t *pctx)
fail:
+ nxt_perl_psgi_io_release(my_perl, &pctx->arg_input);
+ nxt_perl_psgi_io_release(my_perl, &pctx->arg_error);
+
if (run_module != NULL) {
nxt_unit_free(NULL, run_module);
}
@@ -614,6 +584,8 @@ fail:
perl_destruct(my_perl);
perl_free(my_perl);
+ pctx->my_perl = NULL;
+
return NXT_UNIT_ERROR;
}
@@ -640,7 +612,7 @@ nxt_perl_psgi_env_create(PerlInterpreter *my_perl,
do { \
if (nxt_slow_path((FNS) != NXT_UNIT_OK)) \
goto fail; \
- } while (0)
+ } while (0)
#define NL(S) (S), sizeof(S)-1
@@ -672,21 +644,25 @@ nxt_perl_psgi_env_create(PerlInterpreter *my_perl,
r->tls ? newSVpv("https", 5)
: newSVpv("http", 4)));
+ RC(nxt_perl_psgi_io_init(my_perl, &pctx->arg_input, "r", req));
RC(nxt_perl_psgi_add_value(my_perl, hash_env, NL("psgi.input"),
- SvREFCNT_inc(pctx->arg_input.io)));
+ SvREFCNT_inc(pctx->arg_input.io)));
+
+ RC(nxt_perl_psgi_io_init(my_perl, &pctx->arg_error, "w", req));
RC(nxt_perl_psgi_add_value(my_perl, hash_env, NL("psgi.errors"),
- SvREFCNT_inc(pctx->arg_error.io)));
+ SvREFCNT_inc(pctx->arg_error.io)));
+
RC(nxt_perl_psgi_add_value(my_perl, hash_env, NL("psgi.multithread"),
- nxt_perl_psgi_ctxs != NULL
- ? &PL_sv_yes : &PL_sv_no));
+ nxt_perl_psgi_ctxs != NULL
+ ? &PL_sv_yes : &PL_sv_no));
RC(nxt_perl_psgi_add_value(my_perl, hash_env, NL("psgi.multiprocess"),
- &PL_sv_yes));
+ &PL_sv_yes));
RC(nxt_perl_psgi_add_value(my_perl, hash_env, NL("psgi.run_once"),
- &PL_sv_no));
+ &PL_sv_no));
RC(nxt_perl_psgi_add_value(my_perl, hash_env, NL("psgi.nonblocking"),
- &PL_sv_no));
+ &PL_sv_no));
RC(nxt_perl_psgi_add_value(my_perl, hash_env, NL("psgi.streaming"),
- &PL_sv_yes));
+ &PL_sv_yes));
RC(nxt_perl_psgi_add_sptr(my_perl, hash_env, NL("QUERY_STRING"),
&r->query, r->query_length));
@@ -1447,11 +1423,11 @@ nxt_perl_psgi_ctx_free(nxt_perl_psgi_ctx_t *pctx)
PERL_SET_CONTEXT(my_perl);
- nxt_perl_psgi_layer_stream_io_destroy(aTHX_ pctx->arg_input.io);
- nxt_perl_psgi_layer_stream_fp_destroy(aTHX_ pctx->arg_input.fp);
+ SvREFCNT_dec(pctx->arg_input.rv);
+ SvREFCNT_dec(pctx->arg_error.rv);
- nxt_perl_psgi_layer_stream_io_destroy(aTHX_ pctx->arg_error.io);
- nxt_perl_psgi_layer_stream_fp_destroy(aTHX_ pctx->arg_error.fp);
+ nxt_perl_psgi_io_release(my_perl, &pctx->arg_input);
+ nxt_perl_psgi_io_release(my_perl, &pctx->arg_error);
perl_destruct(my_perl);
perl_free(my_perl);
diff --git a/src/perl/nxt_perl_psgi_layer.c b/src/perl/nxt_perl_psgi_layer.c
index f77453e9..303e5f27 100644
--- a/src/perl/nxt_perl_psgi_layer.c
+++ b/src/perl/nxt_perl_psgi_layer.c
@@ -93,11 +93,9 @@ nxt_perl_psgi_layer_stream_pushed(pTHX_ PerlIO *f, const char *mode, SV *arg,
unit_stream = PerlIOSelf(f, nxt_perl_psgi_layer_stream_t);
if (arg != NULL && SvOK(arg)) {
- unit_stream->var = arg;
+ unit_stream->var = SvREFCNT_inc(arg);
}
- SvSETMAGIC(unit_stream->var);
-
return PerlIOBase_pushed(aTHX_ f, mode, Nullsv, tab);
}
@@ -105,11 +103,17 @@ nxt_perl_psgi_layer_stream_pushed(pTHX_ PerlIO *f, const char *mode, SV *arg,
static IV
nxt_perl_psgi_layer_stream_popped(pTHX_ PerlIO *f)
{
+ nxt_perl_psgi_io_arg_t *arg;
nxt_perl_psgi_layer_stream_t *unit_stream;
unit_stream = PerlIOSelf(f, nxt_perl_psgi_layer_stream_t);
if (unit_stream->var != NULL) {
+ arg = (void *) (intptr_t) SvIV(SvRV(unit_stream->var));
+
+ arg->io = NULL;
+ arg->fp = NULL;
+
SvREFCNT_dec(unit_stream->var);
unit_stream->var = Nullsv;
}
@@ -181,9 +185,6 @@ nxt_perl_psgi_layer_stream_read(pTHX_ PerlIO *f, void *vbuf, Size_t count)
return 0;
}
- unit_stream = PerlIOSelf(f, nxt_perl_psgi_layer_stream_t);
- arg = (nxt_perl_psgi_io_arg_t *) (intptr_t) SvIV(SvRV(unit_stream->var));
-
if ((PerlIOBase(f)->flags & PERLIO_F_CANREAD) == 0) {
PerlIOBase(f)->flags |= PERLIO_F_ERROR;
@@ -192,7 +193,10 @@ nxt_perl_psgi_layer_stream_read(pTHX_ PerlIO *f, void *vbuf, Size_t count)
return 0;
}
- return (SSize_t) arg->read(PERL_GET_CONTEXT, arg, vbuf, count);
+ unit_stream = PerlIOSelf(f, nxt_perl_psgi_layer_stream_t);
+ arg = (void *) (intptr_t) SvIV(SvRV(unit_stream->var));
+
+ return arg->io_tab->read(PERL_GET_CONTEXT, arg, vbuf, count);
}
@@ -204,13 +208,10 @@ nxt_perl_psgi_layer_stream_write(pTHX_ PerlIO *f,
nxt_perl_psgi_layer_stream_t *unit_stream;
if (PerlIOBase(f)->flags & PERLIO_F_CANWRITE) {
-
unit_stream = PerlIOSelf(f, nxt_perl_psgi_layer_stream_t);
+ arg = (void *) (intptr_t) SvIV(SvRV(unit_stream->var));
- arg = (nxt_perl_psgi_io_arg_t *)
- (intptr_t) SvIV(SvRV(unit_stream->var));
-
- return (SSize_t) arg->write(PERL_GET_CONTEXT, arg, vbuf, count);
+ return arg->io_tab->write(PERL_GET_CONTEXT, arg, vbuf, count);
}
return 0;
@@ -244,13 +245,7 @@ nxt_perl_psgi_layer_stream_fill(pTHX_ PerlIO *f)
static IV
nxt_perl_psgi_layer_stream_flush(pTHX_ PerlIO *f)
{
- nxt_perl_psgi_io_arg_t *arg;
- nxt_perl_psgi_layer_stream_t *unit_stream;
-
- unit_stream = PerlIOSelf(f, nxt_perl_psgi_layer_stream_t);
- arg = (nxt_perl_psgi_io_arg_t *) (intptr_t) SvIV(SvRV(unit_stream->var));
-
- return (IV) arg->flush(PERL_GET_CONTEXT, arg);
+ return 0;
}
@@ -346,29 +341,11 @@ nxt_perl_psgi_layer_stream_init(pTHX)
PerlIO *
-nxt_perl_psgi_layer_stream_fp_create(pTHX_ nxt_perl_psgi_io_arg_t *arg,
+nxt_perl_psgi_layer_stream_fp_create(pTHX_ SV *arg_rv,
const char *mode)
{
- SV *arg_rv;
- PerlIO *fp;
-
- arg_rv = newSV_type(SVt_RV);
-
- if (arg_rv == NULL) {
- return NULL;
- }
-
- sv_setptrref(arg_rv, arg);
-
- fp = PerlIO_openn(aTHX_ "NGINX_Unit_PSGI_Layer_Stream",
- mode, 0, 0, 0, NULL, 1, &arg_rv);
-
- if (fp == NULL) {
- SvREFCNT_dec(arg_rv);
- return NULL;
- }
-
- return fp;
+ return PerlIO_openn(aTHX_ "NGINX_Unit_PSGI_Layer_Stream",
+ mode, 0, 0, 0, NULL, 1, &arg_rv);
}
@@ -403,10 +380,3 @@ nxt_perl_psgi_layer_stream_io_create(pTHX_ PerlIO *fp)
return rvio;
}
-
-
-void
-nxt_perl_psgi_layer_stream_io_destroy(pTHX_ SV *rvio)
-{
- SvREFCNT_dec(rvio);
-}
diff --git a/src/perl/nxt_perl_psgi_layer.h b/src/perl/nxt_perl_psgi_layer.h
index af18ad0d..0972d66f 100644
--- a/src/perl/nxt_perl_psgi_layer.h
+++ b/src/perl/nxt_perl_psgi_layer.h
@@ -14,35 +14,35 @@
#include <perliol.h>
+typedef struct nxt_perl_psgi_io_tab_s nxt_perl_psgi_io_tab_t;
typedef struct nxt_perl_psgi_io_arg_s nxt_perl_psgi_io_arg_t;
-typedef long (*nxt_perl_psgi_io_read_f)(PerlInterpreter *my_perl,
- nxt_perl_psgi_io_arg_t *arg, void *vbuf, size_t length);
-typedef long (*nxt_perl_psgi_io_write_f)(PerlInterpreter *my_perl,
- nxt_perl_psgi_io_arg_t *arg, const void *vbuf, size_t length);
-typedef long (*nxt_perl_psgi_io_arg_f)(PerlInterpreter *my_perl,
- nxt_perl_psgi_io_arg_t *arg);
+
+struct nxt_perl_psgi_io_tab_s {
+ SSize_t (*read)(PerlInterpreter *my_perl,
+ nxt_perl_psgi_io_arg_t *arg, void *vbuf, size_t length);
+ SSize_t (*write)(PerlInterpreter *my_perl,
+ nxt_perl_psgi_io_arg_t *arg, const void *vbuf, size_t length);
+};
struct nxt_perl_psgi_io_arg_s {
- SV *io;
- PerlIO *fp;
+ SV *rv;
+ SV *io;
+ PerlIO *fp;
- nxt_perl_psgi_io_arg_f flush;
- nxt_perl_psgi_io_read_f read;
- nxt_perl_psgi_io_write_f write;
+ const nxt_perl_psgi_io_tab_t *io_tab;
- void *pctx;
+ void *req;
};
void nxt_perl_psgi_layer_stream_init(pTHX);
-PerlIO *nxt_perl_psgi_layer_stream_fp_create(pTHX_ nxt_perl_psgi_io_arg_t *arg,
+PerlIO *nxt_perl_psgi_layer_stream_fp_create(pTHX_ SV *arg_rv,
const char *mode);
void nxt_perl_psgi_layer_stream_fp_destroy(pTHX_ PerlIO *io);
SV *nxt_perl_psgi_layer_stream_io_create(pTHX_ PerlIO *fp);
-void nxt_perl_psgi_layer_stream_io_destroy(pTHX_ SV *rvio);
#endif /* _NXT_PERL_PSGI_LAYER_H_INCLUDED_ */
diff --git a/src/python/nxt_python.c b/src/python/nxt_python.c
index 8687c869..188c4920 100644
--- a/src/python/nxt_python.c
+++ b/src/python/nxt_python.c
@@ -411,15 +411,8 @@ nxt_python_set_path(nxt_task_t *task, nxt_conf_value_t *value)
/* sys is a Borrowed reference. */
- if (nxt_conf_type(value) == NXT_CONF_STRING) {
- n = 0;
- goto value_is_string;
- }
-
- /* NXT_CONF_ARRAY */
array = value;
-
- n = nxt_conf_array_elements_count(array);
+ n = nxt_conf_array_elements_count_or_1(array);
while (n != 0) {
n--;
@@ -430,9 +423,7 @@ nxt_python_set_path(nxt_task_t *task, nxt_conf_value_t *value)
* specified in the "path" option.
*/
- value = nxt_conf_get_array_element(array, n);
-
- value_is_string:
+ value = nxt_conf_get_array_element_or_itself(array, n);
nxt_conf_get_string(value, &str);
diff --git a/src/python/nxt_python_asgi.c b/src/python/nxt_python_asgi.c
index 354e3a81..91af8f4b 100644
--- a/src/python/nxt_python_asgi.c
+++ b/src/python/nxt_python_asgi.c
@@ -117,15 +117,20 @@ nxt_python_asgi_get_func(PyObject *obj)
if (PyMethod_Check(call)) {
obj = PyMethod_GET_FUNCTION(call);
- Py_INCREF(obj);
- Py_DECREF(call);
+ if (PyFunction_Check(obj)) {
+ Py_INCREF(obj);
- return obj;
+ } else {
+ obj = NULL;
+ }
+
+ } else {
+ obj = NULL;
}
Py_DECREF(call);
- return NULL;
+ return obj;
}
@@ -161,8 +166,10 @@ nxt_python_asgi_init(nxt_unit_init_t *init, nxt_python_proto_t *proto)
for (i = 0; i < nxt_py_targets->count; i++) {
func = nxt_python_asgi_get_func(nxt_py_targets->target[i].application);
if (nxt_slow_path(func == NULL)) {
- nxt_unit_alert(NULL, "Python cannot find function for callable");
- return NXT_UNIT_ERROR;
+ nxt_unit_debug(NULL, "asgi: cannot find function for callable, "
+ "unable to check for legacy mode (#%d)",
+ (int) i);
+ continue;
}
code = (PyCodeObject *) PyFunction_GET_CODE(func);
diff --git a/src/ruby/nxt_ruby.c b/src/ruby/nxt_ruby.c
index 62498127..8f4afd35 100644
--- a/src/ruby/nxt_ruby.c
+++ b/src/ruby/nxt_ruby.c
@@ -29,6 +29,7 @@ typedef struct {
static nxt_int_t nxt_ruby_start(nxt_task_t *task,
nxt_process_data_t *data);
static VALUE nxt_ruby_init_basic(VALUE arg);
+static VALUE nxt_ruby_script_basename(nxt_str_t *script);
static VALUE nxt_ruby_hook_procs_load(VALUE path);
static VALUE nxt_ruby_hook_register(VALUE arg);
@@ -49,7 +50,7 @@ static void *nxt_ruby_thread_create_gvl(void *rctx);
static VALUE nxt_ruby_thread_func(VALUE arg);
static void *nxt_ruby_unit_run(void *ctx);
static void nxt_ruby_ubf(void *ctx);
-static int nxt_ruby_init_threads(nxt_ruby_app_conf_t *c);
+static int nxt_ruby_init_threads(VALUE script, nxt_ruby_app_conf_t *c);
static void nxt_ruby_join_threads(nxt_unit_ctx_t *ctx,
nxt_ruby_app_conf_t *c);
@@ -260,7 +261,7 @@ static nxt_int_t
nxt_ruby_start(nxt_task_t *task, nxt_process_data_t *data)
{
int state, rc;
- VALUE res, path;
+ VALUE res, path, script;
nxt_ruby_ctx_t ruby_ctx;
nxt_unit_ctx_t *unit_ctx;
nxt_unit_init_t ruby_unit_init;
@@ -282,7 +283,10 @@ nxt_ruby_start(nxt_task_t *task, nxt_process_data_t *data)
ruby_options(2, argv);
ruby_script("NGINX_Unit");
+ script = nxt_ruby_script_basename(&c->script);
+
ruby_ctx.env = Qnil;
+ ruby_ctx.script = script;
ruby_ctx.io_input = Qnil;
ruby_ctx.io_error = Qnil;
ruby_ctx.thread = Qnil;
@@ -352,7 +356,7 @@ nxt_ruby_start(nxt_task_t *task, nxt_process_data_t *data)
goto fail;
}
- rc = nxt_ruby_init_threads(c);
+ rc = nxt_ruby_init_threads(script, c);
if (nxt_slow_path(rc == NXT_UNIT_ERROR)) {
goto fail;
}
@@ -421,6 +425,37 @@ fail:
static VALUE
+nxt_ruby_script_basename(nxt_str_t *script)
+{
+ size_t len;
+ u_char *p, *last;
+
+ last = NULL;
+ p = script->start + script->length;
+
+ while (p > script->start) {
+
+ if (p[-1] == '/') {
+ last = p;
+ break;
+ }
+
+ p--;
+ }
+
+ if (last != NULL) {
+ len = script->length - (last - script->start);
+
+ } else {
+ last = script->start;
+ len = script->length;
+ }
+
+ return rb_str_new((const char *) last, len);
+}
+
+
+static VALUE
nxt_ruby_init_basic(VALUE arg)
{
int state;
@@ -563,6 +598,7 @@ nxt_ruby_rack_env_create(VALUE arg)
rb_ary_push(version, UINT2NUM(NXT_RUBY_RACK_API_VERSION_MAJOR));
rb_ary_push(version, UINT2NUM(NXT_RUBY_RACK_API_VERSION_MINOR));
+ rb_hash_aset(hash_env, rb_str_new2("SCRIPT_NAME"), rctx->script);
rb_hash_aset(hash_env, rb_str_new2("rack.version"), version);
rb_hash_aset(hash_env, rb_str_new2("rack.input"), rctx->io_input);
rb_hash_aset(hash_env, rb_str_new2("rack.errors"), rctx->io_error);
@@ -1357,7 +1393,7 @@ nxt_ruby_ubf(void *ctx)
static int
-nxt_ruby_init_threads(nxt_ruby_app_conf_t *c)
+nxt_ruby_init_threads(VALUE script, nxt_ruby_app_conf_t *c)
{
int state;
uint32_t i;
@@ -1379,6 +1415,7 @@ nxt_ruby_init_threads(nxt_ruby_app_conf_t *c)
rctx = &nxt_ruby_ctxs[i];
rctx->env = Qnil;
+ rctx->script = script;
rctx->io_input = Qnil;
rctx->io_error = Qnil;
rctx->thread = Qnil;
diff --git a/src/ruby/nxt_ruby.h b/src/ruby/nxt_ruby.h
index 26430021..3bdd567a 100644
--- a/src/ruby/nxt_ruby.h
+++ b/src/ruby/nxt_ruby.h
@@ -22,6 +22,7 @@
typedef struct {
VALUE env;
+ VALUE script;
VALUE io_input;
VALUE io_error;
VALUE thread;
diff --git a/src/ruby/nxt_ruby_stream_io.c b/src/ruby/nxt_ruby_stream_io.c
index 82ad3908..4ef69cee 100644
--- a/src/ruby/nxt_ruby_stream_io.c
+++ b/src/ruby/nxt_ruby_stream_io.c
@@ -18,6 +18,7 @@ static VALUE nxt_ruby_stream_io_puts(VALUE obj, VALUE args);
static VALUE nxt_ruby_stream_io_write(VALUE obj, VALUE args);
nxt_inline long nxt_ruby_stream_io_s_write(nxt_ruby_ctx_t *rctx, VALUE val);
static VALUE nxt_ruby_stream_io_flush(VALUE obj);
+static VALUE nxt_ruby_stream_io_close(VALUE obj);
VALUE
@@ -38,6 +39,7 @@ nxt_ruby_stream_io_input_init(void)
rb_define_method(stream_io, "each", nxt_ruby_stream_io_each, 0);
rb_define_method(stream_io, "read", nxt_ruby_stream_io_read, -2);
rb_define_method(stream_io, "rewind", nxt_ruby_stream_io_rewind, 0);
+ rb_define_method(stream_io, "close", nxt_ruby_stream_io_close, 0);
return stream_io;
}
@@ -60,6 +62,7 @@ nxt_ruby_stream_io_error_init(void)
rb_define_method(stream_io, "puts", nxt_ruby_stream_io_puts, -2);
rb_define_method(stream_io, "write", nxt_ruby_stream_io_write, -2);
rb_define_method(stream_io, "flush", nxt_ruby_stream_io_flush, 0);
+ rb_define_method(stream_io, "close", nxt_ruby_stream_io_close, 0);
return stream_io;
}
@@ -257,3 +260,10 @@ nxt_ruby_stream_io_flush(VALUE obj)
{
return Qnil;
}
+
+
+static VALUE
+nxt_ruby_stream_io_close(VALUE obj)
+{
+ return Qnil;
+}
diff --git a/src/test/nxt_rbtree1_test.c b/src/test/nxt_rbtree1_test.c
index d4783ea1..1f23998c 100644
--- a/src/test/nxt_rbtree1_test.c
+++ b/src/test/nxt_rbtree1_test.c
@@ -9,13 +9,11 @@
#include "nxt_rbtree1.h"
-#define \
-nxt_rbtree1_is_empty(tree) \
+#define nxt_rbtree1_is_empty(tree) \
(((tree)->root) == (tree)->sentinel)
-#define \
-nxt_rbtree1_is_there_successor(tree, node) \
+#define nxt_rbtree1_is_there_successor(tree, node) \
((node) != (tree)->sentinel)