From igor at sysoev.ru Wed Jun 1 12:50:18 2016 From: igor at sysoev.ru (Igor Sysoev) Date: Wed, 01 Jun 2016 12:50:18 +0000 Subject: [njs] String.toLowerCase(). Message-ID: details: http://hg.nginx.org/njs/rev/b7442865d9fa branches: changeset: 100:b7442865d9fa user: Igor Sysoev date: Fri Apr 15 18:01:19 2016 +0300 description: String.toLowerCase(). diffstat: njs/njs_string.c | 59 ++ njs/test/njs_unit_test.c | 9 + nxt/Makefile | 1 + nxt/nxt_djb_hash.c | 4 +- nxt/nxt_stub.h | 9 +- nxt/nxt_unicode_lowcase.h | 1043 ----------------------------------------- nxt/nxt_unicode_lowcase.pl | 88 --- nxt/nxt_unicode_lower_case.h | 1043 +++++++++++++++++++++++++++++++++++++++++ nxt/nxt_unicode_lower_case.pl | 92 +++ nxt/nxt_utf8.c | 28 +- nxt/nxt_utf8.h | 3 +- 11 files changed, 1225 insertions(+), 1154 deletions(-) diffs (truncated from 2510 to 1000 lines): diff -r 1c50334fbea6 -r b7442865d9fa njs/njs_string.c --- a/njs/njs_string.c Thu Apr 14 18:23:09 2016 +0300 +++ b/njs/njs_string.c Fri Apr 15 18:01:19 2016 +0300 @@ -1291,6 +1291,58 @@ njs_string_index(njs_string_prop_t *stri } +/* + * String.toLowerCase(). + * The method supports only simple folding. For example, Turkish "?" + * folding "\u0130" to "\u0069\u0307" is not supported. + */ + +static njs_ret_t +njs_string_prototype_to_lower_case(njs_vm_t *vm, njs_value_t *args, + nxt_uint_t nargs, njs_index_t unused) +{ + size_t size; + u_char *p, *start; + const u_char *s, *end; + njs_string_prop_t string; + + (void) njs_string_prop(&string, &args[0]); + + start = njs_string_alloc(vm, &vm->retval, string.size, string.length); + if (nxt_slow_path(start == NULL)) { + return NXT_ERROR; + } + + p = start; + s = string.start; + size = string.size; + + if (string.length == 0 || string.length == size) { + /* Byte or ASCII string. */ + + while (size != 0) { + *p++ = nxt_lower_case(*s++); + size--; + } + + } else { + /* UTF-8 string. */ + end = s + size; + + while (size != 0) { + p = nxt_utf8_encode(p, nxt_utf8_lower_case(&s, end)); + size--; + } + + if (string.length >= NJS_STRING_MAP_OFFSET) { + njs_string_offset_map_init(start, string.size); + } + } + + return NXT_OK; +} + + static njs_ret_t njs_string_prototype_search(njs_vm_t *vm, njs_value_t *args, nxt_uint_t nargs, njs_index_t unused) @@ -1754,6 +1806,13 @@ static const njs_object_prop_t njs_stri { .type = NJS_METHOD, + .name = njs_string("toLowerCase"), + .value = njs_native_function(njs_string_prototype_to_lower_case, 0, + NJS_STRING_OBJECT_ARG, NJS_REGEXP_ARG), + }, + + { + .type = NJS_METHOD, .name = njs_string("search"), .value = njs_native_function(njs_string_prototype_search, 0, NJS_STRING_OBJECT_ARG, NJS_REGEXP_ARG), diff -r 1c50334fbea6 -r b7442865d9fa njs/test/njs_unit_test.c --- a/njs/test/njs_unit_test.c Thu Apr 14 18:23:09 2016 +0300 +++ b/njs/test/njs_unit_test.c Fri Apr 15 18:01:19 2016 +0300 @@ -2745,6 +2745,15 @@ static njs_unit_test_t njs_test[] = { nxt_string("'abc abc abc abc'.lastIndexOf('abc', 0)"), nxt_string("-1") }, + { nxt_string("'ABC'.toLowerCase()"), + nxt_string("abc") }, + + { nxt_string("'???'.toLowerCase()"), + nxt_string("???") }, + + { nxt_string("'???'.toLowerCase()"), + nxt_string("???") }, + { nxt_string("'abcdefgh'.search()"), nxt_string("0") }, diff -r 1c50334fbea6 -r b7442865d9fa nxt/Makefile --- a/nxt/Makefile Thu Apr 14 18:23:09 2016 +0300 +++ b/nxt/Makefile Fri Apr 15 18:01:19 2016 +0300 @@ -47,6 +47,7 @@ NXT_LIB = nxt $(NXT_LIB)/nxt_types.h \ $(NXT_LIB)/nxt_clang.h \ $(NXT_LIB)/nxt_utf8.h \ + $(NXT_LIB)/nxt_unicode_lower_case.h \ $(NXT_LIB)/nxt_utf8.c \ $(NXT_CC) -c -o $(NXT_BUILDDIR)/nxt_utf8.o $(NXT_CFLAGS) \ diff -r 1c50334fbea6 -r b7442865d9fa nxt/nxt_djb_hash.c --- a/nxt/nxt_djb_hash.c Thu Apr 14 18:23:09 2016 +0300 +++ b/nxt/nxt_djb_hash.c Fri Apr 15 18:01:19 2016 +0300 @@ -31,7 +31,6 @@ nxt_djb_hash(const void *data, size_t le uint32_t nxt_djb_hash_lowcase(const void *data, size_t len) { - u_char c; uint32_t hash; const u_char *p; @@ -39,8 +38,7 @@ nxt_djb_hash_lowcase(const void *data, s hash = NXT_DJB_HASH_INIT; while (len != 0) { - c = *p++; - hash = nxt_djb_hash_add(hash, nxt_lowcase(c)); + hash = nxt_djb_hash_add(hash, nxt_lower_case(*p++)); len--; } diff -r 1c50334fbea6 -r b7442865d9fa nxt/nxt_stub.h --- a/nxt/nxt_stub.h Thu Apr 14 18:23:09 2016 +0300 +++ b/nxt/nxt_stub.h Fri Apr 15 18:01:19 2016 +0300 @@ -14,8 +14,13 @@ #define nxt_min(val1, val2) \ ((val1 < val2) ? (val1) : (val2)) -#define nxt_lowcase(c) \ - (u_char) ((c >= 'A' && c <= 'Z') ? c | 0x20 : c) + +nxt_inline u_char +nxt_lower_case(u_char c) +{ + return (u_char) ((c >= 'A' && c <= 'Z') ? c | 0x20 : c); +} + #define nxt_strstr_eq(s1, s2) \ (((s1)->len == (s2)->len) \ diff -r 1c50334fbea6 -r b7442865d9fa nxt/nxt_unicode_lowcase.h --- a/nxt/nxt_unicode_lowcase.h Thu Apr 14 18:23:09 2016 +0300 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,1043 +0,0 @@ - -/* - * 26 128-bytes blocks, 521 pointers. - * 14920 bytes on 32-bit platforms, 17000 bytes on 64-bit platforms. - */ - -#define NXT_UNICODE_MAX_LOWCASE 0x10427 - -#define NXT_UNICODE_BLOCK_SIZE 128 - - -static const uint32_t nxt_unicode_block_000[128] nxt_aligned(64) = { - 0x00000, 0x00001, 0x00002, 0x00003, 0x00004, 0x00005, 0x00006, 0x00007, - 0x00008, 0x00009, 0x0000a, 0x0000b, 0x0000c, 0x0000d, 0x0000e, 0x0000f, - 0x00010, 0x00011, 0x00012, 0x00013, 0x00014, 0x00015, 0x00016, 0x00017, - 0x00018, 0x00019, 0x0001a, 0x0001b, 0x0001c, 0x0001d, 0x0001e, 0x0001f, - 0x00020, 0x00021, 0x00022, 0x00023, 0x00024, 0x00025, 0x00026, 0x00027, - 0x00028, 0x00029, 0x0002a, 0x0002b, 0x0002c, 0x0002d, 0x0002e, 0x0002f, - 0x00030, 0x00031, 0x00032, 0x00033, 0x00034, 0x00035, 0x00036, 0x00037, - 0x00038, 0x00039, 0x0003a, 0x0003b, 0x0003c, 0x0003d, 0x0003e, 0x0003f, - 0x00040, 0x00061, 0x00062, 0x00063, 0x00064, 0x00065, 0x00066, 0x00067, - 0x00068, 0x00069, 0x0006a, 0x0006b, 0x0006c, 0x0006d, 0x0006e, 0x0006f, - 0x00070, 0x00071, 0x00072, 0x00073, 0x00074, 0x00075, 0x00076, 0x00077, - 0x00078, 0x00079, 0x0007a, 0x0005b, 0x0005c, 0x0005d, 0x0005e, 0x0005f, - 0x00060, 0x00061, 0x00062, 0x00063, 0x00064, 0x00065, 0x00066, 0x00067, - 0x00068, 0x00069, 0x0006a, 0x0006b, 0x0006c, 0x0006d, 0x0006e, 0x0006f, - 0x00070, 0x00071, 0x00072, 0x00073, 0x00074, 0x00075, 0x00076, 0x00077, - 0x00078, 0x00079, 0x0007a, 0x0007b, 0x0007c, 0x0007d, 0x0007e, 0x0007f, -}; - - -static const uint32_t nxt_unicode_block_001[128] nxt_aligned(64) = { - 0x00080, 0x00081, 0x00082, 0x00083, 0x00084, 0x00085, 0x00086, 0x00087, - 0x00088, 0x00089, 0x0008a, 0x0008b, 0x0008c, 0x0008d, 0x0008e, 0x0008f, - 0x00090, 0x00091, 0x00092, 0x00093, 0x00094, 0x00095, 0x00096, 0x00097, - 0x00098, 0x00099, 0x0009a, 0x0009b, 0x0009c, 0x0009d, 0x0009e, 0x0009f, - 0x000a0, 0x000a1, 0x000a2, 0x000a3, 0x000a4, 0x000a5, 0x000a6, 0x000a7, - 0x000a8, 0x000a9, 0x000aa, 0x000ab, 0x000ac, 0x000ad, 0x000ae, 0x000af, - 0x000b0, 0x000b1, 0x000b2, 0x000b3, 0x000b4, 0x003bc, 0x000b6, 0x000b7, - 0x000b8, 0x000b9, 0x000ba, 0x000bb, 0x000bc, 0x000bd, 0x000be, 0x000bf, - 0x000e0, 0x000e1, 0x000e2, 0x000e3, 0x000e4, 0x000e5, 0x000e6, 0x000e7, - 0x000e8, 0x000e9, 0x000ea, 0x000eb, 0x000ec, 0x000ed, 0x000ee, 0x000ef, - 0x000f0, 0x000f1, 0x000f2, 0x000f3, 0x000f4, 0x000f5, 0x000f6, 0x000d7, - 0x000f8, 0x000f9, 0x000fa, 0x000fb, 0x000fc, 0x000fd, 0x000fe, 0x000df, - 0x000e0, 0x000e1, 0x000e2, 0x000e3, 0x000e4, 0x000e5, 0x000e6, 0x000e7, - 0x000e8, 0x000e9, 0x000ea, 0x000eb, 0x000ec, 0x000ed, 0x000ee, 0x000ef, - 0x000f0, 0x000f1, 0x000f2, 0x000f3, 0x000f4, 0x000f5, 0x000f6, 0x000f7, - 0x000f8, 0x000f9, 0x000fa, 0x000fb, 0x000fc, 0x000fd, 0x000fe, 0x000ff, -}; - - -static const uint32_t nxt_unicode_block_002[128] nxt_aligned(64) = { - 0x00101, 0x00101, 0x00103, 0x00103, 0x00105, 0x00105, 0x00107, 0x00107, - 0x00109, 0x00109, 0x0010b, 0x0010b, 0x0010d, 0x0010d, 0x0010f, 0x0010f, - 0x00111, 0x00111, 0x00113, 0x00113, 0x00115, 0x00115, 0x00117, 0x00117, - 0x00119, 0x00119, 0x0011b, 0x0011b, 0x0011d, 0x0011d, 0x0011f, 0x0011f, - 0x00121, 0x00121, 0x00123, 0x00123, 0x00125, 0x00125, 0x00127, 0x00127, - 0x00129, 0x00129, 0x0012b, 0x0012b, 0x0012d, 0x0012d, 0x0012f, 0x0012f, - 0x00130, 0x00131, 0x00133, 0x00133, 0x00135, 0x00135, 0x00137, 0x00137, - 0x00138, 0x0013a, 0x0013a, 0x0013c, 0x0013c, 0x0013e, 0x0013e, 0x00140, - 0x00140, 0x00142, 0x00142, 0x00144, 0x00144, 0x00146, 0x00146, 0x00148, - 0x00148, 0x00149, 0x0014b, 0x0014b, 0x0014d, 0x0014d, 0x0014f, 0x0014f, - 0x00151, 0x00151, 0x00153, 0x00153, 0x00155, 0x00155, 0x00157, 0x00157, - 0x00159, 0x00159, 0x0015b, 0x0015b, 0x0015d, 0x0015d, 0x0015f, 0x0015f, - 0x00161, 0x00161, 0x00163, 0x00163, 0x00165, 0x00165, 0x00167, 0x00167, - 0x00169, 0x00169, 0x0016b, 0x0016b, 0x0016d, 0x0016d, 0x0016f, 0x0016f, - 0x00171, 0x00171, 0x00173, 0x00173, 0x00175, 0x00175, 0x00177, 0x00177, - 0x000ff, 0x0017a, 0x0017a, 0x0017c, 0x0017c, 0x0017e, 0x0017e, 0x00073, -}; - - -static const uint32_t nxt_unicode_block_003[128] nxt_aligned(64) = { - 0x00180, 0x00253, 0x00183, 0x00183, 0x00185, 0x00185, 0x00254, 0x00188, - 0x00188, 0x00256, 0x00257, 0x0018c, 0x0018c, 0x0018d, 0x001dd, 0x00259, - 0x0025b, 0x00192, 0x00192, 0x00260, 0x00263, 0x00195, 0x00269, 0x00268, - 0x00199, 0x00199, 0x0019a, 0x0019b, 0x0026f, 0x00272, 0x0019e, 0x00275, - 0x001a1, 0x001a1, 0x001a3, 0x001a3, 0x001a5, 0x001a5, 0x00280, 0x001a8, - 0x001a8, 0x00283, 0x001aa, 0x001ab, 0x001ad, 0x001ad, 0x00288, 0x001b0, - 0x001b0, 0x0028a, 0x0028b, 0x001b4, 0x001b4, 0x001b6, 0x001b6, 0x00292, - 0x001b9, 0x001b9, 0x001ba, 0x001bb, 0x001bd, 0x001bd, 0x001be, 0x001bf, - 0x001c0, 0x001c1, 0x001c2, 0x001c3, 0x001c6, 0x001c6, 0x001c6, 0x001c9, - 0x001c9, 0x001c9, 0x001cc, 0x001cc, 0x001cc, 0x001ce, 0x001ce, 0x001d0, - 0x001d0, 0x001d2, 0x001d2, 0x001d4, 0x001d4, 0x001d6, 0x001d6, 0x001d8, - 0x001d8, 0x001da, 0x001da, 0x001dc, 0x001dc, 0x001dd, 0x001df, 0x001df, - 0x001e1, 0x001e1, 0x001e3, 0x001e3, 0x001e5, 0x001e5, 0x001e7, 0x001e7, - 0x001e9, 0x001e9, 0x001eb, 0x001eb, 0x001ed, 0x001ed, 0x001ef, 0x001ef, - 0x001f0, 0x001f3, 0x001f3, 0x001f3, 0x001f5, 0x001f5, 0x00195, 0x001bf, - 0x001f9, 0x001f9, 0x001fb, 0x001fb, 0x001fd, 0x001fd, 0x001ff, 0x001ff, -}; - - -static const uint32_t nxt_unicode_block_004[128] nxt_aligned(64) = { - 0x00201, 0x00201, 0x00203, 0x00203, 0x00205, 0x00205, 0x00207, 0x00207, - 0x00209, 0x00209, 0x0020b, 0x0020b, 0x0020d, 0x0020d, 0x0020f, 0x0020f, - 0x00211, 0x00211, 0x00213, 0x00213, 0x00215, 0x00215, 0x00217, 0x00217, - 0x00219, 0x00219, 0x0021b, 0x0021b, 0x0021d, 0x0021d, 0x0021f, 0x0021f, - 0x0019e, 0x00221, 0x00223, 0x00223, 0x00225, 0x00225, 0x00227, 0x00227, - 0x00229, 0x00229, 0x0022b, 0x0022b, 0x0022d, 0x0022d, 0x0022f, 0x0022f, - 0x00231, 0x00231, 0x00233, 0x00233, 0x00234, 0x00235, 0x00236, 0x00237, - 0x00238, 0x00239, 0x02c65, 0x0023c, 0x0023c, 0x0019a, 0x02c66, 0x0023f, - 0x00240, 0x00242, 0x00242, 0x00180, 0x00289, 0x0028c, 0x00247, 0x00247, - 0x00249, 0x00249, 0x0024b, 0x0024b, 0x0024d, 0x0024d, 0x0024f, 0x0024f, - 0x00250, 0x00251, 0x00252, 0x00253, 0x00254, 0x00255, 0x00256, 0x00257, - 0x00258, 0x00259, 0x0025a, 0x0025b, 0x0025c, 0x0025d, 0x0025e, 0x0025f, - 0x00260, 0x00261, 0x00262, 0x00263, 0x00264, 0x00265, 0x00266, 0x00267, - 0x00268, 0x00269, 0x0026a, 0x0026b, 0x0026c, 0x0026d, 0x0026e, 0x0026f, - 0x00270, 0x00271, 0x00272, 0x00273, 0x00274, 0x00275, 0x00276, 0x00277, - 0x00278, 0x00279, 0x0027a, 0x0027b, 0x0027c, 0x0027d, 0x0027e, 0x0027f, -}; - - -static const uint32_t nxt_unicode_block_006[128] nxt_aligned(64) = { - 0x00300, 0x00301, 0x00302, 0x00303, 0x00304, 0x00305, 0x00306, 0x00307, - 0x00308, 0x00309, 0x0030a, 0x0030b, 0x0030c, 0x0030d, 0x0030e, 0x0030f, - 0x00310, 0x00311, 0x00312, 0x00313, 0x00314, 0x00315, 0x00316, 0x00317, - 0x00318, 0x00319, 0x0031a, 0x0031b, 0x0031c, 0x0031d, 0x0031e, 0x0031f, - 0x00320, 0x00321, 0x00322, 0x00323, 0x00324, 0x00325, 0x00326, 0x00327, - 0x00328, 0x00329, 0x0032a, 0x0032b, 0x0032c, 0x0032d, 0x0032e, 0x0032f, - 0x00330, 0x00331, 0x00332, 0x00333, 0x00334, 0x00335, 0x00336, 0x00337, - 0x00338, 0x00339, 0x0033a, 0x0033b, 0x0033c, 0x0033d, 0x0033e, 0x0033f, - 0x00340, 0x00341, 0x00342, 0x00343, 0x00344, 0x003b9, 0x00346, 0x00347, - 0x00348, 0x00349, 0x0034a, 0x0034b, 0x0034c, 0x0034d, 0x0034e, 0x0034f, - 0x00350, 0x00351, 0x00352, 0x00353, 0x00354, 0x00355, 0x00356, 0x00357, - 0x00358, 0x00359, 0x0035a, 0x0035b, 0x0035c, 0x0035d, 0x0035e, 0x0035f, - 0x00360, 0x00361, 0x00362, 0x00363, 0x00364, 0x00365, 0x00366, 0x00367, - 0x00368, 0x00369, 0x0036a, 0x0036b, 0x0036c, 0x0036d, 0x0036e, 0x0036f, - 0x00371, 0x00371, 0x00373, 0x00373, 0x00374, 0x00375, 0x00377, 0x00377, - 0x00378, 0x00379, 0x0037a, 0x0037b, 0x0037c, 0x0037d, 0x0037e, 0x0037f, -}; - - -static const uint32_t nxt_unicode_block_007[128] nxt_aligned(64) = { - 0x00380, 0x00381, 0x00382, 0x00383, 0x00384, 0x00385, 0x003ac, 0x00387, - 0x003ad, 0x003ae, 0x003af, 0x0038b, 0x003cc, 0x0038d, 0x003cd, 0x003ce, - 0x00390, 0x003b1, 0x003b2, 0x003b3, 0x003b4, 0x003b5, 0x003b6, 0x003b7, - 0x003b8, 0x003b9, 0x003ba, 0x003bb, 0x003bc, 0x003bd, 0x003be, 0x003bf, - 0x003c0, 0x003c1, 0x003a2, 0x003c3, 0x003c4, 0x003c5, 0x003c6, 0x003c7, - 0x003c8, 0x003c9, 0x003ca, 0x003cb, 0x003ac, 0x003ad, 0x003ae, 0x003af, - 0x003b0, 0x003b1, 0x003b2, 0x003b3, 0x003b4, 0x003b5, 0x003b6, 0x003b7, - 0x003b8, 0x003b9, 0x003ba, 0x003bb, 0x003bc, 0x003bd, 0x003be, 0x003bf, - 0x003c0, 0x003c1, 0x003c3, 0x003c3, 0x003c4, 0x003c5, 0x003c6, 0x003c7, - 0x003c8, 0x003c9, 0x003ca, 0x003cb, 0x003cc, 0x003cd, 0x003ce, 0x003d7, - 0x003b2, 0x003b8, 0x003d2, 0x003d3, 0x003d4, 0x003c6, 0x003c0, 0x003d7, - 0x003d9, 0x003d9, 0x003db, 0x003db, 0x003dd, 0x003dd, 0x003df, 0x003df, - 0x003e1, 0x003e1, 0x003e3, 0x003e3, 0x003e5, 0x003e5, 0x003e7, 0x003e7, - 0x003e9, 0x003e9, 0x003eb, 0x003eb, 0x003ed, 0x003ed, 0x003ef, 0x003ef, - 0x003ba, 0x003c1, 0x003f2, 0x003f3, 0x003b8, 0x003b5, 0x003f6, 0x003f8, - 0x003f8, 0x003f2, 0x003fb, 0x003fb, 0x003fc, 0x0037b, 0x0037c, 0x0037d, -}; - - -static const uint32_t nxt_unicode_block_008[128] nxt_aligned(64) = { - 0x00450, 0x00451, 0x00452, 0x00453, 0x00454, 0x00455, 0x00456, 0x00457, - 0x00458, 0x00459, 0x0045a, 0x0045b, 0x0045c, 0x0045d, 0x0045e, 0x0045f, - 0x00430, 0x00431, 0x00432, 0x00433, 0x00434, 0x00435, 0x00436, 0x00437, - 0x00438, 0x00439, 0x0043a, 0x0043b, 0x0043c, 0x0043d, 0x0043e, 0x0043f, - 0x00440, 0x00441, 0x00442, 0x00443, 0x00444, 0x00445, 0x00446, 0x00447, - 0x00448, 0x00449, 0x0044a, 0x0044b, 0x0044c, 0x0044d, 0x0044e, 0x0044f, - 0x00430, 0x00431, 0x00432, 0x00433, 0x00434, 0x00435, 0x00436, 0x00437, - 0x00438, 0x00439, 0x0043a, 0x0043b, 0x0043c, 0x0043d, 0x0043e, 0x0043f, - 0x00440, 0x00441, 0x00442, 0x00443, 0x00444, 0x00445, 0x00446, 0x00447, - 0x00448, 0x00449, 0x0044a, 0x0044b, 0x0044c, 0x0044d, 0x0044e, 0x0044f, - 0x00450, 0x00451, 0x00452, 0x00453, 0x00454, 0x00455, 0x00456, 0x00457, - 0x00458, 0x00459, 0x0045a, 0x0045b, 0x0045c, 0x0045d, 0x0045e, 0x0045f, - 0x00461, 0x00461, 0x00463, 0x00463, 0x00465, 0x00465, 0x00467, 0x00467, - 0x00469, 0x00469, 0x0046b, 0x0046b, 0x0046d, 0x0046d, 0x0046f, 0x0046f, - 0x00471, 0x00471, 0x00473, 0x00473, 0x00475, 0x00475, 0x00477, 0x00477, - 0x00479, 0x00479, 0x0047b, 0x0047b, 0x0047d, 0x0047d, 0x0047f, 0x0047f, -}; - - -static const uint32_t nxt_unicode_block_009[128] nxt_aligned(64) = { - 0x00481, 0x00481, 0x00482, 0x00483, 0x00484, 0x00485, 0x00486, 0x00487, - 0x00488, 0x00489, 0x0048b, 0x0048b, 0x0048d, 0x0048d, 0x0048f, 0x0048f, - 0x00491, 0x00491, 0x00493, 0x00493, 0x00495, 0x00495, 0x00497, 0x00497, - 0x00499, 0x00499, 0x0049b, 0x0049b, 0x0049d, 0x0049d, 0x0049f, 0x0049f, - 0x004a1, 0x004a1, 0x004a3, 0x004a3, 0x004a5, 0x004a5, 0x004a7, 0x004a7, - 0x004a9, 0x004a9, 0x004ab, 0x004ab, 0x004ad, 0x004ad, 0x004af, 0x004af, - 0x004b1, 0x004b1, 0x004b3, 0x004b3, 0x004b5, 0x004b5, 0x004b7, 0x004b7, - 0x004b9, 0x004b9, 0x004bb, 0x004bb, 0x004bd, 0x004bd, 0x004bf, 0x004bf, - 0x004cf, 0x004c2, 0x004c2, 0x004c4, 0x004c4, 0x004c6, 0x004c6, 0x004c8, - 0x004c8, 0x004ca, 0x004ca, 0x004cc, 0x004cc, 0x004ce, 0x004ce, 0x004cf, - 0x004d1, 0x004d1, 0x004d3, 0x004d3, 0x004d5, 0x004d5, 0x004d7, 0x004d7, - 0x004d9, 0x004d9, 0x004db, 0x004db, 0x004dd, 0x004dd, 0x004df, 0x004df, - 0x004e1, 0x004e1, 0x004e3, 0x004e3, 0x004e5, 0x004e5, 0x004e7, 0x004e7, - 0x004e9, 0x004e9, 0x004eb, 0x004eb, 0x004ed, 0x004ed, 0x004ef, 0x004ef, - 0x004f1, 0x004f1, 0x004f3, 0x004f3, 0x004f5, 0x004f5, 0x004f7, 0x004f7, - 0x004f9, 0x004f9, 0x004fb, 0x004fb, 0x004fd, 0x004fd, 0x004ff, 0x004ff, -}; - - -static const uint32_t nxt_unicode_block_00a[128] nxt_aligned(64) = { - 0x00501, 0x00501, 0x00503, 0x00503, 0x00505, 0x00505, 0x00507, 0x00507, - 0x00509, 0x00509, 0x0050b, 0x0050b, 0x0050d, 0x0050d, 0x0050f, 0x0050f, - 0x00511, 0x00511, 0x00513, 0x00513, 0x00515, 0x00515, 0x00517, 0x00517, - 0x00519, 0x00519, 0x0051b, 0x0051b, 0x0051d, 0x0051d, 0x0051f, 0x0051f, - 0x00521, 0x00521, 0x00523, 0x00523, 0x00525, 0x00525, 0x00527, 0x00527, - 0x00528, 0x00529, 0x0052a, 0x0052b, 0x0052c, 0x0052d, 0x0052e, 0x0052f, - 0x00530, 0x00561, 0x00562, 0x00563, 0x00564, 0x00565, 0x00566, 0x00567, - 0x00568, 0x00569, 0x0056a, 0x0056b, 0x0056c, 0x0056d, 0x0056e, 0x0056f, - 0x00570, 0x00571, 0x00572, 0x00573, 0x00574, 0x00575, 0x00576, 0x00577, - 0x00578, 0x00579, 0x0057a, 0x0057b, 0x0057c, 0x0057d, 0x0057e, 0x0057f, - 0x00580, 0x00581, 0x00582, 0x00583, 0x00584, 0x00585, 0x00586, 0x00557, - 0x00558, 0x00559, 0x0055a, 0x0055b, 0x0055c, 0x0055d, 0x0055e, 0x0055f, - 0x00560, 0x00561, 0x00562, 0x00563, 0x00564, 0x00565, 0x00566, 0x00567, - 0x00568, 0x00569, 0x0056a, 0x0056b, 0x0056c, 0x0056d, 0x0056e, 0x0056f, - 0x00570, 0x00571, 0x00572, 0x00573, 0x00574, 0x00575, 0x00576, 0x00577, - 0x00578, 0x00579, 0x0057a, 0x0057b, 0x0057c, 0x0057d, 0x0057e, 0x0057f, -}; - - -static const uint32_t nxt_unicode_block_021[128] nxt_aligned(64) = { - 0x01080, 0x01081, 0x01082, 0x01083, 0x01084, 0x01085, 0x01086, 0x01087, - 0x01088, 0x01089, 0x0108a, 0x0108b, 0x0108c, 0x0108d, 0x0108e, 0x0108f, - 0x01090, 0x01091, 0x01092, 0x01093, 0x01094, 0x01095, 0x01096, 0x01097, - 0x01098, 0x01099, 0x0109a, 0x0109b, 0x0109c, 0x0109d, 0x0109e, 0x0109f, - 0x02d00, 0x02d01, 0x02d02, 0x02d03, 0x02d04, 0x02d05, 0x02d06, 0x02d07, - 0x02d08, 0x02d09, 0x02d0a, 0x02d0b, 0x02d0c, 0x02d0d, 0x02d0e, 0x02d0f, - 0x02d10, 0x02d11, 0x02d12, 0x02d13, 0x02d14, 0x02d15, 0x02d16, 0x02d17, - 0x02d18, 0x02d19, 0x02d1a, 0x02d1b, 0x02d1c, 0x02d1d, 0x02d1e, 0x02d1f, - 0x02d20, 0x02d21, 0x02d22, 0x02d23, 0x02d24, 0x02d25, 0x010c6, 0x02d27, - 0x010c8, 0x010c9, 0x010ca, 0x010cb, 0x010cc, 0x02d2d, 0x010ce, 0x010cf, - 0x010d0, 0x010d1, 0x010d2, 0x010d3, 0x010d4, 0x010d5, 0x010d6, 0x010d7, - 0x010d8, 0x010d9, 0x010da, 0x010db, 0x010dc, 0x010dd, 0x010de, 0x010df, - 0x010e0, 0x010e1, 0x010e2, 0x010e3, 0x010e4, 0x010e5, 0x010e6, 0x010e7, - 0x010e8, 0x010e9, 0x010ea, 0x010eb, 0x010ec, 0x010ed, 0x010ee, 0x010ef, - 0x010f0, 0x010f1, 0x010f2, 0x010f3, 0x010f4, 0x010f5, 0x010f6, 0x010f7, - 0x010f8, 0x010f9, 0x010fa, 0x010fb, 0x010fc, 0x010fd, 0x010fe, 0x010ff, -}; - - -static const uint32_t nxt_unicode_block_03c[128] nxt_aligned(64) = { - 0x01e01, 0x01e01, 0x01e03, 0x01e03, 0x01e05, 0x01e05, 0x01e07, 0x01e07, - 0x01e09, 0x01e09, 0x01e0b, 0x01e0b, 0x01e0d, 0x01e0d, 0x01e0f, 0x01e0f, - 0x01e11, 0x01e11, 0x01e13, 0x01e13, 0x01e15, 0x01e15, 0x01e17, 0x01e17, - 0x01e19, 0x01e19, 0x01e1b, 0x01e1b, 0x01e1d, 0x01e1d, 0x01e1f, 0x01e1f, - 0x01e21, 0x01e21, 0x01e23, 0x01e23, 0x01e25, 0x01e25, 0x01e27, 0x01e27, - 0x01e29, 0x01e29, 0x01e2b, 0x01e2b, 0x01e2d, 0x01e2d, 0x01e2f, 0x01e2f, - 0x01e31, 0x01e31, 0x01e33, 0x01e33, 0x01e35, 0x01e35, 0x01e37, 0x01e37, - 0x01e39, 0x01e39, 0x01e3b, 0x01e3b, 0x01e3d, 0x01e3d, 0x01e3f, 0x01e3f, - 0x01e41, 0x01e41, 0x01e43, 0x01e43, 0x01e45, 0x01e45, 0x01e47, 0x01e47, - 0x01e49, 0x01e49, 0x01e4b, 0x01e4b, 0x01e4d, 0x01e4d, 0x01e4f, 0x01e4f, - 0x01e51, 0x01e51, 0x01e53, 0x01e53, 0x01e55, 0x01e55, 0x01e57, 0x01e57, - 0x01e59, 0x01e59, 0x01e5b, 0x01e5b, 0x01e5d, 0x01e5d, 0x01e5f, 0x01e5f, - 0x01e61, 0x01e61, 0x01e63, 0x01e63, 0x01e65, 0x01e65, 0x01e67, 0x01e67, - 0x01e69, 0x01e69, 0x01e6b, 0x01e6b, 0x01e6d, 0x01e6d, 0x01e6f, 0x01e6f, - 0x01e71, 0x01e71, 0x01e73, 0x01e73, 0x01e75, 0x01e75, 0x01e77, 0x01e77, - 0x01e79, 0x01e79, 0x01e7b, 0x01e7b, 0x01e7d, 0x01e7d, 0x01e7f, 0x01e7f, -}; - - -static const uint32_t nxt_unicode_block_03d[128] nxt_aligned(64) = { - 0x01e81, 0x01e81, 0x01e83, 0x01e83, 0x01e85, 0x01e85, 0x01e87, 0x01e87, - 0x01e89, 0x01e89, 0x01e8b, 0x01e8b, 0x01e8d, 0x01e8d, 0x01e8f, 0x01e8f, - 0x01e91, 0x01e91, 0x01e93, 0x01e93, 0x01e95, 0x01e95, 0x01e96, 0x01e97, - 0x01e98, 0x01e99, 0x01e9a, 0x01e61, 0x01e9c, 0x01e9d, 0x000df, 0x01e9f, - 0x01ea1, 0x01ea1, 0x01ea3, 0x01ea3, 0x01ea5, 0x01ea5, 0x01ea7, 0x01ea7, - 0x01ea9, 0x01ea9, 0x01eab, 0x01eab, 0x01ead, 0x01ead, 0x01eaf, 0x01eaf, - 0x01eb1, 0x01eb1, 0x01eb3, 0x01eb3, 0x01eb5, 0x01eb5, 0x01eb7, 0x01eb7, - 0x01eb9, 0x01eb9, 0x01ebb, 0x01ebb, 0x01ebd, 0x01ebd, 0x01ebf, 0x01ebf, - 0x01ec1, 0x01ec1, 0x01ec3, 0x01ec3, 0x01ec5, 0x01ec5, 0x01ec7, 0x01ec7, - 0x01ec9, 0x01ec9, 0x01ecb, 0x01ecb, 0x01ecd, 0x01ecd, 0x01ecf, 0x01ecf, - 0x01ed1, 0x01ed1, 0x01ed3, 0x01ed3, 0x01ed5, 0x01ed5, 0x01ed7, 0x01ed7, - 0x01ed9, 0x01ed9, 0x01edb, 0x01edb, 0x01edd, 0x01edd, 0x01edf, 0x01edf, - 0x01ee1, 0x01ee1, 0x01ee3, 0x01ee3, 0x01ee5, 0x01ee5, 0x01ee7, 0x01ee7, - 0x01ee9, 0x01ee9, 0x01eeb, 0x01eeb, 0x01eed, 0x01eed, 0x01eef, 0x01eef, - 0x01ef1, 0x01ef1, 0x01ef3, 0x01ef3, 0x01ef5, 0x01ef5, 0x01ef7, 0x01ef7, - 0x01ef9, 0x01ef9, 0x01efb, 0x01efb, 0x01efd, 0x01efd, 0x01eff, 0x01eff, -}; - - -static const uint32_t nxt_unicode_block_03e[128] nxt_aligned(64) = { - 0x01f00, 0x01f01, 0x01f02, 0x01f03, 0x01f04, 0x01f05, 0x01f06, 0x01f07, - 0x01f00, 0x01f01, 0x01f02, 0x01f03, 0x01f04, 0x01f05, 0x01f06, 0x01f07, - 0x01f10, 0x01f11, 0x01f12, 0x01f13, 0x01f14, 0x01f15, 0x01f16, 0x01f17, - 0x01f10, 0x01f11, 0x01f12, 0x01f13, 0x01f14, 0x01f15, 0x01f1e, 0x01f1f, - 0x01f20, 0x01f21, 0x01f22, 0x01f23, 0x01f24, 0x01f25, 0x01f26, 0x01f27, - 0x01f20, 0x01f21, 0x01f22, 0x01f23, 0x01f24, 0x01f25, 0x01f26, 0x01f27, - 0x01f30, 0x01f31, 0x01f32, 0x01f33, 0x01f34, 0x01f35, 0x01f36, 0x01f37, - 0x01f30, 0x01f31, 0x01f32, 0x01f33, 0x01f34, 0x01f35, 0x01f36, 0x01f37, - 0x01f40, 0x01f41, 0x01f42, 0x01f43, 0x01f44, 0x01f45, 0x01f46, 0x01f47, - 0x01f40, 0x01f41, 0x01f42, 0x01f43, 0x01f44, 0x01f45, 0x01f4e, 0x01f4f, - 0x01f50, 0x01f51, 0x01f52, 0x01f53, 0x01f54, 0x01f55, 0x01f56, 0x01f57, - 0x01f58, 0x01f51, 0x01f5a, 0x01f53, 0x01f5c, 0x01f55, 0x01f5e, 0x01f57, - 0x01f60, 0x01f61, 0x01f62, 0x01f63, 0x01f64, 0x01f65, 0x01f66, 0x01f67, - 0x01f60, 0x01f61, 0x01f62, 0x01f63, 0x01f64, 0x01f65, 0x01f66, 0x01f67, - 0x01f70, 0x01f71, 0x01f72, 0x01f73, 0x01f74, 0x01f75, 0x01f76, 0x01f77, - 0x01f78, 0x01f79, 0x01f7a, 0x01f7b, 0x01f7c, 0x01f7d, 0x01f7e, 0x01f7f, -}; - - -static const uint32_t nxt_unicode_block_03f[128] nxt_aligned(64) = { - 0x01f80, 0x01f81, 0x01f82, 0x01f83, 0x01f84, 0x01f85, 0x01f86, 0x01f87, - 0x01f80, 0x01f81, 0x01f82, 0x01f83, 0x01f84, 0x01f85, 0x01f86, 0x01f87, - 0x01f90, 0x01f91, 0x01f92, 0x01f93, 0x01f94, 0x01f95, 0x01f96, 0x01f97, - 0x01f90, 0x01f91, 0x01f92, 0x01f93, 0x01f94, 0x01f95, 0x01f96, 0x01f97, - 0x01fa0, 0x01fa1, 0x01fa2, 0x01fa3, 0x01fa4, 0x01fa5, 0x01fa6, 0x01fa7, - 0x01fa0, 0x01fa1, 0x01fa2, 0x01fa3, 0x01fa4, 0x01fa5, 0x01fa6, 0x01fa7, - 0x01fb0, 0x01fb1, 0x01fb2, 0x01fb3, 0x01fb4, 0x01fb5, 0x01fb6, 0x01fb7, - 0x01fb0, 0x01fb1, 0x01f70, 0x01f71, 0x01fb3, 0x01fbd, 0x003b9, 0x01fbf, - 0x01fc0, 0x01fc1, 0x01fc2, 0x01fc3, 0x01fc4, 0x01fc5, 0x01fc6, 0x01fc7, - 0x01f72, 0x01f73, 0x01f74, 0x01f75, 0x01fc3, 0x01fcd, 0x01fce, 0x01fcf, - 0x01fd0, 0x01fd1, 0x01fd2, 0x01fd3, 0x01fd4, 0x01fd5, 0x01fd6, 0x01fd7, - 0x01fd0, 0x01fd1, 0x01f76, 0x01f77, 0x01fdc, 0x01fdd, 0x01fde, 0x01fdf, - 0x01fe0, 0x01fe1, 0x01fe2, 0x01fe3, 0x01fe4, 0x01fe5, 0x01fe6, 0x01fe7, - 0x01fe0, 0x01fe1, 0x01f7a, 0x01f7b, 0x01fe5, 0x01fed, 0x01fee, 0x01fef, - 0x01ff0, 0x01ff1, 0x01ff2, 0x01ff3, 0x01ff4, 0x01ff5, 0x01ff6, 0x01ff7, - 0x01f78, 0x01f79, 0x01f7c, 0x01f7d, 0x01ff3, 0x01ffd, 0x01ffe, 0x01fff, -}; - - -static const uint32_t nxt_unicode_block_042[128] nxt_aligned(64) = { - 0x02100, 0x02101, 0x02102, 0x02103, 0x02104, 0x02105, 0x02106, 0x02107, - 0x02108, 0x02109, 0x0210a, 0x0210b, 0x0210c, 0x0210d, 0x0210e, 0x0210f, - 0x02110, 0x02111, 0x02112, 0x02113, 0x02114, 0x02115, 0x02116, 0x02117, - 0x02118, 0x02119, 0x0211a, 0x0211b, 0x0211c, 0x0211d, 0x0211e, 0x0211f, - 0x02120, 0x02121, 0x02122, 0x02123, 0x02124, 0x02125, 0x003c9, 0x02127, - 0x02128, 0x02129, 0x0006b, 0x000e5, 0x0212c, 0x0212d, 0x0212e, 0x0212f, - 0x02130, 0x02131, 0x0214e, 0x02133, 0x02134, 0x02135, 0x02136, 0x02137, - 0x02138, 0x02139, 0x0213a, 0x0213b, 0x0213c, 0x0213d, 0x0213e, 0x0213f, - 0x02140, 0x02141, 0x02142, 0x02143, 0x02144, 0x02145, 0x02146, 0x02147, - 0x02148, 0x02149, 0x0214a, 0x0214b, 0x0214c, 0x0214d, 0x0214e, 0x0214f, - 0x02150, 0x02151, 0x02152, 0x02153, 0x02154, 0x02155, 0x02156, 0x02157, - 0x02158, 0x02159, 0x0215a, 0x0215b, 0x0215c, 0x0215d, 0x0215e, 0x0215f, - 0x02170, 0x02171, 0x02172, 0x02173, 0x02174, 0x02175, 0x02176, 0x02177, - 0x02178, 0x02179, 0x0217a, 0x0217b, 0x0217c, 0x0217d, 0x0217e, 0x0217f, - 0x02170, 0x02171, 0x02172, 0x02173, 0x02174, 0x02175, 0x02176, 0x02177, - 0x02178, 0x02179, 0x0217a, 0x0217b, 0x0217c, 0x0217d, 0x0217e, 0x0217f, -}; - - -static const uint32_t nxt_unicode_block_043[128] nxt_aligned(64) = { - 0x02180, 0x02181, 0x02182, 0x02184, 0x02184, 0x02185, 0x02186, 0x02187, - 0x02188, 0x02189, 0x0218a, 0x0218b, 0x0218c, 0x0218d, 0x0218e, 0x0218f, - 0x02190, 0x02191, 0x02192, 0x02193, 0x02194, 0x02195, 0x02196, 0x02197, - 0x02198, 0x02199, 0x0219a, 0x0219b, 0x0219c, 0x0219d, 0x0219e, 0x0219f, - 0x021a0, 0x021a1, 0x021a2, 0x021a3, 0x021a4, 0x021a5, 0x021a6, 0x021a7, - 0x021a8, 0x021a9, 0x021aa, 0x021ab, 0x021ac, 0x021ad, 0x021ae, 0x021af, - 0x021b0, 0x021b1, 0x021b2, 0x021b3, 0x021b4, 0x021b5, 0x021b6, 0x021b7, - 0x021b8, 0x021b9, 0x021ba, 0x021bb, 0x021bc, 0x021bd, 0x021be, 0x021bf, - 0x021c0, 0x021c1, 0x021c2, 0x021c3, 0x021c4, 0x021c5, 0x021c6, 0x021c7, - 0x021c8, 0x021c9, 0x021ca, 0x021cb, 0x021cc, 0x021cd, 0x021ce, 0x021cf, - 0x021d0, 0x021d1, 0x021d2, 0x021d3, 0x021d4, 0x021d5, 0x021d6, 0x021d7, - 0x021d8, 0x021d9, 0x021da, 0x021db, 0x021dc, 0x021dd, 0x021de, 0x021df, - 0x021e0, 0x021e1, 0x021e2, 0x021e3, 0x021e4, 0x021e5, 0x021e6, 0x021e7, - 0x021e8, 0x021e9, 0x021ea, 0x021eb, 0x021ec, 0x021ed, 0x021ee, 0x021ef, - 0x021f0, 0x021f1, 0x021f2, 0x021f3, 0x021f4, 0x021f5, 0x021f6, 0x021f7, - 0x021f8, 0x021f9, 0x021fa, 0x021fb, 0x021fc, 0x021fd, 0x021fe, 0x021ff, -}; - - -static const uint32_t nxt_unicode_block_049[128] nxt_aligned(64) = { - 0x02480, 0x02481, 0x02482, 0x02483, 0x02484, 0x02485, 0x02486, 0x02487, - 0x02488, 0x02489, 0x0248a, 0x0248b, 0x0248c, 0x0248d, 0x0248e, 0x0248f, - 0x02490, 0x02491, 0x02492, 0x02493, 0x02494, 0x02495, 0x02496, 0x02497, - 0x02498, 0x02499, 0x0249a, 0x0249b, 0x0249c, 0x0249d, 0x0249e, 0x0249f, - 0x024a0, 0x024a1, 0x024a2, 0x024a3, 0x024a4, 0x024a5, 0x024a6, 0x024a7, - 0x024a8, 0x024a9, 0x024aa, 0x024ab, 0x024ac, 0x024ad, 0x024ae, 0x024af, - 0x024b0, 0x024b1, 0x024b2, 0x024b3, 0x024b4, 0x024b5, 0x024d0, 0x024d1, - 0x024d2, 0x024d3, 0x024d4, 0x024d5, 0x024d6, 0x024d7, 0x024d8, 0x024d9, - 0x024da, 0x024db, 0x024dc, 0x024dd, 0x024de, 0x024df, 0x024e0, 0x024e1, - 0x024e2, 0x024e3, 0x024e4, 0x024e5, 0x024e6, 0x024e7, 0x024e8, 0x024e9, - 0x024d0, 0x024d1, 0x024d2, 0x024d3, 0x024d4, 0x024d5, 0x024d6, 0x024d7, - 0x024d8, 0x024d9, 0x024da, 0x024db, 0x024dc, 0x024dd, 0x024de, 0x024df, - 0x024e0, 0x024e1, 0x024e2, 0x024e3, 0x024e4, 0x024e5, 0x024e6, 0x024e7, - 0x024e8, 0x024e9, 0x024ea, 0x024eb, 0x024ec, 0x024ed, 0x024ee, 0x024ef, - 0x024f0, 0x024f1, 0x024f2, 0x024f3, 0x024f4, 0x024f5, 0x024f6, 0x024f7, - 0x024f8, 0x024f9, 0x024fa, 0x024fb, 0x024fc, 0x024fd, 0x024fe, 0x024ff, -}; - - -static const uint32_t nxt_unicode_block_058[128] nxt_aligned(64) = { - 0x02c30, 0x02c31, 0x02c32, 0x02c33, 0x02c34, 0x02c35, 0x02c36, 0x02c37, - 0x02c38, 0x02c39, 0x02c3a, 0x02c3b, 0x02c3c, 0x02c3d, 0x02c3e, 0x02c3f, - 0x02c40, 0x02c41, 0x02c42, 0x02c43, 0x02c44, 0x02c45, 0x02c46, 0x02c47, - 0x02c48, 0x02c49, 0x02c4a, 0x02c4b, 0x02c4c, 0x02c4d, 0x02c4e, 0x02c4f, - 0x02c50, 0x02c51, 0x02c52, 0x02c53, 0x02c54, 0x02c55, 0x02c56, 0x02c57, - 0x02c58, 0x02c59, 0x02c5a, 0x02c5b, 0x02c5c, 0x02c5d, 0x02c5e, 0x02c2f, - 0x02c30, 0x02c31, 0x02c32, 0x02c33, 0x02c34, 0x02c35, 0x02c36, 0x02c37, - 0x02c38, 0x02c39, 0x02c3a, 0x02c3b, 0x02c3c, 0x02c3d, 0x02c3e, 0x02c3f, - 0x02c40, 0x02c41, 0x02c42, 0x02c43, 0x02c44, 0x02c45, 0x02c46, 0x02c47, - 0x02c48, 0x02c49, 0x02c4a, 0x02c4b, 0x02c4c, 0x02c4d, 0x02c4e, 0x02c4f, - 0x02c50, 0x02c51, 0x02c52, 0x02c53, 0x02c54, 0x02c55, 0x02c56, 0x02c57, - 0x02c58, 0x02c59, 0x02c5a, 0x02c5b, 0x02c5c, 0x02c5d, 0x02c5e, 0x02c5f, - 0x02c61, 0x02c61, 0x0026b, 0x01d7d, 0x0027d, 0x02c65, 0x02c66, 0x02c68, - 0x02c68, 0x02c6a, 0x02c6a, 0x02c6c, 0x02c6c, 0x00251, 0x00271, 0x00250, - 0x00252, 0x02c71, 0x02c73, 0x02c73, 0x02c74, 0x02c76, 0x02c76, 0x02c77, - 0x02c78, 0x02c79, 0x02c7a, 0x02c7b, 0x02c7c, 0x02c7d, 0x0023f, 0x00240, -}; - - -static const uint32_t nxt_unicode_block_059[128] nxt_aligned(64) = { - 0x02c81, 0x02c81, 0x02c83, 0x02c83, 0x02c85, 0x02c85, 0x02c87, 0x02c87, - 0x02c89, 0x02c89, 0x02c8b, 0x02c8b, 0x02c8d, 0x02c8d, 0x02c8f, 0x02c8f, - 0x02c91, 0x02c91, 0x02c93, 0x02c93, 0x02c95, 0x02c95, 0x02c97, 0x02c97, - 0x02c99, 0x02c99, 0x02c9b, 0x02c9b, 0x02c9d, 0x02c9d, 0x02c9f, 0x02c9f, - 0x02ca1, 0x02ca1, 0x02ca3, 0x02ca3, 0x02ca5, 0x02ca5, 0x02ca7, 0x02ca7, - 0x02ca9, 0x02ca9, 0x02cab, 0x02cab, 0x02cad, 0x02cad, 0x02caf, 0x02caf, - 0x02cb1, 0x02cb1, 0x02cb3, 0x02cb3, 0x02cb5, 0x02cb5, 0x02cb7, 0x02cb7, - 0x02cb9, 0x02cb9, 0x02cbb, 0x02cbb, 0x02cbd, 0x02cbd, 0x02cbf, 0x02cbf, - 0x02cc1, 0x02cc1, 0x02cc3, 0x02cc3, 0x02cc5, 0x02cc5, 0x02cc7, 0x02cc7, - 0x02cc9, 0x02cc9, 0x02ccb, 0x02ccb, 0x02ccd, 0x02ccd, 0x02ccf, 0x02ccf, - 0x02cd1, 0x02cd1, 0x02cd3, 0x02cd3, 0x02cd5, 0x02cd5, 0x02cd7, 0x02cd7, - 0x02cd9, 0x02cd9, 0x02cdb, 0x02cdb, 0x02cdd, 0x02cdd, 0x02cdf, 0x02cdf, - 0x02ce1, 0x02ce1, 0x02ce3, 0x02ce3, 0x02ce4, 0x02ce5, 0x02ce6, 0x02ce7, - 0x02ce8, 0x02ce9, 0x02cea, 0x02cec, 0x02cec, 0x02cee, 0x02cee, 0x02cef, - 0x02cf0, 0x02cf1, 0x02cf3, 0x02cf3, 0x02cf4, 0x02cf5, 0x02cf6, 0x02cf7, - 0x02cf8, 0x02cf9, 0x02cfa, 0x02cfb, 0x02cfc, 0x02cfd, 0x02cfe, 0x02cff, -}; - - -static const uint32_t nxt_unicode_block_14c[128] nxt_aligned(64) = { - 0x0a600, 0x0a601, 0x0a602, 0x0a603, 0x0a604, 0x0a605, 0x0a606, 0x0a607, - 0x0a608, 0x0a609, 0x0a60a, 0x0a60b, 0x0a60c, 0x0a60d, 0x0a60e, 0x0a60f, - 0x0a610, 0x0a611, 0x0a612, 0x0a613, 0x0a614, 0x0a615, 0x0a616, 0x0a617, - 0x0a618, 0x0a619, 0x0a61a, 0x0a61b, 0x0a61c, 0x0a61d, 0x0a61e, 0x0a61f, - 0x0a620, 0x0a621, 0x0a622, 0x0a623, 0x0a624, 0x0a625, 0x0a626, 0x0a627, - 0x0a628, 0x0a629, 0x0a62a, 0x0a62b, 0x0a62c, 0x0a62d, 0x0a62e, 0x0a62f, - 0x0a630, 0x0a631, 0x0a632, 0x0a633, 0x0a634, 0x0a635, 0x0a636, 0x0a637, - 0x0a638, 0x0a639, 0x0a63a, 0x0a63b, 0x0a63c, 0x0a63d, 0x0a63e, 0x0a63f, - 0x0a641, 0x0a641, 0x0a643, 0x0a643, 0x0a645, 0x0a645, 0x0a647, 0x0a647, - 0x0a649, 0x0a649, 0x0a64b, 0x0a64b, 0x0a64d, 0x0a64d, 0x0a64f, 0x0a64f, - 0x0a651, 0x0a651, 0x0a653, 0x0a653, 0x0a655, 0x0a655, 0x0a657, 0x0a657, - 0x0a659, 0x0a659, 0x0a65b, 0x0a65b, 0x0a65d, 0x0a65d, 0x0a65f, 0x0a65f, - 0x0a661, 0x0a661, 0x0a663, 0x0a663, 0x0a665, 0x0a665, 0x0a667, 0x0a667, - 0x0a669, 0x0a669, 0x0a66b, 0x0a66b, 0x0a66d, 0x0a66d, 0x0a66e, 0x0a66f, - 0x0a670, 0x0a671, 0x0a672, 0x0a673, 0x0a674, 0x0a675, 0x0a676, 0x0a677, - 0x0a678, 0x0a679, 0x0a67a, 0x0a67b, 0x0a67c, 0x0a67d, 0x0a67e, 0x0a67f, -}; - - -static const uint32_t nxt_unicode_block_14d[128] nxt_aligned(64) = { - 0x0a681, 0x0a681, 0x0a683, 0x0a683, 0x0a685, 0x0a685, 0x0a687, 0x0a687, - 0x0a689, 0x0a689, 0x0a68b, 0x0a68b, 0x0a68d, 0x0a68d, 0x0a68f, 0x0a68f, - 0x0a691, 0x0a691, 0x0a693, 0x0a693, 0x0a695, 0x0a695, 0x0a697, 0x0a697, - 0x0a698, 0x0a699, 0x0a69a, 0x0a69b, 0x0a69c, 0x0a69d, 0x0a69e, 0x0a69f, - 0x0a6a0, 0x0a6a1, 0x0a6a2, 0x0a6a3, 0x0a6a4, 0x0a6a5, 0x0a6a6, 0x0a6a7, - 0x0a6a8, 0x0a6a9, 0x0a6aa, 0x0a6ab, 0x0a6ac, 0x0a6ad, 0x0a6ae, 0x0a6af, - 0x0a6b0, 0x0a6b1, 0x0a6b2, 0x0a6b3, 0x0a6b4, 0x0a6b5, 0x0a6b6, 0x0a6b7, - 0x0a6b8, 0x0a6b9, 0x0a6ba, 0x0a6bb, 0x0a6bc, 0x0a6bd, 0x0a6be, 0x0a6bf, - 0x0a6c0, 0x0a6c1, 0x0a6c2, 0x0a6c3, 0x0a6c4, 0x0a6c5, 0x0a6c6, 0x0a6c7, - 0x0a6c8, 0x0a6c9, 0x0a6ca, 0x0a6cb, 0x0a6cc, 0x0a6cd, 0x0a6ce, 0x0a6cf, - 0x0a6d0, 0x0a6d1, 0x0a6d2, 0x0a6d3, 0x0a6d4, 0x0a6d5, 0x0a6d6, 0x0a6d7, - 0x0a6d8, 0x0a6d9, 0x0a6da, 0x0a6db, 0x0a6dc, 0x0a6dd, 0x0a6de, 0x0a6df, - 0x0a6e0, 0x0a6e1, 0x0a6e2, 0x0a6e3, 0x0a6e4, 0x0a6e5, 0x0a6e6, 0x0a6e7, - 0x0a6e8, 0x0a6e9, 0x0a6ea, 0x0a6eb, 0x0a6ec, 0x0a6ed, 0x0a6ee, 0x0a6ef, - 0x0a6f0, 0x0a6f1, 0x0a6f2, 0x0a6f3, 0x0a6f4, 0x0a6f5, 0x0a6f6, 0x0a6f7, - 0x0a6f8, 0x0a6f9, 0x0a6fa, 0x0a6fb, 0x0a6fc, 0x0a6fd, 0x0a6fe, 0x0a6ff, -}; - - -static const uint32_t nxt_unicode_block_14e[128] nxt_aligned(64) = { - 0x0a700, 0x0a701, 0x0a702, 0x0a703, 0x0a704, 0x0a705, 0x0a706, 0x0a707, - 0x0a708, 0x0a709, 0x0a70a, 0x0a70b, 0x0a70c, 0x0a70d, 0x0a70e, 0x0a70f, - 0x0a710, 0x0a711, 0x0a712, 0x0a713, 0x0a714, 0x0a715, 0x0a716, 0x0a717, - 0x0a718, 0x0a719, 0x0a71a, 0x0a71b, 0x0a71c, 0x0a71d, 0x0a71e, 0x0a71f, - 0x0a720, 0x0a721, 0x0a723, 0x0a723, 0x0a725, 0x0a725, 0x0a727, 0x0a727, - 0x0a729, 0x0a729, 0x0a72b, 0x0a72b, 0x0a72d, 0x0a72d, 0x0a72f, 0x0a72f, - 0x0a730, 0x0a731, 0x0a733, 0x0a733, 0x0a735, 0x0a735, 0x0a737, 0x0a737, - 0x0a739, 0x0a739, 0x0a73b, 0x0a73b, 0x0a73d, 0x0a73d, 0x0a73f, 0x0a73f, - 0x0a741, 0x0a741, 0x0a743, 0x0a743, 0x0a745, 0x0a745, 0x0a747, 0x0a747, - 0x0a749, 0x0a749, 0x0a74b, 0x0a74b, 0x0a74d, 0x0a74d, 0x0a74f, 0x0a74f, - 0x0a751, 0x0a751, 0x0a753, 0x0a753, 0x0a755, 0x0a755, 0x0a757, 0x0a757, - 0x0a759, 0x0a759, 0x0a75b, 0x0a75b, 0x0a75d, 0x0a75d, 0x0a75f, 0x0a75f, - 0x0a761, 0x0a761, 0x0a763, 0x0a763, 0x0a765, 0x0a765, 0x0a767, 0x0a767, - 0x0a769, 0x0a769, 0x0a76b, 0x0a76b, 0x0a76d, 0x0a76d, 0x0a76f, 0x0a76f, - 0x0a770, 0x0a771, 0x0a772, 0x0a773, 0x0a774, 0x0a775, 0x0a776, 0x0a777, - 0x0a778, 0x0a77a, 0x0a77a, 0x0a77c, 0x0a77c, 0x01d79, 0x0a77f, 0x0a77f, -}; - - -static const uint32_t nxt_unicode_block_14f[128] nxt_aligned(64) = { - 0x0a781, 0x0a781, 0x0a783, 0x0a783, 0x0a785, 0x0a785, 0x0a787, 0x0a787, - 0x0a788, 0x0a789, 0x0a78a, 0x0a78c, 0x0a78c, 0x00265, 0x0a78e, 0x0a78f, - 0x0a791, 0x0a791, 0x0a793, 0x0a793, 0x0a794, 0x0a795, 0x0a796, 0x0a797, - 0x0a798, 0x0a799, 0x0a79a, 0x0a79b, 0x0a79c, 0x0a79d, 0x0a79e, 0x0a79f, - 0x0a7a1, 0x0a7a1, 0x0a7a3, 0x0a7a3, 0x0a7a5, 0x0a7a5, 0x0a7a7, 0x0a7a7, - 0x0a7a9, 0x0a7a9, 0x00266, 0x0a7ab, 0x0a7ac, 0x0a7ad, 0x0a7ae, 0x0a7af, - 0x0a7b0, 0x0a7b1, 0x0a7b2, 0x0a7b3, 0x0a7b4, 0x0a7b5, 0x0a7b6, 0x0a7b7, - 0x0a7b8, 0x0a7b9, 0x0a7ba, 0x0a7bb, 0x0a7bc, 0x0a7bd, 0x0a7be, 0x0a7bf, - 0x0a7c0, 0x0a7c1, 0x0a7c2, 0x0a7c3, 0x0a7c4, 0x0a7c5, 0x0a7c6, 0x0a7c7, - 0x0a7c8, 0x0a7c9, 0x0a7ca, 0x0a7cb, 0x0a7cc, 0x0a7cd, 0x0a7ce, 0x0a7cf, - 0x0a7d0, 0x0a7d1, 0x0a7d2, 0x0a7d3, 0x0a7d4, 0x0a7d5, 0x0a7d6, 0x0a7d7, - 0x0a7d8, 0x0a7d9, 0x0a7da, 0x0a7db, 0x0a7dc, 0x0a7dd, 0x0a7de, 0x0a7df, - 0x0a7e0, 0x0a7e1, 0x0a7e2, 0x0a7e3, 0x0a7e4, 0x0a7e5, 0x0a7e6, 0x0a7e7, - 0x0a7e8, 0x0a7e9, 0x0a7ea, 0x0a7eb, 0x0a7ec, 0x0a7ed, 0x0a7ee, 0x0a7ef, - 0x0a7f0, 0x0a7f1, 0x0a7f2, 0x0a7f3, 0x0a7f4, 0x0a7f5, 0x0a7f6, 0x0a7f7, - 0x0a7f8, 0x0a7f9, 0x0a7fa, 0x0a7fb, 0x0a7fc, 0x0a7fd, 0x0a7fe, 0x0a7ff, -}; - - -static const uint32_t nxt_unicode_block_1fe[128] nxt_aligned(64) = { - 0x0ff00, 0x0ff01, 0x0ff02, 0x0ff03, 0x0ff04, 0x0ff05, 0x0ff06, 0x0ff07, - 0x0ff08, 0x0ff09, 0x0ff0a, 0x0ff0b, 0x0ff0c, 0x0ff0d, 0x0ff0e, 0x0ff0f, - 0x0ff10, 0x0ff11, 0x0ff12, 0x0ff13, 0x0ff14, 0x0ff15, 0x0ff16, 0x0ff17, - 0x0ff18, 0x0ff19, 0x0ff1a, 0x0ff1b, 0x0ff1c, 0x0ff1d, 0x0ff1e, 0x0ff1f, - 0x0ff20, 0x0ff41, 0x0ff42, 0x0ff43, 0x0ff44, 0x0ff45, 0x0ff46, 0x0ff47, - 0x0ff48, 0x0ff49, 0x0ff4a, 0x0ff4b, 0x0ff4c, 0x0ff4d, 0x0ff4e, 0x0ff4f, - 0x0ff50, 0x0ff51, 0x0ff52, 0x0ff53, 0x0ff54, 0x0ff55, 0x0ff56, 0x0ff57, - 0x0ff58, 0x0ff59, 0x0ff5a, 0x0ff3b, 0x0ff3c, 0x0ff3d, 0x0ff3e, 0x0ff3f, - 0x0ff40, 0x0ff41, 0x0ff42, 0x0ff43, 0x0ff44, 0x0ff45, 0x0ff46, 0x0ff47, - 0x0ff48, 0x0ff49, 0x0ff4a, 0x0ff4b, 0x0ff4c, 0x0ff4d, 0x0ff4e, 0x0ff4f, - 0x0ff50, 0x0ff51, 0x0ff52, 0x0ff53, 0x0ff54, 0x0ff55, 0x0ff56, 0x0ff57, - 0x0ff58, 0x0ff59, 0x0ff5a, 0x0ff5b, 0x0ff5c, 0x0ff5d, 0x0ff5e, 0x0ff5f, - 0x0ff60, 0x0ff61, 0x0ff62, 0x0ff63, 0x0ff64, 0x0ff65, 0x0ff66, 0x0ff67, - 0x0ff68, 0x0ff69, 0x0ff6a, 0x0ff6b, 0x0ff6c, 0x0ff6d, 0x0ff6e, 0x0ff6f, - 0x0ff70, 0x0ff71, 0x0ff72, 0x0ff73, 0x0ff74, 0x0ff75, 0x0ff76, 0x0ff77, - 0x0ff78, 0x0ff79, 0x0ff7a, 0x0ff7b, 0x0ff7c, 0x0ff7d, 0x0ff7e, 0x0ff7f, -}; - - -static const uint32_t nxt_unicode_block_208[40] nxt_aligned(64) = { - 0x10428, 0x10429, 0x1042a, 0x1042b, 0x1042c, 0x1042d, 0x1042e, 0x1042f, - 0x10430, 0x10431, 0x10432, 0x10433, 0x10434, 0x10435, 0x10436, 0x10437, - 0x10438, 0x10439, 0x1043a, 0x1043b, 0x1043c, 0x1043d, 0x1043e, 0x1043f, - 0x10440, 0x10441, 0x10442, 0x10443, 0x10444, 0x10445, 0x10446, 0x10447, - 0x10448, 0x10449, 0x1044a, 0x1044b, 0x1044c, 0x1044d, 0x1044e, 0x1044f, -}; - - -static const uint32_t *nxt_unicode_blocks[] nxt_aligned(64) = { - nxt_unicode_block_000, - nxt_unicode_block_001, - nxt_unicode_block_002, - nxt_unicode_block_003, - nxt_unicode_block_004, - NULL, - nxt_unicode_block_006, - nxt_unicode_block_007, - nxt_unicode_block_008, - nxt_unicode_block_009, - nxt_unicode_block_00a, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - nxt_unicode_block_021, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - nxt_unicode_block_03c, - nxt_unicode_block_03d, - nxt_unicode_block_03e, - nxt_unicode_block_03f, - NULL, - NULL, - nxt_unicode_block_042, - nxt_unicode_block_043, - NULL, - NULL, - NULL, - NULL, - NULL, - nxt_unicode_block_049, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - nxt_unicode_block_058, - nxt_unicode_block_059, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, From igor at sysoev.ru Wed Jun 1 12:50:21 2016 From: igor at sysoev.ru (Igor Sysoev) Date: Wed, 01 Jun 2016 12:50:21 +0000 Subject: [njs] String.toUpperCase(). Message-ID: details: http://hg.nginx.org/njs/rev/e411e0cbd20d branches: changeset: 101:e411e0cbd20d user: Igor Sysoev date: Fri Apr 15 18:01:40 2016 +0300 description: String.toUpperCase(). diffstat: njs/njs_string.c | 59 ++ njs/test/njs_unit_test.c | 27 + nxt/Makefile | 1 + nxt/nxt_stub.h | 7 + nxt/nxt_unicode_upper_case.h | 1108 +++++++++++++++++++++++++++++++++++++++++ nxt/nxt_unicode_upper_case.pl | 91 +++ nxt/nxt_utf8.c | 35 +- nxt/nxt_utf8.h | 2 + 8 files changed, 1328 insertions(+), 2 deletions(-) diffs (truncated from 1420 to 1000 lines): diff -r b7442865d9fa -r e411e0cbd20d njs/njs_string.c --- a/njs/njs_string.c Fri Apr 15 18:01:19 2016 +0300 +++ b/njs/njs_string.c Fri Apr 15 18:01:40 2016 +0300 @@ -1343,6 +1343,58 @@ njs_string_prototype_to_lower_case(njs_v } +/* + * String.toUpperCase(). + * The method supports only simple folding. For example, German "?" + * folding "\u00DF" to "\u0053\u0053" is not supported. + */ + +static njs_ret_t +njs_string_prototype_to_upper_case(njs_vm_t *vm, njs_value_t *args, + nxt_uint_t nargs, njs_index_t unused) +{ + size_t size; + u_char *p, *start; + const u_char *s, *end; + njs_string_prop_t string; + + (void) njs_string_prop(&string, &args[0]); + + start = njs_string_alloc(vm, &vm->retval, string.size, string.length); + if (nxt_slow_path(start == NULL)) { + return NXT_ERROR; + } + + p = start; + s = string.start; + size = string.size; + + if (string.length == 0 || string.length == size) { + /* Byte or ASCII string. */ + + while (size != 0) { + *p++ = nxt_upper_case(*s++); + size--; + } + + } else { + /* UTF-8 string. */ + end = s + size; + + while (size != 0) { + p = nxt_utf8_encode(p, nxt_utf8_upper_case(&s, end)); + size--; + } + + if (string.length >= NJS_STRING_MAP_OFFSET) { + njs_string_offset_map_init(start, string.size); + } + } + + return NXT_OK; +} + + static njs_ret_t njs_string_prototype_search(njs_vm_t *vm, njs_value_t *args, nxt_uint_t nargs, njs_index_t unused) @@ -1813,6 +1865,13 @@ static const njs_object_prop_t njs_stri { .type = NJS_METHOD, + .name = njs_string("toUpperCase"), + .value = njs_native_function(njs_string_prototype_to_upper_case, 0, + NJS_STRING_OBJECT_ARG, NJS_REGEXP_ARG), + }, + + { + .type = NJS_METHOD, .name = njs_string("search"), .value = njs_native_function(njs_string_prototype_search, 0, NJS_STRING_OBJECT_ARG, NJS_REGEXP_ARG), diff -r b7442865d9fa -r e411e0cbd20d njs/test/njs_unit_test.c --- a/njs/test/njs_unit_test.c Fri Apr 15 18:01:19 2016 +0300 +++ b/njs/test/njs_unit_test.c Fri Apr 15 18:01:40 2016 +0300 @@ -2754,6 +2754,33 @@ static njs_unit_test_t njs_test[] = { nxt_string("'???'.toLowerCase()"), nxt_string("???") }, + { nxt_string("'abc'.toUpperCase()"), + nxt_string("ABC") }, + + { nxt_string("'???'.toUpperCase()"), + nxt_string("???") }, + + { nxt_string("'???'.toUpperCase()"), + nxt_string("???") }, + + { nxt_string("var a = [];" + "for (code = 0; code <= 1114111; code++) {" + " var s = String.fromCharCode(code);" + " var n = s.toUpperCase();" + " if (s != n && s != n.toLowerCase())" + " a.push(code);" + "} a"), + nxt_string("181,305,383,453,456,459,498,837,962,976,977,981,982,1008,1009,1013,7835,8126") }, + + { nxt_string("var a = [];" + "for (code = 0; code <= 1114111; code++) {" + " var s = String.fromCharCode(code);" + " var n = s.toLowerCase();" + " if (s != n && s != n.toUpperCase())" + " a.push(code);" + "} a"), + nxt_string("304,453,456,459,498,1012,7838,8486,8490,8491") }, + { nxt_string("'abcdefgh'.search()"), nxt_string("0") }, diff -r b7442865d9fa -r e411e0cbd20d nxt/Makefile --- a/nxt/Makefile Fri Apr 15 18:01:19 2016 +0300 +++ b/nxt/Makefile Fri Apr 15 18:01:40 2016 +0300 @@ -48,6 +48,7 @@ NXT_LIB = nxt $(NXT_LIB)/nxt_clang.h \ $(NXT_LIB)/nxt_utf8.h \ $(NXT_LIB)/nxt_unicode_lower_case.h \ + $(NXT_LIB)/nxt_unicode_upper_case.h \ $(NXT_LIB)/nxt_utf8.c \ $(NXT_CC) -c -o $(NXT_BUILDDIR)/nxt_utf8.o $(NXT_CFLAGS) \ diff -r b7442865d9fa -r e411e0cbd20d nxt/nxt_stub.h --- a/nxt/nxt_stub.h Fri Apr 15 18:01:19 2016 +0300 +++ b/nxt/nxt_stub.h Fri Apr 15 18:01:40 2016 +0300 @@ -22,6 +22,13 @@ nxt_lower_case(u_char c) } +nxt_inline u_char +nxt_upper_case(u_char c) +{ + return (u_char) ((c >= 'a' && c <= 'z') ? c & 0xDF : c); +} + + #define nxt_strstr_eq(s1, s2) \ (((s1)->len == (s2)->len) \ && (memcmp((s1)->data, (s2)->data, (s1)->len) == 0)) diff -r b7442865d9fa -r e411e0cbd20d nxt/nxt_unicode_upper_case.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/nxt/nxt_unicode_upper_case.h Fri Apr 15 18:01:40 2016 +0300 @@ -0,0 +1,1108 @@ + +/* + * 29 128-bytes blocks, 521 pointers. + * 16496 bytes on 32-bit platforms, 18576 bytes on 64-bit platforms. + */ + +#define NXT_UNICODE_MAX_UPPER_CASE 0x1044f + +#define NXT_UNICODE_BLOCK_SIZE 128 + + +static const uint32_t nxt_unicode_upper_case_block_000[128] nxt_aligned(64) = { + 0x00000, 0x00001, 0x00002, 0x00003, 0x00004, 0x00005, 0x00006, 0x00007, + 0x00008, 0x00009, 0x0000a, 0x0000b, 0x0000c, 0x0000d, 0x0000e, 0x0000f, + 0x00010, 0x00011, 0x00012, 0x00013, 0x00014, 0x00015, 0x00016, 0x00017, + 0x00018, 0x00019, 0x0001a, 0x0001b, 0x0001c, 0x0001d, 0x0001e, 0x0001f, + 0x00020, 0x00021, 0x00022, 0x00023, 0x00024, 0x00025, 0x00026, 0x00027, + 0x00028, 0x00029, 0x0002a, 0x0002b, 0x0002c, 0x0002d, 0x0002e, 0x0002f, + 0x00030, 0x00031, 0x00032, 0x00033, 0x00034, 0x00035, 0x00036, 0x00037, + 0x00038, 0x00039, 0x0003a, 0x0003b, 0x0003c, 0x0003d, 0x0003e, 0x0003f, + 0x00040, 0x00041, 0x00042, 0x00043, 0x00044, 0x00045, 0x00046, 0x00047, + 0x00048, 0x00049, 0x0004a, 0x0004b, 0x0004c, 0x0004d, 0x0004e, 0x0004f, + 0x00050, 0x00051, 0x00052, 0x00053, 0x00054, 0x00055, 0x00056, 0x00057, + 0x00058, 0x00059, 0x0005a, 0x0005b, 0x0005c, 0x0005d, 0x0005e, 0x0005f, + 0x00060, 0x00041, 0x00042, 0x00043, 0x00044, 0x00045, 0x00046, 0x00047, + 0x00048, 0x00049, 0x0004a, 0x0004b, 0x0004c, 0x0004d, 0x0004e, 0x0004f, + 0x00050, 0x00051, 0x00052, 0x00053, 0x00054, 0x00055, 0x00056, 0x00057, + 0x00058, 0x00059, 0x0005a, 0x0007b, 0x0007c, 0x0007d, 0x0007e, 0x0007f, +}; + + +static const uint32_t nxt_unicode_upper_case_block_001[128] nxt_aligned(64) = { + 0x00080, 0x00081, 0x00082, 0x00083, 0x00084, 0x00085, 0x00086, 0x00087, + 0x00088, 0x00089, 0x0008a, 0x0008b, 0x0008c, 0x0008d, 0x0008e, 0x0008f, + 0x00090, 0x00091, 0x00092, 0x00093, 0x00094, 0x00095, 0x00096, 0x00097, + 0x00098, 0x00099, 0x0009a, 0x0009b, 0x0009c, 0x0009d, 0x0009e, 0x0009f, + 0x000a0, 0x000a1, 0x000a2, 0x000a3, 0x000a4, 0x000a5, 0x000a6, 0x000a7, + 0x000a8, 0x000a9, 0x000aa, 0x000ab, 0x000ac, 0x000ad, 0x000ae, 0x000af, + 0x000b0, 0x000b1, 0x000b2, 0x000b3, 0x000b4, 0x0039c, 0x000b6, 0x000b7, + 0x000b8, 0x000b9, 0x000ba, 0x000bb, 0x000bc, 0x000bd, 0x000be, 0x000bf, + 0x000c0, 0x000c1, 0x000c2, 0x000c3, 0x000c4, 0x000c5, 0x000c6, 0x000c7, + 0x000c8, 0x000c9, 0x000ca, 0x000cb, 0x000cc, 0x000cd, 0x000ce, 0x000cf, + 0x000d0, 0x000d1, 0x000d2, 0x000d3, 0x000d4, 0x000d5, 0x000d6, 0x000d7, + 0x000d8, 0x000d9, 0x000da, 0x000db, 0x000dc, 0x000dd, 0x000de, 0x000df, + 0x000c0, 0x000c1, 0x000c2, 0x000c3, 0x000c4, 0x000c5, 0x000c6, 0x000c7, + 0x000c8, 0x000c9, 0x000ca, 0x000cb, 0x000cc, 0x000cd, 0x000ce, 0x000cf, + 0x000d0, 0x000d1, 0x000d2, 0x000d3, 0x000d4, 0x000d5, 0x000d6, 0x000f7, + 0x000d8, 0x000d9, 0x000da, 0x000db, 0x000dc, 0x000dd, 0x000de, 0x00178, +}; + + +static const uint32_t nxt_unicode_upper_case_block_002[128] nxt_aligned(64) = { + 0x00100, 0x00100, 0x00102, 0x00102, 0x00104, 0x00104, 0x00106, 0x00106, + 0x00108, 0x00108, 0x0010a, 0x0010a, 0x0010c, 0x0010c, 0x0010e, 0x0010e, + 0x00110, 0x00110, 0x00112, 0x00112, 0x00114, 0x00114, 0x00116, 0x00116, + 0x00118, 0x00118, 0x0011a, 0x0011a, 0x0011c, 0x0011c, 0x0011e, 0x0011e, + 0x00120, 0x00120, 0x00122, 0x00122, 0x00124, 0x00124, 0x00126, 0x00126, + 0x00128, 0x00128, 0x0012a, 0x0012a, 0x0012c, 0x0012c, 0x0012e, 0x0012e, + 0x00130, 0x00049, 0x00132, 0x00132, 0x00134, 0x00134, 0x00136, 0x00136, + 0x00138, 0x00139, 0x00139, 0x0013b, 0x0013b, 0x0013d, 0x0013d, 0x0013f, + 0x0013f, 0x00141, 0x00141, 0x00143, 0x00143, 0x00145, 0x00145, 0x00147, + 0x00147, 0x00149, 0x0014a, 0x0014a, 0x0014c, 0x0014c, 0x0014e, 0x0014e, + 0x00150, 0x00150, 0x00152, 0x00152, 0x00154, 0x00154, 0x00156, 0x00156, + 0x00158, 0x00158, 0x0015a, 0x0015a, 0x0015c, 0x0015c, 0x0015e, 0x0015e, + 0x00160, 0x00160, 0x00162, 0x00162, 0x00164, 0x00164, 0x00166, 0x00166, + 0x00168, 0x00168, 0x0016a, 0x0016a, 0x0016c, 0x0016c, 0x0016e, 0x0016e, + 0x00170, 0x00170, 0x00172, 0x00172, 0x00174, 0x00174, 0x00176, 0x00176, + 0x00178, 0x00179, 0x00179, 0x0017b, 0x0017b, 0x0017d, 0x0017d, 0x00053, +}; + + +static const uint32_t nxt_unicode_upper_case_block_003[128] nxt_aligned(64) = { + 0x00243, 0x00181, 0x00182, 0x00182, 0x00184, 0x00184, 0x00186, 0x00187, + 0x00187, 0x00189, 0x0018a, 0x0018b, 0x0018b, 0x0018d, 0x0018e, 0x0018f, + 0x00190, 0x00191, 0x00191, 0x00193, 0x00194, 0x001f6, 0x00196, 0x00197, + 0x00198, 0x00198, 0x0023d, 0x0019b, 0x0019c, 0x0019d, 0x00220, 0x0019f, + 0x001a0, 0x001a0, 0x001a2, 0x001a2, 0x001a4, 0x001a4, 0x001a6, 0x001a7, + 0x001a7, 0x001a9, 0x001aa, 0x001ab, 0x001ac, 0x001ac, 0x001ae, 0x001af, + 0x001af, 0x001b1, 0x001b2, 0x001b3, 0x001b3, 0x001b5, 0x001b5, 0x001b7, + 0x001b8, 0x001b8, 0x001ba, 0x001bb, 0x001bc, 0x001bc, 0x001be, 0x001f7, + 0x001c0, 0x001c1, 0x001c2, 0x001c3, 0x001c4, 0x001c4, 0x001c4, 0x001c7, + 0x001c7, 0x001c7, 0x001ca, 0x001ca, 0x001ca, 0x001cd, 0x001cd, 0x001cf, + 0x001cf, 0x001d1, 0x001d1, 0x001d3, 0x001d3, 0x001d5, 0x001d5, 0x001d7, + 0x001d7, 0x001d9, 0x001d9, 0x001db, 0x001db, 0x0018e, 0x001de, 0x001de, + 0x001e0, 0x001e0, 0x001e2, 0x001e2, 0x001e4, 0x001e4, 0x001e6, 0x001e6, + 0x001e8, 0x001e8, 0x001ea, 0x001ea, 0x001ec, 0x001ec, 0x001ee, 0x001ee, + 0x001f0, 0x001f1, 0x001f1, 0x001f1, 0x001f4, 0x001f4, 0x001f6, 0x001f7, + 0x001f8, 0x001f8, 0x001fa, 0x001fa, 0x001fc, 0x001fc, 0x001fe, 0x001fe, +}; + + +static const uint32_t nxt_unicode_upper_case_block_004[128] nxt_aligned(64) = { + 0x00200, 0x00200, 0x00202, 0x00202, 0x00204, 0x00204, 0x00206, 0x00206, + 0x00208, 0x00208, 0x0020a, 0x0020a, 0x0020c, 0x0020c, 0x0020e, 0x0020e, + 0x00210, 0x00210, 0x00212, 0x00212, 0x00214, 0x00214, 0x00216, 0x00216, + 0x00218, 0x00218, 0x0021a, 0x0021a, 0x0021c, 0x0021c, 0x0021e, 0x0021e, + 0x00220, 0x00221, 0x00222, 0x00222, 0x00224, 0x00224, 0x00226, 0x00226, + 0x00228, 0x00228, 0x0022a, 0x0022a, 0x0022c, 0x0022c, 0x0022e, 0x0022e, + 0x00230, 0x00230, 0x00232, 0x00232, 0x00234, 0x00235, 0x00236, 0x00237, + 0x00238, 0x00239, 0x0023a, 0x0023b, 0x0023b, 0x0023d, 0x0023e, 0x02c7e, + 0x02c7f, 0x00241, 0x00241, 0x00243, 0x00244, 0x00245, 0x00246, 0x00246, + 0x00248, 0x00248, 0x0024a, 0x0024a, 0x0024c, 0x0024c, 0x0024e, 0x0024e, + 0x02c6f, 0x02c6d, 0x02c70, 0x00181, 0x00186, 0x00255, 0x00189, 0x0018a, + 0x00258, 0x0018f, 0x0025a, 0x00190, 0x0025c, 0x0025d, 0x0025e, 0x0025f, + 0x00193, 0x00261, 0x00262, 0x00194, 0x00264, 0x0a78d, 0x0a7aa, 0x00267, + 0x00197, 0x00196, 0x0026a, 0x02c62, 0x0026c, 0x0026d, 0x0026e, 0x0019c, + 0x00270, 0x02c6e, 0x0019d, 0x00273, 0x00274, 0x0019f, 0x00276, 0x00277, + 0x00278, 0x00279, 0x0027a, 0x0027b, 0x0027c, 0x02c64, 0x0027e, 0x0027f, +}; + + +static const uint32_t nxt_unicode_upper_case_block_005[128] nxt_aligned(64) = { + 0x001a6, 0x00281, 0x00282, 0x001a9, 0x00284, 0x00285, 0x00286, 0x00287, + 0x001ae, 0x00244, 0x001b1, 0x001b2, 0x00245, 0x0028d, 0x0028e, 0x0028f, + 0x00290, 0x00291, 0x001b7, 0x00293, 0x00294, 0x00295, 0x00296, 0x00297, + 0x00298, 0x00299, 0x0029a, 0x0029b, 0x0029c, 0x0029d, 0x0029e, 0x0029f, + 0x002a0, 0x002a1, 0x002a2, 0x002a3, 0x002a4, 0x002a5, 0x002a6, 0x002a7, + 0x002a8, 0x002a9, 0x002aa, 0x002ab, 0x002ac, 0x002ad, 0x002ae, 0x002af, + 0x002b0, 0x002b1, 0x002b2, 0x002b3, 0x002b4, 0x002b5, 0x002b6, 0x002b7, + 0x002b8, 0x002b9, 0x002ba, 0x002bb, 0x002bc, 0x002bd, 0x002be, 0x002bf, + 0x002c0, 0x002c1, 0x002c2, 0x002c3, 0x002c4, 0x002c5, 0x002c6, 0x002c7, + 0x002c8, 0x002c9, 0x002ca, 0x002cb, 0x002cc, 0x002cd, 0x002ce, 0x002cf, + 0x002d0, 0x002d1, 0x002d2, 0x002d3, 0x002d4, 0x002d5, 0x002d6, 0x002d7, + 0x002d8, 0x002d9, 0x002da, 0x002db, 0x002dc, 0x002dd, 0x002de, 0x002df, + 0x002e0, 0x002e1, 0x002e2, 0x002e3, 0x002e4, 0x002e5, 0x002e6, 0x002e7, + 0x002e8, 0x002e9, 0x002ea, 0x002eb, 0x002ec, 0x002ed, 0x002ee, 0x002ef, + 0x002f0, 0x002f1, 0x002f2, 0x002f3, 0x002f4, 0x002f5, 0x002f6, 0x002f7, + 0x002f8, 0x002f9, 0x002fa, 0x002fb, 0x002fc, 0x002fd, 0x002fe, 0x002ff, +}; + + +static const uint32_t nxt_unicode_upper_case_block_006[128] nxt_aligned(64) = { + 0x00300, 0x00301, 0x00302, 0x00303, 0x00304, 0x00305, 0x00306, 0x00307, + 0x00308, 0x00309, 0x0030a, 0x0030b, 0x0030c, 0x0030d, 0x0030e, 0x0030f, + 0x00310, 0x00311, 0x00312, 0x00313, 0x00314, 0x00315, 0x00316, 0x00317, + 0x00318, 0x00319, 0x0031a, 0x0031b, 0x0031c, 0x0031d, 0x0031e, 0x0031f, + 0x00320, 0x00321, 0x00322, 0x00323, 0x00324, 0x00325, 0x00326, 0x00327, + 0x00328, 0x00329, 0x0032a, 0x0032b, 0x0032c, 0x0032d, 0x0032e, 0x0032f, + 0x00330, 0x00331, 0x00332, 0x00333, 0x00334, 0x00335, 0x00336, 0x00337, + 0x00338, 0x00339, 0x0033a, 0x0033b, 0x0033c, 0x0033d, 0x0033e, 0x0033f, + 0x00340, 0x00341, 0x00342, 0x00343, 0x00344, 0x00399, 0x00346, 0x00347, + 0x00348, 0x00349, 0x0034a, 0x0034b, 0x0034c, 0x0034d, 0x0034e, 0x0034f, + 0x00350, 0x00351, 0x00352, 0x00353, 0x00354, 0x00355, 0x00356, 0x00357, + 0x00358, 0x00359, 0x0035a, 0x0035b, 0x0035c, 0x0035d, 0x0035e, 0x0035f, + 0x00360, 0x00361, 0x00362, 0x00363, 0x00364, 0x00365, 0x00366, 0x00367, + 0x00368, 0x00369, 0x0036a, 0x0036b, 0x0036c, 0x0036d, 0x0036e, 0x0036f, + 0x00370, 0x00370, 0x00372, 0x00372, 0x00374, 0x00375, 0x00376, 0x00376, + 0x00378, 0x00379, 0x0037a, 0x003fd, 0x003fe, 0x003ff, 0x0037e, 0x0037f, +}; + + +static const uint32_t nxt_unicode_upper_case_block_007[128] nxt_aligned(64) = { + 0x00380, 0x00381, 0x00382, 0x00383, 0x00384, 0x00385, 0x00386, 0x00387, + 0x00388, 0x00389, 0x0038a, 0x0038b, 0x0038c, 0x0038d, 0x0038e, 0x0038f, + 0x00390, 0x00391, 0x00392, 0x00393, 0x00394, 0x00395, 0x00396, 0x00397, + 0x00398, 0x00399, 0x0039a, 0x0039b, 0x0039c, 0x0039d, 0x0039e, 0x0039f, + 0x003a0, 0x003a1, 0x003a2, 0x003a3, 0x003a4, 0x003a5, 0x003a6, 0x003a7, + 0x003a8, 0x003a9, 0x003aa, 0x003ab, 0x00386, 0x00388, 0x00389, 0x0038a, + 0x003b0, 0x00391, 0x00392, 0x00393, 0x00394, 0x00395, 0x00396, 0x00397, + 0x00398, 0x00399, 0x0039a, 0x0039b, 0x0039c, 0x0039d, 0x0039e, 0x0039f, + 0x003a0, 0x003a1, 0x003a3, 0x003a3, 0x003a4, 0x003a5, 0x003a6, 0x003a7, + 0x003a8, 0x003a9, 0x003aa, 0x003ab, 0x0038c, 0x0038e, 0x0038f, 0x003cf, + 0x00392, 0x00398, 0x003d2, 0x003d3, 0x003d4, 0x003a6, 0x003a0, 0x003cf, + 0x003d8, 0x003d8, 0x003da, 0x003da, 0x003dc, 0x003dc, 0x003de, 0x003de, + 0x003e0, 0x003e0, 0x003e2, 0x003e2, 0x003e4, 0x003e4, 0x003e6, 0x003e6, + 0x003e8, 0x003e8, 0x003ea, 0x003ea, 0x003ec, 0x003ec, 0x003ee, 0x003ee, + 0x0039a, 0x003a1, 0x003f9, 0x003f3, 0x003f4, 0x00395, 0x003f6, 0x003f7, + 0x003f7, 0x003f9, 0x003fa, 0x003fa, 0x003fc, 0x003fd, 0x003fe, 0x003ff, +}; + + +static const uint32_t nxt_unicode_upper_case_block_008[128] nxt_aligned(64) = { + 0x00400, 0x00401, 0x00402, 0x00403, 0x00404, 0x00405, 0x00406, 0x00407, + 0x00408, 0x00409, 0x0040a, 0x0040b, 0x0040c, 0x0040d, 0x0040e, 0x0040f, + 0x00410, 0x00411, 0x00412, 0x00413, 0x00414, 0x00415, 0x00416, 0x00417, + 0x00418, 0x00419, 0x0041a, 0x0041b, 0x0041c, 0x0041d, 0x0041e, 0x0041f, + 0x00420, 0x00421, 0x00422, 0x00423, 0x00424, 0x00425, 0x00426, 0x00427, + 0x00428, 0x00429, 0x0042a, 0x0042b, 0x0042c, 0x0042d, 0x0042e, 0x0042f, + 0x00410, 0x00411, 0x00412, 0x00413, 0x00414, 0x00415, 0x00416, 0x00417, + 0x00418, 0x00419, 0x0041a, 0x0041b, 0x0041c, 0x0041d, 0x0041e, 0x0041f, + 0x00420, 0x00421, 0x00422, 0x00423, 0x00424, 0x00425, 0x00426, 0x00427, + 0x00428, 0x00429, 0x0042a, 0x0042b, 0x0042c, 0x0042d, 0x0042e, 0x0042f, + 0x00400, 0x00401, 0x00402, 0x00403, 0x00404, 0x00405, 0x00406, 0x00407, + 0x00408, 0x00409, 0x0040a, 0x0040b, 0x0040c, 0x0040d, 0x0040e, 0x0040f, + 0x00460, 0x00460, 0x00462, 0x00462, 0x00464, 0x00464, 0x00466, 0x00466, + 0x00468, 0x00468, 0x0046a, 0x0046a, 0x0046c, 0x0046c, 0x0046e, 0x0046e, + 0x00470, 0x00470, 0x00472, 0x00472, 0x00474, 0x00474, 0x00476, 0x00476, + 0x00478, 0x00478, 0x0047a, 0x0047a, 0x0047c, 0x0047c, 0x0047e, 0x0047e, +}; + + +static const uint32_t nxt_unicode_upper_case_block_009[128] nxt_aligned(64) = { + 0x00480, 0x00480, 0x00482, 0x00483, 0x00484, 0x00485, 0x00486, 0x00487, + 0x00488, 0x00489, 0x0048a, 0x0048a, 0x0048c, 0x0048c, 0x0048e, 0x0048e, + 0x00490, 0x00490, 0x00492, 0x00492, 0x00494, 0x00494, 0x00496, 0x00496, + 0x00498, 0x00498, 0x0049a, 0x0049a, 0x0049c, 0x0049c, 0x0049e, 0x0049e, + 0x004a0, 0x004a0, 0x004a2, 0x004a2, 0x004a4, 0x004a4, 0x004a6, 0x004a6, + 0x004a8, 0x004a8, 0x004aa, 0x004aa, 0x004ac, 0x004ac, 0x004ae, 0x004ae, + 0x004b0, 0x004b0, 0x004b2, 0x004b2, 0x004b4, 0x004b4, 0x004b6, 0x004b6, + 0x004b8, 0x004b8, 0x004ba, 0x004ba, 0x004bc, 0x004bc, 0x004be, 0x004be, + 0x004c0, 0x004c1, 0x004c1, 0x004c3, 0x004c3, 0x004c5, 0x004c5, 0x004c7, + 0x004c7, 0x004c9, 0x004c9, 0x004cb, 0x004cb, 0x004cd, 0x004cd, 0x004c0, + 0x004d0, 0x004d0, 0x004d2, 0x004d2, 0x004d4, 0x004d4, 0x004d6, 0x004d6, + 0x004d8, 0x004d8, 0x004da, 0x004da, 0x004dc, 0x004dc, 0x004de, 0x004de, + 0x004e0, 0x004e0, 0x004e2, 0x004e2, 0x004e4, 0x004e4, 0x004e6, 0x004e6, + 0x004e8, 0x004e8, 0x004ea, 0x004ea, 0x004ec, 0x004ec, 0x004ee, 0x004ee, + 0x004f0, 0x004f0, 0x004f2, 0x004f2, 0x004f4, 0x004f4, 0x004f6, 0x004f6, + 0x004f8, 0x004f8, 0x004fa, 0x004fa, 0x004fc, 0x004fc, 0x004fe, 0x004fe, +}; + + +static const uint32_t nxt_unicode_upper_case_block_00a[128] nxt_aligned(64) = { + 0x00500, 0x00500, 0x00502, 0x00502, 0x00504, 0x00504, 0x00506, 0x00506, + 0x00508, 0x00508, 0x0050a, 0x0050a, 0x0050c, 0x0050c, 0x0050e, 0x0050e, + 0x00510, 0x00510, 0x00512, 0x00512, 0x00514, 0x00514, 0x00516, 0x00516, + 0x00518, 0x00518, 0x0051a, 0x0051a, 0x0051c, 0x0051c, 0x0051e, 0x0051e, + 0x00520, 0x00520, 0x00522, 0x00522, 0x00524, 0x00524, 0x00526, 0x00526, + 0x00528, 0x00529, 0x0052a, 0x0052b, 0x0052c, 0x0052d, 0x0052e, 0x0052f, + 0x00530, 0x00531, 0x00532, 0x00533, 0x00534, 0x00535, 0x00536, 0x00537, + 0x00538, 0x00539, 0x0053a, 0x0053b, 0x0053c, 0x0053d, 0x0053e, 0x0053f, + 0x00540, 0x00541, 0x00542, 0x00543, 0x00544, 0x00545, 0x00546, 0x00547, + 0x00548, 0x00549, 0x0054a, 0x0054b, 0x0054c, 0x0054d, 0x0054e, 0x0054f, + 0x00550, 0x00551, 0x00552, 0x00553, 0x00554, 0x00555, 0x00556, 0x00557, + 0x00558, 0x00559, 0x0055a, 0x0055b, 0x0055c, 0x0055d, 0x0055e, 0x0055f, + 0x00560, 0x00531, 0x00532, 0x00533, 0x00534, 0x00535, 0x00536, 0x00537, + 0x00538, 0x00539, 0x0053a, 0x0053b, 0x0053c, 0x0053d, 0x0053e, 0x0053f, + 0x00540, 0x00541, 0x00542, 0x00543, 0x00544, 0x00545, 0x00546, 0x00547, + 0x00548, 0x00549, 0x0054a, 0x0054b, 0x0054c, 0x0054d, 0x0054e, 0x0054f, +}; + + +static const uint32_t nxt_unicode_upper_case_block_00b[128] nxt_aligned(64) = { + 0x00550, 0x00551, 0x00552, 0x00553, 0x00554, 0x00555, 0x00556, 0x00587, + 0x00588, 0x00589, 0x0058a, 0x0058b, 0x0058c, 0x0058d, 0x0058e, 0x0058f, + 0x00590, 0x00591, 0x00592, 0x00593, 0x00594, 0x00595, 0x00596, 0x00597, + 0x00598, 0x00599, 0x0059a, 0x0059b, 0x0059c, 0x0059d, 0x0059e, 0x0059f, + 0x005a0, 0x005a1, 0x005a2, 0x005a3, 0x005a4, 0x005a5, 0x005a6, 0x005a7, + 0x005a8, 0x005a9, 0x005aa, 0x005ab, 0x005ac, 0x005ad, 0x005ae, 0x005af, + 0x005b0, 0x005b1, 0x005b2, 0x005b3, 0x005b4, 0x005b5, 0x005b6, 0x005b7, + 0x005b8, 0x005b9, 0x005ba, 0x005bb, 0x005bc, 0x005bd, 0x005be, 0x005bf, + 0x005c0, 0x005c1, 0x005c2, 0x005c3, 0x005c4, 0x005c5, 0x005c6, 0x005c7, + 0x005c8, 0x005c9, 0x005ca, 0x005cb, 0x005cc, 0x005cd, 0x005ce, 0x005cf, + 0x005d0, 0x005d1, 0x005d2, 0x005d3, 0x005d4, 0x005d5, 0x005d6, 0x005d7, + 0x005d8, 0x005d9, 0x005da, 0x005db, 0x005dc, 0x005dd, 0x005de, 0x005df, + 0x005e0, 0x005e1, 0x005e2, 0x005e3, 0x005e4, 0x005e5, 0x005e6, 0x005e7, + 0x005e8, 0x005e9, 0x005ea, 0x005eb, 0x005ec, 0x005ed, 0x005ee, 0x005ef, + 0x005f0, 0x005f1, 0x005f2, 0x005f3, 0x005f4, 0x005f5, 0x005f6, 0x005f7, + 0x005f8, 0x005f9, 0x005fa, 0x005fb, 0x005fc, 0x005fd, 0x005fe, 0x005ff, +}; + + +static const uint32_t nxt_unicode_upper_case_block_03a[128] nxt_aligned(64) = { + 0x01d00, 0x01d01, 0x01d02, 0x01d03, 0x01d04, 0x01d05, 0x01d06, 0x01d07, + 0x01d08, 0x01d09, 0x01d0a, 0x01d0b, 0x01d0c, 0x01d0d, 0x01d0e, 0x01d0f, + 0x01d10, 0x01d11, 0x01d12, 0x01d13, 0x01d14, 0x01d15, 0x01d16, 0x01d17, + 0x01d18, 0x01d19, 0x01d1a, 0x01d1b, 0x01d1c, 0x01d1d, 0x01d1e, 0x01d1f, + 0x01d20, 0x01d21, 0x01d22, 0x01d23, 0x01d24, 0x01d25, 0x01d26, 0x01d27, + 0x01d28, 0x01d29, 0x01d2a, 0x01d2b, 0x01d2c, 0x01d2d, 0x01d2e, 0x01d2f, + 0x01d30, 0x01d31, 0x01d32, 0x01d33, 0x01d34, 0x01d35, 0x01d36, 0x01d37, + 0x01d38, 0x01d39, 0x01d3a, 0x01d3b, 0x01d3c, 0x01d3d, 0x01d3e, 0x01d3f, + 0x01d40, 0x01d41, 0x01d42, 0x01d43, 0x01d44, 0x01d45, 0x01d46, 0x01d47, + 0x01d48, 0x01d49, 0x01d4a, 0x01d4b, 0x01d4c, 0x01d4d, 0x01d4e, 0x01d4f, + 0x01d50, 0x01d51, 0x01d52, 0x01d53, 0x01d54, 0x01d55, 0x01d56, 0x01d57, + 0x01d58, 0x01d59, 0x01d5a, 0x01d5b, 0x01d5c, 0x01d5d, 0x01d5e, 0x01d5f, + 0x01d60, 0x01d61, 0x01d62, 0x01d63, 0x01d64, 0x01d65, 0x01d66, 0x01d67, + 0x01d68, 0x01d69, 0x01d6a, 0x01d6b, 0x01d6c, 0x01d6d, 0x01d6e, 0x01d6f, + 0x01d70, 0x01d71, 0x01d72, 0x01d73, 0x01d74, 0x01d75, 0x01d76, 0x01d77, + 0x01d78, 0x0a77d, 0x01d7a, 0x01d7b, 0x01d7c, 0x02c63, 0x01d7e, 0x01d7f, +}; + + +static const uint32_t nxt_unicode_upper_case_block_03c[128] nxt_aligned(64) = { + 0x01e00, 0x01e00, 0x01e02, 0x01e02, 0x01e04, 0x01e04, 0x01e06, 0x01e06, + 0x01e08, 0x01e08, 0x01e0a, 0x01e0a, 0x01e0c, 0x01e0c, 0x01e0e, 0x01e0e, + 0x01e10, 0x01e10, 0x01e12, 0x01e12, 0x01e14, 0x01e14, 0x01e16, 0x01e16, + 0x01e18, 0x01e18, 0x01e1a, 0x01e1a, 0x01e1c, 0x01e1c, 0x01e1e, 0x01e1e, + 0x01e20, 0x01e20, 0x01e22, 0x01e22, 0x01e24, 0x01e24, 0x01e26, 0x01e26, + 0x01e28, 0x01e28, 0x01e2a, 0x01e2a, 0x01e2c, 0x01e2c, 0x01e2e, 0x01e2e, + 0x01e30, 0x01e30, 0x01e32, 0x01e32, 0x01e34, 0x01e34, 0x01e36, 0x01e36, + 0x01e38, 0x01e38, 0x01e3a, 0x01e3a, 0x01e3c, 0x01e3c, 0x01e3e, 0x01e3e, + 0x01e40, 0x01e40, 0x01e42, 0x01e42, 0x01e44, 0x01e44, 0x01e46, 0x01e46, + 0x01e48, 0x01e48, 0x01e4a, 0x01e4a, 0x01e4c, 0x01e4c, 0x01e4e, 0x01e4e, + 0x01e50, 0x01e50, 0x01e52, 0x01e52, 0x01e54, 0x01e54, 0x01e56, 0x01e56, + 0x01e58, 0x01e58, 0x01e5a, 0x01e5a, 0x01e5c, 0x01e5c, 0x01e5e, 0x01e5e, + 0x01e60, 0x01e60, 0x01e62, 0x01e62, 0x01e64, 0x01e64, 0x01e66, 0x01e66, + 0x01e68, 0x01e68, 0x01e6a, 0x01e6a, 0x01e6c, 0x01e6c, 0x01e6e, 0x01e6e, + 0x01e70, 0x01e70, 0x01e72, 0x01e72, 0x01e74, 0x01e74, 0x01e76, 0x01e76, + 0x01e78, 0x01e78, 0x01e7a, 0x01e7a, 0x01e7c, 0x01e7c, 0x01e7e, 0x01e7e, +}; + + +static const uint32_t nxt_unicode_upper_case_block_03d[128] nxt_aligned(64) = { + 0x01e80, 0x01e80, 0x01e82, 0x01e82, 0x01e84, 0x01e84, 0x01e86, 0x01e86, + 0x01e88, 0x01e88, 0x01e8a, 0x01e8a, 0x01e8c, 0x01e8c, 0x01e8e, 0x01e8e, + 0x01e90, 0x01e90, 0x01e92, 0x01e92, 0x01e94, 0x01e94, 0x01e96, 0x01e97, + 0x01e98, 0x01e99, 0x01e9a, 0x01e60, 0x01e9c, 0x01e9d, 0x01e9e, 0x01e9f, + 0x01ea0, 0x01ea0, 0x01ea2, 0x01ea2, 0x01ea4, 0x01ea4, 0x01ea6, 0x01ea6, + 0x01ea8, 0x01ea8, 0x01eaa, 0x01eaa, 0x01eac, 0x01eac, 0x01eae, 0x01eae, + 0x01eb0, 0x01eb0, 0x01eb2, 0x01eb2, 0x01eb4, 0x01eb4, 0x01eb6, 0x01eb6, + 0x01eb8, 0x01eb8, 0x01eba, 0x01eba, 0x01ebc, 0x01ebc, 0x01ebe, 0x01ebe, + 0x01ec0, 0x01ec0, 0x01ec2, 0x01ec2, 0x01ec4, 0x01ec4, 0x01ec6, 0x01ec6, + 0x01ec8, 0x01ec8, 0x01eca, 0x01eca, 0x01ecc, 0x01ecc, 0x01ece, 0x01ece, + 0x01ed0, 0x01ed0, 0x01ed2, 0x01ed2, 0x01ed4, 0x01ed4, 0x01ed6, 0x01ed6, + 0x01ed8, 0x01ed8, 0x01eda, 0x01eda, 0x01edc, 0x01edc, 0x01ede, 0x01ede, + 0x01ee0, 0x01ee0, 0x01ee2, 0x01ee2, 0x01ee4, 0x01ee4, 0x01ee6, 0x01ee6, + 0x01ee8, 0x01ee8, 0x01eea, 0x01eea, 0x01eec, 0x01eec, 0x01eee, 0x01eee, + 0x01ef0, 0x01ef0, 0x01ef2, 0x01ef2, 0x01ef4, 0x01ef4, 0x01ef6, 0x01ef6, + 0x01ef8, 0x01ef8, 0x01efa, 0x01efa, 0x01efc, 0x01efc, 0x01efe, 0x01efe, +}; + + +static const uint32_t nxt_unicode_upper_case_block_03e[128] nxt_aligned(64) = { + 0x01f08, 0x01f09, 0x01f0a, 0x01f0b, 0x01f0c, 0x01f0d, 0x01f0e, 0x01f0f, + 0x01f08, 0x01f09, 0x01f0a, 0x01f0b, 0x01f0c, 0x01f0d, 0x01f0e, 0x01f0f, + 0x01f18, 0x01f19, 0x01f1a, 0x01f1b, 0x01f1c, 0x01f1d, 0x01f16, 0x01f17, + 0x01f18, 0x01f19, 0x01f1a, 0x01f1b, 0x01f1c, 0x01f1d, 0x01f1e, 0x01f1f, + 0x01f28, 0x01f29, 0x01f2a, 0x01f2b, 0x01f2c, 0x01f2d, 0x01f2e, 0x01f2f, + 0x01f28, 0x01f29, 0x01f2a, 0x01f2b, 0x01f2c, 0x01f2d, 0x01f2e, 0x01f2f, + 0x01f38, 0x01f39, 0x01f3a, 0x01f3b, 0x01f3c, 0x01f3d, 0x01f3e, 0x01f3f, + 0x01f38, 0x01f39, 0x01f3a, 0x01f3b, 0x01f3c, 0x01f3d, 0x01f3e, 0x01f3f, + 0x01f48, 0x01f49, 0x01f4a, 0x01f4b, 0x01f4c, 0x01f4d, 0x01f46, 0x01f47, + 0x01f48, 0x01f49, 0x01f4a, 0x01f4b, 0x01f4c, 0x01f4d, 0x01f4e, 0x01f4f, + 0x01f50, 0x01f59, 0x01f52, 0x01f5b, 0x01f54, 0x01f5d, 0x01f56, 0x01f5f, + 0x01f58, 0x01f59, 0x01f5a, 0x01f5b, 0x01f5c, 0x01f5d, 0x01f5e, 0x01f5f, + 0x01f68, 0x01f69, 0x01f6a, 0x01f6b, 0x01f6c, 0x01f6d, 0x01f6e, 0x01f6f, + 0x01f68, 0x01f69, 0x01f6a, 0x01f6b, 0x01f6c, 0x01f6d, 0x01f6e, 0x01f6f, + 0x01fba, 0x01fbb, 0x01fc8, 0x01fc9, 0x01fca, 0x01fcb, 0x01fda, 0x01fdb, + 0x01ff8, 0x01ff9, 0x01fea, 0x01feb, 0x01ffa, 0x01ffb, 0x01f7e, 0x01f7f, +}; + + +static const uint32_t nxt_unicode_upper_case_block_03f[128] nxt_aligned(64) = { + 0x01f88, 0x01f89, 0x01f8a, 0x01f8b, 0x01f8c, 0x01f8d, 0x01f8e, 0x01f8f, + 0x01f88, 0x01f89, 0x01f8a, 0x01f8b, 0x01f8c, 0x01f8d, 0x01f8e, 0x01f8f, + 0x01f98, 0x01f99, 0x01f9a, 0x01f9b, 0x01f9c, 0x01f9d, 0x01f9e, 0x01f9f, + 0x01f98, 0x01f99, 0x01f9a, 0x01f9b, 0x01f9c, 0x01f9d, 0x01f9e, 0x01f9f, + 0x01fa8, 0x01fa9, 0x01faa, 0x01fab, 0x01fac, 0x01fad, 0x01fae, 0x01faf, + 0x01fa8, 0x01fa9, 0x01faa, 0x01fab, 0x01fac, 0x01fad, 0x01fae, 0x01faf, + 0x01fb8, 0x01fb9, 0x01fb2, 0x01fbc, 0x01fb4, 0x01fb5, 0x01fb6, 0x01fb7, + 0x01fb8, 0x01fb9, 0x01fba, 0x01fbb, 0x01fbc, 0x01fbd, 0x00399, 0x01fbf, + 0x01fc0, 0x01fc1, 0x01fc2, 0x01fcc, 0x01fc4, 0x01fc5, 0x01fc6, 0x01fc7, + 0x01fc8, 0x01fc9, 0x01fca, 0x01fcb, 0x01fcc, 0x01fcd, 0x01fce, 0x01fcf, + 0x01fd8, 0x01fd9, 0x01fd2, 0x01fd3, 0x01fd4, 0x01fd5, 0x01fd6, 0x01fd7, + 0x01fd8, 0x01fd9, 0x01fda, 0x01fdb, 0x01fdc, 0x01fdd, 0x01fde, 0x01fdf, + 0x01fe8, 0x01fe9, 0x01fe2, 0x01fe3, 0x01fe4, 0x01fec, 0x01fe6, 0x01fe7, + 0x01fe8, 0x01fe9, 0x01fea, 0x01feb, 0x01fec, 0x01fed, 0x01fee, 0x01fef, + 0x01ff0, 0x01ff1, 0x01ff2, 0x01ffc, 0x01ff4, 0x01ff5, 0x01ff6, 0x01ff7, + 0x01ff8, 0x01ff9, 0x01ffa, 0x01ffb, 0x01ffc, 0x01ffd, 0x01ffe, 0x01fff, +}; + + +static const uint32_t nxt_unicode_upper_case_block_042[128] nxt_aligned(64) = { + 0x02100, 0x02101, 0x02102, 0x02103, 0x02104, 0x02105, 0x02106, 0x02107, + 0x02108, 0x02109, 0x0210a, 0x0210b, 0x0210c, 0x0210d, 0x0210e, 0x0210f, + 0x02110, 0x02111, 0x02112, 0x02113, 0x02114, 0x02115, 0x02116, 0x02117, + 0x02118, 0x02119, 0x0211a, 0x0211b, 0x0211c, 0x0211d, 0x0211e, 0x0211f, + 0x02120, 0x02121, 0x02122, 0x02123, 0x02124, 0x02125, 0x02126, 0x02127, + 0x02128, 0x02129, 0x0212a, 0x0212b, 0x0212c, 0x0212d, 0x0212e, 0x0212f, + 0x02130, 0x02131, 0x02132, 0x02133, 0x02134, 0x02135, 0x02136, 0x02137, + 0x02138, 0x02139, 0x0213a, 0x0213b, 0x0213c, 0x0213d, 0x0213e, 0x0213f, + 0x02140, 0x02141, 0x02142, 0x02143, 0x02144, 0x02145, 0x02146, 0x02147, + 0x02148, 0x02149, 0x0214a, 0x0214b, 0x0214c, 0x0214d, 0x02132, 0x0214f, + 0x02150, 0x02151, 0x02152, 0x02153, 0x02154, 0x02155, 0x02156, 0x02157, + 0x02158, 0x02159, 0x0215a, 0x0215b, 0x0215c, 0x0215d, 0x0215e, 0x0215f, + 0x02160, 0x02161, 0x02162, 0x02163, 0x02164, 0x02165, 0x02166, 0x02167, + 0x02168, 0x02169, 0x0216a, 0x0216b, 0x0216c, 0x0216d, 0x0216e, 0x0216f, + 0x02160, 0x02161, 0x02162, 0x02163, 0x02164, 0x02165, 0x02166, 0x02167, + 0x02168, 0x02169, 0x0216a, 0x0216b, 0x0216c, 0x0216d, 0x0216e, 0x0216f, +}; + + +static const uint32_t nxt_unicode_upper_case_block_043[128] nxt_aligned(64) = { + 0x02180, 0x02181, 0x02182, 0x02183, 0x02183, 0x02185, 0x02186, 0x02187, + 0x02188, 0x02189, 0x0218a, 0x0218b, 0x0218c, 0x0218d, 0x0218e, 0x0218f, + 0x02190, 0x02191, 0x02192, 0x02193, 0x02194, 0x02195, 0x02196, 0x02197, + 0x02198, 0x02199, 0x0219a, 0x0219b, 0x0219c, 0x0219d, 0x0219e, 0x0219f, + 0x021a0, 0x021a1, 0x021a2, 0x021a3, 0x021a4, 0x021a5, 0x021a6, 0x021a7, + 0x021a8, 0x021a9, 0x021aa, 0x021ab, 0x021ac, 0x021ad, 0x021ae, 0x021af, + 0x021b0, 0x021b1, 0x021b2, 0x021b3, 0x021b4, 0x021b5, 0x021b6, 0x021b7, + 0x021b8, 0x021b9, 0x021ba, 0x021bb, 0x021bc, 0x021bd, 0x021be, 0x021bf, + 0x021c0, 0x021c1, 0x021c2, 0x021c3, 0x021c4, 0x021c5, 0x021c6, 0x021c7, + 0x021c8, 0x021c9, 0x021ca, 0x021cb, 0x021cc, 0x021cd, 0x021ce, 0x021cf, + 0x021d0, 0x021d1, 0x021d2, 0x021d3, 0x021d4, 0x021d5, 0x021d6, 0x021d7, + 0x021d8, 0x021d9, 0x021da, 0x021db, 0x021dc, 0x021dd, 0x021de, 0x021df, + 0x021e0, 0x021e1, 0x021e2, 0x021e3, 0x021e4, 0x021e5, 0x021e6, 0x021e7, + 0x021e8, 0x021e9, 0x021ea, 0x021eb, 0x021ec, 0x021ed, 0x021ee, 0x021ef, + 0x021f0, 0x021f1, 0x021f2, 0x021f3, 0x021f4, 0x021f5, 0x021f6, 0x021f7, + 0x021f8, 0x021f9, 0x021fa, 0x021fb, 0x021fc, 0x021fd, 0x021fe, 0x021ff, +}; + + +static const uint32_t nxt_unicode_upper_case_block_049[128] nxt_aligned(64) = { + 0x02480, 0x02481, 0x02482, 0x02483, 0x02484, 0x02485, 0x02486, 0x02487, + 0x02488, 0x02489, 0x0248a, 0x0248b, 0x0248c, 0x0248d, 0x0248e, 0x0248f, + 0x02490, 0x02491, 0x02492, 0x02493, 0x02494, 0x02495, 0x02496, 0x02497, + 0x02498, 0x02499, 0x0249a, 0x0249b, 0x0249c, 0x0249d, 0x0249e, 0x0249f, + 0x024a0, 0x024a1, 0x024a2, 0x024a3, 0x024a4, 0x024a5, 0x024a6, 0x024a7, + 0x024a8, 0x024a9, 0x024aa, 0x024ab, 0x024ac, 0x024ad, 0x024ae, 0x024af, + 0x024b0, 0x024b1, 0x024b2, 0x024b3, 0x024b4, 0x024b5, 0x024b6, 0x024b7, + 0x024b8, 0x024b9, 0x024ba, 0x024bb, 0x024bc, 0x024bd, 0x024be, 0x024bf, + 0x024c0, 0x024c1, 0x024c2, 0x024c3, 0x024c4, 0x024c5, 0x024c6, 0x024c7, + 0x024c8, 0x024c9, 0x024ca, 0x024cb, 0x024cc, 0x024cd, 0x024ce, 0x024cf, + 0x024b6, 0x024b7, 0x024b8, 0x024b9, 0x024ba, 0x024bb, 0x024bc, 0x024bd, + 0x024be, 0x024bf, 0x024c0, 0x024c1, 0x024c2, 0x024c3, 0x024c4, 0x024c5, + 0x024c6, 0x024c7, 0x024c8, 0x024c9, 0x024ca, 0x024cb, 0x024cc, 0x024cd, + 0x024ce, 0x024cf, 0x024ea, 0x024eb, 0x024ec, 0x024ed, 0x024ee, 0x024ef, + 0x024f0, 0x024f1, 0x024f2, 0x024f3, 0x024f4, 0x024f5, 0x024f6, 0x024f7, + 0x024f8, 0x024f9, 0x024fa, 0x024fb, 0x024fc, 0x024fd, 0x024fe, 0x024ff, +}; + + +static const uint32_t nxt_unicode_upper_case_block_058[128] nxt_aligned(64) = { + 0x02c00, 0x02c01, 0x02c02, 0x02c03, 0x02c04, 0x02c05, 0x02c06, 0x02c07, + 0x02c08, 0x02c09, 0x02c0a, 0x02c0b, 0x02c0c, 0x02c0d, 0x02c0e, 0x02c0f, + 0x02c10, 0x02c11, 0x02c12, 0x02c13, 0x02c14, 0x02c15, 0x02c16, 0x02c17, + 0x02c18, 0x02c19, 0x02c1a, 0x02c1b, 0x02c1c, 0x02c1d, 0x02c1e, 0x02c1f, + 0x02c20, 0x02c21, 0x02c22, 0x02c23, 0x02c24, 0x02c25, 0x02c26, 0x02c27, + 0x02c28, 0x02c29, 0x02c2a, 0x02c2b, 0x02c2c, 0x02c2d, 0x02c2e, 0x02c2f, + 0x02c00, 0x02c01, 0x02c02, 0x02c03, 0x02c04, 0x02c05, 0x02c06, 0x02c07, + 0x02c08, 0x02c09, 0x02c0a, 0x02c0b, 0x02c0c, 0x02c0d, 0x02c0e, 0x02c0f, + 0x02c10, 0x02c11, 0x02c12, 0x02c13, 0x02c14, 0x02c15, 0x02c16, 0x02c17, + 0x02c18, 0x02c19, 0x02c1a, 0x02c1b, 0x02c1c, 0x02c1d, 0x02c1e, 0x02c1f, + 0x02c20, 0x02c21, 0x02c22, 0x02c23, 0x02c24, 0x02c25, 0x02c26, 0x02c27, + 0x02c28, 0x02c29, 0x02c2a, 0x02c2b, 0x02c2c, 0x02c2d, 0x02c2e, 0x02c5f, + 0x02c60, 0x02c60, 0x02c62, 0x02c63, 0x02c64, 0x0023a, 0x0023e, 0x02c67, + 0x02c67, 0x02c69, 0x02c69, 0x02c6b, 0x02c6b, 0x02c6d, 0x02c6e, 0x02c6f, + 0x02c70, 0x02c71, 0x02c72, 0x02c72, 0x02c74, 0x02c75, 0x02c75, 0x02c77, + 0x02c78, 0x02c79, 0x02c7a, 0x02c7b, 0x02c7c, 0x02c7d, 0x02c7e, 0x02c7f, +}; + + +static const uint32_t nxt_unicode_upper_case_block_059[128] nxt_aligned(64) = { + 0x02c80, 0x02c80, 0x02c82, 0x02c82, 0x02c84, 0x02c84, 0x02c86, 0x02c86, + 0x02c88, 0x02c88, 0x02c8a, 0x02c8a, 0x02c8c, 0x02c8c, 0x02c8e, 0x02c8e, + 0x02c90, 0x02c90, 0x02c92, 0x02c92, 0x02c94, 0x02c94, 0x02c96, 0x02c96, + 0x02c98, 0x02c98, 0x02c9a, 0x02c9a, 0x02c9c, 0x02c9c, 0x02c9e, 0x02c9e, + 0x02ca0, 0x02ca0, 0x02ca2, 0x02ca2, 0x02ca4, 0x02ca4, 0x02ca6, 0x02ca6, + 0x02ca8, 0x02ca8, 0x02caa, 0x02caa, 0x02cac, 0x02cac, 0x02cae, 0x02cae, + 0x02cb0, 0x02cb0, 0x02cb2, 0x02cb2, 0x02cb4, 0x02cb4, 0x02cb6, 0x02cb6, + 0x02cb8, 0x02cb8, 0x02cba, 0x02cba, 0x02cbc, 0x02cbc, 0x02cbe, 0x02cbe, + 0x02cc0, 0x02cc0, 0x02cc2, 0x02cc2, 0x02cc4, 0x02cc4, 0x02cc6, 0x02cc6, + 0x02cc8, 0x02cc8, 0x02cca, 0x02cca, 0x02ccc, 0x02ccc, 0x02cce, 0x02cce, + 0x02cd0, 0x02cd0, 0x02cd2, 0x02cd2, 0x02cd4, 0x02cd4, 0x02cd6, 0x02cd6, + 0x02cd8, 0x02cd8, 0x02cda, 0x02cda, 0x02cdc, 0x02cdc, 0x02cde, 0x02cde, + 0x02ce0, 0x02ce0, 0x02ce2, 0x02ce2, 0x02ce4, 0x02ce5, 0x02ce6, 0x02ce7, + 0x02ce8, 0x02ce9, 0x02cea, 0x02ceb, 0x02ceb, 0x02ced, 0x02ced, 0x02cef, + 0x02cf0, 0x02cf1, 0x02cf2, 0x02cf2, 0x02cf4, 0x02cf5, 0x02cf6, 0x02cf7, + 0x02cf8, 0x02cf9, 0x02cfa, 0x02cfb, 0x02cfc, 0x02cfd, 0x02cfe, 0x02cff, +}; + + +static const uint32_t nxt_unicode_upper_case_block_05a[128] nxt_aligned(64) = { + 0x010a0, 0x010a1, 0x010a2, 0x010a3, 0x010a4, 0x010a5, 0x010a6, 0x010a7, + 0x010a8, 0x010a9, 0x010aa, 0x010ab, 0x010ac, 0x010ad, 0x010ae, 0x010af, + 0x010b0, 0x010b1, 0x010b2, 0x010b3, 0x010b4, 0x010b5, 0x010b6, 0x010b7, + 0x010b8, 0x010b9, 0x010ba, 0x010bb, 0x010bc, 0x010bd, 0x010be, 0x010bf, + 0x010c0, 0x010c1, 0x010c2, 0x010c3, 0x010c4, 0x010c5, 0x02d26, 0x010c7, + 0x02d28, 0x02d29, 0x02d2a, 0x02d2b, 0x02d2c, 0x010cd, 0x02d2e, 0x02d2f, + 0x02d30, 0x02d31, 0x02d32, 0x02d33, 0x02d34, 0x02d35, 0x02d36, 0x02d37, + 0x02d38, 0x02d39, 0x02d3a, 0x02d3b, 0x02d3c, 0x02d3d, 0x02d3e, 0x02d3f, + 0x02d40, 0x02d41, 0x02d42, 0x02d43, 0x02d44, 0x02d45, 0x02d46, 0x02d47, + 0x02d48, 0x02d49, 0x02d4a, 0x02d4b, 0x02d4c, 0x02d4d, 0x02d4e, 0x02d4f, + 0x02d50, 0x02d51, 0x02d52, 0x02d53, 0x02d54, 0x02d55, 0x02d56, 0x02d57, + 0x02d58, 0x02d59, 0x02d5a, 0x02d5b, 0x02d5c, 0x02d5d, 0x02d5e, 0x02d5f, + 0x02d60, 0x02d61, 0x02d62, 0x02d63, 0x02d64, 0x02d65, 0x02d66, 0x02d67, + 0x02d68, 0x02d69, 0x02d6a, 0x02d6b, 0x02d6c, 0x02d6d, 0x02d6e, 0x02d6f, + 0x02d70, 0x02d71, 0x02d72, 0x02d73, 0x02d74, 0x02d75, 0x02d76, 0x02d77, + 0x02d78, 0x02d79, 0x02d7a, 0x02d7b, 0x02d7c, 0x02d7d, 0x02d7e, 0x02d7f, +}; + + +static const uint32_t nxt_unicode_upper_case_block_14c[128] nxt_aligned(64) = { + 0x0a600, 0x0a601, 0x0a602, 0x0a603, 0x0a604, 0x0a605, 0x0a606, 0x0a607, + 0x0a608, 0x0a609, 0x0a60a, 0x0a60b, 0x0a60c, 0x0a60d, 0x0a60e, 0x0a60f, + 0x0a610, 0x0a611, 0x0a612, 0x0a613, 0x0a614, 0x0a615, 0x0a616, 0x0a617, + 0x0a618, 0x0a619, 0x0a61a, 0x0a61b, 0x0a61c, 0x0a61d, 0x0a61e, 0x0a61f, + 0x0a620, 0x0a621, 0x0a622, 0x0a623, 0x0a624, 0x0a625, 0x0a626, 0x0a627, + 0x0a628, 0x0a629, 0x0a62a, 0x0a62b, 0x0a62c, 0x0a62d, 0x0a62e, 0x0a62f, + 0x0a630, 0x0a631, 0x0a632, 0x0a633, 0x0a634, 0x0a635, 0x0a636, 0x0a637, + 0x0a638, 0x0a639, 0x0a63a, 0x0a63b, 0x0a63c, 0x0a63d, 0x0a63e, 0x0a63f, + 0x0a640, 0x0a640, 0x0a642, 0x0a642, 0x0a644, 0x0a644, 0x0a646, 0x0a646, + 0x0a648, 0x0a648, 0x0a64a, 0x0a64a, 0x0a64c, 0x0a64c, 0x0a64e, 0x0a64e, + 0x0a650, 0x0a650, 0x0a652, 0x0a652, 0x0a654, 0x0a654, 0x0a656, 0x0a656, + 0x0a658, 0x0a658, 0x0a65a, 0x0a65a, 0x0a65c, 0x0a65c, 0x0a65e, 0x0a65e, + 0x0a660, 0x0a660, 0x0a662, 0x0a662, 0x0a664, 0x0a664, 0x0a666, 0x0a666, + 0x0a668, 0x0a668, 0x0a66a, 0x0a66a, 0x0a66c, 0x0a66c, 0x0a66e, 0x0a66f, + 0x0a670, 0x0a671, 0x0a672, 0x0a673, 0x0a674, 0x0a675, 0x0a676, 0x0a677, + 0x0a678, 0x0a679, 0x0a67a, 0x0a67b, 0x0a67c, 0x0a67d, 0x0a67e, 0x0a67f, +}; + + +static const uint32_t nxt_unicode_upper_case_block_14d[128] nxt_aligned(64) = { + 0x0a680, 0x0a680, 0x0a682, 0x0a682, 0x0a684, 0x0a684, 0x0a686, 0x0a686, + 0x0a688, 0x0a688, 0x0a68a, 0x0a68a, 0x0a68c, 0x0a68c, 0x0a68e, 0x0a68e, + 0x0a690, 0x0a690, 0x0a692, 0x0a692, 0x0a694, 0x0a694, 0x0a696, 0x0a696, + 0x0a698, 0x0a699, 0x0a69a, 0x0a69b, 0x0a69c, 0x0a69d, 0x0a69e, 0x0a69f, + 0x0a6a0, 0x0a6a1, 0x0a6a2, 0x0a6a3, 0x0a6a4, 0x0a6a5, 0x0a6a6, 0x0a6a7, + 0x0a6a8, 0x0a6a9, 0x0a6aa, 0x0a6ab, 0x0a6ac, 0x0a6ad, 0x0a6ae, 0x0a6af, + 0x0a6b0, 0x0a6b1, 0x0a6b2, 0x0a6b3, 0x0a6b4, 0x0a6b5, 0x0a6b6, 0x0a6b7, + 0x0a6b8, 0x0a6b9, 0x0a6ba, 0x0a6bb, 0x0a6bc, 0x0a6bd, 0x0a6be, 0x0a6bf, + 0x0a6c0, 0x0a6c1, 0x0a6c2, 0x0a6c3, 0x0a6c4, 0x0a6c5, 0x0a6c6, 0x0a6c7, + 0x0a6c8, 0x0a6c9, 0x0a6ca, 0x0a6cb, 0x0a6cc, 0x0a6cd, 0x0a6ce, 0x0a6cf, + 0x0a6d0, 0x0a6d1, 0x0a6d2, 0x0a6d3, 0x0a6d4, 0x0a6d5, 0x0a6d6, 0x0a6d7, + 0x0a6d8, 0x0a6d9, 0x0a6da, 0x0a6db, 0x0a6dc, 0x0a6dd, 0x0a6de, 0x0a6df, + 0x0a6e0, 0x0a6e1, 0x0a6e2, 0x0a6e3, 0x0a6e4, 0x0a6e5, 0x0a6e6, 0x0a6e7, + 0x0a6e8, 0x0a6e9, 0x0a6ea, 0x0a6eb, 0x0a6ec, 0x0a6ed, 0x0a6ee, 0x0a6ef, + 0x0a6f0, 0x0a6f1, 0x0a6f2, 0x0a6f3, 0x0a6f4, 0x0a6f5, 0x0a6f6, 0x0a6f7, + 0x0a6f8, 0x0a6f9, 0x0a6fa, 0x0a6fb, 0x0a6fc, 0x0a6fd, 0x0a6fe, 0x0a6ff, +}; + + +static const uint32_t nxt_unicode_upper_case_block_14e[128] nxt_aligned(64) = { + 0x0a700, 0x0a701, 0x0a702, 0x0a703, 0x0a704, 0x0a705, 0x0a706, 0x0a707, + 0x0a708, 0x0a709, 0x0a70a, 0x0a70b, 0x0a70c, 0x0a70d, 0x0a70e, 0x0a70f, + 0x0a710, 0x0a711, 0x0a712, 0x0a713, 0x0a714, 0x0a715, 0x0a716, 0x0a717, + 0x0a718, 0x0a719, 0x0a71a, 0x0a71b, 0x0a71c, 0x0a71d, 0x0a71e, 0x0a71f, + 0x0a720, 0x0a721, 0x0a722, 0x0a722, 0x0a724, 0x0a724, 0x0a726, 0x0a726, + 0x0a728, 0x0a728, 0x0a72a, 0x0a72a, 0x0a72c, 0x0a72c, 0x0a72e, 0x0a72e, + 0x0a730, 0x0a731, 0x0a732, 0x0a732, 0x0a734, 0x0a734, 0x0a736, 0x0a736, + 0x0a738, 0x0a738, 0x0a73a, 0x0a73a, 0x0a73c, 0x0a73c, 0x0a73e, 0x0a73e, + 0x0a740, 0x0a740, 0x0a742, 0x0a742, 0x0a744, 0x0a744, 0x0a746, 0x0a746, + 0x0a748, 0x0a748, 0x0a74a, 0x0a74a, 0x0a74c, 0x0a74c, 0x0a74e, 0x0a74e, + 0x0a750, 0x0a750, 0x0a752, 0x0a752, 0x0a754, 0x0a754, 0x0a756, 0x0a756, + 0x0a758, 0x0a758, 0x0a75a, 0x0a75a, 0x0a75c, 0x0a75c, 0x0a75e, 0x0a75e, + 0x0a760, 0x0a760, 0x0a762, 0x0a762, 0x0a764, 0x0a764, 0x0a766, 0x0a766, + 0x0a768, 0x0a768, 0x0a76a, 0x0a76a, 0x0a76c, 0x0a76c, 0x0a76e, 0x0a76e, + 0x0a770, 0x0a771, 0x0a772, 0x0a773, 0x0a774, 0x0a775, 0x0a776, 0x0a777, + 0x0a778, 0x0a779, 0x0a779, 0x0a77b, 0x0a77b, 0x0a77d, 0x0a77e, 0x0a77e, +}; + + +static const uint32_t nxt_unicode_upper_case_block_14f[128] nxt_aligned(64) = { + 0x0a780, 0x0a780, 0x0a782, 0x0a782, 0x0a784, 0x0a784, 0x0a786, 0x0a786, + 0x0a788, 0x0a789, 0x0a78a, 0x0a78b, 0x0a78b, 0x0a78d, 0x0a78e, 0x0a78f, + 0x0a790, 0x0a790, 0x0a792, 0x0a792, 0x0a794, 0x0a795, 0x0a796, 0x0a797, + 0x0a798, 0x0a799, 0x0a79a, 0x0a79b, 0x0a79c, 0x0a79d, 0x0a79e, 0x0a79f, + 0x0a7a0, 0x0a7a0, 0x0a7a2, 0x0a7a2, 0x0a7a4, 0x0a7a4, 0x0a7a6, 0x0a7a6, + 0x0a7a8, 0x0a7a8, 0x0a7aa, 0x0a7ab, 0x0a7ac, 0x0a7ad, 0x0a7ae, 0x0a7af, + 0x0a7b0, 0x0a7b1, 0x0a7b2, 0x0a7b3, 0x0a7b4, 0x0a7b5, 0x0a7b6, 0x0a7b7, + 0x0a7b8, 0x0a7b9, 0x0a7ba, 0x0a7bb, 0x0a7bc, 0x0a7bd, 0x0a7be, 0x0a7bf, + 0x0a7c0, 0x0a7c1, 0x0a7c2, 0x0a7c3, 0x0a7c4, 0x0a7c5, 0x0a7c6, 0x0a7c7, + 0x0a7c8, 0x0a7c9, 0x0a7ca, 0x0a7cb, 0x0a7cc, 0x0a7cd, 0x0a7ce, 0x0a7cf, + 0x0a7d0, 0x0a7d1, 0x0a7d2, 0x0a7d3, 0x0a7d4, 0x0a7d5, 0x0a7d6, 0x0a7d7, + 0x0a7d8, 0x0a7d9, 0x0a7da, 0x0a7db, 0x0a7dc, 0x0a7dd, 0x0a7de, 0x0a7df, + 0x0a7e0, 0x0a7e1, 0x0a7e2, 0x0a7e3, 0x0a7e4, 0x0a7e5, 0x0a7e6, 0x0a7e7, + 0x0a7e8, 0x0a7e9, 0x0a7ea, 0x0a7eb, 0x0a7ec, 0x0a7ed, 0x0a7ee, 0x0a7ef, + 0x0a7f0, 0x0a7f1, 0x0a7f2, 0x0a7f3, 0x0a7f4, 0x0a7f5, 0x0a7f6, 0x0a7f7, + 0x0a7f8, 0x0a7f9, 0x0a7fa, 0x0a7fb, 0x0a7fc, 0x0a7fd, 0x0a7fe, 0x0a7ff, +}; + + +static const uint32_t nxt_unicode_upper_case_block_1fe[128] nxt_aligned(64) = { + 0x0ff00, 0x0ff01, 0x0ff02, 0x0ff03, 0x0ff04, 0x0ff05, 0x0ff06, 0x0ff07, + 0x0ff08, 0x0ff09, 0x0ff0a, 0x0ff0b, 0x0ff0c, 0x0ff0d, 0x0ff0e, 0x0ff0f, + 0x0ff10, 0x0ff11, 0x0ff12, 0x0ff13, 0x0ff14, 0x0ff15, 0x0ff16, 0x0ff17, + 0x0ff18, 0x0ff19, 0x0ff1a, 0x0ff1b, 0x0ff1c, 0x0ff1d, 0x0ff1e, 0x0ff1f, + 0x0ff20, 0x0ff21, 0x0ff22, 0x0ff23, 0x0ff24, 0x0ff25, 0x0ff26, 0x0ff27, + 0x0ff28, 0x0ff29, 0x0ff2a, 0x0ff2b, 0x0ff2c, 0x0ff2d, 0x0ff2e, 0x0ff2f, + 0x0ff30, 0x0ff31, 0x0ff32, 0x0ff33, 0x0ff34, 0x0ff35, 0x0ff36, 0x0ff37, + 0x0ff38, 0x0ff39, 0x0ff3a, 0x0ff3b, 0x0ff3c, 0x0ff3d, 0x0ff3e, 0x0ff3f, + 0x0ff40, 0x0ff21, 0x0ff22, 0x0ff23, 0x0ff24, 0x0ff25, 0x0ff26, 0x0ff27, + 0x0ff28, 0x0ff29, 0x0ff2a, 0x0ff2b, 0x0ff2c, 0x0ff2d, 0x0ff2e, 0x0ff2f, + 0x0ff30, 0x0ff31, 0x0ff32, 0x0ff33, 0x0ff34, 0x0ff35, 0x0ff36, 0x0ff37, + 0x0ff38, 0x0ff39, 0x0ff3a, 0x0ff5b, 0x0ff5c, 0x0ff5d, 0x0ff5e, 0x0ff5f, + 0x0ff60, 0x0ff61, 0x0ff62, 0x0ff63, 0x0ff64, 0x0ff65, 0x0ff66, 0x0ff67, + 0x0ff68, 0x0ff69, 0x0ff6a, 0x0ff6b, 0x0ff6c, 0x0ff6d, 0x0ff6e, 0x0ff6f, + 0x0ff70, 0x0ff71, 0x0ff72, 0x0ff73, 0x0ff74, 0x0ff75, 0x0ff76, 0x0ff77, + 0x0ff78, 0x0ff79, 0x0ff7a, 0x0ff7b, 0x0ff7c, 0x0ff7d, 0x0ff7e, 0x0ff7f, +}; + + +static const uint32_t nxt_unicode_upper_case_block_208[80] nxt_aligned(64) = { + 0x10400, 0x10401, 0x10402, 0x10403, 0x10404, 0x10405, 0x10406, 0x10407, + 0x10408, 0x10409, 0x1040a, 0x1040b, 0x1040c, 0x1040d, 0x1040e, 0x1040f, + 0x10410, 0x10411, 0x10412, 0x10413, 0x10414, 0x10415, 0x10416, 0x10417, + 0x10418, 0x10419, 0x1041a, 0x1041b, 0x1041c, 0x1041d, 0x1041e, 0x1041f, + 0x10420, 0x10421, 0x10422, 0x10423, 0x10424, 0x10425, 0x10426, 0x10427, + 0x10400, 0x10401, 0x10402, 0x10403, 0x10404, 0x10405, 0x10406, 0x10407, + 0x10408, 0x10409, 0x1040a, 0x1040b, 0x1040c, 0x1040d, 0x1040e, 0x1040f, + 0x10410, 0x10411, 0x10412, 0x10413, 0x10414, 0x10415, 0x10416, 0x10417, + 0x10418, 0x10419, 0x1041a, 0x1041b, 0x1041c, 0x1041d, 0x1041e, 0x1041f, + 0x10420, 0x10421, 0x10422, 0x10423, 0x10424, 0x10425, 0x10426, 0x10427, +}; + + +static const uint32_t *nxt_unicode_upper_case_blocks[] nxt_aligned(64) = { + nxt_unicode_upper_case_block_000, + nxt_unicode_upper_case_block_001, + nxt_unicode_upper_case_block_002, + nxt_unicode_upper_case_block_003, + nxt_unicode_upper_case_block_004, + nxt_unicode_upper_case_block_005, + nxt_unicode_upper_case_block_006, + nxt_unicode_upper_case_block_007, + nxt_unicode_upper_case_block_008, + nxt_unicode_upper_case_block_009, + nxt_unicode_upper_case_block_00a, + nxt_unicode_upper_case_block_00b, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + nxt_unicode_upper_case_block_03a, + NULL, + nxt_unicode_upper_case_block_03c, + nxt_unicode_upper_case_block_03d, + nxt_unicode_upper_case_block_03e, + nxt_unicode_upper_case_block_03f, + NULL, + NULL, + nxt_unicode_upper_case_block_042, + nxt_unicode_upper_case_block_043, + NULL, + NULL, + NULL, + NULL, + NULL, + nxt_unicode_upper_case_block_049, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + nxt_unicode_upper_case_block_058, + nxt_unicode_upper_case_block_059, + nxt_unicode_upper_case_block_05a, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, From igor at sysoev.ru Wed Jun 1 12:50:23 2016 From: igor at sysoev.ru (Igor Sysoev) Date: Wed, 01 Jun 2016 12:50:23 +0000 Subject: [njs] Number.toString(radix). Message-ID: details: http://hg.nginx.org/njs/rev/23ff7c369101 branches: changeset: 102:23ff7c369101 user: Igor Sysoev date: Tue Apr 19 17:26:25 2016 +0300 description: Number.toString(radix). diffstat: njs/njs_number.c | 94 ++++++++++++++++++++++++++++++++++++++++++++++- njs/test/njs_unit_test.c | 29 ++++++++++++++ 2 files changed, 121 insertions(+), 2 deletions(-) diffs (164 lines): diff -r e411e0cbd20d -r 23ff7c369101 njs/njs_number.c --- a/njs/njs_number.c Fri Apr 15 18:01:40 2016 +0300 +++ b/njs/njs_number.c Tue Apr 19 17:26:25 2016 +0300 @@ -22,6 +22,10 @@ #include +static njs_ret_t njs_number_to_string_radix(njs_vm_t *vm, njs_value_t *string, + const njs_value_t *number, uint32_t radix); + + double njs_value_to_number(njs_value_t *value) { @@ -313,6 +317,7 @@ static njs_ret_t njs_number_prototype_to_string(njs_vm_t *vm, njs_value_t *args, nxt_uint_t nargs, njs_index_t unused) { + double radix; njs_value_t *value; value = &args[0]; @@ -328,7 +333,91 @@ njs_number_prototype_to_string(njs_vm_t } } - return njs_number_to_string(vm, &vm->retval, value); + if (nargs == 1 || args[1].data.u.number == 10) { + return njs_number_to_string(vm, &vm->retval, value); + } + + radix = args[1].data.u.number; + + if (radix < 2 || radix > 36 || radix != (int) radix) { + vm->exception = &njs_exception_range_error; + return NXT_ERROR; + } + + return njs_number_to_string_radix(vm, &vm->retval, value, radix); +} + + +/* + * The radix equal to 2 produces the longest intergral value of a number + * and the maximum value consists of 1024 digits and minus sign. + */ + +#define NJS_STRING_RADIX_INTERGRAL_LEN (1 + 1024) +#define NJS_STRING_RADIX_FRACTION_LEN (1 + 54) +#define NJS_STRING_RADIX_LEN \ + (NJS_STRING_RADIX_INTERGRAL_LEN + NJS_STRING_RADIX_FRACTION_LEN) + + +static njs_ret_t +njs_number_to_string_radix(njs_vm_t *vm, njs_value_t *string, + const njs_value_t *number, uint32_t radix) +{ + u_char *p, *f, *start, *end; + double n, next; + size_t size; + uint8_t reminder; + u_char buf[NJS_STRING_RADIX_LEN]; + + static const char *digits = "0123456789abcdefghijklmnopqrstuvwxyz"; + + end = buf + NJS_STRING_RADIX_LEN; + p = buf + NJS_STRING_RADIX_INTERGRAL_LEN; + + n = number->data.u.number; + + if (n < 0) { + n = -n; + } + + do { + next = trunc(n / radix); + reminder = n - next * radix; + *(--p) = digits[reminder]; + n = next; + } while (n != 0); + + n = number->data.u.number; + + if (n < 0) { + *(--p) = '-'; + } + + f = buf + NJS_STRING_RADIX_INTERGRAL_LEN; + + n = n - trunc(n); + + if (n != 0) { + *f++ = '.'; + + do { + n = n * radix; + reminder = trunc(n); + *f++ = digits[reminder]; + n = n - reminder; + } while (n != 0 && f < end); + } + + size = f - p; + + start = njs_string_alloc(vm, string, size, size); + + if (nxt_fast_path(start != NULL)) { + memcpy(start, p, size); + return NXT_OK; + } + + return NXT_ERROR; } @@ -349,7 +438,8 @@ static const njs_object_prop_t njs_numb { .type = NJS_METHOD, .name = njs_string("toString"), - .value = njs_native_function(njs_number_prototype_to_string, 0, 0), + .value = njs_native_function(njs_number_prototype_to_string, 0, + NJS_SKIP_ARG, NJS_NUMBER_ARG), }, }; diff -r e411e0cbd20d -r 23ff7c369101 njs/test/njs_unit_test.c --- a/njs/test/njs_unit_test.c Fri Apr 15 18:01:40 2016 +0300 +++ b/njs/test/njs_unit_test.c Tue Apr 19 17:26:25 2016 +0300 @@ -92,6 +92,35 @@ static njs_unit_test_t njs_test[] = { nxt_string("\n +1"), nxt_string("1") }, + /* Number.toString(radix) method. */ + + { nxt_string("0..toString(2)"), + nxt_string("0") }, + + { nxt_string("240..toString(2)"), + nxt_string("11110000") }, + + { nxt_string("Math.pow(-2, 1023).toString(2).length"), + nxt_string("1025") }, + + { nxt_string("8.0625.toString(2)"), + nxt_string("1000.0001") }, + + { nxt_string("(1/3).toString(2)"), + nxt_string("0.010101010101010101010101010101010101010101010101010101") }, + + { nxt_string("9999..toString(3)"), + nxt_string("111201100") }, + + { nxt_string("-9999..toString(3)"), + nxt_string("-111201100") }, + + { nxt_string("81985529216486895..toString(16)"), + nxt_string("123456789abcdf0") }, + + { nxt_string("1845449130881..toString(36)"), + nxt_string("njscript") }, + /* An object "valueOf/toString" methods. */ { nxt_string("var a = { valueOf: function() { return 1 } }; +a"), From igor at sysoev.ru Wed Jun 1 12:50:24 2016 From: igor at sysoev.ru (Igor Sysoev) Date: Wed, 01 Jun 2016 12:50:24 +0000 Subject: [njs] njs_string_new(). Message-ID: details: http://hg.nginx.org/njs/rev/f720a6378a2f branches: changeset: 103:f720a6378a2f user: Igor Sysoev date: Tue Apr 19 16:07:33 2016 +0300 description: njs_string_new(). diffstat: njs/njs_date.c | 30 +++--------------------------- njs/njs_number.c | 25 +++++-------------------- njs/njs_string.c | 51 +++++++++++++++++++++++++-------------------------- njs/njs_string.h | 2 ++ 4 files changed, 35 insertions(+), 73 deletions(-) diffs (237 lines): diff -r 23ff7c369101 -r f720a6378a2f njs/njs_date.c --- a/njs/njs_date.c Tue Apr 19 17:26:25 2016 +0300 +++ b/njs/njs_date.c Tue Apr 19 16:07:33 2016 +0300 @@ -831,7 +831,6 @@ njs_date_string(njs_vm_t *vm, const char { size_t size; time_t clock; - u_char *start; u_char buf[NJS_DATE_TIME_LEN]; struct tm tm; @@ -841,14 +840,7 @@ njs_date_string(njs_vm_t *vm, const char size = strftime((char *) buf, NJS_DATE_TIME_LEN, fmt, &tm); - start = njs_string_alloc(vm, &vm->retval, size, size); - - if (nxt_fast_path(start != NULL)) { - memcpy(start, buf, size); - return NXT_OK; - } - - return NXT_ERROR; + return njs_string_new(vm, &vm->retval, buf, size, size); } vm->retval = njs_string_invalid_date; @@ -864,7 +856,6 @@ njs_date_prototype_to_utc_string(njs_vm_ double time; size_t size; time_t clock; - u_char *start; u_char buf[NJS_DATE_TIME_LEN]; struct tm tm; @@ -886,14 +877,7 @@ njs_date_prototype_to_utc_string(njs_vm_ tm.tm_mday, tm.tm_year + 1900, tm.tm_hour, tm.tm_min, tm.tm_sec); - start = njs_string_alloc(vm, &vm->retval, size, size); - - if (nxt_fast_path(start != NULL)) { - memcpy(start, buf, size); - return NXT_OK; - } - - return NXT_ERROR; + return njs_string_new(vm, &vm->retval, buf, size, size); } vm->retval = njs_string_invalid_date; @@ -910,7 +894,6 @@ njs_date_prototype_to_iso_string(njs_vm_ double time; size_t size; time_t clock; - u_char *start; u_char buf[NJS_ISO_DATE_TIME_LEN]; struct tm tm; @@ -930,14 +913,7 @@ njs_date_prototype_to_iso_string(njs_vm_ tm.tm_hour, tm.tm_min, tm.tm_sec, (int) ((int64_t) time % 1000)); - start = njs_string_alloc(vm, &vm->retval, size, size); - - if (nxt_fast_path(start != NULL)) { - memcpy(start, buf, size); - return NXT_OK; - } - - return NXT_ERROR; + return njs_string_new(vm, &vm->retval, buf, size, size); } vm->exception = &njs_exception_range_error; diff -r 23ff7c369101 -r f720a6378a2f njs/njs_number.c --- a/njs/njs_number.c Tue Apr 19 17:26:25 2016 +0300 +++ b/njs/njs_number.c Tue Apr 19 16:07:33 2016 +0300 @@ -167,12 +167,11 @@ njs_ret_t njs_number_to_string(njs_vm_t *vm, njs_value_t *string, const njs_value_t *number) { - u_char *p; double n, num; size_t size; const char *fmt; const njs_value_t *value; - char buf[128]; + u_char buf[128]; num = number->data.u.number; @@ -207,16 +206,9 @@ njs_number_to_string(njs_vm_t *vm, njs_v fmt = "%1.e"; } - size = snprintf(buf, sizeof(buf), fmt, num); - - p = njs_string_alloc(vm, string, size, size); + size = snprintf((char *) buf, sizeof(buf), fmt, num); - if (nxt_fast_path(p != NULL)) { - memcpy(p, buf, size); - return NXT_OK; - } - - return NXT_ERROR; + return njs_string_new(vm, string, buf, size, size); } *string = *value; @@ -363,7 +355,7 @@ static njs_ret_t njs_number_to_string_radix(njs_vm_t *vm, njs_value_t *string, const njs_value_t *number, uint32_t radix) { - u_char *p, *f, *start, *end; + u_char *p, *f, *end; double n, next; size_t size; uint8_t reminder; @@ -410,14 +402,7 @@ njs_number_to_string_radix(njs_vm_t *vm, size = f - p; - start = njs_string_alloc(vm, string, size, size); - - if (nxt_fast_path(start != NULL)) { - memcpy(start, p, size); - return NXT_OK; - } - - return NXT_ERROR; + return njs_string_new(vm, string, p, size, size); } diff -r 23ff7c369101 -r f720a6378a2f njs/njs_string.c --- a/njs/njs_string.c Tue Apr 19 17:26:25 2016 +0300 +++ b/njs/njs_string.c Tue Apr 19 16:07:33 2016 +0300 @@ -92,6 +92,28 @@ njs_string_create(njs_vm_t *vm, njs_valu } +nxt_noinline njs_ret_t +njs_string_new(njs_vm_t *vm, njs_value_t *value, const u_char *start, + uint32_t size, uint32_t length) +{ + u_char *p; + + p = njs_string_alloc(vm, value, size, length); + + if (nxt_fast_path(p != NULL)) { + memcpy(p, start, size); + + if (size != length && length >= NJS_STRING_MAP_OFFSET) { + njs_string_offset_map_init(p, size); + } + + return NXT_OK; + } + + return NXT_ERROR; +} + + nxt_noinline u_char * njs_string_alloc(njs_vm_t *vm, njs_value_t *value, uint32_t size, uint32_t length) @@ -571,7 +593,6 @@ static njs_ret_t njs_string_prototype_from_utf8(njs_vm_t *vm, njs_value_t *args, nxt_uint_t nargs, njs_index_t unused) { - u_char *p; ssize_t length; njs_slice_prop_t slice; njs_string_prop_t string; @@ -596,17 +617,8 @@ njs_string_prototype_from_utf8(njs_vm_t } /* Long UTF-8 string. */ - - p = njs_string_alloc(vm, &vm->retval, slice.length, length); - - if (nxt_fast_path(p != NULL)) { - memcpy(p, string.start, slice.length); - njs_string_offset_map_init(p, slice.length); - - return NXT_OK; - } - - return NXT_ERROR; + return njs_string_new(vm, &vm->retval, string.start, slice.length, + length); } vm->retval = njs_value_null; @@ -949,7 +961,6 @@ nxt_noinline njs_ret_t njs_string_slice(njs_vm_t *vm, njs_value_t *dst, const njs_string_prop_t *string, njs_slice_prop_t *slice) { - u_char *s; size_t size, n, length; ssize_t excess; const u_char *p, *start, *end; @@ -994,19 +1005,7 @@ njs_string_slice(njs_vm_t *vm, njs_value } if (nxt_fast_path(size != 0)) { - s = njs_string_alloc(vm, &vm->retval, size, length); - - if (nxt_slow_path(s == NULL)) { - return NXT_ERROR; - } - - memcpy(s, start, size); - - if (length >= NJS_STRING_MAP_OFFSET && size != length) { - njs_string_offset_map_init(s, size); - } - - return NXT_OK; + return njs_string_new(vm, &vm->retval, start, size, length); } } diff -r 23ff7c369101 -r f720a6378a2f njs/njs_string.h --- a/njs/njs_string.h Tue Apr 19 17:26:25 2016 +0300 +++ b/njs/njs_string.h Tue Apr 19 16:07:33 2016 +0300 @@ -80,6 +80,8 @@ typedef struct { } njs_slice_prop_t; +njs_ret_t njs_string_new(njs_vm_t *vm, njs_value_t *value, const u_char *start, + uint32_t size, uint32_t length); u_char *njs_string_alloc(njs_vm_t *vm, njs_value_t *value, uint32_t size, uint32_t length) NXT_MALLOC_LIKE; From igor at sysoev.ru Wed Jun 1 12:50:25 2016 From: igor at sysoev.ru (Igor Sysoev) Date: Wed, 01 Jun 2016 12:50:25 +0000 Subject: [njs] eval() placeholder has been moved from the constructor table Message-ID: details: http://hg.nginx.org/njs/rev/3f2480c38f8e branches: changeset: 104:3f2480c38f8e user: Igor Sysoev date: Tue Apr 19 16:08:32 2016 +0300 description: eval() placeholder has been moved from the constructor table to the shared function table. diffstat: njs/njs_builtin.c | 90 ++++++++++++++++++++++++++++++++---------------- njs/njs_generator.c | 2 +- njs/njs_lexer_keyword.c | 1 + njs/njs_object.c | 2 +- njs/njs_parser.c | 35 +++++++++++++++++- njs/njs_parser.h | 3 + njs/njs_vm.h | 69 ++++++++++++++++++++----------------- 7 files changed, 135 insertions(+), 67 deletions(-) diffs (421 lines): diff -r f720a6378a2f -r 3f2480c38f8e njs/njs_builtin.c --- a/njs/njs_builtin.c Tue Apr 19 16:07:33 2016 +0300 +++ b/njs/njs_builtin.c Tue Apr 19 16:08:32 2016 +0300 @@ -34,10 +34,10 @@ typedef struct { nxt_int_t njs_builtin_objects_create(njs_vm_t *vm) { - nxt_int_t ret; - nxt_uint_t i; - njs_object_t *objects, *prototypes; - njs_function_t *functions; + nxt_int_t ret; + nxt_uint_t i; + njs_object_t *objects, *prototypes; + njs_function_t *functions, *constructors; static const njs_object_init_t *prototype_init[] = { &njs_object_prototype_init, @@ -50,7 +50,7 @@ njs_builtin_objects_create(njs_vm_t *vm) &njs_date_prototype_init, }; - static const njs_object_init_t *function_init[] = { + static const njs_object_init_t *constructor_init[] = { &njs_object_constructor_init, &njs_array_constructor_init, &njs_boolean_constructor_init, @@ -59,11 +59,9 @@ njs_builtin_objects_create(njs_vm_t *vm) &njs_function_constructor_init, &njs_regexp_constructor_init, &njs_date_constructor_init, - - &njs_eval_function_init, }; - static const njs_function_init_t native_functions[] = { + static const njs_function_init_t native_constructors[] = { /* SunC does not allow empty array initialization. */ { njs_object_constructor, { 0 } }, { njs_array_constructor, { 0 } }, @@ -74,14 +72,21 @@ njs_builtin_objects_create(njs_vm_t *vm) { njs_regexp_constructor, { NJS_SKIP_ARG, NJS_STRING_ARG, NJS_STRING_ARG } }, { njs_date_constructor, { 0 } }, - - { njs_eval_function, { 0 } }, }; - static const njs_object_init_t *objects_init[] = { + static const njs_object_init_t *object_init[] = { &njs_math_object_init, }; + static const njs_object_init_t *function_init[] = { + &njs_eval_function_init, + }; + + static const njs_function_init_t native_functions[] = { + /* SunC does not allow empty array initialization. */ + { njs_eval_function, { 0 } }, + }; + static const njs_object_prop_t null_proto_property = { .type = NJS_WHITEOUT, .name = njs_string("__proto__"), @@ -110,8 +115,8 @@ njs_builtin_objects_create(njs_vm_t *vm) for (i = NJS_OBJECT_MATH; i < NJS_OBJECT_MAX; i++) { ret = njs_object_hash_create(vm, &objects[i].shared_hash, - objects_init[i]->properties, - objects_init[i]->items); + object_init[i]->properties, + object_init[i]->items); if (nxt_slow_path(ret != NXT_OK)) { return NXT_ERROR; } @@ -119,6 +124,27 @@ njs_builtin_objects_create(njs_vm_t *vm) objects[i].shared = 1; } + functions = vm->shared->functions; + + for (i = NJS_FUNCTION_EVAL; i < NJS_FUNCTION_MAX; i++) { + ret = njs_object_hash_create(vm, &functions[i].object.shared_hash, + function_init[i]->properties, + function_init[i]->items); + if (nxt_slow_path(ret != NXT_OK)) { + return NXT_ERROR; + } + + functions[i].object.shared = 1; + functions[i].native = 1; + functions[i].args_offset = 1; + functions[i].u.native = native_functions[i].native; + functions[i].args_types[0] = native_functions[i].args_types[0]; + functions[i].args_types[1] = native_functions[i].args_types[1]; + functions[i].args_types[2] = native_functions[i].args_types[2]; + functions[i].args_types[3] = native_functions[i].args_types[3]; + functions[i].args_types[4] = native_functions[i].args_types[4]; + } + prototypes = vm->shared->prototypes; for (i = NJS_PROTOTYPE_OBJECT; i < NJS_PROTOTYPE_MAX; i++) { @@ -130,20 +156,22 @@ njs_builtin_objects_create(njs_vm_t *vm) } } - functions = vm->shared->functions; + constructors = vm->shared->constructors; - for (i = NJS_FUNCTION_OBJECT; i < NJS_FUNCTION_MAX; i++) { - functions[i].object.shared = 0; - functions[i].native = 1; - functions[i].args_offset = 1; - functions[i].u.native = native_functions[i].native; - functions[i].args_types[0] = native_functions[i].args_types[0]; - functions[i].args_types[1] = native_functions[i].args_types[1]; - functions[i].args_types[2] = native_functions[i].args_types[2]; + for (i = NJS_CONSTRUCTOR_OBJECT; i < NJS_CONSTRUCTOR_MAX; i++) { + constructors[i].object.shared = 0; + constructors[i].native = 1; + constructors[i].args_offset = 1; + constructors[i].u.native = native_constructors[i].native; + constructors[i].args_types[0] = native_constructors[i].args_types[0]; + constructors[i].args_types[1] = native_constructors[i].args_types[1]; + constructors[i].args_types[2] = native_constructors[i].args_types[2]; + constructors[i].args_types[3] = native_constructors[i].args_types[3]; + constructors[i].args_types[4] = native_constructors[i].args_types[4]; - ret = njs_object_hash_create(vm, &functions[i].object.shared_hash, - function_init[i]->properties, - function_init[i]->items); + ret = njs_object_hash_create(vm, &constructors[i].object.shared_hash, + constructor_init[i]->properties, + constructor_init[i]->items); if (nxt_slow_path(ret != NXT_OK)) { return NXT_ERROR; } @@ -200,11 +228,11 @@ njs_builtin_objects_clone(njs_vm_t *vm) njs_object_t *function_prototype; /* - * Copy both prototypes and functions arrays by one memcpy() + * Copy both prototypes and constructors arrays by one memcpy() * because they are stored together. */ size = NJS_PROTOTYPE_MAX * sizeof(njs_object_t) - + NJS_FUNCTION_MAX * sizeof(njs_function_t); + + NJS_CONSTRUCTOR_MAX * sizeof(njs_function_t); memcpy(vm->prototypes, vm->shared->prototypes, size); @@ -212,14 +240,14 @@ njs_builtin_objects_clone(njs_vm_t *vm) vm->prototypes[i].__proto__ = &vm->prototypes[NJS_PROTOTYPE_OBJECT]; } - function_prototype = &vm->prototypes[NJS_FUNCTION_FUNCTION]; + function_prototype = &vm->prototypes[NJS_CONSTRUCTOR_FUNCTION]; values = vm->scopes[NJS_SCOPE_GLOBAL]; - for (i = NJS_FUNCTION_OBJECT; i < NJS_FUNCTION_MAX; i++) { + for (i = NJS_CONSTRUCTOR_OBJECT; i < NJS_CONSTRUCTOR_MAX; i++) { values[i].type = NJS_FUNCTION; values[i].data.truth = 1; - values[i].data.u.function = &vm->functions[i]; - vm->functions[i].object.__proto__ = function_prototype; + values[i].data.u.function = &vm->constructors[i]; + vm->constructors[i].object.__proto__ = function_prototype; } return NXT_OK; diff -r f720a6378a2f -r 3f2480c38f8e njs/njs_generator.c --- a/njs/njs_generator.c Tue Apr 19 16:07:33 2016 +0300 +++ b/njs/njs_generator.c Tue Apr 19 16:08:32 2016 +0300 @@ -286,7 +286,6 @@ njs_generator(njs_vm_t *vm, njs_parser_t case NJS_TOKEN_FUNCTION_CONSTRUCTOR: case NJS_TOKEN_REGEXP_CONSTRUCTOR: case NJS_TOKEN_DATE_CONSTRUCTOR: - case NJS_TOKEN_EVAL: case NJS_TOKEN_EXTERNAL: return NXT_OK; @@ -294,6 +293,7 @@ njs_generator(njs_vm_t *vm, njs_parser_t return njs_generate_name(vm, parser, node); case NJS_TOKEN_MATH: + case NJS_TOKEN_EVAL: return njs_generate_builtin_object(vm, parser, node); case NJS_TOKEN_FUNCTION: diff -r f720a6378a2f -r 3f2480c38f8e njs/njs_lexer_keyword.c --- a/njs/njs_lexer_keyword.c Tue Apr 19 16:07:33 2016 +0300 +++ b/njs/njs_lexer_keyword.c Tue Apr 19 16:08:32 2016 +0300 @@ -86,6 +86,7 @@ static const njs_keyword_t njs_keywords { nxt_string("Function"), NJS_TOKEN_FUNCTION_CONSTRUCTOR, 0 }, { nxt_string("RegExp"), NJS_TOKEN_REGEXP_CONSTRUCTOR, 0 }, { nxt_string("Date"), NJS_TOKEN_DATE_CONSTRUCTOR, 0 }, + { nxt_string("eval"), NJS_TOKEN_EVAL, 0 }, /* Reserved words. */ diff -r f720a6378a2f -r 3f2480c38f8e njs/njs_object.c --- a/njs/njs_object.c Tue Apr 19 16:07:33 2016 +0300 +++ b/njs/njs_object.c Tue Apr 19 16:08:32 2016 +0300 @@ -359,7 +359,7 @@ njs_object_prototype_create(njs_vm_t *vm proto = NULL; function = value->data.u.function; - index = function - vm->functions; + index = function - vm->constructors; if (index >= 0 && index < NJS_PROTOTYPE_MAX) { proto = njs_property_prototype_create(vm, &function->object.hash, diff -r f720a6378a2f -r 3f2480c38f8e njs/njs_parser.c --- a/njs/njs_parser.c Tue Apr 19 16:07:33 2016 +0300 +++ b/njs/njs_parser.c Tue Apr 19 16:08:32 2016 +0300 @@ -71,6 +71,8 @@ static njs_token_t njs_parser_grouping_e njs_parser_t *parser); static njs_token_t njs_parser_builtin_object(njs_vm_t *vm, njs_parser_t *parser, njs_parser_node_t *node); +static njs_token_t njs_parser_builtin_function(njs_vm_t *vm, + njs_parser_t *parser, njs_parser_node_t *node); static njs_token_t njs_parser_object(njs_vm_t *vm, njs_parser_t *parser, njs_parser_node_t *obj); static njs_token_t njs_parser_array(njs_vm_t *vm, njs_parser_t *parser, @@ -1627,8 +1629,7 @@ njs_parser_terminal(njs_vm_t *vm, njs_pa break; case NJS_TOKEN_EVAL: - node->index = NJS_INDEX_EVAL; - break; + return njs_parser_builtin_function(vm, parser, node); default: vm->exception = &njs_exception_syntax_error; @@ -1672,6 +1673,36 @@ njs_parser_builtin_object(njs_vm_t *vm, static njs_token_t +njs_parser_builtin_function(njs_vm_t *vm, njs_parser_t *parser, + njs_parser_node_t *node) +{ + nxt_uint_t index, level; + njs_value_t *value; + njs_variable_t *var; + + var = njs_parser_variable(vm, parser, &level); + if (nxt_slow_path(var == NULL)) { + return NJS_TOKEN_ERROR; + } + + var->state = NJS_VARIABLE_DECLARED; + node->index = var->index; + + value = njs_variable_value(parser, node->index); + + index = node->token - NJS_TOKEN_FIRST_FUNCTION; + value->data.u.function = &vm->shared->functions[index]; + value->type = NJS_FUNCTION; + value->data.truth = 1; + + parser->node = node; + parser->code_size += sizeof(njs_vmcode_object_copy_t); + + return njs_lexer_token(parser->lexer); +} + + +static njs_token_t njs_parser_object(njs_vm_t *vm, njs_parser_t *parser, njs_parser_node_t *obj) { njs_token_t token; diff -r f720a6378a2f -r 3f2480c38f8e njs/njs_parser.h --- a/njs/njs_parser.h Tue Apr 19 16:07:33 2016 +0300 +++ b/njs/njs_parser.h Tue Apr 19 16:08:32 2016 +0300 @@ -171,6 +171,9 @@ typedef enum { NJS_TOKEN_FUNCTION_CONSTRUCTOR, NJS_TOKEN_REGEXP_CONSTRUCTOR, NJS_TOKEN_DATE_CONSTRUCTOR, + +#define NJS_TOKEN_FIRST_FUNCTION NJS_TOKEN_EVAL + NJS_TOKEN_EVAL, NJS_TOKEN_RESERVED, diff -r f720a6378a2f -r 3f2480c38f8e njs/njs_vm.h --- a/njs/njs_vm.h Tue Apr 19 16:07:33 2016 +0300 +++ b/njs/njs_vm.h Tue Apr 19 16:08:32 2016 +0300 @@ -86,7 +86,7 @@ typedef enum { * NJS_OBJECT_BOOLEAN, NJS_OBJECT_NUMBER, and NJS_OBJECT_STRING must be * in the same order as NJS_BOOLEAN, NJS_NUMBER, and NJS_STRING. It is * used in njs_primitive_prototype_index(). The order of object types - * is used in vm->prototypes and vm->functions arrays. + * is used in vm->prototypes and vm->constructors arrays. */ NJS_OBJECT = 0x08, NJS_ARRAY = 0x09, @@ -664,7 +664,7 @@ typedef enum { enum njs_prototypes_e { - NJS_PROTOTYPE_OBJECT = 0, + NJS_PROTOTYPE_OBJECT = 0, NJS_PROTOTYPE_ARRAY, NJS_PROTOTYPE_BOOLEAN, NJS_PROTOTYPE_NUMBER, @@ -672,7 +672,7 @@ enum njs_prototypes_e { NJS_PROTOTYPE_FUNCTION, NJS_PROTOTYPE_REGEXP, NJS_PROTOTYPE_DATE, -#define NJS_PROTOTYPE_MAX (NJS_PROTOTYPE_DATE + 1) +#define NJS_PROTOTYPE_MAX (NJS_PROTOTYPE_DATE + 1) }; @@ -680,24 +680,28 @@ enum njs_prototypes_e { (NJS_PROTOTYPE_BOOLEAN + ((type) - NJS_BOOLEAN)) -enum njs_functions_e { - NJS_FUNCTION_OBJECT = NJS_PROTOTYPE_OBJECT, - NJS_FUNCTION_ARRAY = NJS_PROTOTYPE_ARRAY, - NJS_FUNCTION_BOOLEAN = NJS_PROTOTYPE_BOOLEAN, - NJS_FUNCTION_NUMBER = NJS_PROTOTYPE_NUMBER, - NJS_FUNCTION_STRING = NJS_PROTOTYPE_STRING, - NJS_FUNCTION_FUNCTION = NJS_PROTOTYPE_FUNCTION, - NJS_FUNCTION_REGEXP = NJS_PROTOTYPE_REGEXP, - NJS_FUNCTION_DATE = NJS_PROTOTYPE_DATE, - - NJS_FUNCTION_EVAL, -#define NJS_FUNCTION_MAX (NJS_FUNCTION_EVAL + 1) +enum njs_constructor_e { + NJS_CONSTRUCTOR_OBJECT = NJS_PROTOTYPE_OBJECT, + NJS_CONSTRUCTOR_ARRAY = NJS_PROTOTYPE_ARRAY, + NJS_CONSTRUCTOR_BOOLEAN = NJS_PROTOTYPE_BOOLEAN, + NJS_CONSTRUCTOR_NUMBER = NJS_PROTOTYPE_NUMBER, + NJS_CONSTRUCTOR_STRING = NJS_PROTOTYPE_STRING, + NJS_CONSTRUCTOR_FUNCTION = NJS_PROTOTYPE_FUNCTION, + NJS_CONSTRUCTOR_REGEXP = NJS_PROTOTYPE_REGEXP, + NJS_CONSTRUCTOR_DATE = NJS_PROTOTYPE_DATE, +#define NJS_CONSTRUCTOR_MAX (NJS_CONSTRUCTOR_DATE + 1) }; enum njs_object_e { - NJS_OBJECT_MATH = 0, -#define NJS_OBJECT_MAX (NJS_OBJECT_MATH + 1) + NJS_OBJECT_MATH = 0, +#define NJS_OBJECT_MAX (NJS_OBJECT_MATH + 1) +}; + + +enum njs_function_e { + NJS_FUNCTION_EVAL = 0, +#define NJS_FUNCTION_MAX (NJS_FUNCTION_EVAL + 1) }; @@ -708,18 +712,18 @@ enum njs_object_e { ((njs_index_t) (((value) << NJS_SCOPE_SHIFT) | NJS_SCOPE_GLOBAL)) -#define NJS_INDEX_OBJECT njs_global_scope_index(NJS_FUNCTION_OBJECT) -#define NJS_INDEX_ARRAY njs_global_scope_index(NJS_FUNCTION_ARRAY) -#define NJS_INDEX_BOOLEAN njs_global_scope_index(NJS_FUNCTION_BOOLEAN) -#define NJS_INDEX_NUMBER njs_global_scope_index(NJS_FUNCTION_NUMBER) -#define NJS_INDEX_STRING njs_global_scope_index(NJS_FUNCTION_STRING) -#define NJS_INDEX_FUNCTION njs_global_scope_index(NJS_FUNCTION_FUNCTION) -#define NJS_INDEX_REGEXP njs_global_scope_index(NJS_FUNCTION_REGEXP) -#define NJS_INDEX_DATE njs_global_scope_index(NJS_FUNCTION_DATE) -#define NJS_INDEX_EVAL njs_global_scope_index(NJS_FUNCTION_EVAL) +#define NJS_INDEX_OBJECT njs_global_scope_index(NJS_CONSTRUCTOR_OBJECT) +#define NJS_INDEX_ARRAY njs_global_scope_index(NJS_CONSTRUCTOR_ARRAY) +#define NJS_INDEX_BOOLEAN njs_global_scope_index(NJS_CONSTRUCTOR_BOOLEAN) +#define NJS_INDEX_NUMBER njs_global_scope_index(NJS_CONSTRUCTOR_NUMBER) +#define NJS_INDEX_STRING njs_global_scope_index(NJS_CONSTRUCTOR_STRING) +#define NJS_INDEX_FUNCTION \ + njs_global_scope_index(NJS_CONSTRUCTOR_FUNCTION) +#define NJS_INDEX_REGEXP njs_global_scope_index(NJS_CONSTRUCTOR_REGEXP) +#define NJS_INDEX_DATE njs_global_scope_index(NJS_CONSTRUCTOR_DATE) -#define NJS_INDEX_GLOBAL_RETVAL njs_global_scope_index(NJS_FUNCTION_MAX) -#define NJS_INDEX_GLOBAL_OFFSET njs_scope_index(NJS_FUNCTION_MAX + 1) +#define NJS_INDEX_GLOBAL_RETVAL njs_global_scope_index(NJS_CONSTRUCTOR_MAX) +#define NJS_INDEX_GLOBAL_OFFSET njs_scope_index(NJS_CONSTRUCTOR_MAX + 1) #define njs_offset(index) \ @@ -767,12 +771,12 @@ struct njs_vm_s { nxt_lvlhsh_t values_hash; /* - * The prototypes and functions arrays must be togther because + * The prototypes and constructors arrays must be togther because * they are copied from njs_vm_shared_t by single memcpy() * in njs_builtin_objects_clone(). */ njs_object_t prototypes[NJS_PROTOTYPE_MAX]; - njs_function_t functions[NJS_FUNCTION_MAX]; + njs_function_t constructors[NJS_CONSTRUCTOR_MAX]; nxt_mem_cache_pool_t *mem_cache_pool; @@ -802,13 +806,14 @@ struct njs_vm_shared_s { nxt_lvlhsh_t function_prototype_hash; njs_object_t objects[NJS_OBJECT_MAX]; + njs_function_t functions[NJS_FUNCTION_MAX]; /* - * The prototypes and functions arrays must be togther because they are + * The prototypes and constructors arrays must be togther because they are * copied to njs_vm_t by single memcpy() in njs_builtin_objects_clone(). */ njs_object_t prototypes[NJS_PROTOTYPE_MAX]; - njs_function_t functions[NJS_FUNCTION_MAX]; + njs_function_t constructors[NJS_CONSTRUCTOR_MAX]; }; From igor at sysoev.ru Wed Jun 1 12:50:27 2016 From: igor at sysoev.ru (Igor Sysoev) Date: Wed, 01 Jun 2016 12:50:27 +0000 Subject: [njs] Reserverd words can be used as property names. Message-ID: details: http://hg.nginx.org/njs/rev/6fa680a54811 branches: changeset: 105:6fa680a54811 user: Igor Sysoev date: Wed Apr 20 18:30:31 2016 +0300 description: Reserverd words can be used as property names. diffstat: njs/njs_lexer.c | 4 ++++ njs/njs_parser.c | 17 ++++++++++++++++- njs/njs_parser.h | 2 ++ njs/njs_parser_expression.c | 22 +++++++++++++--------- njs/test/njs_unit_test.c | 6 ++++++ 5 files changed, 41 insertions(+), 10 deletions(-) diffs (129 lines): diff -r 3f2480c38f8e -r 6fa680a54811 njs/njs_lexer.c --- a/njs/njs_lexer.c Tue Apr 19 16:08:32 2016 +0300 +++ b/njs/njs_lexer.c Wed Apr 20 18:30:31 2016 +0300 @@ -465,6 +465,10 @@ njs_lexer_word(njs_lexer_t *lexer, u_cha lexer->start = p; lexer->text.len = p - lexer->text.data; + if (lexer->property) { + return NJS_TOKEN_NAME; + } + return njs_lexer_keyword(lexer); } diff -r 3f2480c38f8e -r 6fa680a54811 njs/njs_parser.c --- a/njs/njs_parser.c Tue Apr 19 16:08:32 2016 +0300 +++ b/njs/njs_parser.c Wed Apr 20 18:30:31 2016 +0300 @@ -1381,6 +1381,21 @@ njs_parser_grouping_expression(njs_vm_t njs_token_t +njs_parser_property_token(njs_parser_t *parser) +{ + njs_token_t token; + + parser->lexer->property = 1; + + token = njs_parser_token(parser); + + parser->lexer->property = 0; + + return token; +} + + +njs_token_t njs_parser_token(njs_parser_t *parser) { njs_token_t token; @@ -1711,7 +1726,7 @@ njs_parser_object(njs_vm_t *vm, njs_pars left = NULL; for ( ;; ) { - token = njs_parser_token(parser); + token = njs_parser_property_token(parser); switch (token) { diff -r 3f2480c38f8e -r 6fa680a54811 njs/njs_parser.h --- a/njs/njs_parser.h Tue Apr 19 16:08:32 2016 +0300 +++ b/njs/njs_parser.h Wed Apr 20 18:30:31 2016 +0300 @@ -183,6 +183,7 @@ typedef enum { typedef struct { njs_token_t token:8; njs_token_t prev_token:8; + uint8_t property; /* 1 bit */ uint32_t key_hash; nxt_str_t text; @@ -328,6 +329,7 @@ njs_token_t njs_parser_terminal(njs_vm_t njs_token_t token); njs_token_t njs_parser_property_name(njs_vm_t *vm, njs_parser_t *parser, njs_token_t token); +njs_token_t njs_parser_property_token(njs_parser_t *parser); njs_token_t njs_parser_token(njs_parser_t *parser); nxt_int_t njs_parser_string_create(njs_vm_t *vm, njs_value_t *value); njs_index_t njs_parser_index(njs_parser_t *parser, uint32_t scope); diff -r 3f2480c38f8e -r 6fa680a54811 njs/njs_parser_expression.c --- a/njs/njs_parser_expression.c Tue Apr 19 16:08:32 2016 +0300 +++ b/njs/njs_parser_expression.c Wed Apr 20 18:30:31 2016 +0300 @@ -999,7 +999,6 @@ static njs_token_t njs_parser_property_expression(njs_vm_t *vm, njs_parser_t *parser, njs_token_t token) { - njs_token_t next; njs_parser_node_t *node; for ( ;; ) { @@ -1019,21 +1018,26 @@ njs_parser_property_expression(njs_vm_t node->u.operation = njs_vmcode_property_get; node->left = parser->node; - next = njs_parser_token(parser); - if (nxt_slow_path(next <= NJS_TOKEN_ILLEGAL)) { - return next; - } - if (token == NJS_TOKEN_DOT) { - if (next != NJS_TOKEN_NAME) { + token = njs_parser_property_token(parser); + if (nxt_slow_path(token <= NJS_TOKEN_ILLEGAL)) { + return token; + } + + if (token != NJS_TOKEN_NAME) { return NJS_TOKEN_ILLEGAL; } - token = njs_parser_property_name(vm, parser, next); + token = njs_parser_property_name(vm, parser, token); } else { - token = njs_parser_property_brackets(vm, parser, next); + token = njs_parser_token(parser); + if (nxt_slow_path(token <= NJS_TOKEN_ILLEGAL)) { + return token; + } + + token = njs_parser_property_brackets(vm, parser, token); } if (nxt_slow_path(token <= NJS_TOKEN_ILLEGAL)) { diff -r 3f2480c38f8e -r 6fa680a54811 njs/test/njs_unit_test.c --- a/njs/test/njs_unit_test.c Tue Apr 19 16:08:32 2016 +0300 +++ b/njs/test/njs_unit_test.c Wed Apr 20 18:30:31 2016 +0300 @@ -1938,6 +1938,12 @@ static njs_unit_test_t njs_test[] = "var o = { a: 5, '[object Object]': 7 }; o[n]"), nxt_string("7") }, + { nxt_string("var o = {}; o.new = 'OK'; o.new"), + nxt_string("OK") }, + + { nxt_string("var o = { new: 'OK'}; o.new"), + nxt_string("OK") }, + /* Arrays */ /* Empty array to primitive. */ From igor at sysoev.ru Wed Jun 1 12:50:28 2016 From: igor at sysoev.ru (Igor Sysoev) Date: Wed, 01 Jun 2016 12:50:28 +0000 Subject: [njs] Global toString() function. Message-ID: details: http://hg.nginx.org/njs/rev/a69b4eaebdcf branches: changeset: 106:a69b4eaebdcf user: Igor Sysoev date: Thu Apr 21 15:57:05 2016 +0300 description: Global toString() function. diffstat: njs/njs_builtin.c | 16 ++++++++++------ njs/njs_generator.c | 6 +----- njs/njs_lexer_keyword.c | 1 + njs/njs_parser.c | 1 + njs/njs_parser.h | 1 + njs/njs_vm.h | 3 ++- njs/test/njs_unit_test.c | 14 ++++++++++++++ 7 files changed, 30 insertions(+), 12 deletions(-) diffs (130 lines): diff -r 6fa680a54811 -r a69b4eaebdcf njs/njs_builtin.c --- a/njs/njs_builtin.c Wed Apr 20 18:30:31 2016 +0300 +++ b/njs/njs_builtin.c Thu Apr 21 15:57:05 2016 +0300 @@ -80,11 +80,13 @@ njs_builtin_objects_create(njs_vm_t *vm) static const njs_object_init_t *function_init[] = { &njs_eval_function_init, + NULL, }; static const njs_function_init_t native_functions[] = { /* SunC does not allow empty array initialization. */ - { njs_eval_function, { 0 } }, + { njs_eval_function, { 0 } }, + { njs_object_prototype_to_string, { 0 } }, }; static const njs_object_prop_t null_proto_property = { @@ -127,11 +129,13 @@ njs_builtin_objects_create(njs_vm_t *vm) functions = vm->shared->functions; for (i = NJS_FUNCTION_EVAL; i < NJS_FUNCTION_MAX; i++) { - ret = njs_object_hash_create(vm, &functions[i].object.shared_hash, - function_init[i]->properties, - function_init[i]->items); - if (nxt_slow_path(ret != NXT_OK)) { - return NXT_ERROR; + if (function_init[i] != NULL) { + ret = njs_object_hash_create(vm, &functions[i].object.shared_hash, + function_init[i]->properties, + function_init[i]->items); + if (nxt_slow_path(ret != NXT_OK)) { + return NXT_ERROR; + } } functions[i].object.shared = 1; diff -r 6fa680a54811 -r a69b4eaebdcf njs/njs_generator.c --- a/njs/njs_generator.c Wed Apr 20 18:30:31 2016 +0300 +++ b/njs/njs_generator.c Thu Apr 21 15:57:05 2016 +0300 @@ -294,6 +294,7 @@ njs_generator(njs_vm_t *vm, njs_parser_t case NJS_TOKEN_MATH: case NJS_TOKEN_EVAL: + case NJS_TOKEN_TO_STRING: return njs_generate_builtin_object(vm, parser, node); case NJS_TOKEN_FUNCTION: @@ -2050,11 +2051,6 @@ njs_generate_function_call(njs_vm_t *vm, func->code.ctor = node->ctor; func->name = name->index; - ret = njs_generator_node_index_release(vm, parser, name); - if (nxt_slow_path(ret != NXT_OK)) { - return ret; - } - ret = njs_generate_call(vm, parser, node); if (nxt_fast_path(ret >= 0)) { diff -r 6fa680a54811 -r a69b4eaebdcf njs/njs_lexer_keyword.c --- a/njs/njs_lexer_keyword.c Wed Apr 20 18:30:31 2016 +0300 +++ b/njs/njs_lexer_keyword.c Thu Apr 21 15:57:05 2016 +0300 @@ -88,6 +88,7 @@ static const njs_keyword_t njs_keywords { nxt_string("Date"), NJS_TOKEN_DATE_CONSTRUCTOR, 0 }, { nxt_string("eval"), NJS_TOKEN_EVAL, 0 }, + { nxt_string("toString"), NJS_TOKEN_TO_STRING, 0 }, /* Reserved words. */ diff -r 6fa680a54811 -r a69b4eaebdcf njs/njs_parser.c --- a/njs/njs_parser.c Wed Apr 20 18:30:31 2016 +0300 +++ b/njs/njs_parser.c Thu Apr 21 15:57:05 2016 +0300 @@ -1644,6 +1644,7 @@ njs_parser_terminal(njs_vm_t *vm, njs_pa break; case NJS_TOKEN_EVAL: + case NJS_TOKEN_TO_STRING: return njs_parser_builtin_function(vm, parser, node); default: diff -r 6fa680a54811 -r a69b4eaebdcf njs/njs_parser.h --- a/njs/njs_parser.h Wed Apr 20 18:30:31 2016 +0300 +++ b/njs/njs_parser.h Thu Apr 21 15:57:05 2016 +0300 @@ -175,6 +175,7 @@ typedef enum { #define NJS_TOKEN_FIRST_FUNCTION NJS_TOKEN_EVAL NJS_TOKEN_EVAL, + NJS_TOKEN_TO_STRING, NJS_TOKEN_RESERVED, } njs_token_t; diff -r 6fa680a54811 -r a69b4eaebdcf njs/njs_vm.h --- a/njs/njs_vm.h Wed Apr 20 18:30:31 2016 +0300 +++ b/njs/njs_vm.h Thu Apr 21 15:57:05 2016 +0300 @@ -701,7 +701,8 @@ enum njs_object_e { enum njs_function_e { NJS_FUNCTION_EVAL = 0, -#define NJS_FUNCTION_MAX (NJS_FUNCTION_EVAL + 1) + NJS_FUNCTION_TO_STRING = 1, +#define NJS_FUNCTION_MAX (NJS_FUNCTION_TO_STRING + 1) }; diff -r 6fa680a54811 -r a69b4eaebdcf njs/test/njs_unit_test.c --- a/njs/test/njs_unit_test.c Wed Apr 20 18:30:31 2016 +0300 +++ b/njs/test/njs_unit_test.c Thu Apr 21 15:57:05 2016 +0300 @@ -3953,6 +3953,20 @@ static njs_unit_test_t njs_test[] = { nxt_string("/./.__proto__ === RegExp.prototype"), nxt_string("true") }, + { nxt_string("toString()"), + nxt_string("[object Undefined]") }, + + { nxt_string("toString() + Object.prototype.toString"), + nxt_string("[object Undefined][object Function]") }, + +#if 0 + { nxt_string("toString === Object.prototype.toString"), + nxt_string("true") }, + + { nxt_string("Object.prototype.toString.yes = 'OK'; toString.yes"), + nxt_string("OK") }, +#endif + { nxt_string("Object.prototype.toString.call()"), nxt_string("[object Undefined]") }, From igor at sysoev.ru Wed Jun 1 12:50:30 2016 From: igor at sysoev.ru (Igor Sysoev) Date: Wed, 01 Jun 2016 12:50:30 +0000 Subject: [njs] isNaN() function. Message-ID: details: http://hg.nginx.org/njs/rev/a61f70d8874a branches: changeset: 107:a61f70d8874a user: Igor Sysoev date: Thu Apr 21 18:23:12 2016 +0300 description: isNaN() function. diffstat: njs/njs_builtin.c | 2 ++ njs/njs_generator.c | 1 + njs/njs_lexer_keyword.c | 1 + njs/njs_number.c | 18 ++++++++++++++++++ njs/njs_number.h | 3 +++ njs/njs_parser.c | 1 + njs/njs_parser.h | 1 + njs/njs_string.c | 13 ++++++++++++- njs/njs_vm.h | 3 ++- njs/test/njs_unit_test.c | 18 ++++++++++++++++++ 10 files changed, 59 insertions(+), 2 deletions(-) diffs (175 lines): diff -r a69b4eaebdcf -r a61f70d8874a njs/njs_builtin.c --- a/njs/njs_builtin.c Thu Apr 21 15:57:05 2016 +0300 +++ b/njs/njs_builtin.c Thu Apr 21 18:23:12 2016 +0300 @@ -81,12 +81,14 @@ njs_builtin_objects_create(njs_vm_t *vm) static const njs_object_init_t *function_init[] = { &njs_eval_function_init, NULL, + NULL, }; static const njs_function_init_t native_functions[] = { /* SunC does not allow empty array initialization. */ { njs_eval_function, { 0 } }, { njs_object_prototype_to_string, { 0 } }, + { njs_number_is_nan, { NJS_SKIP_ARG, NJS_NUMBER_ARG } }, }; static const njs_object_prop_t null_proto_property = { diff -r a69b4eaebdcf -r a61f70d8874a njs/njs_generator.c --- a/njs/njs_generator.c Thu Apr 21 15:57:05 2016 +0300 +++ b/njs/njs_generator.c Thu Apr 21 18:23:12 2016 +0300 @@ -295,6 +295,7 @@ njs_generator(njs_vm_t *vm, njs_parser_t case NJS_TOKEN_MATH: case NJS_TOKEN_EVAL: case NJS_TOKEN_TO_STRING: + case NJS_TOKEN_IS_NAN: return njs_generate_builtin_object(vm, parser, node); case NJS_TOKEN_FUNCTION: diff -r a69b4eaebdcf -r a61f70d8874a njs/njs_lexer_keyword.c --- a/njs/njs_lexer_keyword.c Thu Apr 21 15:57:05 2016 +0300 +++ b/njs/njs_lexer_keyword.c Thu Apr 21 18:23:12 2016 +0300 @@ -89,6 +89,7 @@ static const njs_keyword_t njs_keywords { nxt_string("eval"), NJS_TOKEN_EVAL, 0 }, { nxt_string("toString"), NJS_TOKEN_TO_STRING, 0 }, + { nxt_string("isNaN"), NJS_TOKEN_IS_NAN, 0 }, /* Reserved words. */ diff -r a69b4eaebdcf -r a61f70d8874a njs/njs_number.c --- a/njs/njs_number.c Thu Apr 21 15:57:05 2016 +0300 +++ b/njs/njs_number.c Thu Apr 21 18:23:12 2016 +0300 @@ -433,3 +433,21 @@ const njs_object_init_t njs_number_prot njs_number_prototype_properties, nxt_nitems(njs_number_prototype_properties), }; + + +njs_ret_t +njs_number_is_nan(njs_vm_t *vm, njs_value_t *args, nxt_uint_t nargs, + njs_index_t unused) +{ + const njs_value_t *value; + + value = &njs_value_true; + + if (nargs > 1 && !njs_is_nan(args[1].data.u.number)) { + value = &njs_value_false; + } + + vm->retval = *value; + + return NXT_OK; +} diff -r a69b4eaebdcf -r a61f70d8874a njs/njs_number.h --- a/njs/njs_number.h Thu Apr 21 15:57:05 2016 +0300 +++ b/njs/njs_number.h Thu Apr 21 18:23:12 2016 +0300 @@ -30,6 +30,9 @@ njs_ret_t njs_number_to_string(njs_vm_t const njs_value_t *number); njs_ret_t njs_number_constructor(njs_vm_t *vm, njs_value_t *args, nxt_uint_t nargs, njs_index_t unused); +njs_ret_t njs_number_is_nan(njs_vm_t *vm, njs_value_t *args, nxt_uint_t nargs, + njs_index_t unused); + extern const njs_object_init_t njs_number_constructor_init; extern const njs_object_init_t njs_number_prototype_init; diff -r a69b4eaebdcf -r a61f70d8874a njs/njs_parser.c --- a/njs/njs_parser.c Thu Apr 21 15:57:05 2016 +0300 +++ b/njs/njs_parser.c Thu Apr 21 18:23:12 2016 +0300 @@ -1645,6 +1645,7 @@ njs_parser_terminal(njs_vm_t *vm, njs_pa case NJS_TOKEN_EVAL: case NJS_TOKEN_TO_STRING: + case NJS_TOKEN_IS_NAN: return njs_parser_builtin_function(vm, parser, node); default: diff -r a69b4eaebdcf -r a61f70d8874a njs/njs_parser.h --- a/njs/njs_parser.h Thu Apr 21 15:57:05 2016 +0300 +++ b/njs/njs_parser.h Thu Apr 21 18:23:12 2016 +0300 @@ -176,6 +176,7 @@ typedef enum { NJS_TOKEN_EVAL, NJS_TOKEN_TO_STRING, + NJS_TOKEN_IS_NAN, NJS_TOKEN_RESERVED, } njs_token_t; diff -r a69b4eaebdcf -r a61f70d8874a njs/njs_string.c --- a/njs/njs_string.c Thu Apr 21 15:57:05 2016 +0300 +++ b/njs/njs_string.c Thu Apr 21 18:23:12 2016 +0300 @@ -1685,6 +1685,8 @@ njs_string_to_number(njs_value_t *value) nxt_bool_t minus; const u_char *p, *end; + const size_t infinity = sizeof("Infinity") - 1; + size = value->short_string.size; if (size != NJS_STRING_LONG) { @@ -1719,11 +1721,20 @@ njs_string_to_number(njs_value_t *value) minus = 1; } + if (p == end) { + return NJS_NAN; + } + if (*p >= '0' && *p <= '9') { num = njs_number_parse(&p, end); } else { - return NJS_NAN; + if (p + infinity > end || memcmp(p, "Infinity", infinity) != 0) { + return NJS_NAN; + } + + num = NJS_INFINITY; + p += infinity; } while (p < end) { diff -r a69b4eaebdcf -r a61f70d8874a njs/njs_vm.h --- a/njs/njs_vm.h Thu Apr 21 15:57:05 2016 +0300 +++ b/njs/njs_vm.h Thu Apr 21 18:23:12 2016 +0300 @@ -702,7 +702,8 @@ enum njs_object_e { enum njs_function_e { NJS_FUNCTION_EVAL = 0, NJS_FUNCTION_TO_STRING = 1, -#define NJS_FUNCTION_MAX (NJS_FUNCTION_TO_STRING + 1) + NJS_FUNCTION_IS_NAN = 2, +#define NJS_FUNCTION_MAX (NJS_FUNCTION_IS_NAN + 1) }; diff -r a69b4eaebdcf -r a61f70d8874a njs/test/njs_unit_test.c --- a/njs/test/njs_unit_test.c Thu Apr 21 15:57:05 2016 +0300 +++ b/njs/test/njs_unit_test.c Thu Apr 21 18:23:12 2016 +0300 @@ -4395,6 +4395,24 @@ static njs_unit_test_t njs_test[] = { nxt_string("Math"), nxt_string("[object Object]") }, + { nxt_string("isNaN"), + nxt_string("[object Function]") }, + + { nxt_string("isNaN()"), + nxt_string("true") }, + + { nxt_string("isNaN(123)"), + nxt_string("false") }, + + { nxt_string("isNaN('123')"), + nxt_string("false") }, + + { nxt_string("isNaN('Infinity')"), + nxt_string("false") }, + + { nxt_string("isNaN('abc')"), + nxt_string("true") }, + /* External interface. */ { nxt_string("function f(req) { return req.uri }"), From igor at sysoev.ru Wed Jun 1 12:50:31 2016 From: igor at sysoev.ru (Igor Sysoev) Date: Wed, 01 Jun 2016 12:50:31 +0000 Subject: [njs] isFinite() function. Message-ID: details: http://hg.nginx.org/njs/rev/fd72dd7112c2 branches: changeset: 108:fd72dd7112c2 user: Igor Sysoev date: Thu Apr 21 18:23:16 2016 +0300 description: isFinite() function. diffstat: njs/njs_builtin.c | 2 ++ njs/njs_generator.c | 1 + njs/njs_lexer_keyword.c | 1 + njs/njs_number.c | 23 +++++++++++++++++++++++ njs/njs_number.h | 2 ++ njs/njs_parser.c | 1 + njs/njs_parser.h | 1 + njs/njs_vm.h | 3 ++- njs/test/njs_unit_test.c | 18 ++++++++++++++++++ 9 files changed, 51 insertions(+), 1 deletions(-) diffs (146 lines): diff -r a61f70d8874a -r fd72dd7112c2 njs/njs_builtin.c --- a/njs/njs_builtin.c Thu Apr 21 18:23:12 2016 +0300 +++ b/njs/njs_builtin.c Thu Apr 21 18:23:16 2016 +0300 @@ -82,6 +82,7 @@ njs_builtin_objects_create(njs_vm_t *vm) &njs_eval_function_init, NULL, NULL, + NULL, }; static const njs_function_init_t native_functions[] = { @@ -89,6 +90,7 @@ njs_builtin_objects_create(njs_vm_t *vm) { njs_eval_function, { 0 } }, { njs_object_prototype_to_string, { 0 } }, { njs_number_is_nan, { NJS_SKIP_ARG, NJS_NUMBER_ARG } }, + { njs_number_is_finite, { NJS_SKIP_ARG, NJS_NUMBER_ARG } }, }; static const njs_object_prop_t null_proto_property = { diff -r a61f70d8874a -r fd72dd7112c2 njs/njs_generator.c --- a/njs/njs_generator.c Thu Apr 21 18:23:12 2016 +0300 +++ b/njs/njs_generator.c Thu Apr 21 18:23:16 2016 +0300 @@ -296,6 +296,7 @@ njs_generator(njs_vm_t *vm, njs_parser_t case NJS_TOKEN_EVAL: case NJS_TOKEN_TO_STRING: case NJS_TOKEN_IS_NAN: + case NJS_TOKEN_IS_FINITE: return njs_generate_builtin_object(vm, parser, node); case NJS_TOKEN_FUNCTION: diff -r a61f70d8874a -r fd72dd7112c2 njs/njs_lexer_keyword.c --- a/njs/njs_lexer_keyword.c Thu Apr 21 18:23:12 2016 +0300 +++ b/njs/njs_lexer_keyword.c Thu Apr 21 18:23:16 2016 +0300 @@ -90,6 +90,7 @@ static const njs_keyword_t njs_keywords { nxt_string("eval"), NJS_TOKEN_EVAL, 0 }, { nxt_string("toString"), NJS_TOKEN_TO_STRING, 0 }, { nxt_string("isNaN"), NJS_TOKEN_IS_NAN, 0 }, + { nxt_string("isFinite"), NJS_TOKEN_IS_FINITE, 0 }, /* Reserved words. */ diff -r a61f70d8874a -r fd72dd7112c2 njs/njs_number.c --- a/njs/njs_number.c Thu Apr 21 18:23:12 2016 +0300 +++ b/njs/njs_number.c Thu Apr 21 18:23:16 2016 +0300 @@ -451,3 +451,26 @@ njs_number_is_nan(njs_vm_t *vm, njs_valu return NXT_OK; } + + +njs_ret_t +njs_number_is_finite(njs_vm_t *vm, njs_value_t *args, nxt_uint_t nargs, + njs_index_t unused) +{ + double num; + const njs_value_t *value; + + value = &njs_value_false; + + if (nargs > 1) { + num = args[1].data.u.number; + + if (!njs_is_nan(num) && !njs_is_infinity(num)) { + value = &njs_value_true; + } + } + + vm->retval = *value; + + return NXT_OK; +} diff -r a61f70d8874a -r fd72dd7112c2 njs/njs_number.h --- a/njs/njs_number.h Thu Apr 21 18:23:12 2016 +0300 +++ b/njs/njs_number.h Thu Apr 21 18:23:16 2016 +0300 @@ -32,6 +32,8 @@ njs_ret_t njs_number_constructor(njs_vm_ nxt_uint_t nargs, njs_index_t unused); njs_ret_t njs_number_is_nan(njs_vm_t *vm, njs_value_t *args, nxt_uint_t nargs, njs_index_t unused); +njs_ret_t njs_number_is_finite(njs_vm_t *vm, njs_value_t *args, + nxt_uint_t nargs, njs_index_t unused); extern const njs_object_init_t njs_number_constructor_init; diff -r a61f70d8874a -r fd72dd7112c2 njs/njs_parser.c --- a/njs/njs_parser.c Thu Apr 21 18:23:12 2016 +0300 +++ b/njs/njs_parser.c Thu Apr 21 18:23:16 2016 +0300 @@ -1646,6 +1646,7 @@ njs_parser_terminal(njs_vm_t *vm, njs_pa case NJS_TOKEN_EVAL: case NJS_TOKEN_TO_STRING: case NJS_TOKEN_IS_NAN: + case NJS_TOKEN_IS_FINITE: return njs_parser_builtin_function(vm, parser, node); default: diff -r a61f70d8874a -r fd72dd7112c2 njs/njs_parser.h --- a/njs/njs_parser.h Thu Apr 21 18:23:12 2016 +0300 +++ b/njs/njs_parser.h Thu Apr 21 18:23:16 2016 +0300 @@ -177,6 +177,7 @@ typedef enum { NJS_TOKEN_EVAL, NJS_TOKEN_TO_STRING, NJS_TOKEN_IS_NAN, + NJS_TOKEN_IS_FINITE, NJS_TOKEN_RESERVED, } njs_token_t; diff -r a61f70d8874a -r fd72dd7112c2 njs/njs_vm.h --- a/njs/njs_vm.h Thu Apr 21 18:23:12 2016 +0300 +++ b/njs/njs_vm.h Thu Apr 21 18:23:16 2016 +0300 @@ -703,7 +703,8 @@ enum njs_function_e { NJS_FUNCTION_EVAL = 0, NJS_FUNCTION_TO_STRING = 1, NJS_FUNCTION_IS_NAN = 2, -#define NJS_FUNCTION_MAX (NJS_FUNCTION_IS_NAN + 1) + NJS_FUNCTION_IS_FINITE = 3, +#define NJS_FUNCTION_MAX (NJS_FUNCTION_IS_FINITE + 1) }; diff -r a61f70d8874a -r fd72dd7112c2 njs/test/njs_unit_test.c --- a/njs/test/njs_unit_test.c Thu Apr 21 18:23:12 2016 +0300 +++ b/njs/test/njs_unit_test.c Thu Apr 21 18:23:16 2016 +0300 @@ -4413,6 +4413,24 @@ static njs_unit_test_t njs_test[] = { nxt_string("isNaN('abc')"), nxt_string("true") }, + { nxt_string("isFinite"), + nxt_string("[object Function]") }, + + { nxt_string("isFinite()"), + nxt_string("false") }, + + { nxt_string("isFinite(123)"), + nxt_string("true") }, + + { nxt_string("isFinite('123')"), + nxt_string("true") }, + + { nxt_string("isFinite('Infinity')"), + nxt_string("false") }, + + { nxt_string("isFinite('abc')"), + nxt_string("false") }, + /* External interface. */ { nxt_string("function f(req) { return req.uri }"), From igor at sysoev.ru Wed Jun 1 12:50:32 2016 From: igor at sysoev.ru (Igor Sysoev) Date: Wed, 01 Jun 2016 12:50:32 +0000 Subject: [njs] parseInt() function. Message-ID: details: http://hg.nginx.org/njs/rev/ffe9a5658450 branches: changeset: 109:ffe9a5658450 user: Igor Sysoev date: Mon Apr 25 17:28:34 2016 +0300 description: parseInt() function. diffstat: njs/njs_builtin.c | 3 + njs/njs_generator.c | 1 + njs/njs_lexer_keyword.c | 1 + njs/njs_number.c | 99 ++++++++++++++++++++++++++++++++++++++++++----- njs/njs_number.h | 5 +- njs/njs_parser.c | 3 +- njs/njs_parser.h | 1 + njs/njs_vm.h | 3 +- njs/test/njs_unit_test.c | 18 ++++++++ 9 files changed, 119 insertions(+), 15 deletions(-) diffs (267 lines): diff -r fd72dd7112c2 -r ffe9a5658450 njs/njs_builtin.c --- a/njs/njs_builtin.c Thu Apr 21 18:23:16 2016 +0300 +++ b/njs/njs_builtin.c Mon Apr 25 17:28:34 2016 +0300 @@ -83,6 +83,7 @@ njs_builtin_objects_create(njs_vm_t *vm) NULL, NULL, NULL, + NULL, }; static const njs_function_init_t native_functions[] = { @@ -91,6 +92,8 @@ njs_builtin_objects_create(njs_vm_t *vm) { njs_object_prototype_to_string, { 0 } }, { njs_number_is_nan, { NJS_SKIP_ARG, NJS_NUMBER_ARG } }, { njs_number_is_finite, { NJS_SKIP_ARG, NJS_NUMBER_ARG } }, + { njs_number_parse_int, + { NJS_SKIP_ARG, NJS_STRING_ARG, NJS_INTEGER_ARG } }, }; static const njs_object_prop_t null_proto_property = { diff -r fd72dd7112c2 -r ffe9a5658450 njs/njs_generator.c --- a/njs/njs_generator.c Thu Apr 21 18:23:16 2016 +0300 +++ b/njs/njs_generator.c Mon Apr 25 17:28:34 2016 +0300 @@ -297,6 +297,7 @@ njs_generator(njs_vm_t *vm, njs_parser_t case NJS_TOKEN_TO_STRING: case NJS_TOKEN_IS_NAN: case NJS_TOKEN_IS_FINITE: + case NJS_TOKEN_PARSE_INT: return njs_generate_builtin_object(vm, parser, node); case NJS_TOKEN_FUNCTION: diff -r fd72dd7112c2 -r ffe9a5658450 njs/njs_lexer_keyword.c --- a/njs/njs_lexer_keyword.c Thu Apr 21 18:23:16 2016 +0300 +++ b/njs/njs_lexer_keyword.c Mon Apr 25 17:28:34 2016 +0300 @@ -91,6 +91,7 @@ static const njs_keyword_t njs_keywords { nxt_string("toString"), NJS_TOKEN_TO_STRING, 0 }, { nxt_string("isNaN"), NJS_TOKEN_IS_NAN, 0 }, { nxt_string("isFinite"), NJS_TOKEN_IS_FINITE, 0 }, + { nxt_string("parseInt"), NJS_TOKEN_PARSE_INT, 0 }, /* Reserved words. */ diff -r fd72dd7112c2 -r ffe9a5658450 njs/njs_number.c --- a/njs/njs_number.c Thu Apr 21 18:23:16 2016 +0300 +++ b/njs/njs_number.c Mon Apr 25 17:28:34 2016 +0300 @@ -121,22 +121,22 @@ njs_number_parse(const u_char **start, c int64_t -njs_hex_number_parse(u_char *p, u_char *end) +njs_number_radix_parse(u_char *p, u_char *end, uint8_t radix, nxt_bool_t exact) { - int8_t d; - uint32_t n; + uint8_t d; + uint64_t n; - static const int8_t hex[256] + static const int8_t digits[256] nxt_aligned(32) = { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -1, -1, -1, -1, -1, -1, - -1, 10, 11, 12, 13, 14, 15, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, 10, 11, 12, 13, 14, 15, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, + 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, -1, -1, -1, -1, -1, + -1, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, + 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, @@ -150,13 +150,13 @@ njs_hex_number_parse(u_char *p, u_char * n = 0; while (p < end) { - d = hex[*p++]; + d = digits[*p++]; - if (nxt_slow_path(d < 0)) { - return -1; + if (nxt_slow_path(d >= radix)) { + return (exact) ? -1 : (int64_t) n; } - n = (n << 4) + d; + n = (n * radix) + d; } return n; @@ -474,3 +474,78 @@ njs_number_is_finite(njs_vm_t *vm, njs_v return NXT_OK; } + + +njs_ret_t +njs_number_parse_int(njs_vm_t *vm, njs_value_t *args, nxt_uint_t nargs, + njs_index_t unused) +{ + double num; + u_char *p, *end; + int64_t n; + uint8_t radix; + nxt_bool_t minus; + njs_string_prop_t string; + + num = NJS_NAN; + + if (nargs > 1) { + (void) njs_string_prop(&string, &args[1]); + + p = string.start; + end = string.start + string.size; + + while (p < end) { + if (*p != ' ') { + goto found; + } + } + + goto done; + + found: + + minus = 0; + + if (p[0] == '-') { + p++; + minus = 1; + + } else if (p[0] == '+') { + p++; + } + + if (end - p > 1 && p[0] == '0' && (p[1] == 'x' || p[1] == 'X')) { + p += 2; + radix = 16; + + } else { + radix = 10; + } + + if (nargs > 2) { + n = args[2].data.u.number; + + if (n != 0) { + + if (n < 2 || n > 36) { + goto done; + } + + radix = n; + } + } + + n = njs_number_radix_parse(p, end, radix, 0); + + if (n >= 0) { + num = (minus) ? -n : n; + } + } + +done: + + njs_number_set(&vm->retval, num); + + return NXT_OK; +} diff -r fd72dd7112c2 -r ffe9a5658450 njs/njs_number.h --- a/njs/njs_number.h Thu Apr 21 18:23:16 2016 +0300 +++ b/njs/njs_number.h Mon Apr 25 17:28:34 2016 +0300 @@ -25,7 +25,8 @@ double njs_value_to_number(njs_value_t *value); double njs_number_parse(const u_char **start, const u_char *end); -int64_t njs_hex_number_parse(u_char *p, u_char *end); +int64_t njs_number_radix_parse(u_char *p, u_char *end, uint8_t radix, + nxt_bool_t exact); njs_ret_t njs_number_to_string(njs_vm_t *vm, njs_value_t *string, const njs_value_t *number); njs_ret_t njs_number_constructor(njs_vm_t *vm, njs_value_t *args, @@ -34,6 +35,8 @@ njs_ret_t njs_number_is_nan(njs_vm_t *vm njs_index_t unused); njs_ret_t njs_number_is_finite(njs_vm_t *vm, njs_value_t *args, nxt_uint_t nargs, njs_index_t unused); +njs_ret_t njs_number_parse_int(njs_vm_t *vm, njs_value_t *args, + nxt_uint_t nargs, njs_index_t unused); extern const njs_object_init_t njs_number_constructor_init; diff -r fd72dd7112c2 -r ffe9a5658450 njs/njs_parser.c --- a/njs/njs_parser.c Thu Apr 21 18:23:16 2016 +0300 +++ b/njs/njs_parser.c Mon Apr 25 17:28:34 2016 +0300 @@ -1647,6 +1647,7 @@ njs_parser_terminal(njs_vm_t *vm, njs_pa case NJS_TOKEN_TO_STRING: case NJS_TOKEN_IS_NAN: case NJS_TOKEN_IS_FINITE: + case NJS_TOKEN_PARSE_INT: return njs_parser_builtin_function(vm, parser, node); default: @@ -2071,7 +2072,7 @@ njs_parser_escape_string_create(njs_vm_t return NJS_TOKEN_ILLEGAL; } - u = njs_hex_number_parse(src, hex_end); + u = njs_number_radix_parse(src, hex_end, 16, 1); if (nxt_slow_path(u < 0)) { return NJS_TOKEN_ILLEGAL; } diff -r fd72dd7112c2 -r ffe9a5658450 njs/njs_parser.h --- a/njs/njs_parser.h Thu Apr 21 18:23:16 2016 +0300 +++ b/njs/njs_parser.h Mon Apr 25 17:28:34 2016 +0300 @@ -178,6 +178,7 @@ typedef enum { NJS_TOKEN_TO_STRING, NJS_TOKEN_IS_NAN, NJS_TOKEN_IS_FINITE, + NJS_TOKEN_PARSE_INT, NJS_TOKEN_RESERVED, } njs_token_t; diff -r fd72dd7112c2 -r ffe9a5658450 njs/njs_vm.h --- a/njs/njs_vm.h Thu Apr 21 18:23:16 2016 +0300 +++ b/njs/njs_vm.h Mon Apr 25 17:28:34 2016 +0300 @@ -704,7 +704,8 @@ enum njs_function_e { NJS_FUNCTION_TO_STRING = 1, NJS_FUNCTION_IS_NAN = 2, NJS_FUNCTION_IS_FINITE = 3, -#define NJS_FUNCTION_MAX (NJS_FUNCTION_IS_FINITE + 1) + NJS_FUNCTION_PARSE_INT = 4, +#define NJS_FUNCTION_MAX (NJS_FUNCTION_PARSE_INT + 1) }; diff -r fd72dd7112c2 -r ffe9a5658450 njs/test/njs_unit_test.c --- a/njs/test/njs_unit_test.c Thu Apr 21 18:23:16 2016 +0300 +++ b/njs/test/njs_unit_test.c Mon Apr 25 17:28:34 2016 +0300 @@ -4431,6 +4431,24 @@ static njs_unit_test_t njs_test[] = { nxt_string("isFinite('abc')"), nxt_string("false") }, + { nxt_string("parseInt('12345abc')"), + nxt_string("12345") }, + + { nxt_string("parseInt('1010', 2)"), + nxt_string("10") }, + + { nxt_string("parseInt('aBc', 16)"), + nxt_string("2748") }, + + { nxt_string("parseInt('0XaBc')"), + nxt_string("2748") }, + + { nxt_string("parseInt('-0xabc')"), + nxt_string("-2748") }, + + { nxt_string("parseInt('njscript', 36)"), + nxt_string("1845449130881") }, + /* External interface. */ { nxt_string("function f(req) { return req.uri }"), From igor at sysoev.ru Wed Jun 1 12:50:33 2016 From: igor at sysoev.ru (Igor Sysoev) Date: Wed, 01 Jun 2016 12:50:33 +0000 Subject: [njs] parseFloat() function. Message-ID: details: http://hg.nginx.org/njs/rev/169958fd3f70 branches: changeset: 110:169958fd3f70 user: Igor Sysoev date: Mon Apr 25 19:30:27 2016 +0300 description: parseFloat() function. diffstat: njs/njs_builtin.c | 2 ++ njs/njs_generator.c | 1 + njs/njs_lexer_keyword.c | 1 + njs/njs_number.c | 20 +++++++++++++++++++- njs/njs_number.h | 2 ++ njs/njs_parser.c | 1 + njs/njs_parser.h | 1 + njs/njs_string.c | 14 ++++++++------ njs/njs_string.h | 2 +- njs/njs_vm.c | 4 ++-- njs/njs_vm.h | 3 ++- njs/test/njs_unit_test.c | 3 +++ 12 files changed, 43 insertions(+), 11 deletions(-) diffs (200 lines): diff -r ffe9a5658450 -r 169958fd3f70 njs/njs_builtin.c --- a/njs/njs_builtin.c Mon Apr 25 17:28:34 2016 +0300 +++ b/njs/njs_builtin.c Mon Apr 25 19:30:27 2016 +0300 @@ -84,6 +84,7 @@ njs_builtin_objects_create(njs_vm_t *vm) NULL, NULL, NULL, + NULL, }; static const njs_function_init_t native_functions[] = { @@ -94,6 +95,7 @@ njs_builtin_objects_create(njs_vm_t *vm) { njs_number_is_finite, { NJS_SKIP_ARG, NJS_NUMBER_ARG } }, { njs_number_parse_int, { NJS_SKIP_ARG, NJS_STRING_ARG, NJS_INTEGER_ARG } }, + { njs_number_parse_float, { NJS_SKIP_ARG, NJS_STRING_ARG } }, }; static const njs_object_prop_t null_proto_property = { diff -r ffe9a5658450 -r 169958fd3f70 njs/njs_generator.c --- a/njs/njs_generator.c Mon Apr 25 17:28:34 2016 +0300 +++ b/njs/njs_generator.c Mon Apr 25 19:30:27 2016 +0300 @@ -298,6 +298,7 @@ njs_generator(njs_vm_t *vm, njs_parser_t case NJS_TOKEN_IS_NAN: case NJS_TOKEN_IS_FINITE: case NJS_TOKEN_PARSE_INT: + case NJS_TOKEN_PARSE_FLOAT: return njs_generate_builtin_object(vm, parser, node); case NJS_TOKEN_FUNCTION: diff -r ffe9a5658450 -r 169958fd3f70 njs/njs_lexer_keyword.c --- a/njs/njs_lexer_keyword.c Mon Apr 25 17:28:34 2016 +0300 +++ b/njs/njs_lexer_keyword.c Mon Apr 25 19:30:27 2016 +0300 @@ -92,6 +92,7 @@ static const njs_keyword_t njs_keywords { nxt_string("isNaN"), NJS_TOKEN_IS_NAN, 0 }, { nxt_string("isFinite"), NJS_TOKEN_IS_FINITE, 0 }, { nxt_string("parseInt"), NJS_TOKEN_PARSE_INT, 0 }, + { nxt_string("parseFloat"), NJS_TOKEN_PARSE_FLOAT, 0 }, /* Reserved words. */ diff -r ffe9a5658450 -r 169958fd3f70 njs/njs_number.c --- a/njs/njs_number.c Mon Apr 25 17:28:34 2016 +0300 +++ b/njs/njs_number.c Mon Apr 25 19:30:27 2016 +0300 @@ -36,7 +36,7 @@ njs_value_to_number(njs_value_t *value) } if (njs_is_string(value)) { - return njs_string_to_number(value); + return njs_string_to_number(value, 1); } if (njs_is_array(value)) { @@ -549,3 +549,21 @@ done: return NXT_OK; } + + +njs_ret_t +njs_number_parse_float(njs_vm_t *vm, njs_value_t *args, nxt_uint_t nargs, + njs_index_t unused) +{ + double num; + + num = NJS_NAN; + + if (nargs > 1) { + num = njs_string_to_number(&args[1], 0); + } + + njs_number_set(&vm->retval, num); + + return NXT_OK; +} diff -r ffe9a5658450 -r 169958fd3f70 njs/njs_number.h --- a/njs/njs_number.h Mon Apr 25 17:28:34 2016 +0300 +++ b/njs/njs_number.h Mon Apr 25 19:30:27 2016 +0300 @@ -37,6 +37,8 @@ njs_ret_t njs_number_is_finite(njs_vm_t nxt_uint_t nargs, njs_index_t unused); njs_ret_t njs_number_parse_int(njs_vm_t *vm, njs_value_t *args, nxt_uint_t nargs, njs_index_t unused); +njs_ret_t njs_number_parse_float(njs_vm_t *vm, njs_value_t *args, + nxt_uint_t nargs, njs_index_t unused); extern const njs_object_init_t njs_number_constructor_init; diff -r ffe9a5658450 -r 169958fd3f70 njs/njs_parser.c --- a/njs/njs_parser.c Mon Apr 25 17:28:34 2016 +0300 +++ b/njs/njs_parser.c Mon Apr 25 19:30:27 2016 +0300 @@ -1648,6 +1648,7 @@ njs_parser_terminal(njs_vm_t *vm, njs_pa case NJS_TOKEN_IS_NAN: case NJS_TOKEN_IS_FINITE: case NJS_TOKEN_PARSE_INT: + case NJS_TOKEN_PARSE_FLOAT: return njs_parser_builtin_function(vm, parser, node); default: diff -r ffe9a5658450 -r 169958fd3f70 njs/njs_parser.h --- a/njs/njs_parser.h Mon Apr 25 17:28:34 2016 +0300 +++ b/njs/njs_parser.h Mon Apr 25 19:30:27 2016 +0300 @@ -179,6 +179,7 @@ typedef enum { NJS_TOKEN_IS_NAN, NJS_TOKEN_IS_FINITE, NJS_TOKEN_PARSE_INT, + NJS_TOKEN_PARSE_FLOAT, NJS_TOKEN_RESERVED, } njs_token_t; diff -r ffe9a5658450 -r 169958fd3f70 njs/njs_string.c --- a/njs/njs_string.c Mon Apr 25 17:28:34 2016 +0300 +++ b/njs/njs_string.c Mon Apr 25 19:30:27 2016 +0300 @@ -1678,7 +1678,7 @@ njs_primitive_value_to_string(njs_vm_t * double -njs_string_to_number(njs_value_t *value) +njs_string_to_number(njs_value_t *value, nxt_bool_t exact) { double num; size_t size; @@ -1737,12 +1737,14 @@ njs_string_to_number(njs_value_t *value) p += infinity; } - while (p < end) { - if (*p != ' ' && *p != '\t') { - return NJS_NAN; + if (exact) { + while (p < end) { + if (*p != ' ' && *p != '\t') { + return NJS_NAN; + } + + p++; } - - p++; } return minus ? -num : num; diff -r ffe9a5658450 -r 169958fd3f70 njs/njs_string.h --- a/njs/njs_string.h Mon Apr 25 17:28:34 2016 +0300 +++ b/njs/njs_string.h Mon Apr 25 19:30:27 2016 +0300 @@ -103,7 +103,7 @@ nxt_noinline uint32_t njs_string_index(n uint32_t offset); njs_ret_t njs_primitive_value_to_string(njs_vm_t *vm, njs_value_t *dst, const njs_value_t *src); -double njs_string_to_number(njs_value_t *value); +double njs_string_to_number(njs_value_t *value, nxt_bool_t exact); njs_index_t njs_value_index(njs_vm_t *vm, njs_parser_t *parser, const njs_value_t *src); diff -r ffe9a5658450 -r 169958fd3f70 njs/njs_vm.c --- a/njs/njs_vm.c Mon Apr 25 17:28:34 2016 +0300 +++ b/njs/njs_vm.c Mon Apr 25 19:30:27 2016 +0300 @@ -2915,7 +2915,7 @@ njs_vmcode_number_primitive(njs_vm_t *vm num = NJS_NAN; if (njs_is_string(value)) { - num = njs_string_to_number(value); + num = njs_string_to_number(value, 1); } njs_number_set(value, num); @@ -2968,7 +2968,7 @@ njs_vmcode_number_argument(njs_vm_t *vm, num = NJS_NAN; if (njs_is_string(value)) { - num = njs_string_to_number(value); + num = njs_string_to_number(value, 1); } njs_number_set(value, num); diff -r ffe9a5658450 -r 169958fd3f70 njs/njs_vm.h --- a/njs/njs_vm.h Mon Apr 25 17:28:34 2016 +0300 +++ b/njs/njs_vm.h Mon Apr 25 19:30:27 2016 +0300 @@ -705,7 +705,8 @@ enum njs_function_e { NJS_FUNCTION_IS_NAN = 2, NJS_FUNCTION_IS_FINITE = 3, NJS_FUNCTION_PARSE_INT = 4, -#define NJS_FUNCTION_MAX (NJS_FUNCTION_PARSE_INT + 1) + NJS_FUNCTION_PARSE_FLOAT = 5, +#define NJS_FUNCTION_MAX (NJS_FUNCTION_PARSE_FLOAT + 1) }; diff -r ffe9a5658450 -r 169958fd3f70 njs/test/njs_unit_test.c --- a/njs/test/njs_unit_test.c Mon Apr 25 17:28:34 2016 +0300 +++ b/njs/test/njs_unit_test.c Mon Apr 25 19:30:27 2016 +0300 @@ -4449,6 +4449,9 @@ static njs_unit_test_t njs_test[] = { nxt_string("parseInt('njscript', 36)"), nxt_string("1845449130881") }, + { nxt_string("parseFloat('12345abc')"), + nxt_string("12345") }, + /* External interface. */ { nxt_string("function f(req) { return req.uri }"), From igor at sysoev.ru Wed Jun 1 12:50:35 2016 From: igor at sysoev.ru (Igor Sysoev) Date: Wed, 01 Jun 2016 12:50:35 +0000 Subject: [njs] Fix in String.indexOf() and String.lastIndexOf() functions. Message-ID: details: http://hg.nginx.org/njs/rev/1c96b24bcdd2 branches: changeset: 111:1c96b24bcdd2 user: Igor Sysoev date: Fri Apr 29 17:02:52 2016 +0300 description: Fix in String.indexOf() and String.lastIndexOf() functions. diffstat: njs/njs_string.c | 37 ++++++++++++++++++++++++------------- 1 files changed, 24 insertions(+), 13 deletions(-) diffs (53 lines): diff -r 169958fd3f70 -r 1c96b24bcdd2 njs/njs_string.c --- a/njs/njs_string.c Mon Apr 25 19:30:27 2016 +0300 +++ b/njs/njs_string.c Fri Apr 29 17:02:52 2016 +0300 @@ -1192,25 +1192,36 @@ njs_string_index_of(njs_vm_t *vm, njs_va if (index < length) { - p = string.start; - end = p + string.size; - if (string.size == length) { /* Byte or ASCII string. */ - p += index; + p = string.start + index; + end = (string.start + string.size) - (search.size - 1); + + while (p < end) { + if (memcmp(p, search.start, search.size) == 0) { + return index; + } + + index++; + p++; + } } else { /* UTF-8 string. */ - p = njs_string_offset(p, end, index); - } - - while (p < end) { - if (memcmp(p, search.start, search.size) == 0) { - return index; + end = string.start + string.size; + + p = njs_string_offset(string.start, end, index); + + end -= search.size - 1; + + while (p < end) { + if (memcmp(p, search.start, search.size) == 0) { + return index; + } + + index++; + p = nxt_utf8_next(p, end); } - - index++; - p = nxt_utf8_next(p, end); } } else if (search.size == 0) { From igor at sysoev.ru Wed Jun 1 12:50:36 2016 From: igor at sysoev.ru (Igor Sysoev) Date: Wed, 01 Jun 2016 12:50:36 +0000 Subject: [njs] PCRE code is available via nxt_regex interface. Message-ID: details: http://hg.nginx.org/njs/rev/b8084a72d667 branches: changeset: 112:b8084a72d667 user: Igor Sysoev date: Wed Jun 01 15:30:50 2016 +0300 description: PCRE code is available via nxt_regex interface. diffstat: nxt/Makefile | 35 +++++-- nxt/nxt_pcre.c | 259 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ nxt/nxt_pcre.h | 34 +++++++ nxt/nxt_regex.h | 42 +++++++++ 4 files changed, 359 insertions(+), 11 deletions(-) diffs (414 lines): diff -r 1c96b24bcdd2 -r b8084a72d667 nxt/Makefile --- a/nxt/Makefile Fri Apr 29 17:02:52 2016 +0300 +++ b/nxt/Makefile Wed Jun 01 15:30:50 2016 +0300 @@ -10,6 +10,7 @@ NXT_LIB = nxt $(NXT_BUILDDIR)/nxt_rbtree.o \ $(NXT_BUILDDIR)/nxt_lvlhsh.o \ $(NXT_BUILDDIR)/nxt_random.o \ + $(NXT_BUILDDIR)/nxt_pcre.o \ $(NXT_BUILDDIR)/nxt_malloc.o \ $(NXT_BUILDDIR)/nxt_mem_cache_pool.o \ @@ -19,8 +20,9 @@ NXT_LIB = nxt $(NXT_BUILDDIR)/nxt_array.o \ $(NXT_BUILDDIR)/nxt_rbtree.o \ $(NXT_BUILDDIR)/nxt_lvlhsh.o \ + $(NXT_BUILDDIR)/nxt_random.o \ + $(NXT_BUILDDIR)/nxt_pcre.o \ $(NXT_BUILDDIR)/nxt_malloc.o \ - $(NXT_BUILDDIR)/nxt_random.o \ $(NXT_BUILDDIR)/nxt_mem_cache_pool.o \ $(NXT_BUILDDIR)/nxt_murmur_hash.o: \ @@ -95,6 +97,27 @@ NXT_LIB = nxt -I$(NXT_LIB) \ $(NXT_LIB)/nxt_lvlhsh.c +$(NXT_BUILDDIR)/nxt_random.o: \ + $(NXT_LIB)/nxt_types.h \ + $(NXT_LIB)/nxt_clang.h \ + $(NXT_LIB)/nxt_random.h \ + $(NXT_LIB)/nxt_random.c \ + + $(NXT_CC) -c -o $(NXT_BUILDDIR)/nxt_random.o $(NXT_CFLAGS) \ + -I$(NXT_LIB) \ + $(NXT_LIB)/nxt_random.c + +$(NXT_BUILDDIR)/nxt_pcre.o: \ + $(NXT_LIB)/nxt_types.h \ + $(NXT_LIB)/nxt_clang.h \ + $(NXT_LIB)/nxt_regex.h \ + $(NXT_LIB)/nxt_pcre.h \ + $(NXT_LIB)/nxt_pcre.c \ + + $(NXT_CC) -c -o $(NXT_BUILDDIR)/nxt_pcre.o $(NXT_CFLAGS) \ + -I$(NXT_LIB) $(NXT_PCRE_CFLAGS) \ + $(NXT_LIB)/nxt_pcre.c + $(NXT_BUILDDIR)/nxt_malloc.o: \ $(NXT_LIB)/nxt_auto_config.h \ $(NXT_LIB)/nxt_types.h \ @@ -106,16 +129,6 @@ NXT_LIB = nxt -I$(NXT_LIB) \ $(NXT_LIB)/nxt_malloc.c -$(NXT_BUILDDIR)/nxt_random.o: \ - $(NXT_LIB)/nxt_types.h \ - $(NXT_LIB)/nxt_clang.h \ - $(NXT_LIB)/nxt_random.h \ - $(NXT_LIB)/nxt_random.c \ - - $(NXT_CC) -c -o $(NXT_BUILDDIR)/nxt_random.o $(NXT_CFLAGS) \ - -I$(NXT_LIB) \ - $(NXT_LIB)/nxt_random.c - $(NXT_BUILDDIR)/nxt_mem_cache_pool.o: \ $(NXT_LIB)/nxt_types.h \ $(NXT_LIB)/nxt_clang.h \ diff -r 1c96b24bcdd2 -r b8084a72d667 nxt/nxt_pcre.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/nxt/nxt_pcre.c Wed Jun 01 15:30:50 2016 +0300 @@ -0,0 +1,259 @@ + +/* + * Copyright (C) Igor Sysoev + * Copyright (C) NGINX, Inc. + */ + +#include +#include +#include +#include +#include +#include +#include + + +static void *nxt_pcre_malloc(size_t size); +static void nxt_pcre_free(void *p); +static void *nxt_pcre_default_malloc(size_t size, void *memory_data); +static void nxt_pcre_default_free(void *p, void *memory_data); + + +static nxt_regex_context_t *regex_context; + + +nxt_regex_context_t * +nxt_regex_context_create(nxt_pcre_malloc_t private_malloc, + nxt_pcre_free_t private_free, void *memory_data) +{ + nxt_regex_context_t *ctx; + + if (private_malloc == NULL) { + private_malloc = nxt_pcre_default_malloc; + private_free = nxt_pcre_default_free; + } + + ctx = private_malloc(sizeof(nxt_regex_context_t), memory_data); + + if (nxt_fast_path(ctx != NULL)) { + ctx->private_malloc = private_malloc; + ctx->private_free = private_free; + ctx->memory_data = memory_data; + } + + return ctx; +} + + +nxt_int_t +nxt_regex_compile(nxt_regex_t *regex, u_char *source, size_t len, + nxt_uint_t options, nxt_regex_context_t *ctx) +{ + int ret, err, erroff; + char *pattern, *error; + void *(*saved_malloc)(size_t size); + void (*saved_free)(void *p); + size_t size; + const char *errstr; + + ret = NXT_ERROR; + + saved_malloc = pcre_malloc; + pcre_malloc = nxt_pcre_malloc; + saved_free = pcre_free; + pcre_free = nxt_pcre_free; + regex_context = ctx; + + if (len == 0) { + pattern = (char *) source; + + } else { + pattern = ctx->private_malloc(len + 1, ctx->memory_data); + if (nxt_slow_path(pattern == NULL)) { + goto done; + } + + memcpy(pattern, source, len); + pattern[len] = '\0'; + } + + regex->code = pcre_compile(pattern, options, &errstr, &erroff, NULL); + + if (nxt_slow_path(regex->code == NULL)) { + error = pattern + erroff; + + size = sizeof("pcre_compile(\"\") failed: at \"\"") + + strlen(errstr) + strlen(error) * 2 + erroff; + + ctx->error = ctx->private_malloc(size, ctx->memory_data); + if (nxt_slow_path(ctx->error == NULL)) { + goto done; + } + + if (*error != '\0') { + (void) snprintf((char *) ctx->error, size, + "pcre_compile(\"%s\") failed: %s at \"%s\"", + pattern, errstr, error); + } else { + (void) snprintf((char *) ctx->error, size, + "pcre_compile(\"%s\") failed: %s", + pattern, errstr); + } + + goto done; + } + + regex->extra = pcre_study(regex->code, 0, &errstr); + + if (nxt_slow_path(errstr != NULL)) { + size = sizeof("pcre_study(\"\") failed: ") + + strlen(pattern) + strlen(errstr); + + ctx->error = ctx->private_malloc(size, ctx->memory_data); + if (nxt_slow_path(ctx->error == NULL)) { + goto done; + } + + (void) snprintf((char *) ctx->error, size, + "pcre_study(\"%s\") failed: %s", pattern, errstr); + + goto done; + } + + err = pcre_fullinfo(regex->code, NULL, PCRE_INFO_CAPTURECOUNT, + ®ex->ncaptures); + + if (nxt_slow_path(err < 0)) { + size = sizeof("pcre_fullinfo(\"\", PCRE_INFO_CAPTURECOUNT) failed: ") + + strlen(pattern) + sizeof("-2147483647"); + + ctx->error = ctx->private_malloc(size, ctx->memory_data); + if (nxt_slow_path(ctx->error == NULL)) { + goto done; + } + + (void) snprintf((char *) ctx->error, size, + "pcre_fullinfo(\"%s\", PCRE_INFO_CAPTURECOUNT) failed: %d", + pattern, err); + + goto done; + } + + /* Reserve additional elements for the first "$0" capture. */ + regex->ncaptures++; + + ret = NXT_OK; + +done: + + pcre_malloc = saved_malloc; + pcre_free = saved_free; + regex_context = NULL; + + return ret; +} + + +nxt_regex_match_data_t * +nxt_regex_match_data(nxt_regex_t *regex, nxt_regex_context_t *ctx) +{ + size_t size; + nxt_uint_t ncaptures; + nxt_regex_match_data_t *match_data; + + if (regex != NULL) { + ncaptures = regex->ncaptures - 1; + + } else { + ncaptures = 0; + } + + /* Each capture is stored in 3 "int" vector elements. */ + ncaptures *= 3; + size = sizeof(nxt_regex_match_data_t) + ncaptures * sizeof(int); + + match_data = ctx->private_malloc(size, ctx->memory_data); + + if (nxt_fast_path(match_data != NULL)) { + match_data->ncaptures = ncaptures + 3; + } + + return match_data; +} + + +void +nxt_regex_match_data_free(nxt_regex_match_data_t *match_data, + nxt_regex_context_t *ctx) +{ + ctx->private_free(match_data, ctx->memory_data); +} + + +static void * +nxt_pcre_malloc(size_t size) +{ + return regex_context->private_malloc(size, regex_context->memory_data); +} + + +static void +nxt_pcre_free(void *p) +{ + regex_context->private_free(p, regex_context->memory_data); +} + + +static void * +nxt_pcre_default_malloc(size_t size, void *memory_data) +{ + return malloc(size); +} + + +static void +nxt_pcre_default_free(void *p, void *memory_data) +{ + free(p); +} + + +nxt_bool_t +nxt_regex_is_valid(nxt_regex_t *regex) +{ + return (regex->code != NULL); +} + + +nxt_int_t +nxt_regex_match(nxt_regex_t *regex, u_char *subject, size_t len, + nxt_regex_match_data_t *match_data, nxt_regex_context_t *ctx) +{ + int ret; + size_t size; + + ret = pcre_exec(regex->code, regex->extra, (char *) subject, len, 0, 0, + match_data->captures, match_data->ncaptures); + + /* PCRE_ERROR_NOMATCH is -1. */ + + if (nxt_slow_path(ret < PCRE_ERROR_NOMATCH)) { + size = sizeof("pcre_exec() failed: ") + sizeof("-2147483647"); + + ctx->error = ctx->private_malloc(size, ctx->memory_data); + + if (nxt_fast_path(ctx->error != NULL)) { + (void) snprintf((char *) ctx->error, size, "pcre_exec() failed: %d", + ret); + } + } + + return ret; +} + + +int * +nxt_regex_captures(nxt_regex_match_data_t *match_data) +{ + return (match_data)->captures; +} diff -r 1c96b24bcdd2 -r b8084a72d667 nxt/nxt_pcre.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/nxt/nxt_pcre.h Wed Jun 01 15:30:50 2016 +0300 @@ -0,0 +1,34 @@ + +/* + * Copyright (C) Igor Sysoev + * Copyright (C) NGINX, Inc. + */ + +#ifndef _NXT_PCRE_H_INCLUDED_ +#define _NXT_PCRE_H_INCLUDED_ + + +#include + + +#define NGX_REGEX_NOMATCH PCRE_ERROR_NOMATCH + + +struct nxt_regex_s { + pcre *code; + pcre_extra *extra; + int ncaptures; +}; + + +struct nxt_regex_match_data_s { + int ncaptures; + /* + * Each capture is stored in 3 "int" vector elements. + * The first vector is for the "$0" capture and it is always allocated. + */ + int captures[3]; +}; + + +#endif /* _NXT_PCRE_H_INCLUDED_ */ diff -r 1c96b24bcdd2 -r b8084a72d667 nxt/nxt_regex.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/nxt/nxt_regex.h Wed Jun 01 15:30:50 2016 +0300 @@ -0,0 +1,42 @@ + +/* + * Copyright (C) Igor Sysoev + * Copyright (C) NGINX, Inc. + */ + +#ifndef _NXT_REGEX_H_INCLUDED_ +#define _NXT_REGEX_H_INCLUDED_ + + +typedef void *(*nxt_pcre_malloc_t)(size_t size, void *memory_data); +typedef void (*nxt_pcre_free_t)(void *p, void *memory_data); + + +typedef struct nxt_regex_s nxt_regex_t; +typedef struct nxt_regex_match_data_s nxt_regex_match_data_t; + + +typedef struct { + nxt_pcre_malloc_t private_malloc; + nxt_pcre_free_t private_free; + void *memory_data; + u_char *error; +} nxt_regex_context_t; + + +NXT_EXPORT nxt_regex_context_t * + nxt_regex_context_create(nxt_pcre_malloc_t private_malloc, + nxt_pcre_free_t private_free, void *memory_data); +NXT_EXPORT nxt_int_t nxt_regex_compile(nxt_regex_t *regex, u_char *source, + size_t len, nxt_uint_t options, nxt_regex_context_t *ctx); +NXT_EXPORT nxt_bool_t nxt_regex_is_valid(nxt_regex_t *regex); +NXT_EXPORT nxt_regex_match_data_t *nxt_regex_match_data(nxt_regex_t *regex, + nxt_regex_context_t *ctx); +NXT_EXPORT void nxt_regex_match_data_free(nxt_regex_match_data_t *match_data, + nxt_regex_context_t *ctx); +NXT_EXPORT nxt_int_t nxt_regex_match(nxt_regex_t *regex, u_char *subject, + size_t len, nxt_regex_match_data_t *match_data, nxt_regex_context_t *ctx); +NXT_EXPORT int *nxt_regex_captures(nxt_regex_match_data_t *match_data); + + +#endif /* _NXT_REGEX_H_INCLUDED_ */ From igor at sysoev.ru Wed Jun 1 12:50:37 2016 From: igor at sysoev.ru (Igor Sysoev) Date: Wed, 01 Jun 2016 12:50:37 +0000 Subject: [njs] Using nxt_regex interface in nJSVM. Message-ID: details: http://hg.nginx.org/njs/rev/c72fd0d1fabc branches: changeset: 113:c72fd0d1fabc user: Igor Sysoev date: Wed Jun 01 15:31:34 2016 +0300 description: Using nxt_regex interface in nJSVM. diffstat: Makefile | 2 + njs/njs_disassembler.c | 1 - njs/njs_lexer_keyword.c | 1 - njs/njs_regexp.c | 238 ++++++++++++++++++++-------------------------- njs/njs_regexp.h | 3 +- njs/njs_regexp_pattern.h | 4 +- njs/njs_string.c | 91 +++++++++++++---- njs/njs_string.h | 2 + njs/njs_vm.h | 13 ++- njs/njscript.c | 15 +- njs/test/njs_unit_test.c | 3 + 11 files changed, 205 insertions(+), 168 deletions(-) diffs (773 lines): diff -r b8084a72d667 -r c72fd0d1fabc Makefile --- a/Makefile Wed Jun 01 15:30:50 2016 +0300 +++ b/Makefile Wed Jun 01 15:31:34 2016 +0300 @@ -36,6 +36,7 @@ NXT_BUILDDIR = build $(NXT_BUILDDIR)/nxt_rbtree.o \ $(NXT_BUILDDIR)/nxt_lvlhsh.o \ $(NXT_BUILDDIR)/nxt_random.o \ + $(NXT_BUILDDIR)/nxt_pcre.o \ $(NXT_BUILDDIR)/nxt_malloc.o \ $(NXT_BUILDDIR)/nxt_mem_cache_pool.o \ @@ -67,6 +68,7 @@ NXT_BUILDDIR = build $(NXT_BUILDDIR)/nxt_rbtree.o \ $(NXT_BUILDDIR)/nxt_lvlhsh.o \ $(NXT_BUILDDIR)/nxt_random.o \ + $(NXT_BUILDDIR)/nxt_pcre.o \ $(NXT_BUILDDIR)/nxt_malloc.o \ $(NXT_BUILDDIR)/nxt_mem_cache_pool.o \ diff -r b8084a72d667 -r c72fd0d1fabc njs/njs_disassembler.c --- a/njs/njs_disassembler.c Wed Jun 01 15:30:50 2016 +0300 +++ b/njs/njs_disassembler.c Wed Jun 01 15:31:34 2016 +0300 @@ -14,7 +14,6 @@ #include #include #include -#include #include #include #include diff -r b8084a72d667 -r c72fd0d1fabc njs/njs_lexer_keyword.c --- a/njs/njs_lexer_keyword.c Wed Jun 01 15:30:50 2016 +0300 +++ b/njs/njs_lexer_keyword.c Wed Jun 01 15:31:34 2016 +0300 @@ -16,7 +16,6 @@ #include #include #include -#include #include #include #include diff -r b8084a72d667 -r c72fd0d1fabc njs/njs_regexp.c --- a/njs/njs_regexp.c Wed Jun 01 15:30:50 2016 +0300 +++ b/njs/njs_regexp.c Wed Jun 01 15:31:34 2016 +0300 @@ -14,6 +14,7 @@ #include #include #include +#include #include #include #include @@ -30,17 +31,51 @@ #include +static void *njs_regexp_malloc(size_t size, void *memory_data); +static void njs_regexp_free(void *p, void *memory_data); static njs_regexp_flags_t njs_regexp_flags(u_char **start, u_char *end, nxt_bool_t bound); -static int njs_regexp_pattern_compile(pcre **code, pcre_extra **extra, +static int njs_regexp_pattern_compile(njs_vm_t *vm, nxt_regex_t *regex, u_char *source, int options); static njs_ret_t njs_regexp_exec_result(njs_vm_t *vm, njs_regexp_t *regexp, - u_char *string, int *captures, nxt_uint_t utf8); + u_char *string, nxt_regex_match_data_t *match_data, nxt_uint_t utf8); static njs_ret_t njs_regexp_string_create(njs_vm_t *vm, njs_value_t *value, u_char *start, uint32_t size, int32_t length); njs_ret_t +njs_regexp_init(njs_vm_t *vm) +{ + vm->regex_context = nxt_regex_context_create(njs_regexp_malloc, + njs_regexp_free, vm->mem_cache_pool); + if (nxt_slow_path(vm->regex_context == NULL)) { + return NXT_ERROR; + } + + vm->single_match_data = nxt_regex_match_data(NULL, vm->regex_context); + if (nxt_slow_path(vm->single_match_data == NULL)) { + return NXT_ERROR; + } + + return NXT_OK; +} + + +static void * +njs_regexp_malloc(size_t size, void *memory_data) +{ + return nxt_mem_cache_alloc(memory_data, size); +} + + +static void +njs_regexp_free(void *p, void *memory_data) +{ + nxt_mem_cache_free(memory_data, p); +} + + +njs_ret_t njs_regexp_constructor(njs_vm_t *vm, njs_value_t *args, nxt_uint_t nargs, njs_index_t unused) { @@ -205,18 +240,14 @@ njs_regexp_pattern_create(njs_vm_t *vm, size += ((flags & NJS_REGEXP_IGNORE_CASE) != 0); size += ((flags & NJS_REGEXP_MULTILINE) != 0); - pattern = nxt_mem_cache_alloc(vm->mem_cache_pool, - sizeof(njs_regexp_pattern_t) - + 1 + length + size + 1); + pattern = nxt_mem_cache_zalloc(vm->mem_cache_pool, + sizeof(njs_regexp_pattern_t) + + 1 + length + size + 1); if (nxt_slow_path(pattern == NULL)) { return NULL; } pattern->flags = size; - pattern->code[0] = NULL; - pattern->code[1] = NULL; - pattern->extra[0] = NULL; - pattern->extra[1] = NULL; pattern->next = NULL; p = (u_char *) pattern + sizeof(njs_regexp_pattern_t); @@ -254,18 +285,16 @@ njs_regexp_pattern_create(njs_vm_t *vm, *p++ = '\0'; - ret = njs_regexp_pattern_compile(&pattern->code[0], &pattern->extra[0], + ret = njs_regexp_pattern_compile(vm, &pattern->regex[0], &pattern->source[1], options); - if (nxt_slow_path(ret < 0)) { return NULL; } pattern->ncaptures = ret; - ret = njs_regexp_pattern_compile(&pattern->code[1], &pattern->extra[1], + ret = njs_regexp_pattern_compile(vm, &pattern->regex[1], &pattern->source[1], options | PCRE_UTF8); - if (nxt_fast_path(ret >= 0)) { if (nxt_slow_path((u_int) ret != pattern->ncaptures)) { @@ -273,75 +302,35 @@ njs_regexp_pattern_create(njs_vm_t *vm, "and UTF-8 versions of RegExp \"%s\" vary: %d vs %d", &pattern->source[1], pattern->ncaptures, ret); - njs_regexp_pattern_free(pattern); + nxt_mem_cache_free(vm->mem_cache_pool, pattern); return NULL; } } else if (ret != NXT_DECLINED) { - njs_regexp_pattern_free(pattern); + nxt_mem_cache_free(vm->mem_cache_pool, pattern); return NULL; } *end = '/'; - pattern->next = vm->pattern; - vm->pattern = pattern; - return pattern; } static int -njs_regexp_pattern_compile(pcre **code, pcre_extra **extra, u_char *source, +njs_regexp_pattern_compile(njs_vm_t *vm, nxt_regex_t *regex, u_char *source, int options) { - int ret, erroff, captures; - u_char *error; - const char *errstr; - - *code = pcre_compile((char *) source, options, &errstr, &erroff, NULL); - - if (nxt_slow_path(*code == NULL)) { - - if ((options & PCRE_UTF8) != 0) { - return NXT_DECLINED; - } + nxt_int_t ret; - error = source + erroff; + /* Zero length means a zero-terminated string. */ + ret = nxt_regex_compile(regex, source, 0, options, vm->regex_context); - if (*error != '\0') { - nxt_thread_log_error(NXT_LOG_ERR, - "pcre_compile(\"%s\") failed: %s at \"%s\"", - source, errstr, error); - } else { - nxt_thread_log_error(NXT_LOG_ERR, - "pcre_compile(\"%s\") failed: %s", - source, errstr); - } - - return NXT_ERROR; + if (nxt_fast_path(ret == NXT_OK)) { + return regex->ncaptures; } - *extra = pcre_study(*code, 0, &errstr); - - if (nxt_slow_path(errstr != NULL)) { - nxt_thread_log_error(NXT_LOG_ERR, "pcre_study(\"%s\") failed: %s", - source, errstr); - return NXT_ERROR; - } - - ret = pcre_fullinfo(*code, NULL, PCRE_INFO_CAPTURECOUNT, &captures); - - if (nxt_fast_path(ret >= 0)) { - /* Reserve additional elements for the first "$0" capture. */ - return captures + 1; - } - - nxt_thread_log_error(NXT_LOG_ERR, - "pcre_fullinfo(\"%s\", PCRE_INFO_CAPTURECOUNT) failed: %d", - source, ret); - - return NXT_ERROR; + return njs_string_exception(vm, NJS_SYNTAX_ERROR, vm->regex_context->error); } @@ -491,16 +480,15 @@ njs_regexp_prototype_test(njs_vm_t *vm, pattern = args[0].data.u.regexp->pattern; - if (pattern->code[n] != NULL) { - ret = pcre_exec(pattern->code[n], pattern->extra[n], - (char *) string.start, string.size, 0, 0, NULL, 0); - + if (nxt_regex_is_valid(&pattern->regex[n])) { + ret = nxt_regex_match(&pattern->regex[n], string.start, string.size, + vm->single_match_data, vm->regex_context); if (ret >= 0) { retval = &njs_value_true; - } else if (ret != PCRE_ERROR_NOMATCH) { - vm->exception = &njs_exception_internal_error; - return NXT_ERROR; + } else if (ret != NGX_REGEX_NOMATCH) { + return njs_string_exception(vm, NJS_INTERNAL_ERROR, + vm->regex_context->error); } } @@ -514,13 +502,13 @@ njs_ret_t njs_regexp_prototype_exec(njs_vm_t *vm, njs_value_t *args, nxt_uint_t nargs, njs_index_t unused) { - int *captures, ncaptures; - njs_ret_t ret; - nxt_uint_t n, utf8; - njs_value_t *value; - njs_regexp_t *regexp; - njs_string_prop_t string; - njs_regexp_pattern_t *pattern; + njs_ret_t ret; + nxt_uint_t n, utf8; + njs_value_t *value; + njs_regexp_t *regexp; + njs_string_prop_t string; + njs_regexp_pattern_t *pattern; + nxt_regex_match_data_t *match_data; if (!njs_is_regexp(&args[0])) { vm->exception = &njs_exception_type_error; @@ -553,27 +541,28 @@ njs_regexp_prototype_exec(njs_vm_t *vm, pattern = regexp->pattern; - if (pattern->code[n] != NULL) { + if (nxt_regex_is_valid(&pattern->regex[n])) { string.start += regexp->last_index; string.size -= regexp->last_index; - /* Each capture is stored in 3 vector elements. */ - ncaptures = pattern->ncaptures * 3; - - captures = alloca(ncaptures * sizeof(int)); - - ret = pcre_exec(pattern->code[n], pattern->extra[n], - (char *) string.start, string.size, - 0, 0, captures, ncaptures); - - if (ret >= 0) { - return njs_regexp_exec_result(vm, regexp, string.start, - captures, utf8); + match_data = nxt_regex_match_data(&pattern->regex[n], + vm->regex_context); + if (nxt_slow_path(match_data == NULL)) { + return NXT_ERROR; } - if (nxt_slow_path(ret != PCRE_ERROR_NOMATCH)) { - vm->exception = &njs_exception_internal_error; - return NXT_ERROR; + ret = nxt_regex_match(&pattern->regex[n], string.start, string.size, + match_data, vm->regex_context); + if (ret >= 0) { + return njs_regexp_exec_result(vm, regexp, string.start, match_data, + utf8); + } + + if (nxt_slow_path(ret != NGX_REGEX_NOMATCH)) { + nxt_regex_match_data_free(match_data, vm->regex_context); + + return njs_string_exception(vm, NJS_INTERNAL_ERROR, + vm->regex_context->error); } } @@ -586,8 +575,9 @@ njs_regexp_prototype_exec(njs_vm_t *vm, static njs_ret_t njs_regexp_exec_result(njs_vm_t *vm, njs_regexp_t *regexp, u_char *string, - int *captures, nxt_uint_t utf8) + nxt_regex_match_data_t *match_data, nxt_uint_t utf8) { + int *captures; u_char *start; int32_t size, length; njs_ret_t ret; @@ -601,9 +591,11 @@ njs_regexp_exec_result(njs_vm_t *vm, njs array = njs_array_alloc(vm, regexp->pattern->ncaptures, 0); if (nxt_slow_path(array == NULL)) { - return NXT_ERROR; + goto fail; } + captures = nxt_regex_captures(match_data); + for (i = 0; i < regexp->pattern->ncaptures; i++) { n = 2 * i; @@ -626,7 +618,7 @@ njs_regexp_exec_result(njs_vm_t *vm, njs ret = njs_regexp_string_create(vm, &array->start[i], start, size, length); if (nxt_slow_path(ret != NXT_OK)) { - return NXT_ERROR; + goto fail; } } else { @@ -636,7 +628,7 @@ njs_regexp_exec_result(njs_vm_t *vm, njs prop = njs_object_prop_alloc(vm, &njs_string_index); if (nxt_slow_path(prop == NULL)) { - return NXT_ERROR; + goto fail; } /* TODO: Non UTF-8 position */ @@ -657,13 +649,12 @@ njs_regexp_exec_result(njs_vm_t *vm, njs ret = nxt_lvlhsh_insert(&array->object.hash, &lhq); if (nxt_slow_path(ret != NXT_OK)) { - /* Only NXT_ERROR can be returned here. */ - return ret; + goto fail; } prop = njs_object_prop_alloc(vm, &njs_string_input); if (nxt_slow_path(prop == NULL)) { - return NXT_ERROR; + goto fail; } njs_string_copy(&prop->value, ®exp->string); @@ -674,16 +665,25 @@ njs_regexp_exec_result(njs_vm_t *vm, njs lhq.value = prop; ret = nxt_lvlhsh_insert(&array->object.hash, &lhq); - if (nxt_slow_path(ret != NXT_OK)) { - /* Only NXT_ERROR can be returned here. */ - return ret; + + if (nxt_fast_path(ret == NXT_OK)) { + vm->retval.data.u.array = array; + vm->retval.type = NJS_ARRAY; + vm->retval.data.truth = 1; + + ret = NXT_OK; + goto done; } - vm->retval.data.u.array = array; - vm->retval.type = NJS_ARRAY; - vm->retval.data.truth = 1; +fail: - return NXT_OK; + ret = NXT_ERROR; + +done: + + nxt_regex_match_data_free(match_data, vm->regex_context); + + return ret; } @@ -789,29 +789,3 @@ const njs_object_init_t njs_regexp_prot njs_regexp_prototype_properties, nxt_nitems(njs_regexp_prototype_properties), }; - - -void -njs_regexp_pattern_free(njs_regexp_pattern_t *pattern) -{ - /* - * pcre_free() is enough to free PCRE extra study data. - * pcre_free_study() is required for JIT optimization, pcreapi(3): - * - * When you are finished with a pattern, you can free the memory used - * for the study data by calling pcre_free_study(). This function was - * added to the API for release 8.20. For earlier versions, the memory - * could be freed with pcre_free(), just like the pattern itself. This - * will still work in cases where JIT optimization is not used, but it - * is advisable to change to the new function when convenient. - */ - while (pattern != NULL) { - pcre_free(pattern->extra[0]); - pcre_free(pattern->code[0]); - - pcre_free(pattern->extra[1]); - pcre_free(pattern->code[1]); - - pattern = pattern->next; - } -} diff -r b8084a72d667 -r c72fd0d1fabc njs/njs_regexp.h --- a/njs/njs_regexp.h Wed Jun 01 15:30:50 2016 +0300 +++ b/njs/njs_regexp.h Wed Jun 01 15:31:34 2016 +0300 @@ -32,6 +32,7 @@ struct njs_regexp_s { }; +njs_ret_t njs_regexp_init(njs_vm_t *vm); njs_ret_t njs_regexp_constructor(njs_vm_t *vm, njs_value_t *args, nxt_uint_t nargs, njs_index_t unused); nxt_int_t njs_regexp_literal(njs_vm_t *vm, njs_parser_t *parser, @@ -41,7 +42,7 @@ njs_regexp_pattern_t *njs_regexp_pattern njs_regexp_t *njs_regexp_alloc(njs_vm_t *vm, njs_regexp_pattern_t *pattern); njs_ret_t njs_regexp_prototype_exec(njs_vm_t *vm, njs_value_t *args, nxt_uint_t nargs, njs_index_t unused); -void njs_regexp_pattern_free(njs_regexp_pattern_t *pattern); + extern const njs_object_init_t njs_regexp_constructor_init; extern const njs_object_init_t njs_regexp_prototype_init; diff -r b8084a72d667 -r c72fd0d1fabc njs/njs_regexp_pattern.h --- a/njs/njs_regexp_pattern.h Wed Jun 01 15:30:50 2016 +0300 +++ b/njs/njs_regexp_pattern.h Wed Jun 01 15:31:34 2016 +0300 @@ -11,8 +11,8 @@ struct njs_regexp_pattern_s { - pcre *code[2]; - pcre_extra *extra[2]; + nxt_regex_t regex[2]; + njs_regexp_pattern_t *next; /* * A pattern source is used by RegExp.toString() method and diff -r b8084a72d667 -r c72fd0d1fabc njs/njs_string.c --- a/njs/njs_string.c Wed Jun 01 15:30:50 2016 +0300 +++ b/njs/njs_string.c Wed Jun 01 15:31:34 2016 +0300 @@ -14,6 +14,7 @@ #include #include #include +#include #include #include #include @@ -1409,12 +1410,11 @@ static njs_ret_t njs_string_prototype_search(njs_vm_t *vm, njs_value_t *args, nxt_uint_t nargs, njs_index_t unused) { - int ret; + int ret, *captures; nxt_int_t index; nxt_uint_t n; njs_string_prop_t string; njs_regexp_pattern_t *pattern; - int captures[3]; index = 0; @@ -1450,17 +1450,16 @@ njs_string_prototype_search(njs_vm_t *vm n = (string.length != 0 && string.length != string.size); - if (pattern->code[n] != NULL) { - ret = pcre_exec(pattern->code[n], pattern->extra[n], - (char *) string.start, string.size, - 0, 0, captures, 3); - + if (nxt_regex_is_valid(&pattern->regex[n])) { + ret = nxt_regex_match(&pattern->regex[n], string.start, string.size, + vm->single_match_data, vm->regex_context); if (ret >= 0) { + captures = nxt_regex_captures(vm->single_match_data); index = njs_string_index(&string, captures[0]); - } else if (ret != PCRE_ERROR_NOMATCH) { - vm->exception = &njs_exception_internal_error; - return NXT_ERROR; + } else if (ret != NGX_REGEX_NOMATCH) { + return njs_string_exception(vm, NJS_INTERNAL_ERROR, + vm->regex_context->error); } } } @@ -1489,7 +1488,7 @@ njs_string_prototype_match(njs_vm_t *vm, njs_array_t *array; njs_string_prop_t string; njs_regexp_pattern_t *pattern; - int captures[3]; + int *captures; if (nargs == 1) { goto empty; @@ -1549,14 +1548,12 @@ njs_string_prototype_match(njs_vm_t *vm, } } - if (pattern->code[n] != NULL) { + if (nxt_regex_is_valid(&pattern->regex[n])) { array = NULL; do { - ret = pcre_exec(pattern->code[n], pattern->extra[n], - (char *) string.start, string.size, - 0, 0, captures, 3); - + ret = nxt_regex_match(&pattern->regex[n], string.start, string.size, + vm->single_match_data, vm->regex_context); if (ret >= 0) { if (array != NULL) { if (array->length == array->size) { @@ -1577,6 +1574,7 @@ njs_string_prototype_match(njs_vm_t *vm, vm->retval.data.truth = 1; } + captures = nxt_regex_captures(vm->single_match_data); start = &string.start[captures[0]]; string.start += captures[1]; @@ -1595,8 +1593,10 @@ njs_string_prototype_match(njs_vm_t *vm, default: length = nxt_utf8_length(start, size); + if (nxt_slow_path(length < 0)) { - goto error; + vm->exception = &njs_exception_internal_error; + return NXT_ERROR; } break; @@ -1610,11 +1610,12 @@ njs_string_prototype_match(njs_vm_t *vm, array->length++; - } else if (ret == PCRE_ERROR_NOMATCH) { + } else if (ret == NGX_REGEX_NOMATCH) { break; } else { - goto error; + return njs_string_exception(vm, NJS_INTERNAL_ERROR, + vm->regex_context->error); } } while (string.size > 0); @@ -1626,12 +1627,6 @@ njs_string_prototype_match(njs_vm_t *vm, return NXT_OK; -error: - - vm->exception = &njs_exception_internal_error; - - return NXT_ERROR; - empty: array = njs_array_alloc(vm, 1, 0); @@ -2049,3 +2044,49 @@ njs_value_index(njs_vm_t *vm, njs_parser return (njs_index_t) value; } + + +nxt_int_t +njs_string_exception(njs_vm_t *vm, njs_exception_error_t exception, u_char *msg) +{ + u_char *p, *start; + uint32_t msg_length, size, length; + nxt_str_t *error; + njs_value_t *value; + + static nxt_str_t errors[] = { + nxt_string("SyntaxError: "), + nxt_string("InternalError: "), + }; + + value = nxt_mem_cache_alloc(vm->mem_cache_pool, sizeof(njs_value_t)); + if (nxt_slow_path(value == NULL)) { + return NXT_ERROR; + } + + error = &errors[exception]; + + msg_length = (msg != NULL) ? strlen((char *) msg) : 0; + length = nxt_utf8_length(msg, msg_length); + + size = error->len + msg_length; + length += error->len; + + start = njs_string_alloc(vm, value, size, length); + + if (nxt_fast_path(start != NULL)) { + memcpy(start, error->data, error->len); + p = start + error->len; + + memcpy(p, msg, msg_length); + + if (size != length && length >= NJS_STRING_MAP_OFFSET) { + njs_string_offset_map_init(start, size); + } + } + + vm->exception = value; + + return NXT_ERROR; +} + diff -r b8084a72d667 -r c72fd0d1fabc njs/njs_string.h --- a/njs/njs_string.h Wed Jun 01 15:30:50 2016 +0300 +++ b/njs/njs_string.h Wed Jun 01 15:31:34 2016 +0300 @@ -107,6 +107,8 @@ double njs_string_to_number(njs_value_t njs_index_t njs_value_index(njs_vm_t *vm, njs_parser_t *parser, const njs_value_t *src); +nxt_int_t njs_string_exception(njs_vm_t *vm, njs_exception_error_t exception, + u_char *msg); extern const njs_object_init_t njs_string_constructor_init; extern const njs_object_init_t njs_string_prototype_init; diff -r b8084a72d667 -r c72fd0d1fabc njs/njs_vm.h --- a/njs/njs_vm.h Wed Jun 01 15:30:50 2016 +0300 +++ b/njs/njs_vm.h Wed Jun 01 15:31:34 2016 +0300 @@ -8,6 +8,9 @@ #define _NJS_VM_H_INCLUDED_ +#include + + /* * Negative return values handled by nJSVM interpreter as special events. * The values must be in range from -1 to -11, because -12 is minimal jump @@ -790,7 +793,9 @@ struct njs_vm_s { njs_vm_shared_t *shared; njs_parser_t *parser; - njs_regexp_pattern_t *pattern; + + nxt_regex_context_t *regex_context; + nxt_regex_match_data_t *single_match_data; nxt_array_t *code; /* of njs_vm_code_t */ @@ -822,6 +827,12 @@ struct njs_vm_shared_s { }; +typedef enum { + NJS_SYNTAX_ERROR = 0, + NJS_INTERNAL_ERROR, +} njs_exception_error_t; + + nxt_int_t njs_vmcode_interpreter(njs_vm_t *vm); void njs_value_retain(njs_value_t *value); diff -r b8084a72d667 -r c72fd0d1fabc njs/njscript.c --- a/njs/njscript.c Wed Jun 01 15:30:50 2016 +0300 +++ b/njs/njscript.c Wed Jun 01 15:31:34 2016 +0300 @@ -116,12 +116,16 @@ njs_vm_create(nxt_mem_cache_pool_t *mcp, if (nxt_fast_path(vm != NULL)) { vm->mem_cache_pool = mcp; + ret = njs_regexp_init(vm); + if (nxt_slow_path(ret != NXT_OK)) { + return NULL; + } + if (shared != NULL && *shared != NULL) { vm->shared = *shared; } else { vm->shared = nxt_mem_cache_zalloc(mcp, sizeof(njs_vm_shared_t)); - if (nxt_slow_path(vm->shared == NULL)) { return NULL; } @@ -133,7 +137,6 @@ njs_vm_create(nxt_mem_cache_pool_t *mcp, nxt_lvlhsh_init(&vm->shared->keywords_hash); ret = njs_lexer_keywords_init(mcp, &vm->shared->keywords_hash); - if (nxt_slow_path(ret != NXT_OK)) { return NULL; } @@ -141,7 +144,6 @@ njs_vm_create(nxt_mem_cache_pool_t *mcp, nxt_lvlhsh_init(&vm->shared->values_hash); ret = njs_builtin_objects_create(vm); - if (nxt_slow_path(ret != NXT_OK)) { return NULL; } @@ -161,8 +163,6 @@ njs_vm_create(nxt_mem_cache_pool_t *mcp, void njs_vm_destroy(njs_vm_t *vm) { - njs_regexp_pattern_free(vm->pattern); - nxt_mem_cache_pool_destroy(vm->mem_cache_pool); } @@ -312,6 +312,11 @@ njs_vm_clone(njs_vm_t *vm, nxt_mem_cache memcpy(values + NJS_INDEX_GLOBAL_OFFSET, vm->global_scope, vm->scope_size); + ret = njs_regexp_init(nvm); + if (nxt_slow_path(ret != NXT_OK)) { + goto fail; + } + ret = njs_builtin_objects_clone(nvm); if (nxt_slow_path(ret != NXT_OK)) { goto fail; diff -r b8084a72d667 -r c72fd0d1fabc njs/test/njs_unit_test.c --- a/njs/test/njs_unit_test.c Wed Jun 01 15:30:50 2016 +0300 +++ b/njs/test/njs_unit_test.c Wed Jun 01 15:31:34 2016 +0300 @@ -3369,6 +3369,9 @@ static njs_unit_test_t njs_test[] = /* RegExp. */ + { nxt_string("/(/.test('')"), + nxt_string("SyntaxError: pcre_compile(\"(\") failed: missing )") }, + { nxt_string("/^$/.test('')"), nxt_string("true") }, From sepherosa at gmail.com Thu Jun 2 12:48:19 2016 From: sepherosa at gmail.com (Sepherosa Ziehau) Date: Thu, 2 Jun 2016 20:48:19 +0800 Subject: [PATCH] Use clock_gettime(REAL_FAST) on DragonFlyBSD Message-ID: Hi, On DragonflyBSD only clock_gettime(*_FAST) avoids system call and time counter read cost (kinda like Linux VDSO). This gives some improvement for performance and reduces latency. My testing setup consists two clients and one nginx (recent head code) server, two clients connected to the nginx server through two 10Ge (82599). 15K concurrent connections from each client; client runs a modified version of wrk and each connection only carries one request for an 1KB file. Performance goes from 183Kreqs/s to 184Kreqs/s (admittedly pretty minor). Average latency reduces 2ms (98ms -> 96ms). Latency stdev reduces 6ms (198ms -> 192ms). Patch is attached. Thanks, sephe -- Tomorrow Will Never Die -------------- next part -------------- diff --git a/src/os/unix/ngx_time.h b/src/os/unix/ngx_time.h index c128c9a..da33a64 100644 --- a/src/os/unix/ngx_time.h +++ b/src/os/unix/ngx_time.h @@ -58,7 +58,22 @@ void ngx_localtime(time_t s, ngx_tm_t *tm); void ngx_libc_localtime(time_t s, struct tm *tm); void ngx_libc_gmtime(time_t s, struct tm *tm); +#ifdef __DragonFly__ +static inline int +ngx_gettimeofday(struct timeval *tp) +{ + struct timespec ts; + int ret; + + ret = clock_gettime(CLOCK_REALTIME_FAST, &ts); + tp->tv_sec = ts.tv_sec; + tp->tv_usec = ts.tv_nsec / 1000; + return ret; +} +#else #define ngx_gettimeofday(tp) (void) gettimeofday(tp, NULL); +#endif + #define ngx_msleep(ms) (void) usleep(ms * 1000) #define ngx_sleep(s) (void) sleep(s) From mdounin at mdounin.ru Thu Jun 2 15:05:49 2016 From: mdounin at mdounin.ru (Maxim Dounin) Date: Thu, 2 Jun 2016 18:05:49 +0300 Subject: [PATCH] Use clock_gettime(REAL_FAST) on DragonFlyBSD In-Reply-To: References: Message-ID: <20160602150549.GJ36620@mdounin.ru> Hello! On Thu, Jun 02, 2016 at 08:48:19PM +0800, Sepherosa Ziehau wrote: > On DragonflyBSD only clock_gettime(*_FAST) avoids system call and time > counter read cost (kinda like Linux VDSO). This gives some > improvement for performance and reduces latency. At least FreeBSD also has clock_gettime(*_FAST), from where it was taken to DragonFly BSD. And Linux 2.6.32+ has clock_gettime(*_COARSE). We do have plans to use monotonic versions, see https://trac.nginx.org/nginx/ticket/189. > My testing setup consists two clients and one nginx (recent head code) > server, two clients connected to the nginx server through two 10Ge > (82599). 15K concurrent connections from each client; client runs a > modified version of wrk and each connection only carries one request > for an 1KB file. > > Performance goes from 183Kreqs/s to 184Kreqs/s (admittedly pretty > minor). Average latency reduces 2ms (98ms -> 96ms). Latency stdev > reduces 6ms (198ms -> 192ms). This doesn't look statistically significant. Have you tried something like ministat(1) to test the results? Note that nginx only uses gettimeofday() once per event loop iteration, so I wouldn't expect it to make measureable difference. [...] -- Maxim Dounin http://nginx.org/ From sepherosa at gmail.com Thu Jun 2 15:19:26 2016 From: sepherosa at gmail.com (Sepherosa Ziehau) Date: Thu, 2 Jun 2016 23:19:26 +0800 Subject: [PATCH] Use clock_gettime(REAL_FAST) on DragonFlyBSD In-Reply-To: <20160602150549.GJ36620@mdounin.ru> References: <20160602150549.GJ36620@mdounin.ru> Message-ID: On Thu, Jun 2, 2016 at 11:05 PM, Maxim Dounin wrote: > Hello! > > On Thu, Jun 02, 2016 at 08:48:19PM +0800, Sepherosa Ziehau wrote: > >> On DragonflyBSD only clock_gettime(*_FAST) avoids system call and time >> counter read cost (kinda like Linux VDSO). This gives some >> improvement for performance and reduces latency. > > At least FreeBSD also has clock_gettime(*_FAST), from where it was > taken to DragonFly BSD. And Linux 2.6.32+ has > clock_gettime(*_COARSE). > > We do have plans to use monotonic versions, see > https://trac.nginx.org/nginx/ticket/189. Yeah, if we can use clock_gettime(REAL_FAST/REAL_COARSE) that would be great :) Should I submit another patch for it? I think the clockid can be put into the config file. I patched the Dfly specifically, mainly because its gettimeofday is still a syscall and read time counter. While both FreeBSD-current and Linux (which seems to have a sysctl to enable) has VDSO gettimeofday(). > >> My testing setup consists two clients and one nginx (recent head code) >> server, two clients connected to the nginx server through two 10Ge >> (82599). 15K concurrent connections from each client; client runs a >> modified version of wrk and each connection only carries one request >> for an 1KB file. >> >> Performance goes from 183Kreqs/s to 184Kreqs/s (admittedly pretty >> minor). Average latency reduces 2ms (98ms -> 96ms). Latency stdev >> reduces 6ms (198ms -> 192ms). > > This doesn't look statistically significant. Have you tried > something like ministat(1) to test the results? I have wrk --latency data: Before: Latency Distribution 50% 26.03ms 75% 73.95ms 90% 285.33ms 99% 1.04s After: Latency Distribution 50% 22.63ms 75% 77.42ms 90% 278.79ms 99% 1.01s Admittedly, kinda like acceptable measurement errors :P. > > Note that nginx only uses gettimeofday() once per event loop > iteration, so I wouldn't expect it to make measureable difference. Yeah, that's probably why the effect of VDSO like clock_gettime() is not that obvious as w/ the database application. But it is still better than gettimeofday() ;). It will be good, if we can reach the consensus to make the move :) Thanks, sephe From mdounin at mdounin.ru Thu Jun 2 18:21:15 2016 From: mdounin at mdounin.ru (Maxim Dounin) Date: Thu, 2 Jun 2016 21:21:15 +0300 Subject: [PATCH] Use clock_gettime(REAL_FAST) on DragonFlyBSD In-Reply-To: References: <20160602150549.GJ36620@mdounin.ru> Message-ID: <20160602182115.GL36620@mdounin.ru> Hello! On Thu, Jun 02, 2016 at 11:19:26PM +0800, Sepherosa Ziehau wrote: > On Thu, Jun 2, 2016 at 11:05 PM, Maxim Dounin wrote: > > Hello! > > > > On Thu, Jun 02, 2016 at 08:48:19PM +0800, Sepherosa Ziehau wrote: > > > >> On DragonflyBSD only clock_gettime(*_FAST) avoids system call and time > >> counter read cost (kinda like Linux VDSO). This gives some > >> improvement for performance and reduces latency. > > > > At least FreeBSD also has clock_gettime(*_FAST), from where it was > > taken to DragonFly BSD. And Linux 2.6.32+ has > > clock_gettime(*_COARSE). > > > > We do have plans to use monotonic versions, see > > https://trac.nginx.org/nginx/ticket/189. > > Yeah, if we can use clock_gettime(REAL_FAST/REAL_COARSE) that would be great :) > > Should I submit another patch for it? I think the clockid can be put > into the config file. > > I patched the Dfly specifically, mainly because its gettimeofday is > still a syscall and read time counter. While both FreeBSD-current and > Linux (which seems to have a sysctl to enable) has VDSO > gettimeofday(). I don't really think we really should introduce clock_gettime(CLOCK_REALTIME*) instead of gettimeofday(). It's not really needed as gettimeofday() isn't called often. Though we can consider doing this as a part of clock_gettime(CLOCK_MONOTONIC) work as we are going to add appropriate configure tests anyway. > >> My testing setup consists two clients and one nginx (recent head code) > >> server, two clients connected to the nginx server through two 10Ge > >> (82599). 15K concurrent connections from each client; client runs a > >> modified version of wrk and each connection only carries one request > >> for an 1KB file. > >> > >> Performance goes from 183Kreqs/s to 184Kreqs/s (admittedly pretty > >> minor). Average latency reduces 2ms (98ms -> 96ms). Latency stdev > >> reduces 6ms (198ms -> 192ms). > > > > This doesn't look statistically significant. Have you tried > > something like ministat(1) to test the results? > > I have wrk --latency data: > > Before: > Latency Distribution > 50% 26.03ms > 75% 73.95ms > 90% 285.33ms > 99% 1.04s > > After: > Latency Distribution > 50% 22.63ms > 75% 77.42ms > 90% 278.79ms > 99% 1.01s > > Admittedly, kinda like acceptable measurement errors :P. Doesn't look like a statistically significant difference for me, at least in the absense of a margin of error. If you think there is a difference, please try ministat, as already suggested. Not sure it's available on DragonFly BSD, but you can easily grab it here: https://svnweb.freebsd.org/base/head/usr.bin/ministat/ -- Maxim Dounin http://nginx.org/ From sepherosa at gmail.com Fri Jun 3 02:26:01 2016 From: sepherosa at gmail.com (Sepherosa Ziehau) Date: Fri, 3 Jun 2016 10:26:01 +0800 Subject: [PATCH] Use clock_gettime(REAL_FAST) on DragonFlyBSD In-Reply-To: <20160602182115.GL36620@mdounin.ru> References: <20160602150549.GJ36620@mdounin.ru> <20160602182115.GL36620@mdounin.ru> Message-ID: On Fri, Jun 3, 2016 at 2:21 AM, Maxim Dounin wrote: > I don't really think we really should introduce > clock_gettime(CLOCK_REALTIME*) instead of gettimeofday(). It's > not really needed as gettimeofday() isn't called often. > > Though we can consider doing this as a part of > clock_gettime(CLOCK_MONOTONIC) work as we are going to add > appropriate configure tests anyway. OK, got it. :) Thanks, sephe From pluknet at nginx.com Tue Jun 7 09:36:49 2016 From: pluknet at nginx.com (Sergey Kandaurov) Date: Tue, 07 Jun 2016 09:36:49 +0000 Subject: [nginx] Version bump. Message-ID: details: http://hg.nginx.org/nginx/rev/0626855014d6 branches: changeset: 6582:0626855014d6 user: Sergey Kandaurov date: Tue Jun 07 12:26:34 2016 +0300 description: Version bump. diffstat: src/core/nginx.h | 4 ++-- 1 files changed, 2 insertions(+), 2 deletions(-) diffs (14 lines): diff -r ffab73f90763 -r 0626855014d6 src/core/nginx.h --- a/src/core/nginx.h Tue May 31 16:43:49 2016 +0300 +++ b/src/core/nginx.h Tue Jun 07 12:26:34 2016 +0300 @@ -9,8 +9,8 @@ #define _NGINX_H_INCLUDED_ -#define nginx_version 1011001 -#define NGINX_VERSION "1.11.1" +#define nginx_version 1011002 +#define NGINX_VERSION "1.11.2" #define NGINX_VER "nginx/" NGINX_VERSION #ifdef NGX_BUILD From pluknet at nginx.com Tue Jun 7 09:36:57 2016 From: pluknet at nginx.com (Sergey Kandaurov) Date: Tue, 07 Jun 2016 09:36:57 +0000 Subject: [nginx] Configure: revised GCC version processing. Message-ID: details: http://hg.nginx.org/nginx/rev/ade7d0335d77 branches: changeset: 6583:ade7d0335d77 user: Sergey Kandaurov date: Tue Jun 07 12:15:56 2016 +0300 description: Configure: revised GCC version processing. Now GCC 6 and onwards will use -Wno-unused-parameter. diffstat: auto/cc/gcc | 13 ++++++------- 1 files changed, 6 insertions(+), 7 deletions(-) diffs (31 lines): diff -r 0626855014d6 -r ade7d0335d77 auto/cc/gcc --- a/auto/cc/gcc Tue Jun 07 12:26:34 2016 +0300 +++ b/auto/cc/gcc Tue Jun 07 12:15:56 2016 +0300 @@ -151,9 +151,13 @@ CFLAGS="$CFLAGS -Wall -Wpointer-arith" #CFLAGS="$CFLAGS -Winline" #CFLAGS="$CFLAGS -Wmissing-prototypes" +case "$NGX_GCC_VER" in + 2.*) + # we have a lot of the unused function arguments + CFLAGS="$CFLAGS -Wno-unused" + ;; -case "$NGX_GCC_VER" in - [3-5].*) + *) # we have a lot of the unused function arguments CFLAGS="$CFLAGS -Wno-unused-parameter" # 4.2.1 shows the warning in wrong places @@ -164,11 +168,6 @@ case "$NGX_GCC_VER" in CFLAGS="$CFLAGS -Wno-deprecated-declarations" fi ;; - - *) - # we have a lot of the unused function arguments - CFLAGS="$CFLAGS -Wno-unused" - ;; esac From vbart at nginx.com Tue Jun 7 14:44:47 2016 From: vbart at nginx.com (Valentin Bartenev) Date: Tue, 07 Jun 2016 14:44:47 +0000 Subject: [nginx] Fixed an error log message. Message-ID: details: http://hg.nginx.org/nginx/rev/690b15cc8915 branches: changeset: 6584:690b15cc8915 user: Valentin Bartenev date: Tue Jun 07 17:44:20 2016 +0300 description: Fixed an error log message. diffstat: src/http/ngx_http_request.c | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diffs (12 lines): diff -r ade7d0335d77 -r 690b15cc8915 src/http/ngx_http_request.c --- a/src/http/ngx_http_request.c Tue Jun 07 12:15:56 2016 +0300 +++ b/src/http/ngx_http_request.c Tue Jun 07 17:44:20 2016 +0300 @@ -2068,7 +2068,7 @@ ngx_http_set_virtual_server(ngx_http_req if (sscf->verify) { ngx_log_error(NGX_LOG_INFO, r->connection->log, 0, "client attempted to request the server name " - "different from that one was negotiated"); + "different from the one that was negotiated"); ngx_http_finalize_request(r, NGX_HTTP_MISDIRECTED_REQUEST); return NGX_ERROR; } From ranier_gyn at hotmail.com Tue Jun 7 20:15:09 2016 From: ranier_gyn at hotmail.com (Ranier VF) Date: Tue, 7 Jun 2016 20:15:09 +0000 Subject: Nginx bug? Message-ID: Hi, nginx-1.10, windows build. msvc 2010 where full_name is u_char [64] b->last = ngx_sprintf(b->last, "{\"uid\": \"%u\", \"full_name\": \"%s\"}", uid, full_name); This crash in ngx_string.c (line 257) case 's': p = va_arg(args, u_char *); if (slen == (size_t) -1) { while (*p && buf < last) { *buf++ = *p++; // <-- CRASH MSVC 2010 Anyone, can help with this? Thanks a lot. Ranier Livre de v?rus. www.avast.com. -------------- next part -------------- An HTML attachment was scrubbed... URL: From otto at seravo.fi Tue Jun 7 21:56:53 2016 From: otto at seravo.fi (=?UTF-8?B?T3R0byBLZWvDpGzDpGluZW4=?=) Date: Wed, 8 Jun 2016 00:56:53 +0300 Subject: [PATCH] Fix spelling in one file Message-ID: Hello! Please apply this very trivial spelling patch: https://github.com/ottok/nginx/commit/d0c325162a127afdf32d4e35aa6a58fe2caa8ec1.patch Thanks! From ru at nginx.com Wed Jun 8 05:28:23 2016 From: ru at nginx.com (Ruslan Ermilov) Date: Wed, 08 Jun 2016 05:28:23 +0000 Subject: [nginx] Fixed spelling. Message-ID: details: http://hg.nginx.org/nginx/rev/e511e3d581bb branches: changeset: 6585:e511e3d581bb user: Otto Kek?l?inen date: Wed Jun 08 08:27:41 2016 +0300 description: Fixed spelling. diffstat: src/os/unix/ngx_thread_mutex.c | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diffs (12 lines): diff -r 690b15cc8915 -r e511e3d581bb src/os/unix/ngx_thread_mutex.c --- a/src/os/unix/ngx_thread_mutex.c Tue Jun 07 17:44:20 2016 +0300 +++ b/src/os/unix/ngx_thread_mutex.c Wed Jun 08 08:27:41 2016 +0300 @@ -49,7 +49,7 @@ * for each mutex from 10 to 100 based on spin count taken * previously. * FreeBSD: Deadlock detection. The default spin count is 2000. - * It can be overriden using LIBPTHREAD_SPINLOOPS environment + * It can be overridden using LIBPTHREAD_SPINLOOPS environment * variable or by pthread_mutex_setspinloops_np(). If a lock * is still busy, sched_yield() can be called on both UP and * SMP systems. The default yield loop count is zero, but From ru at nginx.com Wed Jun 8 05:29:36 2016 From: ru at nginx.com (Ruslan Ermilov) Date: Wed, 8 Jun 2016 08:29:36 +0300 Subject: [PATCH] Fix spelling in one file In-Reply-To: References: Message-ID: <20160608052936.GA73582@lo0.su> On Wed, Jun 08, 2016 at 12:56:53AM +0300, Otto Kek?l?inen wrote: > Hello! > > Please apply this very trivial spelling patch: > https://github.com/ottok/nginx/commit/d0c325162a127afdf32d4e35aa6a58fe2caa8ec1.patch http://hg.nginx.org/nginx/rev/e511e3d581bb From mdounin at mdounin.ru Wed Jun 8 15:32:41 2016 From: mdounin at mdounin.ru (Maxim Dounin) Date: Wed, 8 Jun 2016 18:32:41 +0300 Subject: Nginx bug? In-Reply-To: References: Message-ID: <20160608153240.GG36620@mdounin.ru> Hello! On Tue, Jun 07, 2016 at 08:15:09PM +0000, Ranier VF wrote: > Hi, > nginx-1.10, windows build. > msvc 2010 > > where full_name is u_char [64] > b->last = ngx_sprintf(b->last, "{\"uid\": \"%u\", \"full_name\": \"%s\"}", uid, full_name); > > This crash in ngx_string.c (line 257) > case 's': > p = va_arg(args, u_char *); > > if (slen == (size_t) -1) { > while (*p && buf < last) { > *buf++ = *p++; // <-- CRASH MSVC 2010 > > Anyone, can help with this? The "%u" format specification is invalid. -- Maxim Dounin http://nginx.org/ From ranier_gyn at hotmail.com Wed Jun 8 16:48:30 2016 From: ranier_gyn at hotmail.com (Ranier VF) Date: Wed, 8 Jun 2016 16:48:30 +0000 Subject: Nginx bug? In-Reply-To: <20160608153240.GG36620@mdounin.ru> References: , <20160608153240.GG36620@mdounin.ru> Message-ID: Hello Maxim,Thank you. > The "%u" format specification is invalid.Nginx ignore %u. b->last = ngx_sprintf(b->last, "{\"uid\": \"%u\", \"full_name\": \"%u\"}", 0,0);results:{"uid": "", "full_name": ""} Best regards, Ranier > Date: Wed, 8 Jun 2016 18:32:41 +0300 > From: mdounin at mdounin.ru > To: nginx-devel at nginx.org > Subject: Re: Nginx bug? > > Hello! > > On Tue, Jun 07, 2016 at 08:15:09PM +0000, Ranier VF wrote: > > > Hi, > > nginx-1.10, windows build. > > msvc 2010 > > > > where full_name is u_char [64] > > b->last = ngx_sprintf(b->last, "{\"uid\": \"%u\", \"full_name\": \"%s\"}", uid, full_name); > > > > This crash in ngx_string.c (line 257) > > case 's': > > p = va_arg(args, u_char *); > > > > if (slen == (size_t) -1) { > > while (*p && buf < last) { > > *buf++ = *p++; // <-- CRASH MSVC 2010 > > > > Anyone, can help with this? > > The "%u" format specification is invalid. > > -- > Maxim Dounin > http://nginx.org/ > > _______________________________________________ > nginx-devel mailing list > nginx-devel at nginx.org > http://mailman.nginx.org/mailman/listinfo/nginx-devel Livre de v?rus. www.avast.com. -------------- next part -------------- An HTML attachment was scrubbed... URL: From justin at justinkennedy.ca Wed Jun 8 17:32:07 2016 From: justin at justinkennedy.ca (Justin Kennedy) Date: Wed, 8 Jun 2016 14:32:07 -0300 Subject: enable module for specific site Message-ID: Hello, I am developing an nginx module and one of the requirements is to enable the module only for specific sites or virtual hosts (using a directive I would suppose). Is this possible with nginx? Thank you, -Justin -------------- next part -------------- An HTML attachment was scrubbed... URL: From ranier_gyn at hotmail.com Wed Jun 8 18:35:37 2016 From: ranier_gyn at hotmail.com (Ranier VF) Date: Wed, 8 Jun 2016 18:35:37 +0000 Subject: Nginx 1.10, UNADDRESSABLE ACCESS Message-ID: Hi, Dr. Memory version 1.10.0 build 2 built on Mar 7 2016 23:05:56Dr. Memory results for pid 1860: "nginx.exe"Application cmdline: "nginx.exe"Recorded 117 suppression(s) from default c:\DrMemory\bin\suppress-default.txt Error #1: UNADDRESSABLE ACCESS: reading 0x00000030-0x00000034 4 byte(s)# 0 ngx_conf_set_num_slot [c:\msys\1.0\nginx-1.10\src\core\ngx_conf_file.c:1136]# 1 ngx_conf_handler [c:\msys\1.0\nginx-1.10\src\core\ngx_conf_file.c:427]# 2 ngx_conf_parse [c:\msys\1.0\nginx-1.10\src\core\ngx_conf_file.c:283]# 3 ngx_http_core_location [c:\msys\1.0\nginx-1.10\src\http\ngx_http_core_module.c:3256]# 4 ngx_conf_handler [c:\msys\1.0\nginx-1.10\src\core\ngx_conf_file.c:427]# 5 ngx_conf_parse [c:\msys\1.0\nginx-1.10\src\core\ngx_conf_file.c:283]# 6 ngx_http_core_server [c:\msys\1.0\nginx-1.10\src\http\ngx_http_core_module.c:3028]# 7 ngx_conf_handler [c:\msys\1.0\nginx-1.10\src\core\ngx_conf_file.c:427]# 8 ngx_conf_parse [c:\msys\1.0\nginx-1.10\src\core\ngx_conf_file.c:283]# 9 ngx_http_block [c:\msys\1.0\nginx-1.10\src\http\ngx_http.c:237]#10 ngx_conf_handler [c:\msys\1.0\nginx-1.10\src\core\ngx_conf_file.c:427]#11 ngx_conf_parse [c:\msys\1.0\nginx-1.10\src\core\ngx_conf_file.c:283]#12 ngx_init_cycle [c:\msys\1.0\nginx-1.10\src\core\ngx_cycle.c:274]#13 main [c:\msys\1.0\nginx-1.10\src\core\nginx.c:276]Note: @0:00:03.234 in thread 3136Note: instruction: cmp (%eax) $0xffffffff Best regards, Ranier Livre de v?rus. www.avast.com. -------------- next part -------------- An HTML attachment was scrubbed... URL: From mdounin at mdounin.ru Wed Jun 8 19:09:33 2016 From: mdounin at mdounin.ru (Maxim Dounin) Date: Wed, 8 Jun 2016 22:09:33 +0300 Subject: Nginx 1.10, UNADDRESSABLE ACCESS In-Reply-To: References: Message-ID: <20160608190933.GI36620@mdounin.ru> Hello! On Wed, Jun 08, 2016 at 06:35:37PM +0000, Ranier VF wrote: > Hi, > Dr. Memory version 1.10.0 build 2 built on Mar 7 2016 23:05:56Dr. Memory results for pid 1860: "nginx.exe"Application cmdline: "nginx.exe"Recorded 117 suppression(s) from default c:\DrMemory\bin\suppress-default.txt > Error #1: UNADDRESSABLE ACCESS: reading 0x00000030-0x00000034 4 byte(s)# 0 ngx_conf_set_num_slot [c:\msys\1.0\nginx-1.10\src\core\ngx_conf_file.c:1136]# 1 ngx_conf_handler [c:\msys\1.0\nginx-1.10\src\core\ngx_conf_file.c:427]# 2 ngx_conf_parse [c:\msys\1.0\nginx-1.10\src\core\ngx_conf_file.c:283]# 3 ngx_http_core_location [c:\msys\1.0\nginx-1.10\src\http\ngx_http_core_module.c:3256]# 4 ngx_conf_handler [c:\msys\1.0\nginx-1.10\src\core\ngx_conf_file.c:427]# 5 ngx_conf_parse [c:\msys\1.0\nginx-1.10\src\core\ngx_conf_file.c:283]# 6 ngx_http_core_server [c:\msys\1.0\nginx-1.10\src\http\ngx_http_core_module.c:3028]# 7 ngx_conf_handler [c:\msys\1.0\nginx-1.10\src\core\ngx_conf_file.c:427]# 8 ngx_conf_parse [c:\msys\1.0\nginx-1.10\src\core\ngx_conf_file.c:283]# 9 ngx_http_block [c:\msys\1.0\nginx-1.10\src\http\ngx_http.c:237]#10 ngx_conf_handler [c:\msys\1.0\nginx-1.10\src\core\ngx_conf_file.c:427]#11 ngx_conf_parse [c:\msys\1.0\nginx-1.10\src\core\ngx_conf_file.c:283]#12 ngx_init_cycle [c:\msys\1.0\nginx-1.10\src\core\ngx_cycle.c:274]#13 main [c:\msys\1.0\nginx-1.10\src\core\nginx.c:276]Note: @0:00:03.234 in thread 3136Note: instruction: cmp (%eax) $0xffffffff > Best regards, > Ranier What "nginx -V" shows? (Additionally, please avoid posting HTML to the mailing list. Thank you.) -- Maxim Dounin http://nginx.org/ From ranier_gyn at hotmail.com Wed Jun 8 19:16:39 2016 From: ranier_gyn at hotmail.com (Ranier VF) Date: Wed, 8 Jun 2016 19:16:39 +0000 Subject: Nginx 1.10, UNADDRESSABLE ACCESS In-Reply-To: <20160608190933.GI36620@mdounin.ru> References: , <20160608190933.GI36620@mdounin.ru> Message-ID: HI Maxim, > What "nginx -V" shows?C:\nginx>nginx -Vnginx version: nginx/1.10.1built by cl 16.00.30319.01 for 80x86configure arguments: --with-cc=cl --builddir=objs --prefix= --conf-path=conf/nginx.conf --pid-path=logs/nginx.pid --http-log-path=logs/access.log --error-log-path=logs/error.log --sbin-path=nginx.exe --http-client-body-temp-path=temp/client_body_temp --http-proxy-temp-path=temp/proxy_temp --http-fastcgi-temp-path=temp/fastcgi_temp --with-cc-opt=-DFD_SETSIZE=1024 --with-pcre=objs/lib/pcre-8.38 --with-zlib=objs/lib/zlib-1.2.8 --with-md5-asm --with-sha1-asm --with-select_module--add-module=ngx_rcpdv > (Additionally, please avoid posting HTML to the mailing list. Sorry, but I only use outlook.com web. Ranier > Date: Wed, 8 Jun 2016 22:09:33 +0300 > From: mdounin at mdounin.ru > To: nginx-devel at nginx.org > Subject: Re: Nginx 1.10, UNADDRESSABLE ACCESS > > Hello! > > On Wed, Jun 08, 2016 at 06:35:37PM +0000, Ranier VF wrote: > > > Hi, > > Dr. Memory version 1.10.0 build 2 built on Mar 7 2016 23:05:56Dr. Memory results for pid 1860: "nginx.exe"Application cmdline: "nginx.exe"Recorded 117 suppression(s) from default c:\DrMemory\bin\suppress-default.txt > > Error #1: UNADDRESSABLE ACCESS: reading 0x00000030-0x00000034 4 byte(s)# 0 ngx_conf_set_num_slot [c:\msys\1.0\nginx-1.10\src\core\ngx_conf_file.c:1136]# 1 ngx_conf_handler [c:\msys\1.0\nginx-1.10\src\core\ngx_conf_file.c:427]# 2 ngx_conf_parse [c:\msys\1.0\nginx-1.10\src\core\ngx_conf_file.c:283]# 3 ngx_http_core_location [c:\msys\1.0\nginx-1.10\src\http\ngx_http_core_module.c:3256]# 4 ngx_conf_handler [c:\msys\1.0\nginx-1.10\src\core\ngx_conf_file.c:427]# 5 ngx_conf_parse [c:\msys\1.0\nginx-1.10\src\core\ngx_conf_file.c:283]# 6 ngx_http_core_server [c:\msys\1.0\nginx-1.10\src\http\ngx_http_core_module.c:3028]# 7 ngx_conf_handler [c:\msys\1.0\nginx-1.10\src\core\ngx_conf_file.c:427]# 8 ngx_conf_parse [c:\msys\1.0\nginx-1.10\src\core\ngx_conf_file.c:283]# 9 ngx_http_block [c:\msys\1.0\nginx-1. > 10\src\http\ngx_http.c:237]#10 ngx_conf_handler [c:\msys\1.0\nginx-1.10\src\core\ngx_conf_file.c:427]#11 ngx_conf_parse [c:\msys\1.0\nginx-1.10\src\core\ngx_conf_file.c:283]#12 ngx_init_cycle [c:\msys\1.0\nginx-1.10\src\core\ngx_cycle.c:274]#13 main [c:\msys\1.0\nginx-1.10\src\core\nginx.c:276]Note: @0:00:03.234 in thread 3136Note: instruction: cmp (%eax) $0xffffffff > > Best regards, > > Ranier > > What "nginx -V" shows? > > (Additionally, please avoid posting HTML to the mailing list. > Thank you.) > > -- > Maxim Dounin > http://nginx.org/ > > _______________________________________________ > nginx-devel mailing list > nginx-devel at nginx.org > http://mailman.nginx.org/mailman/listinfo/nginx-devel Livre de v?rus. www.avast.com. -------------- next part -------------- An HTML attachment was scrubbed... URL: From kuroishi at iij.ad.jp Thu Jun 9 03:19:15 2016 From: kuroishi at iij.ad.jp (Kuroishi Mitsuo) Date: Thu, 09 Jun 2016 12:19:15 +0900 (JST) Subject: log to desired path Message-ID: <20160609.121915.1563144270906385466.kuroishi@iij.ad.jp> Hi, I'm developing a module that needs to log its status and result to a file at an appropriate path. And it's preferred that the log file contains only its own data. This is a demand of our customer. I come up with using fopen(3), fwrite(3) or something like that in the module first. Is this bad idea in terms of the NGINX module manner? Is there any way using the access_log or error_log directive to achieve the need. Or please let me know if you know modules that can be used for that. Thanks in advance. -- Kuroishi Mitsuo From ranier_gyn at hotmail.com Thu Jun 9 10:39:02 2016 From: ranier_gyn at hotmail.com (Ranier VF) Date: Thu, 9 Jun 2016 10:39:02 +0000 Subject: log to desired path In-Reply-To: <20160609.121915.1563144270906385466.kuroishi@iij.ad.jp> References: <20160609.121915.1563144270906385466.kuroishi@iij.ad.jp> Message-ID: Hi,Perhaps using:http://nginx.org/en/docs/http/ngx_http_log_module.html Best, Ranier > Date: Thu, 9 Jun 2016 12:19:15 +0900 > To: nginx-devel at nginx.org > Subject: log to desired path > From: kuroishi at iij.ad.jp > > > Hi, > > I'm developing a module that needs to log its status and result > to a file at an appropriate path. And it's preferred that the > log file contains only its own data. > > This is a demand of our customer. > > I come up with using fopen(3), fwrite(3) or something like that > in the module first. > > Is this bad idea in terms of the NGINX module manner? > > Is there any way using the access_log or error_log > directive to achieve the need. > > Or please let me know if you know modules that can be used for > that. > > Thanks in advance. > > -- > Kuroishi Mitsuo > > _______________________________________________ > nginx-devel mailing list > nginx-devel at nginx.org > http://mailman.nginx.org/mailman/listinfo/nginx-devel Livre de v?rus. www.avast.com. -------------- next part -------------- An HTML attachment was scrubbed... URL: From mdounin at mdounin.ru Thu Jun 9 10:50:55 2016 From: mdounin at mdounin.ru (Maxim Dounin) Date: Thu, 9 Jun 2016 13:50:55 +0300 Subject: Nginx 1.10, UNADDRESSABLE ACCESS In-Reply-To: References: <20160608190933.GI36620@mdounin.ru> Message-ID: <20160609105055.GJ36620@mdounin.ru> Hello! On Wed, Jun 08, 2016 at 07:16:39PM +0000, Ranier VF wrote: > HI Maxim, > > What "nginx -V" shows?C:\nginx>nginx -Vnginx version: > > nginx/1.10.1built by cl 16.00.30319.01 for 80x86configure > > arguments: --with-cc=cl --builddir=objs --prefix= > > --conf-path=conf/nginx.conf --pid-path=logs/nginx.pid > > --http-log-path=logs/access.log > > --error-log-path=logs/error.log --sbin-path=nginx.exe > > --http-client-body-temp-path=temp/client_body_temp > > --http-proxy-temp-path=temp/proxy_temp > > --http-fastcgi-temp-path=temp/fastcgi_temp > > --with-cc-opt=-DFD_SETSIZE=1024 --with-pcre=objs/lib/pcre-8.38 > > --with-zlib=objs/lib/zlib-1.2.8 --with-md5-asm --with-sha1-asm > > --with-select_module--add-module=ngx_rcpdv You are using an external module "ngx_rcpdv", and likely it's the problem in the module (incorrect configuration directive definition). Try without the module to see if it helps. > > (Additionally, please avoid posting HTML to the mailing list. > Sorry, but I only use outlook.com web. Try something like this: http://answers.microsoft.com/en-us/outlook_com/forum/oemail-osend/how-do-i-send-a-plain-text-message-using/32f33589-98f9-4e1a-b92f-053b7782cf23 -- Maxim Dounin http://nginx.org/ From ranier_gyn at hotmail.com Thu Jun 9 12:08:50 2016 From: ranier_gyn at hotmail.com (Ranier VF) Date: Thu, 9 Jun 2016 12:08:50 +0000 Subject: Nginx 1.10, UNADDRESSABLE ACCESS In-Reply-To: <20160609105055.GJ36620@mdounin.ru> References: , <20160608190933.GI36620@mdounin.ru>, , <20160609105055.GJ36620@mdounin.ru> Message-ID: Hi Maxim. > You are using an external module "ngx_rcpdv", and likely it's the > problem in the module (incorrect configuration directive > definition). Try without the module to see if it helps. Correct, the error gones. But, I still have reports. I submit with new thread. Best regards, Ranier > Date: Thu, 9 Jun 2016 13:50:55 +0300 > From: mdounin at mdounin.ru > To: nginx-devel at nginx.org > Subject: Re: Nginx 1.10, UNADDRESSABLE ACCESS > > Hello! > > On Wed, Jun 08, 2016 at 07:16:39PM +0000, Ranier VF wrote: > > > HI Maxim, > > > What "nginx -V" shows?C:\nginx>nginx -Vnginx version: > > > nginx/1.10.1built by cl 16.00.30319.01 for 80x86configure > > > arguments: --with-cc=cl --builddir=objs --prefix= > > > --conf-path=conf/nginx.conf --pid-path=logs/nginx.pid > > > --http-log-path=logs/access.log > > > --error-log-path=logs/error.log --sbin-path=nginx.exe > > > --http-client-body-temp-path=temp/client_body_temp > > > --http-proxy-temp-path=temp/proxy_temp > > > --http-fastcgi-temp-path=temp/fastcgi_temp > > > --with-cc-opt=-DFD_SETSIZE=1024 --with-pcre=objs/lib/pcre-8.38 > > > --with-zlib=objs/lib/zlib-1.2.8 --with-md5-asm --with-sha1-asm > > > --with-select_module--add-module=ngx_rcpdv > > You are using an external module "ngx_rcpdv", and likely it's the > problem in the module (incorrect configuration directive > definition). Try without the module to see if it helps. > > > > (Additionally, please avoid posting HTML to the mailing list. > > Sorry, but I only use outlook.com web. > > Try something like this: > http://answers.microsoft.com/en-us/outlook_com/forum/oemail-osend/how-do-i-send-a-plain-text-message-using/32f33589-98f9-4e1a-b92f-053b7782cf23 > > -- > Maxim Dounin > http://nginx.org/ > > _______________________________________________ > nginx-devel mailing list > nginx-devel at nginx.org > http://mailman.nginx.org/mailman/listinfo/nginx-devel Livre de v?rus. www.avast.com. -------------- next part -------------- An HTML attachment was scrubbed... URL: From ranier_gyn at hotmail.com Thu Jun 9 12:11:40 2016 From: ranier_gyn at hotmail.com (Ranier VF) Date: Thu, 9 Jun 2016 12:11:40 +0000 Subject: Nginx 1.10, DrMemory report Message-ID: C:\nginx>nginx -Vnginx version: nginx/1.10.1built by cl 16.00.30319.01 for 80x86configure arguments: --with-cc=cl --builddir=objs --prefix= --conf-path=conf/nginx.conf --pid-path=logs/nginx.pid --http-log-path=logs/access.log --error-log-path=logs/error.log --sbin-path=nginx.exe --http-client-body-temp-path=temp/client_body_temp --http-proxy-temp-path=temp/proxy_temp --http-fastcgi-temp-path=temp/fastcgi_temp --with-cc-opt=-DFD_SETSIZE=1024 --with-pcre=objs/lib/pcre-8.38 --with-zlib=objs/lib/zlib-1.2.8 --with-select_module Dr. Memory version 1.10.0 build 2 built on Mar 7 2016 23:05:56Dr. Memory results for pid 2052: "nginx.exe"Application cmdline: "nginx.exe"Recorded 117 suppression(s) from default c:\DrMemory\bin\suppress-default.txt Error #1: UNINITIALIZED READ: reading 0x0012fbb4-0x0012fbbb 7 byte(s) within 0x0012fb78-0x0012fbbb# 0 system call NtCreateFile parameter #9# 1 ntdll.dll!ZwCreateFile +0xb (0x7c90d09c )# 2 MSWSOCK.dll!? +0x0 (0x71a149c0 )# 3 WS2_32.dll!WSASocketW +0x9c (0x71a740eb )# 4 ngx_open_listening_sockets [c:\msys\1.0\nginx-1.10\src\core\ngx_connection.c:448]# 5 ngx_init_cycle [c:\msys\1.0\nginx-1.10\src\core\ngx_cycle.c:609]# 6 main [c:\msys\1.0\nginx-1.10\src\core\nginx.c:276]Note: @0:00:02.985 in thread 2160 Error #2: POSSIBLE LEAK 768 direct bytes 0x021d2898-0x021d2b98 + 0 indirect bytes# 0 replace_calloc [d:\drmemory_package\common\alloc_replace.c:2616]# 1 _calloc_crt [f:\dd\vctools\crt_bld\self_x86\crt\src\crtheap.c:61]# 2 __init_ctype [f:\dd\vctools\crt_bld\self_x86\crt\src\initctyp.c:98]# 3 _setlocale_set_cat [f:\dd\vctools\crt_bld\self_x86\crt\src\setlocal.c:842]# 4 _setlocale_nolock [f:\dd\vctools\crt_bld\self_x86\crt\src\setlocal.c:694]# 5 setlocale [f:\dd\vctools\crt_bld\self_x86\crt\src\setlocal.c:579]# 6 ngx_os_init [c:\msys\1.0\nginx-1.10\src\os\win32\ngx_win32_init.c:128]# 7 main [c:\msys\1.0\nginx-1.10\src\core\nginx.c:256] Error #3: POSSIBLE LEAK 384 direct bytes 0x021d2bb8-0x021d2d38 + 0 indirect bytes# 0 replace_calloc [d:\drmemory_package\common\alloc_replace.c:2616]# 1 _calloc_crt [f:\dd\vctools\crt_bld\self_x86\crt\src\crtheap.c:61]# 2 __init_ctype [f:\dd\vctools\crt_bld\self_x86\crt\src\initctyp.c:100]# 3 _setlocale_set_cat [f:\dd\vctools\crt_bld\self_x86\crt\src\setlocal.c:842]# 4 _setlocale_nolock [f:\dd\vctools\crt_bld\self_x86\crt\src\setlocal.c:694]# 5 setlocale [f:\dd\vctools\crt_bld\self_x86\crt\src\setlocal.c:579]# 6 ngx_os_init [c:\msys\1.0\nginx-1.10\src\os\win32\ngx_win32_init.c:128]# 7 main [c:\msys\1.0\nginx-1.10\src\core\nginx.c:256] Error #4: POSSIBLE LEAK 384 direct bytes 0x021d2d58-0x021d2ed8 + 0 indirect bytes# 0 replace_calloc [d:\drmemory_package\common\alloc_replace.c:2616]# 1 _calloc_crt [f:\dd\vctools\crt_bld\self_x86\crt\src\crtheap.c:61]# 2 __init_ctype [f:\dd\vctools\crt_bld\self_x86\crt\src\initctyp.c:102]# 3 _setlocale_set_cat [f:\dd\vctools\crt_bld\self_x86\crt\src\setlocal.c:842]# 4 _setlocale_nolock [f:\dd\vctools\crt_bld\self_x86\crt\src\setlocal.c:694]# 5 setlocale [f:\dd\vctools\crt_bld\self_x86\crt\src\setlocal.c:579]# 6 ngx_os_init [c:\msys\1.0\nginx-1.10\src\os\win32\ngx_win32_init.c:128]# 7 main [c:\msys\1.0\nginx-1.10\src\core\nginx.c:256] Error #5: POSSIBLE LEAK 96 direct bytes 0x021d4958-0x021d49b8 + 0 indirect bytes# 0 replace_malloc [d:\drmemory_package\common\alloc_replace.c:2576]# 1 ngx_alloc [c:\msys\1.0\nginx-1.10\src\os\win32\ngx_alloc.c:21]# 2 ngx_crc32_table_init [c:\msys\1.0\nginx-1.10\src\core\ngx_crc32.c:117]# 3 main [c:\msys\1.0\nginx-1.10\src\core\nginx.c:264] ===========================================================================FINAL SUMMARY: DUPLICATE ERROR COUNTS: SUPPRESSIONS USED: ERRORS FOUND: 0 unique, 0 total unaddressable access(es) 1 unique, 1 total uninitialized access(es) 0 unique, 0 total invalid heap argument(s) 0 unique, 0 total GDI usage error(s) 0 unique, 0 total handle leak(s) 0 unique, 0 total warning(s) 0 unique, 0 total, 0 byte(s) of leak(s) 4 unique, 4 total, 1632 byte(s) of possible leak(s)ERRORS IGNORED: 120 potential error(s) (suspected false positives) (details: c:\tmp\DrMemory-nginx.exe.2052.000\potential_errors.txt) 1 potential leak(s) (suspected false positives) (details: c:\tmp\DrMemory-nginx.exe.2052.000\potential_errors.txt) 234 unique, 340 total, 38511 byte(s) of still-reachable allocation(s) (re-run with "-show_reachable" for details)Details: c:\tmp\DrMemory-nginx.exe.2052.000\results.txt Best regards, Ranier Livre de v?rus. www.avast.com. -------------- next part -------------- An HTML attachment was scrubbed... URL: From ranier_gyn at hotmail.com Thu Jun 9 12:26:33 2016 From: ranier_gyn at hotmail.com (Ranier VF) Date: Thu, 9 Jun 2016 12:26:33 +0000 Subject: Nginx do not call WSACleanup? Message-ID: Hi Maxim,I have another report by Dr.Memory, withs lots ofPotential Error HANDLE LEAK: KERNEL handle I do grep:grep WSACleanup in win32 directory. Why nginx, do not call WSACleanup when finish with -s stop? Best regards, Ranier Livre de v?rus. www.avast.com. -------------- next part -------------- An HTML attachment was scrubbed... URL: From mdounin at mdounin.ru Thu Jun 9 12:42:00 2016 From: mdounin at mdounin.ru (Maxim Dounin) Date: Thu, 9 Jun 2016 15:42:00 +0300 Subject: Nginx 1.10, DrMemory report In-Reply-To: References: Message-ID: <20160609124200.GP36620@mdounin.ru> Hello! On Thu, Jun 09, 2016 at 12:11:40PM +0000, Ranier VF wrote: > C:\nginx>nginx -Vnginx version: nginx/1.10.1built by cl 16.00.30319.01 for 80x86configure arguments: --with-cc=cl --builddir=objs --prefix= --conf-path=conf/nginx.conf --pid-path=logs/nginx.pid --http-log-path=logs/access.log --error-log-path=logs/error.log --sbin-path=nginx.exe --http-client-body-temp-path=temp/client_body_temp --http-proxy-temp-path=temp/proxy_temp --http-fastcgi-temp-path=temp/fastcgi_temp --with-cc-opt=-DFD_SETSIZE=1024 --with-pcre=objs/lib/pcre-8.38 --with-zlib=objs/lib/zlib-1.2.8 --with-select_module > > Dr. Memory version 1.10.0 build 2 built on Mar 7 2016 23:05:56Dr. Memory results for pid 2052: "nginx.exe"Application cmdline: "nginx.exe"Recorded 117 suppression(s) from default c:\DrMemory\bin\suppress-default.txt > Error #1: UNINITIALIZED READ: reading 0x0012fbb4-0x0012fbbb 7 byte(s) within 0x0012fb78-0x0012fbbb# 0 system call NtCreateFile parameter #9# 1 ntdll.dll!ZwCreateFile +0xb (0x7c90d09c )# 2 MSWSOCK.dll!? +0x0 (0x71a149c0 )# 3 WS2_32.dll!WSASocketW +0x9c (0x71a740eb )# 4 ngx_open_listening_sockets [c:\msys\1.0\nginx-1.10\src\core\ngx_connection.c:448]# 5 ngx_init_cycle [c:\msys\1.0\nginx-1.10\src\core\ngx_cycle.c:609]# 6 main [c:\msys\1.0\nginx-1.10\src\core\nginx.c:276]Note: @0:00:02.985 in thread 2160 This doesn't looks like an nginx problem. Rather, a problem in Windows or in the tool you are using. > Error #2: POSSIBLE LEAK 768 direct bytes 0x021d2898-0x021d2b98 + 0 indirect bytes# 0 replace_calloc [d:\drmemory_package\common\alloc_replace.c:2616]# 1 _calloc_crt [f:\dd\vctools\crt_bld\self_x86\crt\src\crtheap.c:61]# 2 __init_ctype [f:\dd\vctools\crt_bld\self_x86\crt\src\initctyp.c:98]# 3 _setlocale_set_cat [f:\dd\vctools\crt_bld\self_x86\crt\src\setlocal.c:842]# 4 _setlocale_nolock [f:\dd\vctools\crt_bld\self_x86\crt\src\setlocal.c:694]# 5 setlocale [f:\dd\vctools\crt_bld\self_x86\crt\src\setlocal.c:579]# 6 ngx_os_init [c:\msys\1.0\nginx-1.10\src\os\win32\ngx_win32_init.c:128]# 7 main [c:\msys\1.0\nginx-1.10\src\core\nginx.c:256] Same here. > Error #3: POSSIBLE LEAK 384 direct bytes 0x021d2bb8-0x021d2d38 + 0 indirect bytes# 0 replace_calloc [d:\drmemory_package\common\alloc_replace.c:2616]# 1 _calloc_crt [f:\dd\vctools\crt_bld\self_x86\crt\src\crtheap.c:61]# 2 __init_ctype [f:\dd\vctools\crt_bld\self_x86\crt\src\initctyp.c:100]# 3 _setlocale_set_cat [f:\dd\vctools\crt_bld\self_x86\crt\src\setlocal.c:842]# 4 _setlocale_nolock [f:\dd\vctools\crt_bld\self_x86\crt\src\setlocal.c:694]# 5 setlocale [f:\dd\vctools\crt_bld\self_x86\crt\src\setlocal.c:579]# 6 ngx_os_init [c:\msys\1.0\nginx-1.10\src\os\win32\ngx_win32_init.c:128]# 7 main [c:\msys\1.0\nginx-1.10\src\core\nginx.c:256] Same here. > Error #4: POSSIBLE LEAK 384 direct bytes 0x021d2d58-0x021d2ed8 + 0 indirect bytes# 0 replace_calloc [d:\drmemory_package\common\alloc_replace.c:2616]# 1 _calloc_crt [f:\dd\vctools\crt_bld\self_x86\crt\src\crtheap.c:61]# 2 __init_ctype [f:\dd\vctools\crt_bld\self_x86\crt\src\initctyp.c:102]# 3 _setlocale_set_cat [f:\dd\vctools\crt_bld\self_x86\crt\src\setlocal.c:842]# 4 _setlocale_nolock [f:\dd\vctools\crt_bld\self_x86\crt\src\setlocal.c:694]# 5 setlocale [f:\dd\vctools\crt_bld\self_x86\crt\src\setlocal.c:579]# 6 ngx_os_init [c:\msys\1.0\nginx-1.10\src\os\win32\ngx_win32_init.c:128]# 7 main [c:\msys\1.0\nginx-1.10\src\core\nginx.c:256] Same here. > Error #5: POSSIBLE LEAK 96 direct bytes 0x021d4958-0x021d49b8 + 0 indirect bytes# 0 replace_malloc [d:\drmemory_package\common\alloc_replace.c:2576]# 1 ngx_alloc [c:\msys\1.0\nginx-1.10\src\os\win32\ngx_alloc.c:21]# 2 ngx_crc32_table_init [c:\msys\1.0\nginx-1.10\src\core\ngx_crc32.c:117]# 3 main [c:\msys\1.0\nginx-1.10\src\core\nginx.c:264] This behaviour is intentional. As previously suggested, please avoid posting HTML to the list. Thank you. -- Maxim Dounin http://nginx.org/ From mdounin at mdounin.ru Thu Jun 9 13:13:30 2016 From: mdounin at mdounin.ru (Maxim Dounin) Date: Thu, 9 Jun 2016 16:13:30 +0300 Subject: Nginx do not call WSACleanup? In-Reply-To: References: Message-ID: <20160609131330.GQ36620@mdounin.ru> Hello! On Thu, Jun 09, 2016 at 12:26:33PM +0000, Ranier VF wrote: > Hi Maxim,I have another report by Dr.Memory, withs lots ofPotential Error HANDLE LEAK: KERNEL handle > I do grep:grep WSACleanup in win32 directory. > Why nginx, do not call WSACleanup when finish with -s stop? The main reason is: because nginx is a program designed for UNIX, and Windows-specific quirks are only added when they are needed. On the other hand, for process-scope use of sockets WSACleanup() was only really needed for Windows 3.x or earlier, and nginx never supported these Windows versions. -- Maxim Dounin http://nginx.org/ From mdounin at mdounin.ru Thu Jun 9 14:20:44 2016 From: mdounin at mdounin.ru (Maxim Dounin) Date: Thu, 09 Jun 2016 14:20:44 +0000 Subject: [nginx] An internal SHA1 implementation. Message-ID: details: http://hg.nginx.org/nginx/rev/1064ea81ed3a branches: changeset: 6586:1064ea81ed3a user: Maxim Dounin date: Thu Jun 09 16:55:38 2016 +0300 description: An internal SHA1 implementation. diffstat: auto/sources | 1 + src/core/ngx_crypt.c | 13 -- src/core/ngx_sha1.c | 300 +++++++++++++++++++++++++++++++++++++++++++++++++++ src/core/ngx_sha1.h | 19 +++ 4 files changed, 320 insertions(+), 13 deletions(-) diffs (410 lines): diff --git a/auto/sources b/auto/sources --- a/auto/sources +++ b/auto/sources @@ -61,6 +61,7 @@ CORE_SRCS="src/core/nginx.c \ src/core/ngx_crc32.c \ src/core/ngx_murmurhash.c \ src/core/ngx_md5.c \ + src/core/ngx_sha1.c \ src/core/ngx_rbtree.c \ src/core/ngx_radix_tree.c \ src/core/ngx_slab.c \ diff --git a/src/core/ngx_crypt.c b/src/core/ngx_crypt.c --- a/src/core/ngx_crypt.c +++ b/src/core/ngx_crypt.c @@ -8,9 +8,7 @@ #include #include #include -#if (NGX_HAVE_SHA1) #include -#endif #if (NGX_CRYPT) @@ -19,16 +17,11 @@ static ngx_int_t ngx_crypt_apr1(ngx_pool u_char **encrypted); static ngx_int_t ngx_crypt_plain(ngx_pool_t *pool, u_char *key, u_char *salt, u_char **encrypted); - -#if (NGX_HAVE_SHA1) - static ngx_int_t ngx_crypt_ssha(ngx_pool_t *pool, u_char *key, u_char *salt, u_char **encrypted); static ngx_int_t ngx_crypt_sha(ngx_pool_t *pool, u_char *key, u_char *salt, u_char **encrypted); -#endif - static u_char *ngx_crypt_to64(u_char *p, uint32_t v, size_t n); @@ -42,13 +35,11 @@ ngx_crypt(ngx_pool_t *pool, u_char *key, } else if (ngx_strncmp(salt, "{PLAIN}", sizeof("{PLAIN}") - 1) == 0) { return ngx_crypt_plain(pool, key, salt, encrypted); -#if (NGX_HAVE_SHA1) } else if (ngx_strncmp(salt, "{SSHA}", sizeof("{SSHA}") - 1) == 0) { return ngx_crypt_ssha(pool, key, salt, encrypted); } else if (ngx_strncmp(salt, "{SHA}", sizeof("{SHA}") - 1) == 0) { return ngx_crypt_sha(pool, key, salt, encrypted); -#endif } /* fallback to libc crypt() */ @@ -193,8 +184,6 @@ ngx_crypt_plain(ngx_pool_t *pool, u_char } -#if (NGX_HAVE_SHA1) - static ngx_int_t ngx_crypt_ssha(ngx_pool_t *pool, u_char *key, u_char *salt, u_char **encrypted) { @@ -278,6 +267,4 @@ ngx_crypt_sha(ngx_pool_t *pool, u_char * return NGX_OK; } -#endif /* NGX_HAVE_SHA1 */ - #endif /* NGX_CRYPT */ diff --git a/src/core/ngx_sha1.c b/src/core/ngx_sha1.c new file mode 100644 --- /dev/null +++ b/src/core/ngx_sha1.c @@ -0,0 +1,300 @@ + +/* + * Copyright (C) Maxim Dounin + * Copyright (C) Nginx, Inc. + * + * An internal SHA1 implementation. + * It is not expected to be optimal and is used only + * if no SHA1 implementation was found in system. + */ + + +#include +#include +#include + + +#if !(NGX_HAVE_SHA1) + +static const u_char *ngx_sha1_body(ngx_sha1_t *ctx, const u_char *data, + size_t size); + + +void +ngx_sha1_init(ngx_sha1_t *ctx) +{ + ctx->a = 0x67452301; + ctx->b = 0xefcdab89; + ctx->c = 0x98badcfe; + ctx->d = 0x10325476; + ctx->e = 0xc3d2e1f0; + + ctx->bytes = 0; +} + + +void +ngx_sha1_update(ngx_sha1_t *ctx, const void *data, size_t size) +{ + size_t used, free; + + used = (size_t) (ctx->bytes & 0x3f); + ctx->bytes += size; + + if (used) { + free = 64 - used; + + if (size < free) { + ngx_memcpy(&ctx->buffer[used], data, size); + return; + } + + ngx_memcpy(&ctx->buffer[used], data, free); + data = (u_char *) data + free; + size -= free; + (void) ngx_sha1_body(ctx, ctx->buffer, 64); + } + + if (size >= 64) { + data = ngx_sha1_body(ctx, data, size & ~(size_t) 0x3f); + size &= 0x3f; + } + + ngx_memcpy(ctx->buffer, data, size); +} + + +void +ngx_sha1_final(u_char result[20], ngx_sha1_t *ctx) +{ + size_t used, free; + + used = (size_t) (ctx->bytes & 0x3f); + + ctx->buffer[used++] = 0x80; + + free = 64 - used; + + if (free < 8) { + ngx_memzero(&ctx->buffer[used], free); + (void) ngx_sha1_body(ctx, ctx->buffer, 64); + used = 0; + free = 64; + } + + ngx_memzero(&ctx->buffer[used], free - 8); + + ctx->bytes <<= 3; + ctx->buffer[56] = (u_char) (ctx->bytes >> 56); + ctx->buffer[57] = (u_char) (ctx->bytes >> 48); + ctx->buffer[58] = (u_char) (ctx->bytes >> 40); + ctx->buffer[59] = (u_char) (ctx->bytes >> 32); + ctx->buffer[60] = (u_char) (ctx->bytes >> 24); + ctx->buffer[61] = (u_char) (ctx->bytes >> 16); + ctx->buffer[62] = (u_char) (ctx->bytes >> 8); + ctx->buffer[63] = (u_char) ctx->bytes; + + (void) ngx_sha1_body(ctx, ctx->buffer, 64); + + result[0] = (u_char) (ctx->a >> 24); + result[1] = (u_char) (ctx->a >> 16); + result[2] = (u_char) (ctx->a >> 8); + result[3] = (u_char) ctx->a; + result[4] = (u_char) (ctx->b >> 24); + result[5] = (u_char) (ctx->b >> 16); + result[6] = (u_char) (ctx->b >> 8); + result[7] = (u_char) ctx->b; + result[8] = (u_char) (ctx->c >> 24); + result[9] = (u_char) (ctx->c >> 16); + result[10] = (u_char) (ctx->c >> 8); + result[11] = (u_char) ctx->c; + result[12] = (u_char) (ctx->d >> 24); + result[13] = (u_char) (ctx->d >> 16); + result[14] = (u_char) (ctx->d >> 8); + result[15] = (u_char) ctx->d; + result[16] = (u_char) (ctx->e >> 24); + result[17] = (u_char) (ctx->e >> 16); + result[18] = (u_char) (ctx->e >> 8); + result[19] = (u_char) ctx->e; + + ngx_memzero(ctx, sizeof(*ctx)); +} + + +/* + * Helper functions. + */ + +#define ROTATE(bits, word) (((word) << (bits)) | ((word) >> (32 - (bits)))) + +#define F1(b, c, d) (((b) & (c)) | ((~(b)) & (d))) +#define F2(b, c, d) ((b) ^ (c) ^ (d)) +#define F3(b, c, d) (((b) & (c)) | ((b) & (d)) | ((c) & (d))) + +#define STEP(f, a, b, c, d, e, w, t) \ + temp = ROTATE(5, (a)) + f((b), (c), (d)) + (e) + (w) + (t); \ + (e) = (d); \ + (d) = (c); \ + (c) = ROTATE(30, (b)); \ + (b) = (a); \ + (a) = temp; + + +/* + * GET() reads 4 input bytes in big-endian byte order and returns + * them as uint32_t. + */ + +#define GET(n) \ + ((uint32_t) p[n * 4 + 3] | \ + ((uint32_t) p[n * 4 + 2] << 8) | \ + ((uint32_t) p[n * 4 + 1] << 16) | \ + ((uint32_t) p[n * 4] << 24)) + + +/* + * This processes one or more 64-byte data blocks, but does not update + * the bit counters. There are no alignment requirements. + */ + +static const u_char * +ngx_sha1_body(ngx_sha1_t *ctx, const u_char *data, size_t size) +{ + uint32_t a, b, c, d, e, temp; + uint32_t saved_a, saved_b, saved_c, saved_d, saved_e; + uint32_t words[80]; + ngx_uint_t i; + const u_char *p; + + p = data; + + a = ctx->a; + b = ctx->b; + c = ctx->c; + d = ctx->d; + e = ctx->e; + + do { + saved_a = a; + saved_b = b; + saved_c = c; + saved_d = d; + saved_e = e; + + /* Load data block into the words array */ + + for (i = 0; i < 16; i++) { + words[i] = GET(i); + } + + for (i = 16; i < 80; i++) { + words[i] = ROTATE(1, words[i - 3] ^ words[i - 8] ^ words[i - 14] + ^ words[i - 16]); + } + + /* Transformations */ + + STEP(F1, a, b, c, d, e, words[0], 0x5a827999); + STEP(F1, a, b, c, d, e, words[1], 0x5a827999); + STEP(F1, a, b, c, d, e, words[2], 0x5a827999); + STEP(F1, a, b, c, d, e, words[3], 0x5a827999); + STEP(F1, a, b, c, d, e, words[4], 0x5a827999); + STEP(F1, a, b, c, d, e, words[5], 0x5a827999); + STEP(F1, a, b, c, d, e, words[6], 0x5a827999); + STEP(F1, a, b, c, d, e, words[7], 0x5a827999); + STEP(F1, a, b, c, d, e, words[8], 0x5a827999); + STEP(F1, a, b, c, d, e, words[9], 0x5a827999); + STEP(F1, a, b, c, d, e, words[10], 0x5a827999); + STEP(F1, a, b, c, d, e, words[11], 0x5a827999); + STEP(F1, a, b, c, d, e, words[12], 0x5a827999); + STEP(F1, a, b, c, d, e, words[13], 0x5a827999); + STEP(F1, a, b, c, d, e, words[14], 0x5a827999); + STEP(F1, a, b, c, d, e, words[15], 0x5a827999); + STEP(F1, a, b, c, d, e, words[16], 0x5a827999); + STEP(F1, a, b, c, d, e, words[17], 0x5a827999); + STEP(F1, a, b, c, d, e, words[18], 0x5a827999); + STEP(F1, a, b, c, d, e, words[19], 0x5a827999); + + STEP(F2, a, b, c, d, e, words[20], 0x6ed9eba1); + STEP(F2, a, b, c, d, e, words[21], 0x6ed9eba1); + STEP(F2, a, b, c, d, e, words[22], 0x6ed9eba1); + STEP(F2, a, b, c, d, e, words[23], 0x6ed9eba1); + STEP(F2, a, b, c, d, e, words[24], 0x6ed9eba1); + STEP(F2, a, b, c, d, e, words[25], 0x6ed9eba1); + STEP(F2, a, b, c, d, e, words[26], 0x6ed9eba1); + STEP(F2, a, b, c, d, e, words[27], 0x6ed9eba1); + STEP(F2, a, b, c, d, e, words[28], 0x6ed9eba1); + STEP(F2, a, b, c, d, e, words[29], 0x6ed9eba1); + STEP(F2, a, b, c, d, e, words[30], 0x6ed9eba1); + STEP(F2, a, b, c, d, e, words[31], 0x6ed9eba1); + STEP(F2, a, b, c, d, e, words[32], 0x6ed9eba1); + STEP(F2, a, b, c, d, e, words[33], 0x6ed9eba1); + STEP(F2, a, b, c, d, e, words[34], 0x6ed9eba1); + STEP(F2, a, b, c, d, e, words[35], 0x6ed9eba1); + STEP(F2, a, b, c, d, e, words[36], 0x6ed9eba1); + STEP(F2, a, b, c, d, e, words[37], 0x6ed9eba1); + STEP(F2, a, b, c, d, e, words[38], 0x6ed9eba1); + STEP(F2, a, b, c, d, e, words[39], 0x6ed9eba1); + + STEP(F3, a, b, c, d, e, words[40], 0x8f1bbcdc); + STEP(F3, a, b, c, d, e, words[41], 0x8f1bbcdc); + STEP(F3, a, b, c, d, e, words[42], 0x8f1bbcdc); + STEP(F3, a, b, c, d, e, words[43], 0x8f1bbcdc); + STEP(F3, a, b, c, d, e, words[44], 0x8f1bbcdc); + STEP(F3, a, b, c, d, e, words[45], 0x8f1bbcdc); + STEP(F3, a, b, c, d, e, words[46], 0x8f1bbcdc); + STEP(F3, a, b, c, d, e, words[47], 0x8f1bbcdc); + STEP(F3, a, b, c, d, e, words[48], 0x8f1bbcdc); + STEP(F3, a, b, c, d, e, words[49], 0x8f1bbcdc); + STEP(F3, a, b, c, d, e, words[50], 0x8f1bbcdc); + STEP(F3, a, b, c, d, e, words[51], 0x8f1bbcdc); + STEP(F3, a, b, c, d, e, words[52], 0x8f1bbcdc); + STEP(F3, a, b, c, d, e, words[53], 0x8f1bbcdc); + STEP(F3, a, b, c, d, e, words[54], 0x8f1bbcdc); + STEP(F3, a, b, c, d, e, words[55], 0x8f1bbcdc); + STEP(F3, a, b, c, d, e, words[56], 0x8f1bbcdc); + STEP(F3, a, b, c, d, e, words[57], 0x8f1bbcdc); + STEP(F3, a, b, c, d, e, words[58], 0x8f1bbcdc); + STEP(F3, a, b, c, d, e, words[59], 0x8f1bbcdc); + + STEP(F2, a, b, c, d, e, words[60], 0xca62c1d6); + STEP(F2, a, b, c, d, e, words[61], 0xca62c1d6); + STEP(F2, a, b, c, d, e, words[62], 0xca62c1d6); + STEP(F2, a, b, c, d, e, words[63], 0xca62c1d6); + STEP(F2, a, b, c, d, e, words[64], 0xca62c1d6); + STEP(F2, a, b, c, d, e, words[65], 0xca62c1d6); + STEP(F2, a, b, c, d, e, words[66], 0xca62c1d6); + STEP(F2, a, b, c, d, e, words[67], 0xca62c1d6); + STEP(F2, a, b, c, d, e, words[68], 0xca62c1d6); + STEP(F2, a, b, c, d, e, words[69], 0xca62c1d6); + STEP(F2, a, b, c, d, e, words[70], 0xca62c1d6); + STEP(F2, a, b, c, d, e, words[71], 0xca62c1d6); + STEP(F2, a, b, c, d, e, words[72], 0xca62c1d6); + STEP(F2, a, b, c, d, e, words[73], 0xca62c1d6); + STEP(F2, a, b, c, d, e, words[74], 0xca62c1d6); + STEP(F2, a, b, c, d, e, words[75], 0xca62c1d6); + STEP(F2, a, b, c, d, e, words[76], 0xca62c1d6); + STEP(F2, a, b, c, d, e, words[77], 0xca62c1d6); + STEP(F2, a, b, c, d, e, words[78], 0xca62c1d6); + STEP(F2, a, b, c, d, e, words[79], 0xca62c1d6); + + a += saved_a; + b += saved_b; + c += saved_c; + d += saved_d; + e += saved_e; + + p += 64; + + } while (size -= 64); + + ctx->a = a; + ctx->b = b; + ctx->c = c; + ctx->d = d; + ctx->e = e; + + return p; +} + +#endif diff --git a/src/core/ngx_sha1.h b/src/core/ngx_sha1.h --- a/src/core/ngx_sha1.h +++ b/src/core/ngx_sha1.h @@ -13,6 +13,8 @@ #include +#if (NGX_HAVE_SHA1) + #if (NGX_HAVE_OPENSSL_SHA1_H) #include #else @@ -28,4 +30,21 @@ typedef SHA_CTX ngx_sha1_t; #define ngx_sha1_final SHA1_Final +#else /* !NGX_HAVE_SHA1 */ + + +typedef struct { + uint64_t bytes; + uint32_t a, b, c, d, e, f; + u_char buffer[64]; +} ngx_sha1_t; + + +void ngx_sha1_init(ngx_sha1_t *ctx); +void ngx_sha1_update(ngx_sha1_t *ctx, const void *data, size_t size); +void ngx_sha1_final(u_char result[20], ngx_sha1_t *ctx); + + +#endif + #endif /* _NGX_SHA1_H_INCLUDED_ */ From bblack at wikimedia.org Thu Jun 9 16:40:19 2016 From: bblack at wikimedia.org (Brandon Black) Date: Thu, 9 Jun 2016 16:40:19 +0000 Subject: ssl_session_timeout and forward secrecy concerns Message-ID: This topic has been brought up before here on the forums with no response [1]. The blog post linked there from Tim Taubert [2] suggests that entries in an ssl_session_cache (and let's presume the common case here that it's a shm cache) don't get explicitly purged on expiry. It seems to be backed up by some text from the related post by Adam Langley [3] too. Therefore, the argument goes: because a large cache (relative to session rate) could hang onto a cached expired session in memory for a very long time, an administrator who cares about forward secrecy in the face of server breach needs to mitigate by periodically wiping the whole cache (nginx restart) and/or setting the size relatively-small to ensure the entire cache will be fully-overwritten in reasonable time. While tuning and playing with related things, I got curious about how hard it would be to add explicit purging of expired sessions from the cache, so that we could size caches with large headroom and not have to worry about the forward-secrecy implications. Once I started looking at the code, it seemed to me like sessions are already actively purged via two separate mechanisms: A) In the nginx code itself, in ngx_ssl_new_session(), there's an explicit unconditional call near the top that drops up to 2 expired sessions from the expire_queue, if there are any actually-expired ones. This is separate from and before "expiring" the oldest unexpired sessions just to make room in the cache if necessary. This seems to provide a fairly reasonable path for expired sessions getting regularly purged if the overall session rate is relatively-stable, but might leave them longer than expected if the new-session rate drops off significantly from past highs. B) In OpenSSL, the default is apparently to purge *all* expired sessions periodically (every 256th received connection). There's an option to disable that behavior ( SSL_SESS_CACHE_NO_AUTO_CLEAR ), but nginx doesn't set that option when a shm cache is configured. The OpenSSL-level flushing code used here seems to zero out the secret data, and also invokes the session remove callback set up by nginx to clear it from nginx's rbtree and such. I would think this alone would solve the problem even without the stuff in ngx_ssl_new_session(), assuming you can guarantee a bare minimum new-session rate of 256/day or so (easy: if nothing else create a curl cronjob to ping your server in case of zero legit traffic flow). Perhaps I'm reading the code wrong, or I've made some faulty assumptions about how it works? Or are these blog posts actually wrong and nginx's ssl_session_timeout is already a safe boundary for forward secrecy issues all on its own, assuming the 1/256 flush built into openssl is regularly triggered? Thanks for any insight, -- Brandon 1. https://forum.nginx.org/read.php?2,254881,254881#msg-254881 2. https://timtaubert.de/blog/2014/11/the-sad-state-of-server-side-tls-session-resumption-implementations/ 3. https://www.imperialviolet.org/2013/06/27/botchingpfs.html From richard at fussenegger.info Thu Jun 9 16:57:12 2016 From: richard at fussenegger.info (Richard Fussenegger) Date: Thu, 9 Jun 2016 18:57:12 +0200 Subject: ssl_session_timeout and forward secrecy concerns In-Reply-To: References: Message-ID: <71fe67a0-ad77-c8da-3cbd-b88227fcaf09@fussenegger.info> Note that a solution for session ticket key rotation is actually trivial: https://github.com/Fleshgrinder/nginx-session-ticket-key-rotation http://richard.fussenegger.info/ma/masters-thesis-web-signed.pdf#107 The second link contains some more info on the actual implementation and the relevant nginx parts. Richard -------------- next part -------------- A non-text attachment was scrubbed... Name: smime.p7s Type: application/pkcs7-signature Size: 3880 bytes Desc: S/MIME Cryptographic Signature URL: From bblack at wikimedia.org Thu Jun 9 17:00:43 2016 From: bblack at wikimedia.org (Brandon Black) Date: Thu, 9 Jun 2016 17:00:43 +0000 Subject: ssl_session_timeout and forward secrecy concerns In-Reply-To: References: Message-ID: On Thu, Jun 9, 2016 at 4:53 PM, Richard Fussenegger wrote: > Note that a solution for session ticket key rotation is actually trivial: Definitely agreed that a ticket-based solution is much better. The problem is that we still face a significant volume of real-world browser clients that fail to implement tickets (All MSIE before 11.x (and even 11.x on Win7), as well as all Apple Safari versions to date). We could implement tickets with a healthy rotation scheme like you've outlined to support the better browsers, but we'd still want a sessionid cache as well to support the rest, at which point we're back to the same question again. -- Brandon From richard at fussenegger.info Thu Jun 9 17:03:26 2016 From: richard at fussenegger.info (Richard Fussenegger) Date: Thu, 9 Jun 2016 19:03:26 +0200 Subject: ssl_session_timeout and forward secrecy concerns In-Reply-To: References: Message-ID: On 6/9/2016 7:00 PM, Brandon Black wrote: > On Thu, Jun 9, 2016 at 4:53 PM, Richard Fussenegger > wrote: >> Note that a solution for session ticket key rotation is actually trivial: > Definitely agreed that a ticket-based solution is much better. The > problem is that we still face a significant volume of real-world > browser clients that fail to implement tickets (All MSIE before 11.x > (and even 11.x on Win7), as well as all Apple Safari versions to > date). We could implement tickets with a healthy rotation scheme like > you've outlined to support the better browsers, but we'd still want a > sessionid cache as well to support the rest, at which point we're back > to the same question again. > > -- Brandon Sorry for sending two mails, the mailing list does not allow attachments. ;) Your question is perfectly valid and especially for smaller websites super relevant because a working session ID approach out of the box is simply perfect for them. I just wanted to mention the ticket thingy because the topics are tightly bound to each other. It does not answer your question nor do I want to invalidate it. :) Richard From ranier.vf at gmail.com Thu Jun 9 18:42:57 2016 From: ranier.vf at gmail.com (Ranier Vf) Date: Thu, 9 Jun 2016 15:42:57 -0300 Subject: setlocale Unwanted behavior Message-ID: Hi, In ngx_win32_init.c function ngx_os_init, nginx call: setlocale(LC_ALL, ""); This break all conversions sprintf, when wanted '.' point decimal. In my case, results are ',' coma decimal. Solution: setlocale(LC_TYPE, ""); Only LC_TYPE affects _wcsicmp(). Best regards, Ranier -------------- next part -------------- An HTML attachment was scrubbed... URL: From ranier.vf at gmail.com Thu Jun 9 19:55:08 2016 From: ranier.vf at gmail.com (Ranier Vf) Date: Thu, 9 Jun 2016 16:55:08 -0300 Subject: Nginx for Windows access violation Message-ID: Hi, C:\nginx>nginx -V nginx version: nginx/1.10.1 built by cl 16.00.30319.01 for 80x86 configure arguments: --with-cc=cl --builddir=objs --prefix= --conf-path=conf/ngi nx.conf --pid-path=logs/nginx.pid --http-log-path=logs/access.log --error-log-pa th=logs/error.log --sbin-path=nginx.exe --http-client-body-temp-path=temp/client _body_temp --http-proxy-temp-path=temp/proxy_temp --http-fastcgi-temp-path=temp/ fastcgi_temp --with-cc-opt=-DFD_SETSIZE=1024 --with-pcre=objs/lib/pcre-8.38 --wi th-zlib=objs/lib/zlib-1.2.8 --with-md5-asm --with-sha1-asm --with-select_module --add-module=ngx_rcpdv WARNING: Stack unwind information not available. Following frames may be wrong. ntdll!KiFastSystemCallRet kernel32!WaitForMultipleObjects+0x18 nginx!ngx_worker_process_cycle+0x2d3 [c:\msys\1.0\nginx-1.10\src\os\win32\ngx_process_cycle.c @ 656] nginx!ngx_master_process_cycle+0x37 [c:\msys\1.0\nginx-1.10\src\os\win32\ngx_process_cycle.c @ 76] nginx!main+0x45c [c:\msys\1.0\nginx-1.10\src\core\nginx.c @ 367] nginx!__tmainCRTStartup+0x10b [f:\dd\vctools\crt_bld\self_x86\crt\src\crt0.c @ 278] kernel32!RegisterWaitForInputIdle+0x49 WARNING: Stack unwind information not available. Following frames may be wrong. ntdll!KiFastSystemCallRet kernel32!Sleep+0xf nginx!ngx_cache_loader_thread+0x11 [c:\msys\1.0\nginx-1.10\src\os\win32\ngx_process_cycle.c @ 965] kernel32!GetModuleFileNameA+0x1b4 Consistently, this errors arrives with nginx for windows. Any chance to investigate? Best regards, Ranier -------------- next part -------------- An HTML attachment was scrubbed... URL: From mdounin at mdounin.ru Thu Jun 9 20:47:00 2016 From: mdounin at mdounin.ru (Maxim Dounin) Date: Thu, 9 Jun 2016 23:47:00 +0300 Subject: Nginx for Windows access violation In-Reply-To: References: Message-ID: <20160609204700.GX36620@mdounin.ru> Hello! On Thu, Jun 09, 2016 at 04:55:08PM -0300, Ranier Vf wrote: > Hi, > > C:\nginx>nginx -V > nginx version: nginx/1.10.1 > built by cl 16.00.30319.01 for 80x86 > configure arguments: --with-cc=cl --builddir=objs --prefix= > --conf-path=conf/ngi > nx.conf --pid-path=logs/nginx.pid --http-log-path=logs/access.log > --error-log-pa > th=logs/error.log --sbin-path=nginx.exe > --http-client-body-temp-path=temp/client > _body_temp --http-proxy-temp-path=temp/proxy_temp > --http-fastcgi-temp-path=temp/ > fastcgi_temp --with-cc-opt=-DFD_SETSIZE=1024 --with-pcre=objs/lib/pcre-8.38 > --wi > th-zlib=objs/lib/zlib-1.2.8 --with-md5-asm --with-sha1-asm > --with-select_module > --add-module=ngx_rcpdv [...] > Consistently, this errors arrives with nginx for windows. > > Any chance to investigate? As previously suggested, try without any 3rd party modules. Or, better yet, use an official compiled binary from http://nginx.org/. -- Maxim Dounin http://nginx.org/ From ranier.vf at gmail.com Thu Jun 9 21:07:18 2016 From: ranier.vf at gmail.com (Ranier Vf) Date: Thu, 9 Jun 2016 18:07:18 -0300 Subject: Nginx for Windows access violation In-Reply-To: <20160609204700.GX36620@mdounin.ru> References: <20160609204700.GX36620@mdounin.ru> Message-ID: Hi, What is configure options to compile 3rd module as DLL? Best regards, Ranier 2016-06-09 17:47 GMT-03:00 Maxim Dounin : > Hello! > > On Thu, Jun 09, 2016 at 04:55:08PM -0300, Ranier Vf wrote: > > > Hi, > > > > C:\nginx>nginx -V > > nginx version: nginx/1.10.1 > > built by cl 16.00.30319.01 for 80x86 > > configure arguments: --with-cc=cl --builddir=objs --prefix= > > --conf-path=conf/ngi > > nx.conf --pid-path=logs/nginx.pid --http-log-path=logs/access.log > > --error-log-pa > > th=logs/error.log --sbin-path=nginx.exe > > --http-client-body-temp-path=temp/client > > _body_temp --http-proxy-temp-path=temp/proxy_temp > > --http-fastcgi-temp-path=temp/ > > fastcgi_temp --with-cc-opt=-DFD_SETSIZE=1024 > --with-pcre=objs/lib/pcre-8.38 > > --wi > > th-zlib=objs/lib/zlib-1.2.8 --with-md5-asm --with-sha1-asm > > --with-select_module > > --add-module=ngx_rcpdv > > [...] > > > Consistently, this errors arrives with nginx for windows. > > > > Any chance to investigate? > > As previously suggested, try without any 3rd party modules. Or, > better yet, use an official compiled binary from http://nginx.org/. > > -- > Maxim Dounin > http://nginx.org/ > > _______________________________________________ > nginx-devel mailing list > nginx-devel at nginx.org > http://mailman.nginx.org/mailman/listinfo/nginx-devel > -------------- next part -------------- An HTML attachment was scrubbed... URL: From tim at timtaubert.de Fri Jun 10 10:30:32 2016 From: tim at timtaubert.de (Tim Taubert) Date: Fri, 10 Jun 2016 12:30:32 +0200 Subject: [PATCH] Add ngx_ssl_ciphers() to set list of cipher suites in openssl module Message-ID: <575A96C8.8000403@timtaubert.de> # HG changeset patch # User Tim Taubert # Date 1465549632 -7200 # Fri Jun 10 11:07:12 2016 +0200 # Node ID d94b74c337b70087b78258d2124c49a6422190c9 # Parent 1064ea81ed3aabb8ad422ffcc60ddcde667022ac Add ngx_ssl_ciphers() to set list of cipher suites in openssl module Replace all calls to SSL_CTX_set_cipher_list() from outside the OpenSSL module by ngx_sll_ciphers() calls to make NGINX more crypto-library-agnostic diff --git a/src/event/ngx_event_openssl.c b/src/event/ngx_event_openssl.c --- a/src/event/ngx_event_openssl.c +++ b/src/event/ngx_event_openssl.c @@ -562,16 +562,30 @@ ngx_ssl_certificate(ngx_conf_t *cf, ngx_ } SSL_CTX_set_default_passwd_cb(ssl->ctx, NULL); return NGX_OK; } +ngx_int_t +ngx_ssl_ciphers(ngx_conf_t *cf, ngx_ssl_t *ssl, ngx_str_t *ciphers) +{ + if (SSL_CTX_set_cipher_list(ssl->ctx, (const char *) ciphers->data) == 0) { + ngx_ssl_error(NGX_LOG_EMERG, ssl->log, 0, + "SSL_CTX_set_cipher_list(\"%V\") failed", + ciphers); + return NGX_ERROR; + } + + return NGX_OK; +} + + static int ngx_ssl_password_callback(char *buf, int size, int rwflag, void *userdata) { ngx_str_t *pwd = userdata; if (rwflag) { ngx_log_error(NGX_LOG_ALERT, ngx_cycle->log, 0, "ngx_ssl_password_callback() is called for encryption"); diff --git a/src/event/ngx_event_openssl.h b/src/event/ngx_event_openssl.h --- a/src/event/ngx_event_openssl.h +++ b/src/event/ngx_event_openssl.h @@ -139,16 +139,17 @@ typedef struct { ngx_int_t ngx_ssl_init(ngx_log_t *log); ngx_int_t ngx_ssl_create(ngx_ssl_t *ssl, ngx_uint_t protocols, void *data); ngx_int_t ngx_ssl_certificates(ngx_conf_t *cf, ngx_ssl_t *ssl, ngx_array_t *certs, ngx_array_t *keys, ngx_array_t *passwords); ngx_int_t ngx_ssl_certificate(ngx_conf_t *cf, ngx_ssl_t *ssl, ngx_str_t *cert, ngx_str_t *key, ngx_array_t *passwords); +ngx_int_t ngx_ssl_ciphers(ngx_conf_t *cf, ngx_ssl_t *ssl, ngx_str_t *ciphers); ngx_int_t ngx_ssl_client_certificate(ngx_conf_t *cf, ngx_ssl_t *ssl, ngx_str_t *cert, ngx_int_t depth); ngx_int_t ngx_ssl_trusted_certificate(ngx_conf_t *cf, ngx_ssl_t *ssl, ngx_str_t *cert, ngx_int_t depth); ngx_int_t ngx_ssl_crl(ngx_conf_t *cf, ngx_ssl_t *ssl, ngx_str_t *crl); ngx_int_t ngx_ssl_stapling(ngx_conf_t *cf, ngx_ssl_t *ssl, ngx_str_t *file, ngx_str_t *responder, ngx_uint_t verify); ngx_int_t ngx_ssl_stapling_resolver(ngx_conf_t *cf, ngx_ssl_t *ssl, diff --git a/src/http/modules/ngx_http_proxy_module.c b/src/http/modules/ngx_http_proxy_module.c --- a/src/http/modules/ngx_http_proxy_module.c +++ b/src/http/modules/ngx_http_proxy_module.c @@ -4318,23 +4318,17 @@ ngx_http_proxy_set_ssl(ngx_conf_t *cf, n if (ngx_ssl_certificate(cf, plcf->upstream.ssl, &plcf->ssl_certificate, &plcf->ssl_certificate_key, plcf->ssl_passwords) != NGX_OK) { return NGX_ERROR; } } - if (SSL_CTX_set_cipher_list(plcf->upstream.ssl->ctx, - (const char *) plcf->ssl_ciphers.data) - == 0) - { - ngx_ssl_error(NGX_LOG_EMERG, cf->log, 0, - "SSL_CTX_set_cipher_list(\"%V\") failed", - &plcf->ssl_ciphers); + if (ngx_ssl_ciphers(cf, plcf->upstream.ssl, &plcf->ssl_ciphers) != NGX_OK) { return NGX_ERROR; } if (plcf->upstream.ssl_verify) { if (plcf->ssl_trusted_certificate.len == 0) { ngx_log_error(NGX_LOG_EMERG, cf->log, 0, "no proxy_ssl_trusted_certificate for proxy_ssl_verify"); return NGX_ERROR; diff --git a/src/http/modules/ngx_http_ssl_module.c b/src/http/modules/ngx_http_ssl_module.c --- a/src/http/modules/ngx_http_ssl_module.c +++ b/src/http/modules/ngx_http_ssl_module.c @@ -684,23 +684,17 @@ ngx_http_ssl_merge_srv_conf(ngx_conf_t * if (ngx_ssl_certificates(cf, &conf->ssl, conf->certificates, conf->certificate_keys, conf->passwords) != NGX_OK) { return NGX_CONF_ERROR; } - if (SSL_CTX_set_cipher_list(conf->ssl.ctx, - (const char *) conf->ciphers.data) - == 0) - { - ngx_ssl_error(NGX_LOG_EMERG, cf->log, 0, - "SSL_CTX_set_cipher_list(\"%V\") failed", - &conf->ciphers); + if (ngx_ssl_ciphers(cf, &conf->ssl, &conf->ciphers) != NGX_OK) { return NGX_CONF_ERROR; } conf->ssl.buffer_size = conf->buffer_size; if (conf->verify) { if (conf->client_certificate.len == 0 && conf->verify != 3) { diff --git a/src/http/modules/ngx_http_uwsgi_module.c b/src/http/modules/ngx_http_uwsgi_module.c --- a/src/http/modules/ngx_http_uwsgi_module.c +++ b/src/http/modules/ngx_http_uwsgi_module.c @@ -2320,23 +2320,17 @@ ngx_http_uwsgi_set_ssl(ngx_conf_t *cf, n if (ngx_ssl_certificate(cf, uwcf->upstream.ssl, &uwcf->ssl_certificate, &uwcf->ssl_certificate_key, uwcf->ssl_passwords) != NGX_OK) { return NGX_ERROR; } } - if (SSL_CTX_set_cipher_list(uwcf->upstream.ssl->ctx, - (const char *) uwcf->ssl_ciphers.data) - == 0) - { - ngx_ssl_error(NGX_LOG_EMERG, cf->log, 0, - "SSL_CTX_set_cipher_list(\"%V\") failed", - &uwcf->ssl_ciphers); + if (ngx_ssl_ciphers(cf, uwcf->upstream.ssl, &uwcf->ssl_ciphers) != NGX_OK) { return NGX_ERROR; } if (uwcf->upstream.ssl_verify) { if (uwcf->ssl_trusted_certificate.len == 0) { ngx_log_error(NGX_LOG_EMERG, cf->log, 0, "no uwsgi_ssl_trusted_certificate for uwsgi_ssl_verify"); return NGX_ERROR; diff --git a/src/mail/ngx_mail_ssl_module.c b/src/mail/ngx_mail_ssl_module.c --- a/src/mail/ngx_mail_ssl_module.c +++ b/src/mail/ngx_mail_ssl_module.c @@ -417,23 +417,17 @@ ngx_mail_ssl_merge_conf(ngx_conf_t *cf, return NGX_CONF_ERROR; } if (ngx_ssl_crl(cf, &conf->ssl, &conf->crl) != NGX_OK) { return NGX_CONF_ERROR; } } - if (SSL_CTX_set_cipher_list(conf->ssl.ctx, - (const char *) conf->ciphers.data) - == 0) - { - ngx_ssl_error(NGX_LOG_EMERG, cf->log, 0, - "SSL_CTX_set_cipher_list(\"%V\") failed", - &conf->ciphers); + if (ngx_ssl_ciphers(cf, &conf->ssl, &conf->ciphers) != NGX_OK) { return NGX_CONF_ERROR; } if (conf->prefer_server_ciphers) { SSL_CTX_set_options(conf->ssl.ctx, SSL_OP_CIPHER_SERVER_PREFERENCE); } #if (OPENSSL_VERSION_NUMBER < 0x10100001L && !defined LIBRESSL_VERSION_NUMBER) diff --git a/src/stream/ngx_stream_proxy_module.c b/src/stream/ngx_stream_proxy_module.c --- a/src/stream/ngx_stream_proxy_module.c +++ b/src/stream/ngx_stream_proxy_module.c @@ -1635,23 +1635,17 @@ ngx_stream_proxy_set_ssl(ngx_conf_t *cf, if (ngx_ssl_certificate(cf, pscf->ssl, &pscf->ssl_certificate, &pscf->ssl_certificate_key, pscf->ssl_passwords) != NGX_OK) { return NGX_ERROR; } } - if (SSL_CTX_set_cipher_list(pscf->ssl->ctx, - (const char *) pscf->ssl_ciphers.data) - == 0) - { - ngx_ssl_error(NGX_LOG_EMERG, cf->log, 0, - "SSL_CTX_set_cipher_list(\"%V\") failed", - &pscf->ssl_ciphers); + if (ngx_ssl_ciphers(cf, pscf->ssl, &pscf->ssl_ciphers) != NGX_OK) { return NGX_ERROR; } if (pscf->ssl_verify) { if (pscf->ssl_trusted_certificate.len == 0) { ngx_log_error(NGX_LOG_EMERG, cf->log, 0, "no proxy_ssl_trusted_certificate for proxy_ssl_verify"); return NGX_ERROR; diff --git a/src/stream/ngx_stream_ssl_module.c b/src/stream/ngx_stream_ssl_module.c --- a/src/stream/ngx_stream_ssl_module.c +++ b/src/stream/ngx_stream_ssl_module.c @@ -261,23 +261,17 @@ ngx_stream_ssl_merge_conf(ngx_conf_t *cf if (ngx_ssl_certificates(cf, &conf->ssl, conf->certificates, conf->certificate_keys, conf->passwords) != NGX_OK) { return NGX_CONF_ERROR; } - if (SSL_CTX_set_cipher_list(conf->ssl.ctx, - (const char *) conf->ciphers.data) - == 0) - { - ngx_ssl_error(NGX_LOG_EMERG, cf->log, 0, - "SSL_CTX_set_cipher_list(\"%V\") failed", - &conf->ciphers); + if (ngx_ssl_ciphers(cf, &conf->ssl, &conf->ciphers) != NGX_OK) { return NGX_CONF_ERROR; } if (conf->prefer_server_ciphers) { SSL_CTX_set_options(conf->ssl.ctx, SSL_OP_CIPHER_SERVER_PREFERENCE); } #if (OPENSSL_VERSION_NUMBER < 0x10100001L && !defined LIBRESSL_VERSION_NUMBER) From hongzhidao at gmail.com Sun Jun 12 12:22:25 2016 From: hongzhidao at gmail.com (=?UTF-8?B?5rSq5b+X6YGT?=) Date: Sun, 12 Jun 2016 20:22:25 +0800 Subject: upstream keepalive variable Message-ID: Hi, It seems to we can't check a request whether used upstream keepalive, so I add the following code with an additional variable named $upstream_keepalive. static ngx_int_t ngx_http_upstream_keepalive_variable(ngx_http_request_t *r, ngx_http_variable_value_t *v, uintptr_t data) { if (r->upstream_states == NULL || r->upstream_states->nelts == 0 || r->upstream->peer.cached == 0) { v->data = (u_char *) "0"; } else { v->data = (u_char *) "1"; } v->len = 1; v->valid = 1; v->no_cacheable = 0; v->not_found = 0; return NGX_OK; } Help check it, thanks a lot! B.R. -------------- next part -------------- An HTML attachment was scrubbed... URL: From ranier.vf at gmail.com Mon Jun 13 18:50:18 2016 From: ranier.vf at gmail.com (Ranier Vf) Date: Mon, 13 Jun 2016 15:50:18 -0300 Subject: Possible leak? Message-ID: Hi, nginx-1.10 for windows This report only touch nginx source files. Error #28: POSSIBLE LEAK 16384 direct bytes 0x0109c970-0x010a0970 + 100944 indirect bytes # 0 replace_malloc [d:\drmemory_package\common\alloc_replace.c:2576] # 1 ngx_alloc [c:\msys\1.0\nginx-1.10\src\os\win32\ngx_alloc.c:21] # 2 ngx_palloc_block [c:\msys\1.0\nginx-1.10\src\core\ngx_palloc.c:186] # 3 ngx_palloc_small [c:\msys\1.0\nginx-1.10\src\core\ngx_palloc.c:173] # 4 ngx_palloc [c:\msys\1.0\nginx-1.10\src\core\ngx_palloc.c:127] # 5 ngx_pcalloc [c:\msys\1.0\nginx-1.10\src\core\ngx_palloc.c:302] # 6 ngx_hash_keys_array_init [c:\msys\1.0\nginx-1.10\src\core\ngx_hash.c:699] # 7 ngx_http_variables_add_core_vars [c:\msys\1.0\nginx-1.10\src\http\ngx_http_variables.c:2465] # 8 ngx_http_core_preconfiguration [c:\msys\1.0\nginx-1.10\src\http\ngx_http_core_module.c:3400] # 9 ngx_http_block [c:\msys\1.0\nginx-1.10\src\http\ngx_http.c:227] #10 ngx_conf_handler [c:\msys\1.0\nginx-1.10\src\core\ngx_conf_file.c:427] #11 ngx_conf_parse [c:\msys\1.0\nginx-1.10\src\core\ngx_conf_file.c:283] Best regards, Ranier Livre de v?rus. www.avast.com . <#DDB4FAA8-2DD7-40BB-A1B8-4E2AA1F9FDF2> -------------- next part -------------- An HTML attachment was scrubbed... URL: From ranier.vf at gmail.com Mon Jun 13 21:12:29 2016 From: ranier.vf at gmail.com (Ranier Vf) Date: Mon, 13 Jun 2016 18:12:29 -0300 Subject: Nginx 3d module context configuration Message-ID: Hi, I writing own nginx module, that connect via tcp, with external server. What is correct place to put variables configuration? SRV, MAIN or LOC contexts? Inside handler, I need get conn variable, to execute external request. In NIXs, we can have defaults 512 workers connections. The correct is have 512 own conn variables, one for each worker? Best regards, Ranier Vilela Livre de v?rus. www.avast.com . <#DDB4FAA8-2DD7-40BB-A1B8-4E2AA1F9FDF2> -------------- next part -------------- An HTML attachment was scrubbed... URL: From mdounin at mdounin.ru Tue Jun 14 13:36:27 2016 From: mdounin at mdounin.ru (Maxim Dounin) Date: Tue, 14 Jun 2016 16:36:27 +0300 Subject: Possible leak? In-Reply-To: References: Message-ID: <20160614133627.GC36620@mdounin.ru> Hello! On Mon, Jun 13, 2016 at 03:50:18PM -0300, Ranier Vf wrote: > Hi, > nginx-1.10 for windows > This report only touch nginx source files. > > Error #28: POSSIBLE LEAK 16384 direct bytes 0x0109c970-0x010a0970 + 100944 > indirect bytes > # 0 replace_malloc > [d:\drmemory_package\common\alloc_replace.c:2576] > # 1 ngx_alloc > [c:\msys\1.0\nginx-1.10\src\os\win32\ngx_alloc.c:21] > # 2 ngx_palloc_block > [c:\msys\1.0\nginx-1.10\src\core\ngx_palloc.c:186] > # 3 ngx_palloc_small [...] I don't see a memory leak here. If you see it - please explain what happens. Also, please avoid further reports without an explanation / analysis, it's not really helpful. -- Maxim Dounin http://nginx.org/ From serg.brester at sebres.de Tue Jun 14 14:50:19 2016 From: serg.brester at sebres.de (Sergey Brester) Date: Tue, 14 Jun 2016 16:50:19 +0200 Subject: [BF] wrong value of cache max-size in workers Message-ID: <7a429ee385267d07ccf44d49e6fd230a@sebres.de> Hi, enclosed you'll find a changeset with fix for wrong max_size in http file cache: max_size still in bytes in child workers, because cache init called in master (and cache->max_size does not corrected from child if already exists, and it is not in shared mem), so this large size will be "never" reached, in such comparisons like `if (size < cache->max_size) ...`. Regards, Sergey Brester (aka sebres). -------------- next part -------------- A non-text attachment was scrubbed... Name: _sb-cache-max-size-fix.patch Type: text/x-diff Size: 838 bytes Desc: not available URL: From mdounin at mdounin.ru Tue Jun 14 17:24:37 2016 From: mdounin at mdounin.ru (Maxim Dounin) Date: Tue, 14 Jun 2016 20:24:37 +0300 Subject: [PATCH] Add ngx_ssl_ciphers() to set list of cipher suites in openssl module In-Reply-To: <575A96C8.8000403@timtaubert.de> References: <575A96C8.8000403@timtaubert.de> Message-ID: <20160614172437.GJ36620@mdounin.ru> Hello! On Fri, Jun 10, 2016 at 12:30:32PM +0200, Tim Taubert wrote: > # HG changeset patch > # User Tim Taubert > # Date 1465549632 -7200 > # Fri Jun 10 11:07:12 2016 +0200 > # Node ID d94b74c337b70087b78258d2124c49a6422190c9 > # Parent 1064ea81ed3aabb8ad422ffcc60ddcde667022ac > Add ngx_ssl_ciphers() to set list of cipher suites in openssl module > > Replace all calls to SSL_CTX_set_cipher_list() from outside the OpenSSL module > by ngx_sll_ciphers() calls to make NGINX more crypto-library-agnostic Style nitpicking: Please use the "SSL: " prefix for SSL-related commits. Please use full sentences in the commit log, including dots. Please spell "nginx" lowercase. Please keep summary line under 67 symbols. E.g.: : SSL: ngx_ssl_ciphers() to set list of ciphers. : : It replaces all direct calls to SSL_CTX_set_cipher_list() to make : nginx more crypto-library-agnostic. > > diff --git a/src/event/ngx_event_openssl.c b/src/event/ngx_event_openssl.c > --- a/src/event/ngx_event_openssl.c > +++ b/src/event/ngx_event_openssl.c > @@ -562,16 +562,30 @@ ngx_ssl_certificate(ngx_conf_t *cf, ngx_ > } > > SSL_CTX_set_default_passwd_cb(ssl->ctx, NULL); > > return NGX_OK; > } > > > +ngx_int_t > +ngx_ssl_ciphers(ngx_conf_t *cf, ngx_ssl_t *ssl, ngx_str_t *ciphers) > +{ > + if (SSL_CTX_set_cipher_list(ssl->ctx, (const char *) ciphers->data) == 0) { The "const" qualifier can be safely dropped here. And I tend to think it should, as I already removed "const" from all "(const char *)" casts found in ngx_event_openssl.c, see rev. addd98357629. > + ngx_ssl_error(NGX_LOG_EMERG, ssl->log, 0, > + "SSL_CTX_set_cipher_list(\"%V\") failed", > + ciphers); > + return NGX_ERROR; > + } > + > + return NGX_OK; > +} > + > + > static int > ngx_ssl_password_callback(char *buf, int size, int rwflag, void *userdata) > { > ngx_str_t *pwd = userdata; > > if (rwflag) { > ngx_log_error(NGX_LOG_ALERT, ngx_cycle->log, 0, > "ngx_ssl_password_callback() is called for encryption"); The place choosen for the ngx_ssl_ciphers() function looks wrong, as ngx_ssl_password_callback() is a part of ngx_ssl_certificate() code. I would suggest to put it after ngx_ssl_password_callback() instead. Or may be it would be even better to put it somewhere before ngx_ssl_dhparam() (with appropriate ngx_event_openssl.h change). [...] > diff --git a/src/stream/ngx_stream_ssl_module.c b/src/stream/ngx_stream_ssl_module.c > --- a/src/stream/ngx_stream_ssl_module.c > +++ b/src/stream/ngx_stream_ssl_module.c > @@ -261,23 +261,17 @@ ngx_stream_ssl_merge_conf(ngx_conf_t *cf > > if (ngx_ssl_certificates(cf, &conf->ssl, conf->certificates, > conf->certificate_keys, conf->passwords) > != NGX_OK) > { > return NGX_CONF_ERROR; > } > > - if (SSL_CTX_set_cipher_list(conf->ssl.ctx, > - (const char *) conf->ciphers.data) > - == 0) > - { > - ngx_ssl_error(NGX_LOG_EMERG, cf->log, 0, > - "SSL_CTX_set_cipher_list(\"%V\") failed", > - &conf->ciphers); > + if (ngx_ssl_ciphers(cf, &conf->ssl, &conf->ciphers) != NGX_OK) { > return NGX_CONF_ERROR; > } > > if (conf->prefer_server_ciphers) { > SSL_CTX_set_options(conf->ssl.ctx, SSL_OP_CIPHER_SERVER_PREFERENCE); > } What about moving SSL_CTX_set_options(SSL_OP_CIPHER_SERVER_PREFERENCE) calls to the ngx_ssl_ciphers() function as well? -- Maxim Dounin http://nginx.org/ From piotrsikora at google.com Tue Jun 14 19:58:47 2016 From: piotrsikora at google.com (Piotr Sikora) Date: Tue, 14 Jun 2016 12:58:47 -0700 Subject: [PATCH] Add ngx_ssl_ciphers() to set list of cipher suites in openssl module In-Reply-To: <20160614172437.GJ36620@mdounin.ru> References: <575A96C8.8000403@timtaubert.de> <20160614172437.GJ36620@mdounin.ru> Message-ID: Hey, > What about moving SSL_CTX_set_options(SSL_OP_CIPHER_SERVER_PREFERENCE) > calls to the ngx_ssl_ciphers() function as well? +1. Best regards, Piotr Sikora From tim at timtaubert.de Wed Jun 15 08:39:22 2016 From: tim at timtaubert.de (Tim Taubert) Date: Wed, 15 Jun 2016 09:39:22 +0100 Subject: [PATCH] Add ngx_ssl_ciphers() to set list of cipher suites in openssl module In-Reply-To: <20160614172437.GJ36620@mdounin.ru> References: <575A96C8.8000403@timtaubert.de> <20160614172437.GJ36620@mdounin.ru> Message-ID: <5761143A.50705@timtaubert.de> Thanks Maxim and Piotr, comments inline and a new version of the patch is at the end. Maxim Dounin wrote: > Style nitpicking: Please use the "SSL: " prefix for SSL-related > commits. Please use full sentences in the commit log, including > dots. Please spell "nginx" lowercase. Please keep summary line > under 67 symbols. Done. >> +ngx_int_t >> +ngx_ssl_ciphers(ngx_conf_t *cf, ngx_ssl_t *ssl, ngx_str_t *ciphers) >> +{ >> + if (SSL_CTX_set_cipher_list(ssl->ctx, (const char *) ciphers->data) == 0) { > > The "const" qualifier can be safely dropped here. And I tend to > think it should, as I already removed "const" from all "(const char *)" > casts found in ngx_event_openssl.c, see rev. addd98357629. Done. > The place choosen for the ngx_ssl_ciphers() function looks wrong, > as ngx_ssl_password_callback() is a part of ngx_ssl_certificate() > code. I would suggest to put it after ngx_ssl_password_callback() > instead. I put it after ngx_ssl_password_callback(), didn't realize that ngx_ssl_password_callback() is a part of ngx_ssl_certificate(). I think that's the right place as ngx_ssl_ciphers() is called after ngx_ssl_certificates(). >> + if (ngx_ssl_ciphers(cf, &conf->ssl, &conf->ciphers) != NGX_OK) { >> return NGX_CONF_ERROR; >> } >> >> if (conf->prefer_server_ciphers) { >> SSL_CTX_set_options(conf->ssl.ctx, SSL_OP_CIPHER_SERVER_PREFERENCE); >> } > > What about moving SSL_CTX_set_options(SSL_OP_CIPHER_SERVER_PREFERENCE) > calls to the ngx_ssl_ciphers() function as well? Good idea, done. # HG changeset patch # User Tim Taubert # Date 1465979514 -3600 # Wed Jun 15 09:31:54 2016 +0100 # Node ID 004faf919d8b4fb64240dadad36e3f9c9959fcd7 # Parent 1064ea81ed3aabb8ad422ffcc60ddcde667022ac SSL: ngx_ssl_ciphers() to set list of ciphers. This patch replaces all calls to SSL_CTX_set_cipher_list() with ngx_sll_ciphers() to make nginx more crypto-library-agnostic. diff --git a/src/event/ngx_event_openssl.c b/src/event/ngx_event_openssl.c --- a/src/event/ngx_event_openssl.c +++ b/src/event/ngx_event_openssl.c @@ -587,16 +587,34 @@ ngx_ssl_password_callback(char *buf, int ngx_memcpy(buf, pwd->data, size); return size; } ngx_int_t +ngx_ssl_ciphers(ngx_conf_t *cf, ngx_ssl_t *ssl, ngx_str_t *ciphers) +{ + if (SSL_CTX_set_cipher_list(ssl->ctx, (char *) ciphers->data) == 0) { + ngx_ssl_error(NGX_LOG_EMERG, ssl->log, 0, + "SSL_CTX_set_cipher_list(\"%V\") failed", + ciphers); + return NGX_ERROR; + } + + if (cf->prefer_server_ciphers) { + SSL_CTX_set_options(ssl->ctx, SSL_OP_CIPHER_SERVER_PREFERENCE); + } + + return NGX_OK; +} + + +ngx_int_t ngx_ssl_client_certificate(ngx_conf_t *cf, ngx_ssl_t *ssl, ngx_str_t *cert, ngx_int_t depth) { STACK_OF(X509_NAME) *list; SSL_CTX_set_verify(ssl->ctx, SSL_VERIFY_PEER, ngx_ssl_verify_callback); SSL_CTX_set_verify_depth(ssl->ctx, depth); diff --git a/src/event/ngx_event_openssl.h b/src/event/ngx_event_openssl.h --- a/src/event/ngx_event_openssl.h +++ b/src/event/ngx_event_openssl.h @@ -139,16 +139,17 @@ typedef struct { ngx_int_t ngx_ssl_init(ngx_log_t *log); ngx_int_t ngx_ssl_create(ngx_ssl_t *ssl, ngx_uint_t protocols, void *data); ngx_int_t ngx_ssl_certificates(ngx_conf_t *cf, ngx_ssl_t *ssl, ngx_array_t *certs, ngx_array_t *keys, ngx_array_t *passwords); ngx_int_t ngx_ssl_certificate(ngx_conf_t *cf, ngx_ssl_t *ssl, ngx_str_t *cert, ngx_str_t *key, ngx_array_t *passwords); +ngx_int_t ngx_ssl_ciphers(ngx_conf_t *cf, ngx_ssl_t *ssl, ngx_str_t *ciphers); ngx_int_t ngx_ssl_client_certificate(ngx_conf_t *cf, ngx_ssl_t *ssl, ngx_str_t *cert, ngx_int_t depth); ngx_int_t ngx_ssl_trusted_certificate(ngx_conf_t *cf, ngx_ssl_t *ssl, ngx_str_t *cert, ngx_int_t depth); ngx_int_t ngx_ssl_crl(ngx_conf_t *cf, ngx_ssl_t *ssl, ngx_str_t *crl); ngx_int_t ngx_ssl_stapling(ngx_conf_t *cf, ngx_ssl_t *ssl, ngx_str_t *file, ngx_str_t *responder, ngx_uint_t verify); ngx_int_t ngx_ssl_stapling_resolver(ngx_conf_t *cf, ngx_ssl_t *ssl, diff --git a/src/http/modules/ngx_http_proxy_module.c b/src/http/modules/ngx_http_proxy_module.c --- a/src/http/modules/ngx_http_proxy_module.c +++ b/src/http/modules/ngx_http_proxy_module.c @@ -4318,23 +4318,17 @@ ngx_http_proxy_set_ssl(ngx_conf_t *cf, n if (ngx_ssl_certificate(cf, plcf->upstream.ssl, &plcf->ssl_certificate, &plcf->ssl_certificate_key, plcf->ssl_passwords) != NGX_OK) { return NGX_ERROR; } } - if (SSL_CTX_set_cipher_list(plcf->upstream.ssl->ctx, - (const char *) plcf->ssl_ciphers.data) - == 0) - { - ngx_ssl_error(NGX_LOG_EMERG, cf->log, 0, - "SSL_CTX_set_cipher_list(\"%V\") failed", - &plcf->ssl_ciphers); + if (ngx_ssl_ciphers(cf, plcf->upstream.ssl, &plcf->ssl_ciphers) != NGX_OK) { return NGX_ERROR; } if (plcf->upstream.ssl_verify) { if (plcf->ssl_trusted_certificate.len == 0) { ngx_log_error(NGX_LOG_EMERG, cf->log, 0, "no proxy_ssl_trusted_certificate for proxy_ssl_verify"); return NGX_ERROR; diff --git a/src/http/modules/ngx_http_ssl_module.c b/src/http/modules/ngx_http_ssl_module.c --- a/src/http/modules/ngx_http_ssl_module.c +++ b/src/http/modules/ngx_http_ssl_module.c @@ -684,23 +684,17 @@ ngx_http_ssl_merge_srv_conf(ngx_conf_t * if (ngx_ssl_certificates(cf, &conf->ssl, conf->certificates, conf->certificate_keys, conf->passwords) != NGX_OK) { return NGX_CONF_ERROR; } - if (SSL_CTX_set_cipher_list(conf->ssl.ctx, - (const char *) conf->ciphers.data) - == 0) - { - ngx_ssl_error(NGX_LOG_EMERG, cf->log, 0, - "SSL_CTX_set_cipher_list(\"%V\") failed", - &conf->ciphers); + if (ngx_ssl_ciphers(cf, &conf->ssl, &conf->ciphers) != NGX_OK) { return NGX_CONF_ERROR; } conf->ssl.buffer_size = conf->buffer_size; if (conf->verify) { if (conf->client_certificate.len == 0 && conf->verify != 3) { @@ -725,20 +719,16 @@ ngx_http_ssl_merge_srv_conf(ngx_conf_t * { return NGX_CONF_ERROR; } if (ngx_ssl_crl(cf, &conf->ssl, &conf->crl) != NGX_OK) { return NGX_CONF_ERROR; } - if (conf->prefer_server_ciphers) { - SSL_CTX_set_options(conf->ssl.ctx, SSL_OP_CIPHER_SERVER_PREFERENCE); - } - #if (OPENSSL_VERSION_NUMBER < 0x10100001L && !defined LIBRESSL_VERSION_NUMBER) /* a temporary 512-bit RSA key is required for export versions of MSIE */ SSL_CTX_set_tmp_rsa_callback(conf->ssl.ctx, ngx_ssl_rsa512_key_callback); #endif if (ngx_ssl_dhparam(cf, &conf->ssl, &conf->dhparam) != NGX_OK) { return NGX_CONF_ERROR; } diff --git a/src/http/modules/ngx_http_uwsgi_module.c b/src/http/modules/ngx_http_uwsgi_module.c --- a/src/http/modules/ngx_http_uwsgi_module.c +++ b/src/http/modules/ngx_http_uwsgi_module.c @@ -2320,23 +2320,17 @@ ngx_http_uwsgi_set_ssl(ngx_conf_t *cf, n if (ngx_ssl_certificate(cf, uwcf->upstream.ssl, &uwcf->ssl_certificate, &uwcf->ssl_certificate_key, uwcf->ssl_passwords) != NGX_OK) { return NGX_ERROR; } } - if (SSL_CTX_set_cipher_list(uwcf->upstream.ssl->ctx, - (const char *) uwcf->ssl_ciphers.data) - == 0) - { - ngx_ssl_error(NGX_LOG_EMERG, cf->log, 0, - "SSL_CTX_set_cipher_list(\"%V\") failed", - &uwcf->ssl_ciphers); + if (ngx_ssl_ciphers(cf, uwcf->upstream.ssl, &uwcf->ssl_ciphers) != NGX_OK) { return NGX_ERROR; } if (uwcf->upstream.ssl_verify) { if (uwcf->ssl_trusted_certificate.len == 0) { ngx_log_error(NGX_LOG_EMERG, cf->log, 0, "no uwsgi_ssl_trusted_certificate for uwsgi_ssl_verify"); return NGX_ERROR; diff --git a/src/mail/ngx_mail_ssl_module.c b/src/mail/ngx_mail_ssl_module.c --- a/src/mail/ngx_mail_ssl_module.c +++ b/src/mail/ngx_mail_ssl_module.c @@ -417,30 +417,20 @@ ngx_mail_ssl_merge_conf(ngx_conf_t *cf, return NGX_CONF_ERROR; } if (ngx_ssl_crl(cf, &conf->ssl, &conf->crl) != NGX_OK) { return NGX_CONF_ERROR; } } - if (SSL_CTX_set_cipher_list(conf->ssl.ctx, - (const char *) conf->ciphers.data) - == 0) - { - ngx_ssl_error(NGX_LOG_EMERG, cf->log, 0, - "SSL_CTX_set_cipher_list(\"%V\") failed", - &conf->ciphers); + if (ngx_ssl_ciphers(cf, &conf->ssl, &conf->ciphers) != NGX_OK) { return NGX_CONF_ERROR; } - if (conf->prefer_server_ciphers) { - SSL_CTX_set_options(conf->ssl.ctx, SSL_OP_CIPHER_SERVER_PREFERENCE); - } - #if (OPENSSL_VERSION_NUMBER < 0x10100001L && !defined LIBRESSL_VERSION_NUMBER) SSL_CTX_set_tmp_rsa_callback(conf->ssl.ctx, ngx_ssl_rsa512_key_callback); #endif if (ngx_ssl_dhparam(cf, &conf->ssl, &conf->dhparam) != NGX_OK) { return NGX_CONF_ERROR; } diff --git a/src/stream/ngx_stream_proxy_module.c b/src/stream/ngx_stream_proxy_module.c --- a/src/stream/ngx_stream_proxy_module.c +++ b/src/stream/ngx_stream_proxy_module.c @@ -1635,23 +1635,17 @@ ngx_stream_proxy_set_ssl(ngx_conf_t *cf, if (ngx_ssl_certificate(cf, pscf->ssl, &pscf->ssl_certificate, &pscf->ssl_certificate_key, pscf->ssl_passwords) != NGX_OK) { return NGX_ERROR; } } - if (SSL_CTX_set_cipher_list(pscf->ssl->ctx, - (const char *) pscf->ssl_ciphers.data) - == 0) - { - ngx_ssl_error(NGX_LOG_EMERG, cf->log, 0, - "SSL_CTX_set_cipher_list(\"%V\") failed", - &pscf->ssl_ciphers); + if (ngx_ssl_ciphers(cf, pscf->ssl, &pscf->ssl_ciphers) != NGX_OK) { return NGX_ERROR; } if (pscf->ssl_verify) { if (pscf->ssl_trusted_certificate.len == 0) { ngx_log_error(NGX_LOG_EMERG, cf->log, 0, "no proxy_ssl_trusted_certificate for proxy_ssl_verify"); return NGX_ERROR; diff --git a/src/stream/ngx_stream_ssl_module.c b/src/stream/ngx_stream_ssl_module.c --- a/src/stream/ngx_stream_ssl_module.c +++ b/src/stream/ngx_stream_ssl_module.c @@ -261,30 +261,20 @@ ngx_stream_ssl_merge_conf(ngx_conf_t *cf if (ngx_ssl_certificates(cf, &conf->ssl, conf->certificates, conf->certificate_keys, conf->passwords) != NGX_OK) { return NGX_CONF_ERROR; } - if (SSL_CTX_set_cipher_list(conf->ssl.ctx, - (const char *) conf->ciphers.data) - == 0) - { - ngx_ssl_error(NGX_LOG_EMERG, cf->log, 0, - "SSL_CTX_set_cipher_list(\"%V\") failed", - &conf->ciphers); + if (ngx_ssl_ciphers(cf, &conf->ssl, &conf->ciphers) != NGX_OK) { return NGX_CONF_ERROR; } - if (conf->prefer_server_ciphers) { - SSL_CTX_set_options(conf->ssl.ctx, SSL_OP_CIPHER_SERVER_PREFERENCE); - } - #if (OPENSSL_VERSION_NUMBER < 0x10100001L && !defined LIBRESSL_VERSION_NUMBER) SSL_CTX_set_tmp_rsa_callback(conf->ssl.ctx, ngx_ssl_rsa512_key_callback); #endif if (ngx_ssl_dhparam(cf, &conf->ssl, &conf->dhparam) != NGX_OK) { return NGX_CONF_ERROR; } From tim at timtaubert.de Wed Jun 15 09:44:13 2016 From: tim at timtaubert.de (Tim Taubert) Date: Wed, 15 Jun 2016 10:44:13 +0100 Subject: [PATCH] Add ngx_ssl_ciphers() to set list of cipher suites in openssl module In-Reply-To: <20160615093659.GC77155@lo0.su> References: <575A96C8.8000403@timtaubert.de> <20160614172437.GJ36620@mdounin.ru> <5761143A.50705@timtaubert.de> <20160615093659.GC77155@lo0.su> Message-ID: <5761236D.4000400@timtaubert.de> (Fixing a typo in the commit message, spotted by Ruslan.) # HG changeset patch # User Tim Taubert # Date 1465983726 -3600 # Wed Jun 15 10:42:06 2016 +0100 # Node ID f42955a35ac0363553fd887ec88a93d51bac8c9e # Parent 1064ea81ed3aabb8ad422ffcc60ddcde667022ac SSL: ngx_ssl_ciphers() to set list of ciphers. This patch replaces all calls to SSL_CTX_set_cipher_list() with ngx_ssl_ciphers() to make nginx more crypto-library-agnostic. diff --git a/src/event/ngx_event_openssl.c b/src/event/ngx_event_openssl.c --- a/src/event/ngx_event_openssl.c +++ b/src/event/ngx_event_openssl.c @@ -587,16 +587,34 @@ ngx_ssl_password_callback(char *buf, int ngx_memcpy(buf, pwd->data, size); return size; } ngx_int_t +ngx_ssl_ciphers(ngx_conf_t *cf, ngx_ssl_t *ssl, ngx_str_t *ciphers) +{ + if (SSL_CTX_set_cipher_list(ssl->ctx, (char *) ciphers->data) == 0) { + ngx_ssl_error(NGX_LOG_EMERG, ssl->log, 0, + "SSL_CTX_set_cipher_list(\"%V\") failed", + ciphers); + return NGX_ERROR; + } + + if (cf->prefer_server_ciphers) { + SSL_CTX_set_options(ssl->ctx, SSL_OP_CIPHER_SERVER_PREFERENCE); + } + + return NGX_OK; +} + + +ngx_int_t ngx_ssl_client_certificate(ngx_conf_t *cf, ngx_ssl_t *ssl, ngx_str_t *cert, ngx_int_t depth) { STACK_OF(X509_NAME) *list; SSL_CTX_set_verify(ssl->ctx, SSL_VERIFY_PEER, ngx_ssl_verify_callback); SSL_CTX_set_verify_depth(ssl->ctx, depth); diff --git a/src/event/ngx_event_openssl.h b/src/event/ngx_event_openssl.h --- a/src/event/ngx_event_openssl.h +++ b/src/event/ngx_event_openssl.h @@ -139,16 +139,17 @@ typedef struct { ngx_int_t ngx_ssl_init(ngx_log_t *log); ngx_int_t ngx_ssl_create(ngx_ssl_t *ssl, ngx_uint_t protocols, void *data); ngx_int_t ngx_ssl_certificates(ngx_conf_t *cf, ngx_ssl_t *ssl, ngx_array_t *certs, ngx_array_t *keys, ngx_array_t *passwords); ngx_int_t ngx_ssl_certificate(ngx_conf_t *cf, ngx_ssl_t *ssl, ngx_str_t *cert, ngx_str_t *key, ngx_array_t *passwords); +ngx_int_t ngx_ssl_ciphers(ngx_conf_t *cf, ngx_ssl_t *ssl, ngx_str_t *ciphers); ngx_int_t ngx_ssl_client_certificate(ngx_conf_t *cf, ngx_ssl_t *ssl, ngx_str_t *cert, ngx_int_t depth); ngx_int_t ngx_ssl_trusted_certificate(ngx_conf_t *cf, ngx_ssl_t *ssl, ngx_str_t *cert, ngx_int_t depth); ngx_int_t ngx_ssl_crl(ngx_conf_t *cf, ngx_ssl_t *ssl, ngx_str_t *crl); ngx_int_t ngx_ssl_stapling(ngx_conf_t *cf, ngx_ssl_t *ssl, ngx_str_t *file, ngx_str_t *responder, ngx_uint_t verify); ngx_int_t ngx_ssl_stapling_resolver(ngx_conf_t *cf, ngx_ssl_t *ssl, diff --git a/src/http/modules/ngx_http_proxy_module.c b/src/http/modules/ngx_http_proxy_module.c --- a/src/http/modules/ngx_http_proxy_module.c +++ b/src/http/modules/ngx_http_proxy_module.c @@ -4318,23 +4318,17 @@ ngx_http_proxy_set_ssl(ngx_conf_t *cf, n if (ngx_ssl_certificate(cf, plcf->upstream.ssl, &plcf->ssl_certificate, &plcf->ssl_certificate_key, plcf->ssl_passwords) != NGX_OK) { return NGX_ERROR; } } - if (SSL_CTX_set_cipher_list(plcf->upstream.ssl->ctx, - (const char *) plcf->ssl_ciphers.data) - == 0) - { - ngx_ssl_error(NGX_LOG_EMERG, cf->log, 0, - "SSL_CTX_set_cipher_list(\"%V\") failed", - &plcf->ssl_ciphers); + if (ngx_ssl_ciphers(cf, plcf->upstream.ssl, &plcf->ssl_ciphers) != NGX_OK) { return NGX_ERROR; } if (plcf->upstream.ssl_verify) { if (plcf->ssl_trusted_certificate.len == 0) { ngx_log_error(NGX_LOG_EMERG, cf->log, 0, "no proxy_ssl_trusted_certificate for proxy_ssl_verify"); return NGX_ERROR; diff --git a/src/http/modules/ngx_http_ssl_module.c b/src/http/modules/ngx_http_ssl_module.c --- a/src/http/modules/ngx_http_ssl_module.c +++ b/src/http/modules/ngx_http_ssl_module.c @@ -684,23 +684,17 @@ ngx_http_ssl_merge_srv_conf(ngx_conf_t * if (ngx_ssl_certificates(cf, &conf->ssl, conf->certificates, conf->certificate_keys, conf->passwords) != NGX_OK) { return NGX_CONF_ERROR; } - if (SSL_CTX_set_cipher_list(conf->ssl.ctx, - (const char *) conf->ciphers.data) - == 0) - { - ngx_ssl_error(NGX_LOG_EMERG, cf->log, 0, - "SSL_CTX_set_cipher_list(\"%V\") failed", - &conf->ciphers); + if (ngx_ssl_ciphers(cf, &conf->ssl, &conf->ciphers) != NGX_OK) { return NGX_CONF_ERROR; } conf->ssl.buffer_size = conf->buffer_size; if (conf->verify) { if (conf->client_certificate.len == 0 && conf->verify != 3) { @@ -725,20 +719,16 @@ ngx_http_ssl_merge_srv_conf(ngx_conf_t * { return NGX_CONF_ERROR; } if (ngx_ssl_crl(cf, &conf->ssl, &conf->crl) != NGX_OK) { return NGX_CONF_ERROR; } - if (conf->prefer_server_ciphers) { - SSL_CTX_set_options(conf->ssl.ctx, SSL_OP_CIPHER_SERVER_PREFERENCE); - } - #if (OPENSSL_VERSION_NUMBER < 0x10100001L && !defined LIBRESSL_VERSION_NUMBER) /* a temporary 512-bit RSA key is required for export versions of MSIE */ SSL_CTX_set_tmp_rsa_callback(conf->ssl.ctx, ngx_ssl_rsa512_key_callback); #endif if (ngx_ssl_dhparam(cf, &conf->ssl, &conf->dhparam) != NGX_OK) { return NGX_CONF_ERROR; } diff --git a/src/http/modules/ngx_http_uwsgi_module.c b/src/http/modules/ngx_http_uwsgi_module.c --- a/src/http/modules/ngx_http_uwsgi_module.c +++ b/src/http/modules/ngx_http_uwsgi_module.c @@ -2320,23 +2320,17 @@ ngx_http_uwsgi_set_ssl(ngx_conf_t *cf, n if (ngx_ssl_certificate(cf, uwcf->upstream.ssl, &uwcf->ssl_certificate, &uwcf->ssl_certificate_key, uwcf->ssl_passwords) != NGX_OK) { return NGX_ERROR; } } - if (SSL_CTX_set_cipher_list(uwcf->upstream.ssl->ctx, - (const char *) uwcf->ssl_ciphers.data) - == 0) - { - ngx_ssl_error(NGX_LOG_EMERG, cf->log, 0, - "SSL_CTX_set_cipher_list(\"%V\") failed", - &uwcf->ssl_ciphers); + if (ngx_ssl_ciphers(cf, uwcf->upstream.ssl, &uwcf->ssl_ciphers) != NGX_OK) { return NGX_ERROR; } if (uwcf->upstream.ssl_verify) { if (uwcf->ssl_trusted_certificate.len == 0) { ngx_log_error(NGX_LOG_EMERG, cf->log, 0, "no uwsgi_ssl_trusted_certificate for uwsgi_ssl_verify"); return NGX_ERROR; diff --git a/src/mail/ngx_mail_ssl_module.c b/src/mail/ngx_mail_ssl_module.c --- a/src/mail/ngx_mail_ssl_module.c +++ b/src/mail/ngx_mail_ssl_module.c @@ -417,30 +417,20 @@ ngx_mail_ssl_merge_conf(ngx_conf_t *cf, return NGX_CONF_ERROR; } if (ngx_ssl_crl(cf, &conf->ssl, &conf->crl) != NGX_OK) { return NGX_CONF_ERROR; } } - if (SSL_CTX_set_cipher_list(conf->ssl.ctx, - (const char *) conf->ciphers.data) - == 0) - { - ngx_ssl_error(NGX_LOG_EMERG, cf->log, 0, - "SSL_CTX_set_cipher_list(\"%V\") failed", - &conf->ciphers); + if (ngx_ssl_ciphers(cf, &conf->ssl, &conf->ciphers) != NGX_OK) { return NGX_CONF_ERROR; } - if (conf->prefer_server_ciphers) { - SSL_CTX_set_options(conf->ssl.ctx, SSL_OP_CIPHER_SERVER_PREFERENCE); - } - #if (OPENSSL_VERSION_NUMBER < 0x10100001L && !defined LIBRESSL_VERSION_NUMBER) SSL_CTX_set_tmp_rsa_callback(conf->ssl.ctx, ngx_ssl_rsa512_key_callback); #endif if (ngx_ssl_dhparam(cf, &conf->ssl, &conf->dhparam) != NGX_OK) { return NGX_CONF_ERROR; } diff --git a/src/stream/ngx_stream_proxy_module.c b/src/stream/ngx_stream_proxy_module.c --- a/src/stream/ngx_stream_proxy_module.c +++ b/src/stream/ngx_stream_proxy_module.c @@ -1635,23 +1635,17 @@ ngx_stream_proxy_set_ssl(ngx_conf_t *cf, if (ngx_ssl_certificate(cf, pscf->ssl, &pscf->ssl_certificate, &pscf->ssl_certificate_key, pscf->ssl_passwords) != NGX_OK) { return NGX_ERROR; } } - if (SSL_CTX_set_cipher_list(pscf->ssl->ctx, - (const char *) pscf->ssl_ciphers.data) - == 0) - { - ngx_ssl_error(NGX_LOG_EMERG, cf->log, 0, - "SSL_CTX_set_cipher_list(\"%V\") failed", - &pscf->ssl_ciphers); + if (ngx_ssl_ciphers(cf, pscf->ssl, &pscf->ssl_ciphers) != NGX_OK) { return NGX_ERROR; } if (pscf->ssl_verify) { if (pscf->ssl_trusted_certificate.len == 0) { ngx_log_error(NGX_LOG_EMERG, cf->log, 0, "no proxy_ssl_trusted_certificate for proxy_ssl_verify"); return NGX_ERROR; diff --git a/src/stream/ngx_stream_ssl_module.c b/src/stream/ngx_stream_ssl_module.c --- a/src/stream/ngx_stream_ssl_module.c +++ b/src/stream/ngx_stream_ssl_module.c @@ -261,30 +261,20 @@ ngx_stream_ssl_merge_conf(ngx_conf_t *cf if (ngx_ssl_certificates(cf, &conf->ssl, conf->certificates, conf->certificate_keys, conf->passwords) != NGX_OK) { return NGX_CONF_ERROR; } - if (SSL_CTX_set_cipher_list(conf->ssl.ctx, - (const char *) conf->ciphers.data) - == 0) - { - ngx_ssl_error(NGX_LOG_EMERG, cf->log, 0, - "SSL_CTX_set_cipher_list(\"%V\") failed", - &conf->ciphers); + if (ngx_ssl_ciphers(cf, &conf->ssl, &conf->ciphers) != NGX_OK) { return NGX_CONF_ERROR; } - if (conf->prefer_server_ciphers) { - SSL_CTX_set_options(conf->ssl.ctx, SSL_OP_CIPHER_SERVER_PREFERENCE); - } - #if (OPENSSL_VERSION_NUMBER < 0x10100001L && !defined LIBRESSL_VERSION_NUMBER) SSL_CTX_set_tmp_rsa_callback(conf->ssl.ctx, ngx_ssl_rsa512_key_callback); #endif if (ngx_ssl_dhparam(cf, &conf->ssl, &conf->dhparam) != NGX_OK) { return NGX_CONF_ERROR; } From serg.brester at sebres.de Wed Jun 15 11:53:31 2016 From: serg.brester at sebres.de (Sergey Brester) Date: Wed, 15 Jun 2016 13:53:31 +0200 Subject: [BF] slab init + http file cache fixes In-Reply-To: <7a429ee385267d07ccf44d49e6fd230a@sebres.de> References: <7a429ee385267d07ccf44d49e6fd230a@sebres.de> Message-ID: <90d675c425386f7ffdd6139b4d55834e@sebres.de> The story with shared zone (slab) resp. http file cache has a continuation. I've additionally found and fixed 2 bugs, the fixes for that you'll find the changesets enclosed as attachments: - _sb-slab-init-fix.patch - slab (zone pool) initialization bug: many static stubs not initialized in workers (because only master calls ngx_slab_init). So stubs initialization moved to new "ngx_slab_core_init" called from "main" direct after "ngx_os_init" (requires "ngx_pagesize"). In consequence of this bug, the pool always allocated a full page (4K - 8K) instead of small slots inside page, so for example 1MB zone can store not more as 250 keys. BTW. According to the documentation: One megabyte zone can store about 8 thousand keys. - _sb-scarce-cache-fix.patch - fixes http file cache: * prevent failure of requests, for that cache cannot be allocated, just because of the cache scarce (NGX_HTTP_CACHE_SCARCE) - alert and send the request data nevertheless; * wrong counting size of cache (too many decrease of "cache->sh->size", because unlocked delete and value of "fcn->exists" was not reset); For the people using github - here is my PR as fix for all 3 issues (3 commits), merged in my mod-branch: https://github.com/sebres/nginx/pull/8 Regargs, sebres _______________________________________ 14.06.2016 16:50, Sergey Brester wrote: > Hi, > > enclosed you'll find a changeset with fix for wrong max_size in http > file cache: > > max_size still in bytes in child workers, because cache init called in > master (and cache->max_size does not corrected from child if already > exists, and it is not in shared mem), > so this large size will be "never" reached, in such comparisons like > `if (size < cache->max_size) ...`. > > Regards, > Sergey Brester (aka sebres). > > _______________________________________________ > nginx-devel mailing list > nginx-devel at nginx.org > http://mailman.nginx.org/mailman/listinfo/nginx-devel [1] Links: ------ [1] http://mailman.nginx.org/mailman/listinfo/nginx-devel -------------- next part -------------- A non-text attachment was scrubbed... Name: _sb-scarce-cache-fix.patch Type: text/x-diff Size: 3244 bytes Desc: not available URL: -------------- next part -------------- A non-text attachment was scrubbed... Name: _sb-slab-init-fix.patch Type: text/x-diff Size: 2557 bytes Desc: not available URL: From mdounin at mdounin.ru Wed Jun 15 13:16:52 2016 From: mdounin at mdounin.ru (Maxim Dounin) Date: Wed, 15 Jun 2016 16:16:52 +0300 Subject: [BF] wrong value of cache max-size in workers In-Reply-To: <7a429ee385267d07ccf44d49e6fd230a@sebres.de> References: <7a429ee385267d07ccf44d49e6fd230a@sebres.de> Message-ID: <20160615131652.GK36620@mdounin.ru> Hello! On Tue, Jun 14, 2016 at 04:50:19PM +0200, Sergey Brester wrote: > Hi, > > enclosed you'll find a changeset with fix for wrong max_size in http file > cache: > > max_size still in bytes in child workers, because cache init called in > master (and cache->max_size does not corrected from child if already exists, > and it is not in shared mem), > so this large size will be "never" reached, in such comparisons like `if > (size < cache->max_size) ...`. Thanks, looks like a valid win32-related problem. See below for comments about the patch. > # HG changeset patch > # User Serg G. Brester (sebres) > # Date 1465913777 -7200 > # Tue Jun 14 16:16:17 2016 +0200 > # Node ID b430e4546172af42bcecf0fc289ec45ef5f9e865 > # Parent 1064ea81ed3aabb8ad422ffcc60ddcde667022ac > fix for http file cache: max_size still in bytes in child workers, > because cache init called in master, so this large size will be "never" reached As this is a win32-only problem, please clearly describe this in commit log. E.g., use "Win32: " prefix in the summary line. Please also describe that this is win32-specific. Alternatively, please use "Cache: " prefix. Also, please use full sentences, including dots. More hints can be found here: http://nginx.org/en/docs/contributing_changes.html > diff -r 1064ea81ed3a -r b430e4546172 src/http/ngx_http_file_cache.c > --- a/src/http/ngx_http_file_cache.c Thu Jun 09 16:55:38 2016 +0300 > +++ b/src/http/ngx_http_file_cache.c Tue Jun 14 16:16:17 2016 +0200 > @@ -130,6 +130,8 @@ ngx_http_file_cache_init(ngx_shm_zone_t > cache->sh = cache->shpool->data; > cache->bsize = ngx_fs_bsize(cache->path->name.data); > This empty line looks unneded for me. YMMV. > + cache->max_size /= cache->bsize; > + > return NGX_OK; > } > -- Maxim Dounin http://nginx.org/ From serg.brester at sebres.de Wed Jun 15 13:51:57 2016 From: serg.brester at sebres.de (Sergey Brester) Date: Wed, 15 Jun 2016 15:51:57 +0200 Subject: [BF] wrong value of cache max-size in workers In-Reply-To: <20160615131652.GK36620@mdounin.ru> References: <7a429ee385267d07ccf44d49e6fd230a@sebres.de> <20160615131652.GK36620@mdounin.ru> Message-ID: <4391f226c406c018429c350831452b37@sebres.de> > Thanks, looks like a valid win32-related problem. See below for > comments about the patch. And why you come to this conclusion? > As this is a win32-only problem, please clearly describe this in > commit log. E.g., use "Win32: " prefix in the summary line. > Please also describe that this is win32-specific. Alternatively, > please use "Cache: " prefix. Also, please use full sentences, > including dots. Well, I think, by merging you can modify the commit message as you like (I renounce the authorship of messsage;))) > More hints can be found here: > http://nginx.org/en/docs/contributing_changes.html [1] I known this paper (I'm not a first time here) ... BTW. With this kind of handling with contributors I understand the people, that sometimes or never more want to post anything to the nginx-developers. > This empty line looks unneded for me. YMMV. > If you'll look at source code you will see this was done exactly as in 2 another blocks contains this code piece (one above and one bellow). I've done it, just thus looks like as in the rest of the code. Regards, sebres From rajalakshmi.iyer at blis.com Wed Jun 15 15:27:29 2016 From: rajalakshmi.iyer at blis.com (Rajalakshmi Iyer) Date: Wed, 15 Jun 2016 16:27:29 +0100 Subject: C++ module Message-ID: Hello, Just wanted to check if it is possible to write NGINX modules in C++ that makes extensive use of the standard template library (STL)? If so, what are the things that one needs to be careful about? Thanks in advance, Raj -- This email and any attachments to it may be confidential and are intended solely for the use of the individual to whom it is addressed. Any views or opinions expressed are solely those of the author and do not necessarily represent those of Blis Ltd, a company registered in England and Wales with registered number 06455773. Its registered office is 5th Floor, 85 Tottenham Court Road, London, W1T 4TQ, United Kingdom. If you are not the intended recipient of this email, you must neither take any action based upon its contents, nor copy or show it to anyone. Please contact the sender if you believe you have received this email in error. -------------- next part -------------- An HTML attachment was scrubbed... URL: From mdounin at mdounin.ru Wed Jun 15 15:54:52 2016 From: mdounin at mdounin.ru (Maxim Dounin) Date: Wed, 15 Jun 2016 18:54:52 +0300 Subject: [BF] slab init + http file cache fixes In-Reply-To: <90d675c425386f7ffdd6139b4d55834e@sebres.de> References: <7a429ee385267d07ccf44d49e6fd230a@sebres.de> <90d675c425386f7ffdd6139b4d55834e@sebres.de> Message-ID: <20160615155452.GL36620@mdounin.ru> Hello! On Wed, Jun 15, 2016 at 01:53:31PM +0200, Sergey Brester wrote: > The story with shared zone (slab) resp. http file cache has a continuation. > > I've additionally found and fixed 2 bugs, the fixes for that you'll find the > changesets enclosed as attachments: > > - _sb-slab-init-fix.patch - slab (zone pool) initialization bug: many static > stubs not initialized in workers (because only master calls ngx_slab_init). > So stubs initialization moved to new "ngx_slab_core_init" called from "main" > direct after "ngx_os_init" (requires "ngx_pagesize"). > > In consequence of this bug, the pool always allocated a full page (4K - 8K) > instead of small slots inside page, so for example 1MB zone can store not > more as 250 keys. > BTW. According to the documentation: One megabyte zone can store about 8 > thousand keys. Thanks, looks like another win32-related problem. > - _sb-scarce-cache-fix.patch - fixes http file cache: > * prevent failure of requests, for that cache cannot be allocated, just > because of the cache scarce > (NGX_HTTP_CACHE_SCARCE) - alert and send the request data nevertheless; > * wrong counting size of cache (too many decrease of "cache->sh->size", > because unlocked delete > and value of "fcn->exists" was not reset); See comments below. [...] > # HG changeset patch > # User Serg G. Brester (sebres) > # Date 1465990539 -7200 > # Wed Jun 15 13:35:39 2016 +0200 > # Node ID ed82931de91e4eb335cc2a094896e6f4f10ac536 > # Parent 0bfc68ad1b7af8c3a7dea24d479ed18bfd024028 > * fixes http file cache: > - prevent failure of requests, for that cache cannot be allocated, just because of the cache scarce (NGX_HTTP_CACHE_SCARCE) - alert and send the request data nevertheless; > - wrong counting size of cache (too many decrease "cache->sh->size", because unlocked delete and "fcn->exists" was not reset); This should be two separate patches. Please also see http://nginx.org/en/docs/contributing_changes.html for more hints (summary line, no more than 80 symbols, and so on). > > diff -r 0bfc68ad1b7a -r ed82931de91e src/http/ngx_http_file_cache.c > --- a/src/http/ngx_http_file_cache.c Wed Jun 15 11:53:55 2016 +0200 > +++ b/src/http/ngx_http_file_cache.c Wed Jun 15 13:35:39 2016 +0200 > @@ -879,7 +879,8 @@ ngx_http_file_cache_exists(ngx_http_file > if (fcn == NULL) { > ngx_log_error(NGX_LOG_ALERT, ngx_cycle->log, 0, > "could not allocate node%s", cache->shpool->log_ctx); > - rc = NGX_ERROR; > + /* cannot be cached (NGX_HTTP_CACHE_SCARCE), just use it without cache */ > + rc = NGX_AGAIN; > goto failed; > } > } Not sure it's a good idea to reuse min_uses return code here. I would rather not. > @@ -1870,24 +1871,27 @@ ngx_http_file_cache_delete(ngx_http_file > p = ngx_hex_dump(p, fcn->key, len); > *p = '\0'; > > - fcn->count++; > - fcn->deleting = 1; > - ngx_shmtx_unlock(&cache->shpool->mutex); > - > - len = path->name.len + 1 + path->len + 2 * NGX_HTTP_CACHE_KEY_LEN; > - ngx_create_hashed_filename(path, name, len); > - > - ngx_log_debug1(NGX_LOG_DEBUG_HTTP, ngx_cycle->log, 0, > - "http file cache expire: \"%s\"", name); > - > - if (ngx_delete_file(name) == NGX_FILE_ERROR) { > - ngx_log_error(NGX_LOG_CRIT, ngx_cycle->log, ngx_errno, > - ngx_delete_file_n " \"%s\" failed", name); > + if (!fcn->deleting) { > + fcn->count++; > + fcn->deleting = 1; The condition added looks wrong: fcn->deleting cannot be set here, as it's only set by this function under lock, and fcn->count++ here will prevent the function from being called again. As far as I understand, you are trying to change processing of the race which happens if the node in question is grabbed by another request while the file is being deleted (fcn->count != 0 at the function end). Please explain what you are trying to chanage and how it's expected to affect various cases possible. > + fcn->exists = 0; > + ngx_shmtx_unlock(&cache->shpool->mutex); > + > + len = path->name.len + 1 + path->len + 2 * NGX_HTTP_CACHE_KEY_LEN; > + ngx_create_hashed_filename(path, name, len); > + > + ngx_log_debug1(NGX_LOG_DEBUG_HTTP, ngx_cycle->log, 0, > + "http file cache expire: \"%s\"", name); > + > + if (ngx_delete_file(name) == NGX_FILE_ERROR) { > + ngx_log_error(NGX_LOG_CRIT, ngx_cycle->log, ngx_errno, > + ngx_delete_file_n " \"%s\" failed", name); > + } > + > + ngx_shmtx_lock(&cache->shpool->mutex); > + fcn->count--; > + fcn->deleting = 0; > } > - > - ngx_shmtx_lock(&cache->shpool->mutex); > - fcn->count--; > - fcn->deleting = 0; > } > > if (fcn->count == 0) { > @@ -2006,6 +2010,7 @@ ngx_http_file_cache_manage_file(ngx_tree > > if (ngx_http_file_cache_add_file(ctx, path) != NGX_OK) { > (void) ngx_http_file_cache_delete_file(ctx, path); > + goto done; > } > > if (++cache->files >= cache->loader_files) { > @@ -2024,6 +2029,8 @@ ngx_http_file_cache_manage_file(ngx_tree > } > } > > +done: > + > return (ngx_quit || ngx_terminate) ? NGX_ABORT : NGX_OK; > } This change looks unrelated. If you think it's needed, please explain the reasons. > # HG changeset patch > # User Serg G. Brester (sebres) > # Date 1465984435 -7200 > # Wed Jun 15 11:53:55 2016 +0200 > # Node ID 0bfc68ad1b7af8c3a7dea24d479ed18bfd024028 > # Parent b430e4546172af42bcecf0fc289ec45ef5f9e865 > Grave slab (zone pool) initialization bug fixed: many stubs not initialized in workers (because only master calls ngx_slab_init) - so stubs initializing moved to new ngx_slab_core_init called from main direct after ngx_os_init (requires ngx_pagesize). > In consequence of this bug, the pool always allocated a full page (4K - 8K) instead of small slots inside page, so for example 1MB zone can store not more as 250 keys. > BTW. According to the documentation: One megabyte zone can store about 8 thousand keys. See above, the description doesn't match style and doesn't describe that this is a win32 problem. > > diff -r b430e4546172 -r 0bfc68ad1b7a src/core/nginx.c > --- a/src/core/nginx.c Tue Jun 14 16:16:17 2016 +0200 > +++ b/src/core/nginx.c Wed Jun 15 11:53:55 2016 +0200 > @@ -256,6 +256,11 @@ main(int argc, char *const *argv) > if (ngx_os_init(log) != NGX_OK) { > return 1; > } > + > + /* > + * ngx_slab_core_init() requires ngx_pagesize set in ngx_os_init() > + */ > + ngx_slab_core_init(); I can't say I like the name, but I have no better suggestions. > > /* > * ngx_crc32_table_init() requires ngx_cacheline_size set in ngx_os_init() > diff -r b430e4546172 -r 0bfc68ad1b7a src/core/ngx_slab.c > --- a/src/core/ngx_slab.c Tue Jun 14 16:16:17 2016 +0200 > +++ b/src/core/ngx_slab.c Wed Jun 15 11:53:55 2016 +0200 > @@ -70,13 +70,9 @@ static ngx_uint_t ngx_slab_exact_shift; > > > void > -ngx_slab_init(ngx_slab_pool_t *pool) > +ngx_slab_core_init() > { > - u_char *p; > - size_t size; > - ngx_int_t m; > - ngx_uint_t i, n, pages; > - ngx_slab_page_t *slots; > + ngx_uint_t n; > > /* STUB */ > if (ngx_slab_max_size == 0) { This test is useless with the new logic you've introduced. > @@ -87,6 +83,19 @@ ngx_slab_init(ngx_slab_pool_t *pool) > } > } > /**/ > +} > + > + > +void > +ngx_slab_init(ngx_slab_pool_t *pool) > +{ > + u_char *p; > + size_t size; > + ngx_int_t m; > + ngx_uint_t i, n, pages; > + ngx_slab_page_t *slots; > + > + ngx_slab_core_init(); This call is useless with the new logic you've introduced. > > pool->min_size = 1 << pool->min_shift; > > diff -r b430e4546172 -r 0bfc68ad1b7a src/core/ngx_slab.h > --- a/src/core/ngx_slab.h Tue Jun 14 16:16:17 2016 +0200 > +++ b/src/core/ngx_slab.h Wed Jun 15 11:53:55 2016 +0200 > @@ -47,6 +47,7 @@ typedef struct { > } ngx_slab_pool_t; > > > +void ngx_slab_core_init(); > void ngx_slab_init(ngx_slab_pool_t *pool); > void *ngx_slab_alloc(ngx_slab_pool_t *pool, size_t size); > void *ngx_slab_alloc_locked(ngx_slab_pool_t *pool, size_t size); -- Maxim Dounin http://nginx.org/ From mdounin at mdounin.ru Wed Jun 15 16:31:50 2016 From: mdounin at mdounin.ru (Maxim Dounin) Date: Wed, 15 Jun 2016 19:31:50 +0300 Subject: [BF] wrong value of cache max-size in workers In-Reply-To: <4391f226c406c018429c350831452b37@sebres.de> References: <7a429ee385267d07ccf44d49e6fd230a@sebres.de> <20160615131652.GK36620@mdounin.ru> <4391f226c406c018429c350831452b37@sebres.de> Message-ID: <20160615163150.GM36620@mdounin.ru> Hello! On Wed, Jun 15, 2016 at 03:51:57PM +0200, Sergey Brester wrote: > >Thanks, looks like a valid win32-related problem. See below for > >comments about the patch. > > And why you come to this conclusion? Because the code path in question is only followed on win32. On Unix, workers are forked and just use memory of the master process, the shm.exists flag is never set. > >As this is a win32-only problem, please clearly describe this in > >commit log. E.g., use "Win32: " prefix in the summary line. > >Please also describe that this is win32-specific. Alternatively, > >please use "Cache: " prefix. Also, please use full sentences, > >including dots. > > Well, I think, by merging you can modify the commit message as you like (I > renounce the authorship of messsage;))) It's not going to work, as it's very likely to never happen. > >More hints can be found here: > >http://nginx.org/en/docs/contributing_changes.html [1] > > I known this paper (I'm not a first time here) ... > > BTW. With this kind of handling with contributors I understand the people, > that sometimes or never more want to post anything to the nginx-developers. The page in question is intended to explain how to prepare patches to follow nginx style and make sure patches can be handled with minimal waste of time of all parties involved. Following these guidlines maximizes changes of a patch being accepted, and minimizes time spent by anyone involved. Not following basically says that you don't care about other's time. The commit log in question do not follow various guidelines explicitly written on the page in question, and that's why I've sent you a link. If you are not following the guildelines intentionally - well, that's your choice, and we can do nothing with it, but don't expect it will somehow improve handling. > >This empty line looks unneded for me. YMMV. > > > > If you'll look at source code you will see this was done exactly as in 2 > another blocks contains this code piece (one above and one bellow). I've > done it, just thus looks like as in the rest of the code. Yes, I understand the reasons. Nevertheless, I would not add it there. If you want to preserve it - that's ok though, as reasons are good enough, and that's why I wrote "YMMV". -- Maxim Dounin http://nginx.org/ From mdounin at mdounin.ru Wed Jun 15 16:57:07 2016 From: mdounin at mdounin.ru (Maxim Dounin) Date: Wed, 15 Jun 2016 19:57:07 +0300 Subject: [PATCH] Add ngx_ssl_ciphers() to set list of cipher suites in openssl module In-Reply-To: <5761236D.4000400@timtaubert.de> References: <575A96C8.8000403@timtaubert.de> <20160614172437.GJ36620@mdounin.ru> <5761143A.50705@timtaubert.de> <20160615093659.GC77155@lo0.su> <5761236D.4000400@timtaubert.de> Message-ID: <20160615165707.GN36620@mdounin.ru> Hello! On Wed, Jun 15, 2016 at 10:44:13AM +0100, Tim Taubert wrote: > # HG changeset patch > # User Tim Taubert > # Date 1465983726 -3600 > # Wed Jun 15 10:42:06 2016 +0100 > # Node ID f42955a35ac0363553fd887ec88a93d51bac8c9e > # Parent 1064ea81ed3aabb8ad422ffcc60ddcde667022ac > SSL: ngx_ssl_ciphers() to set list of ciphers. > > This patch replaces all calls to SSL_CTX_set_cipher_list() with > ngx_ssl_ciphers() to make nginx more crypto-library-agnostic. [...] > ngx_int_t > +ngx_ssl_ciphers(ngx_conf_t *cf, ngx_ssl_t *ssl, ngx_str_t *ciphers) > +{ > + if (SSL_CTX_set_cipher_list(ssl->ctx, (char *) ciphers->data) == 0) { > + ngx_ssl_error(NGX_LOG_EMERG, ssl->log, 0, > + "SSL_CTX_set_cipher_list(\"%V\") failed", > + ciphers); > + return NGX_ERROR; > + } > + > + if (cf->prefer_server_ciphers) { > + SSL_CTX_set_options(ssl->ctx, SSL_OP_CIPHER_SERVER_PREFERENCE); > + } This is not going to work, as ngx_conf_t does not have the prefer_server_ciphers in it: src/event/ngx_event_openssl.c:604:13: error: no member named 'prefer_server_ciphers' in 'struct ngx_conf_s' if (cf->prefer_server_ciphers) { ~~ ^ 1 error generated. You have pass the prefer_server_ciphers value as a function argument, much like "ciphers". [...] > @@ -725,20 +719,16 @@ ngx_http_ssl_merge_srv_conf(ngx_conf_t * > { > return NGX_CONF_ERROR; > } > > if (ngx_ssl_crl(cf, &conf->ssl, &conf->crl) != NGX_OK) { > return NGX_CONF_ERROR; > } > > - if (conf->prefer_server_ciphers) { > - SSL_CTX_set_options(conf->ssl.ctx, SSL_OP_CIPHER_SERVER_PREFERENCE); > - } > - > #if (OPENSSL_VERSION_NUMBER < 0x10100001L && !defined LIBRESSL_VERSION_NUMBER) > /* a temporary 512-bit RSA key is required for export versions of MSIE */ > SSL_CTX_set_tmp_rsa_callback(conf->ssl.ctx, ngx_ssl_rsa512_key_callback); > #endif And here is another candidate for the move to the function. [...] -- Maxim Dounin http://nginx.org/ From serg.brester at sebres.de Wed Jun 15 17:08:27 2016 From: serg.brester at sebres.de (Sergey Brester) Date: Wed, 15 Jun 2016 19:08:27 +0200 Subject: [BF] slab init + http file cache fixes In-Reply-To: <20160615155452.GL36620@mdounin.ru> References: <7a429ee385267d07ccf44d49e6fd230a@sebres.de> <90d675c425386f7ffdd6139b4d55834e@sebres.de> <20160615155452.GL36620@mdounin.ru> Message-ID: <35d7ab4c44e63f61cfb723b4a0985c62@sebres.de> > Hello! > > On Wed, Jun 15, 2016 at 01:53:31PM +0200, Sergey Brester wrote: > > Thanks, looks like another win32-related problem. Hmm... Grrr... > This should be two separate patches. Ok > Not sure it's a good idea to reuse min_uses return code here. I > would rather not. Otherwise the cacheable requests will fail, just while the zone don't get a free node (as long as scarce). Because in other respects I do not understand why in other scarce cases "ngx_http_file_cache_open" will return NGX_HTTP_CACHE_SCARCE and continue processing of the request. ... > The condition added looks wrong: fcn->deleting cannot be set > here, as it's only set by this function under lock, and > fcn->count++ here will prevent the function from being called > again. > > As far as I understand, you are trying to change processing of the > race which happens if the node in question is grabbed by another > request while the file is being deleted (fcn->count != 0 at > the function end). Please explain what you are trying to chanage > and how it's expected to affect various cases possible. Do you really understand what the race condition means? And you see a pair lines bellow an ngx_shmtx_unlock for pool, so the second worker can wins and goes this block again? I can only add, that without this fix I had observed: 1) negative value of "cache->sh->size", what evidence, that the count of increment is fewer as decrement (same response length, so always the same "fcn->fs_size" and no cache update); 2) sporadically errors by deleting of cache files; > + goto done; > ... > This change looks unrelated. If you think it's needed, please > explain the reasons. But sure. Otherwise in many cases (e.g. case of scarce) the value of "cache->files" will be incremented (with ++cache->files). > See above, the description doesn't match style and doesn't > describe that this is a win32 problem. I would be not so sure by win32. At least the code is very strange and error-prone (for example if tomorrow some child processes will be not forked and not executed stub initialization... > ngx_slab_core_init ... > I can't say I like the name, but I have no better suggestions. What thus you want to tell me? > ... > This test is useless with the new logic you've introduced. > ... > This call is useless with the new logic you've introduced. Both are done if someone uses slab module as API (as module pure outside nginx process), so not required to call ngx_slab_core_init extra. But I can remove it if disturbing (I wanted to leave it just because this one will be called once per process). ---- BTW. I've always the same questions if I look how some people take contributions: Why such people often assume, that: - in contrast to them, the contributor have all the time in the world (e.g. to revise and resend an update again and again)? - do us a favor, if they assume the commit? - think to be the power holder of the project, that is an open source project, that in the meantime the community of the whole world has (co-)developed? - they are always smarter than those who have found the bug and fixed it? Merely as the signal to cogitate... From hongzhidao at gmail.com Wed Jun 15 17:28:36 2016 From: hongzhidao at gmail.com (=?UTF-8?B?5rSq5b+X6YGT?=) Date: Thu, 16 Jun 2016 01:28:36 +0800 Subject: [nginx] dso In-Reply-To: <6BEEE0A6-BBB6-4F7D-A65E-99C1D7406F31@sysoev.ru> References: <951F36D8-94DC-43E5-85D3-30AAA4EAA538@sysoev.ru> <05EE205C-457A-466C-A286-22EA54B15A3D@sysoev.ru> <6BEEE0A6-BBB6-4F7D-A65E-99C1D7406F31@sysoev.ru> Message-ID: Hi, Assume Now it runs well, then I change nginx source code, should I compile the module files again? It seems It will get wrong when new nginx rpm run together with old so files. Thanks! B.R. 2016-04-28 3:02 GMT+08:00 Igor Sysoev : > On 27 Apr 2016, at 19:32, ??? wrote: > > Get. > In production, there may be some possibility with load_module directive. > 1. add new module: load_module modules/some_module.so; [?] > 2. remove exist load_module directive, just comment out. [?] > 3. directive not changed but the so file changed. [kill -USR2 `cat > nginx.pid`; sleep 2; kill -QUIT `cat nginx.pid.oldbin`] > And how to deal with? > > > USR2/QUIT is online binary upgrade procedure: > http://nginx.org/en/docs/control.html#upgrade > And this procedure should be used to change and to unload modules. > > > -- > Igor Sysoev > http://nginx.com > > 2016-04-28 0:08 GMT+08:00 Igor Sysoev : > >> On 27 Apr 2016, at 18:51, ??? wrote: >> >> Thanks for your reply. >> >> Is it the only way to solve the problem? >> >> >> This is a way to reload a module in production without >> service interruption. >> >> I think it will be common that developers try to use dso instead of >> static module. >> >> >> Developers can simply stop and start nginx again. >> >> -- >> Igor Sysoev >> http://nginx.com >> >> Nginx offical site points out we could load in so modules using reload or >> restart, but it seems forget to instruct the details about reload. >> And it's a great design, thanks again. >> >> 2016-04-27 19:22 GMT+08:00 Igor Sysoev : >> >>> On 27 Apr 2016, at 12:10, ??? wrote: >>> >>> Hi, >>> >>> for example following config: >>> >>> daemon on; >>> ... >>> load_module modules/ngx_http_test_module.so; >>> ... >>> >>> > start nginx >>> > change ngx_http_test_module.c, then regenerate so file >>> > kill -HUP pid >>> >>> I found nginx still run the old so file (load first time), and how to >>> work with new so file? >>> >>> I tried .../sbin/nginx -s reload, It works as I expected. It seems there >>> is some differences in 'kill -HUP' and 'sbin/nginx -s reload?; >>> >>> >>> kill -USR2 `cat nginx.pid`; sleep 2; kill -QUIT `cat nginx.pid.oldbin` >>> >>> >>> -- >>> Igor Sysoev >>> http://nginx.com >>> >> >> >> _______________________________________________ >> nginx-devel mailing list >> nginx-devel at nginx.org >> http://mailman.nginx.org/mailman/listinfo/nginx-devel >> > > _______________________________________________ > nginx-devel mailing list > nginx-devel at nginx.org > http://mailman.nginx.org/mailman/listinfo/nginx-devel > > > > _______________________________________________ > nginx-devel mailing list > nginx-devel at nginx.org > http://mailman.nginx.org/mailman/listinfo/nginx-devel > -------------- next part -------------- An HTML attachment was scrubbed... URL: From tim at timtaubert.de Wed Jun 15 17:51:25 2016 From: tim at timtaubert.de (Tim Taubert) Date: Wed, 15 Jun 2016 18:51:25 +0100 Subject: [PATCH] Add ngx_ssl_ciphers() to set list of cipher suites in openssl module In-Reply-To: <20160615165707.GN36620@mdounin.ru> References: <575A96C8.8000403@timtaubert.de> <20160614172437.GJ36620@mdounin.ru> <5761143A.50705@timtaubert.de> <20160615093659.GC77155@lo0.su> <5761236D.4000400@timtaubert.de> <20160615165707.GN36620@mdounin.ru> Message-ID: <5761959D.9010400@timtaubert.de> Maxim Dounin wrote: > This is not going to work, as ngx_conf_t does not have the > prefer_server_ciphers in it: > > src/event/ngx_event_openssl.c:604:13: error: no member named > 'prefer_server_ciphers' in 'struct ngx_conf_s' > if (cf->prefer_server_ciphers) { > ~~ ^ > 1 error generated. Sorry, I actually built it locally but forgot to remove a local modification that excluded the file, and so I didn't see the error. > You have pass the prefer_server_ciphers value as a function > argument, much like "ciphers". Done. >> @@ -725,20 +719,16 @@ ngx_http_ssl_merge_srv_conf(ngx_conf_t * >> { >> return NGX_CONF_ERROR; >> } >> >> if (ngx_ssl_crl(cf, &conf->ssl, &conf->crl) != NGX_OK) { >> return NGX_CONF_ERROR; >> } >> >> - if (conf->prefer_server_ciphers) { >> - SSL_CTX_set_options(conf->ssl.ctx, SSL_OP_CIPHER_SERVER_PREFERENCE); >> - } >> - >> #if (OPENSSL_VERSION_NUMBER < 0x10100001L && !defined LIBRESSL_VERSION_NUMBER) >> /* a temporary 512-bit RSA key is required for export versions of MSIE */ >> SSL_CTX_set_tmp_rsa_callback(conf->ssl.ctx, ngx_ssl_rsa512_key_callback); >> #endif > > And here is another candidate for the move to the function. Indeed, done. # HG changeset patch # User Tim Taubert # Date 1466012923 -3600 # Wed Jun 15 18:48:43 2016 +0100 # Node ID 2a1e1a1d88c225770bdac64b59688a5129ce8cba # Parent 1064ea81ed3aabb8ad422ffcc60ddcde667022ac SSL: ngx_ssl_ciphers() to set list of ciphers. This patch replaces all calls to SSL_CTX_set_cipher_list() with ngx_ssl_ciphers() to make nginx more crypto-library-agnostic. diff --git a/src/event/ngx_event_openssl.c b/src/event/ngx_event_openssl.c --- a/src/event/ngx_event_openssl.c +++ b/src/event/ngx_event_openssl.c @@ -18,16 +18,18 @@ typedef struct { } ngx_openssl_conf_t; static int ngx_ssl_password_callback(char *buf, int size, int rwflag, void *userdata); static int ngx_ssl_verify_callback(int ok, X509_STORE_CTX *x509_store); static void ngx_ssl_info_callback(const ngx_ssl_conn_t *ssl_conn, int where, int ret); +RSA *ngx_ssl_rsa512_key_callback(ngx_ssl_conn_t *ssl_conn, int is_export, + int key_length); static void ngx_ssl_passwords_cleanup(void *data); static void ngx_ssl_handshake_handler(ngx_event_t *ev); static ngx_int_t ngx_ssl_handle_recv(ngx_connection_t *c, int n); static void ngx_ssl_write_handler(ngx_event_t *wev); static void ngx_ssl_read_handler(ngx_event_t *rev); static void ngx_ssl_shutdown_handler(ngx_event_t *ev); static void ngx_ssl_connection_error(ngx_connection_t *c, int sslerr, ngx_err_t err, char *text); @@ -587,16 +589,40 @@ ngx_ssl_password_callback(char *buf, int ngx_memcpy(buf, pwd->data, size); return size; } ngx_int_t +ngx_ssl_ciphers(ngx_conf_t *cf, ngx_ssl_t *ssl, ngx_str_t *ciphers, + ngx_flag_t prefer_server_ciphers) +{ + if (SSL_CTX_set_cipher_list(ssl->ctx, (char *) ciphers->data) == 0) { + ngx_ssl_error(NGX_LOG_EMERG, ssl->log, 0, + "SSL_CTX_set_cipher_list(\"%V\") failed", + ciphers); + return NGX_ERROR; + } + + if (prefer_server_ciphers) { + SSL_CTX_set_options(ssl->ctx, SSL_OP_CIPHER_SERVER_PREFERENCE); + } + +#if (OPENSSL_VERSION_NUMBER < 0x10100001L && !defined LIBRESSL_VERSION_NUMBER) + /* a temporary 512-bit RSA key is required for export versions of MSIE */ + SSL_CTX_set_tmp_rsa_callback(conf->ssl.ctx, ngx_ssl_rsa512_key_callback); +#endif + + return NGX_OK; +} + + +ngx_int_t ngx_ssl_client_certificate(ngx_conf_t *cf, ngx_ssl_t *ssl, ngx_str_t *cert, ngx_int_t depth) { STACK_OF(X509_NAME) *list; SSL_CTX_set_verify(ssl->ctx, SSL_VERIFY_PEER, ngx_ssl_verify_callback); SSL_CTX_set_verify_depth(ssl->ctx, depth); diff --git a/src/event/ngx_event_openssl.h b/src/event/ngx_event_openssl.h --- a/src/event/ngx_event_openssl.h +++ b/src/event/ngx_event_openssl.h @@ -139,27 +139,27 @@ typedef struct { ngx_int_t ngx_ssl_init(ngx_log_t *log); ngx_int_t ngx_ssl_create(ngx_ssl_t *ssl, ngx_uint_t protocols, void *data); ngx_int_t ngx_ssl_certificates(ngx_conf_t *cf, ngx_ssl_t *ssl, ngx_array_t *certs, ngx_array_t *keys, ngx_array_t *passwords); ngx_int_t ngx_ssl_certificate(ngx_conf_t *cf, ngx_ssl_t *ssl, ngx_str_t *cert, ngx_str_t *key, ngx_array_t *passwords); +ngx_int_t ngx_ssl_ciphers(ngx_conf_t *cf, ngx_ssl_t *ssl, ngx_str_t *ciphers, + ngx_flag_t prefer_server_ciphers); ngx_int_t ngx_ssl_client_certificate(ngx_conf_t *cf, ngx_ssl_t *ssl, ngx_str_t *cert, ngx_int_t depth); ngx_int_t ngx_ssl_trusted_certificate(ngx_conf_t *cf, ngx_ssl_t *ssl, ngx_str_t *cert, ngx_int_t depth); ngx_int_t ngx_ssl_crl(ngx_conf_t *cf, ngx_ssl_t *ssl, ngx_str_t *crl); ngx_int_t ngx_ssl_stapling(ngx_conf_t *cf, ngx_ssl_t *ssl, ngx_str_t *file, ngx_str_t *responder, ngx_uint_t verify); ngx_int_t ngx_ssl_stapling_resolver(ngx_conf_t *cf, ngx_ssl_t *ssl, ngx_resolver_t *resolver, ngx_msec_t resolver_timeout); -RSA *ngx_ssl_rsa512_key_callback(ngx_ssl_conn_t *ssl_conn, int is_export, - int key_length); ngx_array_t *ngx_ssl_read_password_file(ngx_conf_t *cf, ngx_str_t *file); ngx_int_t ngx_ssl_dhparam(ngx_conf_t *cf, ngx_ssl_t *ssl, ngx_str_t *file); ngx_int_t ngx_ssl_ecdh_curve(ngx_conf_t *cf, ngx_ssl_t *ssl, ngx_str_t *name); ngx_int_t ngx_ssl_session_cache(ngx_ssl_t *ssl, ngx_str_t *sess_ctx, ssize_t builtin_session_cache, ngx_shm_zone_t *shm_zone, time_t timeout); ngx_int_t ngx_ssl_session_ticket_keys(ngx_conf_t *cf, ngx_ssl_t *ssl, ngx_array_t *paths); ngx_int_t ngx_ssl_session_cache_init(ngx_shm_zone_t *shm_zone, void *data); diff --git a/src/http/modules/ngx_http_proxy_module.c b/src/http/modules/ngx_http_proxy_module.c --- a/src/http/modules/ngx_http_proxy_module.c +++ b/src/http/modules/ngx_http_proxy_module.c @@ -4318,23 +4318,20 @@ ngx_http_proxy_set_ssl(ngx_conf_t *cf, n if (ngx_ssl_certificate(cf, plcf->upstream.ssl, &plcf->ssl_certificate, &plcf->ssl_certificate_key, plcf->ssl_passwords) != NGX_OK) { return NGX_ERROR; } } - if (SSL_CTX_set_cipher_list(plcf->upstream.ssl->ctx, - (const char *) plcf->ssl_ciphers.data) - == 0) + if (ngx_ssl_ciphers(cf, plcf->upstream.ssl, &plcf->ssl_ciphers, + NGX_CONF_UNSET) + != NGX_OK) { - ngx_ssl_error(NGX_LOG_EMERG, cf->log, 0, - "SSL_CTX_set_cipher_list(\"%V\") failed", - &plcf->ssl_ciphers); return NGX_ERROR; } if (plcf->upstream.ssl_verify) { if (plcf->ssl_trusted_certificate.len == 0) { ngx_log_error(NGX_LOG_EMERG, cf->log, 0, "no proxy_ssl_trusted_certificate for proxy_ssl_verify"); return NGX_ERROR; diff --git a/src/http/modules/ngx_http_ssl_module.c b/src/http/modules/ngx_http_ssl_module.c --- a/src/http/modules/ngx_http_ssl_module.c +++ b/src/http/modules/ngx_http_ssl_module.c @@ -684,23 +684,20 @@ ngx_http_ssl_merge_srv_conf(ngx_conf_t * if (ngx_ssl_certificates(cf, &conf->ssl, conf->certificates, conf->certificate_keys, conf->passwords) != NGX_OK) { return NGX_CONF_ERROR; } - if (SSL_CTX_set_cipher_list(conf->ssl.ctx, - (const char *) conf->ciphers.data) - == 0) + if (ngx_ssl_ciphers(cf, &conf->ssl, &conf->ciphers, + conf->prefer_server_ciphers) + != NGX_OK) { - ngx_ssl_error(NGX_LOG_EMERG, cf->log, 0, - "SSL_CTX_set_cipher_list(\"%V\") failed", - &conf->ciphers); return NGX_CONF_ERROR; } conf->ssl.buffer_size = conf->buffer_size; if (conf->verify) { if (conf->client_certificate.len == 0 && conf->verify != 3) { @@ -725,25 +722,16 @@ ngx_http_ssl_merge_srv_conf(ngx_conf_t * { return NGX_CONF_ERROR; } if (ngx_ssl_crl(cf, &conf->ssl, &conf->crl) != NGX_OK) { return NGX_CONF_ERROR; } - if (conf->prefer_server_ciphers) { - SSL_CTX_set_options(conf->ssl.ctx, SSL_OP_CIPHER_SERVER_PREFERENCE); - } - -#if (OPENSSL_VERSION_NUMBER < 0x10100001L && !defined LIBRESSL_VERSION_NUMBER) - /* a temporary 512-bit RSA key is required for export versions of MSIE */ - SSL_CTX_set_tmp_rsa_callback(conf->ssl.ctx, ngx_ssl_rsa512_key_callback); -#endif - if (ngx_ssl_dhparam(cf, &conf->ssl, &conf->dhparam) != NGX_OK) { return NGX_CONF_ERROR; } if (ngx_ssl_ecdh_curve(cf, &conf->ssl, &conf->ecdh_curve) != NGX_OK) { return NGX_CONF_ERROR; } diff --git a/src/http/modules/ngx_http_uwsgi_module.c b/src/http/modules/ngx_http_uwsgi_module.c --- a/src/http/modules/ngx_http_uwsgi_module.c +++ b/src/http/modules/ngx_http_uwsgi_module.c @@ -2320,23 +2320,20 @@ ngx_http_uwsgi_set_ssl(ngx_conf_t *cf, n if (ngx_ssl_certificate(cf, uwcf->upstream.ssl, &uwcf->ssl_certificate, &uwcf->ssl_certificate_key, uwcf->ssl_passwords) != NGX_OK) { return NGX_ERROR; } } - if (SSL_CTX_set_cipher_list(uwcf->upstream.ssl->ctx, - (const char *) uwcf->ssl_ciphers.data) - == 0) + if (ngx_ssl_ciphers(cf, uwcf->upstream.ssl, &uwcf->ssl_ciphers, + NGX_CONF_UNSET) + != NGX_OK) { - ngx_ssl_error(NGX_LOG_EMERG, cf->log, 0, - "SSL_CTX_set_cipher_list(\"%V\") failed", - &uwcf->ssl_ciphers); return NGX_ERROR; } if (uwcf->upstream.ssl_verify) { if (uwcf->ssl_trusted_certificate.len == 0) { ngx_log_error(NGX_LOG_EMERG, cf->log, 0, "no uwsgi_ssl_trusted_certificate for uwsgi_ssl_verify"); return NGX_ERROR; diff --git a/src/mail/ngx_mail_ssl_module.c b/src/mail/ngx_mail_ssl_module.c --- a/src/mail/ngx_mail_ssl_module.c +++ b/src/mail/ngx_mail_ssl_module.c @@ -417,34 +417,23 @@ ngx_mail_ssl_merge_conf(ngx_conf_t *cf, return NGX_CONF_ERROR; } if (ngx_ssl_crl(cf, &conf->ssl, &conf->crl) != NGX_OK) { return NGX_CONF_ERROR; } } - if (SSL_CTX_set_cipher_list(conf->ssl.ctx, - (const char *) conf->ciphers.data) - == 0) + if (ngx_ssl_ciphers(cf, &conf->ssl, &conf->ciphers, + conf->prefer_server_ciphers) + != NGX_OK) { - ngx_ssl_error(NGX_LOG_EMERG, cf->log, 0, - "SSL_CTX_set_cipher_list(\"%V\") failed", - &conf->ciphers); return NGX_CONF_ERROR; } - if (conf->prefer_server_ciphers) { - SSL_CTX_set_options(conf->ssl.ctx, SSL_OP_CIPHER_SERVER_PREFERENCE); - } - -#if (OPENSSL_VERSION_NUMBER < 0x10100001L && !defined LIBRESSL_VERSION_NUMBER) - SSL_CTX_set_tmp_rsa_callback(conf->ssl.ctx, ngx_ssl_rsa512_key_callback); -#endif - if (ngx_ssl_dhparam(cf, &conf->ssl, &conf->dhparam) != NGX_OK) { return NGX_CONF_ERROR; } if (ngx_ssl_ecdh_curve(cf, &conf->ssl, &conf->ecdh_curve) != NGX_OK) { return NGX_CONF_ERROR; } diff --git a/src/stream/ngx_stream_proxy_module.c b/src/stream/ngx_stream_proxy_module.c --- a/src/stream/ngx_stream_proxy_module.c +++ b/src/stream/ngx_stream_proxy_module.c @@ -1635,23 +1635,17 @@ ngx_stream_proxy_set_ssl(ngx_conf_t *cf, if (ngx_ssl_certificate(cf, pscf->ssl, &pscf->ssl_certificate, &pscf->ssl_certificate_key, pscf->ssl_passwords) != NGX_OK) { return NGX_ERROR; } } - if (SSL_CTX_set_cipher_list(pscf->ssl->ctx, - (const char *) pscf->ssl_ciphers.data) - == 0) - { - ngx_ssl_error(NGX_LOG_EMERG, cf->log, 0, - "SSL_CTX_set_cipher_list(\"%V\") failed", - &pscf->ssl_ciphers); + if (ngx_ssl_ciphers(cf, pscf->ssl, &pscf->ssl_ciphers) != NGX_OK) { return NGX_ERROR; } if (pscf->ssl_verify) { if (pscf->ssl_trusted_certificate.len == 0) { ngx_log_error(NGX_LOG_EMERG, cf->log, 0, "no proxy_ssl_trusted_certificate for proxy_ssl_verify"); return NGX_ERROR; diff --git a/src/stream/ngx_stream_ssl_module.c b/src/stream/ngx_stream_ssl_module.c --- a/src/stream/ngx_stream_ssl_module.c +++ b/src/stream/ngx_stream_ssl_module.c @@ -261,34 +261,23 @@ ngx_stream_ssl_merge_conf(ngx_conf_t *cf if (ngx_ssl_certificates(cf, &conf->ssl, conf->certificates, conf->certificate_keys, conf->passwords) != NGX_OK) { return NGX_CONF_ERROR; } - if (SSL_CTX_set_cipher_list(conf->ssl.ctx, - (const char *) conf->ciphers.data) - == 0) + if (ngx_ssl_ciphers(cf, &conf->ssl, &conf->ciphers, + conf->prefer_server_ciphers) + != NGX_OK) { - ngx_ssl_error(NGX_LOG_EMERG, cf->log, 0, - "SSL_CTX_set_cipher_list(\"%V\") failed", - &conf->ciphers); return NGX_CONF_ERROR; } - if (conf->prefer_server_ciphers) { - SSL_CTX_set_options(conf->ssl.ctx, SSL_OP_CIPHER_SERVER_PREFERENCE); - } - -#if (OPENSSL_VERSION_NUMBER < 0x10100001L && !defined LIBRESSL_VERSION_NUMBER) - SSL_CTX_set_tmp_rsa_callback(conf->ssl.ctx, ngx_ssl_rsa512_key_callback); -#endif - if (ngx_ssl_dhparam(cf, &conf->ssl, &conf->dhparam) != NGX_OK) { return NGX_CONF_ERROR; } if (ngx_ssl_ecdh_curve(cf, &conf->ssl, &conf->ecdh_curve) != NGX_OK) { return NGX_CONF_ERROR; } From mdounin at mdounin.ru Wed Jun 15 18:52:48 2016 From: mdounin at mdounin.ru (Maxim Dounin) Date: Wed, 15 Jun 2016 21:52:48 +0300 Subject: [BF] slab init + http file cache fixes In-Reply-To: <35d7ab4c44e63f61cfb723b4a0985c62@sebres.de> References: <7a429ee385267d07ccf44d49e6fd230a@sebres.de> <90d675c425386f7ffdd6139b4d55834e@sebres.de> <20160615155452.GL36620@mdounin.ru> <35d7ab4c44e63f61cfb723b4a0985c62@sebres.de> Message-ID: <20160615185248.GO36620@mdounin.ru> Hello! On Wed, Jun 15, 2016 at 07:08:27PM +0200, Sergey Brester wrote: > >Not sure it's a good idea to reuse min_uses return code here. I > >would rather not. > > Otherwise the cacheable requests will fail, just while the zone don't get a > free node (as long as scarce). > Because in other respects I do not understand why in other scarce cases > "ngx_http_file_cache_open" will return NGX_HTTP_CACHE_SCARCE and continue > processing of the request. The NGX_HTTP_CACHE_SCARCE is intended to signal to the caller that min_uses was not yet reached, and that's why the request will not use cache. And that's the only case where NGX_HTTP_CACHE_SCARCE is used. Semantics of the error case your are trying to add here is quite different. This will be an immediate problem if/when we'll add appropriate $upstream_cache_status value for SCARCE. (Moreover, I'm not really sure this needs fixing at all, as since version 1.9.13 cache manger monitors number of elements in the cache and tries to avoid cache zone overflows. That is, overflows are not expected to happen often.) > >The condition added looks wrong: fcn->deleting cannot be set > >here, as it's only set by this function under lock, and > >fcn->count++ here will prevent the function from being called > >again. > > > >As far as I understand, you are trying to change processing of the > >race which happens if the node in question is grabbed by another > >request while the file is being deleted (fcn->count != 0 at > >the function end). Please explain what you are trying to chanage > >and how it's expected to affect various cases possible. > > Do you really understand what the race condition means? And you see a pair > lines bellow an ngx_shmtx_unlock for pool, so the second worker can wins and > goes this block again? > > I can only add, that without this fix I had observed: > 1) negative value of "cache->sh->size", what evidence, that the count of > increment is fewer as decrement (same response length, so always the same > "fcn->fs_size" and no cache update); > 2) sporadically errors by deleting of cache files; Race condition here is intended: we are dropping the lock to prevent lock contention during a potentially long syscall. It is expected that in some cases another worker will be able to grab the node, and this will prevent its complete removal. But there is more than one case possible: e.g., another worker can grab the node and put an updated file into it before the file will be deleted, and as a result we'll delete different file here. The question is: what is the case you are trying to improve, and what it means for other possible cases. > >+ goto done; > >... > >This change looks unrelated. If you think it's needed, please > >explain the reasons. > > But sure. Otherwise in many cases (e.g. case of scarce) the value of > "cache->files" will be incremented (with ++cache->files). The "cache->files" is used to count number of files processed by the cache loader. When it reaches loader_files, cache loader will sleep for a while. There is nothing wrong that it is incremented - as the file was processed, it should be incremented. With the change in question cache loader won't be able to properly respect loader_files and loader_threshold, making it use all available resources in case of errors. > >See above, the description doesn't match style and doesn't > >describe that this is a win32 problem. > > I would be not so sure by win32. At least the code is very strange and > error-prone (for example if tomorrow some child processes will be not forked > and not executed stub initialization... If you think this problem can be seen on other platforms - feel free to point them out as well. > >ngx_slab_core_init ... > >I can't say I like the name, but I have no better suggestions. > > What thus you want to tell me? If you can suggest a better name - please do so. > >... > >This test is useless with the new logic you've introduced. > >... > >This call is useless with the new logic you've introduced. > > Both are done if someone uses slab module as API (as module pure outside > nginx process), so not required to call ngx_slab_core_init extra. > But I can remove it if disturbing (I wanted to leave it just because this > one will be called once per process). We certainly don't want to try to preserve compatibility with someone who in theory can use slab code outside of nginx. If somebody really does so, it can add appropriate initialization. > BTW. I've always the same questions if I look how some people take > contributions: > > Why such people often assume, that: > - in contrast to them, the contributor have all the time in the world > (e.g. to revise and resend an update again and again)? > - do us a favor, if they assume the commit? > - think to be the power holder of the project, that is an open source > project, > that in the meantime the community of the whole world has > (co-)developed? > - they are always smarter than those who have found the bug and fixed it? > > Merely as the signal to cogitate... You may find this article interesting: http://blog.flaper87.org/post/opensource-owes-you-everything-and-nothing/ -- Maxim Dounin http://nginx.org/ From mdounin at mdounin.ru Wed Jun 15 19:45:21 2016 From: mdounin at mdounin.ru (Maxim Dounin) Date: Wed, 15 Jun 2016 22:45:21 +0300 Subject: [PATCH] Add ngx_ssl_ciphers() to set list of cipher suites in openssl module In-Reply-To: <5761959D.9010400@timtaubert.de> References: <575A96C8.8000403@timtaubert.de> <20160614172437.GJ36620@mdounin.ru> <5761143A.50705@timtaubert.de> <20160615093659.GC77155@lo0.su> <5761236D.4000400@timtaubert.de> <20160615165707.GN36620@mdounin.ru> <5761959D.9010400@timtaubert.de> Message-ID: <20160615194521.GP36620@mdounin.ru> Hello! On Wed, Jun 15, 2016 at 06:51:25PM +0100, Tim Taubert wrote: > # HG changeset patch > # User Tim Taubert > # Date 1466012923 -3600 > # Wed Jun 15 18:48:43 2016 +0100 > # Node ID 2a1e1a1d88c225770bdac64b59688a5129ce8cba > # Parent 1064ea81ed3aabb8ad422ffcc60ddcde667022ac > SSL: ngx_ssl_ciphers() to set list of ciphers. > > This patch replaces all calls to SSL_CTX_set_cipher_list() with > ngx_ssl_ciphers() to make nginx more crypto-library-agnostic. > > diff --git a/src/event/ngx_event_openssl.c b/src/event/ngx_event_openssl.c > --- a/src/event/ngx_event_openssl.c > +++ b/src/event/ngx_event_openssl.c > @@ -18,16 +18,18 @@ typedef struct { > } ngx_openssl_conf_t; > > > static int ngx_ssl_password_callback(char *buf, int size, int rwflag, > void *userdata); > static int ngx_ssl_verify_callback(int ok, X509_STORE_CTX *x509_store); > static void ngx_ssl_info_callback(const ngx_ssl_conn_t *ssl_conn, int where, > int ret); > +RSA *ngx_ssl_rsa512_key_callback(ngx_ssl_conn_t *ssl_conn, int is_export, > + int key_length); Moving the function here will need "static". You may also want to preserve it as is in the ngx_event_openssl.h for now, for compatibility with 3rd party modules using it, if any. Though I've failed to find any module potentially affected by the change, so it's up to you. [...] > @@ -587,16 +589,40 @@ ngx_ssl_password_callback(char *buf, int > > ngx_memcpy(buf, pwd->data, size); > > return size; > } > > > ngx_int_t > +ngx_ssl_ciphers(ngx_conf_t *cf, ngx_ssl_t *ssl, ngx_str_t *ciphers, > + ngx_flag_t prefer_server_ciphers) Please use "ngx_uint_t" here instead. The "ngx_flag_t" type is used during configuration parsing, and not expected to have any ngx_flag_t-specific values at the point where ngx_ssl_ciphers() is called. [...] > diff --git a/src/http/modules/ngx_http_proxy_module.c b/src/http/modules/ngx_http_proxy_module.c > --- a/src/http/modules/ngx_http_proxy_module.c > +++ b/src/http/modules/ngx_http_proxy_module.c > @@ -4318,23 +4318,20 @@ ngx_http_proxy_set_ssl(ngx_conf_t *cf, n > if (ngx_ssl_certificate(cf, plcf->upstream.ssl, &plcf->ssl_certificate, > &plcf->ssl_certificate_key, plcf->ssl_passwords) > != NGX_OK) > { > return NGX_ERROR; > } > } > > - if (SSL_CTX_set_cipher_list(plcf->upstream.ssl->ctx, > - (const char *) plcf->ssl_ciphers.data) > - == 0) > + if (ngx_ssl_ciphers(cf, plcf->upstream.ssl, &plcf->ssl_ciphers, > + NGX_CONF_UNSET) The NGX_CONF_UNSET here looks wrong and will quite unexpectedly try to set SSL_OP_CIPHER_SERVER_PREFERENCE (it means nothing on client side, but nevertheless somewhat confusing). Just using 0 will be a better idea. [...] -- Maxim Dounin http://nginx.org/ From tim at timtaubert.de Wed Jun 15 20:08:58 2016 From: tim at timtaubert.de (Tim Taubert) Date: Wed, 15 Jun 2016 21:08:58 +0100 Subject: [PATCH] Add ngx_ssl_ciphers() to set list of cipher suites in openssl module In-Reply-To: <20160615194521.GP36620@mdounin.ru> References: <575A96C8.8000403@timtaubert.de> <20160614172437.GJ36620@mdounin.ru> <5761143A.50705@timtaubert.de> <20160615093659.GC77155@lo0.su> <5761236D.4000400@timtaubert.de> <20160615165707.GN36620@mdounin.ru> <5761959D.9010400@timtaubert.de> <20160615194521.GP36620@mdounin.ru> Message-ID: <5761B5DA.3000009@timtaubert.de> (Thanks for all your comments.) Maxim Dounin wrote: >> +RSA *ngx_ssl_rsa512_key_callback(ngx_ssl_conn_t *ssl_conn, int is_export, >> + int key_length); > > Moving the function here will need "static". > > You may also want to preserve it as is in the ngx_event_openssl.h > for now, for compatibility with 3rd party modules using it, if > any. Though I've failed to find any module potentially affected > by the change, so it's up to you. Right, I reverted that change and left the declaration in ngx_event_openssl.h. >> ngx_int_t >> +ngx_ssl_ciphers(ngx_conf_t *cf, ngx_ssl_t *ssl, ngx_str_t *ciphers, >> + ngx_flag_t prefer_server_ciphers) > > Please use "ngx_uint_t" here instead. The "ngx_flag_t" type > is used during configuration parsing, and not expected to have any > ngx_flag_t-specific values at the point where ngx_ssl_ciphers() is > called. Done. >> - if (SSL_CTX_set_cipher_list(plcf->upstream.ssl->ctx, >> - (const char *) plcf->ssl_ciphers.data) >> - == 0) >> + if (ngx_ssl_ciphers(cf, plcf->upstream.ssl, &plcf->ssl_ciphers, >> + NGX_CONF_UNSET) > > The NGX_CONF_UNSET here looks wrong and will quite unexpectedly > try to set SSL_OP_CIPHER_SERVER_PREFERENCE (it means nothing on > client side, but nevertheless somewhat confusing). Just using 0 > will be a better idea. Done. # HG changeset patch # User Tim Taubert # Date 1466021130 -3600 # Wed Jun 15 21:05:30 2016 +0100 # Node ID 42ec0b0933f637da2a4a3a17146eb9c7347fa02c # Parent 1064ea81ed3aabb8ad422ffcc60ddcde667022ac SSL: ngx_ssl_ciphers() to set list of ciphers. This patch moves various OpenSSL-specific function calls into the OpenSSL module and introduces ngx_ssl_ciphers() to make nginx more crypto-library-agnostic. diff --git a/src/event/ngx_event_openssl.c b/src/event/ngx_event_openssl.c --- a/src/event/ngx_event_openssl.c +++ b/src/event/ngx_event_openssl.c @@ -587,16 +587,40 @@ ngx_ssl_password_callback(char *buf, int ngx_memcpy(buf, pwd->data, size); return size; } ngx_int_t +ngx_ssl_ciphers(ngx_conf_t *cf, ngx_ssl_t *ssl, ngx_str_t *ciphers, + ngx_uint_t prefer_server_ciphers) +{ + if (SSL_CTX_set_cipher_list(ssl->ctx, (char *) ciphers->data) == 0) { + ngx_ssl_error(NGX_LOG_EMERG, ssl->log, 0, + "SSL_CTX_set_cipher_list(\"%V\") failed", + ciphers); + return NGX_ERROR; + } + + if (prefer_server_ciphers) { + SSL_CTX_set_options(ssl->ctx, SSL_OP_CIPHER_SERVER_PREFERENCE); + } + +#if (OPENSSL_VERSION_NUMBER < 0x10100001L && !defined LIBRESSL_VERSION_NUMBER) + /* a temporary 512-bit RSA key is required for export versions of MSIE */ + SSL_CTX_set_tmp_rsa_callback(conf->ssl.ctx, ngx_ssl_rsa512_key_callback); +#endif + + return NGX_OK; +} + + +ngx_int_t ngx_ssl_client_certificate(ngx_conf_t *cf, ngx_ssl_t *ssl, ngx_str_t *cert, ngx_int_t depth) { STACK_OF(X509_NAME) *list; SSL_CTX_set_verify(ssl->ctx, SSL_VERIFY_PEER, ngx_ssl_verify_callback); SSL_CTX_set_verify_depth(ssl->ctx, depth); diff --git a/src/event/ngx_event_openssl.h b/src/event/ngx_event_openssl.h --- a/src/event/ngx_event_openssl.h +++ b/src/event/ngx_event_openssl.h @@ -139,16 +139,18 @@ typedef struct { ngx_int_t ngx_ssl_init(ngx_log_t *log); ngx_int_t ngx_ssl_create(ngx_ssl_t *ssl, ngx_uint_t protocols, void *data); ngx_int_t ngx_ssl_certificates(ngx_conf_t *cf, ngx_ssl_t *ssl, ngx_array_t *certs, ngx_array_t *keys, ngx_array_t *passwords); ngx_int_t ngx_ssl_certificate(ngx_conf_t *cf, ngx_ssl_t *ssl, ngx_str_t *cert, ngx_str_t *key, ngx_array_t *passwords); +ngx_int_t ngx_ssl_ciphers(ngx_conf_t *cf, ngx_ssl_t *ssl, ngx_str_t *ciphers, + ngx_uint_t prefer_server_ciphers); ngx_int_t ngx_ssl_client_certificate(ngx_conf_t *cf, ngx_ssl_t *ssl, ngx_str_t *cert, ngx_int_t depth); ngx_int_t ngx_ssl_trusted_certificate(ngx_conf_t *cf, ngx_ssl_t *ssl, ngx_str_t *cert, ngx_int_t depth); ngx_int_t ngx_ssl_crl(ngx_conf_t *cf, ngx_ssl_t *ssl, ngx_str_t *crl); ngx_int_t ngx_ssl_stapling(ngx_conf_t *cf, ngx_ssl_t *ssl, ngx_str_t *file, ngx_str_t *responder, ngx_uint_t verify); ngx_int_t ngx_ssl_stapling_resolver(ngx_conf_t *cf, ngx_ssl_t *ssl, diff --git a/src/http/modules/ngx_http_proxy_module.c b/src/http/modules/ngx_http_proxy_module.c --- a/src/http/modules/ngx_http_proxy_module.c +++ b/src/http/modules/ngx_http_proxy_module.c @@ -4318,23 +4318,19 @@ ngx_http_proxy_set_ssl(ngx_conf_t *cf, n if (ngx_ssl_certificate(cf, plcf->upstream.ssl, &plcf->ssl_certificate, &plcf->ssl_certificate_key, plcf->ssl_passwords) != NGX_OK) { return NGX_ERROR; } } - if (SSL_CTX_set_cipher_list(plcf->upstream.ssl->ctx, - (const char *) plcf->ssl_ciphers.data) - == 0) + if (ngx_ssl_ciphers(cf, plcf->upstream.ssl, &plcf->ssl_ciphers, 0) + != NGX_OK) { - ngx_ssl_error(NGX_LOG_EMERG, cf->log, 0, - "SSL_CTX_set_cipher_list(\"%V\") failed", - &plcf->ssl_ciphers); return NGX_ERROR; } if (plcf->upstream.ssl_verify) { if (plcf->ssl_trusted_certificate.len == 0) { ngx_log_error(NGX_LOG_EMERG, cf->log, 0, "no proxy_ssl_trusted_certificate for proxy_ssl_verify"); return NGX_ERROR; diff --git a/src/http/modules/ngx_http_ssl_module.c b/src/http/modules/ngx_http_ssl_module.c --- a/src/http/modules/ngx_http_ssl_module.c +++ b/src/http/modules/ngx_http_ssl_module.c @@ -684,23 +684,20 @@ ngx_http_ssl_merge_srv_conf(ngx_conf_t * if (ngx_ssl_certificates(cf, &conf->ssl, conf->certificates, conf->certificate_keys, conf->passwords) != NGX_OK) { return NGX_CONF_ERROR; } - if (SSL_CTX_set_cipher_list(conf->ssl.ctx, - (const char *) conf->ciphers.data) - == 0) + if (ngx_ssl_ciphers(cf, &conf->ssl, &conf->ciphers, + conf->prefer_server_ciphers) + != NGX_OK) { - ngx_ssl_error(NGX_LOG_EMERG, cf->log, 0, - "SSL_CTX_set_cipher_list(\"%V\") failed", - &conf->ciphers); return NGX_CONF_ERROR; } conf->ssl.buffer_size = conf->buffer_size; if (conf->verify) { if (conf->client_certificate.len == 0 && conf->verify != 3) { @@ -725,25 +722,16 @@ ngx_http_ssl_merge_srv_conf(ngx_conf_t * { return NGX_CONF_ERROR; } if (ngx_ssl_crl(cf, &conf->ssl, &conf->crl) != NGX_OK) { return NGX_CONF_ERROR; } - if (conf->prefer_server_ciphers) { - SSL_CTX_set_options(conf->ssl.ctx, SSL_OP_CIPHER_SERVER_PREFERENCE); - } - -#if (OPENSSL_VERSION_NUMBER < 0x10100001L && !defined LIBRESSL_VERSION_NUMBER) - /* a temporary 512-bit RSA key is required for export versions of MSIE */ - SSL_CTX_set_tmp_rsa_callback(conf->ssl.ctx, ngx_ssl_rsa512_key_callback); -#endif - if (ngx_ssl_dhparam(cf, &conf->ssl, &conf->dhparam) != NGX_OK) { return NGX_CONF_ERROR; } if (ngx_ssl_ecdh_curve(cf, &conf->ssl, &conf->ecdh_curve) != NGX_OK) { return NGX_CONF_ERROR; } diff --git a/src/http/modules/ngx_http_uwsgi_module.c b/src/http/modules/ngx_http_uwsgi_module.c --- a/src/http/modules/ngx_http_uwsgi_module.c +++ b/src/http/modules/ngx_http_uwsgi_module.c @@ -2320,23 +2320,19 @@ ngx_http_uwsgi_set_ssl(ngx_conf_t *cf, n if (ngx_ssl_certificate(cf, uwcf->upstream.ssl, &uwcf->ssl_certificate, &uwcf->ssl_certificate_key, uwcf->ssl_passwords) != NGX_OK) { return NGX_ERROR; } } - if (SSL_CTX_set_cipher_list(uwcf->upstream.ssl->ctx, - (const char *) uwcf->ssl_ciphers.data) - == 0) + if (ngx_ssl_ciphers(cf, uwcf->upstream.ssl, &uwcf->ssl_ciphers, 0) + != NGX_OK) { - ngx_ssl_error(NGX_LOG_EMERG, cf->log, 0, - "SSL_CTX_set_cipher_list(\"%V\") failed", - &uwcf->ssl_ciphers); return NGX_ERROR; } if (uwcf->upstream.ssl_verify) { if (uwcf->ssl_trusted_certificate.len == 0) { ngx_log_error(NGX_LOG_EMERG, cf->log, 0, "no uwsgi_ssl_trusted_certificate for uwsgi_ssl_verify"); return NGX_ERROR; diff --git a/src/mail/ngx_mail_ssl_module.c b/src/mail/ngx_mail_ssl_module.c --- a/src/mail/ngx_mail_ssl_module.c +++ b/src/mail/ngx_mail_ssl_module.c @@ -417,34 +417,23 @@ ngx_mail_ssl_merge_conf(ngx_conf_t *cf, return NGX_CONF_ERROR; } if (ngx_ssl_crl(cf, &conf->ssl, &conf->crl) != NGX_OK) { return NGX_CONF_ERROR; } } - if (SSL_CTX_set_cipher_list(conf->ssl.ctx, - (const char *) conf->ciphers.data) - == 0) + if (ngx_ssl_ciphers(cf, &conf->ssl, &conf->ciphers, + conf->prefer_server_ciphers) + != NGX_OK) { - ngx_ssl_error(NGX_LOG_EMERG, cf->log, 0, - "SSL_CTX_set_cipher_list(\"%V\") failed", - &conf->ciphers); return NGX_CONF_ERROR; } - if (conf->prefer_server_ciphers) { - SSL_CTX_set_options(conf->ssl.ctx, SSL_OP_CIPHER_SERVER_PREFERENCE); - } - -#if (OPENSSL_VERSION_NUMBER < 0x10100001L && !defined LIBRESSL_VERSION_NUMBER) - SSL_CTX_set_tmp_rsa_callback(conf->ssl.ctx, ngx_ssl_rsa512_key_callback); -#endif - if (ngx_ssl_dhparam(cf, &conf->ssl, &conf->dhparam) != NGX_OK) { return NGX_CONF_ERROR; } if (ngx_ssl_ecdh_curve(cf, &conf->ssl, &conf->ecdh_curve) != NGX_OK) { return NGX_CONF_ERROR; } diff --git a/src/stream/ngx_stream_proxy_module.c b/src/stream/ngx_stream_proxy_module.c --- a/src/stream/ngx_stream_proxy_module.c +++ b/src/stream/ngx_stream_proxy_module.c @@ -1635,23 +1635,17 @@ ngx_stream_proxy_set_ssl(ngx_conf_t *cf, if (ngx_ssl_certificate(cf, pscf->ssl, &pscf->ssl_certificate, &pscf->ssl_certificate_key, pscf->ssl_passwords) != NGX_OK) { return NGX_ERROR; } } - if (SSL_CTX_set_cipher_list(pscf->ssl->ctx, - (const char *) pscf->ssl_ciphers.data) - == 0) - { - ngx_ssl_error(NGX_LOG_EMERG, cf->log, 0, - "SSL_CTX_set_cipher_list(\"%V\") failed", - &pscf->ssl_ciphers); + if (ngx_ssl_ciphers(cf, pscf->ssl, &pscf->ssl_ciphers, 0) != NGX_OK) { return NGX_ERROR; } if (pscf->ssl_verify) { if (pscf->ssl_trusted_certificate.len == 0) { ngx_log_error(NGX_LOG_EMERG, cf->log, 0, "no proxy_ssl_trusted_certificate for proxy_ssl_verify"); return NGX_ERROR; diff --git a/src/stream/ngx_stream_ssl_module.c b/src/stream/ngx_stream_ssl_module.c --- a/src/stream/ngx_stream_ssl_module.c +++ b/src/stream/ngx_stream_ssl_module.c @@ -261,34 +261,23 @@ ngx_stream_ssl_merge_conf(ngx_conf_t *cf if (ngx_ssl_certificates(cf, &conf->ssl, conf->certificates, conf->certificate_keys, conf->passwords) != NGX_OK) { return NGX_CONF_ERROR; } - if (SSL_CTX_set_cipher_list(conf->ssl.ctx, - (const char *) conf->ciphers.data) - == 0) + if (ngx_ssl_ciphers(cf, &conf->ssl, &conf->ciphers, + conf->prefer_server_ciphers) + != NGX_OK) { - ngx_ssl_error(NGX_LOG_EMERG, cf->log, 0, - "SSL_CTX_set_cipher_list(\"%V\") failed", - &conf->ciphers); return NGX_CONF_ERROR; } - if (conf->prefer_server_ciphers) { - SSL_CTX_set_options(conf->ssl.ctx, SSL_OP_CIPHER_SERVER_PREFERENCE); - } - -#if (OPENSSL_VERSION_NUMBER < 0x10100001L && !defined LIBRESSL_VERSION_NUMBER) - SSL_CTX_set_tmp_rsa_callback(conf->ssl.ctx, ngx_ssl_rsa512_key_callback); -#endif - if (ngx_ssl_dhparam(cf, &conf->ssl, &conf->dhparam) != NGX_OK) { return NGX_CONF_ERROR; } if (ngx_ssl_ecdh_curve(cf, &conf->ssl, &conf->ecdh_curve) != NGX_OK) { return NGX_CONF_ERROR; } From mdounin at mdounin.ru Wed Jun 15 20:15:11 2016 From: mdounin at mdounin.ru (Maxim Dounin) Date: Wed, 15 Jun 2016 23:15:11 +0300 Subject: [nginx] dso In-Reply-To: References: <951F36D8-94DC-43E5-85D3-30AAA4EAA538@sysoev.ru> <05EE205C-457A-466C-A286-22EA54B15A3D@sysoev.ru> <6BEEE0A6-BBB6-4F7D-A65E-99C1D7406F31@sysoev.ru> Message-ID: <20160615201511.GQ36620@mdounin.ru> Hello! On Thu, Jun 16, 2016 at 01:28:36AM +0800, ??? wrote: > Assume Now it runs well, then I change nginx source code, should I compile > the module files again? > It seems It will get wrong when new nginx rpm run together with old so > files. Obviously enough, changes to nginx source code can introduce API and/or ABI incompatibilities and modules needs to be recompiled if it's the case. For normal users following releases, there is a version check when loading a module: nginx will check if the module was compiled for the particular nginx version, and will refuse to load the module if the version doesn't match. If you are a developer and you are doing some local changes to nginx sources - version check in question won't help (as the version stays the same) and you are responsible to recompile nginx and modules if there are any API/ABI changes introduced. -- Maxim Dounin http://nginx.org/ From shuxinyang.oss at gmail.com Wed Jun 15 20:45:44 2016 From: shuxinyang.oss at gmail.com (shuxinyang) Date: Wed, 15 Jun 2016 13:45:44 -0700 Subject: C++ module In-Reply-To: References: Message-ID: <5761BE78.9020504@gmail.com> Quite frankly, I don't know the standard way. My way to tackle this problem is to add config.make to the module like this: ======================================================== cat config.make find $ngx_addon_dir -name "*.cc" -print | while read x; do x=$(basename $x | sed 's/\.cc//') cat << __END__ >> $NGX_MAKEFILE objs/addon/mymodule/$x.o: CFLAGS += -std=c++11 __END__ done ========================================================= It is to change CFLAGS just for those *.cc of the module in question, the CFLAGS for other *.c does not change. Of course, you need to add -lstdc++ to the lib. This topic was discussed before, IIRC someone suggested to configure nginx with C++ compiler instead of C compiler. It does not work for me for at least two reasons: - there are too many warnings (e.g. c++ compiler is not happy with the implicit cast from void* to some-type*) - cannot pass c++ specific flags Thanks Shuxin On 06/15/2016 08:27 AM, Rajalakshmi Iyer wrote: > Hello, > > Just wanted to check if it is possible to write NGINX modules in C++ > that makes extensive use of the standard template library (STL)? If > so, what are the things that one needs to be careful about? > > Thanks in advance, > Raj > > > > > This email and any attachments to it may be confidential and are > intended solely for the use of the individual to whom it is addressed. > Any views or opinions expressed are solely those of the author and do > not necessarily represent those of Blis Ltd, a company registered in > England and Wales with registered number 06455773. Its registered > office is 5th Floor, 85 Tottenham Court Road, London, W1T 4TQ, United > Kingdom. > > If you are not the intended recipient of this email, you must neither > take any action based upon its contents, nor copy or show it to > anyone. Please contact the sender if you believe you have received > this email in error. > > > _______________________________________________ > nginx-devel mailing list > nginx-devel at nginx.org > http://mailman.nginx.org/mailman/listinfo/nginx-devel -------------- next part -------------- An HTML attachment was scrubbed... URL: From piotrsikora at google.com Wed Jun 15 20:49:17 2016 From: piotrsikora at google.com (Piotr Sikora) Date: Wed, 15 Jun 2016 13:49:17 -0700 Subject: C++ module In-Reply-To: References: Message-ID: Hey Raj, it is, take a look at ngx_brotli [1] and ngx_pagespeed [2]. [1] https://github.com/google/ngx_brotli [2] https://github.com/pagespeed/ngx_pagespeed Best regards, Piotr Sikora On Wed, Jun 15, 2016 at 8:27 AM, Rajalakshmi Iyer wrote: > Hello, > > Just wanted to check if it is possible to write NGINX modules in C++ that > makes extensive use of the standard template library (STL)? If so, what are > the things that one needs to be careful about? > > Thanks in advance, > Raj > > > This email and any attachments to it may be confidential and are > intended solely for the use of the individual to whom it is addressed. Any > views or opinions expressed are solely those of the author and do not > necessarily represent those of Blis Ltd, a company registered in England > and Wales with registered number 06455773. Its registered office is 5th > Floor, 85 Tottenham Court Road, London, W1T 4TQ, United Kingdom. > > If you are not the intended recipient of this email, you must neither take > any action based upon its contents, nor copy or show it to anyone. Please > contact the sender if you believe you have received this email in error. > > _______________________________________________ > nginx-devel mailing list > nginx-devel at nginx.org > http://mailman.nginx.org/mailman/listinfo/nginx-devel > -------------- next part -------------- An HTML attachment was scrubbed... URL: From hungnv at opensource.com.vn Thu Jun 16 01:31:25 2016 From: hungnv at opensource.com.vn (Hung Nguyen) Date: Thu, 16 Jun 2016 08:31:25 +0700 Subject: C++ module In-Reply-To: References: Message-ID: <737F0C28-049B-4F60-BBC1-8EE41755A590@opensource.com.vn> Hello, Nginx comes with a demo module written in C++ in source code Sent from my iPhone > On Jun 16, 2016, at 3:49 AM, Piotr Sikora wrote: > > Hey Raj, > it is, take a look at ngx_brotli [1] and ngx_pagespeed [2]. > > [1] https://github.com/google/ngx_brotli > [2] https://github.com/pagespeed/ngx_pagespeed > > Best regards, > Piotr Sikora > >> On Wed, Jun 15, 2016 at 8:27 AM, Rajalakshmi Iyer wrote: >> Hello, >> >> Just wanted to check if it is possible to write NGINX modules in C++ that makes extensive use of the standard template library (STL)? If so, what are the things that one needs to be careful about? >> >> Thanks in advance, >> Raj >> >> >> This email and any attachments to it may be confidential and are intended solely for the use of the individual to whom it is addressed. Any views or opinions expressed are solely those of the author and do not necessarily represent those of Blis Ltd, a company registered in England and Wales with registered number 06455773. Its registered office is 5th Floor, 85 Tottenham Court Road, London, W1T 4TQ, United Kingdom. >> >> If you are not the intended recipient of this email, you must neither take any action based upon its contents, nor copy or show it to anyone. Please contact the sender if you believe you have received this email in error. >> >> _______________________________________________ >> nginx-devel mailing list >> nginx-devel at nginx.org >> http://mailman.nginx.org/mailman/listinfo/nginx-devel > > _______________________________________________ > nginx-devel mailing list > nginx-devel at nginx.org > http://mailman.nginx.org/mailman/listinfo/nginx-devel -------------- next part -------------- An HTML attachment was scrubbed... URL: From rajalakshmi.iyer at blis.com Thu Jun 16 04:18:34 2016 From: rajalakshmi.iyer at blis.com (Rajalakshmi Iyer) Date: Thu, 16 Jun 2016 05:18:34 +0100 Subject: C++ module In-Reply-To: <737F0C28-049B-4F60-BBC1-8EE41755A590@opensource.com.vn> References: <737F0C28-049B-4F60-BBC1-8EE41755A590@opensource.com.vn> Message-ID: <644F3E10-2DED-4672-9221-A0DD3EAC250D@blis.com> Thanks everyone. I have been able to compile a C++ module fine. But I am primarily trying to figure out if it's safe to use features like STL containers or Boost libraries within an Nginx module. I am asking this because if I try to allocate an std::string within say the module context, I see a segmentation fault. I assume it's because of the Nginx pool mechanism? > On 16 Jun 2016, at 02:31, Hung Nguyen wrote: > > Hello, > > Nginx comes with a demo module written in C++ in source code > > Sent from my iPhone > >> On Jun 16, 2016, at 3:49 AM, Piotr Sikora wrote: >> >> Hey Raj, >> it is, take a look at ngx_brotli [1] and ngx_pagespeed [2]. >> >> [1] https://github.com/google/ngx_brotli >> [2] https://github.com/pagespeed/ngx_pagespeed >> >> Best regards, >> Piotr Sikora >> >>> On Wed, Jun 15, 2016 at 8:27 AM, Rajalakshmi Iyer wrote: >>> Hello, >>> >>> Just wanted to check if it is possible to write NGINX modules in C++ that makes extensive use of the standard template library (STL)? If so, what are the things that one needs to be careful about? >>> >>> Thanks in advance, >>> Raj >>> >>> >>> This email and any attachments to it may be confidential and are intended solely for the use of the individual to whom it is addressed. Any views or opinions expressed are solely those of the author and do not necessarily represent those of Blis Ltd, a company registered in England and Wales with registered number 06455773. Its registered office is 5th Floor, 85 Tottenham Court Road, London, W1T 4TQ, United Kingdom. >>> >>> If you are not the intended recipient of this email, you must neither take any action based upon its contents, nor copy or show it to anyone. Please contact the sender if you believe you have received this email in error. >>> >>> _______________________________________________ >>> nginx-devel mailing list >>> nginx-devel at nginx.org >>> http://mailman.nginx.org/mailman/listinfo/nginx-devel >> >> _______________________________________________ >> nginx-devel mailing list >> nginx-devel at nginx.org >> http://mailman.nginx.org/mailman/listinfo/nginx-devel > _______________________________________________ > nginx-devel mailing list > nginx-devel at nginx.org > http://mailman.nginx.org/mailman/listinfo/nginx-devel -- This email and any attachments to it may be confidential and are intended solely for the use of the individual to whom it is addressed. Any views or opinions expressed are solely those of the author and do not necessarily represent those of Blis Ltd, a company registered in England and Wales with registered number 06455773. Its registered office is 5th Floor, 85 Tottenham Court Road, London, W1T 4TQ, United Kingdom. If you are not the intended recipient of this email, you must neither take any action based upon its contents, nor copy or show it to anyone. Please contact the sender if you believe you have received this email in error. -------------- next part -------------- An HTML attachment was scrubbed... URL: From hungnv at opensource.com.vn Thu Jun 16 06:24:24 2016 From: hungnv at opensource.com.vn (Hung Nguyen) Date: Thu, 16 Jun 2016 13:24:24 +0700 Subject: C++ module In-Reply-To: <644F3E10-2DED-4672-9221-A0DD3EAC250D@blis.com> References: <737F0C28-049B-4F60-BBC1-8EE41755A590@opensource.com.vn> <644F3E10-2DED-4672-9221-A0DD3EAC250D@blis.com> Message-ID: <73E189E9-D4B0-4C0D-BBC8-EE5331B16707@opensource.com.vn> Hello, I guess there?s no problem using std::string or std::vector since ngx_pagespeed from Google uses them as well. There must be something wrong with your own module, not nginx. ? H?ng From: nginx-devel on behalf of Rajalakshmi Iyer Reply-To: Date: Thursday, June 16, 2016 at 11:18 AM To: Subject: Re: C++ module Thanks everyone. I have been able to compile a C++ module fine. But I am primarily trying to figure out if it's safe to use features like STL containers or Boost libraries within an Nginx module. I am asking this because if I try to allocate an std::string within say the module context, I see a segmentation fault. I assume it's because of the Nginx pool mechanism? On 16 Jun 2016, at 02:31, Hung Nguyen wrote: Hello, Nginx comes with a demo module written in C++ in source code Sent from my iPhone On Jun 16, 2016, at 3:49 AM, Piotr Sikora wrote: Hey Raj, it is, take a look at ngx_brotli [1] and ngx_pagespeed [2]. [1] https://github.com/google/ngx_brotli [2] https://github.com/pagespeed/ngx_pagespeed Best regards, Piotr Sikora On Wed, Jun 15, 2016 at 8:27 AM, Rajalakshmi Iyer wrote: Hello, Just wanted to check if it is possible to write NGINX modules in C++ that makes extensive use of the standard template library (STL)? If so, what are the things that one needs to be careful about? Thanks in advance, Raj This email and any attachments to it may be confidential and are intended solely for the use of the individual to whom it is addressed. Any views or opinions expressed are solely those of the author and do not necessarily represent those of Blis Ltd, a company registered in England and Wales with registered number 06455773. Its registered office is 5th Floor, 85 Tottenham Court Road, London, W1T 4TQ, United Kingdom. If you are not the intended recipient of this email, you must neither take any action based upon its contents, nor copy or show it to anyone. Please contact the sender if you believe you have received this email in error. _______________________________________________ nginx-devel mailing list nginx-devel at nginx.org http://mailman.nginx.org/mailman/listinfo/nginx-devel _______________________________________________ nginx-devel mailing list nginx-devel at nginx.org http://mailman.nginx.org/mailman/listinfo/nginx-devel _______________________________________________ nginx-devel mailing list nginx-devel at nginx.org http://mailman.nginx.org/mailman/listinfo/nginx-devel This email and any attachments to it may be confidential and are intended solely for the use of the individual to whom it is addressed. Any views or opinions expressed are solely those of the author and do not necessarily represent those of Blis Ltd, a company registered in England and Wales with registered number 06455773. Its registered office is 5th Floor, 85 Tottenham Court Road, London, W1T 4TQ, United Kingdom. If you are not the intended recipient of this email, you must neither take any action based upon its contents, nor copy or show it to anyone. Please contact the sender if you believe you have received this email in error. _______________________________________________ nginx-devel mailing list nginx-devel at nginx.org http://mailman.nginx.org/mailman/listinfo/nginx-devel -------------- next part -------------- An HTML attachment was scrubbed... URL: From shuxinyang.oss at gmail.com Thu Jun 16 06:41:06 2016 From: shuxinyang.oss at gmail.com (Shuxin Yang) Date: Wed, 15 Jun 2016 23:41:06 -0700 Subject: C++ module In-Reply-To: <644F3E10-2DED-4672-9221-A0DD3EAC250D@blis.com> References: <737F0C28-049B-4F60-BBC1-8EE41755A590@opensource.com.vn> <644F3E10-2DED-4672-9221-A0DD3EAC250D@blis.com> Message-ID: <57624A02.40800@gmail.com> On 06/15/2016 09:18 PM, Rajalakshmi Iyer wrote: > Thanks everyone. > > I have been able to compile a C++ module fine. But I am primarily > trying to figure out if it's safe to use features like STL containers > or Boost libraries within an Nginx module. > In my project, I used STL. it works fine. > I am asking this because if I try to allocate an std::string within > say the module context, I see a segmentation fault. I assume it's > because of the Nginx pool mechanism? > Not sure what is "say the module context", and how you allocate std::string on Nginx pool. I believe there are following combinations of "allocating std::string" and Nginx-pool usage. 1). does not use pool at all, statement like: std::string *p = new std::string("haha"); // instance allocated from heap std::string s("haha") // instance allocated from stack. 2) use pool to allocate std::string instance, but use heap to allocate data: like following the instance is allocate on pool via placement new, but the data is allocated from heap. void *p = ngx_palloc(enough size) std::string *s = new(p) std::string("haha") it is fine so long as string instance's life time is not longer than pool 3). if you want to allocate data on top of ngx pool (for efficiency reasons), it is bit involved. first, you need to define an allocation class like this http://www.mcs.anl.gov/OpenAD/OpenADFortTkExtendedDox/mempool__allocator_8h_source.html (NOTE that the MEM_POOL is similar to Nginx pool in many ways). and feed to allocator to construction. e.g. typedef mempool_allocator my_allocator; tyepdef std::vector my_vector_t; ngx_pool_t* the_ngx_pool = .... my_vector_t vect(myalloctor(the_ngx_pool)) so the element will allocate from the nginx pool. -------------- next part -------------- An HTML attachment was scrubbed... URL: From serg.brester at sebres.de Thu Jun 16 11:29:04 2016 From: serg.brester at sebres.de (Sergey Brester) Date: Thu, 16 Jun 2016 13:29:04 +0200 Subject: [BF] slab init + http file cache fixes In-Reply-To: <20160615185248.GO36620@mdounin.ru> References: <7a429ee385267d07ccf44d49e6fd230a@sebres.de> <90d675c425386f7ffdd6139b4d55834e@sebres.de> <20160615155452.GL36620@mdounin.ru> <35d7ab4c44e63f61cfb723b4a0985c62@sebres.de> <20160615185248.GO36620@mdounin.ru> Message-ID: <6591911cfab4a0acd299dc49370a051c@sebres.de> > The NGX_HTTP_CACHE_SCARCE is intended to signal to the caller that > min_uses was not yet reached, and that's why the request will not > use cache. And that's the only case where NGX_HTTP_CACHE_SCARCE > is used. Semantics of the error case your are trying to add here > is quite different. This will be an immediate problem if/when > we'll add appropriate $upstream_cache_status value for SCARCE. > > (Moreover, I'm not really sure this needs fixing at all, as since > version 1.9.13 cache manger monitors number of elements in the > cache and tries to avoid cache zone overflows. That is, overflows > are not expected to happen often.) I think, I had clearly described my position to that: always better to process the request as to fail it, just because cache is sometimes exceeded. And I had such situation several times, so cache manger was apparently not succeeded by very intense load. > Race condition here is intended: we are dropping the lock to > prevent lock contention during a potentially long syscall. It is > expected that in some cases another worker will be able to grab > the node, and this will prevent its complete removal. But there > is more than one case possible: e.g., another worker can grab the > node and put an updated file into it before the file will be > deleted, and as a result we'll delete different file here. The > question is: what is the case you are trying to improve, and what > it means for other possible cases. As I already wrote, it happened without this fix. > The "cache->files" is used to count number of files processed by > the cache loader. When it reaches loader_files, cache loader will > sleep for a while. There is nothing wrong that it is incremented - > as the file was processed, it should be incremented. With the > change in question cache loader won't be able to properly respect > loader_files and loader_threshold, making it use all available > resources in case of errors. Well, I do not insist here. >> ... win32 ... > If you think this problem can be seen on other platforms - feel > free to point them out as well. For which purposes? Thus the message contains "win32"? Really? Just to not harry mere any statistics, that says nginx (and nginx+) have no bugs (under *nix)? No, sorry... > If you can suggest a better name - please do so. If I would have better name, I had used it right away. > We certainly don't want to try to preserve compatibility with > someone who in theory can use slab code outside of nginx. If > somebody really does so, it can add appropriate initialization. Agreed, I do not insist here. > You may find this article interesting: > http://blog.flaper87.org/post/opensource-owes-you-everything-and-nothing/ My foot! It's just embarrassing, if it was a respond to critique (imho well-deserved critique). I'm already longer as century quarter a developer, the same long contribute to several projects, more than decade I'm a lead or co-owner of many projects. Never, never I've been so a nonsense read. But shouldn't argue about taste... Regards, sebres. From vbart at nginx.com Thu Jun 16 17:56:31 2016 From: vbart at nginx.com (Valentin Bartenev) Date: Thu, 16 Jun 2016 17:56:31 +0000 Subject: [nginx] HTTP/2: fixed a segfault while processing unbuffered upload. Message-ID: details: http://hg.nginx.org/nginx/rev/d45845a6c96a branches: changeset: 6587:d45845a6c96a user: Valentin Bartenev date: Thu Jun 16 20:55:11 2016 +0300 description: HTTP/2: fixed a segfault while processing unbuffered upload. The ngx_http_v2_finalize_connection() closes current stream, but that is an invalid operation while processing unbuffered upload. This results in access to already freed memory, since the upstream module sets a cleanup handler that also finalizes the request. diffstat: src/http/v2/ngx_http_v2.c | 4 ---- 1 files changed, 0 insertions(+), 4 deletions(-) diffs (14 lines): diff -r 1064ea81ed3a -r d45845a6c96a src/http/v2/ngx_http_v2.c --- a/src/http/v2/ngx_http_v2.c Thu Jun 09 16:55:38 2016 +0300 +++ b/src/http/v2/ngx_http_v2.c Thu Jun 16 20:55:11 2016 +0300 @@ -4169,10 +4169,6 @@ ngx_http_v2_finalize_connection(ngx_http c->error = 1; - if (h2c->state.stream) { - ngx_http_v2_close_stream(h2c->state.stream, NGX_HTTP_BAD_REQUEST); - } - if (!h2c->processing) { ngx_http_close_connection(c); return; From vbart at nginx.com Thu Jun 16 17:56:34 2016 From: vbart at nginx.com (Valentin Bartenev) Date: Thu, 16 Jun 2016 17:56:34 +0000 Subject: [nginx] HTTP/2: prevented double termination of a stream. Message-ID: details: http://hg.nginx.org/nginx/rev/dc5eaf998b96 branches: changeset: 6588:dc5eaf998b96 user: Valentin Bartenev date: Thu Jun 16 20:55:11 2016 +0300 description: HTTP/2: prevented double termination of a stream. According to RFC 7540, an endpoint should not send more than one RST_STREAM frame for any stream. Also, now all the data frames will be skipped while termination. diffstat: src/http/v2/ngx_http_v2.c | 5 +++++ 1 files changed, 5 insertions(+), 0 deletions(-) diffs (22 lines): diff -r d45845a6c96a -r dc5eaf998b96 src/http/v2/ngx_http_v2.c --- a/src/http/v2/ngx_http_v2.c Thu Jun 16 20:55:11 2016 +0300 +++ b/src/http/v2/ngx_http_v2.c Thu Jun 16 20:55:11 2016 +0300 @@ -3890,6 +3890,10 @@ ngx_http_v2_terminate_stream(ngx_http_v2 ngx_event_t *rev; ngx_connection_t *fc; + if (stream->rst_sent) { + return NGX_OK; + } + if (ngx_http_v2_send_rst_stream(h2c, stream->node->id, status) == NGX_ERROR) { @@ -3897,6 +3901,7 @@ ngx_http_v2_terminate_stream(ngx_http_v2 } stream->rst_sent = 1; + stream->skip_data = 1; fc = stream->request->connection; fc->error = 1; From vbart at nginx.com Thu Jun 16 17:56:37 2016 From: vbart at nginx.com (Valentin Bartenev) Date: Thu, 16 Jun 2016 17:56:37 +0000 Subject: [nginx] HTTP/2: avoid adding Content-Length for requests without body. Message-ID: details: http://hg.nginx.org/nginx/rev/78533a74af11 branches: changeset: 6589:78533a74af11 user: Valentin Bartenev date: Thu Jun 16 20:55:11 2016 +0300 description: HTTP/2: avoid adding Content-Length for requests without body. There is no reason to add the "Content-Length: 0" header to a proxied request without body if the header isn't presented in the original request. Thanks to Amazon. diffstat: src/http/v2/ngx_http_v2.c | 6 ++++-- 1 files changed, 4 insertions(+), 2 deletions(-) diffs (23 lines): diff -r dc5eaf998b96 -r 78533a74af11 src/http/v2/ngx_http_v2.c --- a/src/http/v2/ngx_http_v2.c Thu Jun 16 20:55:11 2016 +0300 +++ b/src/http/v2/ngx_http_v2.c Thu Jun 16 20:55:11 2016 +0300 @@ -3424,7 +3424,9 @@ ngx_http_v2_run_request(ngx_http_request return; } - r->headers_in.chunked = (r->headers_in.content_length_n == -1); + if (r->headers_in.content_length_n == -1 && !r->stream->in_closed) { + r->headers_in.chunked = 1; + } ngx_http_process_request(r); } @@ -3638,7 +3640,7 @@ ngx_http_v2_process_request_body(ngx_htt rb->buf = NULL; } - if (r->headers_in.content_length_n == -1) { + if (r->headers_in.chunked) { r->headers_in.content_length_n = rb->received; } From vbart at nginx.com Thu Jun 16 17:56:39 2016 From: vbart at nginx.com (Valentin Bartenev) Date: Thu, 16 Jun 2016 17:56:39 +0000 Subject: [nginx] HTTP/2: fixed the "http request count is zero" alert. Message-ID: details: http://hg.nginx.org/nginx/rev/d375f4210e41 branches: changeset: 6590:d375f4210e41 user: Valentin Bartenev date: Thu Jun 16 20:55:11 2016 +0300 description: HTTP/2: fixed the "http request count is zero" alert. When the stream is terminated the HEADERS frame can still wait in the output queue. This frame can't be removed and must be sent to the client anyway, since HTTP/2 uses stateful compression for headers. So in order to postpone closing and freeing memory of such stream the special close stream handler is set to the write event. After the HEADERS frame is sent the write event is called and the stream will be finally closed. Some events like receiving a RST_STREAM can trigger the read handler of such stream in closing state and cause unexpected processing that can result in another attempt to finalize the request. To prevent it the read handler is now set to ngx_http_empty_handler. Thanks to Amazon. diffstat: src/http/v2/ngx_http_v2.c | 1 + 1 files changed, 1 insertions(+), 0 deletions(-) diffs (11 lines): diff -r 78533a74af11 -r d375f4210e41 src/http/v2/ngx_http_v2.c --- a/src/http/v2/ngx_http_v2.c Thu Jun 16 20:55:11 2016 +0300 +++ b/src/http/v2/ngx_http_v2.c Thu Jun 16 20:55:11 2016 +0300 @@ -3935,6 +3935,7 @@ ngx_http_v2_close_stream(ngx_http_v2_str if (stream->queued) { fc->write->handler = ngx_http_v2_close_stream_handler; + fc->read->handler = ngx_http_empty_handler; return; } From mdounin at mdounin.ru Thu Jun 16 18:24:45 2016 From: mdounin at mdounin.ru (Maxim Dounin) Date: Thu, 16 Jun 2016 18:24:45 +0000 Subject: [nginx] SSL: ngx_ssl_ciphers() to set list of ciphers. Message-ID: details: http://hg.nginx.org/nginx/rev/04d8d1f85649 branches: changeset: 6591:04d8d1f85649 user: Tim Taubert date: Wed Jun 15 21:05:30 2016 +0100 description: SSL: ngx_ssl_ciphers() to set list of ciphers. This patch moves various OpenSSL-specific function calls into the OpenSSL module and introduces ngx_ssl_ciphers() to make nginx more crypto-library-agnostic. diffstat: src/event/ngx_event_openssl.c | 24 ++++++++++++++++++++++++ src/event/ngx_event_openssl.h | 2 ++ src/http/modules/ngx_http_proxy_module.c | 8 ++------ src/http/modules/ngx_http_ssl_module.c | 18 +++--------------- src/http/modules/ngx_http_uwsgi_module.c | 8 ++------ src/mail/ngx_mail_ssl_module.c | 17 +++-------------- src/stream/ngx_stream_proxy_module.c | 8 +------- src/stream/ngx_stream_ssl_module.c | 17 +++-------------- 8 files changed, 40 insertions(+), 62 deletions(-) diffs (200 lines): diff --git a/src/event/ngx_event_openssl.c b/src/event/ngx_event_openssl.c --- a/src/event/ngx_event_openssl.c +++ b/src/event/ngx_event_openssl.c @@ -592,6 +592,30 @@ ngx_ssl_password_callback(char *buf, int ngx_int_t +ngx_ssl_ciphers(ngx_conf_t *cf, ngx_ssl_t *ssl, ngx_str_t *ciphers, + ngx_uint_t prefer_server_ciphers) +{ + if (SSL_CTX_set_cipher_list(ssl->ctx, (char *) ciphers->data) == 0) { + ngx_ssl_error(NGX_LOG_EMERG, ssl->log, 0, + "SSL_CTX_set_cipher_list(\"%V\") failed", + ciphers); + return NGX_ERROR; + } + + if (prefer_server_ciphers) { + SSL_CTX_set_options(ssl->ctx, SSL_OP_CIPHER_SERVER_PREFERENCE); + } + +#if (OPENSSL_VERSION_NUMBER < 0x10100001L && !defined LIBRESSL_VERSION_NUMBER) + /* a temporary 512-bit RSA key is required for export versions of MSIE */ + SSL_CTX_set_tmp_rsa_callback(ssl->ctx, ngx_ssl_rsa512_key_callback); +#endif + + return NGX_OK; +} + + +ngx_int_t ngx_ssl_client_certificate(ngx_conf_t *cf, ngx_ssl_t *ssl, ngx_str_t *cert, ngx_int_t depth) { diff --git a/src/event/ngx_event_openssl.h b/src/event/ngx_event_openssl.h --- a/src/event/ngx_event_openssl.h +++ b/src/event/ngx_event_openssl.h @@ -144,6 +144,8 @@ ngx_int_t ngx_ssl_certificates(ngx_conf_ ngx_array_t *certs, ngx_array_t *keys, ngx_array_t *passwords); ngx_int_t ngx_ssl_certificate(ngx_conf_t *cf, ngx_ssl_t *ssl, ngx_str_t *cert, ngx_str_t *key, ngx_array_t *passwords); +ngx_int_t ngx_ssl_ciphers(ngx_conf_t *cf, ngx_ssl_t *ssl, ngx_str_t *ciphers, + ngx_uint_t prefer_server_ciphers); ngx_int_t ngx_ssl_client_certificate(ngx_conf_t *cf, ngx_ssl_t *ssl, ngx_str_t *cert, ngx_int_t depth); ngx_int_t ngx_ssl_trusted_certificate(ngx_conf_t *cf, ngx_ssl_t *ssl, diff --git a/src/http/modules/ngx_http_proxy_module.c b/src/http/modules/ngx_http_proxy_module.c --- a/src/http/modules/ngx_http_proxy_module.c +++ b/src/http/modules/ngx_http_proxy_module.c @@ -4323,13 +4323,9 @@ ngx_http_proxy_set_ssl(ngx_conf_t *cf, n } } - if (SSL_CTX_set_cipher_list(plcf->upstream.ssl->ctx, - (const char *) plcf->ssl_ciphers.data) - == 0) + if (ngx_ssl_ciphers(cf, plcf->upstream.ssl, &plcf->ssl_ciphers, 0) + != NGX_OK) { - ngx_ssl_error(NGX_LOG_EMERG, cf->log, 0, - "SSL_CTX_set_cipher_list(\"%V\") failed", - &plcf->ssl_ciphers); return NGX_ERROR; } diff --git a/src/http/modules/ngx_http_ssl_module.c b/src/http/modules/ngx_http_ssl_module.c --- a/src/http/modules/ngx_http_ssl_module.c +++ b/src/http/modules/ngx_http_ssl_module.c @@ -689,13 +689,10 @@ ngx_http_ssl_merge_srv_conf(ngx_conf_t * return NGX_CONF_ERROR; } - if (SSL_CTX_set_cipher_list(conf->ssl.ctx, - (const char *) conf->ciphers.data) - == 0) + if (ngx_ssl_ciphers(cf, &conf->ssl, &conf->ciphers, + conf->prefer_server_ciphers) + != NGX_OK) { - ngx_ssl_error(NGX_LOG_EMERG, cf->log, 0, - "SSL_CTX_set_cipher_list(\"%V\") failed", - &conf->ciphers); return NGX_CONF_ERROR; } @@ -730,15 +727,6 @@ ngx_http_ssl_merge_srv_conf(ngx_conf_t * return NGX_CONF_ERROR; } - if (conf->prefer_server_ciphers) { - SSL_CTX_set_options(conf->ssl.ctx, SSL_OP_CIPHER_SERVER_PREFERENCE); - } - -#if (OPENSSL_VERSION_NUMBER < 0x10100001L && !defined LIBRESSL_VERSION_NUMBER) - /* a temporary 512-bit RSA key is required for export versions of MSIE */ - SSL_CTX_set_tmp_rsa_callback(conf->ssl.ctx, ngx_ssl_rsa512_key_callback); -#endif - if (ngx_ssl_dhparam(cf, &conf->ssl, &conf->dhparam) != NGX_OK) { return NGX_CONF_ERROR; } diff --git a/src/http/modules/ngx_http_uwsgi_module.c b/src/http/modules/ngx_http_uwsgi_module.c --- a/src/http/modules/ngx_http_uwsgi_module.c +++ b/src/http/modules/ngx_http_uwsgi_module.c @@ -2325,13 +2325,9 @@ ngx_http_uwsgi_set_ssl(ngx_conf_t *cf, n } } - if (SSL_CTX_set_cipher_list(uwcf->upstream.ssl->ctx, - (const char *) uwcf->ssl_ciphers.data) - == 0) + if (ngx_ssl_ciphers(cf, uwcf->upstream.ssl, &uwcf->ssl_ciphers, 0) + != NGX_OK) { - ngx_ssl_error(NGX_LOG_EMERG, cf->log, 0, - "SSL_CTX_set_cipher_list(\"%V\") failed", - &uwcf->ssl_ciphers); return NGX_ERROR; } diff --git a/src/mail/ngx_mail_ssl_module.c b/src/mail/ngx_mail_ssl_module.c --- a/src/mail/ngx_mail_ssl_module.c +++ b/src/mail/ngx_mail_ssl_module.c @@ -422,24 +422,13 @@ ngx_mail_ssl_merge_conf(ngx_conf_t *cf, } } - if (SSL_CTX_set_cipher_list(conf->ssl.ctx, - (const char *) conf->ciphers.data) - == 0) + if (ngx_ssl_ciphers(cf, &conf->ssl, &conf->ciphers, + conf->prefer_server_ciphers) + != NGX_OK) { - ngx_ssl_error(NGX_LOG_EMERG, cf->log, 0, - "SSL_CTX_set_cipher_list(\"%V\") failed", - &conf->ciphers); return NGX_CONF_ERROR; } - if (conf->prefer_server_ciphers) { - SSL_CTX_set_options(conf->ssl.ctx, SSL_OP_CIPHER_SERVER_PREFERENCE); - } - -#if (OPENSSL_VERSION_NUMBER < 0x10100001L && !defined LIBRESSL_VERSION_NUMBER) - SSL_CTX_set_tmp_rsa_callback(conf->ssl.ctx, ngx_ssl_rsa512_key_callback); -#endif - if (ngx_ssl_dhparam(cf, &conf->ssl, &conf->dhparam) != NGX_OK) { return NGX_CONF_ERROR; } diff --git a/src/stream/ngx_stream_proxy_module.c b/src/stream/ngx_stream_proxy_module.c --- a/src/stream/ngx_stream_proxy_module.c +++ b/src/stream/ngx_stream_proxy_module.c @@ -1640,13 +1640,7 @@ ngx_stream_proxy_set_ssl(ngx_conf_t *cf, } } - if (SSL_CTX_set_cipher_list(pscf->ssl->ctx, - (const char *) pscf->ssl_ciphers.data) - == 0) - { - ngx_ssl_error(NGX_LOG_EMERG, cf->log, 0, - "SSL_CTX_set_cipher_list(\"%V\") failed", - &pscf->ssl_ciphers); + if (ngx_ssl_ciphers(cf, pscf->ssl, &pscf->ssl_ciphers, 0) != NGX_OK) { return NGX_ERROR; } diff --git a/src/stream/ngx_stream_ssl_module.c b/src/stream/ngx_stream_ssl_module.c --- a/src/stream/ngx_stream_ssl_module.c +++ b/src/stream/ngx_stream_ssl_module.c @@ -266,24 +266,13 @@ ngx_stream_ssl_merge_conf(ngx_conf_t *cf return NGX_CONF_ERROR; } - if (SSL_CTX_set_cipher_list(conf->ssl.ctx, - (const char *) conf->ciphers.data) - == 0) + if (ngx_ssl_ciphers(cf, &conf->ssl, &conf->ciphers, + conf->prefer_server_ciphers) + != NGX_OK) { - ngx_ssl_error(NGX_LOG_EMERG, cf->log, 0, - "SSL_CTX_set_cipher_list(\"%V\") failed", - &conf->ciphers); return NGX_CONF_ERROR; } - if (conf->prefer_server_ciphers) { - SSL_CTX_set_options(conf->ssl.ctx, SSL_OP_CIPHER_SERVER_PREFERENCE); - } - -#if (OPENSSL_VERSION_NUMBER < 0x10100001L && !defined LIBRESSL_VERSION_NUMBER) - SSL_CTX_set_tmp_rsa_callback(conf->ssl.ctx, ngx_ssl_rsa512_key_callback); -#endif - if (ngx_ssl_dhparam(cf, &conf->ssl, &conf->dhparam) != NGX_OK) { return NGX_CONF_ERROR; } From mdounin at mdounin.ru Thu Jun 16 18:26:20 2016 From: mdounin at mdounin.ru (Maxim Dounin) Date: Thu, 16 Jun 2016 21:26:20 +0300 Subject: [PATCH] Add ngx_ssl_ciphers() to set list of cipher suites in openssl module In-Reply-To: <5761B5DA.3000009@timtaubert.de> References: <575A96C8.8000403@timtaubert.de> <20160614172437.GJ36620@mdounin.ru> <5761143A.50705@timtaubert.de> <20160615093659.GC77155@lo0.su> <5761236D.4000400@timtaubert.de> <20160615165707.GN36620@mdounin.ru> <5761959D.9010400@timtaubert.de> <20160615194521.GP36620@mdounin.ru> <5761B5DA.3000009@timtaubert.de> Message-ID: <20160616182620.GZ36620@mdounin.ru> Hello! On Wed, Jun 15, 2016 at 09:08:58PM +0100, Tim Taubert wrote: > # HG changeset patch > # User Tim Taubert > # Date 1466021130 -3600 > # Wed Jun 15 21:05:30 2016 +0100 > # Node ID 42ec0b0933f637da2a4a3a17146eb9c7347fa02c > # Parent 1064ea81ed3aabb8ad422ffcc60ddcde667022ac > SSL: ngx_ssl_ciphers() to set list of ciphers. > > This patch moves various OpenSSL-specific function calls into the > OpenSSL module and introduces ngx_ssl_ciphers() to make nginx more > crypto-library-agnostic. > > diff --git a/src/event/ngx_event_openssl.c b/src/event/ngx_event_openssl.c > --- a/src/event/ngx_event_openssl.c > +++ b/src/event/ngx_event_openssl.c > @@ -587,16 +587,40 @@ ngx_ssl_password_callback(char *buf, int > > ngx_memcpy(buf, pwd->data, size); > > return size; > } > > > ngx_int_t > +ngx_ssl_ciphers(ngx_conf_t *cf, ngx_ssl_t *ssl, ngx_str_t *ciphers, > + ngx_uint_t prefer_server_ciphers) > +{ > + if (SSL_CTX_set_cipher_list(ssl->ctx, (char *) ciphers->data) == 0) { > + ngx_ssl_error(NGX_LOG_EMERG, ssl->log, 0, > + "SSL_CTX_set_cipher_list(\"%V\") failed", > + ciphers); > + return NGX_ERROR; > + } > + > + if (prefer_server_ciphers) { > + SSL_CTX_set_options(ssl->ctx, SSL_OP_CIPHER_SERVER_PREFERENCE); > + } > + > +#if (OPENSSL_VERSION_NUMBER < 0x10100001L && !defined LIBRESSL_VERSION_NUMBER) > + /* a temporary 512-bit RSA key is required for export versions of MSIE */ > + SSL_CTX_set_tmp_rsa_callback(conf->ssl.ctx, ngx_ssl_rsa512_key_callback); Here "conf->ssl.ctx" needs to be changed to "ssl->ctx", as there is no "conf" here. Otherwise looks good, so I've fixed this and committed: http://hg.nginx.org/nginx/rev/04d8d1f85649 Thanks! -- Maxim Dounin http://nginx.org/ From 9re.3000 at gmail.com Mon Jun 20 02:13:08 2016 From: 9re.3000 at gmail.com (Taro KOBAYASHI) Date: Mon, 20 Jun 2016 11:13:08 +0900 Subject: [PATCH] -Wno-parentheses-equality for Clang Message-ID: # HG changeset patch # User Taro Kobayashi <9re.3000 at gmail.com> # Date 1466387734 -32400 # Mon Jun 20 10:55:34 2016 +0900 # Node ID f693bcc8e11e63bcbcdafda1b31a9c6a438fa36e # Parent 04d8d1f8564989509f9b03085df1af7618b44be8 With Werror and Wparentheses-equality option, the following will be treated as error in Clang src/core/nginx.c:941:19: error: equality comparison with extraneous parentheses if (((*p) == '/')) { ~~~~~^~~~~~ diff -r 04d8d1f85649 -r f693bcc8e11e auto/cc/clang --- a/auto/cc/clang Wed Jun 15 21:05:30 2016 +0100 +++ b/auto/cc/clang Mon Jun 20 10:55:34 2016 +0900 @@ -93,6 +93,8 @@ CFLAGS="$CFLAGS -Wno-deprecated-declarations" fi +CFLAGS="$CFLAGS -Wno-parentheses-equality" + # stop on warning CFLAGS="$CFLAGS -Werror" From piotrsikora at google.com Mon Jun 20 02:57:53 2016 From: piotrsikora at google.com (Piotr Sikora) Date: Sun, 19 Jun 2016 19:57:53 -0700 Subject: [PATCH] -Wno-parentheses-equality for Clang In-Reply-To: References: Message-ID: Hey Taro, On Sun, Jun 19, 2016 at 7:13 PM, Taro KOBAYASHI <9re.3000 at gmail.com> wrote: > # HG changeset patch > # User Taro Kobayashi <9re.3000 at gmail.com> > # Date 1466387734 -32400 > # Mon Jun 20 10:55:34 2016 +0900 > # Node ID f693bcc8e11e63bcbcdafda1b31a9c6a438fa36e > # Parent 04d8d1f8564989509f9b03085df1af7618b44be8 > With Werror and Wparentheses-equality option, > the following will be treated as error in Clang > > src/core/nginx.c:941:19: error: equality comparison with extraneous parentheses > if (((*p) == '/')) { > ~~~~~^~~~~~ Fixing issue would be better than silencing the warning. Best regards, Piotr Sikora From 9re.3000 at gmail.com Mon Jun 20 06:43:12 2016 From: 9re.3000 at gmail.com (Taro KOBAYASHI) Date: Mon, 20 Jun 2016 15:43:12 +0900 Subject: [PATCH] -Wno-parentheses-equality for Clang Message-ID: Hi Piotr, > Fixing issue would be better than silencing the warning. I aggree with this. And looking into this problem more detail, I found that this is more complicated problem than simple coding style problem. in src/core/nginx.c:941:19 941| if (ngx_path_separator(*p)) { 942| cycle->conf_prefix.len = p - ngx_cycle->conf_file.data + 1; 943| cycle->conf_prefix.data = ngx_cycle->conf_file.data; 944| break; 945| } there is a macro ngx_path_separator defined in src/os/unix/ngx_files.h 201|#define ngx_path_separator(c) ((c) == '/') the warning is raised by the extraneous parentheses expanded by this macro. But generally we cannot say the parentheses in the macro is 'extraneous' as the situation could be changed by the context where it is used. > Hey Taro, > > On Sun, Jun 19, 2016 at 7:13 PM, Taro KOBAYASHI <9re.3000 at gmail.com> wrote: > > # HG changeset patch > > # User Taro Kobayashi <9re.3000 at gmail.com> > > # Date 1466387734 -32400 > > # Mon Jun 20 10:55:34 2016 +0900 > > # Node ID f693bcc8e11e63bcbcdafda1b31a9c6a438fa36e > > # Parent 04d8d1f8564989509f9b03085df1af7618b44be8 > > With Werror and Wparentheses-equality option, > > the following will be treated as error in Clang > > > > src/core/nginx.c:941:19: error: equality comparison with extraneous parentheses > > if (((*p) == '/')) { > > ~~~~~^~~~~~ > > Fixing issue would be better than silencing the warning. > > Best regards, > Piotr Sikora From defan at nginx.com Mon Jun 20 07:48:12 2016 From: defan at nginx.com (Andrei Belov) Date: Mon, 20 Jun 2016 07:48:12 +0000 Subject: [nginx] Set IP_BIND_ADDRESS_NO_PORT socket option for upstream sockets. Message-ID: details: http://hg.nginx.org/nginx/rev/2c7b488a61fb branches: changeset: 6592:2c7b488a61fb user: Andrei Belov date: Mon Jun 20 10:41:17 2016 +0300 description: Set IP_BIND_ADDRESS_NO_PORT socket option for upstream sockets. diffstat: auto/unix | 13 +++++++++++++ src/event/ngx_event_connect.c | 26 ++++++++++++++++++++++++++ 2 files changed, 39 insertions(+), 0 deletions(-) diffs (59 lines): diff -r 04d8d1f85649 -r 2c7b488a61fb auto/unix --- a/auto/unix Wed Jun 15 21:05:30 2016 +0100 +++ b/auto/unix Mon Jun 20 10:41:17 2016 +0300 @@ -341,6 +341,19 @@ ngx_feature_test="setsockopt(0, SOL_SOCK . auto/feature +# Linux IP_BIND_ADDRESS_NO_PORT + +ngx_feature="IP_BIND_ADDRESS_NO_PORT" +ngx_feature_name="NGX_HAVE_IP_BIND_ADDRESS_NO_PORT" +ngx_feature_run=no +ngx_feature_incs="#include + #include " +ngx_feature_path= +ngx_feature_libs= +ngx_feature_test="setsockopt(0, IPPROTO_IP, IP_BIND_ADDRESS_NO_PORT, NULL, 0)" +. auto/feature + + # Linux transparent proxying ngx_feature="IP_TRANSPARENT" diff -r 04d8d1f85649 -r 2c7b488a61fb src/event/ngx_event_connect.c --- a/src/event/ngx_event_connect.c Wed Jun 15 21:05:30 2016 +0100 +++ b/src/event/ngx_event_connect.c Mon Jun 20 10:41:17 2016 +0300 @@ -87,6 +87,32 @@ ngx_event_connect_peer(ngx_peer_connecti } #endif +#if (NGX_HAVE_IP_BIND_ADDRESS_NO_PORT) + + if (pc->sockaddr->sa_family != AF_UNIX) { + static int bind_address_no_port = 1; + + if (bind_address_no_port) { + if (setsockopt(s, IPPROTO_IP, IP_BIND_ADDRESS_NO_PORT, + (const void *) &bind_address_no_port, + sizeof(int)) == -1) + { + err = ngx_socket_errno; + + if (err != NGX_EOPNOTSUPP && err != NGX_ENOPROTOOPT) { + ngx_log_error(NGX_LOG_ALERT, pc->log, err, + "setsockopt(IP_BIND_ADDRESS_NO_PORT) " + "failed, ignored"); + + } else { + bind_address_no_port = 0; + } + } + } + } + +#endif + if (bind(s, pc->local->sockaddr, pc->local->socklen) == -1) { ngx_log_error(NGX_LOG_CRIT, pc->log, ngx_socket_errno, "bind(%V) failed", &pc->local->name); From tim at timtaubert.de Mon Jun 20 07:59:55 2016 From: tim at timtaubert.de (Tim Taubert) Date: Mon, 20 Jun 2016 09:59:55 +0200 Subject: [PATCH] SSL: ngx_ssl_protocol_negotiation() to set up ALPN/NPN handling Message-ID: <5767A27B.5060009@timtaubert.de> # HG changeset patch # User Tim Taubert # Date 1466409485 -7200 # Mon Jun 20 09:58:05 2016 +0200 # Node ID 1955931e69e166e26e6e4b7655695810c58a22c8 # Parent 2c7b488a61fbbd36054bc7410c161ce73b7624b9 SSL: ngx_ssl_protocol_negotiation() to set up ALPN/NPN handling This patch adds ngx_ssl_protocol_negotiation() to be called to set up ALPN/NPN handling for the respective cryptography library used to implement TLS support. diff --git a/src/event/ngx_event_openssl.c b/src/event/ngx_event_openssl.c --- a/src/event/ngx_event_openssl.c +++ b/src/event/ngx_event_openssl.c @@ -13,16 +13,27 @@ #define NGX_SSL_PASSWORD_BUFFER_SIZE 4096 typedef struct { ngx_uint_t engine; /* unsigned engine:1; */ } ngx_openssl_conf_t; +#ifdef TLSEXT_TYPE_application_layer_protocol_negotiation +static int ngx_ssl_alpn_select(ngx_ssl_conn_t *ssl_conn, + const unsigned char **out, unsigned char *outlen, const unsigned char *in, + unsigned int inlen, void *arg); +#endif + +#ifdef TLSEXT_TYPE_next_proto_neg +static int ngx_ssl_npn_advertised(ngx_ssl_conn_t *ssl_conn, + const unsigned char **out, unsigned int *outlen, void *arg); +#endif + static int ngx_ssl_password_callback(char *buf, int size, int rwflag, void *userdata); static int ngx_ssl_verify_callback(int ok, X509_STORE_CTX *x509_store); static void ngx_ssl_info_callback(const ngx_ssl_conn_t *ssl_conn, int where, int ret); static void ngx_ssl_passwords_cleanup(void *data); static void ngx_ssl_handshake_handler(ngx_event_t *ev); static ngx_int_t ngx_ssl_handle_recv(ngx_connection_t *c, int n); @@ -317,16 +328,101 @@ ngx_ssl_create(ngx_ssl_t *ssl, ngx_uint_ SSL_CTX_set_info_callback(ssl->ctx, ngx_ssl_info_callback); return NGX_OK; } ngx_int_t +ngx_ssl_protocol_negotiation(ngx_conf_t *cf, ngx_ssl_t *ssl, ngx_str_t *data) +{ + // Store protocols to offer. + ssl->proto_neg.len = data->len; + ssl->proto_neg.data = ngx_pstrdup(cf->pool, data); + if (ssl->proto_neg.data == NULL) { + return NGX_ERROR; + } + +#ifdef TLSEXT_TYPE_application_layer_protocol_negotiation + SSL_CTX_set_alpn_select_cb(ssl->ctx, ngx_ssl_alpn_select, &ssl->proto_neg); +#endif + +#ifdef TLSEXT_TYPE_next_proto_neg + SSL_CTX_set_next_protos_advertised_cb(ssl->ctx, ngx_ssl_npn_advertised, + &ssl->proto_neg); +#endif + + return NGX_OK; +} + + +#ifdef TLSEXT_TYPE_application_layer_protocol_negotiation + +static int +ngx_ssl_alpn_select(ngx_ssl_conn_t *ssl_conn, const unsigned char **out, + unsigned char *outlen, const unsigned char *in, unsigned int inlen, + void *arg) +{ + ngx_str_t *proto_neg = arg; + +#if (NGX_DEBUG) + unsigned int i; + ngx_connection_t *c = ngx_ssl_get_connection(ssl_conn); + + for (i = 0; i < inlen; i += in[i] + 1) { + ngx_log_debug2(NGX_LOG_DEBUG_HTTP, c->log, 0, + "SSL ALPN supported by client: %*s", + (size_t) in[i], &in[i + 1]); + } +#endif + + if (SSL_select_next_proto((unsigned char **) out, outlen, proto_neg->data, + proto_neg->len, in, inlen) + != OPENSSL_NPN_NEGOTIATED) + { + return SSL_TLSEXT_ERR_NOACK; + } + +#if (NGX_DEBUG) + ngx_log_debug2(NGX_LOG_DEBUG_HTTP, c->log, 0, + "SSL ALPN selected: %*s", (size_t) *outlen, *out); +#endif + + return SSL_TLSEXT_ERR_OK; +} + +#endif + + +#ifdef TLSEXT_TYPE_next_proto_neg + +static int +ngx_ssl_npn_advertised(ngx_ssl_conn_t *ssl_conn, + const unsigned char **out, unsigned int *outlen, void *arg) +{ + ngx_str_t *proto_neg = arg; + +#if (NGX_DEBUG) + ngx_connection_t *c; + + c = ngx_ssl_get_connection(ssl_conn); + ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0, "SSL NPN advertised"); +#endif + + *out = proto_neg->data; + *outlen = proto_neg->len; + + return SSL_TLSEXT_ERR_OK; +} + +#endif + + +ngx_int_t ngx_ssl_certificates(ngx_conf_t *cf, ngx_ssl_t *ssl, ngx_array_t *certs, ngx_array_t *keys, ngx_array_t *passwords) { ngx_str_t *cert, *key; ngx_uint_t i; cert = certs->elts; key = keys->elts; diff --git a/src/event/ngx_event_openssl.h b/src/event/ngx_event_openssl.h --- a/src/event/ngx_event_openssl.h +++ b/src/event/ngx_event_openssl.h @@ -53,16 +53,17 @@ #define ngx_ssl_session_t SSL_SESSION #define ngx_ssl_conn_t SSL typedef struct { SSL_CTX *ctx; ngx_log_t *log; size_t buffer_size; + ngx_str_t proto_neg; } ngx_ssl_t; typedef struct { ngx_ssl_conn_t *connection; SSL_CTX *session_ctx; ngx_int_t last; @@ -135,16 +136,18 @@ typedef struct { #define NGX_SSL_BUFFER 1 #define NGX_SSL_CLIENT 2 #define NGX_SSL_BUFSIZE 16384 ngx_int_t ngx_ssl_init(ngx_log_t *log); ngx_int_t ngx_ssl_create(ngx_ssl_t *ssl, ngx_uint_t protocols, void *data); +ngx_int_t ngx_ssl_protocol_negotiation(ngx_conf_t *cf, ngx_ssl_t *ssl, + ngx_str_t *data); ngx_int_t ngx_ssl_certificates(ngx_conf_t *cf, ngx_ssl_t *ssl, ngx_array_t *certs, ngx_array_t *keys, ngx_array_t *passwords); ngx_int_t ngx_ssl_certificate(ngx_conf_t *cf, ngx_ssl_t *ssl, ngx_str_t *cert, ngx_str_t *key, ngx_array_t *passwords); ngx_int_t ngx_ssl_ciphers(ngx_conf_t *cf, ngx_ssl_t *ssl, ngx_str_t *ciphers, ngx_uint_t prefer_server_ciphers); ngx_int_t ngx_ssl_client_certificate(ngx_conf_t *cf, ngx_ssl_t *ssl, ngx_str_t *cert, ngx_int_t depth); diff --git a/src/http/modules/ngx_http_ssl_module.c b/src/http/modules/ngx_http_ssl_module.c --- a/src/http/modules/ngx_http_ssl_module.c +++ b/src/http/modules/ngx_http_ssl_module.c @@ -15,27 +15,16 @@ typedef ngx_int_t (*ngx_ssl_variable_han #define NGX_DEFAULT_CIPHERS "HIGH:!aNULL:!MD5" #define NGX_DEFAULT_ECDH_CURVE "auto" #define NGX_HTTP_NPN_ADVERTISE "\x08http/1.1" -#ifdef TLSEXT_TYPE_application_layer_protocol_negotiation -static int ngx_http_ssl_alpn_select(ngx_ssl_conn_t *ssl_conn, - const unsigned char **out, unsigned char *outlen, - const unsigned char *in, unsigned int inlen, void *arg); -#endif - -#ifdef TLSEXT_TYPE_next_proto_neg -static int ngx_http_ssl_npn_advertised(ngx_ssl_conn_t *ssl_conn, - const unsigned char **out, unsigned int *outlen, void *arg); -#endif - static ngx_int_t ngx_http_ssl_static_variable(ngx_http_request_t *r, ngx_http_variable_value_t *v, uintptr_t data); static ngx_int_t ngx_http_ssl_variable(ngx_http_request_t *r, ngx_http_variable_value_t *v, uintptr_t data); static ngx_int_t ngx_http_ssl_add_variables(ngx_conf_t *cf); static void *ngx_http_ssl_create_srv_conf(ngx_conf_t *cf); static char *ngx_http_ssl_merge_srv_conf(ngx_conf_t *cf, @@ -308,113 +297,21 @@ static ngx_http_variable_t ngx_http_ssl (uintptr_t) ngx_ssl_get_client_verify, NGX_HTTP_VAR_CHANGEABLE, 0 }, { ngx_null_string, NULL, NULL, 0, 0, 0 } }; static ngx_str_t ngx_http_ssl_sess_id_ctx = ngx_string("HTTP"); - -#ifdef TLSEXT_TYPE_application_layer_protocol_negotiation - -static int -ngx_http_ssl_alpn_select(ngx_ssl_conn_t *ssl_conn, const unsigned char **out, - unsigned char *outlen, const unsigned char *in, unsigned int inlen, - void *arg) -{ - unsigned int srvlen; - unsigned char *srv; -#if (NGX_DEBUG) - unsigned int i; -#endif #if (NGX_HTTP_V2) - ngx_http_connection_t *hc; -#endif -#if (NGX_HTTP_V2 || NGX_DEBUG) - ngx_connection_t *c; - - c = ngx_ssl_get_connection(ssl_conn); -#endif - -#if (NGX_DEBUG) - for (i = 0; i < inlen; i += in[i] + 1) { - ngx_log_debug2(NGX_LOG_DEBUG_HTTP, c->log, 0, - "SSL ALPN supported by client: %*s", - (size_t) in[i], &in[i + 1]); - } -#endif - -#if (NGX_HTTP_V2) - hc = c->data; - - if (hc->addr_conf->http2) { - srv = - (unsigned char *) NGX_HTTP_V2_ALPN_ADVERTISE NGX_HTTP_NPN_ADVERTISE; - srvlen = sizeof(NGX_HTTP_V2_ALPN_ADVERTISE NGX_HTTP_NPN_ADVERTISE) - 1; - - } else +static ngx_str_t ngx_http_ssl_proto_neg_h2 = ngx_string( + NGX_HTTP_V2_ALPN_ADVERTISE NGX_HTTP_NPN_ADVERTISE); #endif - { - srv = (unsigned char *) NGX_HTTP_NPN_ADVERTISE; - srvlen = sizeof(NGX_HTTP_NPN_ADVERTISE) - 1; - } - - if (SSL_select_next_proto((unsigned char **) out, outlen, srv, srvlen, - in, inlen) - != OPENSSL_NPN_NEGOTIATED) - { - return SSL_TLSEXT_ERR_NOACK; - } - - ngx_log_debug2(NGX_LOG_DEBUG_HTTP, c->log, 0, - "SSL ALPN selected: %*s", (size_t) *outlen, *out); - - return SSL_TLSEXT_ERR_OK; -} - -#endif - - -#ifdef TLSEXT_TYPE_next_proto_neg - -static int -ngx_http_ssl_npn_advertised(ngx_ssl_conn_t *ssl_conn, - const unsigned char **out, unsigned int *outlen, void *arg) -{ -#if (NGX_HTTP_V2 || NGX_DEBUG) - ngx_connection_t *c; - - c = ngx_ssl_get_connection(ssl_conn); - ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0, "SSL NPN advertised"); -#endif - -#if (NGX_HTTP_V2) - { - ngx_http_connection_t *hc; - - hc = c->data; - - if (hc->addr_conf->http2) { - *out = - (unsigned char *) NGX_HTTP_V2_NPN_ADVERTISE NGX_HTTP_NPN_ADVERTISE; - *outlen = sizeof(NGX_HTTP_V2_NPN_ADVERTISE NGX_HTTP_NPN_ADVERTISE) - 1; - - return SSL_TLSEXT_ERR_OK; - } - } -#endif - - *out = (unsigned char *) NGX_HTTP_NPN_ADVERTISE; - *outlen = sizeof(NGX_HTTP_NPN_ADVERTISE) - 1; - - return SSL_TLSEXT_ERR_OK; -} - -#endif +static ngx_str_t ngx_http_ssl_proto_neg_h1 = ngx_string(NGX_HTTP_NPN_ADVERTISE); static ngx_int_t ngx_http_ssl_static_variable(ngx_http_request_t *r, ngx_http_variable_value_t *v, uintptr_t data) { ngx_ssl_variable_handler_pt handler = (ngx_ssl_variable_handler_pt) data; @@ -536,16 +433,17 @@ ngx_http_ssl_create_srv_conf(ngx_conf_t return sscf; } static char * ngx_http_ssl_merge_srv_conf(ngx_conf_t *cf, void *parent, void *child) { + ngx_str_t *proto_neg = &ngx_http_ssl_proto_neg_h1; ngx_http_ssl_srv_conf_t *prev = parent; ngx_http_ssl_srv_conf_t *conf = child; ngx_pool_cleanup_t *cln; if (conf->enable == NGX_CONF_UNSET) { if (prev->enable == NGX_CONF_UNSET) { conf->enable = 0; @@ -660,24 +558,27 @@ ngx_http_ssl_merge_srv_conf(ngx_conf_t * ngx_log_error(NGX_LOG_WARN, cf->log, 0, "nginx was built with SNI support, however, now it is linked " "dynamically to an OpenSSL library which has no tlsext support, " "therefore SNI is not available"); } #endif -#ifdef TLSEXT_TYPE_application_layer_protocol_negotiation - SSL_CTX_set_alpn_select_cb(conf->ssl.ctx, ngx_http_ssl_alpn_select, NULL); -#endif +#if (NGX_HTTP_V2) + { + ngx_connection_t *c = ngx_ssl_get_connection(conf->ssl.ctx); + ngx_http_connection_t *hc = c->data; -#ifdef TLSEXT_TYPE_next_proto_neg - SSL_CTX_set_next_protos_advertised_cb(conf->ssl.ctx, - ngx_http_ssl_npn_advertised, NULL); + if (hc->addr_conf->http2) { + proto_neg = &ngx_http_ssl_proto_neg_h2; + } + } #endif + ngx_ssl_protocol_negotiation(cf, &conf->ssl, proto_neg); cln = ngx_pool_cleanup_add(cf->pool, 0); if (cln == NULL) { return NGX_CONF_ERROR; } cln->handler = ngx_ssl_cleanup_ctx; cln->data = &conf->ssl; From arut at nginx.com Mon Jun 20 09:50:03 2016 From: arut at nginx.com (Roman Arutyunyan) Date: Mon, 20 Jun 2016 09:50:03 +0000 Subject: [nginx] Introduced ngx_inet_get_port() and ngx_inet_set_port() functions. Message-ID: details: http://hg.nginx.org/nginx/rev/b3b7e33083ac branches: changeset: 6593:b3b7e33083ac user: Roman Arutyunyan date: Mon Jun 20 11:50:39 2016 +0300 description: Introduced ngx_inet_get_port() and ngx_inet_set_port() functions. diffstat: src/core/ngx_inet.c | 83 +++++++++++++++++++++++------- src/core/ngx_inet.h | 2 + src/core/ngx_proxy_protocol.c | 11 +-- src/core/ngx_resolver.c | 16 +----- src/event/ngx_event_openssl_stapling.c | 14 +---- src/http/modules/ngx_http_realip_module.c | 39 +------------- src/http/ngx_http.c | 26 +--------- src/http/ngx_http_header_filter_module.c | 23 +-------- src/http/ngx_http_upstream_round_robin.c | 11 +--- src/http/ngx_http_variables.c | 54 +------------------ src/http/v2/ngx_http_v2_filter_module.c | 23 +-------- src/mail/ngx_mail.c | 26 +--------- src/mail/ngx_mail_auth_http_module.c | 29 ++-------- src/stream/ngx_stream.c | 26 +--------- src/stream/ngx_stream_proxy_module.c | 24 +------- 15 files changed, 90 insertions(+), 317 deletions(-) diffs (682 lines): diff -r 2c7b488a61fb -r b3b7e33083ac src/core/ngx_inet.c --- a/src/core/ngx_inet.c Mon Jun 20 10:41:17 2016 +0300 +++ b/src/core/ngx_inet.c Mon Jun 20 11:50:39 2016 +0300 @@ -529,13 +529,9 @@ ngx_int_t ngx_parse_addr_port(ngx_pool_t *pool, ngx_addr_t *addr, u_char *text, size_t len) { - u_char *p, *last; - size_t plen; - ngx_int_t rc, port; - struct sockaddr_in *sin; -#if (NGX_HAVE_INET6) - struct sockaddr_in6 *sin6; -#endif + u_char *p, *last; + size_t plen; + ngx_int_t rc, port; rc = ngx_parse_addr(pool, addr, text, len); @@ -585,20 +581,7 @@ ngx_parse_addr_port(ngx_pool_t *pool, ng return rc; } - switch (addr->sockaddr->sa_family) { - -#if (NGX_HAVE_INET6) - case AF_INET6: - sin6 = (struct sockaddr_in6 *) addr->sockaddr; - sin6->sin6_port = htons((in_port_t) port); - break; -#endif - - default: /* AF_INET */ - sin = (struct sockaddr_in *) addr->sockaddr; - sin->sin_port = htons((in_port_t) port); - break; - } + ngx_inet_set_port(addr->sockaddr, port); return NGX_OK; } @@ -1356,3 +1339,61 @@ ngx_cmp_sockaddr(struct sockaddr *sa1, s return NGX_OK; } + + +in_port_t +ngx_inet_get_port(struct sockaddr *sa) +{ + struct sockaddr_in *sin; +#if (NGX_HAVE_INET6) + struct sockaddr_in6 *sin6; +#endif + + switch (sa->sa_family) { + +#if (NGX_HAVE_INET6) + case AF_INET6: + sin6 = (struct sockaddr_in6 *) sa; + return ntohs(sin6->sin6_port); +#endif + +#if (NGX_HAVE_UNIX_DOMAIN) + case AF_UNIX: + return 0; +#endif + + default: /* AF_INET */ + sin = (struct sockaddr_in *) sa; + return ntohs(sin->sin_port); + } +} + + +void +ngx_inet_set_port(struct sockaddr *sa, in_port_t port) +{ + struct sockaddr_in *sin; +#if (NGX_HAVE_INET6) + struct sockaddr_in6 *sin6; +#endif + + switch (sa->sa_family) { + +#if (NGX_HAVE_INET6) + case AF_INET6: + sin6 = (struct sockaddr_in6 *) sa; + sin6->sin6_port = htons(port); + break; +#endif + +#if (NGX_HAVE_UNIX_DOMAIN) + case AF_UNIX: + break; +#endif + + default: /* AF_INET */ + sin = (struct sockaddr_in *) sa; + sin->sin_port = htons(port); + break; + } +} diff -r 2c7b488a61fb -r b3b7e33083ac src/core/ngx_inet.h --- a/src/core/ngx_inet.h Mon Jun 20 10:41:17 2016 +0300 +++ b/src/core/ngx_inet.h Mon Jun 20 11:50:39 2016 +0300 @@ -121,6 +121,8 @@ ngx_int_t ngx_parse_url(ngx_pool_t *pool ngx_int_t ngx_inet_resolve_host(ngx_pool_t *pool, ngx_url_t *u); ngx_int_t ngx_cmp_sockaddr(struct sockaddr *sa1, socklen_t slen1, struct sockaddr *sa2, socklen_t slen2, ngx_uint_t cmp_port); +in_port_t ngx_inet_get_port(struct sockaddr *sa); +void ngx_inet_set_port(struct sockaddr *sa, in_port_t port); #endif /* _NGX_INET_H_INCLUDED_ */ diff -r 2c7b488a61fb -r b3b7e33083ac src/core/ngx_proxy_protocol.c --- a/src/core/ngx_proxy_protocol.c Mon Jun 20 10:41:17 2016 +0300 +++ b/src/core/ngx_proxy_protocol.c Mon Jun 20 11:50:39 2016 +0300 @@ -141,19 +141,11 @@ ngx_proxy_protocol_write(ngx_connection_ case AF_INET: buf = ngx_cpymem(buf, "PROXY TCP4 ", sizeof("PROXY TCP4 ") - 1); - - port = ntohs(((struct sockaddr_in *) c->sockaddr)->sin_port); - lport = ntohs(((struct sockaddr_in *) c->local_sockaddr)->sin_port); - break; #if (NGX_HAVE_INET6) case AF_INET6: buf = ngx_cpymem(buf, "PROXY TCP6 ", sizeof("PROXY TCP6 ") - 1); - - port = ntohs(((struct sockaddr_in6 *) c->sockaddr)->sin6_port); - lport = ntohs(((struct sockaddr_in6 *) c->local_sockaddr)->sin6_port); - break; #endif @@ -169,5 +161,8 @@ ngx_proxy_protocol_write(ngx_connection_ buf += ngx_sock_ntop(c->local_sockaddr, c->local_socklen, buf, last - buf, 0); + port = ngx_inet_get_port(c->sockaddr); + lport = ngx_inet_get_port(c->local_sockaddr); + return ngx_slprintf(buf, last, " %ui %ui" CRLF, port, lport); } diff -r 2c7b488a61fb -r b3b7e33083ac src/core/ngx_resolver.c --- a/src/core/ngx_resolver.c Mon Jun 20 10:41:17 2016 +0300 +++ b/src/core/ngx_resolver.c Mon Jun 20 11:50:39 2016 +0300 @@ -2996,12 +2996,8 @@ ngx_resolver_srv_names_handler(ngx_resol ngx_addr_t *addrs; ngx_resolver_t *r; ngx_sockaddr_t *sockaddr; - struct sockaddr_in *sin; ngx_resolver_ctx_t *ctx; ngx_resolver_srv_name_t *srv; -#if (NGX_HAVE_INET6) - struct sockaddr_in6 *sin6; -#endif r = cctx->resolver; ctx = cctx->data; @@ -3045,17 +3041,7 @@ ngx_resolver_srv_names_handler(ngx_resol ngx_memcpy(&sockaddr[i], cctx->addrs[i].sockaddr, addrs[i].socklen); - switch (addrs[i].sockaddr->sa_family) { -#if (NGX_HAVE_INET6) - case AF_INET6: - sin6 = (struct sockaddr_in6 *) addrs[i].sockaddr; - sin6->sin6_port = htons(srv->port); - break; -#endif - default: /* AF_INET */ - sin = (struct sockaddr_in *) addrs[i].sockaddr; - sin->sin_port = htons(srv->port); - } + ngx_inet_set_port(addrs[i].sockaddr, srv->port); } srv->addrs = addrs; diff -r 2c7b488a61fb -r b3b7e33083ac src/event/ngx_event_openssl_stapling.c --- a/src/event/ngx_event_openssl_stapling.c Mon Jun 20 10:41:17 2016 +0300 +++ b/src/event/ngx_event_openssl_stapling.c Mon Jun 20 11:50:39 2016 +0300 @@ -920,7 +920,6 @@ ngx_ssl_ocsp_resolve_handler(ngx_resolve u_char *p; size_t len; - in_port_t port; socklen_t socklen; ngx_uint_t i; struct sockaddr *sockaddr; @@ -962,8 +961,6 @@ ngx_ssl_ocsp_resolve_handler(ngx_resolve goto failed; } - port = htons(ctx->port); - for (i = 0; i < resolve->naddrs; i++) { socklen = resolve->addrs[i].socklen; @@ -974,16 +971,7 @@ ngx_ssl_ocsp_resolve_handler(ngx_resolve } ngx_memcpy(sockaddr, resolve->addrs[i].sockaddr, socklen); - - switch (sockaddr->sa_family) { -#if (NGX_HAVE_INET6) - case AF_INET6: - ((struct sockaddr_in6 *) sockaddr)->sin6_port = port; - break; -#endif - default: /* AF_INET */ - ((struct sockaddr_in *) sockaddr)->sin_port = port; - } + ngx_inet_set_port(sockaddr, ctx->port); ctx->addrs[i].sockaddr = sockaddr; ctx->addrs[i].socklen = socklen; diff -r 2c7b488a61fb -r b3b7e33083ac src/http/modules/ngx_http_realip_module.c --- a/src/http/modules/ngx_http_realip_module.c Mon Jun 20 10:41:17 2016 +0300 +++ b/src/http/modules/ngx_http_realip_module.c Mon Jun 20 11:50:39 2016 +0300 @@ -138,10 +138,6 @@ ngx_http_realip_handler(ngx_http_request ngx_list_part_t *part; ngx_table_elt_t *header; ngx_connection_t *c; - struct sockaddr_in *sin; -#if (NGX_HAVE_INET6) - struct sockaddr_in6 *sin6; -#endif ngx_http_realip_ctx_t *ctx; ngx_http_realip_loc_conf_t *rlcf; @@ -242,21 +238,7 @@ found: != NGX_DECLINED) { if (rlcf->type == NGX_HTTP_REALIP_PROXY) { - - switch (addr.sockaddr->sa_family) { - -#if (NGX_HAVE_INET6) - case AF_INET6: - sin6 = (struct sockaddr_in6 *) addr.sockaddr; - sin6->sin6_port = htons(c->proxy_protocol_port); - break; -#endif - - default: /* AF_INET */ - sin = (struct sockaddr_in *) addr.sockaddr; - sin->sin_port = htons(c->proxy_protocol_port); - break; - } + ngx_inet_set_port(addr.sockaddr, c->proxy_protocol_port); } return ngx_http_realip_set_addr(r, &addr); @@ -578,24 +560,7 @@ ngx_http_realip_remote_port_variable(ngx return NGX_ERROR; } - switch (sa->sa_family) { - -#if (NGX_HAVE_INET6) - case AF_INET6: - port = ntohs(((struct sockaddr_in6 *) sa)->sin6_port); - break; -#endif - -#if (NGX_HAVE_UNIX_DOMAIN) - case AF_UNIX: - port = 0; - break; -#endif - - default: /* AF_INET */ - port = ntohs(((struct sockaddr_in *) sa)->sin_port); - break; - } + port = ngx_inet_get_port(sa); if (port > 0 && port < 65536) { v->len = ngx_sprintf(v->data, "%ui", port) - v->data; diff -r 2c7b488a61fb -r b3b7e33083ac src/http/ngx_http.c --- a/src/http/ngx_http.c Mon Jun 20 10:41:17 2016 +0300 +++ b/src/http/ngx_http.c Mon Jun 20 11:50:39 2016 +0300 @@ -1144,12 +1144,8 @@ ngx_http_add_listen(ngx_conf_t *cf, ngx_ in_port_t p; ngx_uint_t i; struct sockaddr *sa; - struct sockaddr_in *sin; ngx_http_conf_port_t *port; ngx_http_core_main_conf_t *cmcf; -#if (NGX_HAVE_INET6) - struct sockaddr_in6 *sin6; -#endif cmcf = ngx_http_conf_get_module_main_conf(cf, ngx_http_core_module); @@ -1162,27 +1158,7 @@ ngx_http_add_listen(ngx_conf_t *cf, ngx_ } sa = &lsopt->sockaddr.sockaddr; - - switch (sa->sa_family) { - -#if (NGX_HAVE_INET6) - case AF_INET6: - sin6 = &lsopt->sockaddr.sockaddr_in6; - p = sin6->sin6_port; - break; -#endif - -#if (NGX_HAVE_UNIX_DOMAIN) - case AF_UNIX: - p = 0; - break; -#endif - - default: /* AF_INET */ - sin = &lsopt->sockaddr.sockaddr_in; - p = sin->sin_port; - break; - } + p = ngx_inet_get_port(sa); port = cmcf->ports->elts; for (i = 0; i < cmcf->ports->nelts; i++) { diff -r 2c7b488a61fb -r b3b7e33083ac src/http/ngx_http_header_filter_module.c --- a/src/http/ngx_http_header_filter_module.c Mon Jun 20 10:41:17 2016 +0300 +++ b/src/http/ngx_http_header_filter_module.c Mon Jun 20 11:50:39 2016 +0300 @@ -161,10 +161,6 @@ ngx_http_header_filter(ngx_http_request_ ngx_connection_t *c; ngx_http_core_loc_conf_t *clcf; ngx_http_core_srv_conf_t *cscf; - struct sockaddr_in *sin; -#if (NGX_HAVE_INET6) - struct sockaddr_in6 *sin6; -#endif u_char addr[NGX_SOCKADDR_STRLEN]; if (r->header_sent) { @@ -333,24 +329,7 @@ ngx_http_header_filter(ngx_http_request_ } } - switch (c->local_sockaddr->sa_family) { - -#if (NGX_HAVE_INET6) - case AF_INET6: - sin6 = (struct sockaddr_in6 *) c->local_sockaddr; - port = ntohs(sin6->sin6_port); - break; -#endif -#if (NGX_HAVE_UNIX_DOMAIN) - case AF_UNIX: - port = 0; - break; -#endif - default: /* AF_INET */ - sin = (struct sockaddr_in *) c->local_sockaddr; - port = ntohs(sin->sin_port); - break; - } + port = ngx_inet_get_port(c->local_sockaddr); len += sizeof("Location: https://") - 1 + host.len diff -r 2c7b488a61fb -r b3b7e33083ac src/http/ngx_http_upstream_round_robin.c --- a/src/http/ngx_http_upstream_round_robin.c Mon Jun 20 10:41:17 2016 +0300 +++ b/src/http/ngx_http_upstream_round_robin.c Mon Jun 20 11:50:39 2016 +0300 @@ -354,16 +354,7 @@ ngx_http_upstream_create_round_robin_pee } ngx_memcpy(sockaddr, ur->addrs[i].sockaddr, socklen); - - switch (sockaddr->sa_family) { -#if (NGX_HAVE_INET6) - case AF_INET6: - ((struct sockaddr_in6 *) sockaddr)->sin6_port = htons(ur->port); - break; -#endif - default: /* AF_INET */ - ((struct sockaddr_in *) sockaddr)->sin_port = htons(ur->port); - } + ngx_inet_set_port(sockaddr, ur->port); p = ngx_pnalloc(r->pool, NGX_SOCKADDR_STRLEN); if (p == NULL) { diff -r 2c7b488a61fb -r b3b7e33083ac src/http/ngx_http_variables.c --- a/src/http/ngx_http_variables.c Mon Jun 20 10:41:17 2016 +0300 +++ b/src/http/ngx_http_variables.c Mon Jun 20 11:50:39 2016 +0300 @@ -1201,11 +1201,7 @@ static ngx_int_t ngx_http_variable_remote_port(ngx_http_request_t *r, ngx_http_variable_value_t *v, uintptr_t data) { - ngx_uint_t port; - struct sockaddr_in *sin; -#if (NGX_HAVE_INET6) - struct sockaddr_in6 *sin6; -#endif + ngx_uint_t port; v->len = 0; v->valid = 1; @@ -1217,26 +1213,7 @@ ngx_http_variable_remote_port(ngx_http_r return NGX_ERROR; } - switch (r->connection->sockaddr->sa_family) { - -#if (NGX_HAVE_INET6) - case AF_INET6: - sin6 = (struct sockaddr_in6 *) r->connection->sockaddr; - port = ntohs(sin6->sin6_port); - break; -#endif - -#if (NGX_HAVE_UNIX_DOMAIN) - case AF_UNIX: - port = 0; - break; -#endif - - default: /* AF_INET */ - sin = (struct sockaddr_in *) r->connection->sockaddr; - port = ntohs(sin->sin_port); - break; - } + port = ngx_inet_get_port(r->connection->sockaddr); if (port > 0 && port < 65536) { v->len = ngx_sprintf(v->data, "%ui", port) - v->data; @@ -1321,11 +1298,7 @@ static ngx_int_t ngx_http_variable_server_port(ngx_http_request_t *r, ngx_http_variable_value_t *v, uintptr_t data) { - ngx_uint_t port; - struct sockaddr_in *sin; -#if (NGX_HAVE_INET6) - struct sockaddr_in6 *sin6; -#endif + ngx_uint_t port; v->len = 0; v->valid = 1; @@ -1341,26 +1314,7 @@ ngx_http_variable_server_port(ngx_http_r return NGX_ERROR; } - switch (r->connection->local_sockaddr->sa_family) { - -#if (NGX_HAVE_INET6) - case AF_INET6: - sin6 = (struct sockaddr_in6 *) r->connection->local_sockaddr; - port = ntohs(sin6->sin6_port); - break; -#endif - -#if (NGX_HAVE_UNIX_DOMAIN) - case AF_UNIX: - port = 0; - break; -#endif - - default: /* AF_INET */ - sin = (struct sockaddr_in *) r->connection->local_sockaddr; - port = ntohs(sin->sin_port); - break; - } + port = ngx_inet_get_port(r->connection->local_sockaddr); if (port > 0 && port < 65536) { v->len = ngx_sprintf(v->data, "%ui", port) - v->data; diff -r 2c7b488a61fb -r b3b7e33083ac src/http/v2/ngx_http_v2_filter_module.c --- a/src/http/v2/ngx_http_v2_filter_module.c Mon Jun 20 10:41:17 2016 +0300 +++ b/src/http/v2/ngx_http_v2_filter_module.c Mon Jun 20 11:50:39 2016 +0300 @@ -137,10 +137,6 @@ ngx_http_v2_header_filter(ngx_http_reque ngx_http_v2_out_frame_t *frame; ngx_http_core_loc_conf_t *clcf; ngx_http_core_srv_conf_t *cscf; - struct sockaddr_in *sin; -#if (NGX_HAVE_INET6) - struct sockaddr_in6 *sin6; -#endif u_char addr[NGX_SOCKADDR_STRLEN]; static const u_char nginx[5] = "\x84\xaa\x63\x55\xe7"; @@ -280,24 +276,7 @@ ngx_http_v2_header_filter(ngx_http_reque } } - switch (fc->local_sockaddr->sa_family) { - -#if (NGX_HAVE_INET6) - case AF_INET6: - sin6 = (struct sockaddr_in6 *) fc->local_sockaddr; - port = ntohs(sin6->sin6_port); - break; -#endif -#if (NGX_HAVE_UNIX_DOMAIN) - case AF_UNIX: - port = 0; - break; -#endif - default: /* AF_INET */ - sin = (struct sockaddr_in *) fc->local_sockaddr; - port = ntohs(sin->sin_port); - break; - } + port = ngx_inet_get_port(fc->local_sockaddr); location.len = sizeof("https://") - 1 + host.len + r->headers_out.location->value.len; diff -r 2c7b488a61fb -r b3b7e33083ac src/mail/ngx_mail.c --- a/src/mail/ngx_mail.c Mon Jun 20 10:41:17 2016 +0300 +++ b/src/mail/ngx_mail.c Mon Jun 20 11:50:39 2016 +0300 @@ -228,35 +228,11 @@ ngx_mail_add_ports(ngx_conf_t *cf, ngx_a in_port_t p; ngx_uint_t i; struct sockaddr *sa; - struct sockaddr_in *sin; ngx_mail_conf_port_t *port; ngx_mail_conf_addr_t *addr; -#if (NGX_HAVE_INET6) - struct sockaddr_in6 *sin6; -#endif sa = &listen->sockaddr.sockaddr; - - switch (sa->sa_family) { - -#if (NGX_HAVE_INET6) - case AF_INET6: - sin6 = &listen->sockaddr.sockaddr_in6; - p = sin6->sin6_port; - break; -#endif - -#if (NGX_HAVE_UNIX_DOMAIN) - case AF_UNIX: - p = 0; - break; -#endif - - default: /* AF_INET */ - sin = &listen->sockaddr.sockaddr_in; - p = sin->sin_port; - break; - } + p = ngx_inet_get_port(sa); port = ports->elts; for (i = 0; i < ports->nelts; i++) { diff -r 2c7b488a61fb -r b3b7e33083ac src/mail/ngx_mail_auth_http_module.c --- a/src/mail/ngx_mail_auth_http_module.c Mon Jun 20 10:41:17 2016 +0300 +++ b/src/mail/ngx_mail_auth_http_module.c Mon Jun 20 11:50:39 2016 +0300 @@ -462,15 +462,11 @@ static void ngx_mail_auth_http_process_headers(ngx_mail_session_t *s, ngx_mail_auth_http_ctx_t *ctx) { - u_char *p; - time_t timer; - size_t len, size; - ngx_int_t rc, port, n; - ngx_addr_t *peer; - struct sockaddr_in *sin; -#if (NGX_HAVE_INET6) - struct sockaddr_in6 *sin6; -#endif + u_char *p; + time_t timer; + size_t len, size; + ngx_int_t rc, port, n; + ngx_addr_t *peer; ngx_log_debug0(NGX_LOG_DEBUG_MAIL, s->connection->log, 0, "mail auth http process headers"); @@ -813,20 +809,7 @@ ngx_mail_auth_http_process_headers(ngx_m return; } - switch (peer->sockaddr->sa_family) { - -#if (NGX_HAVE_INET6) - case AF_INET6: - sin6 = (struct sockaddr_in6 *) peer->sockaddr; - sin6->sin6_port = htons((in_port_t) port); - break; -#endif - - default: /* AF_INET */ - sin = (struct sockaddr_in *) peer->sockaddr; - sin->sin_port = htons((in_port_t) port); - break; - } + ngx_inet_set_port(peer->sockaddr, port); len = ctx->addr.len + 1 + ctx->port.len; diff -r 2c7b488a61fb -r b3b7e33083ac src/stream/ngx_stream.c --- a/src/stream/ngx_stream.c Mon Jun 20 10:41:17 2016 +0300 +++ b/src/stream/ngx_stream.c Mon Jun 20 11:50:39 2016 +0300 @@ -243,35 +243,11 @@ ngx_stream_add_ports(ngx_conf_t *cf, ngx in_port_t p; ngx_uint_t i; struct sockaddr *sa; - struct sockaddr_in *sin; ngx_stream_conf_port_t *port; ngx_stream_conf_addr_t *addr; -#if (NGX_HAVE_INET6) - struct sockaddr_in6 *sin6; -#endif sa = &listen->sockaddr.sockaddr; - - switch (sa->sa_family) { - -#if (NGX_HAVE_INET6) - case AF_INET6: - sin6 = &listen->sockaddr.sockaddr_in6; - p = sin6->sin6_port; - break; -#endif - -#if (NGX_HAVE_UNIX_DOMAIN) - case AF_UNIX: - p = 0; - break; -#endif - - default: /* AF_INET */ - sin = &listen->sockaddr.sockaddr_in; - p = sin->sin_port; - break; - } + p = ngx_inet_get_port(sa); port = ports->elts; for (i = 0; i < ports->nelts; i++) { diff -r 2c7b488a61fb -r b3b7e33083ac src/stream/ngx_stream_proxy_module.c --- a/src/stream/ngx_stream_proxy_module.c Mon Jun 20 10:41:17 2016 +0300 +++ b/src/stream/ngx_stream_proxy_module.c Mon Jun 20 11:50:39 2016 +0300 @@ -446,12 +446,8 @@ static ngx_int_t ngx_stream_proxy_set_local(ngx_stream_session_t *s, ngx_stream_upstream_t *u, ngx_stream_upstream_local_t *local) { - ngx_addr_t *addr; - ngx_connection_t *c; - struct sockaddr_in *sin; -#if (NGX_HAVE_INET6) - struct sockaddr_in6 *sin6; -#endif + ngx_addr_t *addr; + ngx_connection_t *c; if (local == NULL) { u->peer.local = NULL; @@ -484,21 +480,7 @@ ngx_stream_proxy_set_local(ngx_stream_se } ngx_memcpy(addr->sockaddr, c->sockaddr, c->socklen); - - switch (addr->sockaddr->sa_family) { - - case AF_INET: - sin = (struct sockaddr_in *) addr->sockaddr; - sin->sin_port = 0; - break; - -#if (NGX_HAVE_INET6) - case AF_INET6: - sin6 = (struct sockaddr_in6 *) addr->sockaddr; - sin6->sin6_port = 0; - break; -#endif - } + ngx_inet_set_port(addr->sockaddr, 0); addr->name = c->addr_text; u->peer.local = addr; From arut at nginx.com Mon Jun 20 09:50:06 2016 From: arut at nginx.com (Roman Arutyunyan) Date: Mon, 20 Jun 2016 09:50:06 +0000 Subject: [nginx] Upstream: support for port in proxy_bind and friends. Message-ID: details: http://hg.nginx.org/nginx/rev/3c87b82b17d4 branches: changeset: 6594:3c87b82b17d4 user: Roman Arutyunyan date: Mon Jun 20 11:50:43 2016 +0300 description: Upstream: support for port in proxy_bind and friends. diffstat: src/http/ngx_http_upstream.c | 5 +++-- src/stream/ngx_stream_proxy_module.c | 3 ++- 2 files changed, 5 insertions(+), 3 deletions(-) diffs (35 lines): diff -r b3b7e33083ac -r 3c87b82b17d4 src/http/ngx_http_upstream.c --- a/src/http/ngx_http_upstream.c Mon Jun 20 11:50:39 2016 +0300 +++ b/src/http/ngx_http_upstream.c Mon Jun 20 11:50:43 2016 +0300 @@ -5828,7 +5828,8 @@ ngx_http_upstream_bind_set_slot(ngx_conf return NGX_CONF_ERROR; } - rc = ngx_parse_addr(cf->pool, local->addr, value[1].data, value[1].len); + rc = ngx_parse_addr_port(cf->pool, local->addr, value[1].data, + value[1].len); switch (rc) { case NGX_OK: @@ -5900,7 +5901,7 @@ ngx_http_upstream_set_local(ngx_http_req return NGX_ERROR; } - rc = ngx_parse_addr(r->pool, addr, val.data, val.len); + rc = ngx_parse_addr_port(r->pool, addr, val.data, val.len); if (rc == NGX_ERROR) { return NGX_ERROR; } diff -r b3b7e33083ac -r 3c87b82b17d4 src/stream/ngx_stream_proxy_module.c --- a/src/stream/ngx_stream_proxy_module.c Mon Jun 20 11:50:39 2016 +0300 +++ b/src/stream/ngx_stream_proxy_module.c Mon Jun 20 11:50:43 2016 +0300 @@ -1720,7 +1720,8 @@ ngx_stream_proxy_bind(ngx_conf_t *cf, ng return NGX_CONF_ERROR; } - rc = ngx_parse_addr(cf->pool, local->addr, value[1].data, value[1].len); + rc = ngx_parse_addr_port(cf->pool, local->addr, value[1].data, + value[1].len); switch (rc) { case NGX_OK: From arut at nginx.com Mon Jun 20 09:50:09 2016 From: arut at nginx.com (Roman Arutyunyan) Date: Mon, 20 Jun 2016 09:50:09 +0000 Subject: [nginx] Stream: support for $remote_port in proxy_bind. Message-ID: details: http://hg.nginx.org/nginx/rev/0c98c4092440 branches: changeset: 6595:0c98c4092440 user: Roman Arutyunyan date: Mon Jun 20 11:50:44 2016 +0300 description: Stream: support for $remote_port in proxy_bind. The following two types of bind addresses are supported in addition to $remote_addr and address literals: - $remote_addr:$remote_port - [$remote_addr]:$remote_port In both cases client remote address with port is used in upstream socket bind. diffstat: src/stream/ngx_stream_proxy_module.c | 29 ++++++++++++++++++++--------- 1 files changed, 20 insertions(+), 9 deletions(-) diffs (63 lines): diff -r 3c87b82b17d4 -r 0c98c4092440 src/stream/ngx_stream_proxy_module.c --- a/src/stream/ngx_stream_proxy_module.c Mon Jun 20 11:50:43 2016 +0300 +++ b/src/stream/ngx_stream_proxy_module.c Mon Jun 20 11:50:44 2016 +0300 @@ -13,8 +13,9 @@ typedef struct { ngx_addr_t *addr; #if (NGX_HAVE_TRANSPARENT_PROXY) - ngx_uint_t transparent; /* unsigned transparent:1; */ + unsigned transparent:1; #endif + unsigned no_port:1; } ngx_stream_upstream_local_t; @@ -463,7 +464,7 @@ ngx_stream_proxy_set_local(ngx_stream_se return NGX_OK; } - /* $remote_addr */ + /* $remote_addr, $remote_addr:$remote_port, [$remote_addr]:$remote_port */ c = s->connection; @@ -474,14 +475,19 @@ ngx_stream_proxy_set_local(ngx_stream_se addr->socklen = c->socklen; - addr->sockaddr = ngx_palloc(c->pool, addr->socklen); - if (addr->sockaddr == NULL) { - return NGX_ERROR; + if (local->no_port) { + addr->sockaddr = ngx_palloc(c->pool, addr->socklen); + if (addr->sockaddr == NULL) { + return NGX_ERROR; + } + + ngx_memcpy(addr->sockaddr, c->sockaddr, c->socklen); + ngx_inet_set_port(addr->sockaddr, 0); + + } else { + addr->sockaddr = c->sockaddr; } - ngx_memcpy(addr->sockaddr, c->sockaddr, c->socklen); - ngx_inet_set_port(addr->sockaddr, 0); - addr->name = c->addr_text; u->peer.local = addr; @@ -1714,7 +1720,12 @@ ngx_stream_proxy_bind(ngx_conf_t *cf, ng pscf->local = local; - if (ngx_strcmp(value[1].data, "$remote_addr") != 0) { + if (ngx_strcmp(value[1].data, "$remote_addr") == 0) { + local->no_port = 1; + + } else if (ngx_strcmp(value[1].data, "$remote_addr:$remote_port") != 0 + && ngx_strcmp(value[1].data, "[$remote_addr]:$remote_port") != 0) + { local->addr = ngx_palloc(cf->pool, sizeof(ngx_addr_t)); if (local->addr == NULL) { return NGX_CONF_ERROR; From arut at nginx.com Mon Jun 20 09:50:11 2016 From: arut at nginx.com (Roman Arutyunyan) Date: Mon, 20 Jun 2016 09:50:11 +0000 Subject: [nginx] Stream: set SO_REUSEADDR for UDP upstream sockets. Message-ID: details: http://hg.nginx.org/nginx/rev/e778fe9a4463 branches: changeset: 6596:e778fe9a4463 user: Roman Arutyunyan date: Mon Jun 20 12:48:47 2016 +0300 description: Stream: set SO_REUSEADDR for UDP upstream sockets. The option is only set if the socket is bound to a specific port to allow several such sockets coexist at the same time. This is required, for example, when nginx acts as a transparent proxy and receives two datagrams from the same client in a short time. The feature is only implemented for Linux. diffstat: src/event/ngx_event_connect.c | 26 +++++++++++++++++++++++++- 1 files changed, 25 insertions(+), 1 deletions(-) diffs (52 lines): diff -r 0c98c4092440 -r e778fe9a4463 src/event/ngx_event_connect.c --- a/src/event/ngx_event_connect.c Mon Jun 20 11:50:44 2016 +0300 +++ b/src/event/ngx_event_connect.c Mon Jun 20 12:48:47 2016 +0300 @@ -21,6 +21,9 @@ ngx_int_t ngx_event_connect_peer(ngx_peer_connection_t *pc) { int rc, type; +#if (NGX_HAVE_IP_BIND_ADDRESS_NO_PORT || NGX_LINUX) + in_port_t port; +#endif ngx_int_t event; ngx_err_t err; ngx_uint_t level; @@ -87,9 +90,13 @@ ngx_event_connect_peer(ngx_peer_connecti } #endif +#if (NGX_HAVE_IP_BIND_ADDRESS_NO_PORT || NGX_LINUX) + port = ngx_inet_get_port(pc->sockaddr); +#endif + #if (NGX_HAVE_IP_BIND_ADDRESS_NO_PORT) - if (pc->sockaddr->sa_family != AF_UNIX) { + if (pc->sockaddr->sa_family != AF_UNIX && port == 0) { static int bind_address_no_port = 1; if (bind_address_no_port) { @@ -113,6 +120,23 @@ ngx_event_connect_peer(ngx_peer_connecti #endif +#if (NGX_LINUX) + + if (pc->type == SOCK_DGRAM && port != 0) { + int reuse_addr = 1; + + if (setsockopt(s, SOL_SOCKET, SO_REUSEADDR, + (const void *) &reuse_addr, sizeof(int)) + == -1) + { + ngx_log_error(NGX_LOG_ALERT, pc->log, ngx_socket_errno, + "setsockopt(SO_REUSEADDR) failed"); + goto failed; + } + } + +#endif + if (bind(s, pc->local->sockaddr, pc->local->socklen) == -1) { ngx_log_error(NGX_LOG_CRIT, pc->log, ngx_socket_errno, "bind(%V) failed", &pc->local->name); From arut at nginx.com Mon Jun 20 13:43:04 2016 From: arut at nginx.com (Roman Arutyunyan) Date: Mon, 20 Jun 2016 13:43:04 +0000 Subject: [nginx] Fixed build on MSVC. Message-ID: details: http://hg.nginx.org/nginx/rev/0a820872dd4c branches: changeset: 6597:0a820872dd4c user: Roman Arutyunyan date: Mon Jun 20 15:11:50 2016 +0300 description: Fixed build on MSVC. diffstat: src/core/ngx_inet.c | 2 +- src/mail/ngx_mail_auth_http_module.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diffs (24 lines): diff -r e778fe9a4463 -r 0a820872dd4c src/core/ngx_inet.c --- a/src/core/ngx_inet.c Mon Jun 20 12:48:47 2016 +0300 +++ b/src/core/ngx_inet.c Mon Jun 20 15:11:50 2016 +0300 @@ -581,7 +581,7 @@ ngx_parse_addr_port(ngx_pool_t *pool, ng return rc; } - ngx_inet_set_port(addr->sockaddr, port); + ngx_inet_set_port(addr->sockaddr, (in_port_t) port); return NGX_OK; } diff -r e778fe9a4463 -r 0a820872dd4c src/mail/ngx_mail_auth_http_module.c --- a/src/mail/ngx_mail_auth_http_module.c Mon Jun 20 12:48:47 2016 +0300 +++ b/src/mail/ngx_mail_auth_http_module.c Mon Jun 20 15:11:50 2016 +0300 @@ -809,7 +809,7 @@ ngx_mail_auth_http_process_headers(ngx_m return; } - ngx_inet_set_port(peer->sockaddr, port); + ngx_inet_set_port(peer->sockaddr, (in_port_t) port); len = ctx->addr.len + 1 + ctx->port.len; From justin at justinkennedy.ca Mon Jun 20 14:43:57 2016 From: justin at justinkennedy.ca (Justin Kennedy) Date: Mon, 20 Jun 2016 11:43:57 -0300 Subject: enable module for specific site In-Reply-To: References: Message-ID: I'll try to simply the question: Can a module be enabled only for specific server blocks? I.e. If a module is "included" in server block B then it will not interfere with requests on server block A (or any other). Please advice, thank you! On 8 June 2016 at 14:32, Justin Kennedy wrote: > Hello, > > I am developing an nginx module and one of the requirements is to enable > the module only for specific sites or virtual hosts (using a directive I > would suppose). > > Is this possible with nginx? > > Thank you, > -Justin > -- Justin Kennedy Software Developer 506 645 1195 -------------- next part -------------- An HTML attachment was scrubbed... URL: From wandenberg at gmail.com Mon Jun 20 15:27:59 2016 From: wandenberg at gmail.com (Wandenberg Peixoto) Date: Mon, 20 Jun 2016 12:27:59 -0300 Subject: enable module for specific site In-Reply-To: References: Message-ID: It depends on the module. If it is configurable on main, server or location blocks. But generally you can enable/disable at any of these 3 levels On Jun 20, 2016 11:44, "Justin Kennedy" wrote: > I'll try to simply the question: Can a module be enabled only for specific > server blocks? > > I.e. If a module is "included" in server block B then it will not > interfere with requests on server block A (or any other). > > Please advice, thank you! > > On 8 June 2016 at 14:32, Justin Kennedy wrote: > >> Hello, >> >> I am developing an nginx module and one of the requirements is to enable >> the module only for specific sites or virtual hosts (using a directive I >> would suppose). >> >> Is this possible with nginx? >> >> Thank you, >> -Justin >> > > > > -- > Justin Kennedy > Software Developer > 506 645 1195 > > > _______________________________________________ > nginx-devel mailing list > nginx-devel at nginx.org > http://mailman.nginx.org/mailman/listinfo/nginx-devel > -------------- next part -------------- An HTML attachment was scrubbed... URL: From mdounin at mdounin.ru Mon Jun 20 17:51:49 2016 From: mdounin at mdounin.ru (Maxim Dounin) Date: Mon, 20 Jun 2016 20:51:49 +0300 Subject: [PATCH] -Wno-parentheses-equality for Clang In-Reply-To: References: Message-ID: <20160620175148.GF36620@mdounin.ru> Hello! On Mon, Jun 20, 2016 at 03:43:12PM +0900, Taro KOBAYASHI wrote: > > Fixing issue would be better than silencing the warning. > > I aggree with this. And looking into this problem more detail, > I found that this is more complicated problem than simple coding > style problem. > > in src/core/nginx.c:941:19 > > 941| if (ngx_path_separator(*p)) { > 942| cycle->conf_prefix.len = p - ngx_cycle->conf_file.data + 1; > 943| cycle->conf_prefix.data = ngx_cycle->conf_file.data; > 944| break; > 945| } > > there is a macro ngx_path_separator defined in > > src/os/unix/ngx_files.h > 201|#define ngx_path_separator(c) ((c) == '/') > > the warning is raised by the extraneous parentheses expanded by this > macro. But generally we cannot say the parentheses in the macro is 'extraneous' > as the situation could be changed by the context where it is used. If some version of clang generates the warning for the code in question, this looks like a bug in clang for me. Though I don't see the warning generated at least by clang 3.4.1, 3.7.1, 3.8.0, and 3.9.0 (trunk 271348), as well as with one shipped by Apple (clang-703.0.31). -- Maxim Dounin http://nginx.org/ From justin at justinkennedy.ca Tue Jun 21 14:06:10 2016 From: justin at justinkennedy.ca (Justin Kennedy) Date: Tue, 21 Jun 2016 11:06:10 -0300 Subject: enable module for specific site In-Reply-To: References: Message-ID: HI Wandenberg, Our module is a request filter. Do we have to do anything special with this type of module to make it configurable per server / location ? I come from the Apache world, and there we would have to make a custom directive, then the module would have to react to that accordingly. Is it different for nginx? Thank you On 20 June 2016 at 11:43, Justin Kennedy wrote: > I'll try to simply the question: Can a module be enabled only for specific > server blocks? > > I.e. If a module is "included" in server block B then it will not > interfere with requests on server block A (or any other). > > Please advice, thank you! > > On 8 June 2016 at 14:32, Justin Kennedy wrote: > >> Hello, >> >> I am developing an nginx module and one of the requirements is to enable >> the module only for specific sites or virtual hosts (using a directive I >> would suppose). >> >> Is this possible with nginx? >> >> Thank you, >> -Justin >> > > > > -- > Justin Kennedy > Software Developer > > -- Justin Kennedy Software Developer -------------- next part -------------- An HTML attachment was scrubbed... URL: From wandenberg at gmail.com Tue Jun 21 14:42:38 2016 From: wandenberg at gmail.com (Wandenberg Peixoto) Date: Tue, 21 Jun 2016 11:42:38 -0300 Subject: enable module for specific site In-Reply-To: References: Message-ID: No, is the same way. You may create a custom directive to set if you module is activated or not on the location. And check this flag as the first action of your module. What I mean is, all requests will reach your module, but only the ones target to the location where it is "on" will handle the request, the other on will suffer a bypass on your module. Take a look on ngx_http_gzip_filter_module.c as a very good example ;) On Tue, Jun 21, 2016 at 11:06 AM, Justin Kennedy wrote: > HI Wandenberg, Our module is a request filter. Do we have to do anything > special with this type of module to make it configurable per server / > location ? I come from the Apache world, and there we would have to make a > custom directive, then the module would have to react to that accordingly. > Is it different for nginx? > > Thank you > > On 20 June 2016 at 11:43, Justin Kennedy wrote: > >> I'll try to simply the question: Can a module be enabled only for >> specific server blocks? >> >> I.e. If a module is "included" in server block B then it will not >> interfere with requests on server block A (or any other). >> >> Please advice, thank you! >> >> On 8 June 2016 at 14:32, Justin Kennedy wrote: >> >>> Hello, >>> >>> I am developing an nginx module and one of the requirements is to enable >>> the module only for specific sites or virtual hosts (using a directive I >>> would suppose). >>> >>> Is this possible with nginx? >>> >>> Thank you, >>> -Justin >>> >> >> >> >> -- >> Justin Kennedy >> Software Developer >> >> > > > -- > Justin Kennedy > Software Developer > > > _______________________________________________ > nginx-devel mailing list > nginx-devel at nginx.org > http://mailman.nginx.org/mailman/listinfo/nginx-devel > -------------- next part -------------- An HTML attachment was scrubbed... URL: From mdounin at mdounin.ru Tue Jun 21 18:40:08 2016 From: mdounin at mdounin.ru (Maxim Dounin) Date: Tue, 21 Jun 2016 21:40:08 +0300 Subject: [PATCH] SSL: ngx_ssl_protocol_negotiation() to set up ALPN/NPN handling In-Reply-To: <5767A27B.5060009@timtaubert.de> References: <5767A27B.5060009@timtaubert.de> Message-ID: <20160621184008.GB30781@mdounin.ru> Hello! On Mon, Jun 20, 2016 at 09:59:55AM +0200, Tim Taubert wrote: > # HG changeset patch > # User Tim Taubert > # Date 1466409485 -7200 > # Mon Jun 20 09:58:05 2016 +0200 > # Node ID 1955931e69e166e26e6e4b7655695810c58a22c8 > # Parent 2c7b488a61fbbd36054bc7410c161ce73b7624b9 > SSL: ngx_ssl_protocol_negotiation() to set up ALPN/NPN handling > > This patch adds ngx_ssl_protocol_negotiation() to be called to > set up ALPN/NPN handling for the respective cryptography library > used to implement TLS support. See various comments below. Overral, the patch doesn't look working. > > diff --git a/src/event/ngx_event_openssl.c b/src/event/ngx_event_openssl.c > --- a/src/event/ngx_event_openssl.c > +++ b/src/event/ngx_event_openssl.c > @@ -13,16 +13,27 @@ > #define NGX_SSL_PASSWORD_BUFFER_SIZE 4096 > > > typedef struct { > ngx_uint_t engine; /* unsigned engine:1; */ > } ngx_openssl_conf_t; > > > +#ifdef TLSEXT_TYPE_application_layer_protocol_negotiation > +static int ngx_ssl_alpn_select(ngx_ssl_conn_t *ssl_conn, > + const unsigned char **out, unsigned char *outlen, const unsigned char *in, > + unsigned int inlen, void *arg); > +#endif > + > +#ifdef TLSEXT_TYPE_next_proto_neg > +static int ngx_ssl_npn_advertised(ngx_ssl_conn_t *ssl_conn, > + const unsigned char **out, unsigned int *outlen, void *arg); > +#endif > + > static int ngx_ssl_password_callback(char *buf, int size, int rwflag, > void *userdata); > static int ngx_ssl_verify_callback(int ok, X509_STORE_CTX *x509_store); > static void ngx_ssl_info_callback(const ngx_ssl_conn_t *ssl_conn, int where, > int ret); > static void ngx_ssl_passwords_cleanup(void *data); > static void ngx_ssl_handshake_handler(ngx_event_t *ev); > static ngx_int_t ngx_ssl_handle_recv(ngx_connection_t *c, int n); > @@ -317,16 +328,101 @@ ngx_ssl_create(ngx_ssl_t *ssl, ngx_uint_ > > SSL_CTX_set_info_callback(ssl->ctx, ngx_ssl_info_callback); > > return NGX_OK; > } > > > ngx_int_t > +ngx_ssl_protocol_negotiation(ngx_conf_t *cf, ngx_ssl_t *ssl, ngx_str_t *data) ALPN/NPN is just one of aspects of SSL, and relatively minor one. Placing this right after ngx_ssl_create() looks wrong for me. The interface suggested doesn't look generic: it uses OpenSSL-specific wire-format way to specify supported protocols. E.g., GnuTLS uses an array of protocol names instead. Additionally, such an interface can't work as we don't know in advance if HTTP/2 will be allowed on a listening socket or not, see below. The argument name "data" looks too generic. (And the name of the function can be better, too.) > +{ > + // Store protocols to offer. No C99-style comments, please. > + ssl->proto_neg.len = data->len; > + ssl->proto_neg.data = ngx_pstrdup(cf->pool, data); > + if (ssl->proto_neg.data == NULL) { > + return NGX_ERROR; > + } Why ngx_pstrdup() is needed here? > + > +#ifdef TLSEXT_TYPE_application_layer_protocol_negotiation > + SSL_CTX_set_alpn_select_cb(ssl->ctx, ngx_ssl_alpn_select, &ssl->proto_neg); > +#endif > + > +#ifdef TLSEXT_TYPE_next_proto_neg > + SSL_CTX_set_next_protos_advertised_cb(ssl->ctx, ngx_ssl_npn_advertised, > + &ssl->proto_neg); > +#endif > + > + return NGX_OK; > +} > + > + > +#ifdef TLSEXT_TYPE_application_layer_protocol_negotiation > + > +static int > +ngx_ssl_alpn_select(ngx_ssl_conn_t *ssl_conn, const unsigned char **out, > + unsigned char *outlen, const unsigned char *in, unsigned int inlen, > + void *arg) > +{ > + ngx_str_t *proto_neg = arg; > + > +#if (NGX_DEBUG) > + unsigned int i; > + ngx_connection_t *c = ngx_ssl_get_connection(ssl_conn); Indentation of variables here looks wrong. General rule is "2 spaces after the longest type". Please don't use variable definition and initialization at the same time (except in a few very specific cases). > + > + for (i = 0; i < inlen; i += in[i] + 1) { > + ngx_log_debug2(NGX_LOG_DEBUG_HTTP, c->log, 0, NGX_LOG_DEBUG_HTTP is wrong here and in other places. > + "SSL ALPN supported by client: %*s", > + (size_t) in[i], &in[i + 1]); > + } > +#endif > + > + if (SSL_select_next_proto((unsigned char **) out, outlen, proto_neg->data, > + proto_neg->len, in, inlen) > + != OPENSSL_NPN_NEGOTIATED) > + { > + return SSL_TLSEXT_ERR_NOACK; > + } > + > +#if (NGX_DEBUG) > + ngx_log_debug2(NGX_LOG_DEBUG_HTTP, c->log, 0, > + "SSL ALPN selected: %*s", (size_t) *outlen, *out); > +#endif > + > + return SSL_TLSEXT_ERR_OK; > +} > + > +#endif > + > + > +#ifdef TLSEXT_TYPE_next_proto_neg > + > +static int > +ngx_ssl_npn_advertised(ngx_ssl_conn_t *ssl_conn, > + const unsigned char **out, unsigned int *outlen, void *arg) > +{ > + ngx_str_t *proto_neg = arg; > + > +#if (NGX_DEBUG) > + ngx_connection_t *c; > + > + c = ngx_ssl_get_connection(ssl_conn); > + ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0, "SSL NPN advertised"); > +#endif > + > + *out = proto_neg->data; > + *outlen = proto_neg->len; > + > + return SSL_TLSEXT_ERR_OK; > +} > + > +#endif > + > + > +ngx_int_t > ngx_ssl_certificates(ngx_conf_t *cf, ngx_ssl_t *ssl, ngx_array_t *certs, > ngx_array_t *keys, ngx_array_t *passwords) > { > ngx_str_t *cert, *key; > ngx_uint_t i; > > cert = certs->elts; > key = keys->elts; > diff --git a/src/event/ngx_event_openssl.h b/src/event/ngx_event_openssl.h > --- a/src/event/ngx_event_openssl.h > +++ b/src/event/ngx_event_openssl.h > @@ -53,16 +53,17 @@ > #define ngx_ssl_session_t SSL_SESSION > #define ngx_ssl_conn_t SSL > > > typedef struct { > SSL_CTX *ctx; > ngx_log_t *log; > size_t buffer_size; > + ngx_str_t proto_neg; I can't say I like the name. Also it's not clear why this field is at all needed. > } ngx_ssl_t; > > > typedef struct { > ngx_ssl_conn_t *connection; > SSL_CTX *session_ctx; > > ngx_int_t last; > @@ -135,16 +136,18 @@ typedef struct { > #define NGX_SSL_BUFFER 1 > #define NGX_SSL_CLIENT 2 > > #define NGX_SSL_BUFSIZE 16384 > > > ngx_int_t ngx_ssl_init(ngx_log_t *log); > ngx_int_t ngx_ssl_create(ngx_ssl_t *ssl, ngx_uint_t protocols, void *data); > +ngx_int_t ngx_ssl_protocol_negotiation(ngx_conf_t *cf, ngx_ssl_t *ssl, > + ngx_str_t *data); > ngx_int_t ngx_ssl_certificates(ngx_conf_t *cf, ngx_ssl_t *ssl, > ngx_array_t *certs, ngx_array_t *keys, ngx_array_t *passwords); > ngx_int_t ngx_ssl_certificate(ngx_conf_t *cf, ngx_ssl_t *ssl, > ngx_str_t *cert, ngx_str_t *key, ngx_array_t *passwords); > ngx_int_t ngx_ssl_ciphers(ngx_conf_t *cf, ngx_ssl_t *ssl, ngx_str_t *ciphers, > ngx_uint_t prefer_server_ciphers); > ngx_int_t ngx_ssl_client_certificate(ngx_conf_t *cf, ngx_ssl_t *ssl, > ngx_str_t *cert, ngx_int_t depth); > diff --git a/src/http/modules/ngx_http_ssl_module.c b/src/http/modules/ngx_http_ssl_module.c > --- a/src/http/modules/ngx_http_ssl_module.c > +++ b/src/http/modules/ngx_http_ssl_module.c > @@ -15,27 +15,16 @@ typedef ngx_int_t (*ngx_ssl_variable_han > > > #define NGX_DEFAULT_CIPHERS "HIGH:!aNULL:!MD5" > #define NGX_DEFAULT_ECDH_CURVE "auto" > > #define NGX_HTTP_NPN_ADVERTISE "\x08http/1.1" > > > -#ifdef TLSEXT_TYPE_application_layer_protocol_negotiation > -static int ngx_http_ssl_alpn_select(ngx_ssl_conn_t *ssl_conn, > - const unsigned char **out, unsigned char *outlen, > - const unsigned char *in, unsigned int inlen, void *arg); > -#endif > - > -#ifdef TLSEXT_TYPE_next_proto_neg > -static int ngx_http_ssl_npn_advertised(ngx_ssl_conn_t *ssl_conn, > - const unsigned char **out, unsigned int *outlen, void *arg); > -#endif > - > static ngx_int_t ngx_http_ssl_static_variable(ngx_http_request_t *r, > ngx_http_variable_value_t *v, uintptr_t data); > static ngx_int_t ngx_http_ssl_variable(ngx_http_request_t *r, > ngx_http_variable_value_t *v, uintptr_t data); > > static ngx_int_t ngx_http_ssl_add_variables(ngx_conf_t *cf); > static void *ngx_http_ssl_create_srv_conf(ngx_conf_t *cf); > static char *ngx_http_ssl_merge_srv_conf(ngx_conf_t *cf, > @@ -308,113 +297,21 @@ static ngx_http_variable_t ngx_http_ssl > (uintptr_t) ngx_ssl_get_client_verify, NGX_HTTP_VAR_CHANGEABLE, 0 }, > > { ngx_null_string, NULL, NULL, 0, 0, 0 } > }; > > > static ngx_str_t ngx_http_ssl_sess_id_ctx = ngx_string("HTTP"); > > - > -#ifdef TLSEXT_TYPE_application_layer_protocol_negotiation > - > -static int > -ngx_http_ssl_alpn_select(ngx_ssl_conn_t *ssl_conn, const unsigned char **out, > - unsigned char *outlen, const unsigned char *in, unsigned int inlen, > - void *arg) > -{ > - unsigned int srvlen; > - unsigned char *srv; > -#if (NGX_DEBUG) > - unsigned int i; > -#endif > #if (NGX_HTTP_V2) > - ngx_http_connection_t *hc; > -#endif > -#if (NGX_HTTP_V2 || NGX_DEBUG) > - ngx_connection_t *c; > - > - c = ngx_ssl_get_connection(ssl_conn); > -#endif > - > -#if (NGX_DEBUG) > - for (i = 0; i < inlen; i += in[i] + 1) { > - ngx_log_debug2(NGX_LOG_DEBUG_HTTP, c->log, 0, > - "SSL ALPN supported by client: %*s", > - (size_t) in[i], &in[i + 1]); > - } > -#endif > - > -#if (NGX_HTTP_V2) > - hc = c->data; > - > - if (hc->addr_conf->http2) { > - srv = > - (unsigned char *) NGX_HTTP_V2_ALPN_ADVERTISE NGX_HTTP_NPN_ADVERTISE; > - srvlen = sizeof(NGX_HTTP_V2_ALPN_ADVERTISE NGX_HTTP_NPN_ADVERTISE) - 1; > - > - } else > +static ngx_str_t ngx_http_ssl_proto_neg_h2 = ngx_string( > + NGX_HTTP_V2_ALPN_ADVERTISE NGX_HTTP_NPN_ADVERTISE); > #endif > - { > - srv = (unsigned char *) NGX_HTTP_NPN_ADVERTISE; > - srvlen = sizeof(NGX_HTTP_NPN_ADVERTISE) - 1; > - } > - > - if (SSL_select_next_proto((unsigned char **) out, outlen, srv, srvlen, > - in, inlen) > - != OPENSSL_NPN_NEGOTIATED) > - { > - return SSL_TLSEXT_ERR_NOACK; > - } > - > - ngx_log_debug2(NGX_LOG_DEBUG_HTTP, c->log, 0, > - "SSL ALPN selected: %*s", (size_t) *outlen, *out); > - > - return SSL_TLSEXT_ERR_OK; > -} > - > -#endif > - > - > -#ifdef TLSEXT_TYPE_next_proto_neg > - > -static int > -ngx_http_ssl_npn_advertised(ngx_ssl_conn_t *ssl_conn, > - const unsigned char **out, unsigned int *outlen, void *arg) > -{ > -#if (NGX_HTTP_V2 || NGX_DEBUG) > - ngx_connection_t *c; > - > - c = ngx_ssl_get_connection(ssl_conn); > - ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0, "SSL NPN advertised"); > -#endif > - > -#if (NGX_HTTP_V2) > - { > - ngx_http_connection_t *hc; > - > - hc = c->data; > - > - if (hc->addr_conf->http2) { > - *out = > - (unsigned char *) NGX_HTTP_V2_NPN_ADVERTISE NGX_HTTP_NPN_ADVERTISE; > - *outlen = sizeof(NGX_HTTP_V2_NPN_ADVERTISE NGX_HTTP_NPN_ADVERTISE) - 1; > - > - return SSL_TLSEXT_ERR_OK; > - } > - } > -#endif > - > - *out = (unsigned char *) NGX_HTTP_NPN_ADVERTISE; > - *outlen = sizeof(NGX_HTTP_NPN_ADVERTISE) - 1; > - > - return SSL_TLSEXT_ERR_OK; > -} > - > -#endif > +static ngx_str_t ngx_http_ssl_proto_neg_h1 = ngx_string(NGX_HTTP_NPN_ADVERTISE); Defining C strings and then defining ngx_str_t using these strings looks wierd. It may be a better idea to just define appropriate strings here, much like it's done with ngx_http_ssl_sess_id_ctx. > > > static ngx_int_t > ngx_http_ssl_static_variable(ngx_http_request_t *r, > ngx_http_variable_value_t *v, uintptr_t data) > { > ngx_ssl_variable_handler_pt handler = (ngx_ssl_variable_handler_pt) data; > > @@ -536,16 +433,17 @@ ngx_http_ssl_create_srv_conf(ngx_conf_t > > return sscf; > } > > > static char * > ngx_http_ssl_merge_srv_conf(ngx_conf_t *cf, void *parent, void *child) > { > + ngx_str_t *proto_neg = &ngx_http_ssl_proto_neg_h1; > ngx_http_ssl_srv_conf_t *prev = parent; > ngx_http_ssl_srv_conf_t *conf = child; > > ngx_pool_cleanup_t *cln; This looks wrong at least from style point of view. The prev/conf case is of very specific cases when variables can be declared and initialized at the same time. All other variables are expected to be defined after an empty line (see "cln"), and initialized separately. > > if (conf->enable == NGX_CONF_UNSET) { > if (prev->enable == NGX_CONF_UNSET) { > conf->enable = 0; > @@ -660,24 +558,27 @@ ngx_http_ssl_merge_srv_conf(ngx_conf_t * > ngx_log_error(NGX_LOG_WARN, cf->log, 0, > "nginx was built with SNI support, however, now it is linked " > "dynamically to an OpenSSL library which has no tlsext support, " > "therefore SNI is not available"); > } > > #endif > > -#ifdef TLSEXT_TYPE_application_layer_protocol_negotiation > - SSL_CTX_set_alpn_select_cb(conf->ssl.ctx, ngx_http_ssl_alpn_select, NULL); > -#endif > +#if (NGX_HTTP_V2) > + { > + ngx_connection_t *c = ngx_ssl_get_connection(conf->ssl.ctx); > + ngx_http_connection_t *hc = c->data; > > -#ifdef TLSEXT_TYPE_next_proto_neg > - SSL_CTX_set_next_protos_advertised_cb(conf->ssl.ctx, > - ngx_http_ssl_npn_advertised, NULL); > + if (hc->addr_conf->http2) { > + proto_neg = &ngx_http_ssl_proto_neg_h2; > + } > + } This looks completely wrong: no connection is expected to be available during configuration merging. And compilation fails accordingly: src/http/modules/ngx_http_ssl_module.c:568:54: error: incompatible pointer types passing 'SSL_CTX *' (aka 'struct ssl_ctx_st *') to parameter of type 'const SSL *' (aka 'const struct ssl_st *') [-Werror,-Wincompatible-pointer-types] ngx_connection_t *c = ngx_ssl_get_connection(conf->ssl.ctx); ^~~~~~~~~~~~~ > #endif > + ngx_ssl_protocol_negotiation(cf, &conf->ssl, proto_neg); > > cln = ngx_pool_cleanup_add(cf->pool, 0); > if (cln == NULL) { > return NGX_CONF_ERROR; > } > > cln->handler = ngx_ssl_cleanup_ctx; > cln->data = &conf->ssl; > > _______________________________________________ > nginx-devel mailing list > nginx-devel at nginx.org > http://mailman.nginx.org/mailman/listinfo/nginx-devel -- Maxim Dounin http://nginx.org/ From arut at nginx.com Wed Jun 22 08:50:35 2016 From: arut at nginx.com (Roman Arutyunyan) Date: Wed, 22 Jun 2016 08:50:35 +0000 Subject: [nginx] Stream: use ngx_pcalloc() in ngx_stream_proxy_bind(). Message-ID: details: http://hg.nginx.org/nginx/rev/4a724d6006ee branches: changeset: 6598:4a724d6006ee user: Roman Arutyunyan date: Wed Jun 22 11:50:02 2016 +0300 description: Stream: use ngx_pcalloc() in ngx_stream_proxy_bind(). diffstat: src/stream/ngx_stream_proxy_module.c | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diffs (12 lines): diff -r 0a820872dd4c -r 4a724d6006ee src/stream/ngx_stream_proxy_module.c --- a/src/stream/ngx_stream_proxy_module.c Mon Jun 20 15:11:50 2016 +0300 +++ b/src/stream/ngx_stream_proxy_module.c Wed Jun 22 11:50:02 2016 +0300 @@ -1713,7 +1713,7 @@ ngx_stream_proxy_bind(ngx_conf_t *cf, ng return NGX_CONF_OK; } - local = ngx_palloc(cf->pool, sizeof(ngx_stream_upstream_local_t)); + local = ngx_pcalloc(cf->pool, sizeof(ngx_stream_upstream_local_t)); if (local == NULL) { return NGX_CONF_ERROR; } From arut at nginx.com Wed Jun 22 08:50:38 2016 From: arut at nginx.com (Roman Arutyunyan) Date: Wed, 22 Jun 2016 08:50:38 +0000 Subject: [nginx] Style. Message-ID: details: http://hg.nginx.org/nginx/rev/191e23214dfb branches: changeset: 6599:191e23214dfb user: Roman Arutyunyan date: Wed Jun 22 11:50:02 2016 +0300 description: Style. diffstat: src/stream/ngx_stream_proxy_module.c | 1 - 1 files changed, 0 insertions(+), 1 deletions(-) diffs (11 lines): diff -r 4a724d6006ee -r 191e23214dfb src/stream/ngx_stream_proxy_module.c --- a/src/stream/ngx_stream_proxy_module.c Wed Jun 22 11:50:02 2016 +0300 +++ b/src/stream/ngx_stream_proxy_module.c Wed Jun 22 11:50:02 2016 +0300 @@ -1753,7 +1753,6 @@ ngx_stream_proxy_bind(ngx_conf_t *cf, ng if (ngx_strcmp(value[2].data, "transparent") == 0) { #if (NGX_HAVE_TRANSPARENT_PROXY) local->transparent = 1; - #else ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "transparent proxying is not supported " From thierry.magnien at sfr.com Wed Jun 22 09:31:12 2016 From: thierry.magnien at sfr.com (MAGNIEN, Thierry) Date: Wed, 22 Jun 2016 09:31:12 +0000 Subject: [module dev] PCRE compiled code lost at reload Message-ID: <5D103CE839D50E4CBC62C9FD7B83287C01F146087B@EXCN015.encara.local.ads> Hi, I'm experiencing a strange behavior and I wonder if I'm missing something obvious... I've developed a module and I use shared memory and slab allocations to keep data unique across workers and have data survive a reload. Everything works fine except one single thing: PCRE compiled codes (ngx_regex_compile_t->regex->code). To be more precise, at reload, in my module init function, I recompile some of the PCRE if they have changed, still using shared memory. What I notice is that, just after init module function has returned, all dying workers lose PCRE compiled code (regex->code = 0), where all new created workers correctly get new compiled code. I tried to use my own pcre_malloc function in order to be sure memory is allocated in shared memory (and this *is* the case), but without success. So any help is welcome: does anyone have a clue about why only those data are "lost" by dying workers ? Thanks a lot for your help, Thierry Magnien P.S.: I can't exhibit code for confidentiality reasons but if no one has a clue, I'll try to write a very simple module, only to exhibit this behavior. From serg.brester at sebres.de Wed Jun 22 09:47:33 2016 From: serg.brester at sebres.de (Sergey Brester) Date: Wed, 22 Jun 2016 11:47:33 +0200 Subject: [module dev] PCRE compiled code lost at reload In-Reply-To: <5D103CE839D50E4CBC62C9FD7B83287C01F146087B@EXCN015.encara.local.ads> References: <5D103CE839D50E4CBC62C9FD7B83287C01F146087B@EXCN015.encara.local.ads> Message-ID: <33d69d4856c84921dd4c794cf2d3a6ca@sebres.de> A little bit off-topic, but which benefits you think, you will get using cross process compiled regexp? The compiling of regex is normally fast operation, that will be done only once (even jit), and can be done in each worker. What I cannot imagine, is the sharing of the result of regexp execution. But not the regexp self. Regards, sebres. 22.06.2016 11:31, MAGNIEN, Thierry wrote: > Hi, > > I'm experiencing a strange behavior and I wonder if I'm missing something obvious... > > I've developed a module and I use shared memory and slab allocations to keep data unique across workers and have data survive a reload. > > Everything works fine except one single thing: PCRE compiled codes (ngx_regex_compile_t->regex->code). > > To be more precise, at reload, in my module init function, I recompile some of the PCRE if they have changed, still using shared memory. What I notice is that, just after init module function has returned, all dying workers lose PCRE compiled code (regex->code = 0), where all new created workers correctly get new compiled code. > > I tried to use my own pcre_malloc function in order to be sure memory is allocated in shared memory (and this *is* the case), but without success. > > So any help is welcome: does anyone have a clue about why only those data are "lost" by dying workers ? > > Thanks a lot for your help, > Thierry Magnien > > P.S.: I can't exhibit code for confidentiality reasons but if no one has a clue, I'll try to write a very simple module, only to exhibit this behavior. > > _______________________________________________ > nginx-devel mailing list > nginx-devel at nginx.org > http://mailman.nginx.org/mailman/listinfo/nginx-devel [1] Links: ------ [1] http://mailman.nginx.org/mailman/listinfo/nginx-devel -------------- next part -------------- An HTML attachment was scrubbed... URL: From thierry.magnien at sfr.com Wed Jun 22 09:58:52 2016 From: thierry.magnien at sfr.com (MAGNIEN, Thierry) Date: Wed, 22 Jun 2016 09:58:52 +0000 Subject: [module dev] PCRE compiled code lost at reload In-Reply-To: <33d69d4856c84921dd4c794cf2d3a6ca@sebres.de> References: <5D103CE839D50E4CBC62C9FD7B83287C01F146087B@EXCN015.encara.local.ads> <33d69d4856c84921dd4c794cf2d3a6ca@sebres.de> Message-ID: <5D103CE839D50E4CBC62C9FD7B83287C01F1460998@EXCN015.encara.local.ads> Hi, My data are not located in a configuration file, all data can be updated in real-time without reloading. A single POST request triggers update of the information by the worker that handles the request and all workers can then use updated information simultaneously. There may be possibilities to bypass the issue but so far, I?d like to understand why only this specific piece of data is lost, where everything else is kept. Regards, Thierry De : Sergey Brester [mailto:serg.brester at sebres.de] Envoy? : mercredi 22 juin 2016 11:48 ? : nginx-devel at nginx.org Cc : MAGNIEN, Thierry Objet : Re: [module dev] PCRE compiled code lost at reload A little bit off-topic, but which benefits you think, you will get using cross process compiled regexp? The compiling of regex is normally fast operation, that will be done only once (even jit), and can be done in each worker. What I cannot imagine, is the sharing of the result of regexp execution. But not the regexp self. Regards, sebres. 22.06.2016 11:31, MAGNIEN, Thierry wrote: Hi, I'm experiencing a strange behavior and I wonder if I'm missing something obvious... I've developed a module and I use shared memory and slab allocations to keep data unique across workers and have data survive a reload. Everything works fine except one single thing: PCRE compiled codes (ngx_regex_compile_t->regex->code). To be more precise, at reload, in my module init function, I recompile some of the PCRE if they have changed, still using shared memory. What I notice is that, just after init module function has returned, all dying workers lose PCRE compiled code (regex->code = 0), where all new created workers correctly get new compiled code. I tried to use my own pcre_malloc function in order to be sure memory is allocated in shared memory (and this *is* the case), but without success. So any help is welcome: does anyone have a clue about why only those data are "lost" by dying workers ? Thanks a lot for your help, Thierry Magnien P.S.: I can't exhibit code for confidentiality reasons but if no one has a clue, I'll try to write a very simple module, only to exhibit this behavior. _______________________________________________ nginx-devel mailing list nginx-devel at nginx.org http://mailman.nginx.org/mailman/listinfo/nginx-devel -------------- next part -------------- An HTML attachment was scrubbed... URL: From mdounin at mdounin.ru Wed Jun 22 13:49:12 2016 From: mdounin at mdounin.ru (Maxim Dounin) Date: Wed, 22 Jun 2016 16:49:12 +0300 Subject: [module dev] PCRE compiled code lost at reload In-Reply-To: <5D103CE839D50E4CBC62C9FD7B83287C01F146087B@EXCN015.encara.local.ads> References: <5D103CE839D50E4CBC62C9FD7B83287C01F146087B@EXCN015.encara.local.ads> Message-ID: <20160622134912.GC30781@mdounin.ru> Hello! On Wed, Jun 22, 2016 at 09:31:12AM +0000, MAGNIEN, Thierry wrote: > I'm experiencing a strange behavior and I wonder if I'm missing > something obvious... > > I've developed a module and I use shared memory and slab > allocations to keep data unique across workers and have data > survive a reload. > > Everything works fine except one single thing: PCRE compiled > codes (ngx_regex_compile_t->regex->code). > > To be more precise, at reload, in my module init function, I > recompile some of the PCRE if they have changed, still using > shared memory. What I notice is that, just after init module > function has returned, all dying workers lose PCRE compiled code > (regex->code = 0), where all new created workers correctly get > new compiled code. > > I tried to use my own pcre_malloc function in order to be sure > memory is allocated in shared memory (and this *is* the case), > but without success. > > So any help is welcome: does anyone have a clue about why only > those data are "lost" by dying workers ? Regex compilation via ngx_regex_compile() uses memory from a pool provided via ngx_regex_compile_t (rc->pool). This memory will be freed when a pool will be destroyed. See rc/core/ngx_regex.c for details. -- Maxim Dounin http://nginx.org/ From thierry.magnien at sfr.com Wed Jun 22 14:21:51 2016 From: thierry.magnien at sfr.com (MAGNIEN, Thierry) Date: Wed, 22 Jun 2016 14:21:51 +0000 Subject: [module dev] PCRE compiled code lost at reload In-Reply-To: <20160622134912.GC30781@mdounin.ru> References: <5D103CE839D50E4CBC62C9FD7B83287C01F146087B@EXCN015.encara.local.ads>, <20160622134912.GC30781@mdounin.ru> Message-ID: <5D103CE839D50E4CBC62C9FD7B83287C01F1460CC9@EXCN015.encara.local.ads> Hi Maxim, Thanks for your response. I already saw that, and that's why I use a dedicated pool in shared memory for regex compilation. All my ngx_regex_compile_t structs allocate from this unique pool. Could pool in shared memory be automatically freed when reloading ? And in that case, why would new workers get the correct value ? Is there a place where memory is duplicated between workers before dying/start of workers ? Thanks a lot, Thierry ________________________________________ De : nginx-devel [nginx-devel-bounces at nginx.org] de la part de Maxim Dounin [mdounin at mdounin.ru] Envoy? : mercredi 22 juin 2016 15:49 ? : nginx-devel at nginx.org Objet : Re: [module dev] PCRE compiled code lost at reload Hello! On Wed, Jun 22, 2016 at 09:31:12AM +0000, MAGNIEN, Thierry wrote: > I'm experiencing a strange behavior and I wonder if I'm missing > something obvious... > > I've developed a module and I use shared memory and slab > allocations to keep data unique across workers and have data > survive a reload. > > Everything works fine except one single thing: PCRE compiled > codes (ngx_regex_compile_t->regex->code). > > To be more precise, at reload, in my module init function, I > recompile some of the PCRE if they have changed, still using > shared memory. What I notice is that, just after init module > function has returned, all dying workers lose PCRE compiled code > (regex->code = 0), where all new created workers correctly get > new compiled code. > > I tried to use my own pcre_malloc function in order to be sure > memory is allocated in shared memory (and this *is* the case), > but without success. > > So any help is welcome: does anyone have a clue about why only > those data are "lost" by dying workers ? Regex compilation via ngx_regex_compile() uses memory from a pool provided via ngx_regex_compile_t (rc->pool). This memory will be freed when a pool will be destroyed. See rc/core/ngx_regex.c for details. -- Maxim Dounin http://nginx.org/ _______________________________________________ nginx-devel mailing list nginx-devel at nginx.org http://mailman.nginx.org/mailman/listinfo/nginx-devel From mdounin at mdounin.ru Wed Jun 22 14:27:08 2016 From: mdounin at mdounin.ru (Maxim Dounin) Date: Wed, 22 Jun 2016 17:27:08 +0300 Subject: [module dev] PCRE compiled code lost at reload In-Reply-To: <5D103CE839D50E4CBC62C9FD7B83287C01F1460CC9@EXCN015.encara.local.ads> References: <5D103CE839D50E4CBC62C9FD7B83287C01F146087B@EXCN015.encara.local.ads> <20160622134912.GC30781@mdounin.ru> <5D103CE839D50E4CBC62C9FD7B83287C01F1460CC9@EXCN015.encara.local.ads> Message-ID: <20160622142708.GD30781@mdounin.ru> Hello! On Wed, Jun 22, 2016 at 02:21:51PM +0000, MAGNIEN, Thierry wrote: > Thanks for your response. I already saw that, and that's why I > use a dedicated pool in shared memory for regex compilation. All > my ngx_regex_compile_t structs allocate from this unique pool. > Could pool in shared memory be automatically freed when > reloading ? And in that case, why would new workers get the > correct value ? Is there a place where memory is duplicated > between workers before dying/start of workers ? There are no pools in shared memory in nginx - except ngx_slab_pool_t, which is quite different from normal memory pools and cannot be used in ngx_regex_compile_t. -- Maxim Dounin http://nginx.org/ From thierry.magnien at sfr.com Wed Jun 22 14:49:36 2016 From: thierry.magnien at sfr.com (MAGNIEN, Thierry) Date: Wed, 22 Jun 2016 14:49:36 +0000 Subject: [module dev] PCRE compiled code lost at reload In-Reply-To: <20160622142708.GD30781@mdounin.ru> References: <5D103CE839D50E4CBC62C9FD7B83287C01F146087B@EXCN015.encara.local.ads> <20160622134912.GC30781@mdounin.ru> <5D103CE839D50E4CBC62C9FD7B83287C01F1460CC9@EXCN015.encara.local.ads>, <20160622142708.GD30781@mdounin.ru> Message-ID: <5D103CE839D50E4CBC62C9FD7B83287C01F1460D76@EXCN015.encara.local.ads> Hi, I think I start understanding what's wrong. Let me explain what I've done: I have a ngx_http_mymodule_data_t struct which include this: ngx_pool_t *regex_pool; After initializing my data struct in shared memory, I do something like this: my_data->regex_pool = ngx_create_pool(REGEX_POOL_SIZE, cycle->log); Later, at regex compilation, I use this: my_regex.pool = ((ngx_http_mymodule_data_t *)(sr_shm_zone->data))->regex_pool; And if I understand correctly, the pool created by ngx_create_pool gets freed. Am I right ? If so, is there a possibility to use a pool that would survive reload ? Thanks, Thierry ________________________________________ De : nginx-devel [nginx-devel-bounces at nginx.org] de la part de Maxim Dounin [mdounin at mdounin.ru] Envoy? : mercredi 22 juin 2016 16:27 ? : nginx-devel at nginx.org Objet : Re: [module dev] PCRE compiled code lost at reload Hello! On Wed, Jun 22, 2016 at 02:21:51PM +0000, MAGNIEN, Thierry wrote: > Thanks for your response. I already saw that, and that's why I > use a dedicated pool in shared memory for regex compilation. All > my ngx_regex_compile_t structs allocate from this unique pool. > Could pool in shared memory be automatically freed when > reloading ? And in that case, why would new workers get the > correct value ? Is there a place where memory is duplicated > between workers before dying/start of workers ? There are no pools in shared memory in nginx - except ngx_slab_pool_t, which is quite different from normal memory pools and cannot be used in ngx_regex_compile_t. -- Maxim Dounin http://nginx.org/ _______________________________________________ nginx-devel mailing list nginx-devel at nginx.org http://mailman.nginx.org/mailman/listinfo/nginx-devel From mdounin at mdounin.ru Wed Jun 22 14:59:21 2016 From: mdounin at mdounin.ru (Maxim Dounin) Date: Wed, 22 Jun 2016 17:59:21 +0300 Subject: [module dev] PCRE compiled code lost at reload In-Reply-To: <5D103CE839D50E4CBC62C9FD7B83287C01F1460D76@EXCN015.encara.local.ads> References: <5D103CE839D50E4CBC62C9FD7B83287C01F146087B@EXCN015.encara.local.ads> <20160622134912.GC30781@mdounin.ru> <5D103CE839D50E4CBC62C9FD7B83287C01F1460CC9@EXCN015.encara.local.ads> <20160622142708.GD30781@mdounin.ru> <5D103CE839D50E4CBC62C9FD7B83287C01F1460D76@EXCN015.encara.local.ads> Message-ID: <20160622145921.GE30781@mdounin.ru> Hello! On Wed, Jun 22, 2016 at 02:49:36PM +0000, MAGNIEN, Thierry wrote: > I think I start understanding what's wrong. > > Let me explain what I've done: > > I have a ngx_http_mymodule_data_t struct which include this: > ngx_pool_t *regex_pool; > > After initializing my data struct in shared memory, I do something like this: > my_data->regex_pool = ngx_create_pool(REGEX_POOL_SIZE, cycle->log); > > Later, at regex compilation, I use this: > my_regex.pool = ((ngx_http_mymodule_data_t *)(sr_shm_zone->data))->regex_pool; This is not going to work. The "regex_pool" here is just a pointer to a pool somewhere in process memory. And each process has it's own pool, if at all. It likely seems to work (i.e., don't cause immediate segfault) because you create the pool in the master process, hence all processes has copies of the pool. But it doesn't make the data allocated from such pools shared. -- Maxim Dounin http://nginx.org/ From thierry.magnien at sfr.com Wed Jun 22 15:03:10 2016 From: thierry.magnien at sfr.com (MAGNIEN, Thierry) Date: Wed, 22 Jun 2016 15:03:10 +0000 Subject: [module dev] PCRE compiled code lost at reload In-Reply-To: <20160622145921.GE30781@mdounin.ru> References: <5D103CE839D50E4CBC62C9FD7B83287C01F146087B@EXCN015.encara.local.ads> <20160622134912.GC30781@mdounin.ru> <5D103CE839D50E4CBC62C9FD7B83287C01F1460CC9@EXCN015.encara.local.ads> <20160622142708.GD30781@mdounin.ru> <5D103CE839D50E4CBC62C9FD7B83287C01F1460D76@EXCN015.encara.local.ads>, <20160622145921.GE30781@mdounin.ru> Message-ID: <5D103CE839D50E4CBC62C9FD7B83287C01F1460E0F@EXCN015.encara.local.ads> OK, this clears up things. Thanks a lot! Thierry ________________________________________ De : nginx-devel [nginx-devel-bounces at nginx.org] de la part de Maxim Dounin [mdounin at mdounin.ru] Envoy? : mercredi 22 juin 2016 16:59 ? : nginx-devel at nginx.org Objet : Re: [module dev] PCRE compiled code lost at reload Hello! On Wed, Jun 22, 2016 at 02:49:36PM +0000, MAGNIEN, Thierry wrote: > I think I start understanding what's wrong. > > Let me explain what I've done: > > I have a ngx_http_mymodule_data_t struct which include this: > ngx_pool_t *regex_pool; > > After initializing my data struct in shared memory, I do something like this: > my_data->regex_pool = ngx_create_pool(REGEX_POOL_SIZE, cycle->log); > > Later, at regex compilation, I use this: > my_regex.pool = ((ngx_http_mymodule_data_t *)(sr_shm_zone->data))->regex_pool; This is not going to work. The "regex_pool" here is just a pointer to a pool somewhere in process memory. And each process has it's own pool, if at all. It likely seems to work (i.e., don't cause immediate segfault) because you create the pool in the master process, hence all processes has copies of the pool. But it doesn't make the data allocated from such pools shared. -- Maxim Dounin http://nginx.org/ _______________________________________________ nginx-devel mailing list nginx-devel at nginx.org http://mailman.nginx.org/mailman/listinfo/nginx-devel From lists.md at gmail.com Wed Jun 22 19:05:17 2016 From: lists.md at gmail.com (Marcelo MD) Date: Wed, 22 Jun 2016 16:05:17 -0300 Subject: [PATCH] Pass configuration options to PCRE build Message-ID: # HG changeset patch # User Marcelo Mallmann # Date 1466622014 10800 # Wed Jun 22 16:00:14 2016 -0300 # Node ID 3458ac42b0ce4e004516411eeab5a960253c1eac # Parent 191e23214dfbaf01255d421f5bbe0d5541d03a2f Pass configuration options to PCRE build Add '--with-pcre-conf-opt' option which passes its args to pcre's 'configure' step. diff -r 191e23214dfb -r 3458ac42b0ce auto/options --- a/auto/options Wed Jun 22 11:50:02 2016 +0300 +++ b/auto/options Wed Jun 22 16:00:14 2016 -0300 @@ -327,6 +327,7 @@ --without-pcre) USE_PCRE=DISABLED ;; --with-pcre) USE_PCRE=YES ;; --with-pcre=*) PCRE="$value" ;; + --with-pcre-conf-opt=*) PCRE_CONF_OPT="$value" ;; --with-pcre-opt=*) PCRE_OPT="$value" ;; --with-pcre-jit) PCRE_JIT=YES ;; @@ -508,6 +509,7 @@ --without-pcre disable PCRE library usage --with-pcre force PCRE library usage --with-pcre=DIR set path to PCRE library sources + --with-pcre-conf-opt=OPTIONS set additional configuration options for PCRE --with-pcre-opt=OPTIONS set additional build options for PCRE --with-pcre-jit build PCRE with JIT compilation support -- Marcelo Mallmann Dias -------------- next part -------------- An HTML attachment was scrubbed... URL: From piotrsikora at google.com Wed Jun 22 20:52:57 2016 From: piotrsikora at google.com (Piotr Sikora) Date: Wed, 22 Jun 2016 13:52:57 -0700 Subject: [PATCH] HTTP/2: style Message-ID: <6f69e3c0f780e29bca75.1466628777@piotrsikora.sfo.corp.google.com> # HG changeset patch # User Piotr Sikora # Date 1466628474 25200 # Wed Jun 22 13:47:54 2016 -0700 # Node ID 6f69e3c0f780e29bca752fc1f938f4a459a1ec59 # Parent 191e23214dfbaf01255d421f5bbe0d5541d03a2f HTTP/2: style. Signed-off-by: Piotr Sikora diff -r 191e23214dfb -r 6f69e3c0f780 src/http/v2/ngx_http_v2_filter_module.c --- a/src/http/v2/ngx_http_v2_filter_module.c +++ b/src/http/v2/ngx_http_v2_filter_module.c @@ -974,12 +974,11 @@ static ngx_http_v2_out_frame_t * ngx_http_v2_filter_get_data_frame(ngx_http_v2_stream_t *stream, size_t len, ngx_chain_t *first, ngx_chain_t *last) { - u_char flags; - ngx_buf_t *buf; - ngx_chain_t *cl; + u_char flags; + ngx_buf_t *buf; + ngx_chain_t *cl; ngx_http_v2_out_frame_t *frame; - frame = stream->free_frames; if (frame) { @@ -1007,7 +1006,7 @@ ngx_http_v2_filter_get_data_frame(ngx_ht buf = cl->buf; - if (!buf->start) { + if (buf->start == NULL) { buf->start = ngx_palloc(stream->request->pool, NGX_HTTP_V2_FRAME_HEADER_SIZE); if (buf->start == NULL) { @@ -1182,7 +1181,6 @@ ngx_http_v2_data_frame_handler(ngx_http_ ngx_http_v2_stream_t *stream; stream = frame->stream; - cl = frame->first; if (cl->buf->tag == (ngx_buf_tag_t) &ngx_http_v2_module) { From piotrsikora at google.com Wed Jun 22 20:53:11 2016 From: piotrsikora at google.com (Piotr Sikora) Date: Wed, 22 Jun 2016 13:53:11 -0700 Subject: [PATCH] Headers filter: style Message-ID: <0419e0ead3d63b8d96f5.1466628791@piotrsikora.sfo.corp.google.com> # HG changeset patch # User Piotr Sikora # Date 1466628475 25200 # Wed Jun 22 13:47:55 2016 -0700 # Node ID 0419e0ead3d63b8d96f59fc3c74b36bf9f3fe188 # Parent 191e23214dfbaf01255d421f5bbe0d5541d03a2f Headers filter: style. Signed-off-by: Piotr Sikora diff -r 191e23214dfb -r 0419e0ead3d6 src/http/modules/ngx_http_headers_filter_module.c --- a/src/http/modules/ngx_http_headers_filter_module.c +++ b/src/http/modules/ngx_http_headers_filter_module.c @@ -151,7 +151,7 @@ ngx_http_headers_filter(ngx_http_request { ngx_str_t value; ngx_uint_t i, safe_status; - ngx_http_header_val_t *h; + ngx_http_header_val_t *hv; ngx_http_headers_conf_t *conf; conf = ngx_http_get_module_loc_conf(r, ngx_http_headers_filter_module); @@ -188,18 +188,18 @@ ngx_http_headers_filter(ngx_http_request } if (conf->headers) { - h = conf->headers->elts; + hv = conf->headers->elts; for (i = 0; i < conf->headers->nelts; i++) { - if (!safe_status && !h[i].always) { + if (!safe_status && !hv[i].always) { continue; } - if (ngx_http_complex_value(r, &h[i].value, &value) != NGX_OK) { + if (ngx_http_complex_value(r, &hv[i].value, &value) != NGX_OK) { return NGX_ERROR; } - if (h[i].handler(r, &h[i], &value) != NGX_OK) { + if (hv[i].handler(r, &hv[i], &value) != NGX_OK) { return NGX_ERROR; } } From hongzhidao at gmail.com Thu Jun 23 03:52:40 2016 From: hongzhidao at gmail.com (=?UTF-8?B?5rSq5b+X6YGT?=) Date: Thu, 23 Jun 2016 11:52:40 +0800 Subject: top n url Message-ID: Hi, Is it possible to find the top 100 urls by visits in real time? You know I dose not want to find the infos from the log file. B.R. -------------- next part -------------- An HTML attachment was scrubbed... URL: From massimiliano.bellomi at gmail.com Thu Jun 23 07:58:04 2016 From: massimiliano.bellomi at gmail.com (Massimiliano Bellomi) Date: Thu, 23 Jun 2016 09:58:04 +0200 Subject: Dynamic module not binary compatible Message-ID: Hi all, is there a way to avoid the module signature check if (ngx_strcmp(module->signature, NGX_MODULE_SIGNATURE) != 0) { ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "module \"%V\" is not binary compatible", file); return NGX_ERROR; } on nginx startup ? I would like to build a dynamic module and make it compatible with a version of nginx regardless of options used in ./configure -Massimiliano -------------- next part -------------- An HTML attachment was scrubbed... URL: From mdounin at mdounin.ru Thu Jun 23 12:20:53 2016 From: mdounin at mdounin.ru (Maxim Dounin) Date: Thu, 23 Jun 2016 15:20:53 +0300 Subject: Dynamic module not binary compatible In-Reply-To: References: Message-ID: <20160623122053.GH30781@mdounin.ru> Hello! On Thu, Jun 23, 2016 at 09:58:04AM +0200, Massimiliano Bellomi wrote: > Hi all, > > is there a way to avoid the module signature check > > if (ngx_strcmp(module->signature, NGX_MODULE_SIGNATURE) != 0) { > ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, > "module \"%V\" is not binary compatible", > file); > return NGX_ERROR; > } > > on nginx startup ? > > I would like to build a dynamic module and make it compatible with a > version of nginx regardless of options used in ./configure Depending on configure options layout of various nginx structures differs, and an attempt to load a module which was compiled with different configure options will likely result in a segmentation fault sooner or later. The binary complatibility check is to prevent such segmentation faults. We are currently working on reduing number of options that cause binary incompatibilities. The goal is to reduce number of such options to the bare minimum. It yet to happen though. For now, generic approach is: compile a module for a particular nginx main binary, and use the same configure options as was used to compile the binary. -- Maxim Dounin http://nginx.org/ From mdounin at mdounin.ru Thu Jun 23 12:31:16 2016 From: mdounin at mdounin.ru (Maxim Dounin) Date: Thu, 23 Jun 2016 15:31:16 +0300 Subject: [PATCH] Headers filter: style In-Reply-To: <0419e0ead3d63b8d96f5.1466628791@piotrsikora.sfo.corp.google.com> References: <0419e0ead3d63b8d96f5.1466628791@piotrsikora.sfo.corp.google.com> Message-ID: <20160623123116.GJ30781@mdounin.ru> Hello! On Wed, Jun 22, 2016 at 01:53:11PM -0700, Piotr Sikora wrote: > # HG changeset patch > # User Piotr Sikora > # Date 1466628475 25200 > # Wed Jun 22 13:47:55 2016 -0700 > # Node ID 0419e0ead3d63b8d96f59fc3c74b36bf9f3fe188 > # Parent 191e23214dfbaf01255d421f5bbe0d5541d03a2f > Headers filter: style. > > Signed-off-by: Piotr Sikora > > diff -r 191e23214dfb -r 0419e0ead3d6 src/http/modules/ngx_http_headers_filter_module.c > --- a/src/http/modules/ngx_http_headers_filter_module.c > +++ b/src/http/modules/ngx_http_headers_filter_module.c > @@ -151,7 +151,7 @@ ngx_http_headers_filter(ngx_http_request > { > ngx_str_t value; > ngx_uint_t i, safe_status; > - ngx_http_header_val_t *h; > + ngx_http_header_val_t *hv; > ngx_http_headers_conf_t *conf; > > conf = ngx_http_get_module_loc_conf(r, ngx_http_headers_filter_module); > @@ -188,18 +188,18 @@ ngx_http_headers_filter(ngx_http_request > } > > if (conf->headers) { > - h = conf->headers->elts; > + hv = conf->headers->elts; > for (i = 0; i < conf->headers->nelts; i++) { > > - if (!safe_status && !h[i].always) { > + if (!safe_status && !hv[i].always) { > continue; > } > > - if (ngx_http_complex_value(r, &h[i].value, &value) != NGX_OK) { > + if (ngx_http_complex_value(r, &hv[i].value, &value) != NGX_OK) { > return NGX_ERROR; > } > > - if (h[i].handler(r, &h[i], &value) != NGX_OK) { > + if (hv[i].handler(r, &hv[i], &value) != NGX_OK) { > return NGX_ERROR; > } > } I would rather not. The "hv" is used to refer to a particular ngx_http_header_val_t, while "h" here is an array of elements. -- Maxim Dounin http://nginx.org/ From vbart at nginx.com Thu Jun 23 14:17:04 2016 From: vbart at nginx.com (Valentin Bartenev) Date: Thu, 23 Jun 2016 14:17:04 +0000 Subject: [nginx] HTTP/2: style. Message-ID: details: http://hg.nginx.org/nginx/rev/6f69e3c0f780 branches: changeset: 6600:6f69e3c0f780 user: Piotr Sikora date: Wed Jun 22 13:47:54 2016 -0700 description: HTTP/2: style. Signed-off-by: Piotr Sikora diffstat: src/http/v2/ngx_http_v2_filter_module.c | 10 ++++------ 1 files changed, 4 insertions(+), 6 deletions(-) diffs (36 lines): diff -r 191e23214dfb -r 6f69e3c0f780 src/http/v2/ngx_http_v2_filter_module.c --- a/src/http/v2/ngx_http_v2_filter_module.c Wed Jun 22 11:50:02 2016 +0300 +++ b/src/http/v2/ngx_http_v2_filter_module.c Wed Jun 22 13:47:54 2016 -0700 @@ -974,12 +974,11 @@ static ngx_http_v2_out_frame_t * ngx_http_v2_filter_get_data_frame(ngx_http_v2_stream_t *stream, size_t len, ngx_chain_t *first, ngx_chain_t *last) { - u_char flags; - ngx_buf_t *buf; - ngx_chain_t *cl; + u_char flags; + ngx_buf_t *buf; + ngx_chain_t *cl; ngx_http_v2_out_frame_t *frame; - frame = stream->free_frames; if (frame) { @@ -1007,7 +1006,7 @@ ngx_http_v2_filter_get_data_frame(ngx_ht buf = cl->buf; - if (!buf->start) { + if (buf->start == NULL) { buf->start = ngx_palloc(stream->request->pool, NGX_HTTP_V2_FRAME_HEADER_SIZE); if (buf->start == NULL) { @@ -1182,7 +1181,6 @@ ngx_http_v2_data_frame_handler(ngx_http_ ngx_http_v2_stream_t *stream; stream = frame->stream; - cl = frame->first; if (cl->buf->tag == (ngx_buf_tag_t) &ngx_http_v2_module) { From vbart at nginx.com Thu Jun 23 14:18:46 2016 From: vbart at nginx.com (Valentin V. Bartenev) Date: Thu, 23 Jun 2016 17:18:46 +0300 Subject: [PATCH] HTTP/2: style In-Reply-To: <6f69e3c0f780e29bca75.1466628777@piotrsikora.sfo.corp.google.com> References: <6f69e3c0f780e29bca75.1466628777@piotrsikora.sfo.corp.google.com> Message-ID: <28209009.oGMsJNVqhP@vbart-workstation> On Wednesday 22 June 2016 13:52:57 Piotr Sikora wrote: > # HG changeset patch > # User Piotr Sikora > # Date 1466628474 25200 > # Wed Jun 22 13:47:54 2016 -0700 > # Node ID 6f69e3c0f780e29bca752fc1f938f4a459a1ec59 > # Parent 191e23214dfbaf01255d421f5bbe0d5541d03a2f > HTTP/2: style. > > Signed-off-by: Piotr Sikora > [..] Thanks! http://hg.nginx.org/nginx/rev/6f69e3c0f780 wbr, Valentin V. Bartenev From piotrsikora at google.com Thu Jun 23 16:53:37 2016 From: piotrsikora at google.com (Piotr Sikora) Date: Thu, 23 Jun 2016 09:53:37 -0700 Subject: [PATCH] Headers filter: style In-Reply-To: <20160623123116.GJ30781@mdounin.ru> References: <0419e0ead3d63b8d96f5.1466628791@piotrsikora.sfo.corp.google.com> <20160623123116.GJ30781@mdounin.ru> Message-ID: Hey Maxim, > I would rather not. The "hv" is used to refer to a particular > ngx_http_header_val_t, while "h" here is an array of elements. But "h" is used throughout the codebase for ngx_table_elt_t, which makes this particular case confusing. Also, "h" is used for ngx_table_elt_t regardless of whether it points to a particular item or an array, so your argument isn't consistent with the current style. Best regards, Piotr Sikora From mdounin at mdounin.ru Thu Jun 23 19:09:39 2016 From: mdounin at mdounin.ru (Maxim Dounin) Date: Thu, 23 Jun 2016 22:09:39 +0300 Subject: [PATCH] Headers filter: style In-Reply-To: References: <0419e0ead3d63b8d96f5.1466628791@piotrsikora.sfo.corp.google.com> <20160623123116.GJ30781@mdounin.ru> Message-ID: <20160623190939.GS30781@mdounin.ru> Hello! On Thu, Jun 23, 2016 at 09:53:37AM -0700, Piotr Sikora wrote: > Hey Maxim, > > > I would rather not. The "hv" is used to refer to a particular > > ngx_http_header_val_t, while "h" here is an array of elements. > > But "h" is used throughout the codebase for ngx_table_elt_t, which > makes this particular case confusing. > > Also, "h" is used for ngx_table_elt_t regardless of whether it points > to a particular item or an array, so your argument isn't consistent > with the current style. The "h" is used for variables of various types, including ngx_http_file_cache_header_t, ngx_str_t, ngx_keyval_t, ngx_table_elt_t, ngx_http_fastcgi_header_t, ngx_uint_t, uin32_t, and int. It's just a convenient short name for a variable. -- Maxim Dounin http://nginx.org/ From piotrsikora at google.com Thu Jun 23 19:45:43 2016 From: piotrsikora at google.com (Piotr Sikora) Date: Thu, 23 Jun 2016 12:45:43 -0700 Subject: [PATCH] Headers filter: style In-Reply-To: <20160623190939.GS30781@mdounin.ru> References: <0419e0ead3d63b8d96f5.1466628791@piotrsikora.sfo.corp.google.com> <20160623123116.GJ30781@mdounin.ru> <20160623190939.GS30781@mdounin.ru> Message-ID: Hey Maxim, > The "h" is used for variables of various types, including > ngx_http_file_cache_header_t, ngx_str_t, ngx_keyval_t, > ngx_table_elt_t, ngx_http_fastcgi_header_t, ngx_uint_t, uin32_t, > and int. It's just a convenient short name for a variable. But it's the only place in the codebase where it's used for ngx_http_header_val_t, it's "hv" everywhere else. Anyway, EOT. Best regards, Piotr Sikora From hongzhidao at gmail.com Fri Jun 24 05:58:55 2016 From: hongzhidao at gmail.com (=?UTF-8?B?5rSq5b+X6YGT?=) Date: Fri, 24 Jun 2016 13:58:55 +0800 Subject: [PATCH] Headers filter: style In-Reply-To: References: <0419e0ead3d63b8d96f5.1466628791@piotrsikora.sfo.corp.google.com> <20160623123116.GJ30781@mdounin.ru> <20160623190939.GS30781@mdounin.ru> Message-ID: I think the name is more meaning in the *context*. So as like Maxim said, "It's just a convenient short name". 2016-06-24 3:45 GMT+08:00 Piotr Sikora : > Hey Maxim, > > > The "h" is used for variables of various types, including > > ngx_http_file_cache_header_t, ngx_str_t, ngx_keyval_t, > > ngx_table_elt_t, ngx_http_fastcgi_header_t, ngx_uint_t, uin32_t, > > and int. It's just a convenient short name for a variable. > > But it's the only place in the codebase where it's used for > ngx_http_header_val_t, it's "hv" everywhere else. > > Anyway, EOT. > > Best regards, > Piotr Sikora > > _______________________________________________ > nginx-devel mailing list > nginx-devel at nginx.org > http://mailman.nginx.org/mailman/listinfo/nginx-devel > -------------- next part -------------- An HTML attachment was scrubbed... URL: From piotrsikora at google.com Sun Jun 26 23:13:15 2016 From: piotrsikora at google.com (Piotr Sikora) Date: Sun, 26 Jun 2016 16:13:15 -0700 Subject: [PATCH 1 of 2] HTTP: add support for trailers in HTTP responses Message-ID: # HG changeset patch # User Piotr Sikora # Date 1466735480 25200 # Thu Jun 23 19:31:20 2016 -0700 # Node ID a96187a9806536ab2a8bf3fa7f7b659cf5d3ff13 # Parent 6f69e3c0f780e29bca752fc1f938f4a459a1ec59 HTTP: add support for trailers in HTTP responses. Example: ngx_table_elt_t *h; h = ngx_list_push(&r->headers_out.trailers); if (h == NULL) { return NGX_ERROR; } ngx_str_set(&h->key, "Fun"); ngx_str_set(&h->value, "with trailers"); h->hash = ngx_hash_key_lc(h->key.data, h->key.len); The code above adds "Fun: with trailers" trailer to the response to the request with "TE: trailers" header (which indicates support for trailers). Note that trailers MUST be added before last buffer of the response (last_buf = 1) reaches chunked or v2 output filters, otherwise they are going to be ignored. Signed-off-by: Piotr Sikora diff -r 6f69e3c0f780 -r a96187a98065 src/http/modules/ngx_http_chunked_filter_module.c --- a/src/http/modules/ngx_http_chunked_filter_module.c +++ b/src/http/modules/ngx_http_chunked_filter_module.c @@ -17,6 +17,7 @@ typedef struct { static ngx_int_t ngx_http_chunked_filter_init(ngx_conf_t *cf); +static ngx_chain_t *ngx_http_chunked_get_trailers(ngx_http_request_t *r); static ngx_http_module_t ngx_http_chunked_filter_module_ctx = { @@ -69,28 +70,31 @@ ngx_http_chunked_header_filter(ngx_http_ return ngx_http_next_header_filter(r); } - if (r->headers_out.content_length_n == -1) { + clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module); + + if (clcf->chunked_transfer_encoding && r->trailers_ok) { + ngx_http_clear_content_length(r); + r->chunked = 1; + + } else if (r->headers_out.content_length_n == -1) { if (r->http_version < NGX_HTTP_VERSION_11) { r->keepalive = 0; + } else if (clcf->chunked_transfer_encoding) { + r->chunked = 1; + } else { - clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module); + r->keepalive = 0; + } + } - if (clcf->chunked_transfer_encoding) { - r->chunked = 1; + if (r->chunked) { + ctx = ngx_pcalloc(r->pool, sizeof(ngx_http_chunked_filter_ctx_t)); + if (ctx == NULL) { + return NGX_ERROR; + } - ctx = ngx_pcalloc(r->pool, - sizeof(ngx_http_chunked_filter_ctx_t)); - if (ctx == NULL) { - return NGX_ERROR; - } - - ngx_http_set_ctx(r, ctx, ngx_http_chunked_filter_module); - - } else { - r->keepalive = 0; - } - } + ngx_http_set_ctx(r, ctx, ngx_http_chunked_filter_module); } return ngx_http_next_header_filter(r); @@ -201,6 +205,15 @@ ngx_http_chunked_body_filter(ngx_http_re b->pos += 2; } + if (r->trailers_ok) { + tl->next = ngx_http_chunked_get_trailers(r); + + if (tl->next != NULL) { + b->last -= 2; + b->last_buf = 0; + } + } + } else if (size > 0) { tl = ngx_chain_get_free_buf(r->pool, &ctx->free); if (tl == NULL) { @@ -230,6 +243,108 @@ ngx_http_chunked_body_filter(ngx_http_re } +static ngx_chain_t * +ngx_http_chunked_get_trailers(ngx_http_request_t *r) +{ + size_t len; + ngx_buf_t *b; + ngx_uint_t i; + ngx_chain_t *cl; + ngx_list_part_t *part; + ngx_table_elt_t *header; + ngx_http_chunked_filter_ctx_t *ctx; + + len = 0; + + part = &r->headers_out.trailers.part; + header = part->elts; + + for (i = 0; /* void */; i++) { + + if (i >= part->nelts) { + if (part->next == NULL) { + break; + } + + part = part->next; + header = part->elts; + i = 0; + } + + if (header[i].hash == 0) { + continue; + } + + len += header[i].key.len + sizeof(": ") - 1 + header[i].value.len + + sizeof(CRLF) - 1; + } + + if (len == 0) { + return NULL; + } + + len += sizeof(CRLF) - 1; + + ctx = ngx_http_get_module_ctx(r, ngx_http_chunked_filter_module); + + cl = ngx_chain_get_free_buf(r->pool, &ctx->free); + if (cl == NULL) { + return NULL; + } + + b = cl->buf; + + b->tag = (ngx_buf_tag_t) &ngx_http_chunked_filter_module; + b->temporary = 0; + b->memory = 1; + b->last_buf = 1; + + b->start = ngx_palloc(r->pool, len); + if (b->start == NULL) { + return NULL; + } + + b->end = b->last + len; + b->pos = b->start; + b->last = b->start; + + part = &r->headers_out.trailers.part; + header = part->elts; + + for (i = 0; /* void */; i++) { + + if (i >= part->nelts) { + if (part->next == NULL) { + break; + } + + part = part->next; + header = part->elts; + i = 0; + } + + if (header[i].hash == 0) { + continue; + } + + ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, + "http trailer: \"%V: %V\"", + &header[i].key, &header[i].value); + + b->last = ngx_copy(b->last, header[i].key.data, header[i].key.len); + *b->last++ = ':'; *b->last++ = ' '; + + b->last = ngx_copy(b->last, header[i].value.data, header[i].value.len); + *b->last++ = CR; *b->last++ = LF; + } + + /* the end of HTTP trailer */ + *b->last++ = CR; *b->last++ = LF; + + return cl; +} + + static ngx_int_t ngx_http_chunked_filter_init(ngx_conf_t *cf) { diff -r 6f69e3c0f780 -r a96187a98065 src/http/ngx_http_request.c --- a/src/http/ngx_http_request.c +++ b/src/http/ngx_http_request.c @@ -29,6 +29,8 @@ static ngx_int_t ngx_http_process_connec ngx_table_elt_t *h, ngx_uint_t offset); static ngx_int_t ngx_http_process_user_agent(ngx_http_request_t *r, ngx_table_elt_t *h, ngx_uint_t offset); +static ngx_int_t ngx_http_process_te(ngx_http_request_t *r, + ngx_table_elt_t *h, ngx_uint_t offset); static ngx_int_t ngx_http_validate_host(ngx_str_t *host, ngx_pool_t *pool, ngx_uint_t alloc); @@ -125,6 +127,10 @@ ngx_http_header_t ngx_http_headers_in[] offsetof(ngx_http_headers_in_t, if_range), ngx_http_process_unique_header_line }, + { ngx_string("TE"), + offsetof(ngx_http_headers_in_t, te), + ngx_http_process_te }, + { ngx_string("Transfer-Encoding"), offsetof(ngx_http_headers_in_t, transfer_encoding), ngx_http_process_header_line }, @@ -559,6 +565,14 @@ ngx_http_create_request(ngx_connection_t return NULL; } + if (ngx_list_init(&r->headers_out.trailers, r->pool, 4, + sizeof(ngx_table_elt_t)) + != NGX_OK) + { + ngx_destroy_pool(r->pool); + return NULL; + } + r->ctx = ngx_pcalloc(r->pool, sizeof(void *) * ngx_http_max_module); if (r->ctx == NULL) { ngx_destroy_pool(r->pool); @@ -1737,6 +1751,59 @@ ngx_http_process_user_agent(ngx_http_req static ngx_int_t +ngx_http_process_te(ngx_http_request_t *r, ngx_table_elt_t *h, + ngx_uint_t offset) +{ + u_char *p; + + if (ngx_http_process_multi_header_lines(r, h, offset) != NGX_OK) { + return NGX_ERROR; + } + + if (r->http_version < NGX_HTTP_VERSION_11) { + return NGX_OK; + } + + if (h->value.len == sizeof("trailers") - 1 + && ngx_memcmp(h->value.data, "trailers", sizeof("trailers") - 1) == 0) + { + r->trailers_ok = 1; + return NGX_OK; + } + + if (r->http_version >= NGX_HTTP_VERSION_20) { + ngx_log_error(NGX_LOG_INFO, r->connection->log, 0, + "client sent HTTP/2 request with invalid value \"%V\" " + "in \"TE\" header", &h->value); + + ngx_http_finalize_request(r, NGX_HTTP_BAD_REQUEST); + return NGX_ERROR; + } + + if (h->value.len < sizeof("trailers") - 1) { + return NGX_OK; + } + + p = ngx_strcasestrn(h->value.data, "trailers", sizeof("trailers") - 2); + if (p == NULL) { + return NGX_OK; + } + + if (p == h->value.data || *(p - 1) == ',' || *(p - 1) == ' ') { + + p += sizeof("trailers") - 1; + + if (p == h->value.data + h->value.len || *p == ',' || *p == ' ') { + r->trailers_ok = 1; + return NGX_OK; + } + } + + return NGX_OK; +} + + +static ngx_int_t ngx_http_process_multi_header_lines(ngx_http_request_t *r, ngx_table_elt_t *h, ngx_uint_t offset) { diff -r 6f69e3c0f780 -r a96187a98065 src/http/ngx_http_request.h --- a/src/http/ngx_http_request.h +++ b/src/http/ngx_http_request.h @@ -189,6 +189,7 @@ typedef struct { ngx_table_elt_t *range; ngx_table_elt_t *if_range; + ngx_array_t te; ngx_table_elt_t *transfer_encoding; ngx_table_elt_t *expect; ngx_table_elt_t *upgrade; @@ -245,6 +246,7 @@ typedef struct { typedef struct { ngx_list_t headers; + ngx_list_t trailers; ngx_uint_t status; ngx_str_t status_line; @@ -514,6 +516,7 @@ struct ngx_http_request_s { unsigned pipeline:1; unsigned chunked:1; unsigned header_only:1; + unsigned trailers_ok:1; unsigned keepalive:1; unsigned lingering_close:1; unsigned discard_body:1; diff -r 6f69e3c0f780 -r a96187a98065 src/http/v2/ngx_http_v2_filter_module.c --- a/src/http/v2/ngx_http_v2_filter_module.c +++ b/src/http/v2/ngx_http_v2_filter_module.c @@ -56,7 +56,9 @@ static u_char *ngx_http_v2_string_encode static u_char *ngx_http_v2_write_int(u_char *pos, ngx_uint_t prefix, ngx_uint_t value); static ngx_http_v2_out_frame_t *ngx_http_v2_create_headers_frame( - ngx_http_request_t *r, u_char *pos, u_char *end); + ngx_http_request_t *r, u_char *pos, u_char *end, ngx_uint_t fin); +static ngx_http_v2_out_frame_t *ngx_http_v2_create_trailers_frame( + ngx_http_request_t *r); static ngx_chain_t *ngx_http_v2_send_chain(ngx_connection_t *fc, ngx_chain_t *in, off_t limit); @@ -571,7 +573,7 @@ ngx_http_v2_header_filter(ngx_http_reque header[i].value.len, tmp); } - frame = ngx_http_v2_create_headers_frame(r, start, pos); + frame = ngx_http_v2_create_headers_frame(r, start, pos, r->header_only); if (frame == NULL) { return NGX_ERROR; } @@ -595,6 +597,121 @@ ngx_http_v2_header_filter(ngx_http_reque } +static ngx_http_v2_out_frame_t * +ngx_http_v2_create_trailers_frame(ngx_http_request_t *r) +{ + u_char *pos, *start, *tmp; + size_t len, tmp_len; + ngx_uint_t i; + ngx_list_part_t *part; + ngx_table_elt_t *header; + + len = 0; + tmp_len = 0; + + part = &r->headers_out.trailers.part; + header = part->elts; + + for (i = 0; /* void */; i++) { + + if (i >= part->nelts) { + if (part->next == NULL) { + break; + } + + part = part->next; + header = part->elts; + i = 0; + } + + if (header[i].hash == 0) { + continue; + } + + if (header[i].key.len > NGX_HTTP_V2_MAX_FIELD) { + ngx_log_error(NGX_LOG_WARN, r->connection->log, 0, + "ignoring too long response trailer name: \"%V\"", + &header[i].key); + continue; + } + + if (header[i].value.len > NGX_HTTP_V2_MAX_FIELD) { + ngx_log_error(NGX_LOG_WARN, r->connection->log, 0, + "ignoring too long response trailer value: " + "\"%V: %V\"", &header[i].key, &header[i].value); + continue; + } + + len += 1 + NGX_HTTP_V2_INT_OCTETS + header[i].key.len + + NGX_HTTP_V2_INT_OCTETS + header[i].value.len; + + if (header[i].key.len > tmp_len) { + tmp_len = header[i].key.len; + } + + if (header[i].value.len > tmp_len) { + tmp_len = header[i].value.len; + } + } + + if (len == 0) { + return NULL; + } + + tmp = ngx_palloc(r->pool, tmp_len); + pos = ngx_pnalloc(r->pool, len); + + if (pos == NULL || tmp == NULL) { + return NULL; + } + + start = pos; + + part = &r->headers_out.trailers.part; + header = part->elts; + + for (i = 0; /* void */; i++) { + + if (i >= part->nelts) { + if (part->next == NULL) { + break; + } + + part = part->next; + header = part->elts; + i = 0; + } + + if (header[i].hash == 0 + || header[i].key.len > NGX_HTTP_V2_MAX_FIELD + || header[i].value.len > NGX_HTTP_V2_MAX_FIELD) + { + continue; + } + +#if (NGX_DEBUG) + if (r->connection->log->log_level & NGX_LOG_DEBUG_HTTP) { + ngx_strlow(tmp, header[i].key.data, header[i].key.len); + + ngx_log_debug3(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, + "http2 output trailer: \"%*s: %V\"", + header[i].key.len, tmp, &header[i].value); + } +#endif + + *pos++ = 0; + + pos = ngx_http_v2_write_name(pos, header[i].key.data, + header[i].key.len, tmp); + + pos = ngx_http_v2_write_value(pos, header[i].value.data, + header[i].value.len, tmp); + } + + return ngx_http_v2_create_headers_frame(r, start, pos, 1); +} + + static u_char * ngx_http_v2_string_encode(u_char *dst, u_char *src, size_t len, u_char *tmp, ngx_uint_t lower) @@ -645,7 +762,7 @@ ngx_http_v2_write_int(u_char *pos, ngx_u static ngx_http_v2_out_frame_t * ngx_http_v2_create_headers_frame(ngx_http_request_t *r, u_char *pos, - u_char *end) + u_char *end, ngx_uint_t fin) { u_char type, flags; size_t rest, frame_size; @@ -666,12 +783,12 @@ ngx_http_v2_create_headers_frame(ngx_htt frame->stream = stream; frame->length = rest; frame->blocked = 1; - frame->fin = r->header_only; + frame->fin = fin; ll = &frame->first; type = NGX_HTTP_V2_HEADERS_FRAME; - flags = r->header_only ? NGX_HTTP_V2_END_STREAM_FLAG : NGX_HTTP_V2_NO_FLAG; + flags = fin ? NGX_HTTP_V2_END_STREAM_FLAG : NGX_HTTP_V2_NO_FLAG; frame_size = stream->connection->frame_size; for ( ;; ) { @@ -733,7 +850,7 @@ ngx_http_v2_create_headers_frame(ngx_htt continue; } - b->last_buf = r->header_only; + b->last_buf = fin; cl->next = NULL; frame->last = cl; @@ -755,7 +872,7 @@ ngx_http_v2_send_chain(ngx_connection_t ngx_http_request_t *r; ngx_http_v2_stream_t *stream; ngx_http_v2_loc_conf_t *h2lcf; - ngx_http_v2_out_frame_t *frame; + ngx_http_v2_out_frame_t *frame, *trailers; ngx_http_v2_connection_t *h2c; r = fc->data; @@ -829,6 +946,8 @@ ngx_http_v2_send_chain(ngx_connection_t frame_size = (h2lcf->chunk_size < h2c->frame_size) ? h2lcf->chunk_size : h2c->frame_size; + trailers = NULL; + #if (NGX_SUPPRESS_WARN) cl = NULL; #endif @@ -891,6 +1010,13 @@ ngx_http_v2_send_chain(ngx_connection_t size -= rest; } + if (cl->buf->last_buf && r->trailers_ok) { + trailers = ngx_http_v2_create_trailers_frame(r); + if (trailers) { + cl->buf->last_buf = 0; + } + } + frame = ngx_http_v2_filter_get_data_frame(stream, frame_size, out, cl); if (frame == NULL) { return NGX_CHAIN_ERROR; @@ -903,6 +1029,11 @@ ngx_http_v2_send_chain(ngx_connection_t stream->send_window -= frame_size; stream->queued++; + if (trailers) { + ngx_http_v2_queue_frame(h2c, trailers); + stream->queued++; + } + if (in == NULL) { break; } From piotrsikora at google.com Sun Jun 26 23:13:16 2016 From: piotrsikora at google.com (Piotr Sikora) Date: Sun, 26 Jun 2016 16:13:16 -0700 Subject: [PATCH 2 of 2] Headers filter: add "add_trailer" directive In-Reply-To: References: Message-ID: # HG changeset patch # User Piotr Sikora # Date 1466735587 25200 # Thu Jun 23 19:33:07 2016 -0700 # Node ID e21760ce55fdae50a6723aeb4cb6e0b0bcf73dcb # Parent a96187a9806536ab2a8bf3fa7f7b659cf5d3ff13 Headers filter: add "add_trailer" directive. Trailers added using this directive are evaluated after response body is processed by output filters (but before it's written to the wire), so it's possible to use variables calculated from the response body as the trailer value. Signed-off-by: Piotr Sikora diff -r a96187a98065 -r e21760ce55fd src/http/modules/ngx_http_chunked_filter_module.c --- a/src/http/modules/ngx_http_chunked_filter_module.c +++ b/src/http/modules/ngx_http_chunked_filter_module.c @@ -254,6 +254,10 @@ ngx_http_chunked_get_trailers(ngx_http_r ngx_table_elt_t *header; ngx_http_chunked_filter_ctx_t *ctx; + if (ngx_http_eval_trailers(r) != NGX_OK) { + return NULL; + } + len = 0; part = &r->headers_out.trailers.part; diff -r a96187a98065 -r e21760ce55fd src/http/modules/ngx_http_headers_filter_module.c --- a/src/http/modules/ngx_http_headers_filter_module.c +++ b/src/http/modules/ngx_http_headers_filter_module.c @@ -48,6 +48,7 @@ typedef struct { time_t expires_time; ngx_http_complex_value_t *expires_value; ngx_array_t *headers; + ngx_array_t *trailers; } ngx_http_headers_conf_t; @@ -72,6 +73,8 @@ static char *ngx_http_headers_expires(ng void *conf); static char *ngx_http_headers_add(ngx_conf_t *cf, ngx_command_t *cmd, void *conf); +static char *ngx_http_headers_add_trailer(ngx_conf_t *cf, ngx_command_t *cmd, + void *conf); static ngx_http_set_header_t ngx_http_set_headers[] = { @@ -108,6 +111,14 @@ static ngx_command_t ngx_http_headers_f 0, NULL}, + { ngx_string("add_trailer"), + NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_HTTP_LIF_CONF + |NGX_CONF_TAKE23, + ngx_http_headers_add_trailer, + NGX_HTTP_LOC_CONF_OFFSET, + 0, + NULL}, + ngx_null_command }; @@ -149,15 +160,23 @@ static ngx_http_output_header_filter_pt static ngx_int_t ngx_http_headers_filter(ngx_http_request_t *r) { + u_char *p, *data; + size_t len; ngx_str_t value; ngx_uint_t i, safe_status; + ngx_table_elt_t *t; ngx_http_header_val_t *h; ngx_http_headers_conf_t *conf; + if (r != r->main) { + return ngx_http_next_header_filter(r); + } + conf = ngx_http_get_module_loc_conf(r, ngx_http_headers_filter_module); - if ((conf->expires == NGX_HTTP_EXPIRES_OFF && conf->headers == NULL) - || r != r->main) + if (conf->expires == NGX_HTTP_EXPIRES_OFF + && conf->headers == NULL + && conf->trailers == NULL) { return ngx_http_next_header_filter(r); } @@ -205,6 +224,64 @@ ngx_http_headers_filter(ngx_http_request } } + if (conf->trailers && r->trailers_ok) { + len = 0; + + h = conf->trailers->elts; + for (i = 0; i < conf->trailers->nelts; i++) { + + if (!safe_status && !h[i].always) { + continue; + } + + if (h[i].value.value.len) { + len += h[i].key.len + sizeof(", ") - 1; + } + } + + if (len == 0) { + return ngx_http_next_header_filter(r); + } + + len -= sizeof(", ") - 1; + + t = ngx_list_push(&r->headers_out.headers); + if (t == NULL) { + return NGX_ERROR; + } + + data = ngx_pnalloc(r->pool, len); + if (data == NULL) { + return NGX_ERROR; + } + + p = data; + + h = conf->trailers->elts; + for (i = 0; i < conf->trailers->nelts; i++) { + + if (!safe_status && !h[i].always) { + continue; + } + + if (h[i].value.value.len) { + p = ngx_copy(p, h[i].key.data, h[i].key.len); + + if (p == data + len) { + break; + } + + *p++ = ','; *p++ = ' '; + } + } + + ngx_str_set(&t->key, "Trailer"); + t->value.data = data; + t->value.len = len; + t->hash = ngx_hash(ngx_hash(ngx_hash(ngx_hash(ngx_hash( + ngx_hash('t', 'r'), 'a'), 'i'), 'l'), 'e'), 'r'); + } + return ngx_http_next_header_filter(r); } @@ -541,6 +618,67 @@ ngx_http_set_response_header(ngx_http_re } +ngx_int_t +ngx_http_eval_trailers(ngx_http_request_t *r) +{ + ngx_str_t value; + ngx_uint_t i, safe_status; + ngx_table_elt_t *t; + ngx_http_header_val_t *h; + ngx_http_headers_conf_t *conf; + + conf = ngx_http_get_module_loc_conf(r, ngx_http_headers_filter_module); + + if (conf->trailers == NULL) { + return NGX_OK; + } + + switch (r->headers_out.status) { + + case NGX_HTTP_OK: + case NGX_HTTP_CREATED: + case NGX_HTTP_NO_CONTENT: + case NGX_HTTP_PARTIAL_CONTENT: + case NGX_HTTP_MOVED_PERMANENTLY: + case NGX_HTTP_MOVED_TEMPORARILY: + case NGX_HTTP_SEE_OTHER: + case NGX_HTTP_NOT_MODIFIED: + case NGX_HTTP_TEMPORARY_REDIRECT: + safe_status = 1; + break; + + default: + safe_status = 0; + break; + } + + h = conf->trailers->elts; + for (i = 0; i < conf->trailers->nelts; i++) { + + if (!safe_status && !h[i].always) { + continue; + } + + if (ngx_http_complex_value(r, &h[i].value, &value) != NGX_OK) { + return NGX_ERROR; + } + + if (value.len) { + t = ngx_list_push(&r->headers_out.trailers); + if (t == NULL) { + return NGX_ERROR; + } + + t->key = h[i].key; + t->value = value; + t->hash = 1; + } + } + + return NGX_OK; +} + + static void * ngx_http_headers_create_conf(ngx_conf_t *cf) { @@ -555,6 +693,7 @@ ngx_http_headers_create_conf(ngx_conf_t * set by ngx_pcalloc(): * * conf->headers = NULL; + * conf->trailers = NULL; * conf->expires_time = 0; * conf->expires_value = NULL; */ @@ -585,6 +724,10 @@ ngx_http_headers_merge_conf(ngx_conf_t * conf->headers = prev->headers; } + if (conf->trailers == NULL) { + conf->trailers = prev->trailers; + } + return NGX_CONF_OK; } @@ -739,3 +882,63 @@ ngx_http_headers_add(ngx_conf_t *cf, ngx return NGX_CONF_OK; } + + +static char * +ngx_http_headers_add_trailer(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) +{ + ngx_http_headers_conf_t *hcf = conf; + + ngx_str_t *value; + ngx_http_header_val_t *hv; + ngx_http_compile_complex_value_t ccv; + + value = cf->args->elts; + + if (hcf->trailers == NULL) { + hcf->trailers = ngx_array_create(cf->pool, 1, + sizeof(ngx_http_header_val_t)); + if (hcf->trailers == NULL) { + return NGX_CONF_ERROR; + } + } + + hv = ngx_array_push(hcf->trailers); + if (hv == NULL) { + return NGX_CONF_ERROR; + } + + hv->key = value[1]; + hv->handler = NULL; + hv->offset = 0; + hv->always = 0; + + if (value[2].len == 0) { + ngx_memzero(&hv->value, sizeof(ngx_http_complex_value_t)); + + } else { + ngx_memzero(&ccv, sizeof(ngx_http_compile_complex_value_t)); + + ccv.cf = cf; + ccv.value = &value[2]; + ccv.complex_value = &hv->value; + + if (ngx_http_compile_complex_value(&ccv) != NGX_OK) { + return NGX_CONF_ERROR; + } + } + + if (cf->args->nelts == 3) { + return NGX_CONF_OK; + } + + if (ngx_strcmp(value[3].data, "always") != 0) { + ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, + "invalid parameter \"%V\"", &value[3]); + return NGX_CONF_ERROR; + } + + hv->always = 1; + + return NGX_CONF_OK; +} diff -r a96187a98065 -r e21760ce55fd src/http/ngx_http.h --- a/src/http/ngx_http.h +++ b/src/http/ngx_http.h @@ -146,6 +146,7 @@ ngx_int_t ngx_http_special_response_hand ngx_int_t ngx_http_filter_finalize_request(ngx_http_request_t *r, ngx_module_t *m, ngx_int_t error); void ngx_http_clean_header(ngx_http_request_t *r); +ngx_int_t ngx_http_eval_trailers(ngx_http_request_t *r); ngx_int_t ngx_http_discard_request_body(ngx_http_request_t *r); diff -r a96187a98065 -r e21760ce55fd src/http/v2/ngx_http_v2_filter_module.c --- a/src/http/v2/ngx_http_v2_filter_module.c +++ b/src/http/v2/ngx_http_v2_filter_module.c @@ -606,6 +606,10 @@ ngx_http_v2_create_trailers_frame(ngx_ht ngx_list_part_t *part; ngx_table_elt_t *header; + if (ngx_http_eval_trailers(r) != NGX_OK) { + return NULL; + } + len = 0; tmp_len = 0; From amdeich at gmail.com Mon Jun 27 09:30:19 2016 From: amdeich at gmail.com (Andrey Kulikov) Date: Mon, 27 Jun 2016 12:30:19 +0300 Subject: Part of debug log in reply instead of reply if nginx runs under debugger. Message-ID: Hello, I stuck in rather strange situation: if I run nginx under debugger, and request zero-length file it gives me correct reply on first connection. But on second connection it reply it output part of debug log (what supposed to be written to debug log, but wasn't). At the same time if nginx runs normally (without debugger attached) - everything works as it should. Is is normal situation when nginx runs under debugger? I run everything on Debian 8.5 # uname -a Linux ng18 3.16.0-4-amd64 #1 SMP Debian 3.16.7-ckt25-2 (2016-04-08) x86_64 GNU/Linux # nginx -V nginx version: nginx/1.10.1 built by gcc 4.9.2 (Debian 4.9.2-10) configure arguments: --with-debug My nginx.conf file: =========================== worker_processes 1; daemon on; master_process off; error_log /root/devel/ngx_module/url-rewrite-nginx-module/t/servroot/logs/error.log debug; pid /root/devel/ngx_module/url-rewrite-nginx-module/t/servroot/logs/nginx.pid; http { access_log /root/devel/ngx_module/url-rewrite-nginx-module/t/servroot/logs/access.log; default_type text/plain; keepalive_timeout 68; server { listen 1984; server_name 'localhost'; client_max_body_size 30M; default_type text/html; client_body_buffer_size 1; client_header_buffer_size 1; proxy_buffer_size 1; chunked_transfer_encoding off; location /t { root /root/devel/ngx_module/url-rewrite-nginx-module/t/servroot/html; } location / { root /root/devel/ngx_module/url-rewrite-nginx-module/t/servroot/html; index index.html index.htm; } } } events { accept_mutex off; worker_connections 64; } =========================== Debug log: =========================== 2016/06/27 12:24:28 [debug] 32736#0: bind() 0.0.0.0:1984 #6 2016/06/27 12:24:28 [notice] 32736#0: using the "epoll" event method 2016/06/27 12:24:28 [notice] 32736#0: nginx/1.10.1 2016/06/27 12:24:28 [notice] 32736#0: built by gcc 4.9.2 (Debian 4.9.2-10) 2016/06/27 12:24:28 [notice] 32736#0: OS: Linux 3.16.0-4-amd64 2016/06/27 12:24:28 [notice] 32736#0: getrlimit(RLIMIT_NOFILE): 65536:65536 2016/06/27 12:24:30 [notice] 32736#0: signal 1 (SIGHUP) received, reconfiguring 2016/06/27 12:24:30 [debug] 32743#0: write: 7, 00007FFFFFFFE060, 6, 0 2016/06/27 12:24:30 [debug] 32743#0: notify eventfd: 7 2016/06/27 12:24:30 [debug] 32743#0: malloc: 00000000006E3340:6144 2016/06/27 12:24:30 [debug] 32743#0: malloc: 00000000006DA310:13824 2016/06/27 12:24:30 [debug] 32743#0: malloc: 00000000006E4B50:6144 2016/06/27 12:24:30 [debug] 32743#0: malloc: 00000000006F5600:6144 2016/06/27 12:24:30 [debug] 32743#0: epoll add event: fd:6 op:1 ev:00002001 2016/06/27 12:24:30 [debug] 32743#0: worker cycle 2016/06/27 12:24:30 [debug] 32743#0: epoll timer: -1 2016/06/27 12:24:45 [debug] 32743#0: epoll: fd:6 ev:0001 d:00000000006DA310 2016/06/27 12:24:45 [debug] 32743#0: accept on 0.0.0.0:1984, ready: 0 2016/06/27 12:24:45 [debug] 32743#0: posix_memalign: 00000000006E6360:512 @16 2016/06/27 12:24:45 [debug] 32743#0: *1 accept: 127.0.0.1:34417 fd:8 2016/06/27 12:24:45 [debug] 32743#0: *1 event timer add: 8: 60000:1467019545151 2016/06/27 12:24:45 [debug] 32743#0: *1 reusable connection: 1 2016/06/27 12:24:45 [debug] 32743#0: *1 epoll add event: fd:8 op:1 ev:80002001 2016/06/27 12:24:45 [debug] 32743#0: timer delta: 16289 2016/06/27 12:24:45 [notice] 32743#0: reconfiguring 2016/06/27 12:24:45 [debug] 32743#0: posix_memalign: 00000000006F6E10:16384 @16 2016/06/27 12:24:45 [debug] 32743#0: posix_memalign: 00000000006FAE20:16384 @16 2016/06/27 12:24:45 [debug] 32743#0: malloc: 00000000006FEE30:4096 2016/06/27 12:24:45 [debug] 32743#0: read: 9, 00000000006FEE30, 985, 0 2016/06/27 12:24:45 [debug] 32743#0: malloc: 00000000006FFE40:4280 2016/06/27 12:24:45 [debug] 32743#0: malloc: 0000000000700F00:4280 2016/06/27 12:24:45 [debug] 32743#0: malloc: 0000000000701FC0:4280 2016/06/27 12:24:45 [debug] 32743#0: malloc: 0000000000703080:4280 2016/06/27 12:24:45 [debug] 32743#0: malloc: 0000000000704140:4280 2016/06/27 12:24:45 [debug] 32743#0: malloc: 0000000000705200:4280 2016/06/27 12:24:45 [debug] 32743#0: posix_memalign: 00000000007062C0:16384 @16 2016/06/27 12:24:45 [debug] 32743#0: malloc: 000000000070A2D0:4096 2016/06/27 12:24:45 [debug] 32743#0: posix_memalign: 000000000070B2E0:16384 @16 2016/06/27 12:24:45 [debug] 32743#0: malloc: 00000000006DD920:2048 2016/06/27 12:24:45 [debug] 32743#0: add cleanup: 000000000070E000 2016/06/27 12:24:45 [debug] 32743#0: malloc: 00000000006D5730:408 2016/06/27 12:24:45 [debug] 32743#0: malloc: 00000000006D58D0:96 2016/06/27 12:24:45 [debug] 32743#0: malloc: 00000000006DD920:1024 2016/06/27 12:24:45 [debug] 32743#0: malloc: 00000000006DD920:1024 2016/06/27 12:24:45 [debug] 32743#0: malloc: 00000000006DD920:1024 2016/06/27 12:24:45 [debug] 32743#0: malloc: 00000000006DD920:1024 2016/06/27 12:24:45 [debug] 32743#0: posix_memalign: 000000000070F2F0:16384 @16 2016/06/27 12:24:45 [debug] 32743#0: malloc: 00000000006DD920:1024 2016/06/27 12:24:45 [debug] 32743#0: malloc: 00000000006DD920:1024 2016/06/27 12:24:45 [debug] 32743#0: malloc: 0000000000713300:4096 2016/06/27 12:24:45 [debug] 32743#0: malloc: 00000000006DD920:2048 2016/06/27 12:24:45 [debug] 32743#0: malloc: 0000000000713300:4096 2016/06/27 12:24:45 [debug] 32743#0: malloc: 0000000000713300:4096 2016/06/27 12:24:45 [debug] 32743#0: malloc: 00000000006DD920:1024 2016/06/27 12:24:45 [debug] 32743#0: malloc: 00000000006DD920:2048 2016/06/27 12:24:45 [debug] 32743#0: malloc: 0000000000713300:4160 2016/06/27 12:24:45 [debug] 32743#0: malloc: 00000000006D5940:376 2016/06/27 12:24:45 [debug] 32743#0: log: 00000000006F7190 9 "/root/devel/ngx_module/url-rewrite-nginx-module/t/servroot/logs/error.log" 2016/06/27 12:24:45 [debug] 32743#0: log: 00000000006F71B8 10 "/root/devel/ngx_module/url-rewrite-nginx-module/t/servroot/logs/access.log" 2016/06/27 12:24:45 [notice] 32743#0: using the "epoll" event method 2016/06/27 12:24:45 [debug] 32743#0: posix_memalign: 00000000006D5940:128 @16 2016/06/27 12:24:45 [debug] 32743#0: malloc: 00000000006D59D0:80 2016/06/27 12:24:45 [debug] 32743#0: event timer add: -1: 30000:1467019515151 2016/06/27 12:24:45 [debug] 32743#0: worker cycle 2016/06/27 12:24:45 [debug] 32743#0: epoll timer: 30000 2016/06/27 12:24:45 [debug] 32743#0: epoll: fd:8 ev:0001 d:00000000006DA3E8 2016/06/27 12:24:45 [debug] 32743#0: timer delta: 1 2016/06/27 12:24:45 [debug] 32743#0: posted event 00000000006E4BB0 2016/06/27 12:24:45 [debug] 32743#0: worker cycle 2016/06/27 12:24:45 [debug] 32743#0: epoll timer: 29999 2016/06/27 12:24:47 [debug] 32743#0: epoll: fd:6 ev:0001 d:00000000006DA310 2016/06/27 12:24:47 [debug] 32743#0: timer delta: 2054 2016/06/27 12:24:47 [debug] 32743#0: worker cycle 2016/06/27 12:24:47 [debug] 32743#0: epoll timer: 27945 2016/06/27 12:24:47 [debug] 32743#0: epoll: fd:4 ev:0001 d:00000000006DA3E9 2016/06/27 12:24:47 [debug] 32743#0: timer delta: 0 2016/06/27 12:24:47 [debug] 32743#0: posted event 00000000006E4BB0 2016/06/27 12:24:47 [debug] 32743#0: worker cycle 2016/06/27 12:24:47 [debug] 32743#0: epoll timer: 27945 2016/06/27 12:25:15 [debug] 32743#0: timer delta: 27974 2016/06/27 12:25:15 [debug] 32743#0: event timer del: -1: 1467019515151 2016/06/27 12:25:15 [debug] 32743#0: clean old cycles 2016/06/27 12:25:15 [debug] 32743#0: live fd:0 2016/06/27 12:25:15 [debug] 32743#0: old cycles status: 1 2016/06/27 12:25:15 [debug] 32743#0: event timer add: -1: 30000:1467019545180 2016/06/27 12:25:15 [debug] 32743#0: worker cycle 2016/06/27 12:25:15 [debug] 32743#0: epoll timer: 30000 2016/06/27 12:25:44 [debug] 32743#0: epoll: fd:4 ev:2001 d:00000000006DA3E9 =========================== Conversation: =========================== # curl -v -t 1 http://localhost:1984/t/zero.html * Hostname was NOT found in DNS cache * Trying ::1... * connect to ::1 port 1984 failed: Connection refused * Trying 127.0.0.1... * Connected to localhost (127.0.0.1) port 1984 (#0) > GET /t/zero.html HTTP/1.1 > User-Agent: curl/7.38.0 > Host: localhost:1984 > Accept: */* > < HTTP/1.1 200 OK * Server nginx/1.10.1 is not blacklisted < Server: nginx/1.10.1 < Date: Mon, 27 Jun 2016 09:24:45 GMT < Content-Type: text/html < Content-Length: 0 < Last-Modified: Mon, 27 Jun 2016 08:41:59 GMT < Connection: keep-alive < ETag: "5770e6d7-0" < Accept-Ranges: bytes < * Connection #0 to host localhost left intact # curl -v -t 1 http://localhost:1984/t/zero.html * Hostname was NOT found in DNS cache * Trying ::1... * connect to ::1 port 1984 failed: Connection refused * Trying 127.0.0.1... * Connected to localhost (127.0.0.1) port 1984 (#0) > GET /t/zero.html HTTP/1.1 > User-Agent: curl/7.38.0 > Host: localhost:1984 > Accept: */* > 2016/06/27 12:24:47 [debug] 32743#0: posix_memalign: 00000000006E6360:512 @16 2016/06/27 12:24:47 [debug] 32743#0: *2 accept: 127.0.0.1:34419 fd:4 2016/06/27 12:24:47 [debug] 32743#0: *2 event timer add: 4: 60000:1467019547206 2016/06/27 12:24:47 [debug] 32743#0: *2 reusable connection: 1 2016/06/27 12:24:47 [debug] 32743#0: *2 epoll add event: fd:4 op:1 ev:80002001 2016/06/27 12:24:47 [debug] 32743#0: *2 http wait request handler 2016/06/27 12:24:47 [debug] 32743#0: *2 recv: fd:4 1 of 1 2016/06/27 12:24:47 [debug] 32743#0: *2 reusable connection: 0 2016/06/27 12:24:47 [debug] 32743#0: *2 posix_memalign: 00000000006FAE20:4096 @16 2016/06/27 12:24:47 [debug] 32743#0: *2 http process request line 2016/06/27 12:24:47 [debug] 32743#0: *2 http alloc large header buffer 2016/06/27 12:24:47 [debug] 32743#0: *2 malloc: 00000000006FBE30:8192 2016/06/27 12:24:47 [debug] 32743#0: *2 http large header alloc: 00000000006FBE30 8192 2016/06/27 12:24:47 [debug] 32743#0: *2 http large header copy: 1 2016/06/27 12:24:47 [debug] 32743#0: *2 recv: fd:4 88 of 8191 2016/06/27 12:24:47 [debug] 32743#0: *2 http request line: "GET /t/zero.html HTTP/1.1" 2016/06/27 12:24:47 [debug] 32743#0: *2 http uri: "/t/zero.html" 2016/06/27 12:24:47 [debug] 32743#0: *2 http args: "" 2016/06/27 12:24:47 [debug] 32743#0: *2 http exten: "html" 2016/06/27 12:24:47 [debug] 32743#0: *2 http process request header line 2016/06/27 12:24:47 [debug] 32743#0: *2 http header: "User-Agent: curl/7.38.0" 2016/06/27 12:24:47 [debug] 32743#0: *2 http header: "Host: localhost:1984" 2016/06/27 12:24:47 [debug] 32743#0: *2 http header: "Accept: */*" 2016/06/27 12:24:47 [debug] 32743#0: *2 http header done 2016/06/27 12:24:47 [debug] 32743#0: *2 event timer del: 4: 1467019547206 2016/06/27 12:24:47 [debug] 32743#0: *2 rewrite phase: 0 2016/06/27 12:24:47 [debug] 32743#0: *2 test location: "/" 2016/06/27 12:24:47 [debug] 32743#0: *2 test location: "t" 2016/06/27 12:24:47 [debug] 32743#0: *2 using configuration "/t" 2016/06/27 12:24:47 [debug] 32743#0: *2 http cl:-1 max:31457280 2016/06/27 12:24:47 [debug] 32743#0: *2 rewrite phase: 2 2016/06/27 12:24:47 [debug] 32743#0: *2 post rewrite phase: 3 2016/06/27 12:24:47 [debug] 32743#0: *2 generic phase: 4 2016/06/27 12:24:47 [debug] 32743#0: *2 generic phase: 5 2016/06/27 12:24:47 [debug] 32743#0: *2 access phase: 6 2016/06/27 12:24:47 [debug] 32743#0: *2 access phase: 7 2016/06/27 12:24:47 [debug] 32743#0: *2 post access phase: 8 2016/06/27 12:24:47 [debug] 32743#0: *2 content phase: 9 2016/06/27 12:24:47 [debug] 32743#0: *2 content phase: 10 2016/06/27 12:24:47 [debug] 32743#0: *2 content phase: 11 2016/06/27 12:24:47 [debug] 32743#0: *2 http filename: "/root/devel/ngx_module/url-rewrite-nginx-module/t/servroot/html/t/zero.html" 2016/06/27 12:24:47 [debug] 32743#0: *2 add cleanup: 00000000006FBD48 2016/06/27 12:24:47 [debug] 32743#0: *2 http static fd: 5 2016/06/27 12:24:47 [debug] 32743#0: *2 http set discard body 2016/06/27 12:24:47 [debug] 32743#0: *2 posix_memalign: 00000000006FDE40:4096 @16 2016/06/27 12:24:47 [debug] 32743#0: *2 HTTP/1.1 200 OK Server: nginx/1.10.1 Date: Mon, 27 Jun 2016 09:24:47 GMT Content-Type: text/html Content-Length: 0 Last-Modified: Mon, 27 Jun 2016 08:41:59 GMT Connection: keep-alive ETag: "5770e6d7-0" Accept-Ranges: bytes 2016/06/27 12:24:47 [debug] 32743#0: *2 write new buf t:1 f:0 00000000006FDF78, pos 00000000006FDF78, size: 234 file: 0, size: 0 2016/06/27 12:24:47 [debug] 32743#0: *2 http write filter: l:0 f:0 s:234 2016/06/27 12:24:47 [debug] 32743#0: *2 http output filter "/t/zero.html?" 2016/06/27 12:24:47 [debug] 32743#0: *2 http copy filter: "/t/zero.html?" 2016/06/27 12:24:47 [debug] 32743#0: *2 http postpone filter "/t/zero.html?" 00007FFFFFFFDF20 2016/06/27 12:24:47 [debug] 32743#0: *2 write old buf t:1 f:0 00000000006FDF78, pos 00000000006FDF78, size: 234 file: 0, size: 0 2016/06/27 12:24:47 [debug] 32743#0: *2 write new buf t:0 f:0 0000000000000000, pos 0000000000000000, size: 0 file: 0, size: 0 2016/06/27 12:24:47 [debug] 32743#0: *2 http write filter: l:1 f:0 s:234 2016/06/27 12:24:47 [debug] 32743#0: *2 http write filter limit 0 HTTP/1.1 200 OK Server: nginx/1.10.1 Date: Mon, 27 Jun 2016 09:24:47 GMT Content-Type: text/html Content-Length: 0 Last-Modified: Mon, 27 Jun 2016 08:41:59 GMT Connection: keep-alive ETag: "5770e6d7-0" Accept-Ranges: bytes 2016/06/27 12:24:47 [debug] 32743#0: *2 writev: 234 of 234 2016/06/27 12:24:47 [debug] 32743#0: *2 http write filter 0000000000000000 2016/06/27 12:24:47 [debug] 32743#0: *2 http copy filter: 0 "/t/zero.html?" 2016/06/27 12:24:47 [debug] 32743#0: *2 http finalize request: 0, "/t/zero.html?" a:1, c:1 2016/06/27 12:24:47 [debug] 32743#0: *2 set http keepalive handler 2016/06/27 12:24:47 [debug] 32743#0: *2 http close request 2016/06/27 12:24:47 [debug] 32743#0: *2 http log handler 2016/06/27 12:24:47 [debug] 32743#0: *2 run cleanup: 00000000006FBD48 2016/06/27 12:24:47 [debug] 32743#0: *2 file cleanup: fd:5 2016/06/27 12:24:47 [debug] 32743#0: *2 free: 00000000006FAE20, unused: 8 2016/06/27 12:24:47 [debug] 32743#0: *2 free: 00000000006FDE40, unused: 3293 2016/06/27 12:24:47 [debug] 32743#0: *2 hc free: 0000000000000000 0 2016/06/27 12:24:47 [debug] 32743#0: *2 hc busy: 00000000006E64C8 1 2016/06/27 12:24:47 [debug] 32743#0: *2 free: 00000000006FBE30 2016/06/27 12:24:47 [debug] 32743#0: *2 tcp_nodelay 2016/06/27 12:24:47 [debug] 32743#0: *2 reusable connection: 1 2016/06/27 12:24:47 [debug] 32743#0: *2 event timer add: 4: 68000:1467019555206 2016/06/27 12:24:47 [debug] 32743#0: *2 post event 00000000006E4BB0 2016/06/27 12:24:47 [debug] 32743#0: *2 delete posted event 00000000006E4BB0 2016/06/27 12:24:47 [debug] 32743#0: *2 http keepalive handler 2016/06/27 12:24:47 [debug] 32743#0: *2 recv: fd:4 -1 of 1 2016/06/27 12:24:47 [debug] 32743#0: *2 recv() not ready (11: Resource temporarily unavailable) =========================== /t/zero.html is essentially empty file under /root/devel/ngx_module/url-rewrite-nginx-module/t/servroot/html/t/zero.html Traffic capture (attached) looks like this: =========================== GET /t/zero.html HTTP/1.1 User-Agent: curl/7.38.0 Host: localhost:1984 Accept: */* 2016/06/27 11:50:46 [debug] 27659#0: posix_memalign: 00000000006E6360:512 @16 2016/06/27 11:50:46 [debug] 27659#0: *2 accept: 127.0.0.1:34397 fd:4 2016/06/27 11:50:46 [debug] 27659#0: *2 event timer add: 4: 60000:1467017506450 2016/06/27 11:50:46 [debug] 27659#0: *2 reusable connection: 1 2016/06/27 11:50:46 [debug] 27659#0: *2 epoll add event: fd:4 op:1 ev:80002001 2016/06/27 11:50:46 [debug] 27659#0: *2 http wait request handler ......... =========================== I.e. no headers sent. Will be grateful for any information about this issue. If it it not a bug but feature - is there a way to disable this behavior? -------------- next part -------------- An HTML attachment was scrubbed... URL: -------------- next part -------------- A non-text attachment was scrubbed... Name: debug_log_in_reply.pcap Type: application/octet-stream Size: 13468 bytes Desc: not available URL: From pankajitbhu at gmail.com Mon Jun 27 11:37:51 2016 From: pankajitbhu at gmail.com (Pankaj Chaudhary) Date: Mon, 27 Jun 2016 17:07:51 +0530 Subject: how can i get nginx lib Message-ID: -------------- next part -------------- An HTML attachment was scrubbed... URL: From mdounin at mdounin.ru Mon Jun 27 13:34:09 2016 From: mdounin at mdounin.ru (Maxim Dounin) Date: Mon, 27 Jun 2016 16:34:09 +0300 Subject: Part of debug log in reply instead of reply if nginx runs under debugger. In-Reply-To: References: Message-ID: <20160627133409.GY30781@mdounin.ru> Hello! On Mon, Jun 27, 2016 at 12:30:19PM +0300, Andrey Kulikov wrote: > I stuck in rather strange situation: if I run nginx under debugger, and > request zero-length file it gives me correct reply on first connection. But > on second connection it reply it output part of debug log (what supposed to > be written to debug log, but wasn't). > At the same time if nginx runs normally (without debugger attached) - > everything works as it should. > > Is is normal situation when nginx runs under debugger? No, it's not. Though it looks like you are using 'master_process off' and reloading the configuration: [...] > master_process off; [...] > 2016/06/27 12:24:30 [notice] 32736#0: signal 1 (SIGHUP) received, reconfiguring This can cause various unexpected effects. If you didn't mean to do a reload - check your debugger documentation if it's responsible for this. -- Maxim Dounin http://nginx.org/ From mdounin at mdounin.ru Mon Jun 27 13:45:01 2016 From: mdounin at mdounin.ru (Maxim Dounin) Date: Mon, 27 Jun 2016 16:45:01 +0300 Subject: [PATCH 1 of 2] HTTP: add support for trailers in HTTP responses In-Reply-To: References: Message-ID: <20160627134500.GZ30781@mdounin.ru> Hello! On Sun, Jun 26, 2016 at 04:13:15PM -0700, Piotr Sikora wrote: > # HG changeset patch > # User Piotr Sikora > # Date 1466735480 25200 > # Thu Jun 23 19:31:20 2016 -0700 > # Node ID a96187a9806536ab2a8bf3fa7f7b659cf5d3ff13 > # Parent 6f69e3c0f780e29bca752fc1f938f4a459a1ec59 > HTTP: add support for trailers in HTTP responses. > > Example: > > ngx_table_elt_t *h; > > h = ngx_list_push(&r->headers_out.trailers); > if (h == NULL) { > return NGX_ERROR; > } > > ngx_str_set(&h->key, "Fun"); > ngx_str_set(&h->value, "with trailers"); > h->hash = ngx_hash_key_lc(h->key.data, h->key.len); > > The code above adds "Fun: with trailers" trailer to the response to > the request with "TE: trailers" header (which indicates support for > trailers). > > Note that trailers MUST be added before last buffer of the response > (last_buf = 1) reaches chunked or v2 output filters, otherwise they > are going to be ignored. > > Signed-off-by: Piotr Sikora What's the goal? Any real-world use for this? > > diff -r 6f69e3c0f780 -r a96187a98065 src/http/modules/ngx_http_chunked_filter_module.c > --- a/src/http/modules/ngx_http_chunked_filter_module.c > +++ b/src/http/modules/ngx_http_chunked_filter_module.c > @@ -17,6 +17,7 @@ typedef struct { > > > static ngx_int_t ngx_http_chunked_filter_init(ngx_conf_t *cf); > +static ngx_chain_t *ngx_http_chunked_get_trailers(ngx_http_request_t *r); > > > static ngx_http_module_t ngx_http_chunked_filter_module_ctx = { > @@ -69,28 +70,31 @@ ngx_http_chunked_header_filter(ngx_http_ > return ngx_http_next_header_filter(r); > } > > - if (r->headers_out.content_length_n == -1) { > + clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module); > + > + if (clcf->chunked_transfer_encoding && r->trailers_ok) { > + ngx_http_clear_content_length(r); > + r->chunked = 1; As far as I understand the patch, this will cause chunked encoding to be used for all responses to a client which supports trailers. This certainly looks like a bad idea. [...] -- Maxim Dounin http://nginx.org/ From piotrsikora at google.com Mon Jun 27 14:37:31 2016 From: piotrsikora at google.com (Piotr Sikora) Date: Mon, 27 Jun 2016 07:37:31 -0700 Subject: [PATCH 1 of 2] HTTP: add support for trailers in HTTP responses In-Reply-To: <20160627134500.GZ30781@mdounin.ru> References: <20160627134500.GZ30781@mdounin.ru> Message-ID: Hey Maxim, > What's the goal? Any real-world use for this? For us? gRPC, which uses HTTP/2 and/or HTTP/1.1 with trailers as a transport protocol. > As far as I understand the patch, this will cause chunked encoding > to be used for all responses to a client which supports trailers. > This certainly looks like a bad idea. It will force chunked encoding in responses to HTTP/1.1 requests with "TE: trailers", i.e. only when HTTP/1.1 client explicitly asked for trailers. Since, at this point (i.e. while processing headers), we don't know whether there will be any trailers after response body (because proxy* and/or 3rd-party modules might add them later), forcing chunked encoding for all clients that asked for trailers is the most reasonable thing we can do. Alternatively, we could add an indicator (i.e. r->trailers_emit) that proxy* and/or 3rd-party modules could set in case they expect to emit trailers, but to be honest, I feel that it would be just set to 1 (unless we want to whitelist which trailers are passed down from upstream). * I'm going to work on proxy support for trailers at some point in future, if this gets merged. Best regards, Piotr Sikora From arut at nginx.com Mon Jun 27 15:43:08 2016 From: arut at nginx.com (Roman Arutyunyan) Date: Mon, 27 Jun 2016 15:43:08 +0000 Subject: [nginx] Style. Message-ID: details: http://hg.nginx.org/nginx/rev/d452cb27639f branches: changeset: 6601:d452cb27639f user: Roman Arutyunyan date: Mon Jun 27 18:42:29 2016 +0300 description: Style. diffstat: src/stream/ngx_stream_limit_conn_module.c | 20 ++++++++++---------- 1 files changed, 10 insertions(+), 10 deletions(-) diffs (30 lines): diff -r 6f69e3c0f780 -r d452cb27639f src/stream/ngx_stream_limit_conn_module.c --- a/src/stream/ngx_stream_limit_conn_module.c Wed Jun 22 13:47:54 2016 -0700 +++ b/src/stream/ngx_stream_limit_conn_module.c Mon Jun 27 18:42:29 2016 +0300 @@ -105,16 +105,16 @@ static ngx_stream_module_t ngx_stream_l ngx_module_t ngx_stream_limit_conn_module = { NGX_MODULE_V1, - &ngx_stream_limit_conn_module_ctx, /* module context */ - ngx_stream_limit_conn_commands, /* module directives */ - NGX_STREAM_MODULE, /* module type */ - NULL, /* init master */ - NULL, /* init module */ - NULL, /* init process */ - NULL, /* init thread */ - NULL, /* exit thread */ - NULL, /* exit process */ - NULL, /* exit master */ + &ngx_stream_limit_conn_module_ctx, /* module context */ + ngx_stream_limit_conn_commands, /* module directives */ + NGX_STREAM_MODULE, /* module type */ + NULL, /* init master */ + NULL, /* init module */ + NULL, /* init process */ + NULL, /* init thread */ + NULL, /* exit thread */ + NULL, /* exit process */ + NULL, /* exit master */ NGX_MODULE_V1_PADDING }; From amdeich at gmail.com Mon Jun 27 16:42:07 2016 From: amdeich at gmail.com (Andrey Kulikov) Date: Mon, 27 Jun 2016 19:42:07 +0300 Subject: Part of debug log in reply instead of reply if nginx runs under debugger. In-Reply-To: <20160627133409.GY30781@mdounin.ru> References: <20160627133409.GY30781@mdounin.ru> Message-ID: Hi Maxim, Thanks for a fast reply! Indeed, I didn't mean to reload configuration. After instructing gdb not to forward SIGHUP to the process being debugged, everything start to work like a charm. Thanks for help! -- WBR, Andrey On 27 June 2016 at 16:34, Maxim Dounin wrote: > Hello! > > On Mon, Jun 27, 2016 at 12:30:19PM +0300, Andrey Kulikov wrote: > > > I stuck in rather strange situation: if I run nginx under debugger, and > > request zero-length file it gives me correct reply on first connection. > But > > on second connection it reply it output part of debug log (what supposed > to > > be written to debug log, but wasn't). > > At the same time if nginx runs normally (without debugger attached) - > > everything works as it should. > > > > Is is normal situation when nginx runs under debugger? > > No, it's not. Though it looks like you are using 'master_process > off' and reloading the configuration: > > [...] > > > master_process off; > > [...] > > > 2016/06/27 12:24:30 [notice] 32736#0: signal 1 (SIGHUP) received, > reconfiguring > > This can cause various unexpected effects. If you didn't mean to > do a reload - check your debugger documentation if it's > responsible for this. > > -- > Maxim Dounin > http://nginx.org/ > > _______________________________________________ > nginx-devel mailing list > nginx-devel at nginx.org > http://mailman.nginx.org/mailman/listinfo/nginx-devel > -------------- next part -------------- An HTML attachment was scrubbed... URL: From shuxinyang.oss at gmail.com Mon Jun 27 17:04:05 2016 From: shuxinyang.oss at gmail.com (shuxinyang) Date: Mon, 27 Jun 2016 10:04:05 -0700 Subject: [PATCH 1 of 2] HTTP: add support for trailers in HTTP responses In-Reply-To: References: <20160627134500.GZ30781@mdounin.ru> Message-ID: <57715C85.70307@gmail.com> Hi, Piotr: I'm wondering why not just change the ngx_http_chunked_filter_module.c? or add a module inserted right after the chunked-filter-module? Shuxin On 06/27/2016 07:37 AM, Piotr Sikora wrote: > Hey Maxim, > >> What's the goal? Any real-world use for this? > > > > On 06/27/2016 06:45 AM, Maxim Dounin wrote: >> Hello! >> >> On Sun, Jun 26, 2016 at 04:13:15PM -0700, Piotr Sikora wrote: >> >>> # HG changeset patch >>> # User Piotr Sikora >>> # Date 1466735480 25200 >>> # Thu Jun 23 19:31:20 2016 -0700 >>> # Node ID a96187a9806536ab2a8bf3fa7f7b659cf5d3ff13 >>> # Parent 6f69e3c0f780e29bca752fc1f938f4a459a1ec59 >>> HTTP: add support for trailers in HTTP responses. >>> >>> Example: >>> >>> ngx_table_elt_t *h; >>> >>> h = ngx_list_push(&r->headers_out.trailers); >>> if (h == NULL) { >>> return NGX_ERROR; >>> } >>> >>> ngx_str_set(&h->key, "Fun"); >>> ngx_str_set(&h->value, "with trailers"); > For us? gRPC, which uses HTTP/2 and/or HTTP/1.1 with trailers as a > transport protocol. > >> As far as I understand the patch, this will cause chunked encoding >> to be used for all responses to a client which supports trailers. >> This certainly looks like a bad idea. > It will force chunked encoding in responses to HTTP/1.1 requests with > "TE: trailers", i.e. only when HTTP/1.1 client explicitly asked for > trailers. > > Since, at this point (i.e. while processing headers), we don't know > whether there will be any trailers after response body (because proxy* > and/or 3rd-party modules might add them later), forcing chunked > encoding for all clients that asked for trailers is the most > reasonable thing we can do. > > Alternatively, we could add an indicator (i.e. r->trailers_emit) that > proxy* and/or 3rd-party modules could set in case they expect to emit > trailers, but to be honest, I feel that it would be just set to 1 > (unless we want to whitelist which trailers are passed down from > upstream). > > * I'm going to work on proxy support for trailers at some point in > future, if this gets merged. > > Best regards, > Piotr Sikora > > _______________________________________________ > nginx-devel mailing list > nginx-devel at nginx.org > http://mailman.nginx.org/mailman/listinfo/nginx-devel From piotrsikora at google.com Mon Jun 27 17:13:18 2016 From: piotrsikora at google.com (Piotr Sikora) Date: Mon, 27 Jun 2016 10:13:18 -0700 Subject: [PATCH 1 of 2] HTTP: add support for trailers in HTTP responses In-Reply-To: <57715C85.70307@gmail.com> References: <20160627134500.GZ30781@mdounin.ru> <57715C85.70307@gmail.com> Message-ID: Hey Shuxin, > I'm wondering why not just change the ngx_http_chunked_filter_module.c? > or add a module inserted right after the chunked-filter-module? Hmm...? I'm confused by your comment. This patch modifies 3 files: - parsing of "TE" header is done in ngx_http_request.c, - HTTP/1.1 trailers are handled in ngx_http_chunked_filter_module.c, - HTTP/2 trailers are handled in ngx_http_v2_filter_module.c. Are you suggesting that HTTP/2 trailers should be handled in ngx_http_chunked_filter_module.c? Best regards, Piotr Sikora From mdounin at mdounin.ru Mon Jun 27 17:53:38 2016 From: mdounin at mdounin.ru (Maxim Dounin) Date: Mon, 27 Jun 2016 20:53:38 +0300 Subject: [PATCH 1 of 2] HTTP: add support for trailers in HTTP responses In-Reply-To: References: <20160627134500.GZ30781@mdounin.ru> Message-ID: <20160627175338.GD30781@mdounin.ru> Hello! On Mon, Jun 27, 2016 at 07:37:31AM -0700, Piotr Sikora wrote: > > What's the goal? Any real-world use for this? > > For us? gRPC, which uses HTTP/2 and/or HTTP/1.1 with trailers as a > transport protocol. Last time I checked gRPC wasn't able to talk HTTP/1.1, and therefore wasn't able to work with nginx at all. So no real-world use for now, right? > > As far as I understand the patch, this will cause chunked encoding > > to be used for all responses to a client which supports trailers. > > This certainly looks like a bad idea. > > It will force chunked encoding in responses to HTTP/1.1 requests with > "TE: trailers", i.e. only when HTTP/1.1 client explicitly asked for > trailers. I disagree here. "TE: trailers" doesn't mean that client asked for trailers, it instead indicates that client supports trailers. Quoting RFC 7230: The "TE" header field in a request indicates what transfer codings, besides chunked, the client is willing to accept in response, and whether or not the client is willing to accept trailer fields in a chunked transfer coding. Using chunked for all clients who send "TE: trailers" looks like a bad idea for me, it will hurt at least some real-world clients. > Since, at this point (i.e. while processing headers), we don't know > whether there will be any trailers after response body (because proxy* > and/or 3rd-party modules might add them later), forcing chunked > encoding for all clients that asked for trailers is the most > reasonable thing we can do. > > Alternatively, we could add an indicator (i.e. r->trailers_emit) that > proxy* and/or 3rd-party modules could set in case they expect to emit > trailers, but to be honest, I feel that it would be just set to 1 > (unless we want to whitelist which trailers are passed down from > upstream). At least in case of proxy, trailers are expected to appear if and only if protocol used to talk to the upstream server supports them. That is, it's only expected to happen when talking to a backend via HTTP/1.1, and the response uses chunked encoding. -- Maxim Dounin http://nginx.org/ From shuxinyang.oss at gmail.com Mon Jun 27 18:53:00 2016 From: shuxinyang.oss at gmail.com (shuxinyang) Date: Mon, 27 Jun 2016 11:53:00 -0700 Subject: [PATCH 1 of 2] HTTP: add support for trailers in HTTP responses In-Reply-To: References: <20160627134500.GZ30781@mdounin.ru> <57715C85.70307@gmail.com> Message-ID: <5771760C.8040201@gmail.com> Hi, Piotr and Maxim: > to Maxim's question about "does trailer has real-world use" first. At least we do, some info is available only after the entire body is sent. Trailer is a viable and convenient solution for that matter, albeit it is not the only solution for it. I cannot "leak" more info as I don't know if I'm allowed say more about it. The bottom line is we did use trailer header in some situations. To Piotr: > parsing of "TE" header is done in As far as I can understand, your change is just to add trailer headers (not including the part that paring incoming trailer header from upstream, or merge the incoming trailer and generated trailer). If that is correct, you just need to add "trailer: hdr1,hdr2... hdrn" to the out-headers. TE is for something else as Maxim pointed out, and adding this header can be done in chunked-filter-module as well. My previous implementation of generating trailer header is completely done in chunk-module. Later on, I change my mind, and add a standalone module along with minor change to configure script. Thanks Shuxin On 06/27/2016 10:13 AM, Piotr Sikora wrote: > Hey Shuxin, > >> I'm wondering why not just change the ngx_http_chunked_filter_module.c? >> or add a module inserted right after the chunked-filter-module? > Hmm...? I'm confused by your comment. > > This patch modifies 3 files: > - parsing of "TE" header is done in ngx_http_request.c, > - HTTP/1.1 trailers are handled in ngx_http_chunked_filter_module.c, > - HTTP/2 trailers are handled in ngx_http_v2_filter_module.c. > > Are you suggesting that HTTP/2 trailers should be handled in > ngx_http_chunked_filter_module.c? > > Best regards, > Piotr Sikora > > _______________________________________________ > nginx-devel mailing list > nginx-devel at nginx.org > http://mailman.nginx.org/mailman/listinfo/nginx-devel From piotrsikora at google.com Mon Jun 27 19:03:56 2016 From: piotrsikora at google.com (Piotr Sikora) Date: Mon, 27 Jun 2016 12:03:56 -0700 Subject: [PATCH 1 of 2] HTTP: add support for trailers in HTTP responses In-Reply-To: <20160627175338.GD30781@mdounin.ru> References: <20160627134500.GZ30781@mdounin.ru> <20160627175338.GD30781@mdounin.ru> Message-ID: Hey Maxim, > Last time I checked gRPC wasn't able to talk HTTP/1.1, and > therefore wasn't able to work with nginx at all. So no real-world > use for now, right? Official clients & servers support only HTTP/2, but gRPC protocol can be layered on top of HTTP/1.1 with trailers, so it's up to the implementation to offer gRPC-over-HTTP/1.1 support. As for HTTP/2 trailers, the code I submitted is already used to send gRPC-over-HTTP/2, so it's quite real-world use case. > I disagree here. "TE: trailers" doesn't mean that client asked > for trailers, it instead indicates that client supports trailers. > Quoting RFC 7230: > > The "TE" header field in a request indicates what transfer codings, > besides chunked, the client is willing to accept in response, and > whether or not the client is willing to accept trailer fields in a > chunked transfer coding. > > Using chunked for all clients who send "TE: trailers" looks like a > bad idea for me, it will hurt at least some real-world clients. In theory, you're right... In practice, I'm not aware of any generic-purpose client sending "TE: trailers" header (i.e. browsers don't send it, even though at least some support trailers), and it's used only by clients that want to receive trailers. > At least in case of proxy, trailers are expected to appear if and > only if protocol used to talk to the upstream server supports > them. That is, it's only expected to happen when talking to a > backend via HTTP/1.1, and the response uses chunked encoding. NGINX can add them with "add_trailer", which works even with HTTP/1.0 backends... But point taken. Would adding r->trailers_emit (or r->expect_trailers, whichever you prefer) make you happy? Best regards, Piotr Sikora From piotrsikora at google.com Mon Jun 27 19:14:20 2016 From: piotrsikora at google.com (Piotr Sikora) Date: Mon, 27 Jun 2016 12:14:20 -0700 Subject: [PATCH 1 of 2] HTTP: add support for trailers in HTTP responses In-Reply-To: <5771760C.8040201@gmail.com> References: <20160627134500.GZ30781@mdounin.ru> <57715C85.70307@gmail.com> <5771760C.8040201@gmail.com> Message-ID: Hey Shuxin, > As far as I can understand, your change is just to add trailer headers > (not including the part that paring incoming > trailer header from upstream, or merge the incoming trailer and generated > trailer). If that is correct, you just need > to add "trailer: hdr1,hdr2... hdrn" to the out-headers. Did you look at both patches I've sent? http://mailman.nginx.org/pipermail/nginx-devel/2016-June/008429.html http://mailman.nginx.org/pipermail/nginx-devel/2016-June/008430.html Because they cover much more than just adding "Trailer" header. > TE is for something > else as Maxim pointed out, > and adding this header can be done in chunked-filter-module as well. "TE" is a _request_ header, so I don't see how adding it to response is relevant here. And yes, "TE" header could be parsed in chunked filter, but it's IMHO wrong place to do it, since you need to parse this header in HTTP/2 requests as well. > My previous implementation of generating trailer header is completely done > in chunk-module. Later on, I change > my mind, and add a standalone module along with minor change to configure > script. Does you implementation support trailers in HTTP/2 as well? Best regards, Piotr Sikora From shuxinyang.oss at gmail.com Mon Jun 27 22:03:22 2016 From: shuxinyang.oss at gmail.com (shuxinyang) Date: Mon, 27 Jun 2016 15:03:22 -0700 Subject: [PATCH 1 of 2] HTTP: add support for trailers in HTTP responses In-Reply-To: References: <20160627134500.GZ30781@mdounin.ru> <57715C85.70307@gmail.com> <5771760C.8040201@gmail.com> Message-ID: <5771A2AA.8010506@gmail.com> Hi, Piotr: I took some time to read your code, I believe I fully understand your code at this moment. My implementation is slightly differently from yours, and we have different use-cases. Here is my $0.02 value of comment to your code (cosmetic wise): - the verb "support" in "trailer support" in too general. The trailer-support in my mind include a long list of features (see bellow) - the "get" in "ngx_http_chunked_get_trailers" is sort of misleading. The "get" here actually means "generate". I thought you are looking for a existing buffer. Now go back to the long list of trailer support, I believe it needs to cover at least: 1) generate trailer headers and sent to downstream/visitor as you just did 2) reverse proxy propagate trailer headers from upstream, which needs 2.0 parse the incoming trailer header, both considering the body is buffered and not buffered, 2.1. make the incoming trailer accessible via variable after content phase, 2.2. if response body is is not buffered, combine incoming trailer header with the generated headers. 2.3. convert incoming trailer to regular header if response body is buffered 3|4|..|n) other features. I think 2.x is much harder than 1). I only implement 1) and 2.0) and 2.1). While implement 2.1), I left some room for 2.2 and 2.3 for the future. Now that you have plan for 2.x as your email suggests, wouldn't it be nice to submit these code first, and then go ahead with the code of 1). I believe to support 2.2 or 2.3, your existing code in chunk module needs lots of change. Thanks Shuxin On 06/27/2016 12:14 PM, Piotr Sikora wrote: > Hey Shuxin, > >> As far as I can understand, your change is just to add trailer headers >> (not including the part that paring incoming >> trailer header from upstream, or merge the incoming trailer and generated >> trailer). If that is correct, you just need >> to add "trailer: hdr1,hdr2... hdrn" to the out-headers. > Did you look at both patches I've sent? > http://mailman.nginx.org/pipermail/nginx-devel/2016-June/008429.html > http://mailman.nginx.org/pipermail/nginx-devel/2016-June/008430.html > > Because they cover much more than just adding "Trailer" header. > >> TE is for something >> else as Maxim pointed out, >> and adding this header can be done in chunked-filter-module as well. > "TE" is a _request_ header, so I don't see how adding it to response > is relevant here. > > And yes, "TE" header could be parsed in chunked filter, but it's IMHO > wrong place to do it, since you need to parse this header in HTTP/2 > requests as well. > >> My previous implementation of generating trailer header is completely done >> in chunk-module. Later on, I change >> my mind, and add a standalone module along with minor change to configure >> script. > Does you implementation support trailers in HTTP/2 as well? > > Best regards, > Piotr Sikora > > _______________________________________________ > nginx-devel mailing list > nginx-devel at nginx.org > http://mailman.nginx.org/mailman/listinfo/nginx-devel From piotrsikora at google.com Mon Jun 27 22:59:16 2016 From: piotrsikora at google.com (Piotr Sikora) Date: Mon, 27 Jun 2016 15:59:16 -0700 Subject: [PATCH] Configure: style Message-ID: # HG changeset patch # User Piotr Sikora # Date 1467064801 25200 # Mon Jun 27 15:00:01 2016 -0700 # Node ID d183012fa3d130b8de922d1c8eafd77ae94f8a51 # Parent d452cb27639f714bc43b7f3ede417e3e7f8efdd6 Configure: style. Signed-off-by: Piotr Sikora diff -r d452cb27639f -r d183012fa3d1 auto/unix --- a/auto/unix +++ b/auto/unix @@ -264,7 +264,7 @@ ngx_feature_test="dlopen(NULL, RTLD_NOW . auto/feature -if [ $ngx_found != yes ]; then +if [ $ngx_found = no ]; then ngx_feature="dlopen() in libdl" ngx_feature_libs="-ldl" @@ -287,7 +287,7 @@ ngx_feature_test="sched_yield()" . auto/feature -if [ $ngx_found != yes ]; then +if [ $ngx_found = no ]; then ngx_feature="sched_yield() in librt" ngx_feature_libs="-lrt" From piotrsikora at google.com Mon Jun 27 22:59:18 2016 From: piotrsikora at google.com (Piotr Sikora) Date: Mon, 27 Jun 2016 15:59:18 -0700 Subject: [PATCH] Configure: fix build with -Werror=unused-value Message-ID: # HG changeset patch # User Piotr Sikora # Date 1467064802 25200 # Mon Jun 27 15:00:02 2016 -0700 # Node ID f5ece83dbcc4c46bcda51511e4fbf8fb90aa9432 # Parent d452cb27639f714bc43b7f3ede417e3e7f8efdd6 Configure: fix build with -Werror=unused-value. Signed-off-by: Piotr Sikora diff -r d452cb27639f -r f5ece83dbcc4 auto/cc/conf --- a/auto/cc/conf +++ b/auto/cc/conf @@ -231,7 +231,7 @@ if [ "$NGX_PLATFORM" != win32 ]; then ngx_feature_incs= ngx_feature_path= ngx_feature_libs= - ngx_feature_test="__builtin_bswap64(0)" + ngx_feature_test="if (__builtin_bswap64(0)) return 1" . auto/feature From piotrsikora at google.com Mon Jun 27 22:59:19 2016 From: piotrsikora at google.com (Piotr Sikora) Date: Mon, 27 Jun 2016 15:59:19 -0700 Subject: [PATCH] Configure: fix build with -Werror=unused-but-set-variable Message-ID: # HG changeset patch # User Piotr Sikora # Date 1467064803 25200 # Mon Jun 27 15:00:03 2016 -0700 # Node ID ad603262a99df74951b05ce30c81ebc381694162 # Parent d452cb27639f714bc43b7f3ede417e3e7f8efdd6 Configure: fix build with -Werror=unused-but-set-variable. Signed-off-by: Piotr Sikora diff -r d452cb27639f -r ad603262a99d auto/os/linux --- a/auto/os/linux +++ b/auto/os/linux @@ -44,6 +44,7 @@ ngx_feature_test="int efd = 0; struct epoll_event ee; ee.events = EPOLLIN|EPOLLOUT|EPOLLET; ee.data.ptr = NULL; + (void) ee; efd = epoll_create(100); if (efd == -1) return 1;" . auto/feature diff -r d452cb27639f -r ad603262a99d auto/unix --- a/auto/unix +++ b/auto/unix @@ -644,7 +644,8 @@ if [ $NGX_IPV6 = YES ]; then ngx_feature_path= ngx_feature_libs= ngx_feature_test="struct sockaddr_in6 sin6; - sin6.sin6_family = AF_INET6;" + sin6.sin6_family = AF_INET6; + (void) sin6" . auto/feature fi From piotrsikora at google.com Mon Jun 27 22:59:20 2016 From: piotrsikora at google.com (Piotr Sikora) Date: Mon, 27 Jun 2016 15:59:20 -0700 Subject: [PATCH] Configure: fix build with -Werror=nonnull Message-ID: <2c14d7fb1d96c3a1bfb7.1467068360@piotrsikora.sfo.corp.google.com> # HG changeset patch # User Piotr Sikora # Date 1467064804 25200 # Mon Jun 27 15:00:04 2016 -0700 # Node ID 2c14d7fb1d96c3a1bfb7e22383bef895287bf7d7 # Parent d452cb27639f714bc43b7f3ede417e3e7f8efdd6 Configure: fix build with -Werror=nonnull. Signed-off-by: Piotr Sikora diff -r d452cb27639f -r 2c14d7fb1d96 auto/unix --- a/auto/unix +++ b/auto/unix @@ -260,7 +260,8 @@ ngx_feature_run=no ngx_feature_incs="#include " ngx_feature_path= ngx_feature_libs= -ngx_feature_test="dlopen(NULL, RTLD_NOW | RTLD_GLOBAL); dlsym(NULL, NULL)" +ngx_feature_test="dlopen(\"/dev/null\", RTLD_NOW | RTLD_GLOBAL); + dlsym(NULL, \"dummy\")" . auto/feature From piotrsikora at google.com Mon Jun 27 22:59:22 2016 From: piotrsikora at google.com (Piotr Sikora) Date: Mon, 27 Jun 2016 15:59:22 -0700 Subject: [PATCH] Configure: fix build with -Werror=old-style-definition Message-ID: <3ba6126630ceec0767e7.1467068362@piotrsikora.sfo.corp.google.com> # HG changeset patch # User Piotr Sikora # Date 1467064805 25200 # Mon Jun 27 15:00:05 2016 -0700 # Node ID 3ba6126630ceec0767e70b88be1a004d82e2c27e # Parent d452cb27639f714bc43b7f3ede417e3e7f8efdd6 Configure: fix build with -Werror=old-style-definition. Signed-off-by: Piotr Sikora diff -r d452cb27639f -r 3ba6126630ce auto/cc/sunc --- a/auto/cc/sunc +++ b/auto/cc/sunc @@ -20,7 +20,10 @@ have=NGX_COMPILER value="\"Sun C $NGX_SU cat << END > $NGX_AUTOTEST.c -int main() { printf("%d", __SUNPRO_C); } +int main(void) { + printf("%d", __SUNPRO_C); + return 0; +} END diff -r d452cb27639f -r 3ba6126630ce auto/endianness --- a/auto/endianness +++ b/auto/endianness @@ -15,7 +15,7 @@ END cat << END > $NGX_AUTOTEST.c -int main() { +int main(void) { int i = 0x11223344; char *p; diff -r d452cb27639f -r 3ba6126630ce auto/feature --- a/auto/feature +++ b/auto/feature @@ -31,7 +31,7 @@ cat << END > $NGX_AUTOTEST.c $NGX_INCLUDE_UNISTD_H $ngx_feature_incs -int main() { +int main(void) { $ngx_feature_test; return 0; } diff -r d452cb27639f -r 3ba6126630ce auto/include --- a/auto/include +++ b/auto/include @@ -20,7 +20,7 @@ cat << END > $NGX_AUTOTEST.c $NGX_INCLUDE_SYS_PARAM_H #include <$ngx_include> -int main() { +int main(void) { return 0; } diff -r d452cb27639f -r 3ba6126630ce auto/types/sizeof --- a/auto/types/sizeof +++ b/auto/types/sizeof @@ -25,7 +25,7 @@ cat << END > $NGX_AUTOTEST.c $NGX_INCLUDE_INTTYPES_H $NGX_INCLUDE_AUTO_CONFIG_H -int main() { +int main(void) { printf("%d", (int) sizeof($ngx_type)); return 0; } diff -r d452cb27639f -r 3ba6126630ce auto/types/typedef --- a/auto/types/typedef +++ b/auto/types/typedef @@ -27,7 +27,7 @@ do #include $NGX_INCLUDE_INTTYPES_H -int main() { +int main(void) { $ngx_try i = 0; return (int) i; } diff -r d452cb27639f -r 3ba6126630ce auto/types/uintptr_t --- a/auto/types/uintptr_t +++ b/auto/types/uintptr_t @@ -19,7 +19,7 @@ cat << END > $NGX_AUTOTEST.c #include $NGX_INTTYPES_H -int main() { +int main(void) { uintptr_t i = 0; return (int) i; } From piotrsikora at google.com Mon Jun 27 22:59:23 2016 From: piotrsikora at google.com (Piotr Sikora) Date: Mon, 27 Jun 2016 15:59:23 -0700 Subject: [PATCH] Configure: stop polluting NGX_ namespace Message-ID: <388cf446fe903cfdf0d1.1467068363@piotrsikora.sfo.corp.google.com> # HG changeset patch # User Piotr Sikora # Date 1467064806 25200 # Mon Jun 27 15:00:06 2016 -0700 # Node ID 388cf446fe903cfdf0d13740ab3489cc14a3f377 # Parent d452cb27639f714bc43b7f3ede417e3e7f8efdd6 Configure: stop polluting NGX_ namespace. While there, fix the only test that used alternative variable name. Signed-off-by: Piotr Sikora diff -r d452cb27639f -r 388cf446fe90 auto/include --- a/auto/include +++ b/auto/include @@ -45,9 +45,6 @@ if [ -x $NGX_AUTOTEST ]; then eval "NGX_INCLUDE_$ngx_name='#include <$ngx_include>'" - #STUB - eval "NGX_$ngx_name='#include <$ngx_include>'" - else echo " not found" diff -r d452cb27639f -r 388cf446fe90 auto/types/uintptr_t --- a/auto/types/uintptr_t +++ b/auto/types/uintptr_t @@ -17,7 +17,7 @@ found=no cat << END > $NGX_AUTOTEST.c #include -$NGX_INTTYPES_H +$NGX_INCLUDE_INTTYPES_H int main() { uintptr_t i = 0; From piotrsikora at google.com Mon Jun 27 22:59:26 2016 From: piotrsikora at google.com (Piotr Sikora) Date: Mon, 27 Jun 2016 15:59:26 -0700 Subject: [PATCH] Core: remove unused ngx_tm_zone Message-ID: <890dc5e6a88c49a9d724.1467068366@piotrsikora.sfo.corp.google.com> # HG changeset patch # User Piotr Sikora # Date 1467064808 25200 # Mon Jun 27 15:00:08 2016 -0700 # Node ID 890dc5e6a88c49a9d724cc7da1d0eb20fcc70768 # Parent d452cb27639f714bc43b7f3ede417e3e7f8efdd6 Core: remove unused ngx_tm_zone. Unused since 9c2f3ed7a247 (0.3.3). Signed-off-by: Piotr Sikora diff -r d452cb27639f -r 890dc5e6a88c src/os/unix/ngx_time.h --- a/src/os/unix/ngx_time.h +++ b/src/os/unix/ngx_time.h @@ -38,7 +38,6 @@ typedef struct tm ngx_tm_t; #if (NGX_HAVE_GMTOFF) #define ngx_tm_gmtoff tm_gmtoff -#define ngx_tm_zone tm_zone #endif From piotrsikora at google.com Mon Jun 27 22:59:24 2016 From: piotrsikora at google.com (Piotr Sikora) Date: Mon, 27 Jun 2016 15:59:24 -0700 Subject: [PATCH] Core: remove unused NGX_INVALID_ARRAY_INDEX Message-ID: <8666abaeb43294edd5b9.1467068364@piotrsikora.sfo.corp.google.com> # HG changeset patch # User Piotr Sikora # Date 1467064807 25200 # Mon Jun 27 15:00:07 2016 -0700 # Node ID 8666abaeb43294edd5b93852bad2a42a27dd651b # Parent d452cb27639f714bc43b7f3ede417e3e7f8efdd6 Core: remove unused NGX_INVALID_ARRAY_INDEX. Unused since ae4744c28620 (0.7.51). Signed-off-by: Piotr Sikora diff -r d452cb27639f -r 8666abaeb432 src/core/ngx_config.h --- a/src/core/ngx_config.h +++ b/src/core/ngx_config.h @@ -105,10 +105,6 @@ typedef intptr_t ngx_flag_t; #define ngx_abort abort -/* TODO: platform specific: array[NGX_INVALID_ARRAY_INDEX] must cause SIGSEGV */ -#define NGX_INVALID_ARRAY_INDEX 0x80000000 - - /* TODO: auto_conf: ngx_inline inline __inline __inline__ */ #ifndef ngx_inline #define ngx_inline inline From piotrsikora at google.com Mon Jun 27 23:17:43 2016 From: piotrsikora at google.com (Piotr Sikora) Date: Mon, 27 Jun 2016 16:17:43 -0700 Subject: [PATCH 1 of 2] HTTP: add support for trailers in HTTP responses In-Reply-To: <5771A2AA.8010506@gmail.com> References: <20160627134500.GZ30781@mdounin.ru> <57715C85.70307@gmail.com> <5771760C.8040201@gmail.com> <5771A2AA.8010506@gmail.com> Message-ID: Hey Shuxin, > I took some time to read your code, I believe I fully understand your > code at this moment. > My implementation is slightly differently from yours, and we have different > use-cases. Thanks! > Here is my $0.02 value of comment to your code (cosmetic wise): > - the verb "support" in "trailer support" in too general. The > trailer-support in my mind include > a long list of features (see bellow) It's "trailer support" for the web serving part of NGINX, just not proxying. > - the "get" in "ngx_http_chunked_get_trailers" is sort of misleading. > The "get" here actually > means "generate". I thought you are looking for a existing buffer. That function name got changed a few times, since I cannot find one that I would be 100% happy with... Any suggestions? > Now go back to the long list of trailer support, I believe it needs to > cover at least: > 1) generate trailer headers and sent to downstream/visitor as you just > did > 2) reverse proxy propagate trailer headers from upstream, which needs > 2.0 parse the incoming trailer header, both considering the body is > buffered and not buffered, > 2.1. make the incoming trailer accessible via variable after content > phase, > 2.2. if response body is is not buffered, combine incoming trailer > header with the generated headers. > 2.3. convert incoming trailer to regular header if response body is > buffered > > 3|4|..|n) other features. > > I think 2.x is much harder than 1). I only implement 1) and 2.0) and > 2.1). While implement 2.1), I left some > room for 2.2 and 2.3 for the future. Now that you have plan for 2.x as your > email suggests, wouldn't it > be nice to submit these code first, and then go ahead with the code of 1). I > believe to support 2.2 or 2.3, > your existing code in chunk module needs lots of change. I don't see how anything you listed in 2.x would require modifications to the code I submitted... Actually, everything you listed should be handled in upstream and/or proxy modules, not chunking module, and it could easily use the API (r->headers_out.trailers) I want to add in this commit. Best regards, Piotr Sikora From shuxinyang.oss at gmail.com Tue Jun 28 00:56:37 2016 From: shuxinyang.oss at gmail.com (shuxinyang) Date: Mon, 27 Jun 2016 17:56:37 -0700 Subject: [PATCH 1 of 2] HTTP: add support for trailers in HTTP responses In-Reply-To: References: <20160627134500.GZ30781@mdounin.ru> <57715C85.70307@gmail.com> <5771760C.8040201@gmail.com> <5771A2AA.8010506@gmail.com> Message-ID: <5771CB45.90508@gmail.com> > It's "trailer support" for the web serving part of NGINX, just not proxying. > >> - the "get" in "ngx_http_chunked_get_trailers" is sort of misleading. >> The "get" here actually >> means "generate". I thought you are looking for a existing buffer. > That function name got changed a few times, since I cannot find one > that I would be 100% happy with... Any suggestions? I hope you don't call me "make fuss about nothing":-). Being an impatient code reader, I usually take a glimpse the code by reading comment and/or function, and imagine what it tries to do, and stitch them together into a big picture. the verb "get" did confuse me yesterday and this morning when I took a quick look. I would say "create" or "generate" (or something else) would be better. Anyway, naming is not big deal, maybe I (and other impatient code reader) need change:-) > >> Now go back to the long list of trailer support, I believe it needs to >> cover at least: >> 1) generate trailer headers and sent to downstream/visitor as you just >> did >> 2) reverse proxy propagate trailer headers from upstream, which needs >> 2.0 parse the incoming trailer header, both considering the body is >> buffered and not buffered, >> 2.1. make the incoming trailer accessible via variable after content >> phase, >> 2.2. if response body is is not buffered, combine incoming trailer >> header with the generated headers. >> 2.3. convert incoming trailer to regular header if response body is >> buffered >> >> 3|4|..|n) other features. >> >> I think 2.x is much harder than 1). I only implement 1) and 2.0) and >> 2.1). While implement 2.1), I left some >> room for 2.2 and 2.3 for the future. Now that you have plan for 2.x as your >> email suggests, wouldn't it >> be nice to submit these code first, and then go ahead with the code of 1). I >> believe to support 2.2 or 2.3, >> your existing code in chunk module needs lots of change. > I don't see how anything you listed in 2.x would require modifications > to the code I submitted... Actually, everything you listed should be > handled in upstream and/or proxy modules, not chunking module, and it > could easily use the API (r->headers_out.trailers) I want to add in > this commit. How do you manage to tackle this scenario without changing your existing code: backend server responses with trailer "lol = 123", and you define the same trailer, "lol = $haha" in *.conf. You have two options as to how to combine them: either override the one from origin, and override the one from your *.conf. It seems to me that the chunk-module is again a best place for such change. Best Regards Shuxin > Best regards, > Piotr Sikora > > _______________________________________________ > nginx-devel mailing list > nginx-devel at nginx.org > http://mailman.nginx.org/mailman/listinfo/nginx-devel From piotrsikora at google.com Tue Jun 28 01:30:02 2016 From: piotrsikora at google.com (Piotr Sikora) Date: Mon, 27 Jun 2016 18:30:02 -0700 Subject: [PATCH 1 of 2] Core: remove unused NGX_SIG_ATOMIC_T_SIZE Message-ID: <1059f59c44039020843c.1467077402@piotrsikora.sfo.corp.google.com> # HG changeset patch # User Piotr Sikora # Date 1467064809 25200 # Mon Jun 27 15:00:09 2016 -0700 # Node ID 1059f59c44039020843ced5bca39f165c322bacb # Parent d452cb27639f714bc43b7f3ede417e3e7f8efdd6 Core: remove unused NGX_SIG_ATOMIC_T_SIZE. Unused since 9c2f3ed7a247 (0.3.3). Signed-off-by: Piotr Sikora diff -r d452cb27639f -r 1059f59c4403 auto/unix --- a/auto/unix +++ b/auto/unix @@ -602,8 +602,6 @@ ngx_type="uint32_t"; ngx_types="u_int32_ ngx_type="uint64_t"; ngx_types="u_int64_t"; . auto/types/typedef ngx_type="sig_atomic_t"; ngx_types="int"; . auto/types/typedef -. auto/types/sizeof -ngx_param=NGX_SIG_ATOMIC_T_SIZE; ngx_value=$ngx_size; . auto/types/value ngx_type="socklen_t"; ngx_types="int"; . auto/types/typedef diff -r d452cb27639f -r 1059f59c4403 src/core/ngx_module.h --- a/src/core/ngx_module.h +++ b/src/core/ngx_module.h @@ -20,7 +20,6 @@ #define NGX_MODULE_SIGNATURE_0 \ ngx_value(NGX_PTR_SIZE) "," \ - ngx_value(NGX_SIG_ATOMIC_T_SIZE) "," \ ngx_value(NGX_TIME_T_SIZE) "," #if (NGX_HAVE_KQUEUE) diff -r d452cb27639f -r 1059f59c4403 src/os/win32/ngx_win32_config.h --- a/src/os/win32/ngx_win32_config.h +++ b/src/os/win32/ngx_win32_config.h @@ -217,7 +217,6 @@ typedef int sig_atomic_t #define NGX_OFF_T_LEN (sizeof("-9223372036854775807") - 1) #define NGX_MAX_OFF_T_VALUE 9223372036854775807 -#define NGX_SIG_ATOMIC_T_SIZE 4 #define NGX_HAVE_LITTLE_ENDIAN 1 From piotrsikora at google.com Tue Jun 28 01:30:03 2016 From: piotrsikora at google.com (Piotr Sikora) Date: Mon, 27 Jun 2016 18:30:03 -0700 Subject: [PATCH 2 of 2] Core: remove NGX_TIME_T_SIZE In-Reply-To: <1059f59c44039020843c.1467077402@piotrsikora.sfo.corp.google.com> References: <1059f59c44039020843c.1467077402@piotrsikora.sfo.corp.google.com> Message-ID: # HG changeset patch # User Piotr Sikora # Date 1467064810 25200 # Mon Jun 27 15:00:10 2016 -0700 # Node ID a2892701d91e6aba62719b54792e1e14eeea11a0 # Parent 1059f59c44039020843ced5bca39f165c322bacb Core: remove NGX_TIME_T_SIZE. Replace ./configure-time test with equivalent compile-time test. Signed-off-by: Piotr Sikora diff -r 1059f59c4403 -r a2892701d91e auto/unix --- a/auto/unix +++ b/auto/unix @@ -624,7 +624,6 @@ ngx_param=NGX_MAX_OFF_T_VALUE; ngx_value ngx_param=NGX_OFF_T_LEN; ngx_value=$ngx_max_len; . auto/types/value ngx_type="time_t"; . auto/types/sizeof -ngx_param=NGX_TIME_T_SIZE; ngx_value=$ngx_size; . auto/types/value ngx_param=NGX_TIME_T_LEN; ngx_value=$ngx_max_len; . auto/types/value ngx_param=NGX_MAX_TIME_T_VALUE; ngx_value=$ngx_max_value; . auto/types/value diff -r 1059f59c4403 -r a2892701d91e src/core/ngx_module.h --- a/src/core/ngx_module.h +++ b/src/core/ngx_module.h @@ -18,9 +18,7 @@ #define NGX_MODULE_UNSET_INDEX (ngx_uint_t) -1 -#define NGX_MODULE_SIGNATURE_0 \ - ngx_value(NGX_PTR_SIZE) "," \ - ngx_value(NGX_TIME_T_SIZE) "," +#define NGX_MODULE_SIGNATURE_0 ngx_value(NGX_PTR_SIZE) "," #if (NGX_HAVE_KQUEUE) #define NGX_MODULE_SIGNATURE_1 "1" diff -r 1059f59c4403 -r a2892701d91e src/core/ngx_parse_time.c --- a/src/core/ngx_parse_time.c +++ b/src/core/ngx_parse_time.c @@ -264,13 +264,9 @@ ngx_parse_http_time(u_char *value, size_ - 719527 + 31 + 28) * 86400 + hour * 3600 + min * 60 + sec; -#if (NGX_TIME_T_SIZE <= 4) - - if (time > 0x7fffffff) { + if (sizeof(time_t) <= 4 && time > 0x7fffffff) { return NGX_ERROR; } -#endif - return (time_t) time; } diff -r 1059f59c4403 -r a2892701d91e src/os/win32/ngx_win32_config.h --- a/src/os/win32/ngx_win32_config.h +++ b/src/os/win32/ngx_win32_config.h @@ -200,7 +200,6 @@ typedef int sig_atomic_t #define NGX_SIZE_T_LEN (sizeof("-9223372036854775808") - 1) #define NGX_MAX_SIZE_T_VALUE 9223372036854775807 #define NGX_TIME_T_LEN (sizeof("-9223372036854775808") - 1) -#define NGX_TIME_T_SIZE 8 #define NGX_MAX_TIME_T_VALUE 9223372036854775807 #else @@ -209,7 +208,6 @@ typedef int sig_atomic_t #define NGX_SIZE_T_LEN (sizeof("-2147483648") - 1) #define NGX_MAX_SIZE_T_VALUE 2147483647 #define NGX_TIME_T_LEN (sizeof("-2147483648") - 1) -#define NGX_TIME_T_SIZE 4 #define NGX_MAX_TIME_T_VALUE 2147483647 #endif From piotrsikora at google.com Tue Jun 28 01:43:46 2016 From: piotrsikora at google.com (Piotr Sikora) Date: Mon, 27 Jun 2016 18:43:46 -0700 Subject: [PATCH 1 of 2] HTTP: add support for trailers in HTTP responses In-Reply-To: <5771CB45.90508@gmail.com> References: <20160627134500.GZ30781@mdounin.ru> <57715C85.70307@gmail.com> <5771760C.8040201@gmail.com> <5771A2AA.8010506@gmail.com> <5771CB45.90508@gmail.com> Message-ID: Hey Shuxin, > How do you manage to tackle this scenario without changing your existing > code: > > backend server responses with trailer "lol = 123", and you define the > same trailer, > "lol = $haha" in *.conf. You have two options as to how to combine them: > either override the > one from origin, and override the one from your *.conf. ...or the third option - emit both trailers ;) This is consistent with how duplicate headers are currently handled in NGINX, that is: headers emitted by upstream and those added with "add_header" are both transmitted to the client. > It seems to me that the > chunk-module is again a best place for such change. Again, chunked module is HTTP/1.1 specific and nothing other than "encode trailers from r->headers_out.trailers to HTTP/1.1" should be handled there. Best regards, Piotr Sikora From piotrsikora at google.com Tue Jun 28 02:55:18 2016 From: piotrsikora at google.com (Piotr Sikora) Date: Mon, 27 Jun 2016 19:55:18 -0700 Subject: [PATCH] Core: reorder #ifdef in .h file to match order in .c file Message-ID: <11a53446bd90b8927cb9.1467082518@piotrsikora.sfo.corp.google.com> # HG changeset patch # User Piotr Sikora # Date 1467064811 25200 # Mon Jun 27 15:00:11 2016 -0700 # Node ID 11a53446bd90b8927cb93847c98672a8f056d182 # Parent d452cb27639f714bc43b7f3ede417e3e7f8efdd6 Core: reorder #ifdef in .h file to match order in .c file. Signed-off-by: Piotr Sikora diff -r d452cb27639f -r 11a53446bd90 src/os/unix/ngx_setaffinity.h --- a/src/os/unix/ngx_setaffinity.h +++ b/src/os/unix/ngx_setaffinity.h @@ -11,16 +11,16 @@ #define NGX_HAVE_CPU_AFFINITY 1 -#if (NGX_HAVE_SCHED_SETAFFINITY) - -typedef cpu_set_t ngx_cpuset_t; - -#elif (NGX_HAVE_CPUSET_SETAFFINITY) +#if (NGX_HAVE_CPUSET_SETAFFINITY) #include typedef cpuset_t ngx_cpuset_t; +#elif (NGX_HAVE_SCHED_SETAFFINITY) + +typedef cpu_set_t ngx_cpuset_t; + #endif void ngx_setaffinity(ngx_cpuset_t *cpu_affinity, ngx_log_t *log); From piotrsikora at google.com Tue Jun 28 02:55:17 2016 From: piotrsikora at google.com (Piotr Sikora) Date: Mon, 27 Jun 2016 19:55:17 -0700 Subject: [PATCH] Configure: don't test alternatives if preferred feature is found Message-ID: # HG changeset patch # User Piotr Sikora # Date 1467064812 25200 # Mon Jun 27 15:00:12 2016 -0700 # Node ID e4375e338d9acf927ffdc4cd18c704bb7ea1fd4e # Parent d452cb27639f714bc43b7f3ede417e3e7f8efdd6 Configure: don't test alternatives if preferred feature is found. Signed-off-by: Piotr Sikora diff -r d452cb27639f -r e4375e338d9a auto/cc/conf --- a/auto/cc/conf +++ b/auto/cc/conf @@ -197,6 +197,7 @@ if [ "$NGX_PLATFORM" != win32 ]; then if [ "$NGX_CC_NAME" = "ccc" ]; then echo "checking for C99 variadic macros ... disabled" + ngx_found=no else ngx_feature="C99 variadic macros" ngx_feature_name="NGX_HAVE_C99_VARIADIC_MACROS" @@ -209,20 +210,24 @@ if [ "$NGX_PLATFORM" != win32 ]; then var(0, buf, \"%d\", 1); if (buf[0] != '1') return 1" . auto/feature - fi + fi - ngx_feature="gcc variadic macros" - ngx_feature_name="NGX_HAVE_GCC_VARIADIC_MACROS" - ngx_feature_run=yes - ngx_feature_incs="#include + if [ $ngx_found = no ]; then + + ngx_feature="gcc variadic macros" + ngx_feature_name="NGX_HAVE_GCC_VARIADIC_MACROS" + ngx_feature_run=yes + ngx_feature_incs="#include #define var(dummy, args...) sprintf(args)" - ngx_feature_path= - ngx_feature_libs= - ngx_feature_test="char buf[30]; buf[0] = '0'; - var(0, buf, \"%d\", 1); - if (buf[0] != '1') return 1" - . auto/feature + ngx_feature_path= + ngx_feature_libs= + ngx_feature_test="char buf[30]; buf[0] = '0'; + var(0, buf, \"%d\", 1); + if (buf[0] != '1') return 1" + . auto/feature + + fi ngx_feature="gcc builtin 64 bit byteswap" diff -r d452cb27639f -r e4375e338d9a auto/unix --- a/auto/unix +++ b/auto/unix @@ -184,14 +184,18 @@ ngx_feature_test="fcntl(0, F_READAHEAD, . auto/feature -ngx_feature="posix_fadvise()" -ngx_feature_name="NGX_HAVE_POSIX_FADVISE" -ngx_feature_run=no -ngx_feature_incs="#include " -ngx_feature_path= -ngx_feature_libs= -ngx_feature_test="posix_fadvise(0, 0, 0, POSIX_FADV_SEQUENTIAL);" -. auto/feature +if [ $ngx_found = no ]; then + + ngx_feature="posix_fadvise()" + ngx_feature_name="NGX_HAVE_POSIX_FADVISE" + ngx_feature_run=no + ngx_feature_incs="#include " + ngx_feature_path= + ngx_feature_libs= + ngx_feature_test="posix_fadvise(0, 0, 0, POSIX_FADV_SEQUENTIAL);" + . auto/feature + +fi ngx_feature="O_DIRECT" @@ -208,25 +212,34 @@ if [ $ngx_found = yes -a "$NGX_SYSTEM" = have=NGX_HAVE_ALIGNED_DIRECTIO . auto/have fi -ngx_feature="F_NOCACHE" -ngx_feature_name="NGX_HAVE_F_NOCACHE" -ngx_feature_run=no -ngx_feature_incs="#include " -ngx_feature_path= -ngx_feature_libs= -ngx_feature_test="fcntl(0, F_NOCACHE, 1);" -. auto/feature +if [ $ngx_found = no ]; then -ngx_feature="directio()" -ngx_feature_name="NGX_HAVE_DIRECTIO" -ngx_feature_run=no -ngx_feature_incs="#include - #include " -ngx_feature_path= -ngx_feature_libs= -ngx_feature_test="directio(0, DIRECTIO_ON);" -. auto/feature + ngx_feature="F_NOCACHE" + ngx_feature_name="NGX_HAVE_F_NOCACHE" + ngx_feature_run=no + ngx_feature_incs="#include " + ngx_feature_path= + ngx_feature_libs= + ngx_feature_test="fcntl(0, F_NOCACHE, 1);" + . auto/feature + +fi + + +if [ $ngx_found = no ]; then + + ngx_feature="directio()" + ngx_feature_name="NGX_HAVE_DIRECTIO" + ngx_feature_run=no + ngx_feature_incs="#include + #include " + ngx_feature_path= + ngx_feature_libs= + ngx_feature_test="directio(0, DIRECTIO_ON);" + . auto/feature + +fi ngx_feature="statfs()" @@ -242,16 +255,20 @@ ngx_feature_test="struct statfs fs; . auto/feature -ngx_feature="statvfs()" -ngx_feature_name="NGX_HAVE_STATVFS" -ngx_feature_run=no -ngx_feature_incs="#include - #include " -ngx_feature_path= -ngx_feature_libs= -ngx_feature_test="struct statvfs fs; - statvfs(\".\", &fs);" -. auto/feature +if [ $ngx_found = no ]; then + + ngx_feature="statvfs()" + ngx_feature_name="NGX_HAVE_STATVFS" + ngx_feature_run=no + ngx_feature_incs="#include + #include " + ngx_feature_path= + ngx_feature_libs= + ngx_feature_test="struct statvfs fs; + statvfs(\".\", &fs);" + . auto/feature + +fi ngx_feature="dlopen()" @@ -356,28 +373,36 @@ ngx_feature_test="setsockopt(0, IPPROTO_ # Linux transparent proxying -ngx_feature="IP_TRANSPARENT" -ngx_feature_name="NGX_HAVE_TRANSPARENT_PROXY" -ngx_feature_run=no -ngx_feature_incs="#include - #include " -ngx_feature_path= -ngx_feature_libs= -ngx_feature_test="setsockopt(0, IPPROTO_IP, IP_TRANSPARENT, NULL, 0)" -. auto/feature +if [ $ngx_found = no ]; then + + ngx_feature="IP_TRANSPARENT" + ngx_feature_name="NGX_HAVE_TRANSPARENT_PROXY" + ngx_feature_run=no + ngx_feature_incs="#include + #include " + ngx_feature_path= + ngx_feature_libs= + ngx_feature_test="setsockopt(0, IPPROTO_IP, IP_TRANSPARENT, NULL, 0)" + . auto/feature + +fi # FreeBSD bind to any address for transparent proxying -ngx_feature="IP_BINDANY" -ngx_feature_name="NGX_HAVE_TRANSPARENT_PROXY" -ngx_feature_run=no -ngx_feature_incs="#include - #include " -ngx_feature_path= -ngx_feature_libs= -ngx_feature_test="setsockopt(0, IPPROTO_IP, IP_BINDANY, NULL, 0)" -. auto/feature +if [ $ngx_found = no ]; then + + ngx_feature="IP_BINDANY" + ngx_feature_name="NGX_HAVE_TRANSPARENT_PROXY" + ngx_feature_run=no + ngx_feature_incs="#include + #include " + ngx_feature_path= + ngx_feature_libs= + ngx_feature_test="setsockopt(0, IPPROTO_IP, IP_BINDANY, NULL, 0)" + . auto/feature + +fi # BSD way to get IPv4 datagram destination address @@ -395,15 +420,19 @@ ngx_feature_test="setsockopt(0, IPPROTO_ # Linux way to get IPv4 datagram destination address -ngx_feature="IP_PKTINFO" -ngx_feature_name="NGX_HAVE_IP_PKTINFO" -ngx_feature_run=no -ngx_feature_incs="#include - #include " -ngx_feature_path= -ngx_feature_libs= -ngx_feature_test="setsockopt(0, IPPROTO_IP, IP_PKTINFO, NULL, 0)" -. auto/feature +if [ $ngx_found = no ]; then + + ngx_feature="IP_PKTINFO" + ngx_feature_name="NGX_HAVE_IP_PKTINFO" + ngx_feature_run=no + ngx_feature_incs="#include + #include " + ngx_feature_path= + ngx_feature_libs= + ngx_feature_test="setsockopt(0, IPPROTO_IP, IP_PKTINFO, NULL, 0)" + . auto/feature + +fi # RFC 3542 way to get IPv6 datagram destination address @@ -772,16 +801,20 @@ ngx_feature_test="void *p; int n; n = po . auto/feature -ngx_feature="memalign()" -ngx_feature_name="NGX_HAVE_MEMALIGN" -ngx_feature_run=no -ngx_feature_incs="#include - #include " -ngx_feature_path= -ngx_feature_libs= -ngx_feature_test="void *p; p = memalign(4096, 4096); - if (p == NULL) return 1" -. auto/feature +if [ $ngx_found = no ]; then + + ngx_feature="memalign()" + ngx_feature_name="NGX_HAVE_MEMALIGN" + ngx_feature_run=no + ngx_feature_incs="#include + #include " + ngx_feature_path= + ngx_feature_libs= + ngx_feature_test="void *p; p = memalign(4096, 4096); + if (p == NULL) return 1" + . auto/feature + +fi ngx_feature="mmap(MAP_ANON|MAP_SHARED)" @@ -797,33 +830,42 @@ ngx_feature_test="void *p; . auto/feature -ngx_feature='mmap("/dev/zero", MAP_SHARED)' -ngx_feature_name="NGX_HAVE_MAP_DEVZERO" -ngx_feature_run=yes -ngx_feature_incs="#include - #include - #include " -ngx_feature_path= -ngx_feature_libs= -ngx_feature_test='void *p; int fd; - fd = open("/dev/zero", O_RDWR); - p = mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0); - if (p == MAP_FAILED) return 1;' -. auto/feature +if [ $ngx_found = no ]; then + ngx_feature='mmap("/dev/zero", MAP_SHARED)' + ngx_feature_name="NGX_HAVE_MAP_DEVZERO" + ngx_feature_run=yes + ngx_feature_incs="#include + #include + #include " + ngx_feature_path= + ngx_feature_libs= + ngx_feature_test='void *p; int fd; + fd = open("/dev/zero", O_RDWR); + p = mmap(NULL, 4096, PROT_READ|PROT_WRITE, + MAP_SHARED, fd, 0); + if (p == MAP_FAILED) return 1;' + . auto/feature -ngx_feature="System V shared memory" -ngx_feature_name="NGX_HAVE_SYSVSHM" -ngx_feature_run=yes -ngx_feature_incs="#include - #include " -ngx_feature_path= -ngx_feature_libs= -ngx_feature_test="int id; - id = shmget(IPC_PRIVATE, 4096, (SHM_R|SHM_W|IPC_CREAT)); - if (id == -1) return 1; - shmctl(id, IPC_RMID, NULL);" -. auto/feature +fi + + +if [ $ngx_found = no ]; then + + ngx_feature="System V shared memory" + ngx_feature_name="NGX_HAVE_SYSVSHM" + ngx_feature_run=yes + ngx_feature_incs="#include + #include " + ngx_feature_path= + ngx_feature_libs= + ngx_feature_test="int id; + id = shmget(IPC_PRIVATE, 4096, (SHM_R|SHM_W|IPC_CREAT)); + if (id == -1) return 1; + shmctl(id, IPC_RMID, NULL);" + . auto/feature + +fi ngx_feature="POSIX semaphores" From ru at nginx.com Tue Jun 28 12:54:34 2016 From: ru at nginx.com (Ruslan Ermilov) Date: Tue, 28 Jun 2016 15:54:34 +0300 Subject: [PATCH] Configure: don't test alternatives if preferred feature is found In-Reply-To: References: Message-ID: <20160628125434.GB31538@lo0.su> Hi Piotr, On Mon, Jun 27, 2016 at 07:55:17PM -0700, Piotr Sikora wrote: > # HG changeset patch > # User Piotr Sikora > # Date 1467064812 25200 > # Mon Jun 27 15:00:12 2016 -0700 > # Node ID e4375e338d9acf927ffdc4cd18c704bb7ea1fd4e > # Parent d452cb27639f714bc43b7f3ede417e3e7f8efdd6 > Configure: don't test alternatives if preferred feature is found. > > Signed-off-by: Piotr Sikora > > diff -r d452cb27639f -r e4375e338d9a auto/cc/conf > --- a/auto/cc/conf > +++ b/auto/cc/conf > @@ -197,6 +197,7 @@ if [ "$NGX_PLATFORM" != win32 ]; then > > if [ "$NGX_CC_NAME" = "ccc" ]; then > echo "checking for C99 variadic macros ... disabled" > + ngx_found=no > else > ngx_feature="C99 variadic macros" > ngx_feature_name="NGX_HAVE_C99_VARIADIC_MACROS" > @@ -209,20 +210,24 @@ if [ "$NGX_PLATFORM" != win32 ]; then > var(0, buf, \"%d\", 1); > if (buf[0] != '1') return 1" > . auto/feature > - fi > + fi > > > - ngx_feature="gcc variadic macros" > - ngx_feature_name="NGX_HAVE_GCC_VARIADIC_MACROS" > - ngx_feature_run=yes > - ngx_feature_incs="#include > + if [ $ngx_found = no ]; then > + > + ngx_feature="gcc variadic macros" > + ngx_feature_name="NGX_HAVE_GCC_VARIADIC_MACROS" > + ngx_feature_run=yes > + ngx_feature_incs="#include > #define var(dummy, args...) sprintf(args)" > - ngx_feature_path= > - ngx_feature_libs= > - ngx_feature_test="char buf[30]; buf[0] = '0'; > - var(0, buf, \"%d\", 1); > - if (buf[0] != '1') return 1" > - . auto/feature > + ngx_feature_path= > + ngx_feature_libs= > + ngx_feature_test="char buf[30]; buf[0] = '0'; > + var(0, buf, \"%d\", 1); > + if (buf[0] != '1') return 1" > + . auto/feature > + > + fi > > > ngx_feature="gcc builtin 64 bit byteswap" > diff -r d452cb27639f -r e4375e338d9a auto/unix > --- a/auto/unix > +++ b/auto/unix > @@ -184,14 +184,18 @@ ngx_feature_test="fcntl(0, F_READAHEAD, > . auto/feature > > > -ngx_feature="posix_fadvise()" > -ngx_feature_name="NGX_HAVE_POSIX_FADVISE" > -ngx_feature_run=no > -ngx_feature_incs="#include " > -ngx_feature_path= > -ngx_feature_libs= > -ngx_feature_test="posix_fadvise(0, 0, 0, POSIX_FADV_SEQUENTIAL);" > -. auto/feature > +if [ $ngx_found = no ]; then > + > + ngx_feature="posix_fadvise()" > + ngx_feature_name="NGX_HAVE_POSIX_FADVISE" > + ngx_feature_run=no > + ngx_feature_incs="#include " > + ngx_feature_path= > + ngx_feature_libs= > + ngx_feature_test="posix_fadvise(0, 0, 0, POSIX_FADV_SEQUENTIAL);" > + . auto/feature > + > +fi So far I have mixed feelings about this patch, but if it gets accepted then the compile-time condition for ngx_read_ahead() in src/os/unix/ngx_files.c can be simplified to only test NGX_HAVE_POSIX_FADVISE. Also, there is the currently unused macro NGX_HAVE_READ_AHEAD. > > > ngx_feature="O_DIRECT" > @@ -208,25 +212,34 @@ if [ $ngx_found = yes -a "$NGX_SYSTEM" = > have=NGX_HAVE_ALIGNED_DIRECTIO . auto/have > fi > > -ngx_feature="F_NOCACHE" > -ngx_feature_name="NGX_HAVE_F_NOCACHE" > -ngx_feature_run=no > -ngx_feature_incs="#include " > -ngx_feature_path= > -ngx_feature_libs= > -ngx_feature_test="fcntl(0, F_NOCACHE, 1);" > -. auto/feature > > +if [ $ngx_found = no ]; then > > -ngx_feature="directio()" > -ngx_feature_name="NGX_HAVE_DIRECTIO" > -ngx_feature_run=no > -ngx_feature_incs="#include > - #include " > -ngx_feature_path= > -ngx_feature_libs= > -ngx_feature_test="directio(0, DIRECTIO_ON);" > -. auto/feature > + ngx_feature="F_NOCACHE" > + ngx_feature_name="NGX_HAVE_F_NOCACHE" > + ngx_feature_run=no > + ngx_feature_incs="#include " > + ngx_feature_path= > + ngx_feature_libs= > + ngx_feature_test="fcntl(0, F_NOCACHE, 1);" > + . auto/feature > + > +fi > + > + > +if [ $ngx_found = no ]; then > + > + ngx_feature="directio()" > + ngx_feature_name="NGX_HAVE_DIRECTIO" > + ngx_feature_run=no > + ngx_feature_incs="#include > + #include " > + ngx_feature_path= > + ngx_feature_libs= > + ngx_feature_test="directio(0, DIRECTIO_ON);" > + . auto/feature > + > +fi > > > ngx_feature="statfs()" > @@ -242,16 +255,20 @@ ngx_feature_test="struct statfs fs; > . auto/feature > > > -ngx_feature="statvfs()" > -ngx_feature_name="NGX_HAVE_STATVFS" > -ngx_feature_run=no > -ngx_feature_incs="#include > - #include " > -ngx_feature_path= > -ngx_feature_libs= > -ngx_feature_test="struct statvfs fs; > - statvfs(\".\", &fs);" > -. auto/feature > +if [ $ngx_found = no ]; then > + > + ngx_feature="statvfs()" > + ngx_feature_name="NGX_HAVE_STATVFS" > + ngx_feature_run=no > + ngx_feature_incs="#include > + #include " > + ngx_feature_path= > + ngx_feature_libs= > + ngx_feature_test="struct statvfs fs; > + statvfs(\".\", &fs);" > + . auto/feature > + > +fi > > > ngx_feature="dlopen()" > @@ -356,28 +373,36 @@ ngx_feature_test="setsockopt(0, IPPROTO_ > > # Linux transparent proxying > > -ngx_feature="IP_TRANSPARENT" > -ngx_feature_name="NGX_HAVE_TRANSPARENT_PROXY" > -ngx_feature_run=no > -ngx_feature_incs="#include > - #include " > -ngx_feature_path= > -ngx_feature_libs= > -ngx_feature_test="setsockopt(0, IPPROTO_IP, IP_TRANSPARENT, NULL, 0)" > -. auto/feature > +if [ $ngx_found = no ]; then > + > + ngx_feature="IP_TRANSPARENT" > + ngx_feature_name="NGX_HAVE_TRANSPARENT_PROXY" > + ngx_feature_run=no > + ngx_feature_incs="#include > + #include " > + ngx_feature_path= > + ngx_feature_libs= > + ngx_feature_test="setsockopt(0, IPPROTO_IP, IP_TRANSPARENT, NULL, 0)" > + . auto/feature > + > +fi > > > # FreeBSD bind to any address for transparent proxying > > -ngx_feature="IP_BINDANY" > -ngx_feature_name="NGX_HAVE_TRANSPARENT_PROXY" > -ngx_feature_run=no > -ngx_feature_incs="#include > - #include " > -ngx_feature_path= > -ngx_feature_libs= > -ngx_feature_test="setsockopt(0, IPPROTO_IP, IP_BINDANY, NULL, 0)" > -. auto/feature > +if [ $ngx_found = no ]; then > + > + ngx_feature="IP_BINDANY" > + ngx_feature_name="NGX_HAVE_TRANSPARENT_PROXY" > + ngx_feature_run=no > + ngx_feature_incs="#include > + #include " > + ngx_feature_path= > + ngx_feature_libs= > + ngx_feature_test="setsockopt(0, IPPROTO_IP, IP_BINDANY, NULL, 0)" > + . auto/feature > + > +fi > > > # BSD way to get IPv4 datagram destination address > @@ -395,15 +420,19 @@ ngx_feature_test="setsockopt(0, IPPROTO_ > > # Linux way to get IPv4 datagram destination address > > -ngx_feature="IP_PKTINFO" > -ngx_feature_name="NGX_HAVE_IP_PKTINFO" > -ngx_feature_run=no > -ngx_feature_incs="#include > - #include " > -ngx_feature_path= > -ngx_feature_libs= > -ngx_feature_test="setsockopt(0, IPPROTO_IP, IP_PKTINFO, NULL, 0)" > -. auto/feature > +if [ $ngx_found = no ]; then > + > + ngx_feature="IP_PKTINFO" > + ngx_feature_name="NGX_HAVE_IP_PKTINFO" > + ngx_feature_run=no > + ngx_feature_incs="#include > + #include " > + ngx_feature_path= > + ngx_feature_libs= > + ngx_feature_test="setsockopt(0, IPPROTO_IP, IP_PKTINFO, NULL, 0)" > + . auto/feature > + > +fi > > > # RFC 3542 way to get IPv6 datagram destination address > @@ -772,16 +801,20 @@ ngx_feature_test="void *p; int n; n = po > . auto/feature > > > -ngx_feature="memalign()" > -ngx_feature_name="NGX_HAVE_MEMALIGN" > -ngx_feature_run=no > -ngx_feature_incs="#include > - #include " > -ngx_feature_path= > -ngx_feature_libs= > -ngx_feature_test="void *p; p = memalign(4096, 4096); > - if (p == NULL) return 1" > -. auto/feature > +if [ $ngx_found = no ]; then > + > + ngx_feature="memalign()" > + ngx_feature_name="NGX_HAVE_MEMALIGN" > + ngx_feature_run=no > + ngx_feature_incs="#include > + #include " > + ngx_feature_path= > + ngx_feature_libs= > + ngx_feature_test="void *p; p = memalign(4096, 4096); > + if (p == NULL) return 1" > + . auto/feature > + > +fi > > > ngx_feature="mmap(MAP_ANON|MAP_SHARED)" > @@ -797,33 +830,42 @@ ngx_feature_test="void *p; > . auto/feature > > > -ngx_feature='mmap("/dev/zero", MAP_SHARED)' > -ngx_feature_name="NGX_HAVE_MAP_DEVZERO" > -ngx_feature_run=yes > -ngx_feature_incs="#include > - #include > - #include " > -ngx_feature_path= > -ngx_feature_libs= > -ngx_feature_test='void *p; int fd; > - fd = open("/dev/zero", O_RDWR); > - p = mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0); > - if (p == MAP_FAILED) return 1;' > -. auto/feature > +if [ $ngx_found = no ]; then > > + ngx_feature='mmap("/dev/zero", MAP_SHARED)' > + ngx_feature_name="NGX_HAVE_MAP_DEVZERO" > + ngx_feature_run=yes > + ngx_feature_incs="#include > + #include > + #include " > + ngx_feature_path= > + ngx_feature_libs= > + ngx_feature_test='void *p; int fd; > + fd = open("/dev/zero", O_RDWR); > + p = mmap(NULL, 4096, PROT_READ|PROT_WRITE, > + MAP_SHARED, fd, 0); > + if (p == MAP_FAILED) return 1;' > + . auto/feature > > -ngx_feature="System V shared memory" > -ngx_feature_name="NGX_HAVE_SYSVSHM" > -ngx_feature_run=yes > -ngx_feature_incs="#include > - #include " > -ngx_feature_path= > -ngx_feature_libs= > -ngx_feature_test="int id; > - id = shmget(IPC_PRIVATE, 4096, (SHM_R|SHM_W|IPC_CREAT)); > - if (id == -1) return 1; > - shmctl(id, IPC_RMID, NULL);" > -. auto/feature > +fi > + > + > +if [ $ngx_found = no ]; then > + > + ngx_feature="System V shared memory" > + ngx_feature_name="NGX_HAVE_SYSVSHM" > + ngx_feature_run=yes > + ngx_feature_incs="#include > + #include " > + ngx_feature_path= > + ngx_feature_libs= > + ngx_feature_test="int id; > + id = shmget(IPC_PRIVATE, 4096, (SHM_R|SHM_W|IPC_CREAT)); > + if (id == -1) return 1; > + shmctl(id, IPC_RMID, NULL);" > + . auto/feature > + > +fi > > > ngx_feature="POSIX semaphores" > > _______________________________________________ > nginx-devel mailing list > nginx-devel at nginx.org > http://mailman.nginx.org/mailman/listinfo/nginx-devel > -- Ruslan Ermilov Assume stupidity not malice From mdounin at mdounin.ru Tue Jun 28 12:59:08 2016 From: mdounin at mdounin.ru (Maxim Dounin) Date: Tue, 28 Jun 2016 15:59:08 +0300 Subject: [PATCH] Pass configuration options to PCRE build In-Reply-To: References: Message-ID: <20160628125908.GE30781@mdounin.ru> Hello! On Wed, Jun 22, 2016 at 04:05:17PM -0300, Marcelo MD wrote: > # HG changeset patch > # User Marcelo Mallmann > # Date 1466622014 10800 > # Wed Jun 22 16:00:14 2016 -0300 > # Node ID 3458ac42b0ce4e004516411eeab5a960253c1eac > # Parent 191e23214dfbaf01255d421f5bbe0d5541d03a2f > Pass configuration options to PCRE build > > Add '--with-pcre-conf-opt' option which passes its args to > pcre's 'configure' step. Similar patch was previously rejected, see here: http://mailman.nginx.org/pipermail/nginx-devel/2013-December/004650.html -- Maxim Dounin http://nginx.org/ From mdounin at mdounin.ru Tue Jun 28 13:25:36 2016 From: mdounin at mdounin.ru (Maxim Dounin) Date: Tue, 28 Jun 2016 16:25:36 +0300 Subject: [PATCH] Configure: don't test alternatives if preferred feature is found In-Reply-To: <20160628125434.GB31538@lo0.su> References: <20160628125434.GB31538@lo0.su> Message-ID: <20160628132535.GG30781@mdounin.ru> Hello! On Tue, Jun 28, 2016 at 03:54:34PM +0300, Ruslan Ermilov wrote: > Hi Piotr, > > On Mon, Jun 27, 2016 at 07:55:17PM -0700, Piotr Sikora wrote: > > # HG changeset patch > > # User Piotr Sikora > > # Date 1467064812 25200 > > # Mon Jun 27 15:00:12 2016 -0700 > > # Node ID e4375e338d9acf927ffdc4cd18c704bb7ea1fd4e > > # Parent d452cb27639f714bc43b7f3ede417e3e7f8efdd6 > > Configure: don't test alternatives if preferred feature is found. > > > > Signed-off-by: Piotr Sikora [...] > > diff -r d452cb27639f -r e4375e338d9a auto/unix > > --- a/auto/unix > > +++ b/auto/unix > > @@ -184,14 +184,18 @@ ngx_feature_test="fcntl(0, F_READAHEAD, > > . auto/feature > > > > > > -ngx_feature="posix_fadvise()" > > -ngx_feature_name="NGX_HAVE_POSIX_FADVISE" > > -ngx_feature_run=no > > -ngx_feature_incs="#include " > > -ngx_feature_path= > > -ngx_feature_libs= > > -ngx_feature_test="posix_fadvise(0, 0, 0, POSIX_FADV_SEQUENTIAL);" > > -. auto/feature > > +if [ $ngx_found = no ]; then > > + > > + ngx_feature="posix_fadvise()" > > + ngx_feature_name="NGX_HAVE_POSIX_FADVISE" > > + ngx_feature_run=no > > + ngx_feature_incs="#include " > > + ngx_feature_path= > > + ngx_feature_libs= > > + ngx_feature_test="posix_fadvise(0, 0, 0, POSIX_FADV_SEQUENTIAL);" > > + . auto/feature > > + > > +fi > > So far I have mixed feelings about this patch, but if it gets > accepted then the compile-time condition for ngx_read_ahead() > in src/os/unix/ngx_files.c can be simplified to only test > NGX_HAVE_POSIX_FADVISE. Also, there is the currently unused > macro NGX_HAVE_READ_AHEAD. There was at least one attempt to introduce a code using both fcntl(F_READAHEAD) and posix_fadvise() depending on a configuration. And I don't think this should be prevented at configure stage. -- Maxim Dounin http://nginx.org/ From shuxinyang.oss at gmail.com Tue Jun 28 19:16:48 2016 From: shuxinyang.oss at gmail.com (shuxinyang) Date: Tue, 28 Jun 2016 12:16:48 -0700 Subject: chunked-encoding disable range request Message-ID: <5772CD20.4090101@gmail.com> Hi, There: I find that range-request is disabled by Nginx proxy if backend server responses with chunked encoding. I verify my observation by: 1) manually edit the cache by replacing chunked-encoding header with content-length header, then range-request is enabled. 2) examine the header-filter of range filter, which indicates range filter is disabled when content-length is not valid. Question: a). Is my observation and verification approach correct? b). If so, is it Nginx's limitation or is the behavior defined by RFC? I tried to find the answer from RFCs, but in vain. Thanks! Shuxin From piotrsikora at google.com Tue Jun 28 21:16:29 2016 From: piotrsikora at google.com (Piotr Sikora) Date: Tue, 28 Jun 2016 14:16:29 -0700 Subject: [PATCH] Configure: don't test alternatives if preferred feature is found In-Reply-To: <20160628125434.GB31538@lo0.su> References: <20160628125434.GB31538@lo0.su> Message-ID: Hey Ruslan, > So far I have mixed feelings about this patch, but if it gets > accepted then the compile-time condition for ngx_read_ahead() > in src/os/unix/ngx_files.c can be simplified to only test > NGX_HAVE_POSIX_FADVISE. Also, there is the currently unused > macro NGX_HAVE_READ_AHEAD. Good idea, thanks! Best regards, Piotr Sikora From piotrsikora at google.com Tue Jun 28 21:25:09 2016 From: piotrsikora at google.com (Piotr Sikora) Date: Tue, 28 Jun 2016 14:25:09 -0700 Subject: [PATCH] Configure: don't test alternatives if preferred feature is found In-Reply-To: <20160628132535.GG30781@mdounin.ru> References: <20160628125434.GB31538@lo0.su> <20160628132535.GG30781@mdounin.ru> Message-ID: Hey Maxim, > There was at least one attempt to introduce a code using both > fcntl(F_READAHEAD) and posix_fadvise() depending on a > configuration. And I don't think this should be prevented at > configure stage. This code isn't part of current NGINX codebase, so it's a moot point. Once fallbacks to alternatives are added to the code (and I might add some myself), it's trivial to re-enable them in the ./configure script on case-by-case basis, but right now those tests for alternatives are just pointless and waste CPU cycles. Furthermore, sometimes those tests warn about issues in features that aren't going to get used anyway, because preferred feature was already found. For example, on OSX, you'll see this: checking for mmap(MAP_ANON|MAP_SHARED) ... found checking for mmap("/dev/zero", MAP_SHARED) ... found but is not working checking for System V shared memory ... found Best regards, Piotr Sikora From piotrsikora at google.com Tue Jun 28 22:26:14 2016 From: piotrsikora at google.com (Piotr Sikora) Date: Tue, 28 Jun 2016 15:26:14 -0700 Subject: [PATCH] Configure: don't test alternatives if preferred feature is found In-Reply-To: <20160628125434.GB31538@lo0.su> References: <20160628125434.GB31538@lo0.su> Message-ID: # HG changeset patch # User Piotr Sikora # Date 1467064812 25200 # Mon Jun 27 15:00:12 2016 -0700 # Node ID d1974e5bf34e45539bd2a4b3d08924fd3ed01639 # Parent d452cb27639f714bc43b7f3ede417e3e7f8efdd6 Configure: don't test alternatives if preferred feature is found. While there, remove unused NGX_HAVE_READ_AHEAD. Signed-off-by: Piotr Sikora diff -r d452cb27639f -r d1974e5bf34e auto/cc/conf --- a/auto/cc/conf +++ b/auto/cc/conf @@ -197,6 +197,7 @@ if [ "$NGX_PLATFORM" != win32 ]; then if [ "$NGX_CC_NAME" = "ccc" ]; then echo "checking for C99 variadic macros ... disabled" + ngx_found=no else ngx_feature="C99 variadic macros" ngx_feature_name="NGX_HAVE_C99_VARIADIC_MACROS" @@ -209,20 +210,24 @@ if [ "$NGX_PLATFORM" != win32 ]; then var(0, buf, \"%d\", 1); if (buf[0] != '1') return 1" . auto/feature - fi + fi - ngx_feature="gcc variadic macros" - ngx_feature_name="NGX_HAVE_GCC_VARIADIC_MACROS" - ngx_feature_run=yes - ngx_feature_incs="#include + if [ $ngx_found = no ]; then + + ngx_feature="gcc variadic macros" + ngx_feature_name="NGX_HAVE_GCC_VARIADIC_MACROS" + ngx_feature_run=yes + ngx_feature_incs="#include #define var(dummy, args...) sprintf(args)" - ngx_feature_path= - ngx_feature_libs= - ngx_feature_test="char buf[30]; buf[0] = '0'; - var(0, buf, \"%d\", 1); - if (buf[0] != '1') return 1" - . auto/feature + ngx_feature_path= + ngx_feature_libs= + ngx_feature_test="char buf[30]; buf[0] = '0'; + var(0, buf, \"%d\", 1); + if (buf[0] != '1') return 1" + . auto/feature + + fi ngx_feature="gcc builtin 64 bit byteswap" diff -r d452cb27639f -r d1974e5bf34e auto/unix --- a/auto/unix +++ b/auto/unix @@ -184,14 +184,18 @@ ngx_feature_test="fcntl(0, F_READAHEAD, . auto/feature -ngx_feature="posix_fadvise()" -ngx_feature_name="NGX_HAVE_POSIX_FADVISE" -ngx_feature_run=no -ngx_feature_incs="#include " -ngx_feature_path= -ngx_feature_libs= -ngx_feature_test="posix_fadvise(0, 0, 0, POSIX_FADV_SEQUENTIAL);" -. auto/feature +if [ $ngx_found = no ]; then + + ngx_feature="posix_fadvise()" + ngx_feature_name="NGX_HAVE_POSIX_FADVISE" + ngx_feature_run=no + ngx_feature_incs="#include " + ngx_feature_path= + ngx_feature_libs= + ngx_feature_test="posix_fadvise(0, 0, 0, POSIX_FADV_SEQUENTIAL);" + . auto/feature + +fi ngx_feature="O_DIRECT" @@ -208,25 +212,34 @@ if [ $ngx_found = yes -a "$NGX_SYSTEM" = have=NGX_HAVE_ALIGNED_DIRECTIO . auto/have fi -ngx_feature="F_NOCACHE" -ngx_feature_name="NGX_HAVE_F_NOCACHE" -ngx_feature_run=no -ngx_feature_incs="#include " -ngx_feature_path= -ngx_feature_libs= -ngx_feature_test="fcntl(0, F_NOCACHE, 1);" -. auto/feature +if [ $ngx_found = no ]; then -ngx_feature="directio()" -ngx_feature_name="NGX_HAVE_DIRECTIO" -ngx_feature_run=no -ngx_feature_incs="#include - #include " -ngx_feature_path= -ngx_feature_libs= -ngx_feature_test="directio(0, DIRECTIO_ON);" -. auto/feature + ngx_feature="F_NOCACHE" + ngx_feature_name="NGX_HAVE_F_NOCACHE" + ngx_feature_run=no + ngx_feature_incs="#include " + ngx_feature_path= + ngx_feature_libs= + ngx_feature_test="fcntl(0, F_NOCACHE, 1);" + . auto/feature + +fi + + +if [ $ngx_found = no ]; then + + ngx_feature="directio()" + ngx_feature_name="NGX_HAVE_DIRECTIO" + ngx_feature_run=no + ngx_feature_incs="#include + #include " + ngx_feature_path= + ngx_feature_libs= + ngx_feature_test="directio(0, DIRECTIO_ON);" + . auto/feature + +fi ngx_feature="statfs()" @@ -242,16 +255,20 @@ ngx_feature_test="struct statfs fs; . auto/feature -ngx_feature="statvfs()" -ngx_feature_name="NGX_HAVE_STATVFS" -ngx_feature_run=no -ngx_feature_incs="#include - #include " -ngx_feature_path= -ngx_feature_libs= -ngx_feature_test="struct statvfs fs; - statvfs(\".\", &fs);" -. auto/feature +if [ $ngx_found = no ]; then + + ngx_feature="statvfs()" + ngx_feature_name="NGX_HAVE_STATVFS" + ngx_feature_run=no + ngx_feature_incs="#include + #include " + ngx_feature_path= + ngx_feature_libs= + ngx_feature_test="struct statvfs fs; + statvfs(\".\", &fs);" + . auto/feature + +fi ngx_feature="dlopen()" @@ -356,28 +373,36 @@ ngx_feature_test="setsockopt(0, IPPROTO_ # Linux transparent proxying -ngx_feature="IP_TRANSPARENT" -ngx_feature_name="NGX_HAVE_TRANSPARENT_PROXY" -ngx_feature_run=no -ngx_feature_incs="#include - #include " -ngx_feature_path= -ngx_feature_libs= -ngx_feature_test="setsockopt(0, IPPROTO_IP, IP_TRANSPARENT, NULL, 0)" -. auto/feature +if [ $ngx_found = no ]; then + + ngx_feature="IP_TRANSPARENT" + ngx_feature_name="NGX_HAVE_TRANSPARENT_PROXY" + ngx_feature_run=no + ngx_feature_incs="#include + #include " + ngx_feature_path= + ngx_feature_libs= + ngx_feature_test="setsockopt(0, IPPROTO_IP, IP_TRANSPARENT, NULL, 0)" + . auto/feature + +fi # FreeBSD bind to any address for transparent proxying -ngx_feature="IP_BINDANY" -ngx_feature_name="NGX_HAVE_TRANSPARENT_PROXY" -ngx_feature_run=no -ngx_feature_incs="#include - #include " -ngx_feature_path= -ngx_feature_libs= -ngx_feature_test="setsockopt(0, IPPROTO_IP, IP_BINDANY, NULL, 0)" -. auto/feature +if [ $ngx_found = no ]; then + + ngx_feature="IP_BINDANY" + ngx_feature_name="NGX_HAVE_TRANSPARENT_PROXY" + ngx_feature_run=no + ngx_feature_incs="#include + #include " + ngx_feature_path= + ngx_feature_libs= + ngx_feature_test="setsockopt(0, IPPROTO_IP, IP_BINDANY, NULL, 0)" + . auto/feature + +fi # BSD way to get IPv4 datagram destination address @@ -395,15 +420,19 @@ ngx_feature_test="setsockopt(0, IPPROTO_ # Linux way to get IPv4 datagram destination address -ngx_feature="IP_PKTINFO" -ngx_feature_name="NGX_HAVE_IP_PKTINFO" -ngx_feature_run=no -ngx_feature_incs="#include - #include " -ngx_feature_path= -ngx_feature_libs= -ngx_feature_test="setsockopt(0, IPPROTO_IP, IP_PKTINFO, NULL, 0)" -. auto/feature +if [ $ngx_found = no ]; then + + ngx_feature="IP_PKTINFO" + ngx_feature_name="NGX_HAVE_IP_PKTINFO" + ngx_feature_run=no + ngx_feature_incs="#include + #include " + ngx_feature_path= + ngx_feature_libs= + ngx_feature_test="setsockopt(0, IPPROTO_IP, IP_PKTINFO, NULL, 0)" + . auto/feature + +fi # RFC 3542 way to get IPv6 datagram destination address @@ -772,16 +801,20 @@ ngx_feature_test="void *p; int n; n = po . auto/feature -ngx_feature="memalign()" -ngx_feature_name="NGX_HAVE_MEMALIGN" -ngx_feature_run=no -ngx_feature_incs="#include - #include " -ngx_feature_path= -ngx_feature_libs= -ngx_feature_test="void *p; p = memalign(4096, 4096); - if (p == NULL) return 1" -. auto/feature +if [ $ngx_found = no ]; then + + ngx_feature="memalign()" + ngx_feature_name="NGX_HAVE_MEMALIGN" + ngx_feature_run=no + ngx_feature_incs="#include + #include " + ngx_feature_path= + ngx_feature_libs= + ngx_feature_test="void *p; p = memalign(4096, 4096); + if (p == NULL) return 1" + . auto/feature + +fi ngx_feature="mmap(MAP_ANON|MAP_SHARED)" @@ -797,33 +830,42 @@ ngx_feature_test="void *p; . auto/feature -ngx_feature='mmap("/dev/zero", MAP_SHARED)' -ngx_feature_name="NGX_HAVE_MAP_DEVZERO" -ngx_feature_run=yes -ngx_feature_incs="#include - #include - #include " -ngx_feature_path= -ngx_feature_libs= -ngx_feature_test='void *p; int fd; - fd = open("/dev/zero", O_RDWR); - p = mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0); - if (p == MAP_FAILED) return 1;' -. auto/feature +if [ $ngx_found = no ]; then + ngx_feature='mmap("/dev/zero", MAP_SHARED)' + ngx_feature_name="NGX_HAVE_MAP_DEVZERO" + ngx_feature_run=yes + ngx_feature_incs="#include + #include + #include " + ngx_feature_path= + ngx_feature_libs= + ngx_feature_test='void *p; int fd; + fd = open("/dev/zero", O_RDWR); + p = mmap(NULL, 4096, PROT_READ|PROT_WRITE, + MAP_SHARED, fd, 0); + if (p == MAP_FAILED) return 1;' + . auto/feature -ngx_feature="System V shared memory" -ngx_feature_name="NGX_HAVE_SYSVSHM" -ngx_feature_run=yes -ngx_feature_incs="#include - #include " -ngx_feature_path= -ngx_feature_libs= -ngx_feature_test="int id; - id = shmget(IPC_PRIVATE, 4096, (SHM_R|SHM_W|IPC_CREAT)); - if (id == -1) return 1; - shmctl(id, IPC_RMID, NULL);" -. auto/feature +fi + + +if [ $ngx_found = no ]; then + + ngx_feature="System V shared memory" + ngx_feature_name="NGX_HAVE_SYSVSHM" + ngx_feature_run=yes + ngx_feature_incs="#include + #include " + ngx_feature_path= + ngx_feature_libs= + ngx_feature_test="int id; + id = shmget(IPC_PRIVATE, 4096, (SHM_R|SHM_W|IPC_CREAT)); + if (id == -1) return 1; + shmctl(id, IPC_RMID, NULL);" + . auto/feature + +fi ngx_feature="POSIX semaphores" diff -r d452cb27639f -r d1974e5bf34e src/os/unix/ngx_files.c --- a/src/os/unix/ngx_files.c +++ b/src/os/unix/ngx_files.c @@ -805,7 +805,7 @@ ngx_unlock_fd(ngx_fd_t fd) } -#if (NGX_HAVE_POSIX_FADVISE) && !(NGX_HAVE_F_READAHEAD) +#if (NGX_HAVE_POSIX_FADVISE) ngx_int_t ngx_read_ahead(ngx_fd_t fd, size_t n) diff -r d452cb27639f -r d1974e5bf34e src/os/unix/ngx_files.h --- a/src/os/unix/ngx_files.h +++ b/src/os/unix/ngx_files.h @@ -303,15 +303,11 @@ ngx_err_t ngx_unlock_fd(ngx_fd_t fd); #if (NGX_HAVE_F_READAHEAD) -#define NGX_HAVE_READ_AHEAD 1 - #define ngx_read_ahead(fd, n) fcntl(fd, F_READAHEAD, (int) n) #define ngx_read_ahead_n "fcntl(fd, F_READAHEAD)" #elif (NGX_HAVE_POSIX_FADVISE) -#define NGX_HAVE_READ_AHEAD 1 - ngx_int_t ngx_read_ahead(ngx_fd_t fd, size_t n); #define ngx_read_ahead_n "posix_fadvise(POSIX_FADV_SEQUENTIAL)" From piotrsikora at google.com Tue Jun 28 22:28:31 2016 From: piotrsikora at google.com (Piotr Sikora) Date: Tue, 28 Jun 2016 15:28:31 -0700 Subject: [PATCH] Configure: don't test alternatives if preferred feature is found In-Reply-To: <20160628125434.GB31538@lo0.su> References: <20160628125434.GB31538@lo0.su> Message-ID: <9e0d65eda7fa016c0aeb.1467152911@piotrsikora.sfo.corp.google.com> # HG changeset patch # User Piotr Sikora # Date 1467064812 25200 # Mon Jun 27 15:00:12 2016 -0700 # Node ID 9e0d65eda7fa016c0aebddf898d6f3f5834351f1 # Parent d452cb27639f714bc43b7f3ede417e3e7f8efdd6 Configure: don't test alternatives if preferred feature is found. Signed-off-by: Piotr Sikora diff -r d452cb27639f -r 9e0d65eda7fa auto/cc/conf --- a/auto/cc/conf +++ b/auto/cc/conf @@ -197,6 +197,7 @@ if [ "$NGX_PLATFORM" != win32 ]; then if [ "$NGX_CC_NAME" = "ccc" ]; then echo "checking for C99 variadic macros ... disabled" + ngx_found=no else ngx_feature="C99 variadic macros" ngx_feature_name="NGX_HAVE_C99_VARIADIC_MACROS" @@ -209,20 +210,24 @@ if [ "$NGX_PLATFORM" != win32 ]; then var(0, buf, \"%d\", 1); if (buf[0] != '1') return 1" . auto/feature - fi + fi - ngx_feature="gcc variadic macros" - ngx_feature_name="NGX_HAVE_GCC_VARIADIC_MACROS" - ngx_feature_run=yes - ngx_feature_incs="#include + if [ $ngx_found = no ]; then + + ngx_feature="gcc variadic macros" + ngx_feature_name="NGX_HAVE_GCC_VARIADIC_MACROS" + ngx_feature_run=yes + ngx_feature_incs="#include #define var(dummy, args...) sprintf(args)" - ngx_feature_path= - ngx_feature_libs= - ngx_feature_test="char buf[30]; buf[0] = '0'; - var(0, buf, \"%d\", 1); - if (buf[0] != '1') return 1" - . auto/feature + ngx_feature_path= + ngx_feature_libs= + ngx_feature_test="char buf[30]; buf[0] = '0'; + var(0, buf, \"%d\", 1); + if (buf[0] != '1') return 1" + . auto/feature + + fi ngx_feature="gcc builtin 64 bit byteswap" diff -r d452cb27639f -r 9e0d65eda7fa auto/unix --- a/auto/unix +++ b/auto/unix @@ -184,14 +184,18 @@ ngx_feature_test="fcntl(0, F_READAHEAD, . auto/feature -ngx_feature="posix_fadvise()" -ngx_feature_name="NGX_HAVE_POSIX_FADVISE" -ngx_feature_run=no -ngx_feature_incs="#include " -ngx_feature_path= -ngx_feature_libs= -ngx_feature_test="posix_fadvise(0, 0, 0, POSIX_FADV_SEQUENTIAL);" -. auto/feature +if [ $ngx_found = no ]; then + + ngx_feature="posix_fadvise()" + ngx_feature_name="NGX_HAVE_POSIX_FADVISE" + ngx_feature_run=no + ngx_feature_incs="#include " + ngx_feature_path= + ngx_feature_libs= + ngx_feature_test="posix_fadvise(0, 0, 0, POSIX_FADV_SEQUENTIAL);" + . auto/feature + +fi ngx_feature="O_DIRECT" @@ -208,25 +212,34 @@ if [ $ngx_found = yes -a "$NGX_SYSTEM" = have=NGX_HAVE_ALIGNED_DIRECTIO . auto/have fi -ngx_feature="F_NOCACHE" -ngx_feature_name="NGX_HAVE_F_NOCACHE" -ngx_feature_run=no -ngx_feature_incs="#include " -ngx_feature_path= -ngx_feature_libs= -ngx_feature_test="fcntl(0, F_NOCACHE, 1);" -. auto/feature +if [ $ngx_found = no ]; then -ngx_feature="directio()" -ngx_feature_name="NGX_HAVE_DIRECTIO" -ngx_feature_run=no -ngx_feature_incs="#include - #include " -ngx_feature_path= -ngx_feature_libs= -ngx_feature_test="directio(0, DIRECTIO_ON);" -. auto/feature + ngx_feature="F_NOCACHE" + ngx_feature_name="NGX_HAVE_F_NOCACHE" + ngx_feature_run=no + ngx_feature_incs="#include " + ngx_feature_path= + ngx_feature_libs= + ngx_feature_test="fcntl(0, F_NOCACHE, 1);" + . auto/feature + +fi + + +if [ $ngx_found = no ]; then + + ngx_feature="directio()" + ngx_feature_name="NGX_HAVE_DIRECTIO" + ngx_feature_run=no + ngx_feature_incs="#include + #include " + ngx_feature_path= + ngx_feature_libs= + ngx_feature_test="directio(0, DIRECTIO_ON);" + . auto/feature + +fi ngx_feature="statfs()" @@ -242,16 +255,20 @@ ngx_feature_test="struct statfs fs; . auto/feature -ngx_feature="statvfs()" -ngx_feature_name="NGX_HAVE_STATVFS" -ngx_feature_run=no -ngx_feature_incs="#include - #include " -ngx_feature_path= -ngx_feature_libs= -ngx_feature_test="struct statvfs fs; - statvfs(\".\", &fs);" -. auto/feature +if [ $ngx_found = no ]; then + + ngx_feature="statvfs()" + ngx_feature_name="NGX_HAVE_STATVFS" + ngx_feature_run=no + ngx_feature_incs="#include + #include " + ngx_feature_path= + ngx_feature_libs= + ngx_feature_test="struct statvfs fs; + statvfs(\".\", &fs);" + . auto/feature + +fi ngx_feature="dlopen()" @@ -356,28 +373,36 @@ ngx_feature_test="setsockopt(0, IPPROTO_ # Linux transparent proxying -ngx_feature="IP_TRANSPARENT" -ngx_feature_name="NGX_HAVE_TRANSPARENT_PROXY" -ngx_feature_run=no -ngx_feature_incs="#include - #include " -ngx_feature_path= -ngx_feature_libs= -ngx_feature_test="setsockopt(0, IPPROTO_IP, IP_TRANSPARENT, NULL, 0)" -. auto/feature +if [ $ngx_found = no ]; then + + ngx_feature="IP_TRANSPARENT" + ngx_feature_name="NGX_HAVE_TRANSPARENT_PROXY" + ngx_feature_run=no + ngx_feature_incs="#include + #include " + ngx_feature_path= + ngx_feature_libs= + ngx_feature_test="setsockopt(0, IPPROTO_IP, IP_TRANSPARENT, NULL, 0)" + . auto/feature + +fi # FreeBSD bind to any address for transparent proxying -ngx_feature="IP_BINDANY" -ngx_feature_name="NGX_HAVE_TRANSPARENT_PROXY" -ngx_feature_run=no -ngx_feature_incs="#include - #include " -ngx_feature_path= -ngx_feature_libs= -ngx_feature_test="setsockopt(0, IPPROTO_IP, IP_BINDANY, NULL, 0)" -. auto/feature +if [ $ngx_found = no ]; then + + ngx_feature="IP_BINDANY" + ngx_feature_name="NGX_HAVE_TRANSPARENT_PROXY" + ngx_feature_run=no + ngx_feature_incs="#include + #include " + ngx_feature_path= + ngx_feature_libs= + ngx_feature_test="setsockopt(0, IPPROTO_IP, IP_BINDANY, NULL, 0)" + . auto/feature + +fi # BSD way to get IPv4 datagram destination address @@ -395,15 +420,19 @@ ngx_feature_test="setsockopt(0, IPPROTO_ # Linux way to get IPv4 datagram destination address -ngx_feature="IP_PKTINFO" -ngx_feature_name="NGX_HAVE_IP_PKTINFO" -ngx_feature_run=no -ngx_feature_incs="#include - #include " -ngx_feature_path= -ngx_feature_libs= -ngx_feature_test="setsockopt(0, IPPROTO_IP, IP_PKTINFO, NULL, 0)" -. auto/feature +if [ $ngx_found = no ]; then + + ngx_feature="IP_PKTINFO" + ngx_feature_name="NGX_HAVE_IP_PKTINFO" + ngx_feature_run=no + ngx_feature_incs="#include + #include " + ngx_feature_path= + ngx_feature_libs= + ngx_feature_test="setsockopt(0, IPPROTO_IP, IP_PKTINFO, NULL, 0)" + . auto/feature + +fi # RFC 3542 way to get IPv6 datagram destination address @@ -772,16 +801,20 @@ ngx_feature_test="void *p; int n; n = po . auto/feature -ngx_feature="memalign()" -ngx_feature_name="NGX_HAVE_MEMALIGN" -ngx_feature_run=no -ngx_feature_incs="#include - #include " -ngx_feature_path= -ngx_feature_libs= -ngx_feature_test="void *p; p = memalign(4096, 4096); - if (p == NULL) return 1" -. auto/feature +if [ $ngx_found = no ]; then + + ngx_feature="memalign()" + ngx_feature_name="NGX_HAVE_MEMALIGN" + ngx_feature_run=no + ngx_feature_incs="#include + #include " + ngx_feature_path= + ngx_feature_libs= + ngx_feature_test="void *p; p = memalign(4096, 4096); + if (p == NULL) return 1" + . auto/feature + +fi ngx_feature="mmap(MAP_ANON|MAP_SHARED)" @@ -797,33 +830,42 @@ ngx_feature_test="void *p; . auto/feature -ngx_feature='mmap("/dev/zero", MAP_SHARED)' -ngx_feature_name="NGX_HAVE_MAP_DEVZERO" -ngx_feature_run=yes -ngx_feature_incs="#include - #include - #include " -ngx_feature_path= -ngx_feature_libs= -ngx_feature_test='void *p; int fd; - fd = open("/dev/zero", O_RDWR); - p = mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0); - if (p == MAP_FAILED) return 1;' -. auto/feature +if [ $ngx_found = no ]; then + ngx_feature='mmap("/dev/zero", MAP_SHARED)' + ngx_feature_name="NGX_HAVE_MAP_DEVZERO" + ngx_feature_run=yes + ngx_feature_incs="#include + #include + #include " + ngx_feature_path= + ngx_feature_libs= + ngx_feature_test='void *p; int fd; + fd = open("/dev/zero", O_RDWR); + p = mmap(NULL, 4096, PROT_READ|PROT_WRITE, + MAP_SHARED, fd, 0); + if (p == MAP_FAILED) return 1;' + . auto/feature -ngx_feature="System V shared memory" -ngx_feature_name="NGX_HAVE_SYSVSHM" -ngx_feature_run=yes -ngx_feature_incs="#include - #include " -ngx_feature_path= -ngx_feature_libs= -ngx_feature_test="int id; - id = shmget(IPC_PRIVATE, 4096, (SHM_R|SHM_W|IPC_CREAT)); - if (id == -1) return 1; - shmctl(id, IPC_RMID, NULL);" -. auto/feature +fi + + +if [ $ngx_found = no ]; then + + ngx_feature="System V shared memory" + ngx_feature_name="NGX_HAVE_SYSVSHM" + ngx_feature_run=yes + ngx_feature_incs="#include + #include " + ngx_feature_path= + ngx_feature_libs= + ngx_feature_test="int id; + id = shmget(IPC_PRIVATE, 4096, (SHM_R|SHM_W|IPC_CREAT)); + if (id == -1) return 1; + shmctl(id, IPC_RMID, NULL);" + . auto/feature + +fi ngx_feature="POSIX semaphores" diff -r d452cb27639f -r 9e0d65eda7fa src/os/unix/ngx_files.c --- a/src/os/unix/ngx_files.c +++ b/src/os/unix/ngx_files.c @@ -805,7 +805,7 @@ ngx_unlock_fd(ngx_fd_t fd) } -#if (NGX_HAVE_POSIX_FADVISE) && !(NGX_HAVE_F_READAHEAD) +#if (NGX_HAVE_POSIX_FADVISE) ngx_int_t ngx_read_ahead(ngx_fd_t fd, size_t n) From ru at nginx.com Thu Jun 30 09:36:05 2016 From: ru at nginx.com (Ruslan Ermilov) Date: Thu, 30 Jun 2016 09:36:05 +0000 Subject: [nginx] Removed unused flag accept_context_updated from ngx_event_t. Message-ID: details: http://hg.nginx.org/nginx/rev/bcd442b585f0 branches: changeset: 6602:bcd442b585f0 user: Ruslan Ermilov date: Wed Jun 29 14:30:00 2016 +0300 description: Removed unused flag accept_context_updated from ngx_event_t. Also, removed practically unused flag accept_context_updated from ngx_connection_t. diffstat: src/core/ngx_connection.h | 4 ---- src/event/ngx_event.h | 5 ----- src/event/ngx_event_acceptex.c | 4 ++-- 3 files changed, 2 insertions(+), 11 deletions(-) diffs (43 lines): diff -r d452cb27639f -r bcd442b585f0 src/core/ngx_connection.h --- a/src/core/ngx_connection.h Mon Jun 27 18:42:29 2016 +0300 +++ b/src/core/ngx_connection.h Wed Jun 29 14:30:00 2016 +0300 @@ -186,10 +186,6 @@ struct ngx_connection_s { unsigned need_last_buf:1; -#if (NGX_HAVE_IOCP) - unsigned accept_context_updated:1; -#endif - #if (NGX_HAVE_AIO_SENDFILE) unsigned busy_count:2; #endif diff -r d452cb27639f -r bcd442b585f0 src/event/ngx_event.h --- a/src/event/ngx_event.h Mon Jun 27 18:42:29 2016 +0300 +++ b/src/event/ngx_event.h Wed Jun 29 14:30:00 2016 +0300 @@ -76,11 +76,6 @@ struct ngx_event_s { unsigned cancelable:1; -#if (NGX_WIN32) - /* setsockopt(SO_UPDATE_ACCEPT_CONTEXT) was successful */ - unsigned accept_context_updated:1; -#endif - #if (NGX_HAVE_KQUEUE) unsigned kq_vnode:1; diff -r d452cb27639f -r bcd442b585f0 src/event/ngx_event_acceptex.c --- a/src/event/ngx_event_acceptex.c Mon Jun 27 18:42:29 2016 +0300 +++ b/src/event/ngx_event_acceptex.c Wed Jun 29 14:30:00 2016 +0300 @@ -41,8 +41,8 @@ ngx_event_acceptex(ngx_event_t *rev) ngx_log_error(NGX_LOG_CRIT, c->log, ngx_socket_errno, "setsockopt(SO_UPDATE_ACCEPT_CONTEXT) failed for %V", &c->addr_text); - } else { - c->accept_context_updated = 1; + /* TODO: close socket */ + return; } ngx_getacceptexsockaddrs(c->buffer->pos, From mdounin at mdounin.ru Thu Jun 30 14:16:44 2016 From: mdounin at mdounin.ru (Maxim Dounin) Date: Thu, 30 Jun 2016 17:16:44 +0300 Subject: [PATCH] Configure: don't test alternatives if preferred feature is found In-Reply-To: <9e0d65eda7fa016c0aeb.1467152911@piotrsikora.sfo.corp.google.com> References: <20160628125434.GB31538@lo0.su> <9e0d65eda7fa016c0aeb.1467152911@piotrsikora.sfo.corp.google.com> Message-ID: <20160630141644.GY30781@mdounin.ru> Hello! On Tue, Jun 28, 2016 at 03:28:31PM -0700, Piotr Sikora wrote: > # HG changeset patch > # User Piotr Sikora > # Date 1467064812 25200 > # Mon Jun 27 15:00:12 2016 -0700 > # Node ID 9e0d65eda7fa016c0aebddf898d6f3f5834351f1 > # Parent d452cb27639f714bc43b7f3ede417e3e7f8efdd6 > Configure: don't test alternatives if preferred feature is found. [...] > @@ -356,28 +373,36 @@ ngx_feature_test="setsockopt(0, IPPROTO_ > > # Linux transparent proxying > > -ngx_feature="IP_TRANSPARENT" > -ngx_feature_name="NGX_HAVE_TRANSPARENT_PROXY" > -ngx_feature_run=no > -ngx_feature_incs="#include > - #include " > -ngx_feature_path= > -ngx_feature_libs= > -ngx_feature_test="setsockopt(0, IPPROTO_IP, IP_TRANSPARENT, NULL, 0)" > -. auto/feature > +if [ $ngx_found = no ]; then > + > + ngx_feature="IP_TRANSPARENT" > + ngx_feature_name="NGX_HAVE_TRANSPARENT_PROXY" This looks like a mismerge, as previous tests is about IP_BIND_ADDRESS_NO_PORT (it is probably misplaced though). -- Maxim Dounin http://nginx.org/ From mdounin at mdounin.ru Thu Jun 30 16:17:47 2016 From: mdounin at mdounin.ru (Maxim Dounin) Date: Thu, 30 Jun 2016 16:17:47 +0000 Subject: [nginx] Internal md5 and sha1 implementations are now always used. Message-ID: details: http://hg.nginx.org/nginx/rev/9eefb38f0005 branches: changeset: 6603:9eefb38f0005 user: Maxim Dounin date: Thu Jun 30 18:57:39 2016 +0300 description: Internal md5 and sha1 implementations are now always used. This reduces the number of moving parts in ABI compatibility checks. Additionally, it also allows to use OpenSSL in FIPS mode while still using md5 for non-security tasks. diffstat: auto/cc/acc | 1 - auto/cc/clang | 6 -- auto/cc/gcc | 6 -- auto/cc/icc | 4 - auto/cc/sunc | 4 - auto/lib/conf | 29 ------------ auto/lib/make | 8 --- auto/lib/md5/conf | 103 -------------------------------------------- auto/lib/md5/make | 96 ----------------------------------------- auto/lib/md5/makefile.bcc | 22 --------- auto/lib/md5/makefile.msvc | 22 --------- auto/lib/md5/makefile.owc | 11 ---- auto/lib/sha1/conf | 79 --------------------------------- auto/lib/sha1/make | 96 ----------------------------------------- auto/lib/sha1/makefile.bcc | 22 --------- auto/lib/sha1/makefile.msvc | 22 --------- auto/lib/sha1/makefile.owc | 11 ---- auto/module | 18 ++++++- auto/modules | 6 -- auto/options | 48 ++++++++++---------- auto/summary | 14 ----- src/core/ngx_md5.c | 6 -- src/core/ngx_md5.h | 32 ------------- src/core/ngx_module.h | 9 --- src/core/ngx_sha1.c | 6 -- src/core/ngx_sha1.h | 22 --------- 26 files changed, 39 insertions(+), 664 deletions(-) diffs (truncated from 1003 to 1000 lines): diff --git a/auto/cc/acc b/auto/cc/acc --- a/auto/cc/acc +++ b/auto/cc/acc @@ -12,4 +12,3 @@ CC_TEST_FLAGS="-Ae" PCRE_OPT="$PCRE_OPT -Ae" ZLIB_OPT="$ZLIB_OPT -Ae" -MD5_OPT="$MD5_OPT -Ae" diff --git a/auto/cc/clang b/auto/cc/clang --- a/auto/cc/clang +++ b/auto/cc/clang @@ -66,12 +66,6 @@ else PCRE_OPT="$PCRE_OPT -pipe" fi -if [ ".$MD5_OPT" = "." ]; then - MD5_OPT="-O2 -pipe $CPU_OPT" -else - MD5_OPT="$MD5_OPT -pipe" -fi - if [ ".$ZLIB_OPT" = "." ]; then ZLIB_OPT="-O2 -pipe $CPU_OPT" else diff --git a/auto/cc/gcc b/auto/cc/gcc --- a/auto/cc/gcc +++ b/auto/cc/gcc @@ -128,12 +128,6 @@ else PCRE_OPT="$PCRE_OPT $PIPE" fi -if [ ".$MD5_OPT" = "." ]; then - MD5_OPT="-O2 -fomit-frame-pointer $PIPE $CPU_OPT" -else - MD5_OPT="$MD5_OPT $PIPE" -fi - if [ ".$ZLIB_OPT" = "." ]; then ZLIB_OPT="-O2 -fomit-frame-pointer $PIPE $CPU_OPT" else diff --git a/auto/cc/icc b/auto/cc/icc --- a/auto/cc/icc +++ b/auto/cc/icc @@ -43,10 +43,6 @@ if [ ".$PCRE_OPT" = "." ]; then PCRE_OPT="-O $CPU_OPT" fi -if [ ".$MD5_OPT" = "." ]; then - MD5_OPT="-O $CPU_OPT" -fi - if [ ".$ZLIB_OPT" = "." ]; then ZLIB_OPT="-O $CPU_OPT" fi diff --git a/auto/cc/sunc b/auto/cc/sunc --- a/auto/cc/sunc +++ b/auto/cc/sunc @@ -145,10 +145,6 @@ if [ ".$PCRE_OPT" = "." ]; then PCRE_OPT="$ngx_fast $IPO $CPU_OPT" fi -if [ ".$MD5_OPT" = "." ]; then - MD5_OPT="$ngx_fast $IPO $CPU_OPT" -fi - if [ ".$ZLIB_OPT" = "." ]; then ZLIB_OPT="$ngx_fast $IPO $CPU_OPT" fi diff --git a/auto/lib/conf b/auto/lib/conf --- a/auto/lib/conf +++ b/auto/lib/conf @@ -25,35 +25,6 @@ if [ $USE_OPENSSL = YES ]; then . auto/lib/openssl/conf fi -if [ $USE_MD5 = YES ]; then - - if [ $USE_OPENSSL = YES ]; then - have=NGX_HAVE_OPENSSL_MD5_H . auto/have - have=NGX_OPENSSL_MD5 . auto/have - have=NGX_HAVE_MD5 . auto/have - MD5=YES - MD5_LIB=OpenSSL - - else - . auto/lib/md5/conf - fi - -fi - -if [ $USE_SHA1 = YES ]; then - - if [ $USE_OPENSSL = YES ]; then - have=NGX_HAVE_OPENSSL_SHA1_H . auto/have - have=NGX_HAVE_SHA1 . auto/have - SHA1=YES - SHA1_LIB=OpenSSL - - else - . auto/lib/sha1/conf - fi - -fi - if [ $USE_ZLIB = YES ]; then . auto/lib/zlib/conf fi diff --git a/auto/lib/make b/auto/lib/make --- a/auto/lib/make +++ b/auto/lib/make @@ -7,14 +7,6 @@ if [ $PCRE != NONE -a $PCRE != NO -a $PC . auto/lib/pcre/make fi -if [ $MD5 != NONE -a $MD5 != NO -a $MD5 != YES ]; then - . auto/lib/md5/make -fi - -if [ $SHA1 != NONE -a $SHA1 != NO -a $SHA1 != YES ]; then - . auto/lib/sha1/make -fi - if [ $OPENSSL != NONE -a $OPENSSL != NO -a $OPENSSL != YES ]; then . auto/lib/openssl/make fi diff --git a/auto/lib/md5/conf b/auto/lib/md5/conf deleted file mode 100644 --- a/auto/lib/md5/conf +++ /dev/null @@ -1,103 +0,0 @@ - -# Copyright (C) Igor Sysoev -# Copyright (C) Nginx, Inc. - - -if [ $MD5 != NONE ]; then - - if grep MD5_Init $MD5/md5.h 2>&1 >/dev/null; then - # OpenSSL md5 - OPENSSL_MD5=YES - have=NGX_HAVE_OPENSSL_MD5 . auto/have - have=NGX_OPENSSL_MD5 . auto/have - else - # rsaref md5 - OPENSSL_MD5=NO - fi - - have=NGX_HAVE_MD5 . auto/have - CORE_INCS="$CORE_INCS $MD5" - - case "$NGX_CC_NAME" in - - msvc | owc | bcc) - LINK_DEPS="$LINK_DEPS $MD5/md5.lib" - CORE_LIBS="$CORE_LIBS $MD5/md5.lib" - ;; - - icc) - LINK_DEPS="$LINK_DEPS $MD5/libmd5.a" - - # to allow -ipo optimization we link with the *.o but not library - CORE_LIBS="$CORE_LIBS $MD5/md5_dgst.o" - - if [ $MD5_ASM = YES ]; then - CORE_LIBS="$CORE_LIBS $MD5/asm/mx86-elf.o" - fi - ;; - - *) - LINK_DEPS="$LINK_DEPS $MD5/libmd5.a" - CORE_LIBS="$CORE_LIBS $MD5/libmd5.a" - #CORE_LIBS="$CORE_LIBS -L $MD5 -lmd5" - ;; - - esac - -else - - if [ "$NGX_PLATFORM" != win32 ]; then - - MD5=NO - - # FreeBSD, Solaris 10 - - ngx_feature="md5 in system md library" - ngx_feature_name=NGX_HAVE_MD5 - ngx_feature_run=no - ngx_feature_incs="#include " - ngx_feature_path= - ngx_feature_libs="-lmd" - ngx_feature_test="MD5_CTX md5; MD5Init(&md5)" - . auto/feature - - ngx_md5_lib="system md" - - if [ $ngx_found = no ]; then - - # Solaris 8/9 - - ngx_feature="md5 in system md5 library" - ngx_feature_libs="-lmd5" - . auto/feature - - ngx_md5_lib="system md5" - fi - - if [ $ngx_found = no ]; then - - # OpenSSL crypto library - - ngx_feature="md5 in system OpenSSL crypto library" - ngx_feature_name="NGX_OPENSSL_MD5" - ngx_feature_incs="#include " - ngx_feature_libs="-lcrypto" - ngx_feature_test="MD5_CTX md5; MD5_Init(&md5)" - . auto/feature - - ngx_md5_lib="system crypto" - - if [ $ngx_found = yes ]; then - have=NGX_HAVE_OPENSSL_MD5_H . auto/have - have=NGX_HAVE_MD5 . auto/have - fi - fi - - if [ $ngx_found = yes ]; then - CORE_LIBS="$CORE_LIBS $ngx_feature_libs" - MD5=YES - MD5_LIB=$ngx_md5_lib - fi - fi - -fi diff --git a/auto/lib/md5/make b/auto/lib/md5/make deleted file mode 100644 --- a/auto/lib/md5/make +++ /dev/null @@ -1,96 +0,0 @@ - -# Copyright (C) Igor Sysoev -# Copyright (C) Nginx, Inc. - - -case "$NGX_CC_NAME" in - - msvc) - ngx_makefile=makefile.msvc - ngx_opt="CPU_OPT=\"$CPU_OPT\" LIBC=$LIBC MD5_ASM=$MD5_ASM" - ngx_md5="MD5=\"$MD5\"" - ;; - - owc) - ngx_makefile=makefile.owc - ngx_opt="CPU_OPT=\"$CPU_OPT\"" - ngx_md5=`echo MD5=\"$MD5\" | sed -e "s/\//$ngx_regex_dirsep/g"` - ;; - - bcc) - ngx_makefile=makefile.bcc - ngx_opt="-DCPU_OPT=\"$CPU_OPT\" -DMD5_ASM=$MD5_ASM" - ngx_md5=`echo \-DMD5=\"$MD5\" | sed -e "s/\//$ngx_regex_dirsep/g"` - ;; - -esac - - -done=NO - - -case "$NGX_PLATFORM" in - - win32) - cat << END >> $NGX_MAKEFILE - -`echo "$MD5/md5.lib: $NGX_MAKEFILE" | sed -e "s/\//$ngx_regex_dirsep/g"` - \$(MAKE) -f auto/lib/md5/$ngx_makefile $ngx_opt $ngx_md5 - -END - - done=YES - ;; - - SunOS:*:i86pc) - if [ $MD5_ASM = YES ]; then - - cat << END >> $NGX_MAKEFILE - -$MD5/libmd5.a: $NGX_MAKEFILE - cd $MD5 \\ - && \$(MAKE) CFLAGS="$MD5_OPT -DSOL -DMD5_ASM -DL_ENDIAN" \\ - CC="\$(CC)" CPP="\$(CPP)" \\ - MD5_ASM_OBJ=asm/mx86-sol.o clean libmd5.a - -END - - done=YES - fi - ;; - - # FreeBSD: i386 - # Linux: i686 - - *:i386 | *:i686) - if [ $MD5_ASM = YES ]; then - - cat << END >> $NGX_MAKEFILE - -$MD5/libmd5.a: $NGX_MAKEFILE - cd $MD5 \\ - && \$(MAKE) CFLAGS="$MD5_OPT -DELF -DMD5_ASM -DL_ENDIAN" \\ - CC="\$(CC)" CPP="\$(CPP)" \\ - MD5_ASM_OBJ=asm/mx86-elf.o clean libmd5.a - -END - - done=YES - fi - ;; - -esac - - -if [ $done = NO ]; then - - cat << END >> $NGX_MAKEFILE - -$MD5/libmd5.a: $NGX_MAKEFILE - cd $MD5 \\ - && \$(MAKE) CFLAGS="$MD5_OPT" \\ - CC="\$(CC)" MD5_ASM_OBJ= clean libmd5.a - -END - -fi diff --git a/auto/lib/md5/makefile.bcc b/auto/lib/md5/makefile.bcc deleted file mode 100644 --- a/auto/lib/md5/makefile.bcc +++ /dev/null @@ -1,22 +0,0 @@ - -# Copyright (C) Igor Sysoev -# Copyright (C) Nginx, Inc. - - -CFLAGS = -q -O2 -tWM $(CPU_OPT) -DL_ENDIAN - -!if "$(MD5_ASM)" == "YES" - -md5.lib: - cd $(MD5) - bcc32 -c $(CFLAGS) -DMD5_ASM md5_dgst.c - tlib md5.lib +md5_dgst.obj +"asm\m-win32.obj" - -!else - -md5.lib: - cd $(MD5) - bcc32 -c $(CFLAGS) md5_dgst.c - tlib md5.lib +md5_dgst.obj - -!endif diff --git a/auto/lib/md5/makefile.msvc b/auto/lib/md5/makefile.msvc deleted file mode 100644 --- a/auto/lib/md5/makefile.msvc +++ /dev/null @@ -1,22 +0,0 @@ - -# Copyright (C) Igor Sysoev -# Copyright (C) Nginx, Inc. - - -CFLAGS = -nologo -O2 -Ob1 -Oi -Gs $(LIBC) $(CPU_OPT) -D L_ENDIAN - -!IF "$(MD5_ASM)" == "YES" - -md5.lib: - cd $(MD5) - cl -c $(CFLAGS) -D MD5_ASM md5_dgst.c - link -lib -out:md5.lib md5_dgst.obj asm/m-win32.obj - -!ELSE - -md5.lib: - cd $(MD5) - cl -c $(CFLAGS) md5_dgst.c - link -lib -out:md5.lib md5_dgst.obj - -!ENDIF diff --git a/auto/lib/md5/makefile.owc b/auto/lib/md5/makefile.owc deleted file mode 100644 --- a/auto/lib/md5/makefile.owc +++ /dev/null @@ -1,11 +0,0 @@ - -# Copyright (C) Igor Sysoev -# Copyright (C) Nginx, Inc. - - -CFLAGS = -zq -bt=nt -bm -ot -op -oi -oe -s $(CPU_OPT) - -md5.lib: - cd $(MD5) - wcl386 -c $(CFLAGS) -dL_ENDIAN md5_dgst.c - wlib -n md5.lib md5_dgst.obj diff --git a/auto/lib/sha1/conf b/auto/lib/sha1/conf deleted file mode 100644 --- a/auto/lib/sha1/conf +++ /dev/null @@ -1,79 +0,0 @@ - -# Copyright (C) Igor Sysoev -# Copyright (C) Nginx, Inc. - - -if [ $SHA1 != NONE ]; then - - have=NGX_HAVE_SHA1 . auto/have - CORE_INCS="$CORE_INCS $SHA1" - - case "$NGX_CC_NAME" in - - msvc | owc | bcc) - LINK_DEPS="$LINK_DEPS $SHA1/sha1.lib" - CORE_LIBS="$CORE_LIBS $SHA1/sha1.lib" - ;; - - icc) - LINK_DEPS="$LINK_DEPS $SHA1/libsha.a" - - # to allow -ipo optimization we link with the *.o but not library - CORE_LIBS="$CORE_LIBS $SHA1/sha1_dgst.o" - - if [ $SHA1_ASM = YES ]; then - CORE_LIBS="$CORE_LIBS $SHA1/asm/sx86-elf.o" - fi - ;; - - *) - LINK_DEPS="$LINK_DEPS $SHA1/libsha.a" - CORE_LIBS="$CORE_LIBS $SHA1/libsha.a" - #CORE_LIBS="$CORE_LIBS -L $SHA1 -lsha" - ;; - - esac - -else - - if [ "$NGX_PLATFORM" != win32 ]; then - - SHA1=NO - - # FreeBSD - - ngx_feature="sha1 in system md library" - ngx_feature_name=NGX_HAVE_SHA1 - ngx_feature_run=no - ngx_feature_incs="#include " - ngx_feature_path= - ngx_feature_libs="-lmd" - ngx_feature_test="SHA_CTX sha1; SHA1_Init(&sha1)" - . auto/feature - - ngx_sha1_lib="system md" - - if [ $ngx_found = no ]; then - - # OpenSSL crypto library - - ngx_feature="sha1 in system OpenSSL crypto library" - ngx_feature_incs="#include " - ngx_feature_libs="-lcrypto" - . auto/feature - - ngx_sha1_lib="system crypto" - - if [ $ngx_found = yes ]; then - have=NGX_HAVE_OPENSSL_SHA1_H . auto/have - fi - fi - - if [ $ngx_found = yes ]; then - CORE_LIBS="$CORE_LIBS $ngx_feature_libs" - SHA1=YES - SHA1_LIB=$ngx_sha1_lib - fi - fi - -fi diff --git a/auto/lib/sha1/make b/auto/lib/sha1/make deleted file mode 100644 --- a/auto/lib/sha1/make +++ /dev/null @@ -1,96 +0,0 @@ - -# Copyright (C) Igor Sysoev -# Copyright (C) Nginx, Inc. - - -case "$NGX_CC_NAME" in - - msvc) - ngx_makefile=makefile.msvc - ngx_opt="CPU_OPT=\"$CPU_OPT\" LIBC=$LIBC SHA1_ASM=$SHA1_ASM" - ngx_sha1="SHA1=\"$SHA1\"" - ;; - - owc) - ngx_makefile=makefile.owc - ngx_opt="CPU_OPT=\"$CPU_OPT\"" - ngx_sha1=`echo SHA1=\"$SHA1\" | sed -e "s/\//$ngx_regex_dirsep/g"` - ;; - - bcc) - ngx_makefile=makefile.bcc - ngx_opt="-DCPU_OPT=\"$CPU_OPT\" -DSHA1_ASM=$SHA1_ASM" - ngx_sha1=`echo \-DSHA1=\"$SHA1\" | sed -e "s/\//$ngx_regex_dirsep/g"` - ;; - -esac - - -done=NO - - -case "$NGX_PLATFORM" in - - win32) - cat << END >> $NGX_MAKEFILE - -`echo "$SHA1/sha1.lib: $NGX_MAKEFILE" | sed -e "s/\//$ngx_regex_dirsep/g"` - \$(MAKE) -f auto/lib/sha1/$ngx_makefile $ngx_opt $ngx_sha1 - -END - - done=YES - ;; - - SunOS:*:i86pc) - if [ $SHA1_ASM = YES ]; then - - cat << END >> $NGX_MAKEFILE - -$SHA1/libsha.a: $NGX_MAKEFILE - cd $SHA1 \\ - && \$(MAKE) CFLAGS="$SHA1_OPT -DSOL -DSHA1_ASM -DL_ENDIAN" \\ - CC="\$(CC)" CPP="\$(CPP)" \\ - SHA_ASM_OBJ=asm/sx86-sol.o clean libsha.a - -END - - done=YES - fi - ;; - - # FreeBSD: i386 - # Linux: i686 - - *:i386 | *:i686) - if [ $SHA1_ASM = YES ]; then - - cat << END >> $NGX_MAKEFILE - -$SHA1/libsha.a: $NGX_MAKEFILE - cd $SHA1 \\ - && \$(MAKE) CFLAGS="$SHA1_OPT -DELF -DSHA1_ASM -DL_ENDIAN" \\ - CC="\$(CC)" CPP="\$(CPP)" \\ - SHA_ASM_OBJ=asm/sx86-elf.o clean libsha.a - -END - - done=YES - fi - ;; - -esac - - -if [ $done = NO ]; then - - cat << END >> $NGX_MAKEFILE - -$SHA1/libsha.a: $NGX_MAKEFILE - cd $SHA1 \\ - && \$(MAKE) CFLAGS="$SHA1_OPT" \\ - CC="\$(CC)" SHA_ASM_OBJ= clean libsha.a - -END - -fi diff --git a/auto/lib/sha1/makefile.bcc b/auto/lib/sha1/makefile.bcc deleted file mode 100644 --- a/auto/lib/sha1/makefile.bcc +++ /dev/null @@ -1,22 +0,0 @@ - -# Copyright (C) Igor Sysoev -# Copyright (C) Nginx, Inc. - - -CFLAGS = -q -O2 -tWM $(CPU_OPT) -DL_ENDIAN - -!if "$(SHA1_ASM)" == "YES" - -sha1.lib: - cd $(SHA1) - bcc32 -c $(CFLAGS) -DSHA1_ASM sha1dgst.c - tlib sha1.lib +sha1dgst.obj +"asm\s-win32.obj" - -!else - -sha1.lib: - cd $(SHA1) - bcc32 -c $(CFLAGS) sha1dgst.c - tlib sha1.lib +sha1dgst.obj - -!endif diff --git a/auto/lib/sha1/makefile.msvc b/auto/lib/sha1/makefile.msvc deleted file mode 100644 --- a/auto/lib/sha1/makefile.msvc +++ /dev/null @@ -1,22 +0,0 @@ - -# Copyright (C) Igor Sysoev -# Copyright (C) Nginx, Inc. - - -CFLAGS = -nologo -O2 -Ob1 -Oi -Gs $(LIBC) $(CPU_OPT) -D L_ENDIAN - -!IF "$(SHA1_ASM)" == "YES" - -sha1.lib: - cd $(SHA1) - cl -c $(CFLAGS) -D SHA1_ASM sha1dgst.c - link -lib -out:sha1.lib sha1dgst.obj asm/s-win32.obj - -!ELSE - -sha1.lib: - cd $(SHA1) - cl -c $(CFLAGS) sha1dgst.c - link -lib -out:sha1.lib sha1dgst.obj - -!ENDIF diff --git a/auto/lib/sha1/makefile.owc b/auto/lib/sha1/makefile.owc deleted file mode 100644 --- a/auto/lib/sha1/makefile.owc +++ /dev/null @@ -1,11 +0,0 @@ - -# Copyright (C) Igor Sysoev -# Copyright (C) Nginx, Inc. - - -CFLAGS = -zq -bt=nt -bm -ot -op -oi -oe -s $(CPU_OPT) - -sha1.lib: - cd $(SHA1) - wcl386 -c $(CFLAGS) -dL_ENDIAN sha1dgst.c - wlib -n sha1.lib sha1dgst.obj diff --git a/auto/module b/auto/module --- a/auto/module +++ b/auto/module @@ -48,10 +48,14 @@ if [ "$ngx_module_link" = DYNAMIC ]; the fi ;; - PCRE | OPENSSL | MD5 | SHA1 | ZLIB) + PCRE | OPENSSL | ZLIB) eval USE_${lib}=YES ;; + MD5 | SHA1) + # obsolete + ;; + *) libs="$libs $lib" ;; @@ -79,10 +83,14 @@ elif [ "$ngx_module_link" = YES ]; then do case $lib in - PCRE | OPENSSL | MD5 | SHA1 | ZLIB | LIBXSLT | LIBGD | PERL | GEOIP) + PCRE | OPENSSL | ZLIB | LIBXSLT | LIBGD | PERL | GEOIP) eval USE_${lib}=YES ;; + MD5 | SHA1) + # obsolete + ;; + *) CORE_LIBS="$CORE_LIBS $lib" ;; @@ -109,10 +117,14 @@ elif [ "$ngx_module_link" = ADDON ]; the do case $lib in - PCRE | OPENSSL | MD5 | SHA1 | ZLIB | LIBXSLT | LIBGD | PERL | GEOIP) + PCRE | OPENSSL | ZLIB | LIBXSLT | LIBGD | PERL | GEOIP) eval USE_${lib}=YES ;; + MD5 | SHA1) + # obsolete + ;; + *) CORE_LIBS="$CORE_LIBS $lib" ;; diff --git a/auto/modules b/auto/modules --- a/auto/modules +++ b/auto/modules @@ -101,7 +101,6 @@ fi if [ $HTTP_CACHE = YES ]; then - USE_MD5=YES have=NGX_HTTP_CACHE . auto/have HTTP_SRCS="$HTTP_SRCS $HTTP_FILE_CACHE_SRCS" fi @@ -522,8 +521,6 @@ if [ $HTTP_AUTH_REQUEST = YES ]; then fi if [ $HTTP_AUTH_BASIC = YES ]; then - USE_MD5=YES - USE_SHA1=YES have=NGX_CRYPT . auto/have ngx_module_name=ngx_http_auth_basic_module @@ -682,7 +679,6 @@ fi if [ $HTTP_PROXY = YES ]; then have=NGX_HTTP_X_FORWARDED_FOR . auto/have - #USE_MD5=YES ngx_module_name=ngx_http_proxy_module ngx_module_incs= @@ -772,8 +768,6 @@ if [ $HTTP_BROWSER = YES ]; then fi if [ $HTTP_SECURE_LINK = YES ]; then - USE_MD5=YES - ngx_module_name=ngx_http_secure_link_module ngx_module_incs= ngx_module_deps= diff --git a/auto/options b/auto/options --- a/auto/options +++ b/auto/options @@ -136,16 +136,6 @@ PCRE_JIT=NO USE_OPENSSL=NO OPENSSL=NONE -USE_MD5=NO -MD5=NONE -MD5_OPT= -MD5_ASM=NO - -USE_SHA1=NO -SHA1=NONE -SHA1_OPT= -SHA1_ASM=NO - USE_ZLIB=NO ZLIB=NONE ZLIB_OPT= @@ -333,13 +323,31 @@ use the \"--with-mail_ssl_module\" optio --with-openssl=*) OPENSSL="$value" ;; --with-openssl-opt=*) OPENSSL_OPT="$value" ;; - --with-md5=*) MD5="$value" ;; - --with-md5-opt=*) MD5_OPT="$value" ;; - --with-md5-asm) MD5_ASM=YES ;; + --with-md5=*) + NGX_POST_CONF_MSG="$NGX_POST_CONF_MSG +$0: warning: the \"--with-md5\" option is deprecated" + ;; + --with-md5-opt=*) + NGX_POST_CONF_MSG="$NGX_POST_CONF_MSG +$0: warning: the \"--with-md5-opt\" option is deprecated" + ;; + --with-md5-asm) + NGX_POST_CONF_MSG="$NGX_POST_CONF_MSG +$0: warning: the \"--with-md5-asm\" option is deprecated" + ;; - --with-sha1=*) SHA1="$value" ;; - --with-sha1-opt=*) SHA1_OPT="$value" ;; - --with-sha1-asm) SHA1_ASM=YES ;; + --with-sha1=*) + NGX_POST_CONF_MSG="$NGX_POST_CONF_MSG +$0: warning: the \"--with-sha1\" option is deprecated" + ;; + --with-sha1-opt=*) + NGX_POST_CONF_MSG="$NGX_POST_CONF_MSG +$0: warning: the \"--with-sha1-opt\" option is deprecated" + ;; + --with-sha1-asm) + NGX_POST_CONF_MSG="$NGX_POST_CONF_MSG +$0: warning: the \"--with-sha1-asm\" option is deprecated" + ;; --with-zlib=*) ZLIB="$value" ;; --with-zlib-opt=*) ZLIB_OPT="$value" ;; @@ -511,14 +519,6 @@ cat << END --with-pcre-opt=OPTIONS set additional build options for PCRE --with-pcre-jit build PCRE with JIT compilation support - --with-md5=DIR set path to md5 library sources - --with-md5-opt=OPTIONS set additional build options for md5 - --with-md5-asm use md5 assembler sources - - --with-sha1=DIR set path to sha1 library sources - --with-sha1-opt=OPTIONS set additional build options for sha1 - --with-sha1-asm use sha1 assembler sources - --with-zlib=DIR set path to zlib library sources --with-zlib-opt=OPTIONS set additional build options for zlib --with-zlib-asm=CPU use zlib assembler sources optimized diff --git a/auto/summary b/auto/summary --- a/auto/summary +++ b/auto/summary @@ -28,20 +28,6 @@ case $OPENSSL in *) echo " + using OpenSSL library: $OPENSSL" ;; esac -case $MD5 in - YES) echo " + md5: using $MD5_LIB library" ;; - NONE) echo " + md5 library is not used" ;; - NO) echo " + using builtin md5 code" ;; - *) echo " + using md5 library: $MD5" ;; -esac - -case $SHA1 in - YES) echo " + sha1: using $SHA1_LIB library" ;; - NONE) echo " + sha1 library is not used" ;; - NO) echo " + sha1 library is not found" ;; - *) echo " + using sha1 library: $SHA1" ;; -esac - case $ZLIB in YES) echo " + using system zlib library" ;; NONE) echo " + zlib library is not used" ;; diff --git a/src/core/ngx_md5.c b/src/core/ngx_md5.c --- a/src/core/ngx_md5.c +++ b/src/core/ngx_md5.c @@ -3,8 +3,6 @@ * An internal implementation, based on Alexander Peslyak's * public domain implementation: * http://openwall.info/wiki/people/solar/software/public-domain-source-code/md5 - * It is not expected to be optimal and is used only - * if no MD5 implementation was found in system. */ @@ -13,8 +11,6 @@ #include -#if !(NGX_HAVE_MD5) - static const u_char *ngx_md5_body(ngx_md5_t *ctx, const u_char *data, size_t size); @@ -285,5 +281,3 @@ ngx_md5_body(ngx_md5_t *ctx, const u_cha return p; } - -#endif diff --git a/src/core/ngx_md5.h b/src/core/ngx_md5.h --- a/src/core/ngx_md5.h +++ b/src/core/ngx_md5.h @@ -13,36 +13,6 @@ #include -#if (NGX_HAVE_MD5) - -#if (NGX_HAVE_OPENSSL_MD5_H) -#include -#else -#include -#endif - - -typedef MD5_CTX ngx_md5_t; - - -#if (NGX_OPENSSL_MD5) - -#define ngx_md5_init MD5_Init -#define ngx_md5_update MD5_Update -#define ngx_md5_final MD5_Final - -#else - -#define ngx_md5_init MD5Init -#define ngx_md5_update MD5Update -#define ngx_md5_final MD5Final - -#endif - - -#else /* !NGX_HAVE_MD5 */ - - typedef struct { uint64_t bytes; uint32_t a, b, c, d; @@ -55,6 +25,4 @@ void ngx_md5_update(ngx_md5_t *ctx, cons void ngx_md5_final(u_char result[16], ngx_md5_t *ctx); -#endif - #endif /* _NGX_MD5_H_INCLUDED_ */ diff --git a/src/core/ngx_module.h b/src/core/ngx_module.h --- a/src/core/ngx_module.h +++ b/src/core/ngx_module.h @@ -119,17 +119,8 @@ #define NGX_MODULE_SIGNATURE_16 "0" #endif -#if (NGX_HAVE_MD5) -#define NGX_MODULE_SIGNATURE_17 "1" -#else #define NGX_MODULE_SIGNATURE_17 "0" -#endif - -#if (NGX_HAVE_SHA1) -#define NGX_MODULE_SIGNATURE_18 "1" -#else #define NGX_MODULE_SIGNATURE_18 "0" -#endif #if (NGX_HAVE_OPENAT) #define NGX_MODULE_SIGNATURE_19 "1" diff --git a/src/core/ngx_sha1.c b/src/core/ngx_sha1.c --- a/src/core/ngx_sha1.c +++ b/src/core/ngx_sha1.c @@ -4,8 +4,6 @@ * Copyright (C) Nginx, Inc. * * An internal SHA1 implementation. - * It is not expected to be optimal and is used only - * if no SHA1 implementation was found in system. */ @@ -14,8 +12,6 @@ #include -#if !(NGX_HAVE_SHA1) - static const u_char *ngx_sha1_body(ngx_sha1_t *ctx, const u_char *data, size_t size); @@ -296,5 +292,3 @@ ngx_sha1_body(ngx_sha1_t *ctx, const u_c return p; } - -#endif diff --git a/src/core/ngx_sha1.h b/src/core/ngx_sha1.h --- a/src/core/ngx_sha1.h +++ b/src/core/ngx_sha1.h @@ -13,26 +13,6 @@ #include -#if (NGX_HAVE_SHA1) - -#if (NGX_HAVE_OPENSSL_SHA1_H) -#include -#else -#include -#endif - - -typedef SHA_CTX ngx_sha1_t; - - -#define ngx_sha1_init SHA1_Init -#define ngx_sha1_update SHA1_Update -#define ngx_sha1_final SHA1_Final - - -#else /* !NGX_HAVE_SHA1 */ - - typedef struct { uint64_t bytes; uint32_t a, b, c, d, e, f; @@ -45,6 +25,4 @@ void ngx_sha1_update(ngx_sha1_t *ctx, co void ngx_sha1_final(u_char result[20], ngx_sha1_t *ctx); From piotrsikora at google.com Thu Jun 30 19:44:29 2016 From: piotrsikora at google.com (Piotr Sikora) Date: Thu, 30 Jun 2016 12:44:29 -0700 Subject: [PATCH] Configure: don't test alternatives if preferred feature is found In-Reply-To: <20160630141644.GY30781@mdounin.ru> References: <20160628125434.GB31538@lo0.su> <9e0d65eda7fa016c0aeb.1467152911@piotrsikora.sfo.corp.google.com> <20160630141644.GY30781@mdounin.ru> Message-ID: Hey Maxim, > This looks like a mismerge, as previous tests is about > IP_BIND_ADDRESS_NO_PORT (it is probably misplaced though). Yeah, IP_BIND_ADDRESS_NO_PORT was added in the middle of NGX_HAVE_TRANSPARENT_PROXY checks after I already wrote those changes and I didn't catch the mis-merge. Good catch, thanks! Best regards, Piotr Sikora From piotrsikora at google.com Thu Jun 30 19:45:38 2016 From: piotrsikora at google.com (Piotr Sikora) Date: Thu, 30 Jun 2016 12:45:38 -0700 Subject: [PATCH] Configure: don't test alternatives if preferred feature is found In-Reply-To: <20160630141644.GY30781@mdounin.ru> References: <20160630141644.GY30781@mdounin.ru> Message-ID: <4dd0a17ea347f936d812.1467315938@piotrsikora.sfo.corp.google.com> # HG changeset patch # User Piotr Sikora # Date 1467064812 25200 # Mon Jun 27 15:00:12 2016 -0700 # Node ID 4dd0a17ea347f936d81236168bd33288e15fa782 # Parent d452cb27639f714bc43b7f3ede417e3e7f8efdd6 Configure: don't test alternatives if preferred feature is found. Signed-off-by: Piotr Sikora diff -r d452cb27639f -r 4dd0a17ea347 auto/cc/conf --- a/auto/cc/conf +++ b/auto/cc/conf @@ -197,6 +197,7 @@ if [ "$NGX_PLATFORM" != win32 ]; then if [ "$NGX_CC_NAME" = "ccc" ]; then echo "checking for C99 variadic macros ... disabled" + ngx_found=no else ngx_feature="C99 variadic macros" ngx_feature_name="NGX_HAVE_C99_VARIADIC_MACROS" @@ -209,20 +210,24 @@ if [ "$NGX_PLATFORM" != win32 ]; then var(0, buf, \"%d\", 1); if (buf[0] != '1') return 1" . auto/feature - fi + fi - ngx_feature="gcc variadic macros" - ngx_feature_name="NGX_HAVE_GCC_VARIADIC_MACROS" - ngx_feature_run=yes - ngx_feature_incs="#include + if [ $ngx_found = no ]; then + + ngx_feature="gcc variadic macros" + ngx_feature_name="NGX_HAVE_GCC_VARIADIC_MACROS" + ngx_feature_run=yes + ngx_feature_incs="#include #define var(dummy, args...) sprintf(args)" - ngx_feature_path= - ngx_feature_libs= - ngx_feature_test="char buf[30]; buf[0] = '0'; - var(0, buf, \"%d\", 1); - if (buf[0] != '1') return 1" - . auto/feature + ngx_feature_path= + ngx_feature_libs= + ngx_feature_test="char buf[30]; buf[0] = '0'; + var(0, buf, \"%d\", 1); + if (buf[0] != '1') return 1" + . auto/feature + + fi ngx_feature="gcc builtin 64 bit byteswap" diff -r d452cb27639f -r 4dd0a17ea347 auto/unix --- a/auto/unix +++ b/auto/unix @@ -184,14 +184,18 @@ ngx_feature_test="fcntl(0, F_READAHEAD, . auto/feature -ngx_feature="posix_fadvise()" -ngx_feature_name="NGX_HAVE_POSIX_FADVISE" -ngx_feature_run=no -ngx_feature_incs="#include " -ngx_feature_path= -ngx_feature_libs= -ngx_feature_test="posix_fadvise(0, 0, 0, POSIX_FADV_SEQUENTIAL);" -. auto/feature +if [ $ngx_found = no ]; then + + ngx_feature="posix_fadvise()" + ngx_feature_name="NGX_HAVE_POSIX_FADVISE" + ngx_feature_run=no + ngx_feature_incs="#include " + ngx_feature_path= + ngx_feature_libs= + ngx_feature_test="posix_fadvise(0, 0, 0, POSIX_FADV_SEQUENTIAL);" + . auto/feature + +fi ngx_feature="O_DIRECT" @@ -208,25 +212,34 @@ if [ $ngx_found = yes -a "$NGX_SYSTEM" = have=NGX_HAVE_ALIGNED_DIRECTIO . auto/have fi -ngx_feature="F_NOCACHE" -ngx_feature_name="NGX_HAVE_F_NOCACHE" -ngx_feature_run=no -ngx_feature_incs="#include " -ngx_feature_path= -ngx_feature_libs= -ngx_feature_test="fcntl(0, F_NOCACHE, 1);" -. auto/feature +if [ $ngx_found = no ]; then -ngx_feature="directio()" -ngx_feature_name="NGX_HAVE_DIRECTIO" -ngx_feature_run=no -ngx_feature_incs="#include - #include " -ngx_feature_path= -ngx_feature_libs= -ngx_feature_test="directio(0, DIRECTIO_ON);" -. auto/feature + ngx_feature="F_NOCACHE" + ngx_feature_name="NGX_HAVE_F_NOCACHE" + ngx_feature_run=no + ngx_feature_incs="#include " + ngx_feature_path= + ngx_feature_libs= + ngx_feature_test="fcntl(0, F_NOCACHE, 1);" + . auto/feature + +fi + + +if [ $ngx_found = no ]; then + + ngx_feature="directio()" + ngx_feature_name="NGX_HAVE_DIRECTIO" + ngx_feature_run=no + ngx_feature_incs="#include + #include " + ngx_feature_path= + ngx_feature_libs= + ngx_feature_test="directio(0, DIRECTIO_ON);" + . auto/feature + +fi ngx_feature="statfs()" @@ -242,16 +255,20 @@ ngx_feature_test="struct statfs fs; . auto/feature -ngx_feature="statvfs()" -ngx_feature_name="NGX_HAVE_STATVFS" -ngx_feature_run=no -ngx_feature_incs="#include - #include " -ngx_feature_path= -ngx_feature_libs= -ngx_feature_test="struct statvfs fs; - statvfs(\".\", &fs);" -. auto/feature +if [ $ngx_found = no ]; then + + ngx_feature="statvfs()" + ngx_feature_name="NGX_HAVE_STATVFS" + ngx_feature_run=no + ngx_feature_incs="#include + #include " + ngx_feature_path= + ngx_feature_libs= + ngx_feature_test="struct statvfs fs; + statvfs(\".\", &fs);" + . auto/feature + +fi ngx_feature="dlopen()" @@ -329,18 +346,6 @@ ngx_feature_test="setsockopt(0, SOL_SOCK . auto/feature -# NetBSD bind to any address for transparent proxying - -ngx_feature="SO_BINDANY" -ngx_feature_name="NGX_HAVE_TRANSPARENT_PROXY" -ngx_feature_run=no -ngx_feature_incs="#include " -ngx_feature_path= -ngx_feature_libs= -ngx_feature_test="setsockopt(0, SOL_SOCKET, SO_BINDANY, NULL, 0)" -. auto/feature - - # Linux IP_BIND_ADDRESS_NO_PORT ngx_feature="IP_BIND_ADDRESS_NO_PORT" @@ -354,30 +359,50 @@ ngx_feature_test="setsockopt(0, IPPROTO_ . auto/feature +# NetBSD bind to any address for transparent proxying + +ngx_feature="SO_BINDANY" +ngx_feature_name="NGX_HAVE_TRANSPARENT_PROXY" +ngx_feature_run=no +ngx_feature_incs="#include " +ngx_feature_path= +ngx_feature_libs= +ngx_feature_test="setsockopt(0, SOL_SOCKET, SO_BINDANY, NULL, 0)" +. auto/feature + + # Linux transparent proxying -ngx_feature="IP_TRANSPARENT" -ngx_feature_name="NGX_HAVE_TRANSPARENT_PROXY" -ngx_feature_run=no -ngx_feature_incs="#include - #include " -ngx_feature_path= -ngx_feature_libs= -ngx_feature_test="setsockopt(0, IPPROTO_IP, IP_TRANSPARENT, NULL, 0)" -. auto/feature +if [ $ngx_found = no ]; then + + ngx_feature="IP_TRANSPARENT" + ngx_feature_name="NGX_HAVE_TRANSPARENT_PROXY" + ngx_feature_run=no + ngx_feature_incs="#include + #include " + ngx_feature_path= + ngx_feature_libs= + ngx_feature_test="setsockopt(0, IPPROTO_IP, IP_TRANSPARENT, NULL, 0)" + . auto/feature + +fi # FreeBSD bind to any address for transparent proxying -ngx_feature="IP_BINDANY" -ngx_feature_name="NGX_HAVE_TRANSPARENT_PROXY" -ngx_feature_run=no -ngx_feature_incs="#include - #include " -ngx_feature_path= -ngx_feature_libs= -ngx_feature_test="setsockopt(0, IPPROTO_IP, IP_BINDANY, NULL, 0)" -. auto/feature +if [ $ngx_found = no ]; then + + ngx_feature="IP_BINDANY" + ngx_feature_name="NGX_HAVE_TRANSPARENT_PROXY" + ngx_feature_run=no + ngx_feature_incs="#include + #include " + ngx_feature_path= + ngx_feature_libs= + ngx_feature_test="setsockopt(0, IPPROTO_IP, IP_BINDANY, NULL, 0)" + . auto/feature + +fi # BSD way to get IPv4 datagram destination address @@ -395,15 +420,19 @@ ngx_feature_test="setsockopt(0, IPPROTO_ # Linux way to get IPv4 datagram destination address -ngx_feature="IP_PKTINFO" -ngx_feature_name="NGX_HAVE_IP_PKTINFO" -ngx_feature_run=no -ngx_feature_incs="#include - #include " -ngx_feature_path= -ngx_feature_libs= -ngx_feature_test="setsockopt(0, IPPROTO_IP, IP_PKTINFO, NULL, 0)" -. auto/feature +if [ $ngx_found = no ]; then + + ngx_feature="IP_PKTINFO" + ngx_feature_name="NGX_HAVE_IP_PKTINFO" + ngx_feature_run=no + ngx_feature_incs="#include + #include " + ngx_feature_path= + ngx_feature_libs= + ngx_feature_test="setsockopt(0, IPPROTO_IP, IP_PKTINFO, NULL, 0)" + . auto/feature + +fi # RFC 3542 way to get IPv6 datagram destination address @@ -772,16 +801,20 @@ ngx_feature_test="void *p; int n; n = po . auto/feature -ngx_feature="memalign()" -ngx_feature_name="NGX_HAVE_MEMALIGN" -ngx_feature_run=no -ngx_feature_incs="#include - #include " -ngx_feature_path= -ngx_feature_libs= -ngx_feature_test="void *p; p = memalign(4096, 4096); - if (p == NULL) return 1" -. auto/feature +if [ $ngx_found = no ]; then + + ngx_feature="memalign()" + ngx_feature_name="NGX_HAVE_MEMALIGN" + ngx_feature_run=no + ngx_feature_incs="#include + #include " + ngx_feature_path= + ngx_feature_libs= + ngx_feature_test="void *p; p = memalign(4096, 4096); + if (p == NULL) return 1" + . auto/feature + +fi ngx_feature="mmap(MAP_ANON|MAP_SHARED)" @@ -797,33 +830,42 @@ ngx_feature_test="void *p; . auto/feature -ngx_feature='mmap("/dev/zero", MAP_SHARED)' -ngx_feature_name="NGX_HAVE_MAP_DEVZERO" -ngx_feature_run=yes -ngx_feature_incs="#include - #include - #include " -ngx_feature_path= -ngx_feature_libs= -ngx_feature_test='void *p; int fd; - fd = open("/dev/zero", O_RDWR); - p = mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0); - if (p == MAP_FAILED) return 1;' -. auto/feature +if [ $ngx_found = no ]; then + ngx_feature='mmap("/dev/zero", MAP_SHARED)' + ngx_feature_name="NGX_HAVE_MAP_DEVZERO" + ngx_feature_run=yes + ngx_feature_incs="#include + #include + #include " + ngx_feature_path= + ngx_feature_libs= + ngx_feature_test='void *p; int fd; + fd = open("/dev/zero", O_RDWR); + p = mmap(NULL, 4096, PROT_READ|PROT_WRITE, + MAP_SHARED, fd, 0); + if (p == MAP_FAILED) return 1;' + . auto/feature -ngx_feature="System V shared memory" -ngx_feature_name="NGX_HAVE_SYSVSHM" -ngx_feature_run=yes -ngx_feature_incs="#include - #include " -ngx_feature_path= -ngx_feature_libs= -ngx_feature_test="int id; - id = shmget(IPC_PRIVATE, 4096, (SHM_R|SHM_W|IPC_CREAT)); - if (id == -1) return 1; - shmctl(id, IPC_RMID, NULL);" -. auto/feature +fi + + +if [ $ngx_found = no ]; then + + ngx_feature="System V shared memory" + ngx_feature_name="NGX_HAVE_SYSVSHM" + ngx_feature_run=yes + ngx_feature_incs="#include + #include " + ngx_feature_path= + ngx_feature_libs= + ngx_feature_test="int id; + id = shmget(IPC_PRIVATE, 4096, (SHM_R|SHM_W|IPC_CREAT)); + if (id == -1) return 1; + shmctl(id, IPC_RMID, NULL);" + . auto/feature + +fi ngx_feature="POSIX semaphores" diff -r d452cb27639f -r 4dd0a17ea347 src/os/unix/ngx_files.c --- a/src/os/unix/ngx_files.c +++ b/src/os/unix/ngx_files.c @@ -805,7 +805,7 @@ ngx_unlock_fd(ngx_fd_t fd) } -#if (NGX_HAVE_POSIX_FADVISE) && !(NGX_HAVE_F_READAHEAD) +#if (NGX_HAVE_POSIX_FADVISE) ngx_int_t ngx_read_ahead(ngx_fd_t fd, size_t n) From piotrsikora at google.com Thu Jun 30 19:52:11 2016 From: piotrsikora at google.com (Piotr Sikora) Date: Thu, 30 Jun 2016 12:52:11 -0700 Subject: [PATCH] Configure: don't test alternatives if preferred feature is found In-Reply-To: <20160630141644.GY30781@mdounin.ru> References: <20160630141644.GY30781@mdounin.ru> Message-ID: <33d0b463aa3484428a30.1467316331@piotrsikora.sfo.corp.google.com> # HG changeset patch # User Piotr Sikora # Date 1467064812 25200 # Mon Jun 27 15:00:12 2016 -0700 # Node ID 33d0b463aa3484428a30d838f6c58d8fe717746b # Parent d452cb27639f714bc43b7f3ede417e3e7f8efdd6 Configure: don't test alternatives if preferred feature is found. Signed-off-by: Piotr Sikora diff -r d452cb27639f -r 33d0b463aa34 auto/cc/conf --- a/auto/cc/conf +++ b/auto/cc/conf @@ -197,6 +197,7 @@ if [ "$NGX_PLATFORM" != win32 ]; then if [ "$NGX_CC_NAME" = "ccc" ]; then echo "checking for C99 variadic macros ... disabled" + ngx_found=no else ngx_feature="C99 variadic macros" ngx_feature_name="NGX_HAVE_C99_VARIADIC_MACROS" @@ -209,20 +210,24 @@ if [ "$NGX_PLATFORM" != win32 ]; then var(0, buf, \"%d\", 1); if (buf[0] != '1') return 1" . auto/feature - fi + fi - ngx_feature="gcc variadic macros" - ngx_feature_name="NGX_HAVE_GCC_VARIADIC_MACROS" - ngx_feature_run=yes - ngx_feature_incs="#include + if [ $ngx_found = no ]; then + + ngx_feature="gcc variadic macros" + ngx_feature_name="NGX_HAVE_GCC_VARIADIC_MACROS" + ngx_feature_run=yes + ngx_feature_incs="#include #define var(dummy, args...) sprintf(args)" - ngx_feature_path= - ngx_feature_libs= - ngx_feature_test="char buf[30]; buf[0] = '0'; - var(0, buf, \"%d\", 1); - if (buf[0] != '1') return 1" - . auto/feature + ngx_feature_path= + ngx_feature_libs= + ngx_feature_test="char buf[30]; buf[0] = '0'; + var(0, buf, \"%d\", 1); + if (buf[0] != '1') return 1" + . auto/feature + + fi ngx_feature="gcc builtin 64 bit byteswap" diff -r d452cb27639f -r 33d0b463aa34 auto/unix --- a/auto/unix +++ b/auto/unix @@ -184,14 +184,18 @@ ngx_feature_test="fcntl(0, F_READAHEAD, . auto/feature -ngx_feature="posix_fadvise()" -ngx_feature_name="NGX_HAVE_POSIX_FADVISE" -ngx_feature_run=no -ngx_feature_incs="#include " -ngx_feature_path= -ngx_feature_libs= -ngx_feature_test="posix_fadvise(0, 0, 0, POSIX_FADV_SEQUENTIAL);" -. auto/feature +if [ $ngx_found = no ]; then + + ngx_feature="posix_fadvise()" + ngx_feature_name="NGX_HAVE_POSIX_FADVISE" + ngx_feature_run=no + ngx_feature_incs="#include " + ngx_feature_path= + ngx_feature_libs= + ngx_feature_test="posix_fadvise(0, 0, 0, POSIX_FADV_SEQUENTIAL);" + . auto/feature + +fi ngx_feature="O_DIRECT" @@ -208,25 +212,34 @@ if [ $ngx_found = yes -a "$NGX_SYSTEM" = have=NGX_HAVE_ALIGNED_DIRECTIO . auto/have fi -ngx_feature="F_NOCACHE" -ngx_feature_name="NGX_HAVE_F_NOCACHE" -ngx_feature_run=no -ngx_feature_incs="#include " -ngx_feature_path= -ngx_feature_libs= -ngx_feature_test="fcntl(0, F_NOCACHE, 1);" -. auto/feature +if [ $ngx_found = no ]; then -ngx_feature="directio()" -ngx_feature_name="NGX_HAVE_DIRECTIO" -ngx_feature_run=no -ngx_feature_incs="#include - #include " -ngx_feature_path= -ngx_feature_libs= -ngx_feature_test="directio(0, DIRECTIO_ON);" -. auto/feature + ngx_feature="F_NOCACHE" + ngx_feature_name="NGX_HAVE_F_NOCACHE" + ngx_feature_run=no + ngx_feature_incs="#include " + ngx_feature_path= + ngx_feature_libs= + ngx_feature_test="fcntl(0, F_NOCACHE, 1);" + . auto/feature + +fi + + +if [ $ngx_found = no ]; then + + ngx_feature="directio()" + ngx_feature_name="NGX_HAVE_DIRECTIO" + ngx_feature_run=no + ngx_feature_incs="#include + #include " + ngx_feature_path= + ngx_feature_libs= + ngx_feature_test="directio(0, DIRECTIO_ON);" + . auto/feature + +fi ngx_feature="statfs()" @@ -242,16 +255,20 @@ ngx_feature_test="struct statfs fs; . auto/feature -ngx_feature="statvfs()" -ngx_feature_name="NGX_HAVE_STATVFS" -ngx_feature_run=no -ngx_feature_incs="#include - #include " -ngx_feature_path= -ngx_feature_libs= -ngx_feature_test="struct statvfs fs; - statvfs(\".\", &fs);" -. auto/feature +if [ $ngx_found = no ]; then + + ngx_feature="statvfs()" + ngx_feature_name="NGX_HAVE_STATVFS" + ngx_feature_run=no + ngx_feature_incs="#include + #include " + ngx_feature_path= + ngx_feature_libs= + ngx_feature_test="struct statvfs fs; + statvfs(\".\", &fs);" + . auto/feature + +fi ngx_feature="dlopen()" @@ -341,6 +358,40 @@ ngx_feature_test="setsockopt(0, SOL_SOCK . auto/feature +# Linux transparent proxying + +if [ $ngx_found = no ]; then + + ngx_feature="IP_TRANSPARENT" + ngx_feature_name="NGX_HAVE_TRANSPARENT_PROXY" + ngx_feature_run=no + ngx_feature_incs="#include + #include " + ngx_feature_path= + ngx_feature_libs= + ngx_feature_test="setsockopt(0, IPPROTO_IP, IP_TRANSPARENT, NULL, 0)" + . auto/feature + +fi + + +# FreeBSD bind to any address for transparent proxying + +if [ $ngx_found = no ]; then + + ngx_feature="IP_BINDANY" + ngx_feature_name="NGX_HAVE_TRANSPARENT_PROXY" + ngx_feature_run=no + ngx_feature_incs="#include + #include " + ngx_feature_path= + ngx_feature_libs= + ngx_feature_test="setsockopt(0, IPPROTO_IP, IP_BINDANY, NULL, 0)" + . auto/feature + +fi + + # Linux IP_BIND_ADDRESS_NO_PORT ngx_feature="IP_BIND_ADDRESS_NO_PORT" @@ -354,32 +405,6 @@ ngx_feature_test="setsockopt(0, IPPROTO_ . auto/feature -# Linux transparent proxying - -ngx_feature="IP_TRANSPARENT" -ngx_feature_name="NGX_HAVE_TRANSPARENT_PROXY" -ngx_feature_run=no -ngx_feature_incs="#include - #include " -ngx_feature_path= -ngx_feature_libs= -ngx_feature_test="setsockopt(0, IPPROTO_IP, IP_TRANSPARENT, NULL, 0)" -. auto/feature - - -# FreeBSD bind to any address for transparent proxying - -ngx_feature="IP_BINDANY" -ngx_feature_name="NGX_HAVE_TRANSPARENT_PROXY" -ngx_feature_run=no -ngx_feature_incs="#include - #include " -ngx_feature_path= -ngx_feature_libs= -ngx_feature_test="setsockopt(0, IPPROTO_IP, IP_BINDANY, NULL, 0)" -. auto/feature - - # BSD way to get IPv4 datagram destination address ngx_feature="IP_RECVDSTADDR" @@ -395,15 +420,19 @@ ngx_feature_test="setsockopt(0, IPPROTO_ # Linux way to get IPv4 datagram destination address -ngx_feature="IP_PKTINFO" -ngx_feature_name="NGX_HAVE_IP_PKTINFO" -ngx_feature_run=no -ngx_feature_incs="#include - #include " -ngx_feature_path= -ngx_feature_libs= -ngx_feature_test="setsockopt(0, IPPROTO_IP, IP_PKTINFO, NULL, 0)" -. auto/feature +if [ $ngx_found = no ]; then + + ngx_feature="IP_PKTINFO" + ngx_feature_name="NGX_HAVE_IP_PKTINFO" + ngx_feature_run=no + ngx_feature_incs="#include + #include " + ngx_feature_path= + ngx_feature_libs= + ngx_feature_test="setsockopt(0, IPPROTO_IP, IP_PKTINFO, NULL, 0)" + . auto/feature + +fi # RFC 3542 way to get IPv6 datagram destination address @@ -772,16 +801,20 @@ ngx_feature_test="void *p; int n; n = po . auto/feature -ngx_feature="memalign()" -ngx_feature_name="NGX_HAVE_MEMALIGN" -ngx_feature_run=no -ngx_feature_incs="#include - #include " -ngx_feature_path= -ngx_feature_libs= -ngx_feature_test="void *p; p = memalign(4096, 4096); - if (p == NULL) return 1" -. auto/feature +if [ $ngx_found = no ]; then + + ngx_feature="memalign()" + ngx_feature_name="NGX_HAVE_MEMALIGN" + ngx_feature_run=no + ngx_feature_incs="#include + #include " + ngx_feature_path= + ngx_feature_libs= + ngx_feature_test="void *p; p = memalign(4096, 4096); + if (p == NULL) return 1" + . auto/feature + +fi ngx_feature="mmap(MAP_ANON|MAP_SHARED)" @@ -797,33 +830,42 @@ ngx_feature_test="void *p; . auto/feature -ngx_feature='mmap("/dev/zero", MAP_SHARED)' -ngx_feature_name="NGX_HAVE_MAP_DEVZERO" -ngx_feature_run=yes -ngx_feature_incs="#include - #include - #include " -ngx_feature_path= -ngx_feature_libs= -ngx_feature_test='void *p; int fd; - fd = open("/dev/zero", O_RDWR); - p = mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0); - if (p == MAP_FAILED) return 1;' -. auto/feature +if [ $ngx_found = no ]; then + ngx_feature='mmap("/dev/zero", MAP_SHARED)' + ngx_feature_name="NGX_HAVE_MAP_DEVZERO" + ngx_feature_run=yes + ngx_feature_incs="#include + #include + #include " + ngx_feature_path= + ngx_feature_libs= + ngx_feature_test='void *p; int fd; + fd = open("/dev/zero", O_RDWR); + p = mmap(NULL, 4096, PROT_READ|PROT_WRITE, + MAP_SHARED, fd, 0); + if (p == MAP_FAILED) return 1;' + . auto/feature -ngx_feature="System V shared memory" -ngx_feature_name="NGX_HAVE_SYSVSHM" -ngx_feature_run=yes -ngx_feature_incs="#include - #include " -ngx_feature_path= -ngx_feature_libs= -ngx_feature_test="int id; - id = shmget(IPC_PRIVATE, 4096, (SHM_R|SHM_W|IPC_CREAT)); - if (id == -1) return 1; - shmctl(id, IPC_RMID, NULL);" -. auto/feature +fi + + +if [ $ngx_found = no ]; then + + ngx_feature="System V shared memory" + ngx_feature_name="NGX_HAVE_SYSVSHM" + ngx_feature_run=yes + ngx_feature_incs="#include + #include " + ngx_feature_path= + ngx_feature_libs= + ngx_feature_test="int id; + id = shmget(IPC_PRIVATE, 4096, (SHM_R|SHM_W|IPC_CREAT)); + if (id == -1) return 1; + shmctl(id, IPC_RMID, NULL);" + . auto/feature + +fi ngx_feature="POSIX semaphores" diff -r d452cb27639f -r 33d0b463aa34 src/os/unix/ngx_files.c --- a/src/os/unix/ngx_files.c +++ b/src/os/unix/ngx_files.c @@ -805,7 +805,7 @@ ngx_unlock_fd(ngx_fd_t fd) } -#if (NGX_HAVE_POSIX_FADVISE) && !(NGX_HAVE_F_READAHEAD) +#if (NGX_HAVE_POSIX_FADVISE) ngx_int_t ngx_read_ahead(ngx_fd_t fd, size_t n) From piotrsikora at google.com Thu Jun 30 19:56:07 2016 From: piotrsikora at google.com (Piotr Sikora) Date: Thu, 30 Jun 2016 12:56:07 -0700 Subject: [PATCH] Configure: don't test alternatives if preferred feature is found In-Reply-To: <33d0b463aa3484428a30.1467316331@piotrsikora.sfo.corp.google.com> References: <20160630141644.GY30781@mdounin.ru> <33d0b463aa3484428a30.1467316331@piotrsikora.sfo.corp.google.com> Message-ID: Hey Maxim, On Thu, Jun 30, 2016 at 12:52 PM, Piotr Sikora wrote: > # HG changeset patch > # User Piotr Sikora > # Date 1467064812 25200 > # Mon Jun 27 15:00:12 2016 -0700 > # Node ID 33d0b463aa3484428a30d838f6c58d8fe717746b > # Parent d452cb27639f714bc43b7f3ede417e3e7f8efdd6 > Configure: don't test alternatives if preferred feature is found. Updated diff that retains the SO -> IP -> TCP order. I just moved IP_BIND_ADDRESS_NO_PORT after all NGX_HAVE_TRANSPARENT_PROXY checks. Best regards, Piotr Sikora From piotrsikora at google.com Thu Jun 30 19:56:50 2016 From: piotrsikora at google.com (Piotr Sikora) Date: Thu, 30 Jun 2016 12:56:50 -0700 Subject: [PATCH 1 of 2] HTTP: add support for trailers in HTTP responses In-Reply-To: References: <20160627134500.GZ30781@mdounin.ru> <20160627175338.GD30781@mdounin.ru> Message-ID: Hey Maxim, > Would adding r->trailers_emit (or r->expect_trailers, whichever you > prefer) make you happy? Ping. Best regards, Piotr Sikora From nginx at pixelrebel.com Thu Jun 30 21:41:24 2016 From: nginx at pixelrebel.com (nginx at pixelrebel.com) Date: Thu, 30 Jun 2016 14:41:24 -0700 Subject: Stream: client SSL certificate support Message-ID: <57759204.M1VGzJCUiRwDYqLt%nginx@pixelrebel.com> Are there plans to support client certificate verification for streams? Any workarounds available? Is this patch going to be worked into future releases? https://forum.nginx.org/read.php?29,262636,262636