diff options
author | Konstantin Pavlov <thresh@nginx.com> | 2022-09-13 13:17:16 +0400 |
---|---|---|
committer | Konstantin Pavlov <thresh@nginx.com> | 2022-09-13 13:17:16 +0400 |
commit | ce964aa30b163e2b3263c5af57c1a6dae7d0cebb (patch) | |
tree | 26bf70c1a5991f6471fc4caed8628e068fdc0b7b | |
parent | eba4c3c98fa1bf275d94df8c727f70692ae7eae1 (diff) | |
parent | 38bd7e76a134084ab95a4ee3125af1ccd7b35864 (diff) | |
download | unit-1.28.0-1.tar.gz unit-1.28.0-1.tar.bz2 |
Merged with the default branch.1.28.0-1
141 files changed, 4117 insertions, 3172 deletions
@@ -1,4 +1,43 @@ +Changes with Unit 1.28.0 13 Sep 2022 + + *) Change: increased the applications' startup timeout. + + *) Change: disallowed abstract Unix domain socket syntax in non-Linux + systems. + + *) Feature: basic statistics API. + + *) Feature: customizable access log format. + + *) Feature: more HTTP variables support. + + *) Feature: forwarded header to replace client address and protocol. + + *) Feature: ability to get dynamic variables. + + *) Feature: support for abstract Unix sockets. + + *) Feature: support for Unix sockets in address matching. + + *) Feature: the $dollar variable translates to a literal "$" during + variable substitution. + + *) Bugfix: router process could crash if index file didn't contain an + extension. + + *) Bugfix: force SCRIPT_NAME in Ruby to always be an empty string. + + *) Bugfix: when isolated PID numbers reach the prototype process host + PID, the prototype crashed. + + *) Bugfix: the Ruby application process could crash on SIGTERM. + + *) Bugfix: the Ruby application process could crash on SIGINT. + + *) Bugfix: mutex leak in the C API. + + Changes with Unit 1.27.0 02 Jun 2022 *) Feature: ability to specify a custom index file name when serving @@ -2,7 +2,7 @@ ## Universal Web App Server -![NGINX Unit Logo](docs/unitlogo.png) +![NGINX Unit Logo](docs/unitlogo.svg) NGINX Unit is a lightweight and versatile open-source server that has three core capabilities: diff --git a/auto/isolation b/auto/isolation index fd35f8ed..384f7ef1 100644 --- a/auto/isolation +++ b/auto/isolation @@ -21,7 +21,7 @@ nxt_feature_test="#include <sys/wait.h> #include <sys/syscall.h> int main() { - return __NR_clone | SIGCHLD; + return SYS_clone | SIGCHLD; }" . auto/feature @@ -61,14 +61,30 @@ fi nxt_feature="Linux pivot_root()" -nxt_feature_name=NXT_HAVE_PIVOT_ROOT +nxt_feature_name=NXT_HAVE_LINUX_PIVOT_ROOT nxt_feature_run=no nxt_feature_incs= nxt_feature_libs= nxt_feature_test="#include <sys/syscall.h> + #if !defined(__linux__) + # error + #endif int main() { - return __NR_pivot_root; + return SYS_pivot_root; + }" +. auto/feature + + +nxt_feature="<mntent.h>" +nxt_feature_name=NXT_HAVE_MNTENT_H +nxt_feature_run=no +nxt_feature_incs= +nxt_feature_libs= +nxt_feature_test="#include <mntent.h> + + int main(void) { + return 0; }" . auto/feature diff --git a/auto/sockets b/auto/sockets index e6ef326d..e344a3db 100644 --- a/auto/sockets +++ b/auto/sockets @@ -225,12 +225,6 @@ nxt_feature_test="#include <sys/filio.h> }" . auto/feature -if [ $nxt_found = yes ]; then - NXT_SYS_FILIO_H="#include <sys/filio.h>" -else - NXT_SYS_FILIO_H= -fi - nxt_feature="ioctl(FIONBIO)" nxt_feature_name=NXT_HAVE_FIONBIO @@ -239,7 +233,6 @@ nxt_feature_incs= nxt_feature_libs= nxt_feature_test="#include <unistd.h> #include <sys/socket.h> - $NXT_SYS_FILIO_H #include <sys/ioctl.h> int main() { diff --git a/auto/sources b/auto/sources index 27a45edc..8548f812 100644 --- a/auto/sources +++ b/auto/sources @@ -69,7 +69,6 @@ NXT_LIB_SRCS=" \ src/nxt_event_conn_job_sendfile.c \ src/nxt_conn_proxy.c \ src/nxt_job.c \ - src/nxt_job_resolve.c \ src/nxt_sockaddr.c \ src/nxt_listen_socket.c \ src/nxt_upstream.c \ @@ -84,7 +83,9 @@ NXT_LIB_SRCS=" \ src/nxt_signal_handlers.c \ src/nxt_controller.c \ src/nxt_router.c \ + src/nxt_router_access_log.c \ src/nxt_h1proto.c \ + src/nxt_status.c \ src/nxt_http_request.c \ src/nxt_http_response.c \ src/nxt_http_error.c \ @@ -178,21 +178,6 @@ if [ $nxt_found = no ]; then fi -nxt_feature="posix_spawn()" -nxt_feature_name=NXT_HAVE_POSIX_SPAWN -nxt_feature_run= -nxt_feature_incs= -nxt_feature_libs= -nxt_feature_test="#include <spawn.h> - #include <unistd.h> - - int main(int argc, char *argv[]) { - (void) posix_spawn(NULL, \"\", NULL, NULL, argv, NULL); - return 0; - }" -. auto/feature - - # NetBSD 1.0, OpenBSD 1.0, FreeBSD 2.2 setproctitle(). nxt_feature="setproctitle()" @@ -48,11 +48,6 @@ NXT_GROUP= nxt_module=${1:-""} case $nxt_module in - --help) - . auto/help - exit 0 - ;; - ""|--*) ;; diff --git a/docs/changes.xml b/docs/changes.xml index 1d8a13c2..0674fb54 100644 --- a/docs/changes.xml +++ b/docs/changes.xml @@ -14,8 +14,134 @@ unit-ruby unit-jsc-common unit-jsc8 unit-jsc10 unit-jsc11 unit-jsc13 unit-jsc14 unit-jsc15 unit-jsc16 unit-jsc17 unit-jsc18" + ver="1.28.0" rev="1" + date="2022-09-13" time="18:00:00 +0300" + packager="Nginx Packaging <nginx-packaging@f5.com>"> + +<change> +<para> +NGINX Unit updated to 1.28.0. +</para> +</change> + +</changes> + + +<changes apply="unit" ver="1.28.0" rev="1" + date="2022-09-13" time="18:00:00 +0300" + packager="Nginx Packaging <nginx-packaging@f5.com>"> + +<change type="change"> +<para> +increased the applications' startup timeout. +</para> +</change> + +<change type="change"> +<para> +disallowed abstract Unix domain socket syntax in non-Linux systems. +</para> +</change> + +<change type="feature"> +<para> +basic statistics API. +</para> +</change> + +<change type="feature"> +<para> +customizable access log format. +</para> +</change> + +<change type="feature"> +<para> +more HTTP variables support. +</para> +</change> + +<change type="feature"> +<para> +forwarded header to replace client address and protocol. +</para> +</change> + +<change type="feature"> +<para> +ability to get dynamic variables. +</para> +</change> + +<change type="feature"> +<para> +support for abstract Unix sockets. +</para> +</change> + +<change type="feature"> +<para> +support for Unix sockets in address matching. +</para> +</change> + +<change type="feature"> +<para> +the $dollar variable translates to a literal "$" during variable substitution. +</para> +</change> + +<change type="bugfix"> +<para> +router process could crash if index file didn't contain an extension. +</para> +</change> + +<change type="bugfix"> +<para> +force SCRIPT_NAME in Ruby to always be an empty string. +</para> +</change> + +<change type="bugfix"> +<para> +when isolated PID numbers reach the prototype process host PID, +the prototype crashed. +</para> +</change> + +<change type="bugfix"> +<para> +the Ruby application process could crash on SIGTERM. +</para> +</change> + +<change type="bugfix"> +<para> +the Ruby application process could crash on SIGINT. +</para> +</change> + +<change type="bugfix"> +<para> +mutex leak in the C API. +</para> +</change> + +</changes> + + +<changes apply="unit-php + unit-python unit-python2.7 + unit-python3.4 unit-python3.5 unit-python3.6 unit-python3.7 + unit-python3.8 unit-python3.9 unit-python3.10 + unit-go + unit-perl + unit-ruby + unit-jsc-common unit-jsc8 unit-jsc10 unit-jsc11 unit-jsc13 + unit-jsc14 unit-jsc15 unit-jsc16 unit-jsc17 unit-jsc18" ver="1.27.0" rev="1" - date="" time="" + date="2022-06-02" time="18:00:00 +0300" packager="Andrei Belov <defan@nginx.com>"> <change> @@ -28,7 +154,7 @@ NGINX Unit updated to 1.27.0. <changes apply="unit" ver="1.27.0" rev="1" - date="" time="" + date="2022-06-02" time="18:00:00 +0300" packager="Andrei Belov <defan@nginx.com>"> <change type="feature"> diff --git a/docs/unitlogo.png b/docs/unitlogo.png Binary files differdeleted file mode 100644 index dbd87fd8..00000000 --- a/docs/unitlogo.png +++ /dev/null diff --git a/docs/unitlogo.svg b/docs/unitlogo.svg new file mode 100644 index 00000000..a8b87b18 --- /dev/null +++ b/docs/unitlogo.svg @@ -0,0 +1,305 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- Generator: Adobe Illustrator 26.5.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) --> +<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" + viewBox="0 0 1660 332" style="enable-background:new 0 0 1660 332;" xml:space="preserve"> +<style type="text/css"> + .st0{fill:#222222;} + .st1{fill:#999999;} + .st2{fill:#009639;} + .st3{fill:#FFFFFF;} + .st4{fill:none;stroke:#62C026;stroke-width:6.3479633;stroke-linejoin:round;stroke-miterlimit:10;} + .st5{fill:#267423;} + .st6{fill:#62C026;} + .st7{fill:#E6E6E6;} +</style> +<g id="Layer_1"> + <rect class="st0" width="1660" height="332"/> +</g> +<g id="Art"> + <g> + <g> + <path class="st1" d="M311.9880066,232.1229248h-9.3733826l-1.7800903,5.5219574h-4.396637l7.7028503-25.7251434h6.3584595 + l7.6655273,25.7251434h-4.4327698L311.9880066,232.1229248z M303.8868103,227.9802094h6.8302307L307.3013,216.607666 + L303.8868103,227.9802094z"/> + <path class="st1" d="M336.5467834,226.9271088v10.7177734h-4.3232117v-10.7551117 + c0-2.8331909-1.4900513-4.1775665-3.6696777-4.1775665c-1.9979248,0-3.7431335,1.1974945-3.8514404,3.6323395v11.3003387 + h-4.2871094v-18.4579773h2.7970581l0.7991943,1.5983276c1.3817139-1.4165802,3.3796387-2.1062012,5.5592957-2.1062012 + C333.8218994,218.6790314,336.5467834,221.1138611,336.5467834,226.9271088z"/> + <path class="st1" d="M364.9918518,211.9197388v25.7251434h-4.2149353l-10.1003418-17.4048615v17.4048615h-4.1775818v-25.7251434 + h4.1775818l10.1003418,17.5144043v-17.5144043H364.9918518z"/> + <path class="st1" d="M384.2813416,221.0765228v-1.1999969c0-2.6887665-2.0339966-4.3219604-5.5953979-4.3219604 + c-3.5962219,0-5.6315002,1.633194-5.6315002,4.3219604v9.811554c0,2.6887817,2.0352783,4.3219757,5.5953979,4.3219757 + c3.5975037,0,5.6315002-1.633194,5.6315002-4.3219757v-1.6356659h-5.7771301v-4.1427155h10.2460022v6.0323334 + c0,4.9767303-3.6696777,8.2107239-10.06427,8.2107239c-6.3945618,0-10.1003418-3.2339935-10.1003418-8.2107239v-10.3194427 + c0-4.9767303,3.6696777-8.2107391,10.0642395-8.2107391c6.4306946,0,10.1003723,3.2340088,10.1003723,8.2107391v1.4539337 + H384.2813416z"/> + <path class="st1" d="M392.8530884,211.9197388h4.4688416v25.7251434h-4.4688416V211.9197388z"/> + <path class="st1" d="M420.0657959,211.9197388v25.7251434h-4.2149048l-10.1016235-17.4048615v17.4048615h-4.1775513v-25.7251434 + h4.1775513l10.1016235,17.5144043v-17.5144043H420.0657959z"/> + <path class="st1" d="M436.3403931,224.8906097l7.8111572,12.7542725h-5.1958313l-5.3763123-8.8306427l-5.4870911,8.8306427 + h-4.9406433l7.8111572-13.0804138l-7.7389526-12.6447296h5.1958008l5.3775635,8.7559509l5.5219727-8.7559509h5.0140686 + L436.3403931,224.8906097z"/> + <path class="st1" d="M471.3978577,219.1147156v2.5792389c0,4.396637-3.1244507,7.1949615-8.1746521,7.1949615h-5.9949646 + v8.7559662h-4.4688721v-25.7251434h10.4265137C468.2360535,211.9197388,471.3978577,214.7180634,471.3978577,219.1147156z + M466.9290161,219.0051727c0-1.8896179-1.198761-2.9427185-3.4157715-2.9427185h-6.2850037v8.6837616h6.2489319 + c2.2157288,0,3.4518433-1.0531158,3.4518433-2.9427185V219.0051727z"/> + <path class="st1" d="M484.3649902,218.8956299v3.8165741c-0.5439758-0.1468964-1.1265259-0.253952-1.706604-0.253952 + c-2.2170105,0-4.178833,1.2696991-4.178833,4.0680237v11.1186066h-4.2871094v-18.4579773h2.9066162l0.8352661,1.6705322 + c1.453949-1.3443909,3.4879456-2.0340118,5.5232239-2.0340118 + C483.7836914,218.8234253,484.0749512,218.8607635,484.3649902,218.8956299z"/> + <path class="st1" d="M485.9994202,230.3055115v-3.7792358c0-4.8323212,2.9066467-7.8472443,8.1385498-7.8472443 + c5.2680359,0,8.1746521,3.0149231,8.1746521,7.8472443v3.7792358c0,4.8323364-2.9066162,7.8472443-8.1385498,7.8472443 + C488.9421692,238.1527557,485.9994202,235.1378479,485.9994202,230.3055115z M497.9894104,230.1586151v-3.4879303 + c0-2.6141052-1.1626587-3.9958344-3.8153381-3.9958344c-2.6514282,0-3.8501892,1.3817291-3.8501892,3.9958344v3.4879303 + c0,2.6165924,1.198761,3.9983215,3.8140869,3.9983215C496.7906494,234.1569366,497.9894104,232.7752075,497.9894104,230.1586151z + "/> + <path class="st1" d="M501.3653259,242.0041809h0.7991638c2.7983093,0,3.2340088-1.5634766,3.2340088-3.9236145v-18.8936615 + h4.3232117v20.0563049c0,5.0140686-2.9788208,6.7568054-6.3572388,6.7568054h-1.9991455V242.0041809z M505.3623962,212.2110291 + h4.3954163v4.6157227h-4.3954163V212.2110291z"/> + <path class="st1" d="M529.0498047,225.6549225v4.0680237h-11.6264648v0.5452118 + c0,2.9427185,1.3804932,4.2871094,3.8501587,4.2871094c1.8535156,0,3.4157715-0.9435577,3.4157715-2.5070343v-0.2887878 + h4.3231812c0,3.9958191-3.0883789,6.3933105-7.7389526,6.3933105c-5.2680054,0-8.1746216-3.1966553-8.1746216-8.0289917 + v-3.5252838c0-4.8323364,2.9066162-7.9194489,8.0663452-7.9194489 + C525.8880005,218.6790314,529.0498047,221.6217499,529.0498047,225.6549225z M524.6531372,226.4167328v-0.7269592 + c0-2.2879486-1.1265259-3.4132538-3.4157104-3.4132538c-2.5792847,0-3.7780151,1.4514313-3.8140869,4.140213H524.6531372z"/> + <path class="st1" d="M531.9539185,230.3055115v-3.7792358c0-4.8323212,2.9066162-7.8472443,8.0314941-7.8472443 + c4.7949829,0,7.84729,2.9427185,7.84729,7.5211029v0.4356842h-4.359314v-0.5452271 + c0-2.215744-1.3082886-3.415741-3.4879761-3.415741c-2.5082397,0-3.7070312,1.3817291-3.7070312,3.9958344v3.4879303 + c0,2.6165924,1.1987915,3.9983215,3.7070312,3.9983215c2.1435547,0,3.4879761-1.234848,3.4879761-3.415741v-0.5452271h4.359314 + v0.4356842c0,4.5783844-3.0523071,7.5211029-7.84729,7.5211029 + C534.8966675,238.1527557,531.9539185,235.1378479,531.9539185,230.3055115z"/> + <path class="st1" d="M562.0359497,233.6465607v3.9983215h-2.6153564c-4.3605957,0-6.5762939-2.2530975-6.5762939-6.94104 + v-7.5211029h-2.4709473v-3.9958344h2.4709473v-5.2680054h4.3231812v5.2680054h4.614502v3.9958344h-4.614502v6.687088 + c0,2.61409,1.0531006,3.7767334,3.1605835,3.7767334H562.0359497z"/> + </g> + <g> + <g> + <g> + <g> + <g> + <path class="st2" d="M121.0398254,200.2646637c0.716362,1.2425537,1.7262878,2.211853,2.8912964,2.8691254 + l59.147934,34.1488647l0.0018463-0.0018463c1.1539459,0.6794434,2.4962006,1.0690002,3.9307709,1.0690002 + s2.7786713-0.3895569,3.9307556-1.0690002l59.1497955-34.1488495 + c1.1650085-0.6572876,2.1712341-1.6247406,2.8894348-2.8672943c0.7182159-1.2425385,1.0523987-2.5995636,1.0394745-3.9381104 + v-68.2977295l-0.0018463-0.0018463c0.0110779-1.3367157-0.3231049-2.6955795-1.0394745-3.9381256 + c-0.7182007-1.2425537-1.7281189-2.2100067-2.8912811-2.869133L190.938736,87.0708618v-0.0018463 + c-1.1520844-0.6794434-2.494339-1.0690079-3.9289093-1.0690079c-1.432724,0-2.7749786,0.3895645-3.9270782,1.0690079 + v0.0018463l-59.147934,34.1488571c-1.1650085,0.6591263-2.1749344,1.6265793-2.8931427,2.869133 + c-0.716362,1.2425461-1.0505447,2.6014099-1.0394669,3.9381256l-0.0018463,0.0018463v68.2977295 + c-0.0129242,1.3385468,0.3212585,2.6955719,1.0376205,3.9381104"/> + </g> + </g> + </g> + <path class="st3" d="M168.0723724,188.1761322c0,4.2002869-3.4047394,7.6066895-7.6071014,7.6066895 + c-4.200531,0-7.6071014-3.4064026-7.6071014-7.6066895l0.0018463,0.0018463l0.0073853-52.2166138 + c0-4.0451965,3.5746002-7.3906708,8.6373901-7.3906708c3.6244507,0,7.8083496,1.462265,10.3692932,4.6360168 + l2.2987518,2.7509766l31.7799683,38.0297394v-37.813736h-0.0036774c0-4.2002869,3.4065704-7.6066895,7.6089478-7.6066895 + c4.200531,0,7.6052551,3.4064026,7.6052551,7.6066895h-0.0018463l-0.0073853,52.2129059 + c0,4.0452118-3.5764465,7.390686-8.6373901,7.390686c-3.626297,0-7.8083649-1.4604187-10.3692932-4.6360321 + l-34.0787354-40.7807159v37.8174438L168.0723724,188.1761322z"/> + </g> + <g> + <path class="st1" d="M427.3791809,185.5565643h0.9719543v-2.1648254h0.7688599 + c0.5082397,0,0.8728333,0.0495453,1.0799255,0.1803284c0.3398132,0.1991425,0.5132141,0.6261597,0.5132141,1.2592621v0.4438629 + l0.0217896,0.165451c0.0119019,0.0366669,0.0119019,0.0515289,0.0148621,0.0693665 + c0.0049438,0.0267487,0.0069275,0.034668,0.0217896,0.0465546h0.9006042l-0.0326843-0.0614319 + c-0.0267639-0.0416107-0.041626-0.1357269-0.0435791-0.2813721c-0.0128784-0.1555481-0.0128784-0.2883148-0.0128784-0.4111633 + v-0.4101868c0-0.2754211-0.1030579-0.5568085-0.3012085-0.8580017c-0.2041016-0.2902985-0.525116-0.462677-0.9590759-0.5389709 + c0.3428345-0.0574646,0.6123047-0.1486206,0.7995605-0.2595825c0.3675842-0.231842,0.5369873-0.6083374,0.5369873-1.0898438 + c0-0.6925507-0.2734375-1.1661224-0.8500671-1.3979645c-0.3180237-0.1307831-0.8164062-0.1971741-1.506958-0.1971741h-1.9230957 + V185.5565643z M430.1434326,182.5882263c-0.1951599,0.0842133-0.5053101,0.1228638-0.924408,0.1228638h-0.8678894v-2.0043182 + h0.8283081c0.5369873,0,0.9263611,0.0762787,1.1680908,0.2149963c0.2466736,0.1377106,0.3656006,0.4042358,0.3656006,0.8035126 + C430.7131348,182.1513062,430.5278625,182.4306946,430.1434326,182.5882263 M432.9661255,179.279068 + c-0.9887695-0.9759064-2.1717529-1.4593964-3.5697327-1.4593964c-1.3682556,0-2.5621033,0.48349-3.5281067,1.4593964 + c-0.9887695,0.9788818-1.4673157,2.1628418-1.4673157,3.552887c0,1.3880615,0.4735718,2.5769806,1.4494629,3.5509033 + c0.9689636,0.9887848,2.1648254,1.4792175,3.5459595,1.4792175c1.3979797,0,2.5809631-0.4904327,3.5697327-1.4792175 + c0.9689636-0.9788666,1.4692993-2.1727448,1.4692993-3.5509033 + C434.4354248,181.4320068,433.9350891,180.2579498,432.9661255,179.279068 M432.4559021,179.77742 + c0.8460999,0.8263092,1.2602234,1.8567047,1.2602234,3.0545349c0,1.1859589-0.4141235,2.2242737-1.2602234,3.069397 + c-0.833252,0.841156-1.85672,1.2731323-3.0595093,1.2731323c-1.1938782,0-2.2113647-0.4319763-3.055542-1.2731323 + c-0.8282776-0.8451233-1.254303-1.8834381-1.254303-3.069397c0-1.1978302,0.4260254-2.2282257,1.254303-3.0545349 + c0.8560486-0.8599701,1.8695984-1.2820435,3.055542-1.2820435 + C430.5942078,178.4953766,431.6127319,178.91745,432.4559021,179.77742"/> + <g> + <path class="st3" d="M296.4403381,172.4392395v-36.1351318h8.9604187v35.6251984 + c0,5.3908844,3.5699158,8.6692505,10.7825317,8.6692505s10.7825317-3.2783661,10.7825317-8.6692505v-35.6251984h8.9604492 + v36.1351318c0,10.0534668-7.2126465,16.4645996-19.6701965,16.4645996 + C303.7257385,188.9038391,296.4403381,182.4927063,296.4403381,172.4392395z"/> + <path class="st3" d="M375.7033691,166.3924561v21.4915314l-8.6700134-0.0000153v-21.5643158 + c0-5.6824341-2.9868164-8.378067-7.3582153-8.378067c-4.0066528,0-7.5037842,2.404068-7.722168,7.2850342v22.6573486 + h-8.5964661v-37.0090485h5.6096497l1.6029663,3.2052002c2.7684326-2.8412323,6.775116-4.2254333,11.1465149-4.2254333 + C370.2393188,149.8546906,375.7033691,154.7360229,375.7033691,166.3924561z"/> + <path class="st3" d="M383.7144775,136.887207h8.8876343v9.2519836h-8.8876343V136.887207z M383.8600464,150.8749237h8.669281 + v37.0090485h-8.669281V150.8749237z"/> + <path class="st3" d="M420.5768127,179.8702393v8.0137329h-5.2456665c-8.7420654,0-13.1862488-4.516983-13.1862488-13.9149323 + v-15.0803833h-4.9537659v-8.0137329h4.9537659v-10.5637665h8.6692505v10.5637665h9.2523499v8.0137329h-9.2523499v13.4049988 + c0,5.2453003,2.1132812,7.5765839,6.3383484,7.5765839H420.5768127z"/> + </g> + </g> + </g> + </g> +</g> +<g id="artwork"> + <g> + <g> + <ellipse class="st3" cx="1438.1523438" cy="40.3328018" rx="4.3671799" ry="4.6571636"/> + </g> + <g> + <path class="st4" d="M1449.3671875,185.17453c0,0,42.8554688,17.7458191,55.9665527-38.7562561"/> + <g> + <path class="st2" d="M1515.2062988,150.6308441c-0.2004395,0.6022034-0.7965088,1.0005188-1.4407959,0.8917542 + l-18.2456055-3.0800781c-0.6442871-0.1087646-1.0772705-0.6807861-1.0688477-1.3153992l-0.0385742-0.0065002 + c0,0,0.0134277-0.078949,0.0321045-0.1901245c0.0522461-0.3088837-0.0175781,0.1047668,0.1364746-0.8079987 + c0.4699707-2.7843781,1.265625-7.4972229,1.4852295-8.7984619c0.8564453-5.0735321,4.4857178-8.9770355,9.0693359-10.4446106 + l-1.2091064,7.1621399c-1.1503906,1.0960236-1.9852295,2.5393066-2.2700195,4.2261658 + c-0.041748,0.2472992-0.8549805,5.2803802-0.8549805,5.2803802l9.5836182,1.6178284 + c0,0,0.8430176-4.7857513,0.9511719-5.4262543c0.25-1.4815674,0.0388184-2.928299-0.5042725-4.2173157l1.258667-7.4558563 + c3.6591797,2.9155731,5.6691895,7.6758728,4.8352051,12.6167603c-0.2275391,1.3476562-1.0369873,6.1426239-1.5119629,8.9560699 + c-0.1540527,0.9130707-0.0842285,0.4994202-0.1363525,0.8079834c-0.0187988,0.111496-0.0321045,0.1901398-0.0321045,0.1901398 + L1515.2062988,150.6308441z"/> + </g> + </g> + <g> + <path class="st4" d="M1454.5784912,196.9434509c0,0,3.9665527,46.2144318,60.1638184,31.8529053"/> + <g> + <path class="st2" d="M1515.5456543,239.5000458c-0.6268311,0.0991974-1.2548828-0.2467041-1.4547119-0.8687744 + l-5.6619873-17.616272c-0.1999512-0.6220703,0.1086426-1.2696533,0.6759033-1.5542603l-0.0119629-0.0372009 + c0,0,0.0762939-0.0245056,0.1835938-0.0590057c0.2982178-0.0958405-0.1010742,0.0325165,0.7801514-0.2507324 + c2.6883545-0.8640442,7.2386475-2.3265228,8.4949951-2.7303162c4.8984375-1.5744019,10.0341797-0.1486511,13.4465332,3.2453918 + l-6.9150391,2.2225342c-1.5025635-0.516983-3.1680908-0.5939789-4.7967529-0.0705261 + c-0.2387695,0.0767517-5.081543,1.6708984-5.081543,1.6708984l2.973999,9.2530365c0,0,4.6368408-1.453949,5.255249-1.65271 + c1.4304199-0.4597626,2.6176758-1.3130341,3.512085-2.3884583l7.1987305-2.3136749 + c-0.904541,4.5904236-4.2058105,8.5656891-8.9763184,10.0989227c-1.3011475,0.4181976-5.9306641,1.9061737-8.6470947,2.7792206 + c-0.8815918,0.2833405-0.4821777,0.1549835-0.7801514,0.2507324c-0.107666,0.0346069-0.1835938,0.0590057-0.1835938,0.0590057 + L1515.5456543,239.5000458z"/> + </g> + </g> + <g> + <path class="st4" d="M1315.6970215,243.2423553c0,0-21.9627686-40.8551483,32.9356689-59.5780487"/> + <g> + <path class="st2" d="M1306.9082031,248.4536285c-0.2102051-0.5988464,0.017334-1.278717,0.5932617-1.5871277 + l16.3127441-8.7341766c0.5760498-0.3084259,1.2685547-0.1211395,1.6503906,0.385788l0.0345459-0.0184479 + c0,0,0.0377197,0.0706024,0.0909424,0.1699982c0.1478271,0.2761536-0.0501709-0.0936737,0.3868408,0.7223969 + c1.3328857,2.4893951,3.5888672,6.7029724,4.211792,7.8663483c2.4287109,4.5360565,1.9486084,9.8443756-0.7773438,13.8108063 + l-3.4284668-6.4033813c0.2387695-1.5709229,0.0152588-3.2232208-0.7922363-4.7313843 + c-0.1184082-0.2210999-2.5563965-4.6987-2.5563965-4.6987l-8.5683594,4.5876617c0,0,2.2631836,4.3002167,2.5697021,4.872879 + c0.7092285,1.3246155,1.7619629,2.3392639,2.9805908,3.0260315l3.5690918,6.6659851 + c-4.6782227-0.0653381-9.1818848-2.5988159-11.5471191-7.0162964c-0.6450195-1.2048645-2.9404297-5.4918671-4.2872314-8.0072479 + c-0.4370117-0.8163452-0.2390137-0.4465179-0.3867188-0.7223969c-0.0534668-0.0996704-0.0910645-0.1699829-0.0910645-0.1699829 + L1306.9082031,248.4536285z"/> + </g> + </g> + <g> + <g> + <ellipse class="st5" cx="1464.5943604" cy="188.810318" rx="7.7738867" ry="9.5948353"/> + </g> + </g> + <g> + <g> + <ellipse class="st5" cx="1462.7558594" cy="218.225769" rx="7.7738867" ry="9.5948353"/> + </g> + </g> + <g> + <g> + <ellipse class="st5" cx="1339.057251" cy="188.810318" rx="7.7738867" ry="9.5948353"/> + </g> + </g> + <path class="st6" d="M1456.8769531,228.1189728c0-24.7052765-24.6368408-44.7328644-55.027832-44.7328644 + c-30.3911133,0-55.0279541,20.0275879-55.0279541,44.7328644s24.6368408,44.7328339,55.0279541,44.7328339 + c0.0229492,0,0.0457764-0.0006714,0.0687256-0.0007019c0.0229492,0.0000305,0.0457764,0.0007019,0.0687256,0.0007019 + c0,0-0.0037842-0.0012512-0.0040283-0.0013428C1432.3120117,272.7917786,1456.8769531,252.7880096,1456.8769531,228.1189728z"/> + <g> + <path class="st5" d="M1401.848999,257.1278992c30.8840332,0,56.3187256-7.3460541,59.763916-20.650116 + c0.1726074-0.4505463,0.2983398-0.9141541,0.3278809-1.3972931l5.4649658-86.9454346 + c0.197998-3.2748413-4.7550049-8.4608002-9.0810547-8.6103821l-48.4742432,2.5349731 + c-4.3260498-0.1495819-11.4047852-0.1500549-15.730835-0.0010834l-48.7462158-2.5328064 + c-4.3260498,0.1490479-9.2781982,5.3344574-9.0810547,8.6092987l5.4658203,86.9454346 + c0.0286865,0.4833679,0.1552734,0.9471436,0.3277588,1.3978424"/> + </g> + <g> + <path class="st2" d="M1401.848877,141.9467468c-2.8059082,0.000946-5.6011963,0.0380554-7.7299805,0.1113739 + l-48.7453613-2.5328827c-4.3260498,0.1490021-9.2788086,5.334549-9.0811768,8.609436l5.4648438,86.9454651 + c0.0291748,0.4832611,0.1561279,0.9470215,0.3283691,1.3975525 + c3.4455566,13.3038635,28.8806152,20.6496277,59.7635498,20.6496277"/> + </g> + <g> + <path class="st6" d="M1461.5471191,118.1488495c-3.6014404-24.8404541-28.9459229-44.0927124-59.6981201-44.0927124 + c-30.7520752,0-56.0966797,19.2522583-59.697998,44.0927124l-0.4554443,22.3807983 + c0,0,22.9992676,10.3432465,60.1534424,10.3432465c37.1542969,0,60.1535645-10.3432465,60.1535645-10.3432465 + L1461.5471191,118.1488495z"/> + </g> + <g> + <g> + <path class="st3" d="M1365.4659424,124.1972198c0.1817627,0.3151855,0.4379883,0.561058,0.7335205,0.7277908l15.00354,8.6623001 + l0.0003662-0.000473c0.2927246,0.172348,0.6333008,0.2711639,0.9971924,0.2711639s0.704834-0.0988159,0.9970703-0.2711639 + l15.0040283-8.6623001c0.2954102-0.1667252,0.5506592-0.4121323,0.7329102-0.7273178 + c0.1821289-0.3151932,0.2669678-0.6594162,0.2636719-0.9989624v-17.3245926l-0.0004883-0.000473 + c0.0028076-0.3390732-0.0819092-0.6837616-0.2636719-0.9989548c-0.1821289-0.3151855-0.4383545-0.5605927-0.7333984-0.7277908 + l-15.0040283-8.6623001v-0.0004654c-0.2922363-0.172348-0.6326904-0.2711639-0.996582-0.2711639 + c-0.3634033,0-0.7039795,0.0988159-0.9962158,0.2711639v0.0004654l-15.00354,8.6623001 + c-0.2955322,0.1671982-0.5516357,0.4126053-0.7338867,0.7277908c-0.1816406,0.3151932-0.2664795,0.6598816-0.2636719,0.9989548 + l-0.0004883,0.000473v17.3245926c-0.0031738,0.3395462,0.081543,0.6837692,0.2633057,0.9989624"/> + </g> + </g> + <circle cx="1382.2003174" cy="114.5352554" r="7.8991222"/> + <circle class="st3" cx="1384.4804688" cy="112.5474625" r="2.2802224"/> + <g> + <g> + <path class="st3" d="M1405.2994385,124.1972198c0.1816406,0.3151855,0.4378662,0.561058,0.7333984,0.7277908l15.00354,8.6623001 + l0.0004883-0.000473c0.2927246,0.172348,0.6331787,0.2711639,0.9970703,0.2711639s0.704834-0.0988159,0.9970703-0.2711639 + l15.0040283-8.6623001c0.2955322-0.1667252,0.5507812-0.4121323,0.7329102-0.7273178 + c0.182251-0.3151932,0.2669678-0.6594162,0.2636719-0.9989624v-17.3245926l-0.0004883-0.000473 + c0.0028076-0.3390732-0.0819092-0.6837616-0.2636719-0.9989548c-0.1821289-0.3151855-0.4383545-0.5605927-0.7333984-0.7277908 + l-15.0040283-8.6623001v-0.0004654c-0.2922363-0.172348-0.6326904-0.2711639-0.996582-0.2711639 + c-0.3634033,0-0.7038574,0.0988159-0.9960938,0.2711639v0.0004654l-15.00354,8.6623001 + c-0.2955322,0.1671982-0.5517578,0.4126053-0.7338867,0.7277908c-0.1817627,0.3151932-0.2664795,0.6598816-0.2636719,0.9989548 + l-0.0004883,0.000473v17.3245926c-0.0032959,0.3395462,0.0814209,0.6837692,0.2631836,0.9989624"/> + </g> + </g> + <circle cx="1422.0336914" cy="114.5352554" r="7.8991222"/> + <circle class="st3" cx="1423.0882568" cy="112.5474625" r="2.2802224"/> + <g> + <g> + <path class="st2" d="M1391.7996826,123.6621552C1391.7996826,123.6621552,1391.7996826,123.90728,1391.7996826,123.6621552 + L1391.7996826,123.6621552z M1378.9281006,123.6621552L1378.9281006,123.6621552L1378.9281006,123.6621552z + M1391.3400879,122.4365921L1391.3400879,122.4365921L1391.3400879,122.4365921z"/> + </g> + <g> + <path class="st2" d="M1420.9908447,134.6922913L1420.9908447,134.6922913L1420.9908447,134.6922913z M1427.1968994,123.6621552 + C1427.1968994,123.6621552,1427.1968994,123.90728,1427.1968994,123.6621552L1427.1968994,123.6621552z + M1414.3251953,123.6621552L1414.3251953,123.6621552L1414.3251953,123.6621552z M1426.5073242,122.4365921 + L1426.5073242,122.4365921L1426.5073242,122.4365921z M1420.9908447,119.7403412L1420.9908447,119.7403412 + L1420.9908447,119.7403412z"/> + </g> + <g> + <path class="st7" d="M1330.199585,137.1434174c0,35.296402,32.4090576,63.9747467,72.1733398,63.9747467 + s72.1733398-28.6783142,72.1733398-63.9747314c0,0-10.5732422,50.0032501-72.1733398,51.4739227 + c0,0-51.2568359,2.6962585-70.7943115-46.3265381L1330.199585,137.1434174z"/> + </g> + <g> + <path class="st3" d="M1402.1430664,190.0880432c-40.9135742,0-74.4719238-29.1685638-74.4719238-64.9551926 + s33.3284912-64.9552002,74.4719238-64.9552002s74.2419434,29.16856,74.2419434,64.9552002 + C1476.6148682,160.9194794,1443.286499,190.0880432,1402.1430664,190.0880432z M1402.1430664,62.6287918 + c-39.7642822,0-72.1733398,27.9429855-72.1733398,62.5040588s32.4090576,62.5040512,72.1733398,62.5040512 + s71.9434814-27.9429932,71.9434814-62.5040512S1441.9073486,62.6287918,1402.1430664,62.6287918z"/> + </g> + <g> + <rect x="1437.0030518" y="39.955864" class="st3" width="2.2985139" height="29.4136715"/> + </g> + </g> + <path d="M1421.5812988,147.3400879c2.2796631,0,3.9838867,2.0716553,3.5738525,4.3141785 + c-2.0300293,11.1029358-11.7537842,19.5184631-23.4431152,19.5184631s-21.4130859-8.4155273-23.4431152-19.5184631 + c-0.4100342-2.2425232,1.2941895-4.3141785,3.5738525-4.3141785H1421.5812988z"/> + <g> + <path class="st6" d="M1391.913208,233.8167572c0.0942383,0.1883545,0.2825928,0.2825317,0.4709473,0.4708862l8.8527832,5.0856323 + l0,0c0.376709,0.1883545,0.8475342,0.1883545,1.2242432,0l8.8527832-5.0856323 + c0.1883545-0.0941772,0.2825928-0.2825317,0.4709473-0.4708862c0.0941162-0.1883545,0.1883545-0.3767242,0.1883545-0.5650787 + v-10.2654419l0,0c0-0.1883545-0.0942383-0.376709-0.1883545-0.5650635 + c-0.0942383-0.1883545-0.2825928-0.282547-0.4709473-0.4709015l-8.8527832-5.0856323l0,0 + c-0.376709-0.1883545-0.8475342-0.1883545-1.2242432,0l0,0l-8.8527832,5.0856323 + c-0.1883545,0.0941772-0.376709,0.282547-0.4709473,0.4709015c-0.0941162,0.1883545-0.1883545,0.376709-0.1883545,0.5650635l0,0 + v10.2654419C1391.7248535,233.440033,1391.8190918,233.6283875,1391.913208,233.8167572"/> + </g> + </g> +</g> +</svg> diff --git a/pkg/deb/Makefile b/pkg/deb/Makefile index 52813e37..c4f085f8 100644 --- a/pkg/deb/Makefile +++ b/pkg/deb/Makefile @@ -49,21 +49,6 @@ include Makefile.jsc17 include Makefile.jsc18 endif -# Ubuntu 21.04 -ifeq ($(CODENAME),hirsute) -include Makefile.php -include Makefile.python27 -include Makefile.python39 -include Makefile.go -include Makefile.perl -include Makefile.ruby -include Makefile.jsc-common -include Makefile.jsc11 -include Makefile.jsc15 -include Makefile.jsc16 -include Makefile.jsc17 -endif - # Ubuntu 20.04 ifeq ($(CODENAME),focal) include Makefile.php diff --git a/pkg/deb/Makefile.jsc13 b/pkg/deb/Makefile.jsc13 deleted file mode 100644 index d22944dc..00000000 --- a/pkg/deb/Makefile.jsc13 +++ /dev/null @@ -1,71 +0,0 @@ -MODULES+= jsc13 -MODULE_SUFFIX_jsc13= jsc13 - -MODULE_SUMMARY_jsc13= Java 13 module for NGINX Unit - -MODULE_VERSION_jsc13= $(VERSION) -MODULE_RELEASE_jsc13= 1 - -MODULE_CONFARGS_jsc13= java --module=java13 --home=/usr/lib/jvm/java-13-openjdk-$$\(DEB_HOST_ARCH\) --jars=/usr/share/unit-jsc-common/ -MODULE_MAKEARGS_jsc13= java13 -MODULE_INSTARGS_jsc13= java13-install - -MODULE_SOURCES_jsc13= unit.example-jsc-app \ - unit.example-jsc13-config - -BUILD_DEPENDS_jsc13= openjdk-13-jdk-headless openjdk-13-jre-headless -BUILD_DEPENDS+= $(BUILD_DEPENDS_jsc13) - -MODULE_BUILD_DEPENDS_jsc13=,openjdk-13-jdk-headless -MODULE_DEPENDS_jsc13=,openjdk-13-jre-headless,unit-jsc-common (= $(MODULE_VERSION_jsc_common)-$(MODULE_RELEASE_jsc_common)~$(CODENAME)) - -define MODULE_PREINSTALL_jsc13 - mkdir -p debian/unit-jsc13/usr/share/doc/unit-jsc13/examples/jsc-app - install -m 644 -p debian/unit.example-jsc-app debian/unit-jsc13/usr/share/doc/unit-jsc13/examples/jsc-app/index.jsp - install -m 644 -p debian/unit.example-jsc13-config debian/unit-jsc13/usr/share/doc/unit-jsc13/examples/unit.config - install -m 644 -p src/java/README.JSR-340 debian/unit-jsc13/usr/share/doc/unit-jsc13/ -endef -export MODULE_PREINSTALL_jsc13 - -define MODULE_POSTINSTALL_jsc13 - cd $$\(BUILDDIR_unit\) \&\& \ - DESTDIR=$$\(INSTALLDIR\) make java-shared-uninstall -endef -export MODULE_POSTINSTALL_jsc13 - -define MODULE_POST_jsc13 -cat <<BANNER ----------------------------------------------------------------------- - -The $(MODULE_SUMMARY_jsc13) has been installed. - -To check out the sample app, run these commands: - - sudo service unit restart - cd /usr/share/doc/unit-$(MODULE_SUFFIX_jsc13)/examples - sudo curl -X PUT --data-binary @unit.config --unix-socket /var/run/control.unit.sock http://localhost/config - curl http://localhost:8800/ - -Online documentation is available at https://unit.nginx.org - -NOTICE: - -This version of Unit code is made available in support of the open source -development process. This is an intermediate build made available for -testing purposes only. This Unit code is untested and presumed incompatible -with the JSR 340 Java Servlet 3.1 specification. You should not deploy or -write to this code. You should instead deploy and write production -applications on pre-built binaries that have been tested and certified -to meet the JSR-340 compatibility requirements such as certified binaries -published for the JSR-340 reference implementation available at -https://javaee.github.io/glassfish/. - -Redistribution of any Intermediate Build must retain this notice. - -Oracle and Java are registered trademarks of Oracle and/or its affiliates. -Other names may be trademarks of their respective owners. - ----------------------------------------------------------------------- -BANNER -endef -export MODULE_POST_jsc13 diff --git a/pkg/deb/Makefile.jsc14 b/pkg/deb/Makefile.jsc14 deleted file mode 100644 index 9b53a385..00000000 --- a/pkg/deb/Makefile.jsc14 +++ /dev/null @@ -1,71 +0,0 @@ -MODULES+= jsc14 -MODULE_SUFFIX_jsc14= jsc14 - -MODULE_SUMMARY_jsc14= Java 14 module for NGINX Unit - -MODULE_VERSION_jsc14= $(VERSION) -MODULE_RELEASE_jsc14= 1 - -MODULE_CONFARGS_jsc14= java --module=java14 --home=/usr/lib/jvm/java-14-openjdk-$$\(DEB_HOST_ARCH\) --jars=/usr/share/unit-jsc-common/ -MODULE_MAKEARGS_jsc14= java14 -MODULE_INSTARGS_jsc14= java14-install - -MODULE_SOURCES_jsc14= unit.example-jsc-app \ - unit.example-jsc14-config - -BUILD_DEPENDS_jsc14= openjdk-14-jdk-headless openjdk-14-jre-headless -BUILD_DEPENDS+= $(BUILD_DEPENDS_jsc14) - -MODULE_BUILD_DEPENDS_jsc14=,openjdk-14-jdk-headless -MODULE_DEPENDS_jsc14=,openjdk-14-jre-headless,unit-jsc-common (= $(MODULE_VERSION_jsc_common)-$(MODULE_RELEASE_jsc_common)~$(CODENAME)) - -define MODULE_PREINSTALL_jsc14 - mkdir -p debian/unit-jsc14/usr/share/doc/unit-jsc14/examples/jsc-app - install -m 644 -p debian/unit.example-jsc-app debian/unit-jsc14/usr/share/doc/unit-jsc14/examples/jsc-app/index.jsp - install -m 644 -p debian/unit.example-jsc14-config debian/unit-jsc14/usr/share/doc/unit-jsc14/examples/unit.config - install -m 644 -p src/java/README.JSR-340 debian/unit-jsc14/usr/share/doc/unit-jsc14/ -endef -export MODULE_PREINSTALL_jsc14 - -define MODULE_POSTINSTALL_jsc14 - cd $$\(BUILDDIR_unit\) \&\& \ - DESTDIR=$$\(INSTALLDIR\) make java-shared-uninstall -endef -export MODULE_POSTINSTALL_jsc14 - -define MODULE_POST_jsc14 -cat <<BANNER ----------------------------------------------------------------------- - -The $(MODULE_SUMMARY_jsc14) has been installed. - -To check out the sample app, run these commands: - - sudo service unit restart - cd /usr/share/doc/unit-$(MODULE_SUFFIX_jsc14)/examples - sudo curl -X PUT --data-binary @unit.config --unix-socket /var/run/control.unit.sock http://localhost/config - curl http://localhost:8800/ - -Online documentation is available at https://unit.nginx.org - -NOTICE: - -This version of Unit code is made available in support of the open source -development process. This is an intermediate build made available for -testing purposes only. This Unit code is untested and presumed incompatible -with the JSR 340 Java Servlet 3.1 specification. You should not deploy or -write to this code. You should instead deploy and write production -applications on pre-built binaries that have been tested and certified -to meet the JSR-340 compatibility requirements such as certified binaries -published for the JSR-340 reference implementation available at -https://javaee.github.io/glassfish/. - -Redistribution of any Intermediate Build must retain this notice. - -Oracle and Java are registered trademarks of Oracle and/or its affiliates. -Other names may be trademarks of their respective owners. - ----------------------------------------------------------------------- -BANNER -endef -export MODULE_POST_jsc14 diff --git a/pkg/deb/Makefile.jsc15 b/pkg/deb/Makefile.jsc15 deleted file mode 100644 index 10b5505b..00000000 --- a/pkg/deb/Makefile.jsc15 +++ /dev/null @@ -1,71 +0,0 @@ -MODULES+= jsc15 -MODULE_SUFFIX_jsc15= jsc15 - -MODULE_SUMMARY_jsc15= Java 15 module for NGINX Unit - -MODULE_VERSION_jsc15= $(VERSION) -MODULE_RELEASE_jsc15= 1 - -MODULE_CONFARGS_jsc15= java --module=java15 --home=/usr/lib/jvm/java-15-openjdk-$$\(DEB_HOST_ARCH\) --jars=/usr/share/unit-jsc-common/ -MODULE_MAKEARGS_jsc15= java15 -MODULE_INSTARGS_jsc15= java15-install - -MODULE_SOURCES_jsc15= unit.example-jsc-app \ - unit.example-jsc15-config - -BUILD_DEPENDS_jsc15= openjdk-15-jdk-headless openjdk-15-jre-headless -BUILD_DEPENDS+= $(BUILD_DEPENDS_jsc15) - -MODULE_BUILD_DEPENDS_jsc15=,openjdk-15-jdk-headless -MODULE_DEPENDS_jsc15=,openjdk-15-jre-headless,unit-jsc-common (= $(MODULE_VERSION_jsc_common)-$(MODULE_RELEASE_jsc_common)~$(CODENAME)) - -define MODULE_PREINSTALL_jsc15 - mkdir -p debian/unit-jsc15/usr/share/doc/unit-jsc15/examples/jsc-app - install -m 644 -p debian/unit.example-jsc-app debian/unit-jsc15/usr/share/doc/unit-jsc15/examples/jsc-app/index.jsp - install -m 644 -p debian/unit.example-jsc15-config debian/unit-jsc15/usr/share/doc/unit-jsc15/examples/unit.config - install -m 644 -p src/java/README.JSR-340 debian/unit-jsc15/usr/share/doc/unit-jsc15/ -endef -export MODULE_PREINSTALL_jsc15 - -define MODULE_POSTINSTALL_jsc15 - cd $$\(BUILDDIR_unit\) \&\& \ - DESTDIR=$$\(INSTALLDIR\) make java-shared-uninstall -endef -export MODULE_POSTINSTALL_jsc15 - -define MODULE_POST_jsc15 -cat <<BANNER ----------------------------------------------------------------------- - -The $(MODULE_SUMMARY_jsc15) has been installed. - -To check out the sample app, run these commands: - - sudo service unit restart - cd /usr/share/doc/unit-$(MODULE_SUFFIX_jsc15)/examples - sudo curl -X PUT --data-binary @unit.config --unix-socket /var/run/control.unit.sock http://localhost/config - curl http://localhost:8800/ - -Online documentation is available at https://unit.nginx.org - -NOTICE: - -This version of Unit code is made available in support of the open source -development process. This is an intermediate build made available for -testing purposes only. This Unit code is untested and presumed incompatible -with the JSR 340 Java Servlet 3.1 specification. You should not deploy or -write to this code. You should instead deploy and write production -applications on pre-built binaries that have been tested and certified -to meet the JSR-340 compatibility requirements such as certified binaries -published for the JSR-340 reference implementation available at -https://javaee.github.io/glassfish/. - -Redistribution of any Intermediate Build must retain this notice. - -Oracle and Java are registered trademarks of Oracle and/or its affiliates. -Other names may be trademarks of their respective owners. - ----------------------------------------------------------------------- -BANNER -endef -export MODULE_POST_jsc15 diff --git a/pkg/deb/Makefile.python b/pkg/deb/Makefile.python deleted file mode 100644 index 9bf02bac..00000000 --- a/pkg/deb/Makefile.python +++ /dev/null @@ -1,46 +0,0 @@ -MODULES+= python -MODULE_SUFFIX_python= python - -MODULE_SUMMARY_python= Python module for NGINX Unit - -MODULE_VERSION_python= $(VERSION) -MODULE_RELEASE_python= 1 - -MODULE_CONFARGS_python= python -MODULE_MAKEARGS_python= python -MODULE_INSTARGS_python= python-install - -MODULE_SOURCES_python= unit.example-python-app \ - unit.example-python-config - -BUILD_DEPENDS_python= python-dev -BUILD_DEPENDS+= $(BUILD_DEPENDS_python) - -MODULE_BUILD_DEPENDS_python=,python-dev - -define MODULE_PREINSTALL_python - mkdir -p debian/unit-python/usr/share/doc/unit-python/examples/python-app - install -m 644 -p debian/unit.example-python-app debian/unit-python/usr/share/doc/unit-python/examples/python-app/wsgi.py - install -m 644 -p debian/unit.example-python-config debian/unit-python/usr/share/doc/unit-python/examples/unit.config -endef -export MODULE_PREINSTALL_python - -define MODULE_POST_python -cat <<BANNER ----------------------------------------------------------------------- - -The $(MODULE_SUMMARY_python) has been installed. - -To check out the sample app, run these commands: - - sudo service unit restart - cd /usr/share/doc/unit-$(MODULE_SUFFIX_python)/examples - sudo curl -X PUT --data-binary @unit.config --unix-socket /var/run/control.unit.sock http://localhost/config - curl http://localhost:8400/ - -Online documentation is available at https://unit.nginx.org - ----------------------------------------------------------------------- -BANNER -endef -export MODULE_POST_python diff --git a/pkg/deb/Makefile.python34 b/pkg/deb/Makefile.python34 deleted file mode 100644 index 03c496bd..00000000 --- a/pkg/deb/Makefile.python34 +++ /dev/null @@ -1,46 +0,0 @@ -MODULES+= python34 -MODULE_SUFFIX_python34= python3.4 - -MODULE_SUMMARY_python34= Python 3.4 module for NGINX Unit - -MODULE_VERSION_python34= $(VERSION) -MODULE_RELEASE_python34= 1 - -MODULE_CONFARGS_python34= python --config=python3.4-config -MODULE_MAKEARGS_python34= python3.4 -MODULE_INSTARGS_python34= python3.4-install - -MODULE_SOURCES_python34= unit.example-python-app \ - unit.example-python3.4-config - -BUILD_DEPENDS_python34= python3.4-dev -BUILD_DEPENDS+= $(BUILD_DEPENDS_python34) - -MODULE_BUILD_DEPENDS_python34=,python3.4-dev - -define MODULE_PREINSTALL_python34 - mkdir -p debian/unit-python3.4/usr/share/doc/unit-python3.4/examples/python-app - install -m 644 -p debian/unit.example-python-app debian/unit-python3.4/usr/share/doc/unit-python3.4/examples/python-app/wsgi.py - install -m 644 -p debian/unit.example-python3.4-config debian/unit-python3.4/usr/share/doc/unit-python3.4/examples/unit.config -endef -export MODULE_PREINSTALL_python34 - -define MODULE_POST_python34 -cat <<BANNER ----------------------------------------------------------------------- - -The $(MODULE_SUMMARY_python34) has been installed. - -To check out the sample app, run these commands: - - sudo service unit restart - cd /usr/share/doc/unit-$(MODULE_SUFFIX_python34)/examples - sudo curl -X PUT --data-binary @unit.config --unix-socket /var/run/control.unit.sock http://localhost/config - curl http://localhost:8400/ - -Online documentation is available at https://unit.nginx.org - ----------------------------------------------------------------------- -BANNER -endef -export MODULE_POST_python34 diff --git a/pkg/deb/Makefile.python35 b/pkg/deb/Makefile.python35 deleted file mode 100644 index 514a4bf6..00000000 --- a/pkg/deb/Makefile.python35 +++ /dev/null @@ -1,46 +0,0 @@ -MODULES+= python35 -MODULE_SUFFIX_python35= python3.5 - -MODULE_SUMMARY_python35= Python 3.5 module for NGINX Unit - -MODULE_VERSION_python35= $(VERSION) -MODULE_RELEASE_python35= 1 - -MODULE_CONFARGS_python35= python --config=python3.5-config -MODULE_MAKEARGS_python35= python3.5 -MODULE_INSTARGS_python35= python3.5-install - -MODULE_SOURCES_python35= unit.example-python-app \ - unit.example-python3.5-config - -BUILD_DEPENDS_python35= python3.5-dev -BUILD_DEPENDS+= $(BUILD_DEPENDS_python35) - -MODULE_BUILD_DEPENDS_python35=,python3.5-dev - -define MODULE_PREINSTALL_python35 - mkdir -p debian/unit-python3.5/usr/share/doc/unit-python3.5/examples/python-app - install -m 644 -p debian/unit.example-python-app debian/unit-python3.5/usr/share/doc/unit-python3.5/examples/python-app/wsgi.py - install -m 644 -p debian/unit.example-python3.5-config debian/unit-python3.5/usr/share/doc/unit-python3.5/examples/unit.config -endef -export MODULE_PREINSTALL_python35 - -define MODULE_POST_python35 -cat <<BANNER ----------------------------------------------------------------------- - -The $(MODULE_SUMMARY_python35) has been installed. - -To check out the sample app, run these commands: - - sudo service unit restart - cd /usr/share/doc/unit-$(MODULE_SUFFIX_python35)/examples - sudo curl -X PUT --data-binary @unit.config --unix-socket /var/run/control.unit.sock http://localhost/config - curl http://localhost:8400/ - -Online documentation is available at https://unit.nginx.org - ----------------------------------------------------------------------- -BANNER -endef -export MODULE_POST_python35 diff --git a/pkg/deb/debian.module/copyright.unit-jsc10 b/pkg/deb/debian.module/copyright.unit-jsc10 deleted file mode 100644 index 42dbd3b9..00000000 --- a/pkg/deb/debian.module/copyright.unit-jsc10 +++ /dev/null @@ -1,33 +0,0 @@ - - NGINX Unit. - - Copyright 2017-2022 NGINX, Inc. - Copyright 2017-2022 Valentin V. Bartenev - Copyright 2017-2022 Max Romanov - Copyright 2017-2022 Andrei Zeliankou - Copyright 2018-2022 Konstantin Pavlov - Copyright 2021-2022 Zhidao Hong - Copyright 2021-2022 OisÃn Canty - Copyright 2017-2021 Igor Sysoev - Copyright 2017-2021 Andrei Belov - Copyright 2019-2021 Tiago Natel de Moura - Copyright 2019-2020 Axel Duch - Copyright 2018-2019 Alexander Borisov - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - /usr/share/common-licenses/Apache-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. - - The unit-jsc10 package provides Java servlet container module - for NGINX Unit. - - Java is a registered trademark of Oracle and/or its affiliates. diff --git a/pkg/deb/debian.module/unit.example-jsc10-config b/pkg/deb/debian.module/unit.example-jsc10-config deleted file mode 100644 index 969491e5..00000000 --- a/pkg/deb/debian.module/unit.example-jsc10-config +++ /dev/null @@ -1,15 +0,0 @@ -{ - "applications": { - "example_java10": { - "processes": 1, - "type": "java 10", - "webapp": "/usr/share/doc/unit-jsc10/examples/jsc-app" - } - }, - - "listeners": { - "*:8800": { - "pass": "applications/example_java10" - } - } -} diff --git a/pkg/deb/debian.module/unit.example-jsc13-config b/pkg/deb/debian.module/unit.example-jsc13-config deleted file mode 100644 index ac0b1db6..00000000 --- a/pkg/deb/debian.module/unit.example-jsc13-config +++ /dev/null @@ -1,15 +0,0 @@ -{ - "applications": { - "example_java13": { - "processes": 1, - "type": "java 13", - "webapp": "/usr/share/doc/unit-jsc13/examples/jsc-app" - } - }, - - "listeners": { - "*:8800": { - "pass": "applications/example_java13" - } - } -} diff --git a/pkg/deb/debian.module/unit.example-jsc14-config b/pkg/deb/debian.module/unit.example-jsc14-config deleted file mode 100644 index 76109835..00000000 --- a/pkg/deb/debian.module/unit.example-jsc14-config +++ /dev/null @@ -1,15 +0,0 @@ -{ - "applications": { - "example_java14": { - "processes": 1, - "type": "java 14", - "webapp": "/usr/share/doc/unit-jsc14/examples/jsc-app" - } - }, - - "listeners": { - "*:8800": { - "pass": "applications/example_java14" - } - } -} diff --git a/pkg/deb/debian.module/unit.example-jsc15-config b/pkg/deb/debian.module/unit.example-jsc15-config deleted file mode 100644 index 9f9aec15..00000000 --- a/pkg/deb/debian.module/unit.example-jsc15-config +++ /dev/null @@ -1,15 +0,0 @@ -{ - "applications": { - "example_java15": { - "processes": 1, - "type": "java 15", - "webapp": "/usr/share/doc/unit-jsc15/examples/jsc-app" - } - }, - - "listeners": { - "*:8800": { - "pass": "applications/example_java15" - } - } -} diff --git a/pkg/deb/debian.module/unit.example-jsc9-config b/pkg/deb/debian.module/unit.example-jsc9-config deleted file mode 100644 index a8faa268..00000000 --- a/pkg/deb/debian.module/unit.example-jsc9-config +++ /dev/null @@ -1,15 +0,0 @@ -{ - "applications": { - "example_java9": { - "processes": 1, - "type": "java 9", - "webapp": "/usr/share/doc/unit-jsc9/examples/jsc-app" - } - }, - - "listeners": { - "*:8800": { - "pass": "applications/example_java9" - } - } -} diff --git a/pkg/deb/debian.module/unit.example-python-config b/pkg/deb/debian.module/unit.example-python-config deleted file mode 100644 index b3d3a2e5..00000000 --- a/pkg/deb/debian.module/unit.example-python-config +++ /dev/null @@ -1,16 +0,0 @@ -{ - "applications": { - "example_python": { - "type": "python", - "processes": 2, - "path": "/usr/share/doc/unit-python/examples/python-app", - "module": "wsgi" - } - }, - - "listeners": { - "*:8400": { - "pass": "applications/example_python" - } - } -} diff --git a/pkg/deb/debian.module/unit.example-python3.4-config b/pkg/deb/debian.module/unit.example-python3.4-config deleted file mode 100644 index e6d90acf..00000000 --- a/pkg/deb/debian.module/unit.example-python3.4-config +++ /dev/null @@ -1,16 +0,0 @@ -{ - "applications": { - "example_python": { - "type": "python 3.4", - "processes": 2, - "path": "/usr/share/doc/unit-python3.4/examples/python-app", - "module": "wsgi" - } - }, - - "listeners": { - "*:8400": { - "pass": "applications/example_python" - } - } -} diff --git a/pkg/deb/debian.module/unit.example-python3.5-config b/pkg/deb/debian.module/unit.example-python3.5-config deleted file mode 100644 index 480327ec..00000000 --- a/pkg/deb/debian.module/unit.example-python3.5-config +++ /dev/null @@ -1,16 +0,0 @@ -{ - "applications": { - "example_python": { - "type": "python 3.5", - "processes": 2, - "path": "/usr/share/doc/unit-python3.5/examples/python-app", - "module": "wsgi" - } - }, - - "listeners": { - "*:8400": { - "pass": "applications/example_python" - } - } -} diff --git a/pkg/deb/debian/dirs b/pkg/deb/debian/dirs index fdcb4340..4a6618c8 100644 --- a/pkg/deb/debian/dirs +++ b/pkg/deb/debian/dirs @@ -1,4 +1,3 @@ usr/sbin -etc/unit usr/lib/unit var/lib/unit diff --git a/pkg/docker/Dockerfile.go1.18 b/pkg/docker/Dockerfile.go1.19 index 9162d8cf..1625b64f 100644 --- a/pkg/docker/Dockerfile.go1.18 +++ b/pkg/docker/Dockerfile.go1.19 @@ -1,4 +1,4 @@ -FROM golang:1.18 as BUILDER +FROM golang:1.19 as BUILDER LABEL maintainer="NGINX Docker Maintainers <docker-maint@nginx.com>" @@ -8,7 +8,7 @@ RUN set -ex \ && mkdir -p /usr/lib/unit/modules /usr/lib/unit/debug-modules \ && hg clone https://hg.nginx.org/unit \ && cd unit \ - && hg up 1.27.0 \ + && hg up 1.28.0 \ && NCPU="$(getconf _NPROCESSORS_ONLN)" \ && DEB_HOST_MULTIARCH="$(dpkg-architecture -q DEB_HOST_MULTIARCH)" \ && CC_OPT="$(DEB_BUILD_MAINT_OPTIONS="hardening=+all,-pie" DEB_CFLAGS_MAINT_APPEND="-Wp,-D_FORTIFY_SOURCE=2 -fPIC" dpkg-buildflags --get CFLAGS)" \ @@ -40,7 +40,7 @@ RUN set -ex \ && make -j $NCPU go-install-src libunit-install \ && ldd /usr/sbin/unitd | awk '/=>/{print $(NF-1)}' | while read n; do dpkg-query -S $n; done | sed 's/^\([^:]\+\):.*$/\1/' | sort | uniq > /requirements.apt -FROM golang:1.18 +FROM golang:1.19 COPY docker-entrypoint.sh /usr/local/bin/ COPY --from=BUILDER /usr/sbin/unitd /usr/sbin/unitd COPY --from=BUILDER /usr/sbin/unitd-debug /usr/sbin/unitd-debug diff --git a/pkg/docker/Dockerfile.jsc11 b/pkg/docker/Dockerfile.jsc11 index 69fc72ad..fe344d0e 100644 --- a/pkg/docker/Dockerfile.jsc11 +++ b/pkg/docker/Dockerfile.jsc11 @@ -1,4 +1,4 @@ -FROM openjdk:11-jdk as BUILDER +FROM eclipse-temurin:11-jdk as BUILDER LABEL maintainer="NGINX Docker Maintainers <docker-maint@nginx.com>" @@ -8,7 +8,7 @@ RUN set -ex \ && mkdir -p /usr/lib/unit/modules /usr/lib/unit/debug-modules \ && hg clone https://hg.nginx.org/unit \ && cd unit \ - && hg up 1.27.0 \ + && hg up 1.28.0 \ && NCPU="$(getconf _NPROCESSORS_ONLN)" \ && DEB_HOST_MULTIARCH="$(dpkg-architecture -q DEB_HOST_MULTIARCH)" \ && CC_OPT="$(DEB_BUILD_MAINT_OPTIONS="hardening=+all,-pie" DEB_CFLAGS_MAINT_APPEND="-Wp,-D_FORTIFY_SOURCE=2 -fPIC" dpkg-buildflags --get CFLAGS)" \ @@ -40,7 +40,7 @@ RUN set -ex \ && make -j $NCPU java-shared-install java-install \ && ldd /usr/sbin/unitd | awk '/=>/{print $(NF-1)}' | while read n; do dpkg-query -S $n; done | sed 's/^\([^:]\+\):.*$/\1/' | sort | uniq > /requirements.apt -FROM openjdk:11-jdk +FROM eclipse-temurin:11-jdk COPY docker-entrypoint.sh /usr/local/bin/ COPY --from=BUILDER /usr/sbin/unitd /usr/sbin/unitd COPY --from=BUILDER /usr/sbin/unitd-debug /usr/sbin/unitd-debug diff --git a/pkg/docker/Dockerfile.minimal b/pkg/docker/Dockerfile.minimal index 730e1893..c57379f7 100644 --- a/pkg/docker/Dockerfile.minimal +++ b/pkg/docker/Dockerfile.minimal @@ -8,7 +8,7 @@ RUN set -ex \ && mkdir -p /usr/lib/unit/modules /usr/lib/unit/debug-modules \ && hg clone https://hg.nginx.org/unit \ && cd unit \ - && hg up 1.27.0 \ + && hg up 1.28.0 \ && NCPU="$(getconf _NPROCESSORS_ONLN)" \ && DEB_HOST_MULTIARCH="$(dpkg-architecture -q DEB_HOST_MULTIARCH)" \ && CC_OPT="$(DEB_BUILD_MAINT_OPTIONS="hardening=+all,-pie" DEB_CFLAGS_MAINT_APPEND="-Wp,-D_FORTIFY_SOURCE=2 -fPIC" dpkg-buildflags --get CFLAGS)" \ diff --git a/pkg/docker/Dockerfile.node16 b/pkg/docker/Dockerfile.node16 index 246105d8..d341e43f 100644 --- a/pkg/docker/Dockerfile.node16 +++ b/pkg/docker/Dockerfile.node16 @@ -8,7 +8,7 @@ RUN set -ex \ && mkdir -p /usr/lib/unit/modules /usr/lib/unit/debug-modules \ && hg clone https://hg.nginx.org/unit \ && cd unit \ - && hg up 1.27.0 \ + && hg up 1.28.0 \ && NCPU="$(getconf _NPROCESSORS_ONLN)" \ && DEB_HOST_MULTIARCH="$(dpkg-architecture -q DEB_HOST_MULTIARCH)" \ && CC_OPT="$(DEB_BUILD_MAINT_OPTIONS="hardening=+all,-pie" DEB_CFLAGS_MAINT_APPEND="-Wp,-D_FORTIFY_SOURCE=2 -fPIC" dpkg-buildflags --get CFLAGS)" \ diff --git a/pkg/docker/Dockerfile.perl5.34 b/pkg/docker/Dockerfile.perl5.36 index db87d209..d0b8006f 100644 --- a/pkg/docker/Dockerfile.perl5.34 +++ b/pkg/docker/Dockerfile.perl5.36 @@ -1,4 +1,4 @@ -FROM perl:5.34 as BUILDER +FROM perl:5.36 as BUILDER LABEL maintainer="NGINX Docker Maintainers <docker-maint@nginx.com>" @@ -8,7 +8,7 @@ RUN set -ex \ && mkdir -p /usr/lib/unit/modules /usr/lib/unit/debug-modules \ && hg clone https://hg.nginx.org/unit \ && cd unit \ - && hg up 1.27.0 \ + && hg up 1.28.0 \ && NCPU="$(getconf _NPROCESSORS_ONLN)" \ && DEB_HOST_MULTIARCH="$(dpkg-architecture -q DEB_HOST_MULTIARCH)" \ && CC_OPT="$(DEB_BUILD_MAINT_OPTIONS="hardening=+all,-pie" DEB_CFLAGS_MAINT_APPEND="-Wp,-D_FORTIFY_SOURCE=2 -fPIC" dpkg-buildflags --get CFLAGS)" \ @@ -40,7 +40,7 @@ RUN set -ex \ && make -j $NCPU perl-install \ && ldd /usr/sbin/unitd | awk '/=>/{print $(NF-1)}' | while read n; do dpkg-query -S $n; done | sed 's/^\([^:]\+\):.*$/\1/' | sort | uniq > /requirements.apt -FROM perl:5.34 +FROM perl:5.36 COPY docker-entrypoint.sh /usr/local/bin/ COPY --from=BUILDER /usr/sbin/unitd /usr/sbin/unitd COPY --from=BUILDER /usr/sbin/unitd-debug /usr/sbin/unitd-debug diff --git a/pkg/docker/Dockerfile.php8.1 b/pkg/docker/Dockerfile.php8.1 index 5c18a9bc..c63e708e 100644 --- a/pkg/docker/Dockerfile.php8.1 +++ b/pkg/docker/Dockerfile.php8.1 @@ -8,7 +8,7 @@ RUN set -ex \ && mkdir -p /usr/lib/unit/modules /usr/lib/unit/debug-modules \ && hg clone https://hg.nginx.org/unit \ && cd unit \ - && hg up 1.27.0 \ + && hg up 1.28.0 \ && NCPU="$(getconf _NPROCESSORS_ONLN)" \ && DEB_HOST_MULTIARCH="$(dpkg-architecture -q DEB_HOST_MULTIARCH)" \ && CC_OPT="$(DEB_BUILD_MAINT_OPTIONS="hardening=+all,-pie" DEB_CFLAGS_MAINT_APPEND="-Wp,-D_FORTIFY_SOURCE=2 -fPIC" dpkg-buildflags --get CFLAGS)" \ diff --git a/pkg/docker/Dockerfile.python3.10 b/pkg/docker/Dockerfile.python3.10 index 09e7f42a..6502f8a8 100644 --- a/pkg/docker/Dockerfile.python3.10 +++ b/pkg/docker/Dockerfile.python3.10 @@ -8,7 +8,7 @@ RUN set -ex \ && mkdir -p /usr/lib/unit/modules /usr/lib/unit/debug-modules \ && hg clone https://hg.nginx.org/unit \ && cd unit \ - && hg up 1.27.0 \ + && hg up 1.28.0 \ && NCPU="$(getconf _NPROCESSORS_ONLN)" \ && DEB_HOST_MULTIARCH="$(dpkg-architecture -q DEB_HOST_MULTIARCH)" \ && CC_OPT="$(DEB_BUILD_MAINT_OPTIONS="hardening=+all,-pie" DEB_CFLAGS_MAINT_APPEND="-Wp,-D_FORTIFY_SOURCE=2 -fPIC" dpkg-buildflags --get CFLAGS)" \ diff --git a/pkg/docker/Dockerfile.ruby3.1 b/pkg/docker/Dockerfile.ruby3.1 index 0baedc32..f365bc96 100644 --- a/pkg/docker/Dockerfile.ruby3.1 +++ b/pkg/docker/Dockerfile.ruby3.1 @@ -8,7 +8,7 @@ RUN set -ex \ && mkdir -p /usr/lib/unit/modules /usr/lib/unit/debug-modules \ && hg clone https://hg.nginx.org/unit \ && cd unit \ - && hg up 1.27.0 \ + && hg up 1.28.0 \ && NCPU="$(getconf _NPROCESSORS_ONLN)" \ && DEB_HOST_MULTIARCH="$(dpkg-architecture -q DEB_HOST_MULTIARCH)" \ && CC_OPT="$(DEB_BUILD_MAINT_OPTIONS="hardening=+all,-pie" DEB_CFLAGS_MAINT_APPEND="-Wp,-D_FORTIFY_SOURCE=2 -fPIC" dpkg-buildflags --get CFLAGS)" \ diff --git a/pkg/docker/Makefile b/pkg/docker/Makefile index 5c48f925..03723d1d 100644 --- a/pkg/docker/Makefile +++ b/pkg/docker/Makefile @@ -18,7 +18,7 @@ INSTALL_minimal ?= version define COPY_minimal endef -VERSION_go ?= 1.18 +VERSION_go ?= 1.19 CONTAINER_go ?= golang:$(VERSION_go) CONFIGURE_go ?= go --go-path=$$GOPATH INSTALL_go ?= go-install-src libunit-install @@ -29,7 +29,7 @@ COPY --from=BUILDER /go/src/ /go/src/ endef VERSION_jsc ?= 11 -CONTAINER_jsc ?= openjdk:$(VERSION_jsc)-jdk +CONTAINER_jsc ?= eclipse-temurin:$(VERSION_jsc)-jdk CONFIGURE_jsc ?= java --jars=/usr/share/unit-jsc-common/ INSTALL_jsc ?= java-shared-install java-install COPY_jsc = COPY --from=BUILDER /usr/share/unit-jsc-common/ /usr/share/unit-jsc-common/ @@ -44,7 +44,7 @@ COPY --from=BUILDER /usr/include/nxt_* /usr/include/\n\$ COPY --from=BUILDER /usr/local/lib/node_modules/unit-http/ /usr/local/lib/node_modules/unit-http/ endef -VERSION_perl ?= 5.34 +VERSION_perl ?= 5.36 CONTAINER_perl ?= perl:$(VERSION_perl) CONFIGURE_perl ?= perl INSTALL_perl ?= perl-install diff --git a/pkg/rpm/Makefile b/pkg/rpm/Makefile index a360b36e..bbe44fe5 100644 --- a/pkg/rpm/Makefile +++ b/pkg/rpm/Makefile @@ -10,25 +10,15 @@ RELEASE ?= $(DEFAULT_RELEASE) PACKAGE_VENDOR = NGINX Packaging <nginx-packaging@f5.com> -ifeq ($(shell test `rpm --eval '0%{?rhel} -eq 6 -a 0%{?amzn} -eq 0'`; echo $$?), 0) -OSVER = centos6 -else ifeq ($(shell test `rpm --eval '0%{?rhel} -eq 7 -a 0%{?amzn} -eq 0'`; echo $$?), 0) +ifeq ($(shell test `rpm --eval '0%{?rhel} -eq 7 -a 0%{?amzn} -eq 0'`; echo $$?), 0) OSVER = centos7 else ifeq ($(shell rpm --eval "%{?rhel}"), 8) OSVER = centos8 else ifeq ($(shell rpm --eval "%{?rhel}"), 9) OSVER = centos9 -else ifeq ($(shell rpm --eval "%{?amzn}"), 1) -OSVER = amazonlinux1 else ifeq ($(shell rpm --eval "%{?amzn}"), 2) OSVER = amazonlinux2 -else ifeq ($(shell test `rpm --eval '0%{?suse_version} -ge 1315 -a 0%{?suse_version} -lt 1330 -a 0%{?is_opensuse} -eq 1'`; echo $$?), 0) -OSVER = opensuse-leap -else ifeq ($(shell test `rpm --eval '0%{?suse_version} -ge 1330 -a 0%{?is_opensuse} -eq 1'`; echo $$?), 0) -OSVER = opensuse-tumbleweed -else ifeq ($(shell test `rpm --eval '0%{?suse_version} -ge 1315 -a 0%{?is_opensuse} -eq 0'`; echo $$?), 0) -OSVER = sles -else ifeq ($(shell test `rpm --eval '0%{?fedora} -ge 26'`; echo $$?),0) +else ifeq ($(shell test `rpm --eval '0%{?fedora} -ge 35'`; echo $$?),0) OSVER = fedora endif @@ -38,32 +28,16 @@ ifeq ($(OSVER), centos7) BUILD_DEPENDS_unit += which endif -ifeq ($(OSVER), amazonlinux1) -BUILD_DEPENDS_unit += system-rpm-config -endif - -ifneq (,$(findstring $(OSVER),opensuse-leap opensuse-tumbleweed sles)) -BUILD_DEPENDS_unit += libxml2-tools libxslt1 libopenssl-devel -else ifneq (,$(findstring $(OSVER),amazonlinux2)) BUILD_DEPENDS_unit += libxml2 libxslt openssl11-devel else BUILD_DEPENDS_unit += libxml2 libxslt openssl-devel endif -endif BUILD_DEPENDS = $(BUILD_DEPENDS_unit) MODULES= -ifeq ($(OSVER), centos6) -include Makefile.php -include Makefile.python -include Makefile.go -include Makefile.jsc-common -include Makefile.jsc8 -endif - ifeq ($(OSVER), centos7) include Makefile.php include Makefile.python27 @@ -96,18 +70,6 @@ include Makefile.jsc8 include Makefile.jsc11 endif -ifeq ($(OSVER), amazonlinux1) -include Makefile.php -include Makefile.python27 -include Makefile.python34 -include Makefile.python35 -include Makefile.python36 -include Makefile.go -include Makefile.perl -include Makefile.jsc-common -include Makefile.jsc8 -endif - ifeq ($(OSVER), amazonlinux2) include Makefile.php include Makefile.python27 @@ -118,45 +80,9 @@ include Makefile.jsc-common include Makefile.jsc8 endif -ifeq ($(OSVER), opensuse-leap) -include Makefile.python27 -include Makefile.python34 -include Makefile.go -include Makefile.perl -include Makefile.ruby -endif - -ifeq ($(OSVER), opensuse-tumbleweed) -include Makefile.php -include Makefile.python27 -include Makefile.python36 -include Makefile.go -include Makefile.perl -include Makefile.ruby -endif - -ifeq ($(OSVER), sles) -include Makefile.python27 -include Makefile.python34 -include Makefile.perl -endif - ifeq ($(OSVER), fedora) include Makefile.php -ifeq ($(shell test `rpm --eval '0%{?fedora} -lt 32'`; echo $$?),0) -include Makefile.python27 -endif -ifeq ($(shell test `rpm --eval '0%{?fedora} -ge 35'`; echo $$?),0) include Makefile.python310 -else ifeq ($(shell test `rpm --eval '0%{?fedora} -ge 33'`; echo $$?),0) -include Makefile.python39 -else ifeq ($(shell test `rpm --eval '0%{?fedora} -ge 32'`; echo $$?),0) -include Makefile.python38 -else ifeq ($(shell test `rpm --eval '0%{?fedora} -ge 29'`; echo $$?),0) -include Makefile.python37 -else -include Makefile.python36 -endif include Makefile.go include Makefile.perl include Makefile.ruby diff --git a/pkg/rpm/Makefile.go b/pkg/rpm/Makefile.go index a1421bee..aacbe2b9 100644 --- a/pkg/rpm/Makefile.go +++ b/pkg/rpm/Makefile.go @@ -15,28 +15,17 @@ MODULE_SOURCES_go= unit.example-go-app \ ifeq ($(OSVER), centos6) BUILD_DEPENDS_go= epel-release golang -else ifneq (,$(findstring $(OSVER),opensuse-leap opensuse-tumbleweed)) -BUILD_DEPENDS_go= go1.9 else BUILD_DEPENDS_go= golang endif BUILD_DEPENDS+= $(BUILD_DEPENDS_go) -ifneq (,$(findstring $(OSVER),opensuse-leap opensuse-tumbleweed)) define MODULE_DEFINITIONS_go BuildArch: noarch Requires: unit-devel == $(VERSION)-$(RELEASE)%{?dist}.ngx BuildRequires: $(BUILD_DEPENDS_go) -%define gopath /usr/share/go/contrib endef -else -define MODULE_DEFINITIONS_go -BuildArch: noarch -Requires: unit-devel == $(VERSION)-$(RELEASE)%{?dist}.ngx -BuildRequires: $(BUILD_DEPENDS_go) -endef -endif export MODULE_DEFINITIONS_go define MODULE_PREINSTALL_go diff --git a/pkg/rpm/Makefile.perl b/pkg/rpm/Makefile.perl index f59b7353..92440cfa 100644 --- a/pkg/rpm/Makefile.perl +++ b/pkg/rpm/Makefile.perl @@ -13,11 +13,7 @@ MODULE_INSTARGS_perl= perl-install MODULE_SOURCES_perl= unit.example-perl-app \ unit.example-perl-config -ifneq (,$(findstring $(OSVER),opensuse-leap opensuse-tumbleweed sles)) -BUILD_DEPENDS_perl= perl -else BUILD_DEPENDS_perl= perl-devel perl-libs perl-ExtUtils-Embed -endif BUILD_DEPENDS+= $(BUILD_DEPENDS_perl) diff --git a/pkg/rpm/Makefile.php b/pkg/rpm/Makefile.php index 8f39efc0..0f5a10e5 100644 --- a/pkg/rpm/Makefile.php +++ b/pkg/rpm/Makefile.php @@ -13,11 +13,7 @@ MODULE_INSTARGS_php= php-install MODULE_SOURCES_php= unit.example-php-app \ unit.example-php-config -ifeq ($(OSVER), opensuse-tumbleweed) -BUILD_DEPENDS_php= php7-devel php7-embed -else BUILD_DEPENDS_php= php-devel php-embedded -endif BUILD_DEPENDS+= $(BUILD_DEPENDS_php) diff --git a/pkg/rpm/Makefile.python b/pkg/rpm/Makefile.python deleted file mode 100644 index 334d62c1..00000000 --- a/pkg/rpm/Makefile.python +++ /dev/null @@ -1,57 +0,0 @@ -MODULES+= python -MODULE_SUFFIX_python= python - -MODULE_SUMMARY_python= Python module for NGINX Unit - -MODULE_VERSION_python= $(VERSION) -MODULE_RELEASE_python= 1 - -MODULE_CONFARGS_python= python -MODULE_MAKEARGS_python= python -MODULE_INSTARGS_python= python-install - -MODULE_SOURCES_python= unit.example-python-app \ - unit.example-python-config - -ifeq ($(shell rpm --eval "%{?amzn}"), 1) -BUILD_DEPENDS_python= python26-devel -else -BUILD_DEPENDS_python= python-devel -endif - -BUILD_DEPENDS+= $(BUILD_DEPENDS_python) - -define MODULE_PREINSTALL_python -%{__mkdir} -p %{buildroot}%{_datadir}/doc/unit-python/examples/python-app -%{__install} -m 644 -p %{SOURCE100} \ - %{buildroot}%{_datadir}/doc/unit-python/examples/python-app/wsgi.py -%{__install} -m 644 -p %{SOURCE101} \ - %{buildroot}%{_datadir}/doc/unit-python/examples/unit.config -endef -export MODULE_PREINSTALL_python - -define MODULE_FILES_python -%{_libdir}/unit/modules/* -%{_libdir}/unit/debug-modules/* -endef -export MODULE_FILES_python - -define MODULE_POST_python -cat <<BANNER ----------------------------------------------------------------------- - -The $(MODULE_SUMMARY_python) has been installed. - -To check the sample app, run these commands: - - sudo service unit start - cd /usr/share/doc/%{name}/examples - sudo curl -X PUT --data-binary @unit.config --unix-socket /var/run/unit/control.sock http://localhost/config - curl http://localhost:8400/ - -Online documentation is available at https://unit.nginx.org - ----------------------------------------------------------------------- -BANNER -endef -export MODULE_POST_python diff --git a/pkg/rpm/Makefile.python27 b/pkg/rpm/Makefile.python27 index 079a8512..3de5f634 100644 --- a/pkg/rpm/Makefile.python27 +++ b/pkg/rpm/Makefile.python27 @@ -13,9 +13,7 @@ MODULE_INSTARGS_python27= python2.7-install MODULE_SOURCES_python27= unit.example-python-app \ unit.example-python27-config -ifneq (,$(findstring $(OSVER),opensuse-leap opensuse-tumbleweed sles)) -BUILD_DEPENDS_python27= python-devel -else ifneq (,$(findstring $(OSVER),fedora centos8)) +ifneq (,$(findstring $(OSVER),fedora centos8)) BUILD_DEPENDS_python27= python2-devel else ifneq (,$(findstring $(OSVER),centos7 amazonlinux2)) BUILD_DEPENDS_python27= python-devel diff --git a/pkg/rpm/Makefile.python310 b/pkg/rpm/Makefile.python310 index 82bc311a..50731475 100644 --- a/pkg/rpm/Makefile.python310 +++ b/pkg/rpm/Makefile.python310 @@ -13,7 +13,7 @@ MODULE_INSTARGS_python310= python3.10-install MODULE_SOURCES_python310= unit.example-python-app \ unit.example-python310-config -ifneq (,$(findstring $(OSVER),opensuse-tumbleweed sles fedora amazonlinux2)) +ifneq (,$(findstring $(OSVER),fedora amazonlinux2)) BUILD_DEPENDS_python310= python3-devel else BUILD_DEPENDS_python310= python310-devel diff --git a/pkg/rpm/Makefile.python34 b/pkg/rpm/Makefile.python34 deleted file mode 100644 index 83c0bdb6..00000000 --- a/pkg/rpm/Makefile.python34 +++ /dev/null @@ -1,57 +0,0 @@ -MODULES+= python34 -MODULE_SUFFIX_python34= python3.4 - -MODULE_SUMMARY_python34= Python 3.4 module for NGINX Unit - -MODULE_VERSION_python34= $(VERSION) -MODULE_RELEASE_python34= 1 - -MODULE_CONFARGS_python34= python --config=python3.4-config -MODULE_MAKEARGS_python34= python3.4 -MODULE_INSTARGS_python34= python3.4-install - -MODULE_SOURCES_python34= unit.example-python-app \ - unit.example-python34-config - -ifneq (,$(findstring $(OSVER),opensuse-leap sles)) -BUILD_DEPENDS_python34= python3-devel -else -BUILD_DEPENDS_python34= python34-devel -endif - -BUILD_DEPENDS+= $(BUILD_DEPENDS_python34) - -define MODULE_PREINSTALL_python34 -%{__mkdir} -p %{buildroot}%{_datadir}/doc/unit-python34/examples/python-app -%{__install} -m 644 -p %{SOURCE100} \ - %{buildroot}%{_datadir}/doc/unit-python34/examples/python-app/wsgi.py -%{__install} -m 644 -p %{SOURCE101} \ - %{buildroot}%{_datadir}/doc/unit-python34/examples/unit.config -endef -export MODULE_PREINSTALL_python34 - -define MODULE_FILES_python34 -%{_libdir}/unit/modules/* -%{_libdir}/unit/debug-modules/* -endef -export MODULE_FILES_python34 - -define MODULE_POST_python34 -cat <<BANNER ----------------------------------------------------------------------- - -The $(MODULE_SUMMARY_python34) has been installed. - -To check the sample app, run these commands: - - sudo service unit start - cd /usr/share/doc/%{name}/examples - sudo curl -X PUT --data-binary @unit.config --unix-socket /var/run/unit/control.sock http://localhost/config - curl http://localhost:8400/ - -Online documentation is available at https://unit.nginx.org - ----------------------------------------------------------------------- -BANNER -endef -export MODULE_POST_python34 diff --git a/pkg/rpm/Makefile.python35 b/pkg/rpm/Makefile.python35 deleted file mode 100644 index 6f866771..00000000 --- a/pkg/rpm/Makefile.python35 +++ /dev/null @@ -1,52 +0,0 @@ -MODULES+= python35 -MODULE_SUFFIX_python35= python3.5 - -MODULE_SUMMARY_python35= Python 3.5 module for NGINX Unit - -MODULE_VERSION_python35= $(VERSION) -MODULE_RELEASE_python35= 1 - -MODULE_CONFARGS_python35= python --config=python3.5-config -MODULE_MAKEARGS_python35= python3.5 -MODULE_INSTARGS_python35= python3.5-install - -MODULE_SOURCES_python35= unit.example-python-app \ - unit.example-python35-config - -BUILD_DEPENDS_python35= python35-devel -BUILD_DEPENDS+= $(BUILD_DEPENDS_python35) - -define MODULE_PREINSTALL_python35 -%{__mkdir} -p %{buildroot}%{_datadir}/doc/unit-python35/examples/python-app -%{__install} -m 644 -p %{SOURCE100} \ - %{buildroot}%{_datadir}/doc/unit-python35/examples/python-app/wsgi.py -%{__install} -m 644 -p %{SOURCE101} \ - %{buildroot}%{_datadir}/doc/unit-python35/examples/unit.config -endef -export MODULE_PREINSTALL_python35 - -define MODULE_FILES_python35 -%{_libdir}/unit/modules/* -%{_libdir}/unit/debug-modules/* -endef -export MODULE_FILES_python35 - -define MODULE_POST_python35 -cat <<BANNER ----------------------------------------------------------------------- - -The $(MODULE_SUMMARY_python35) has been installed. - -To check the sample app, run these commands: - - sudo service unit start - cd /usr/share/doc/%{name}/examples - sudo curl -X PUT --data-binary @unit.config --unix-socket /var/run/unit/control.sock http://localhost/config - curl http://localhost:8400/ - -Online documentation is available at https://unit.nginx.org - ----------------------------------------------------------------------- -BANNER -endef -export MODULE_POST_python35 diff --git a/pkg/rpm/Makefile.python36 b/pkg/rpm/Makefile.python36 index 827d2253..c1fc8b6c 100644 --- a/pkg/rpm/Makefile.python36 +++ b/pkg/rpm/Makefile.python36 @@ -13,7 +13,7 @@ MODULE_INSTARGS_python36= python3.6-install MODULE_SOURCES_python36= unit.example-python-app \ unit.example-python36-config -ifneq (,$(findstring $(OSVER),opensuse-tumbleweed sles fedora centos7)) +ifneq (,$(findstring $(OSVER),fedora centos7)) BUILD_DEPENDS_python36= python3-devel else BUILD_DEPENDS_python36= python36-devel diff --git a/pkg/rpm/Makefile.python37 b/pkg/rpm/Makefile.python37 index 563d4539..c0604fd9 100644 --- a/pkg/rpm/Makefile.python37 +++ b/pkg/rpm/Makefile.python37 @@ -13,7 +13,7 @@ MODULE_INSTARGS_python37= python3.7-install MODULE_SOURCES_python37= unit.example-python-app \ unit.example-python37-config -ifneq (,$(findstring $(OSVER),opensuse-tumbleweed sles fedora amazonlinux2)) +ifneq (,$(findstring $(OSVER),fedora amazonlinux2)) BUILD_DEPENDS_python37= python3-devel else BUILD_DEPENDS_python37= python37-devel diff --git a/pkg/rpm/Makefile.python38 b/pkg/rpm/Makefile.python38 deleted file mode 100644 index ffcca07f..00000000 --- a/pkg/rpm/Makefile.python38 +++ /dev/null @@ -1,57 +0,0 @@ -MODULES+= python38 -MODULE_SUFFIX_python38= python3.8 - -MODULE_SUMMARY_python38= Python 3.8 module for NGINX Unit - -MODULE_VERSION_python38= $(VERSION) -MODULE_RELEASE_python38= 1 - -MODULE_CONFARGS_python38= python --config=python3.8-config -MODULE_MAKEARGS_python38= python3.8 -MODULE_INSTARGS_python38= python3.8-install - -MODULE_SOURCES_python38= unit.example-python-app \ - unit.example-python38-config - -ifneq (,$(findstring $(OSVER),opensuse-tumbleweed sles fedora amazonlinux2)) -BUILD_DEPENDS_python38= python3-devel -else -BUILD_DEPENDS_python38= python38-devel -endif - -BUILD_DEPENDS+= $(BUILD_DEPENDS_python38) - -define MODULE_PREINSTALL_python38 -%{__mkdir} -p %{buildroot}%{_datadir}/doc/unit-python38/examples/python-app -%{__install} -m 644 -p %{SOURCE100} \ - %{buildroot}%{_datadir}/doc/unit-python38/examples/python-app/wsgi.py -%{__install} -m 644 -p %{SOURCE101} \ - %{buildroot}%{_datadir}/doc/unit-python38/examples/unit.config -endef -export MODULE_PREINSTALL_python38 - -define MODULE_FILES_python38 -%{_libdir}/unit/modules/* -%{_libdir}/unit/debug-modules/* -endef -export MODULE_FILES_python38 - -define MODULE_POST_python38 -cat <<BANNER ----------------------------------------------------------------------- - -The $(MODULE_SUMMARY_python38) has been installed. - -To check the sample app, run these commands: - - sudo service unit start - cd /usr/share/doc/%{name}/examples - sudo curl -X PUT --data-binary @unit.config --unix-socket /var/run/unit/control.sock http://localhost/config - curl http://localhost:8400/ - -Online documentation is available at https://unit.nginx.org - ----------------------------------------------------------------------- -BANNER -endef -export MODULE_POST_python38 diff --git a/pkg/rpm/Makefile.python39 b/pkg/rpm/Makefile.python39 index 3f791111..5d7c2327 100644 --- a/pkg/rpm/Makefile.python39 +++ b/pkg/rpm/Makefile.python39 @@ -13,7 +13,7 @@ MODULE_INSTARGS_python39= python3.9-install MODULE_SOURCES_python39= unit.example-python-app \ unit.example-python39-config -ifneq (,$(findstring $(OSVER),opensuse-tumbleweed sles fedora amazonlinux2 centos9)) +ifneq (,$(findstring $(OSVER),fedora amazonlinux2 centos9)) BUILD_DEPENDS_python39= python3-devel else BUILD_DEPENDS_python39= python39-devel diff --git a/pkg/rpm/Makefile.ruby b/pkg/rpm/Makefile.ruby index 51c2949d..7fddc145 100644 --- a/pkg/rpm/Makefile.ruby +++ b/pkg/rpm/Makefile.ruby @@ -13,13 +13,7 @@ MODULE_INSTARGS_ruby= ruby-install MODULE_SOURCES_ruby= unit.example-ruby-app \ unit.example-ruby-config -ifeq ($(OSVER), opensuse-leap) -RACK_PACKAGE= ruby2.1-rubygem-rack -else ifeq ($(OSVER), opensuse-tumbleweed) -RACK_PACKAGE= ruby2.5-rubygem-rack -else RACK_PACKAGE= rubygem-rack -endif BUILD_DEPENDS_ruby= ruby-devel $(RACK_PACKAGE) BUILD_DEPENDS+= $(BUILD_DEPENDS_ruby) diff --git a/pkg/rpm/rpmbuild/SOURCES/COPYRIGHT.unit-jsc10 b/pkg/rpm/rpmbuild/SOURCES/COPYRIGHT.unit-jsc10 deleted file mode 100644 index c7860e4b..00000000 --- a/pkg/rpm/rpmbuild/SOURCES/COPYRIGHT.unit-jsc10 +++ /dev/null @@ -1,32 +0,0 @@ - - NGINX Unit. - - Copyright 2017-2022 NGINX, Inc. - Copyright 2017-2022 Valentin V. Bartenev - Copyright 2017-2022 Max Romanov - Copyright 2017-2022 Andrei Zeliankou - Copyright 2018-2022 Konstantin Pavlov - Copyright 2021-2022 Zhidao Hong - Copyright 2021-2022 OisÃn Canty - Copyright 2017-2021 Igor Sysoev - Copyright 2017-2021 Andrei Belov - Copyright 2019-2021 Tiago Natel de Moura - Copyright 2019-2020 Axel Duch - Copyright 2018-2019 Alexander Borisov - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. - - The unit-jsc10 package provides Java servlet container module - for NGINX Unit. - - Java is a registered trademark of Oracle and/or its affiliates. diff --git a/pkg/rpm/rpmbuild/SOURCES/unit.example-python35-config b/pkg/rpm/rpmbuild/SOURCES/unit.example-python35-config deleted file mode 100644 index f9923a49..00000000 --- a/pkg/rpm/rpmbuild/SOURCES/unit.example-python35-config +++ /dev/null @@ -1,16 +0,0 @@ -{ - "applications": { - "example_python": { - "type": "python 3.5", - "processes": 2, - "path": "/usr/share/doc/unit-python35/examples/python-app", - "module": "wsgi" - } - }, - - "listeners": { - "*:8400": { - "pass": "applications/example_python" - } - } -} diff --git a/pkg/rpm/rpmbuild/SOURCES/unit.example-python38-config b/pkg/rpm/rpmbuild/SOURCES/unit.example-python38-config deleted file mode 100644 index c98d1a52..00000000 --- a/pkg/rpm/rpmbuild/SOURCES/unit.example-python38-config +++ /dev/null @@ -1,16 +0,0 @@ -{ - "applications": { - "example_python": { - "type": "python 3.8", - "processes": 2, - "path": "/usr/share/doc/unit-python38/examples/python-app", - "module": "wsgi" - } - }, - - "listeners": { - "*:8400": { - "pass": "applications/example_python" - } - } -} diff --git a/pkg/rpm/unit.module.spec.in b/pkg/rpm/unit.module.spec.in index 9b0f6221..88a1c33e 100644 --- a/pkg/rpm/unit.module.spec.in +++ b/pkg/rpm/unit.module.spec.in @@ -16,10 +16,6 @@ BuildRequires: openssl-devel %endif %endif -%if 0%{?suse_version} >= 1315 -BuildRequires: libopenssl-devel -%endif - %define unit_version %%UNIT_VERSION%% %define unit_release %%UNIT_RELEASE%%%{?dist}.ngx @@ -54,10 +50,6 @@ directly in the cloud / container environments and fully control your app dynamically via an API. This package contains %%SUMMARY%%. -%if 0%{?suse_version} -%debug_package -%endif - %if (0%{?fedora}) || (0%{?rhel} >= 8) %define _debugsource_template %{nil} %endif @@ -106,9 +98,6 @@ DESTDIR=%{buildroot} make %%MODULE_INSTARGS%% cd %{bdir} grep -v 'usr/src' debugfiles.list > debugfiles.list.new && mv debugfiles.list.new debugfiles.list cat /dev/null > debugsources.list -%if 0%{?suse_version} >= 1500 -cat /dev/null > debugsourcefiles.list -%endif %clean %{__rm} -rf %{buildroot} diff --git a/pkg/rpm/unit.spec.in b/pkg/rpm/unit.spec.in index 4cbc7358..01c08bb8 100644 --- a/pkg/rpm/unit.spec.in +++ b/pkg/rpm/unit.spec.in @@ -17,10 +17,6 @@ BuildRequires: openssl-devel %endif %endif -%if 0%{?suse_version} >= 1315 -BuildRequires: libopenssl-devel -%endif - %define CC_OPT %{optflags} -fPIC %define LD_OPT -Wl,-z,relro -Wl,-z,now -pie @@ -59,10 +55,6 @@ in and out of the application. Take this application server and proxy directly in the cloud / container environments and fully control your app dynamically via an API. -%if 0%{?suse_version} -%debug_package -%endif - %if (0%{?fedora}) || (0%{?rhel} >= 8) %define _debugsource_template %{nil} %endif @@ -115,7 +107,6 @@ DESTDIR=%{buildroot} make unitd-install libunit-install manpage-install %{__mkdir} -p %{buildroot}%{_sysconfdir}/logrotate.d %{__install} -m 644 -p %{SOURCE4} \ %{buildroot}%{_sysconfdir}/logrotate.d/unit -%{__mkdir} -p %{buildroot}%{_sysconfdir}/unit %{__mkdir} -p %{buildroot}%{_datadir}/doc/unit/examples %{__install} -m 644 -p %{SOURCE3} \ %{buildroot}%{_datadir}/doc/unit/examples/example.config @@ -143,9 +134,6 @@ cd %{bdir} && make tests && ./build/tests cd %{bdir} grep -v 'usr/src' debugfiles.list > debugfiles.list.new && mv debugfiles.list.new debugfiles.list cat /dev/null > debugsources.list -%if 0%{?suse_version} >= 1500 -cat /dev/null > debugsourcefiles.list -%endif %clean %{__rm} -rf %{buildroot} @@ -203,7 +191,6 @@ BANNER %defattr(-,root,root,-) %attr(0755,root,root) %{_sbindir}/unitd %attr(0755,root,root) %{_sbindir}/unitd-debug -%dir %{_sysconfdir}/unit %{_unitdir}/unit.service %{_unitdir}/unit-debug.service %dir %attr(0755,root,root) %ghost %{_localstatedir}/run/unit diff --git a/src/nxt_application.c b/src/nxt_application.c index 594574b1..556f1ffb 100644 --- a/src/nxt_application.c +++ b/src/nxt_application.c @@ -23,6 +23,13 @@ #endif +#ifdef WCOREDUMP +#define NXT_WCOREDUMP(s) WCOREDUMP(s) +#else +#define NXT_WCOREDUMP(s) 0 +#endif + + typedef struct { nxt_app_type_t type; nxt_str_t version; @@ -636,6 +643,8 @@ nxt_proto_start_process_handler(nxt_task_t *task, nxt_port_recv_msg_t *msg) process->data.app = nxt_app_conf; process->stream = msg->port_msg.stream; + init->siblings = &nxt_proto_children; + ret = nxt_process_start(task, process); if (nxt_slow_path(ret == NXT_ERROR)) { nxt_process_use(task, process, -1); @@ -711,15 +720,19 @@ nxt_proto_process_created_handler(nxt_task_t *task, nxt_port_recv_msg_t *msg) nxt_debug(task, "app process %PI (aka %PI) is created", isolated_pid, pid); - nxt_runtime_process_remove(task->thread->runtime, process); - process->pid = pid; - nxt_runtime_process_add(task, process); - } else { nxt_debug(task, "app process %PI is created", isolated_pid); } + + if (!process->registered) { + nxt_assert(!nxt_queue_is_empty(&process->ports)); + + nxt_runtime_process_add(task, process); + + nxt_port_use(task, nxt_process_port_first(process), -1); + } } @@ -753,7 +766,11 @@ nxt_proto_sigchld_handler(nxt_task_t *task, void *obj, void *data) int status; nxt_err_t err; nxt_pid_t pid; + nxt_port_t *port; nxt_process_t *process; + nxt_runtime_t *rt; + + rt = task->thread->runtime; nxt_debug(task, "proto sigchld handler signo:%d (%s)", (int) (uintptr_t) obj, data); @@ -783,32 +800,58 @@ nxt_proto_sigchld_handler(nxt_task_t *task, void *obj, void *data) return; } + process = nxt_proto_process_remove(task, pid); + if (WTERMSIG(status)) { -#ifdef WCOREDUMP - nxt_alert(task, "app process (isolated %PI) exited on signal %d%s", - pid, WTERMSIG(status), - WCOREDUMP(status) ? " (core dumped)" : ""); -#else - nxt_alert(task, "app process (isolated %PI) exited on signal %d", - pid, WTERMSIG(status)); -#endif + if (rt->is_pid_isolated) { + nxt_alert(task, "app process %PI (isolated %PI) " + "exited on signal %d%s", + process != NULL ? process->pid : 0, + pid, WTERMSIG(status), + NXT_WCOREDUMP(status) ? " (core dumped)" : ""); + + } else { + nxt_alert(task, "app process %PI exited on signal %d%s", + pid, WTERMSIG(status), + NXT_WCOREDUMP(status) ? " (core dumped)" : ""); + } } else { - nxt_trace(task, "app process (isolated %PI) exited with code %d", - pid, WEXITSTATUS(status)); + if (rt->is_pid_isolated) { + nxt_trace(task, "app process %PI (isolated %PI) " + "exited with code %d", + process != NULL ? process->pid : 0, + pid, WEXITSTATUS(status)); + + } else { + nxt_trace(task, "app process %PI exited with code %d", + pid, WEXITSTATUS(status)); + } } - process = nxt_proto_process_remove(task, pid); if (process == NULL) { continue; } + if (process->registered) { + port = NULL; + + } else { + nxt_assert(!nxt_queue_is_empty(&process->ports)); + + port = nxt_process_port_first(process); + } + if (process->state != NXT_PROCESS_STATE_CREATING) { nxt_port_remove_notify_others(task, process); } nxt_process_close_ports(task, process); + if (port != NULL) { + nxt_port_use(task, port, -1); + } + if (nxt_proto_exiting && nxt_queue_is_empty(&nxt_proto_children)) { nxt_process_quit(task, 0); return; @@ -1122,7 +1165,7 @@ nxt_proto_process_add(nxt_task_t *task, nxt_process_t *process) break; default: - nxt_debug(task, "process (isolated %PI) failed to add", + nxt_alert(task, "process (isolated %PI) failed to add", process->isolated_pid); break; } diff --git a/src/nxt_clone.c b/src/nxt_clone.c index aa952a54..a9b39ac1 100644 --- a/src/nxt_clone.c +++ b/src/nxt_clone.c @@ -14,9 +14,9 @@ pid_t nxt_clone(nxt_int_t flags) { #if defined(__s390x__) || defined(__s390__) || defined(__CRIS__) - return syscall(__NR_clone, NULL, flags); + return syscall(SYS_clone, NULL, flags); #else - return syscall(__NR_clone, flags, NULL); + return syscall(SYS_clone, flags, NULL); #endif } diff --git a/src/nxt_conf.c b/src/nxt_conf.c index 79e776a0..c6312f3d 100644 --- a/src/nxt_conf.c +++ b/src/nxt_conf.c @@ -102,7 +102,7 @@ typedef struct { static nxt_int_t nxt_conf_path_next_token(nxt_conf_path_parse_t *parse, nxt_str_t *token); -static u_char *nxt_conf_json_skip_space(u_char *start, u_char *end); +static u_char *nxt_conf_json_skip_space(u_char *start, const u_char *end); static u_char *nxt_conf_json_parse_value(nxt_mp_t *mp, nxt_conf_value_t *value, u_char *start, u_char *end, nxt_conf_json_error_t *error); static u_char *nxt_conf_json_parse_object(nxt_mp_t *mp, nxt_conf_value_t *value, @@ -266,7 +266,7 @@ nxt_conf_create_object(nxt_mp_t *mp, nxt_uint_t count) void nxt_conf_set_member(nxt_conf_value_t *object, nxt_str_t *name, - nxt_conf_value_t *value, uint32_t index) + const nxt_conf_value_t *value, uint32_t index) { nxt_conf_object_member_t *member; @@ -278,6 +278,20 @@ nxt_conf_set_member(nxt_conf_value_t *object, nxt_str_t *name, } +nxt_int_t +nxt_conf_set_member_dup(nxt_conf_value_t *object, nxt_mp_t *mp, nxt_str_t *name, + nxt_conf_value_t *value, uint32_t index) +{ + nxt_conf_object_member_t *member; + + member = &object->u.object->members[index]; + + member->value = *value; + + return nxt_conf_set_string_dup(&member->name, mp, name); +} + + void nxt_conf_set_member_string(nxt_conf_value_t *object, nxt_str_t *name, nxt_str_t *value, uint32_t index) @@ -367,7 +381,7 @@ nxt_conf_create_array(nxt_mp_t *mp, nxt_uint_t count) void nxt_conf_set_element(nxt_conf_value_t *array, nxt_uint_t index, - nxt_conf_value_t *value) + const nxt_conf_value_t *value) { array->u.array->elements[index] = *value; } @@ -1271,7 +1285,7 @@ nxt_conf_json_parse(nxt_mp_t *mp, u_char *start, u_char *end, static u_char * -nxt_conf_json_skip_space(u_char *start, u_char *end) +nxt_conf_json_skip_space(u_char *start, const u_char *end) { u_char *p, ch; @@ -2605,7 +2619,7 @@ nxt_conf_json_escape(u_char *dst, u_char *src, size_t size) void -nxt_conf_json_position(u_char *start, u_char *pos, nxt_uint_t *line, +nxt_conf_json_position(u_char *start, const u_char *pos, nxt_uint_t *line, nxt_uint_t *column) { u_char *p; diff --git a/src/nxt_conf.h b/src/nxt_conf.h index cfbc5991..c8a276c0 100644 --- a/src/nxt_conf.h +++ b/src/nxt_conf.h @@ -72,6 +72,7 @@ typedef struct { nxt_mp_t *pool; nxt_str_t error; void *ctx; + nxt_array_t *var_fields; /* of nxt_var_field_t */ nxt_mp_t *conf_pool; nxt_uint_t ver; } nxt_conf_validation_t; @@ -109,7 +110,7 @@ size_t nxt_conf_json_length(nxt_conf_value_t *value, nxt_conf_json_pretty_t *pretty); u_char *nxt_conf_json_print(u_char *p, nxt_conf_value_t *value, nxt_conf_json_pretty_t *pretty); -void nxt_conf_json_position(u_char *start, u_char *pos, nxt_uint_t *line, +void nxt_conf_json_position(u_char *start, const u_char *pos, nxt_uint_t *line, nxt_uint_t *column); nxt_int_t nxt_conf_validate(nxt_conf_validation_t *vldt); @@ -125,7 +126,9 @@ NXT_EXPORT uint8_t nxt_conf_get_boolean(nxt_conf_value_t *value); NXT_EXPORT nxt_uint_t nxt_conf_object_members_count(nxt_conf_value_t *value); nxt_conf_value_t *nxt_conf_create_object(nxt_mp_t *mp, nxt_uint_t count); void nxt_conf_set_member(nxt_conf_value_t *object, nxt_str_t *name, - nxt_conf_value_t *value, uint32_t index); + const nxt_conf_value_t *value, uint32_t index); +nxt_int_t nxt_conf_set_member_dup(nxt_conf_value_t *object, nxt_mp_t *mp, + nxt_str_t *name, nxt_conf_value_t *value, uint32_t index); void nxt_conf_set_member_string(nxt_conf_value_t *object, nxt_str_t *name, nxt_str_t *value, uint32_t index); nxt_int_t nxt_conf_set_member_string_dup(nxt_conf_value_t *object, nxt_mp_t *mp, @@ -137,7 +140,7 @@ void nxt_conf_set_member_null(nxt_conf_value_t *object, nxt_str_t *name, nxt_conf_value_t *nxt_conf_create_array(nxt_mp_t *mp, nxt_uint_t count); void nxt_conf_set_element(nxt_conf_value_t *array, nxt_uint_t index, - nxt_conf_value_t *value); + const nxt_conf_value_t *value); nxt_int_t nxt_conf_set_element_string_dup(nxt_conf_value_t *array, nxt_mp_t *mp, nxt_uint_t index, nxt_str_t *value); NXT_EXPORT nxt_uint_t nxt_conf_array_elements_count(nxt_conf_value_t *value); diff --git a/src/nxt_conf_validation.c b/src/nxt_conf_validation.c index ee7ebe44..fe6c22e5 100644 --- a/src/nxt_conf_validation.c +++ b/src/nxt_conf_validation.c @@ -166,6 +166,8 @@ static nxt_int_t nxt_conf_vldt_match_addr(nxt_conf_validation_t *vldt, nxt_conf_value_t *value); static nxt_int_t nxt_conf_vldt_app_name(nxt_conf_validation_t *vldt, nxt_conf_value_t *value, void *data); +static nxt_int_t nxt_conf_vldt_forwarded(nxt_conf_validation_t *vldt, + nxt_conf_value_t *value, void *data); static nxt_int_t nxt_conf_vldt_app(nxt_conf_validation_t *vldt, nxt_str_t *name, nxt_conf_value_t *value); static nxt_int_t nxt_conf_vldt_object(nxt_conf_validation_t *vldt, @@ -200,6 +202,8 @@ static nxt_int_t nxt_conf_vldt_server(nxt_conf_validation_t *vldt, nxt_str_t *name, nxt_conf_value_t *value); static nxt_int_t nxt_conf_vldt_server_weight(nxt_conf_validation_t *vldt, nxt_conf_value_t *value, void *data); +static nxt_int_t nxt_conf_vldt_access_log(nxt_conf_validation_t *vldt, + nxt_conf_value_t *value, void *data); static nxt_int_t nxt_conf_vldt_isolation(nxt_conf_validation_t *vldt, nxt_conf_value_t *value, void *data); @@ -220,6 +224,7 @@ static nxt_conf_vldt_object_t nxt_conf_vldt_setting_members[]; static nxt_conf_vldt_object_t nxt_conf_vldt_http_members[]; static nxt_conf_vldt_object_t nxt_conf_vldt_websocket_members[]; static nxt_conf_vldt_object_t nxt_conf_vldt_static_members[]; +static nxt_conf_vldt_object_t nxt_conf_vldt_forwarded_members[]; static nxt_conf_vldt_object_t nxt_conf_vldt_client_ip_members[]; #if (NXT_TLS) static nxt_conf_vldt_object_t nxt_conf_vldt_tls_members[]; @@ -238,6 +243,7 @@ static nxt_conf_vldt_object_t nxt_conf_vldt_app_namespaces_members[]; #if (NXT_HAVE_ISOLATION_ROOTFS) static nxt_conf_vldt_object_t nxt_conf_vldt_app_automount_members[]; #endif +static nxt_conf_vldt_object_t nxt_conf_vldt_access_log_members[]; static nxt_conf_vldt_object_t nxt_conf_vldt_root_members[] = { @@ -267,7 +273,8 @@ static nxt_conf_vldt_object_t nxt_conf_vldt_root_members[] = { .u.object = nxt_conf_vldt_upstream, }, { .name = nxt_string("access_log"), - .type = NXT_CONF_VLDT_STRING, + .type = NXT_CONF_VLDT_STRING | NXT_CONF_VLDT_OBJECT, + .validator = nxt_conf_vldt_access_log, }, NXT_CONF_VLDT_END @@ -366,6 +373,10 @@ static nxt_conf_vldt_object_t nxt_conf_vldt_listener_members[] = { .type = NXT_CONF_VLDT_STRING, .validator = nxt_conf_vldt_app_name, }, { + .name = nxt_string("forwarded"), + .type = NXT_CONF_VLDT_OBJECT, + .validator = nxt_conf_vldt_forwarded, + }, { .name = nxt_string("client_ip"), .type = NXT_CONF_VLDT_OBJECT, .validator = nxt_conf_vldt_object, @@ -385,6 +396,27 @@ static nxt_conf_vldt_object_t nxt_conf_vldt_listener_members[] = { }; +static nxt_conf_vldt_object_t nxt_conf_vldt_forwarded_members[] = { + { + .name = nxt_string("client_ip"), + .type = NXT_CONF_VLDT_STRING, + }, { + .name = nxt_string("protocol"), + .type = NXT_CONF_VLDT_STRING, + }, { + .name = nxt_string("source"), + .type = NXT_CONF_VLDT_STRING | NXT_CONF_VLDT_ARRAY, + .validator = nxt_conf_vldt_match_addrs, + .flags = NXT_CONF_VLDT_REQUIRED + }, { + .name = nxt_string("recursive"), + .type = NXT_CONF_VLDT_BOOLEAN, + }, + + NXT_CONF_VLDT_END +}; + + static nxt_conf_vldt_object_t nxt_conf_vldt_client_ip_members[] = { { .name = nxt_string("source"), @@ -1177,11 +1209,29 @@ static nxt_conf_vldt_object_t nxt_conf_vldt_upstream_server_members[] = { }; +static nxt_conf_vldt_object_t nxt_conf_vldt_access_log_members[] = { + { + .name = nxt_string("path"), + .type = NXT_CONF_VLDT_STRING, + }, { + .name = nxt_string("format"), + .type = NXT_CONF_VLDT_STRING, + }, + + NXT_CONF_VLDT_END +}; + + nxt_int_t nxt_conf_validate(nxt_conf_validation_t *vldt) { nxt_int_t ret; + vldt->var_fields = nxt_array_create(vldt->pool, 4, sizeof(nxt_var_field_t)); + if (nxt_slow_path(vldt->var_fields == NULL)) { + return NXT_ERROR; + } + ret = nxt_conf_vldt_type(vldt, NULL, vldt->conf, NXT_CONF_VLDT_OBJECT); if (ret != NXT_OK) { return ret; @@ -1314,7 +1364,7 @@ nxt_conf_vldt_var(nxt_conf_validation_t *vldt, nxt_str_t *name, { u_char error[NXT_MAX_ERROR_STR]; - if (nxt_var_test(value, error) != NXT_OK) { + if (nxt_var_test(value, vldt->var_fields, error) != NXT_OK) { return nxt_conf_vldt_error(vldt, "%s in the \"%V\" value.", error, name); } @@ -1430,9 +1480,14 @@ nxt_conf_vldt_listener(nxt_conf_validation_t *vldt, nxt_str_t *name, nxt_conf_value_t *value) { nxt_int_t ret; + nxt_str_t str; nxt_sockaddr_t *sa; - sa = nxt_sockaddr_parse(vldt->pool, name); + if (nxt_slow_path(nxt_str_dup(vldt->pool, &str, name) == NULL)) { + return NXT_ERROR; + } + + sa = nxt_sockaddr_parse(vldt->pool, &str); if (nxt_slow_path(sa == NULL)) { return nxt_conf_vldt_error(vldt, "The listener address \"%V\" is invalid.", @@ -2124,6 +2179,11 @@ nxt_conf_vldt_match_addr(nxt_conf_validation_t *vldt, return nxt_conf_vldt_error(vldt, "The \"address\" does not support " "IPv6 with your configuration."); + case NXT_ADDR_PATTERN_NO_UNIX_ERROR: + return nxt_conf_vldt_error(vldt, "The \"address\" does not support " + "UNIX domain sockets with your " + "configuration."); + default: return nxt_conf_vldt_error(vldt, "The \"address\" has an unknown " "format."); @@ -2318,6 +2378,28 @@ error: static nxt_int_t +nxt_conf_vldt_forwarded(nxt_conf_validation_t *vldt, nxt_conf_value_t *value, + void *data) +{ + nxt_conf_value_t *client_ip, *protocol; + + static nxt_str_t client_ip_str = nxt_string("client_ip"); + static nxt_str_t protocol_str = nxt_string("protocol"); + + client_ip = nxt_conf_get_object_member(value, &client_ip_str, NULL); + protocol = nxt_conf_get_object_member(value, &protocol_str, NULL); + + if (client_ip == NULL && protocol == NULL) { + return nxt_conf_vldt_error(vldt, "The \"forwarded\" object must have " + "either \"client_ip\" or \"protocol\" " + "option set."); + } + + return nxt_conf_vldt_object(vldt, value, nxt_conf_vldt_forwarded_members); +} + + +static nxt_int_t nxt_conf_vldt_app(nxt_conf_validation_t *vldt, nxt_str_t *name, nxt_conf_value_t *value) { @@ -3030,3 +3112,65 @@ nxt_conf_vldt_server_weight(nxt_conf_validation_t *vldt, return NXT_OK; } + + +typedef struct { + nxt_str_t path; + nxt_str_t format; +} nxt_conf_vldt_access_log_conf_t; + + +static nxt_conf_map_t nxt_conf_vldt_access_log_map[] = { + { + nxt_string("path"), + NXT_CONF_MAP_STR, + offsetof(nxt_conf_vldt_access_log_conf_t, path), + }, + + { + nxt_string("format"), + NXT_CONF_MAP_STR, + offsetof(nxt_conf_vldt_access_log_conf_t, format), + }, +}; + + +static nxt_int_t +nxt_conf_vldt_access_log(nxt_conf_validation_t *vldt, nxt_conf_value_t *value, + void *data) +{ + nxt_int_t ret; + nxt_conf_vldt_access_log_conf_t conf; + + static nxt_str_t format_str = nxt_string("format"); + + if (nxt_conf_type(value) == NXT_CONF_STRING) { + return NXT_OK; + } + + ret = nxt_conf_vldt_object(vldt, value, nxt_conf_vldt_access_log_members); + if (ret != NXT_OK) { + return ret; + } + + nxt_memzero(&conf, sizeof(nxt_conf_vldt_access_log_conf_t)); + + ret = nxt_conf_map_object(vldt->pool, value, + nxt_conf_vldt_access_log_map, + nxt_nitems(nxt_conf_vldt_access_log_map), + &conf); + if (ret != NXT_OK) { + return ret; + } + + if (conf.path.length == 0) { + return nxt_conf_vldt_error(vldt, + "The \"path\" string must not be empty."); + } + + if (nxt_is_var(&conf.format)) { + return nxt_conf_vldt_var(vldt, &format_str, &conf.format); + } + + return NXT_OK; +} diff --git a/src/nxt_conn.h b/src/nxt_conn.h index a443601f..8a703e9a 100644 --- a/src/nxt_conn.h +++ b/src/nxt_conn.h @@ -160,6 +160,7 @@ struct nxt_conn_s { uint8_t block_read; /* 1 bit */ uint8_t block_write; /* 1 bit */ uint8_t delayed; /* 1 bit */ + uint8_t idle; /* 1 bit */ #define NXT_CONN_SENDFILE_OFF 0 #define NXT_CONN_SENDFILE_ON 1 @@ -294,6 +295,28 @@ NXT_EXPORT void nxt_event_conn_job_sendfile(nxt_task_t *task, } while (0) +#define nxt_conn_idle(engine, c) \ + do { \ + nxt_event_engine_t *e = engine; \ + \ + nxt_queue_insert_head(&e->idle_connections, &c->link); \ + \ + c->idle = 1; \ + e->idle_conns_cnt++; \ + } while (0) + + +#define nxt_conn_active(engine, c) \ + do { \ + nxt_event_engine_t *e = engine; \ + \ + nxt_queue_remove(&c->link); \ + \ + c->idle = 0; \ + e->idle_conns_cnt--; \ + } while (0) + + extern nxt_conn_io_t nxt_unix_conn_io; diff --git a/src/nxt_conn_accept.c b/src/nxt_conn_accept.c index 77c44c58..720c7b64 100644 --- a/src/nxt_conn_accept.c +++ b/src/nxt_conn_accept.c @@ -187,7 +187,8 @@ nxt_conn_io_accept(nxt_task_t *task, void *obj, void *data) void nxt_conn_accept(nxt_task_t *task, nxt_listen_event_t *lev, nxt_conn_t *c) { - nxt_conn_t *next; + nxt_conn_t *next; + nxt_event_engine_t *engine; nxt_sockaddr_text(c->remote); @@ -195,7 +196,11 @@ nxt_conn_accept(nxt_task_t *task, nxt_listen_event_t *lev, nxt_conn_t *c) (size_t) c->remote->address_length, nxt_sockaddr_address(c->remote)); - nxt_queue_insert_head(&task->thread->engine->idle_connections, &c->link); + engine = task->thread->engine; + + engine->accepted_conns_cnt++; + + nxt_conn_idle(engine, c); c->listen = lev; lev->count++; diff --git a/src/nxt_conn_close.c b/src/nxt_conn_close.c index 7c130309..92bd8d1b 100644 --- a/src/nxt_conn_close.c +++ b/src/nxt_conn_close.c @@ -119,6 +119,8 @@ nxt_conn_close_handler(nxt_task_t *task, void *obj, void *data) nxt_socket_close(task, c->socket.fd); c->socket.fd = -1; + engine->closed_conns_cnt++; + if (timers_pending == 0) { nxt_work_queue_add(&engine->fast_work_queue, c->write_state->ready_handler, @@ -137,8 +139,9 @@ nxt_conn_close_handler(nxt_task_t *task, void *obj, void *data) static void nxt_conn_close_timer_handler(nxt_task_t *task, void *obj, void *data) { - nxt_conn_t *c; - nxt_timer_t *timer; + nxt_conn_t *c; + nxt_timer_t *timer; + nxt_event_engine_t *engine; timer = obj; @@ -146,13 +149,16 @@ nxt_conn_close_timer_handler(nxt_task_t *task, void *obj, void *data) nxt_debug(task, "conn close timer handler fd:%d", c->socket.fd); + engine = task->thread->engine; + if (c->socket.fd != -1) { nxt_socket_close(task, c->socket.fd); c->socket.fd = -1; + + engine->closed_conns_cnt++; } - nxt_work_queue_add(&task->thread->engine->fast_work_queue, - c->write_state->ready_handler, + nxt_work_queue_add(&engine->fast_work_queue, c->write_state->ready_handler, task, c, c->socket.data); } diff --git a/src/nxt_controller.c b/src/nxt_controller.c index 7510d6f0..09168821 100644 --- a/src/nxt_controller.c +++ b/src/nxt_controller.c @@ -9,6 +9,7 @@ #include <nxt_runtime.h> #include <nxt_main_process.h> #include <nxt_conf.h> +#include <nxt_status.h> #include <nxt_cert.h> @@ -85,6 +86,12 @@ static void nxt_controller_process_request(nxt_task_t *task, static void nxt_controller_process_config(nxt_task_t *task, nxt_controller_request_t *req, nxt_str_t *path); static nxt_bool_t nxt_controller_check_postpone_request(nxt_task_t *task); +static void nxt_controller_process_status(nxt_task_t *task, + nxt_controller_request_t *req); +static void nxt_controller_status_handler(nxt_task_t *task, + nxt_port_recv_msg_t *msg, void *data); +static void nxt_controller_status_response(nxt_task_t *task, + nxt_controller_request_t *req, nxt_str_t *path); #if (NXT_TLS) static void nxt_controller_process_cert(nxt_task_t *task, nxt_controller_request_t *req, nxt_str_t *path); @@ -120,6 +127,7 @@ static nxt_uint_t nxt_controller_router_ready; static nxt_controller_conf_t nxt_controller_conf; static nxt_queue_t nxt_controller_waiting_requests; static nxt_bool_t nxt_controller_waiting_init_conf; +static nxt_conf_value_t *nxt_controller_status; static const nxt_event_conn_state_t nxt_controller_conn_read_state; @@ -725,7 +733,7 @@ static const nxt_event_conn_state_t nxt_controller_conn_read_state .timer_handler = nxt_controller_conn_read_timeout, .timer_value = nxt_controller_conn_timeout_value, - .timer_data = 60 * 1000, + .timer_data = 300 * 1000, }; @@ -1035,6 +1043,7 @@ nxt_controller_process_request(nxt_task_t *task, nxt_controller_request_t *req) static nxt_str_t certificates = nxt_string("certificates"); #endif static nxt_str_t config = nxt_string("config"); + static nxt_str_t status = nxt_string("status"); c = req->conn; path = req->parser.path; @@ -1058,6 +1067,32 @@ nxt_controller_process_request(nxt_task_t *task, nxt_controller_request_t *req) return; } + nxt_memzero(&resp, sizeof(nxt_controller_response_t)); + + if (nxt_str_start(&path, "/status", 7) + && (path.length == 7 || path.start[7] == '/')) + { + if (!nxt_str_eq(&req->parser.method, "GET", 3)) { + goto invalid_method; + } + + if (nxt_controller_status == NULL) { + nxt_controller_process_status(task, req); + return; + } + + if (path.length == 7) { + path.length = 1; + + } else { + path.length -= 7; + path.start += 7; + } + + nxt_controller_status_response(task, req, &path); + return; + } + #if (NXT_TLS) if (nxt_str_start(&path, "/certificates", 13) @@ -1085,15 +1120,18 @@ nxt_controller_process_request(nxt_task_t *task, nxt_controller_request_t *req) return; } - nxt_memzero(&resp, sizeof(nxt_controller_response_t)); - if (path.length == 1 && path.start[0] == '/') { if (!nxt_str_eq(&req->parser.method, "GET", 3)) { goto invalid_method; } - count = 1; + if (nxt_controller_status == NULL) { + nxt_controller_process_status(task, req); + return; + } + + count = 2; #if (NXT_TLS) count++; #endif @@ -1114,7 +1152,8 @@ nxt_controller_process_request(nxt_task_t *task, nxt_controller_request_t *req) nxt_conf_set_member(value, &certificates, certs, i++); #endif - nxt_conf_set_member(value, &config, nxt_controller_conf.root, i); + nxt_conf_set_member(value, &config, nxt_controller_conf.root, i++); + nxt_conf_set_member(value, &status, nxt_controller_status, i); resp.status = 200; resp.conf = value; @@ -1451,6 +1490,128 @@ nxt_controller_check_postpone_request(nxt_task_t *task) } +static void +nxt_controller_process_status(nxt_task_t *task, nxt_controller_request_t *req) +{ + uint32_t stream; + nxt_int_t rc; + nxt_port_t *router_port, *controller_port; + nxt_runtime_t *rt; + nxt_controller_response_t resp; + + if (nxt_controller_check_postpone_request(task)) { + nxt_queue_insert_tail(&nxt_controller_waiting_requests, &req->link); + return; + } + + rt = task->thread->runtime; + + router_port = rt->port_by_type[NXT_PROCESS_ROUTER]; + + nxt_assert(router_port != NULL); + nxt_assert(nxt_controller_router_ready); + + controller_port = rt->port_by_type[NXT_PROCESS_CONTROLLER]; + + stream = nxt_port_rpc_register_handler(task, controller_port, + nxt_controller_status_handler, + nxt_controller_status_handler, + router_port->pid, req); + if (nxt_slow_path(stream == 0)) { + goto fail; + } + + rc = nxt_port_socket_write(task, router_port, NXT_PORT_MSG_STATUS, + -1, stream, controller_port->id, NULL); + + if (nxt_slow_path(rc != NXT_OK)) { + nxt_port_rpc_cancel(task, controller_port, stream); + + goto fail; + } + + nxt_queue_insert_head(&nxt_controller_waiting_requests, &req->link); + return; + +fail: + + nxt_memzero(&resp, sizeof(nxt_controller_response_t)); + + resp.status = 500; + resp.title = (u_char *) "Failed to get status."; + resp.offset = -1; + + nxt_controller_response(task, req, &resp); + return; +} + + +static void +nxt_controller_status_handler(nxt_task_t *task, nxt_port_recv_msg_t *msg, + void *data) +{ + nxt_conf_value_t *status; + nxt_controller_request_t *req; + nxt_controller_response_t resp; + + nxt_debug(task, "controller status handler"); + + req = data; + + if (msg->port_msg.type == NXT_PORT_MSG_RPC_READY) { + status = nxt_status_get((nxt_status_report_t *) msg->buf->mem.pos, + req->conn->mem_pool); + } else { + status = NULL; + } + + if (status == NULL) { + nxt_queue_remove(&req->link); + + nxt_memzero(&resp, sizeof(nxt_controller_response_t)); + + resp.status = 500; + resp.title = (u_char *) "Failed to get status."; + resp.offset = -1; + + nxt_controller_response(task, req, &resp); + } + + nxt_controller_status = status; + + nxt_controller_flush_requests(task); + + nxt_controller_status = NULL; +} + + +static void +nxt_controller_status_response(nxt_task_t *task, nxt_controller_request_t *req, + nxt_str_t *path) +{ + nxt_conf_value_t *status; + nxt_controller_response_t resp; + + status = nxt_conf_get_path(nxt_controller_status, path); + + nxt_memzero(&resp, sizeof(nxt_controller_response_t)); + + if (status == NULL) { + resp.status = 404; + resp.title = (u_char *) "Invalid path."; + resp.offset = -1; + + nxt_controller_response(task, req, &resp); + return; + } + + resp.status = 200; + resp.conf = status; + + nxt_controller_response(task, req, &resp); +} + + #if (NXT_TLS) static void diff --git a/src/nxt_event_engine.h b/src/nxt_event_engine.h index 91cfc0aa..291ea749 100644 --- a/src/nxt_event_engine.h +++ b/src/nxt_event_engine.h @@ -483,6 +483,11 @@ struct nxt_event_engine_s { nxt_queue_t idle_connections; nxt_array_t *mem_cache; + nxt_atomic_uint_t accepted_conns_cnt; + nxt_atomic_uint_t idle_conns_cnt; + nxt_atomic_uint_t closed_conns_cnt; + nxt_atomic_uint_t requests_cnt; + nxt_queue_link_t link; // STUB: router link nxt_queue_link_t link0; diff --git a/src/nxt_h1proto.c b/src/nxt_h1proto.c index d3340774..852b4866 100644 --- a/src/nxt_h1proto.c +++ b/src/nxt_h1proto.c @@ -478,7 +478,7 @@ nxt_h1p_conn_request_init(nxt_task_t *task, void *obj, void *data) nxt_debug(task, "h1p conn request init"); - nxt_queue_remove(&c->link); + nxt_conn_active(task->thread->engine, c); r = nxt_http_request_create(task); @@ -490,7 +490,7 @@ nxt_h1p_conn_request_init(nxt_task_t *task, void *obj, void *data) r->remote = c->remote; #if (NXT_TLS) - r->tls = c->u.tls; + r->tls = (c->u.tls != NULL); #endif r->task = c->task; @@ -1739,7 +1739,7 @@ nxt_h1p_conn_close(nxt_task_t *task, void *obj, void *data) nxt_debug(task, "h1p conn close"); - nxt_queue_remove(&c->link); + nxt_conn_active(task->thread->engine, c); nxt_h1p_shutdown(task, c); } @@ -1754,7 +1754,7 @@ nxt_h1p_conn_error(nxt_task_t *task, void *obj, void *data) nxt_debug(task, "h1p conn error"); - nxt_queue_remove(&c->link); + nxt_conn_active(task->thread->engine, c); nxt_h1p_shutdown(task, c); } @@ -1801,7 +1801,8 @@ nxt_h1p_keepalive(nxt_task_t *task, nxt_h1proto_t *h1p, nxt_conn_t *c) c->sent = 0; engine = task->thread->engine; - nxt_queue_insert_head(&engine->idle_connections, &c->link); + + nxt_conn_idle(engine, c); if (in == NULL) { c->read_state = &nxt_h1p_keepalive_state; @@ -1855,7 +1856,7 @@ nxt_h1p_idle_close(nxt_task_t *task, void *obj, void *data) nxt_debug(task, "h1p idle close"); - nxt_queue_remove(&c->link); + nxt_conn_active(task->thread->engine, c); nxt_h1p_idle_response(task, c); } @@ -1874,7 +1875,7 @@ nxt_h1p_idle_timeout(nxt_task_t *task, void *obj, void *data) c = nxt_read_timer_conn(timer); c->block_read = 1; - nxt_queue_remove(&c->link); + nxt_conn_active(task->thread->engine, c); nxt_h1p_idle_response(task, c); } diff --git a/src/nxt_http.h b/src/nxt_http.h index d299fdd4..c2e85840 100644 --- a/src/nxt_http.h +++ b/src/nxt_http.h @@ -162,7 +162,6 @@ struct nxt_http_request_s { nxt_sockaddr_t *remote; nxt_sockaddr_t *local; - void *tls; nxt_task_t task; nxt_timer_t timer; @@ -190,6 +189,7 @@ struct nxt_http_request_s { uint8_t pass_count; /* 8 bits */ uint8_t app_target; nxt_http_protocol_t protocol:8; /* 2 bits */ + uint8_t tls; /* 1 bit */ uint8_t logged; /* 1 bit */ uint8_t header_sent; /* 1 bit */ uint8_t inconsistent; /* 1 bit */ @@ -207,6 +207,13 @@ typedef struct { } nxt_http_name_value_t; +typedef enum { + NXT_HTTP_URI_ENCODING_NONE = 0, + NXT_HTTP_URI_ENCODING, + NXT_HTTP_URI_ENCODING_PLUS +} nxt_http_uri_encoding_t; + + typedef struct nxt_http_route_s nxt_http_route_t; typedef struct nxt_http_route_rule_s nxt_http_route_rule_t; typedef struct nxt_http_route_addr_rule_s nxt_http_route_addr_rule_t; @@ -266,10 +273,16 @@ typedef struct { } nxt_http_proto_table_t; -struct nxt_http_client_ip_s { - nxt_http_route_addr_rule_t *source; +typedef struct { nxt_str_t *header; uint32_t header_hash; +} nxt_http_forward_header_t; + + +struct nxt_http_forward_s { + nxt_http_forward_header_t client_ip; + nxt_http_forward_header_t protocol; + nxt_http_route_addr_rule_t *source; uint8_t recursive; /* 1 bit */ }; @@ -324,6 +337,12 @@ nxt_int_t nxt_http_request_content_length(void *ctx, nxt_http_field_t *field, nxt_array_t *nxt_http_arguments_parse(nxt_http_request_t *r); nxt_array_t *nxt_http_cookies_parse(nxt_http_request_t *r); +int64_t nxt_http_field_hash(nxt_mp_t *mp, nxt_str_t *name, + nxt_bool_t case_sensitive, uint8_t encoding); +int64_t nxt_http_argument_hash(nxt_mp_t *mp, nxt_str_t *name); +int64_t nxt_http_header_hash(nxt_mp_t *mp, nxt_str_t *name); +int64_t nxt_http_cookie_hash(nxt_mp_t *mp, nxt_str_t *name); + nxt_http_routes_t *nxt_http_routes_create(nxt_task_t *task, nxt_router_temp_conf_t *tmcf, nxt_conf_value_t *routes_conf); nxt_http_action_t *nxt_http_action_create(nxt_task_t *task, @@ -353,15 +372,16 @@ nxt_int_t nxt_upstreams_create(nxt_task_t *task, nxt_router_temp_conf_t *tmcf, nxt_int_t nxt_upstreams_joint_create(nxt_router_temp_conf_t *tmcf, nxt_upstream_t ***upstream_joint); -nxt_int_t nxt_http_return_init(nxt_mp_t *mp, nxt_http_action_t *action, - nxt_http_action_conf_t *acf); +nxt_int_t nxt_http_return_init(nxt_router_conf_t *rtcf, + nxt_http_action_t *action, nxt_http_action_conf_t *acf); nxt_int_t nxt_http_static_init(nxt_task_t *task, nxt_router_temp_conf_t *tmcf, nxt_http_action_t *action, nxt_http_action_conf_t *acf); nxt_int_t nxt_http_static_mtypes_init(nxt_mp_t *mp, nxt_lvlhsh_t *hash); nxt_int_t nxt_http_static_mtypes_hash_add(nxt_mp_t *mp, nxt_lvlhsh_t *hash, - nxt_str_t *exten, nxt_str_t *type); -nxt_str_t *nxt_http_static_mtype_get(nxt_lvlhsh_t *hash, nxt_str_t *exten); + const nxt_str_t *exten, nxt_str_t *type); +nxt_str_t *nxt_http_static_mtype_get(nxt_lvlhsh_t *hash, + const nxt_str_t *exten); nxt_http_action_t *nxt_http_application_handler(nxt_task_t *task, nxt_http_request_t *r, nxt_http_action_t *action); diff --git a/src/nxt_http_parse.c b/src/nxt_http_parse.c index 1ab6cc90..1bb4291f 100644 --- a/src/nxt_http_parse.c +++ b/src/nxt_http_parse.c @@ -8,16 +8,16 @@ static nxt_int_t nxt_http_parse_unusual_target(nxt_http_request_parse_t *rp, - u_char **pos, u_char *end); + u_char **pos, const u_char *end); static nxt_int_t nxt_http_parse_request_line(nxt_http_request_parse_t *rp, - u_char **pos, u_char *end); + u_char **pos, const u_char *end); static nxt_int_t nxt_http_parse_field_name(nxt_http_request_parse_t *rp, - u_char **pos, u_char *end); + u_char **pos, const u_char *end); static nxt_int_t nxt_http_parse_field_value(nxt_http_request_parse_t *rp, - u_char **pos, u_char *end); -static u_char *nxt_http_lookup_field_end(u_char *p, u_char *end); + u_char **pos, const u_char *end); +static u_char *nxt_http_lookup_field_end(u_char *p, const u_char *end); static nxt_int_t nxt_http_parse_field_end(nxt_http_request_parse_t *rp, - u_char **pos, u_char *end); + u_char **pos, const u_char *end); static nxt_int_t nxt_http_parse_complex_target(nxt_http_request_parse_t *rp); @@ -62,7 +62,7 @@ static const uint8_t nxt_http_target_chars[256] nxt_aligned(64) = { nxt_inline nxt_http_target_traps_e -nxt_http_parse_target(u_char **pos, u_char *end) +nxt_http_parse_target(u_char **pos, const u_char *end) { u_char *p; nxt_uint_t trap; @@ -158,7 +158,7 @@ nxt_http_parse_fields(nxt_http_request_parse_t *rp, nxt_buf_mem_t *b) static nxt_int_t nxt_http_parse_request_line(nxt_http_request_parse_t *rp, u_char **pos, - u_char *end) + const u_char *end) { u_char *p, ch, *after_slash, *args; nxt_int_t rc; @@ -479,7 +479,7 @@ space_after_target: static nxt_int_t nxt_http_parse_unusual_target(nxt_http_request_parse_t *rp, u_char **pos, - u_char *end) + const u_char *end) { u_char *p, ch; @@ -517,7 +517,7 @@ nxt_http_parse_unusual_target(nxt_http_request_parse_t *rp, u_char **pos, static nxt_int_t nxt_http_parse_field_name(nxt_http_request_parse_t *rp, u_char **pos, - u_char *end) + const u_char *end) { u_char *p, c; size_t len; @@ -624,7 +624,7 @@ name_end: static nxt_int_t nxt_http_parse_field_value(nxt_http_request_parse_t *rp, u_char **pos, - u_char *end) + const u_char *end) { u_char *p, *start, ch; size_t len; @@ -704,7 +704,7 @@ nxt_http_parse_field_value(nxt_http_request_parse_t *rp, u_char **pos, static u_char * -nxt_http_lookup_field_end(u_char *p, u_char *end) +nxt_http_lookup_field_end(u_char *p, const u_char *end) { while (nxt_fast_path(end - p >= 16)) { @@ -771,7 +771,7 @@ nxt_http_lookup_field_end(u_char *p, u_char *end) static nxt_int_t nxt_http_parse_field_end(nxt_http_request_parse_t *rp, u_char **pos, - u_char *end) + const u_char *end) { u_char *p; nxt_http_field_t *field; diff --git a/src/nxt_http_parse.h b/src/nxt_http_parse.h index 3cd9bd15..2b714464 100644 --- a/src/nxt_http_parse.h +++ b/src/nxt_http_parse.h @@ -35,7 +35,7 @@ typedef union { struct nxt_http_request_parse_s { nxt_int_t (*handler)(nxt_http_request_parse_t *rp, - u_char **pos, u_char *end); + u_char **pos, const u_char *end); nxt_str_t method; diff --git a/src/nxt_http_request.c b/src/nxt_http_request.c index 04a6f7f3..943ad82d 100644 --- a/src/nxt_http_request.c +++ b/src/nxt_http_request.c @@ -10,10 +10,14 @@ static nxt_int_t nxt_http_validate_host(nxt_str_t *host, nxt_mp_t *mp); static void nxt_http_request_start(nxt_task_t *task, void *obj, void *data); -static nxt_int_t nxt_http_request_client_ip(nxt_task_t *task, - nxt_http_request_t *r); +static nxt_int_t nxt_http_request_forward(nxt_task_t *task, + nxt_http_request_t *r, nxt_http_forward_t *forward); +static void nxt_http_request_forward_client_ip(nxt_http_request_t *r, + nxt_http_forward_t *forward, nxt_array_t *fields); static nxt_sockaddr_t *nxt_http_request_client_ip_sockaddr( nxt_http_request_t *r, u_char *start, size_t len); +static void nxt_http_request_forward_protocol(nxt_http_request_t *r, + nxt_http_field_t *field); static void nxt_http_request_ready(nxt_task_t *task, void *obj, void *data); static void nxt_http_request_proto_info(nxt_task_t *task, nxt_http_request_t *r); @@ -26,11 +30,11 @@ static u_char *nxt_http_date_cache_handler(u_char *buf, nxt_realtime_t *now, static nxt_http_name_value_t *nxt_http_argument(nxt_array_t *array, u_char *name, size_t name_length, uint32_t hash, u_char *start, - u_char *end); + const u_char *end); static nxt_int_t nxt_http_cookie_parse(nxt_array_t *cookies, u_char *start, - u_char *end); + const u_char *end); static nxt_http_name_value_t *nxt_http_cookie(nxt_array_t *array, u_char *name, - size_t name_length, u_char *start, u_char *end); + size_t name_length, u_char *start, const u_char *end); #define NXT_HTTP_COOKIE_HASH \ @@ -274,6 +278,8 @@ nxt_http_request_create(nxt_task_t *task) r->resp.content_length_n = -1; r->state = &nxt_http_request_init_state; + task->thread->engine->requests_cnt++; + return r; fail: @@ -296,74 +302,125 @@ static void nxt_http_request_start(nxt_task_t *task, void *obj, void *data) { nxt_int_t ret; + nxt_socket_conf_t *skcf; nxt_http_request_t *r; r = obj; r->state = &nxt_http_request_body_state; - ret = nxt_http_request_client_ip(task, r); - if (nxt_slow_path(ret != NXT_OK)) { - nxt_http_request_error(task, r, NXT_HTTP_INTERNAL_SERVER_ERROR); + skcf = r->conf->socket_conf; + + if (skcf->forwarded != NULL) { + ret = nxt_http_request_forward(task, r, skcf->forwarded); + if (nxt_slow_path(ret != NXT_OK)) { + goto fail; + } + } + + if (skcf->client_ip != NULL) { + ret = nxt_http_request_forward(task, r, skcf->client_ip); + if (nxt_slow_path(ret != NXT_OK)) { + goto fail; + } } nxt_http_request_read_body(task, r); + + return; + +fail: + nxt_http_request_error(task, r, NXT_HTTP_INTERNAL_SERVER_ERROR); } static nxt_int_t -nxt_http_request_client_ip(nxt_task_t *task, nxt_http_request_t *r) +nxt_http_request_forward(nxt_task_t *task, nxt_http_request_t *r, + nxt_http_forward_t *forward) { - u_char *start, *p; - nxt_int_t ret, i, len; - nxt_str_t *header; - nxt_array_t *fields_arr; /* of nxt_http_field_t * */ - nxt_sockaddr_t *sa, *prev_sa; - nxt_http_field_t *f, **fields; - nxt_http_client_ip_t *client_ip; + nxt_int_t ret; + nxt_array_t *client_ip_fields; + nxt_http_field_t *f, **fields, *protocol_field; + nxt_http_forward_header_t *client_ip, *protocol; - client_ip = r->conf->socket_conf->client_ip; - - if (client_ip == NULL) { - return NXT_OK; - } - - ret = nxt_http_route_addr_rule(r, client_ip->source, r->remote); + ret = nxt_http_route_addr_rule(r, forward->source, r->remote); if (ret <= 0) { return NXT_OK; } - header = client_ip->header; + client_ip = &forward->client_ip; + protocol = &forward->protocol; + + if (client_ip->header != NULL) { + client_ip_fields = nxt_array_create(r->mem_pool, 1, + sizeof(nxt_http_field_t *)); + if (nxt_slow_path(client_ip_fields == NULL)) { + return NXT_ERROR; + } - fields_arr = nxt_array_create(r->mem_pool, 2, sizeof(nxt_http_field_t *)); - if (nxt_slow_path(fields_arr == NULL)) { - return NXT_ERROR; + } else { + client_ip_fields = NULL; } + protocol_field = NULL; + nxt_list_each(f, r->fields) { - if (f->hash == client_ip->header_hash - && f->name_length == client_ip->header->length + if (client_ip_fields != NULL + && f->hash == client_ip->header_hash && f->value_length > 0 - && nxt_memcasecmp(f->name, header->start, header->length) == 0) + && f->name_length == client_ip->header->length + && nxt_memcasecmp(f->name, client_ip->header->start, + client_ip->header->length) == 0) { - fields = nxt_array_add(fields_arr); + fields = nxt_array_add(client_ip_fields); if (nxt_slow_path(fields == NULL)) { return NXT_ERROR; } *fields = f; } + + if (protocol->header != NULL + && protocol_field == NULL + && f->hash == protocol->header_hash + && f->value_length > 0 + && f->name_length == protocol->header->length + && nxt_memcasecmp(f->name, protocol->header->start, + protocol->header->length) == 0) + { + protocol_field = f; + } } nxt_list_loop; + if (client_ip_fields != NULL) { + nxt_http_request_forward_client_ip(r, forward, client_ip_fields); + } + + if (protocol_field != NULL) { + nxt_http_request_forward_protocol(r, protocol_field); + } + + return NXT_OK; +} + + +static void +nxt_http_request_forward_client_ip(nxt_http_request_t *r, + nxt_http_forward_t *forward, nxt_array_t *fields) +{ + u_char *start, *p; + nxt_int_t ret, i, len; + nxt_sockaddr_t *sa, *prev_sa; + nxt_http_field_t **f; + prev_sa = r->remote; - fields = (nxt_http_field_t **) fields_arr->elts; + f = (nxt_http_field_t **) fields->elts; - i = fields_arr->nelts; + i = fields->nelts; while (i-- > 0) { - f = fields[i]; - start = f->value; - len = f->value_length; + start = f[i]->value; + len = f[i]->value_length; do { for (p = start + len - 1; p > start; p--, len--) { @@ -385,20 +442,18 @@ nxt_http_request_client_ip(nxt_task_t *task, nxt_http_request_t *r) r->remote = prev_sa; } - return NXT_OK; + return; } - if (!client_ip->recursive) { + if (!forward->recursive) { r->remote = sa; - - return NXT_OK; + return; } - ret = nxt_http_route_addr_rule(r, client_ip->source, sa); + ret = nxt_http_route_addr_rule(r, forward->source, sa); if (ret <= 0 || (i == 0 && p == start)) { r->remote = sa; - - return NXT_OK; + return; } prev_sa = sa; @@ -406,8 +461,6 @@ nxt_http_request_client_ip(nxt_task_t *task, nxt_http_request_t *r) } while (len > 0); } - - return NXT_OK; } @@ -451,6 +504,28 @@ nxt_http_request_client_ip_sockaddr(nxt_http_request_t *r, u_char *start, } +static void +nxt_http_request_forward_protocol(nxt_http_request_t *r, + nxt_http_field_t *field) +{ + if (field->value_length == 4) { + if (nxt_memcasecmp(field->value, "http", 4) == 0) { + r->tls = 0; + } + + } else if (field->value_length == 5) { + if (nxt_memcasecmp(field->value, "https", 5) == 0) { + r->tls = 1; + } + + } else if (field->value_length == 2) { + if (nxt_memcasecmp(field->value, "on", 2) == 0) { + r->tls = 1; + } + } +} + + static const nxt_http_request_state_t nxt_http_request_body_state nxt_aligned(64) = { @@ -718,6 +793,7 @@ nxt_http_request_error_handler(nxt_task_t *task, void *obj, void *data) void nxt_http_request_close_handler(nxt_task_t *task, void *obj, void *data) { + nxt_var_t *log_format; nxt_http_proto_t proto; nxt_http_request_t *r; nxt_http_protocol_t protocol; @@ -727,20 +803,22 @@ nxt_http_request_close_handler(nxt_task_t *task, void *obj, void *data) r = obj; proto.any = data; - nxt_debug(task, "http request close handler"); - conf = r->conf; if (!r->logged) { r->logged = 1; access_log = conf->socket_conf->router_conf->access_log; + log_format = conf->socket_conf->router_conf->log_format; if (access_log != NULL) { - access_log->handler(task, r, access_log); + access_log->handler(task, r, access_log, log_format); + return; } } + nxt_debug(task, "http request close handler"); + r->proto.any = NULL; if (r->body != NULL && nxt_buf_is_file(r->body) @@ -876,7 +954,7 @@ nxt_http_arguments_parse(nxt_http_request_t *r) static nxt_http_name_value_t * nxt_http_argument(nxt_array_t *array, u_char *name, size_t name_length, - uint32_t hash, u_char *start, u_char *end) + uint32_t hash, u_char *start, const u_char *end) { size_t length; nxt_http_name_value_t *nv; @@ -945,7 +1023,7 @@ nxt_http_cookies_parse(nxt_http_request_t *r) static nxt_int_t -nxt_http_cookie_parse(nxt_array_t *cookies, u_char *start, u_char *end) +nxt_http_cookie_parse(nxt_array_t *cookies, u_char *start, const u_char *end) { size_t name_length; u_char c, *p, *name; @@ -994,7 +1072,7 @@ nxt_http_cookie_parse(nxt_array_t *cookies, u_char *start, u_char *end) static nxt_http_name_value_t * nxt_http_cookie(nxt_array_t *array, u_char *name, size_t name_length, - u_char *start, u_char *end) + u_char *start, const u_char *end) { u_char c, *p; uint32_t hash; @@ -1024,3 +1102,140 @@ nxt_http_cookie(nxt_array_t *array, u_char *name, size_t name_length, return nv; } + + +int64_t +nxt_http_field_hash(nxt_mp_t *mp, nxt_str_t *name, nxt_bool_t case_sensitive, + uint8_t encoding) +{ + u_char c, *p, *src, *start, *end, plus; + uint8_t d0, d1; + uint32_t hash; + nxt_str_t str; + nxt_uint_t i; + + str.length = name->length; + + str.start = nxt_mp_nget(mp, str.length); + if (nxt_slow_path(str.start == NULL)) { + return -1; + } + + p = str.start; + + hash = NXT_HTTP_FIELD_HASH_INIT; + + if (encoding == NXT_HTTP_URI_ENCODING_NONE) { + for (i = 0; i < name->length; i++) { + c = name->start[i]; + *p++ = c; + + c = case_sensitive ? c : nxt_lowcase(c); + hash = nxt_http_field_hash_char(hash, c); + } + + goto end; + } + + plus = (encoding == NXT_HTTP_URI_ENCODING_PLUS) ? ' ' : '+'; + + start = name->start; + end = start + name->length; + + for (src = start; src < end; src++) { + c = *src; + + switch (c) { + case '%': + if (nxt_slow_path(end - src <= 2)) { + return -1; + } + + d0 = nxt_hex2int[src[1]]; + d1 = nxt_hex2int[src[2]]; + src += 2; + + if (nxt_slow_path((d0 | d1) >= 16)) { + return -1; + } + + c = (d0 << 4) + d1; + *p++ = c; + break; + + case '+': + c = plus; + *p++ = c; + break; + + default: + *p++ = c; + break; + } + + c = case_sensitive ? c : nxt_lowcase(c); + hash = nxt_http_field_hash_char(hash, c); + } + + str.length = p - str.start; + +end: + + *name = str; + + return nxt_http_field_hash_end(hash) & 0xFFFF; +} + + +int64_t +nxt_http_argument_hash(nxt_mp_t *mp, nxt_str_t *name) +{ + return nxt_http_field_hash(mp, name, 1, NXT_HTTP_URI_ENCODING_PLUS); +} + + +int64_t +nxt_http_header_hash(nxt_mp_t *mp, nxt_str_t *name) +{ + u_char c, *p; + uint32_t i, hash; + nxt_str_t str; + + str.length = name->length; + + str.start = nxt_mp_nget(mp, str.length); + if (nxt_slow_path(str.start == NULL)) { + return -1; + } + + p = str.start; + hash = NXT_HTTP_FIELD_HASH_INIT; + + for (i = 0; i < name->length; i++) { + c = name->start[i]; + + if (c >= 'A' && c <= 'Z') { + *p = c | 0x20; + + } else if (c == '_') { + *p = '-'; + + } else { + *p = c; + } + + hash = nxt_http_field_hash_char(hash, *p); + p++; + } + + *name = str; + + return nxt_http_field_hash_end(hash) & 0xFFFF; +} + + +int64_t +nxt_http_cookie_hash(nxt_mp_t *mp, nxt_str_t *name) +{ + return nxt_http_field_hash(mp, name, 1, NXT_HTTP_URI_ENCODING_NONE); +} diff --git a/src/nxt_http_return.c b/src/nxt_http_return.c index 82c91568..9f3c4fc5 100644 --- a/src/nxt_http_return.c +++ b/src/nxt_http_return.c @@ -32,12 +32,15 @@ static const nxt_http_request_state_t nxt_http_return_send_state; nxt_int_t -nxt_http_return_init(nxt_mp_t *mp, nxt_http_action_t *action, +nxt_http_return_init(nxt_router_conf_t *rtcf, nxt_http_action_t *action, nxt_http_action_conf_t *acf) { + nxt_mp_t *mp; nxt_str_t str; nxt_http_return_conf_t *conf; + mp = rtcf->mem_pool; + conf = nxt_mp_zget(mp, sizeof(nxt_http_return_conf_t)); if (nxt_slow_path(conf == NULL)) { return NXT_ERROR; @@ -54,7 +57,7 @@ nxt_http_return_init(nxt_mp_t *mp, nxt_http_action_t *action, nxt_conf_get_string(acf->location, &str); - conf->location = nxt_var_compile(&str, mp, 0); + conf->location = nxt_var_compile(&str, mp, rtcf->var_fields, 0); if (nxt_slow_path(conf->location == NULL)) { return NXT_ERROR; } diff --git a/src/nxt_http_route.c b/src/nxt_http_route.c index 9200dc52..cdc9077f 100644 --- a/src/nxt_http_route.c +++ b/src/nxt_http_route.c @@ -40,13 +40,6 @@ typedef enum { } nxt_http_route_pattern_case_t; -typedef enum { - NXT_HTTP_ROUTE_ENCODING_NONE = 0, - NXT_HTTP_ROUTE_ENCODING_URI, - NXT_HTTP_ROUTE_ENCODING_URI_PLUS -} nxt_http_route_encoding_t; - - typedef struct { nxt_conf_value_t *host; nxt_conf_value_t *uri; @@ -169,29 +162,29 @@ static nxt_http_route_match_t *nxt_http_route_match_create(nxt_task_t *task, nxt_router_temp_conf_t *tmcf, nxt_conf_value_t *cv); static nxt_http_route_table_t *nxt_http_route_table_create(nxt_task_t *task, nxt_mp_t *mp, nxt_conf_value_t *table_cv, nxt_http_route_object_t object, - nxt_bool_t case_sensitive, nxt_http_route_encoding_t encoding); + nxt_bool_t case_sensitive, nxt_http_uri_encoding_t encoding); static nxt_http_route_ruleset_t *nxt_http_route_ruleset_create(nxt_task_t *task, nxt_mp_t *mp, nxt_conf_value_t *ruleset_cv, nxt_http_route_object_t object, - nxt_bool_t case_sensitive, nxt_http_route_encoding_t encoding); + nxt_bool_t case_sensitive, nxt_http_uri_encoding_t encoding); static nxt_http_route_rule_t *nxt_http_route_rule_name_create(nxt_task_t *task, nxt_mp_t *mp, nxt_conf_value_t *rule_cv, nxt_str_t *name, - nxt_bool_t case_sensitive, nxt_http_route_encoding_t encoding); + nxt_bool_t case_sensitive, nxt_http_uri_encoding_t encoding); static nxt_http_route_rule_t *nxt_http_route_rule_create(nxt_task_t *task, nxt_mp_t *mp, nxt_conf_value_t *cv, nxt_bool_t case_sensitive, nxt_http_route_pattern_case_t pattern_case, - nxt_http_route_encoding_t encoding); + nxt_http_uri_encoding_t encoding); static int nxt_http_pattern_compare(const void *one, const void *two); static int nxt_http_addr_pattern_compare(const void *one, const void *two); static nxt_int_t nxt_http_route_pattern_create(nxt_task_t *task, nxt_mp_t *mp, nxt_conf_value_t *cv, nxt_http_route_pattern_t *pattern, nxt_http_route_pattern_case_t pattern_case, - nxt_http_route_encoding_t encoding); + nxt_http_uri_encoding_t encoding); static nxt_int_t nxt_http_route_decode_str(nxt_str_t *str, - nxt_http_route_encoding_t encoding); + nxt_http_uri_encoding_t encoding); static nxt_int_t nxt_http_route_pattern_slice(nxt_array_t *slices, nxt_str_t *test, nxt_http_route_pattern_type_t type, - nxt_http_route_encoding_t encoding, + nxt_http_uri_encoding_t encoding, nxt_http_route_pattern_case_t pattern_case); static nxt_int_t nxt_http_route_resolve(nxt_task_t *task, @@ -457,7 +450,7 @@ nxt_http_route_match_create(nxt_task_t *task, nxt_router_temp_conf_t *tmcf, if (mtcf.scheme != NULL) { rule = nxt_http_route_rule_create(task, mp, mtcf.scheme, 1, NXT_HTTP_ROUTE_PATTERN_NOCASE, - NXT_HTTP_ROUTE_ENCODING_NONE); + NXT_HTTP_URI_ENCODING_NONE); if (rule == NULL) { return NULL; } @@ -470,7 +463,7 @@ nxt_http_route_match_create(nxt_task_t *task, nxt_router_temp_conf_t *tmcf, if (mtcf.host != NULL) { rule = nxt_http_route_rule_create(task, mp, mtcf.host, 1, NXT_HTTP_ROUTE_PATTERN_LOWCASE, - NXT_HTTP_ROUTE_ENCODING_NONE); + NXT_HTTP_URI_ENCODING_NONE); if (rule == NULL) { return NULL; } @@ -484,7 +477,7 @@ nxt_http_route_match_create(nxt_task_t *task, nxt_router_temp_conf_t *tmcf, if (mtcf.uri != NULL) { rule = nxt_http_route_rule_create(task, mp, mtcf.uri, 1, NXT_HTTP_ROUTE_PATTERN_NOCASE, - NXT_HTTP_ROUTE_ENCODING_URI); + NXT_HTTP_URI_ENCODING); if (rule == NULL) { return NULL; } @@ -498,7 +491,7 @@ nxt_http_route_match_create(nxt_task_t *task, nxt_router_temp_conf_t *tmcf, if (mtcf.method != NULL) { rule = nxt_http_route_rule_create(task, mp, mtcf.method, 1, NXT_HTTP_ROUTE_PATTERN_UPCASE, - NXT_HTTP_ROUTE_ENCODING_NONE); + NXT_HTTP_URI_ENCODING_NONE); if (rule == NULL) { return NULL; } @@ -512,7 +505,7 @@ nxt_http_route_match_create(nxt_task_t *task, nxt_router_temp_conf_t *tmcf, if (mtcf.headers != NULL) { table = nxt_http_route_table_create(task, mp, mtcf.headers, NXT_HTTP_ROUTE_HEADER, 0, - NXT_HTTP_ROUTE_ENCODING_NONE); + NXT_HTTP_URI_ENCODING_NONE); if (table == NULL) { return NULL; } @@ -524,7 +517,7 @@ nxt_http_route_match_create(nxt_task_t *task, nxt_router_temp_conf_t *tmcf, if (mtcf.arguments != NULL) { table = nxt_http_route_table_create(task, mp, mtcf.arguments, NXT_HTTP_ROUTE_ARGUMENT, 1, - NXT_HTTP_ROUTE_ENCODING_URI_PLUS); + NXT_HTTP_URI_ENCODING_PLUS); if (table == NULL) { return NULL; } @@ -536,7 +529,7 @@ nxt_http_route_match_create(nxt_task_t *task, nxt_router_temp_conf_t *tmcf, if (mtcf.cookies != NULL) { table = nxt_http_route_table_create(task, mp, mtcf.cookies, NXT_HTTP_ROUTE_COOKIE, 1, - NXT_HTTP_ROUTE_ENCODING_NONE); + NXT_HTTP_URI_ENCODING_NONE); if (table == NULL) { return NULL; } @@ -548,7 +541,7 @@ nxt_http_route_match_create(nxt_task_t *task, nxt_router_temp_conf_t *tmcf, if (mtcf.query != NULL) { rule = nxt_http_route_rule_create(task, mp, mtcf.query, 1, NXT_HTTP_ROUTE_PATTERN_NOCASE, - NXT_HTTP_ROUTE_ENCODING_URI_PLUS); + NXT_HTTP_URI_ENCODING_PLUS); if (rule == NULL) { return NULL; } @@ -650,6 +643,7 @@ nxt_http_action_init(nxt_task_t *task, nxt_router_temp_conf_t *tmcf, nxt_mp_t *mp; nxt_int_t ret; nxt_str_t pass; + nxt_router_conf_t *rtcf; nxt_http_action_conf_t acf; nxt_memzero(&acf, sizeof(acf)); @@ -662,10 +656,11 @@ nxt_http_action_init(nxt_task_t *task, nxt_router_temp_conf_t *tmcf, nxt_memzero(action, sizeof(nxt_http_action_t)); - mp = tmcf->router_conf->mem_pool; + rtcf = tmcf->router_conf; + mp = rtcf->mem_pool; if (acf.ret != NULL) { - return nxt_http_return_init(mp, action, &acf); + return nxt_http_return_init(rtcf, action, &acf); } if (acf.share != NULL) { @@ -678,7 +673,7 @@ nxt_http_action_init(nxt_task_t *task, nxt_router_temp_conf_t *tmcf, nxt_conf_get_string(acf.pass, &pass); - action->u.var = nxt_var_compile(&pass, mp, 0); + action->u.var = nxt_var_compile(&pass, mp, rtcf->var_fields, 0); if (nxt_slow_path(action->u.var == NULL)) { return NXT_ERROR; } @@ -690,7 +685,7 @@ nxt_http_action_init(nxt_task_t *task, nxt_router_temp_conf_t *tmcf, static nxt_http_route_table_t * nxt_http_route_table_create(nxt_task_t *task, nxt_mp_t *mp, nxt_conf_value_t *table_cv, nxt_http_route_object_t object, - nxt_bool_t case_sensitive, nxt_http_route_encoding_t encoding) + nxt_bool_t case_sensitive, nxt_http_uri_encoding_t encoding) { size_t size; uint32_t i, n; @@ -729,7 +724,7 @@ nxt_http_route_table_create(nxt_task_t *task, nxt_mp_t *mp, static nxt_http_route_ruleset_t * nxt_http_route_ruleset_create(nxt_task_t *task, nxt_mp_t *mp, nxt_conf_value_t *ruleset_cv, nxt_http_route_object_t object, - nxt_bool_t case_sensitive, nxt_http_route_encoding_t encoding) + nxt_bool_t case_sensitive, nxt_http_uri_encoding_t encoding) { size_t size; uint32_t i, n, next; @@ -777,12 +772,9 @@ nxt_http_route_ruleset_create(nxt_task_t *task, nxt_mp_t *mp, static nxt_http_route_rule_t * nxt_http_route_rule_name_create(nxt_task_t *task, nxt_mp_t *mp, nxt_conf_value_t *rule_cv, nxt_str_t *name, nxt_bool_t case_sensitive, - nxt_http_route_encoding_t encoding) + nxt_http_uri_encoding_t encoding) { - u_char c, *p, *src, *start, *end, plus; - uint8_t d0, d1; - uint32_t hash; - nxt_uint_t i; + int64_t hash; nxt_http_route_rule_t *rule; rule = nxt_http_route_rule_create(task, mp, rule_cv, case_sensitive, @@ -792,73 +784,14 @@ nxt_http_route_rule_name_create(nxt_task_t *task, nxt_mp_t *mp, return NULL; } - rule->u.name.length = name->length; - - p = nxt_mp_nget(mp, name->length); - if (nxt_slow_path(p == NULL)) { + hash = nxt_http_field_hash(mp, name, case_sensitive, encoding); + if (nxt_slow_path(hash == -1)) { return NULL; } - hash = NXT_HTTP_FIELD_HASH_INIT; - rule->u.name.start = p; - - if (encoding == NXT_HTTP_ROUTE_ENCODING_NONE) { - for (i = 0; i < name->length; i++) { - c = name->start[i]; - *p++ = c; - - c = case_sensitive ? c : nxt_lowcase(c); - hash = nxt_http_field_hash_char(hash, c); - } - - goto end; - } - - plus = (encoding == NXT_HTTP_ROUTE_ENCODING_URI_PLUS) ? ' ' : '+'; - - start = name->start; - end = start + name->length; - - for (src = start; src < end; src++) { - c = *src; - - switch (c) { - case '%': - if (nxt_slow_path(end - src <= 2)) { - return NULL; - } - - d0 = nxt_hex2int[src[1]]; - d1 = nxt_hex2int[src[2]]; - src += 2; - - if (nxt_slow_path((d0 | d1) >= 16)) { - return NULL; - } - - c = (d0 << 4) + d1; - *p++ = c; - break; - - case '+': - c = plus; - *p++ = c; - break; - - default: - *p++ = c; - break; - } - - c = case_sensitive ? c : nxt_lowcase(c); - hash = nxt_http_field_hash_char(hash, c); - } - - rule->u.name.length = p - rule->u.name.start; - -end: - - rule->u.name.hash = nxt_http_field_hash_end(hash) & 0xFFFF; + rule->u.name.hash = hash; + rule->u.name.start = name->start; + rule->u.name.length = name->length; return rule; } @@ -868,7 +801,7 @@ static nxt_http_route_rule_t * nxt_http_route_rule_create(nxt_task_t *task, nxt_mp_t *mp, nxt_conf_value_t *cv, nxt_bool_t case_sensitive, nxt_http_route_pattern_case_t pattern_case, - nxt_http_route_encoding_t encoding) + nxt_http_uri_encoding_t encoding) { size_t size; uint32_t i, n; @@ -953,7 +886,7 @@ nxt_http_route_types_rule_create(nxt_task_t *task, nxt_mp_t *mp, { return nxt_http_route_rule_create(task, mp, types, 0, NXT_HTTP_ROUTE_PATTERN_LOWCASE, - NXT_HTTP_ROUTE_ENCODING_NONE); + NXT_HTTP_URI_ENCODING_NONE); } @@ -992,7 +925,7 @@ static nxt_int_t nxt_http_route_pattern_create(nxt_task_t *task, nxt_mp_t *mp, nxt_conf_value_t *cv, nxt_http_route_pattern_t *pattern, nxt_http_route_pattern_case_t pattern_case, - nxt_http_route_encoding_t encoding) + nxt_http_uri_encoding_t encoding) { u_char c, *p, *end; nxt_str_t test, tmp; @@ -1188,15 +1121,15 @@ nxt_http_route_pattern_create(nxt_task_t *task, nxt_mp_t *mp, static nxt_int_t -nxt_http_route_decode_str(nxt_str_t *str, nxt_http_route_encoding_t encoding) +nxt_http_route_decode_str(nxt_str_t *str, nxt_http_uri_encoding_t encoding) { u_char *start, *end; switch (encoding) { - case NXT_HTTP_ROUTE_ENCODING_NONE: + case NXT_HTTP_URI_ENCODING_NONE: break; - case NXT_HTTP_ROUTE_ENCODING_URI: + case NXT_HTTP_URI_ENCODING: start = str->start; end = nxt_decode_uri(start, start, str->length); @@ -1207,7 +1140,7 @@ nxt_http_route_decode_str(nxt_str_t *str, nxt_http_route_encoding_t encoding) str->length = end - start; break; - case NXT_HTTP_ROUTE_ENCODING_URI_PLUS: + case NXT_HTTP_URI_ENCODING_PLUS: start = str->start; end = nxt_decode_uri_plus(start, start, str->length); @@ -1228,9 +1161,8 @@ nxt_http_route_decode_str(nxt_str_t *str, nxt_http_route_encoding_t encoding) static nxt_int_t nxt_http_route_pattern_slice(nxt_array_t *slices, - nxt_str_t *test, - nxt_http_route_pattern_type_t type, - nxt_http_route_encoding_t encoding, + nxt_str_t *test, nxt_http_route_pattern_type_t type, + nxt_http_uri_encoding_t encoding, nxt_http_route_pattern_case_t pattern_case) { u_char *start; @@ -1554,16 +1486,18 @@ nxt_http_action_create(nxt_task_t *task, nxt_router_temp_conf_t *tmcf, { nxt_mp_t *mp; nxt_int_t ret; + nxt_router_conf_t *rtcf; nxt_http_action_t *action; - mp = tmcf->router_conf->mem_pool; + rtcf = tmcf->router_conf; + mp = rtcf->mem_pool; action = nxt_mp_alloc(mp, sizeof(nxt_http_action_t)); if (nxt_slow_path(action == NULL)) { return NULL; } - action->u.var = nxt_var_compile(pass, mp, 0); + action->u.var = nxt_var_compile(pass, mp, rtcf->var_fields, 0); if (nxt_slow_path(action->u.var == NULL)) { return NULL; } @@ -1884,6 +1818,13 @@ nxt_http_route_addr_pattern_match(nxt_http_route_addr_pattern_t *p, break; #endif +#if (NXT_HAVE_UNIX_DOMAIN) + case AF_UNIX: + + match = (base->addr_family == AF_UNIX); + break; +#endif + default: match = 0; break; @@ -2019,14 +1960,13 @@ nxt_http_route_test_argument(nxt_http_request_t *r, static nxt_int_t nxt_http_route_scheme(nxt_http_request_t *r, nxt_http_route_rule_t *rule) { - nxt_bool_t tls, https; + nxt_bool_t https; nxt_http_route_pattern_slice_t *pattern_slice; pattern_slice = rule->pattern[0].u.pattern_slices->elts; https = (pattern_slice->length == nxt_length("https")); - tls = (r->tls != NULL); - return (tls == https); + return (r->tls == https); } diff --git a/src/nxt_http_route_addr.c b/src/nxt_http_route_addr.c index 2907a902..34455af4 100644 --- a/src/nxt_http_route_addr.c +++ b/src/nxt_http_route_addr.c @@ -41,6 +41,16 @@ nxt_http_route_addr_pattern_parse(nxt_mp_t *mp, base->negative = 0; } + if (nxt_str_eq(&addr, "unix", 4)) { +#if (NXT_HAVE_UNIX_DOMAIN) + base->addr_family = AF_UNIX; + + return NXT_OK; +#else + return NXT_ADDR_PATTERN_NO_UNIX_ERROR; +#endif + } + if (nxt_slow_path(addr.length < 2)) { return NXT_ADDR_PATTERN_LENGTH_ERROR; } @@ -233,7 +243,7 @@ nxt_http_route_addr_pattern_parse(nxt_mp_t *mp, } addr.length = delim - addr.start; - inet->end = htonl(0xFFFFFFFF & (0xFFFFFFFF << (32 - cidr_prefix))); + inet->end = htonl(0xFFFFFFFF & (0xFFFFFFFFULL << (32 - cidr_prefix))); inet->start = nxt_inet_addr(addr.start, addr.length) & inet->end; if (nxt_slow_path(inet->start == INADDR_NONE)) { diff --git a/src/nxt_http_route_addr.h b/src/nxt_http_route_addr.h index 3b1e1da3..2deda6f8 100644 --- a/src/nxt_http_route_addr.h +++ b/src/nxt_http_route_addr.h @@ -26,6 +26,7 @@ enum { NXT_ADDR_PATTERN_RANGE_OVERLAP_ERROR, NXT_ADDR_PATTERN_CIDR_ERROR, NXT_ADDR_PATTERN_NO_IPv6_ERROR, + NXT_ADDR_PATTERN_NO_UNIX_ERROR, }; diff --git a/src/nxt_http_static.c b/src/nxt_http_static.c index 61dd0cb3..0507e038 100644 --- a/src/nxt_http_static.c +++ b/src/nxt_http_static.c @@ -79,9 +79,11 @@ nxt_http_static_init(nxt_task_t *task, nxt_router_temp_conf_t *tmcf, nxt_str_t str, *ret; nxt_var_t *var; nxt_conf_value_t *cv; + nxt_router_conf_t *rtcf; nxt_http_static_conf_t *conf; - mp = tmcf->router_conf->mem_pool; + rtcf = tmcf->router_conf; + mp = rtcf->mem_pool; conf = nxt_mp_zget(mp, sizeof(nxt_http_static_conf_t)); if (nxt_slow_path(conf == NULL)) { @@ -102,7 +104,7 @@ nxt_http_static_init(nxt_task_t *task, nxt_router_temp_conf_t *tmcf, cv = nxt_conf_get_array_element_or_itself(acf->share, i); nxt_conf_get_string(cv, &str); - var = nxt_var_compile(&str, mp, 1); + var = nxt_var_compile(&str, mp, rtcf->var_fields, NXT_VAR_STRZ); if (nxt_slow_path(var == NULL)) { return NXT_ERROR; } @@ -128,7 +130,8 @@ nxt_http_static_init(nxt_task_t *task, nxt_router_temp_conf_t *tmcf, nxt_str_t chr, shr; nxt_bool_t is_const; - conf->chroot = nxt_var_compile(&acf->chroot, mp, 1); + conf->chroot = nxt_var_compile(&acf->chroot, mp, rtcf->var_fields, + NXT_VAR_STRZ); if (nxt_slow_path(conf->chroot == NULL)) { return NXT_ERROR; } @@ -756,9 +759,7 @@ nxt_http_static_extract_extension(nxt_str_t *path, nxt_str_t *exten) end = path->start + path->length; p = end; - for ( ;; ) { - /* There's always '/' in the beginning of the request path. */ - + while (p > path->start) { p--; ch = *p; @@ -767,11 +768,14 @@ nxt_http_static_extract_extension(nxt_str_t *path, nxt_str_t *exten) p++; /* Fall through. */ case '.': - exten->length = end - p; - exten->start = p; - return; + goto extension; } } + +extension: + + exten->length = end - p; + exten->start = p; } @@ -1023,7 +1027,7 @@ typedef struct { nxt_int_t nxt_http_static_mtypes_hash_add(nxt_mp_t *mp, nxt_lvlhsh_t *hash, - nxt_str_t *exten, nxt_str_t *type) + const nxt_str_t *exten, nxt_str_t *type) { nxt_lvlhsh_query_t lhq; nxt_http_static_mtype_t *mtype; @@ -1048,7 +1052,7 @@ nxt_http_static_mtypes_hash_add(nxt_mp_t *mp, nxt_lvlhsh_t *hash, nxt_str_t * -nxt_http_static_mtype_get(nxt_lvlhsh_t *hash, nxt_str_t *exten) +nxt_http_static_mtype_get(nxt_lvlhsh_t *hash, const nxt_str_t *exten) { nxt_lvlhsh_query_t lhq; nxt_http_static_mtype_t *mtype; diff --git a/src/nxt_http_variables.c b/src/nxt_http_variables.c index b765e177..5a632b24 100644 --- a/src/nxt_http_variables.c +++ b/src/nxt_http_variables.c @@ -7,32 +7,90 @@ #include <nxt_http.h> -static nxt_int_t nxt_http_var_method(nxt_task_t *task, nxt_var_query_t *query, - nxt_str_t *str, void *ctx); -static nxt_int_t nxt_http_var_request_uri(nxt_task_t *task, - nxt_var_query_t *query, nxt_str_t *str, void *ctx); -static nxt_int_t nxt_http_var_uri(nxt_task_t *task, nxt_var_query_t *query, - nxt_str_t *str, void *ctx); -static nxt_int_t nxt_http_var_host(nxt_task_t *task, nxt_var_query_t *query, - nxt_str_t *str, void *ctx); +static nxt_int_t nxt_http_var_dollar(nxt_task_t *task, nxt_str_t *str, + void *ctx, uint16_t field); +static nxt_int_t nxt_http_var_method(nxt_task_t *task, nxt_str_t *str, + void *ctx, uint16_t field); +static nxt_int_t nxt_http_var_request_uri(nxt_task_t *task, nxt_str_t *str, + void *ctx, uint16_t field); +static nxt_int_t nxt_http_var_uri(nxt_task_t *task, nxt_str_t *str, void *ctx, + uint16_t field); +static nxt_int_t nxt_http_var_host(nxt_task_t *task, nxt_str_t *str, void *ctx, + uint16_t field); +static nxt_int_t nxt_http_var_remote_addr(nxt_task_t *task, nxt_str_t *str, + void *ctx, uint16_t field); +static nxt_int_t nxt_http_var_time_local(nxt_task_t *task, nxt_str_t *str, + void *ctx, uint16_t field); +static u_char *nxt_http_log_date(u_char *buf, nxt_realtime_t *now, + struct tm *tm, size_t size, const char *format); +static nxt_int_t nxt_http_var_request_line(nxt_task_t *task, nxt_str_t *str, + void *ctx, uint16_t field); +static nxt_int_t nxt_http_var_status(nxt_task_t *task, nxt_str_t *str, + void *ctx, uint16_t field); +static nxt_int_t nxt_http_var_body_bytes_sent(nxt_task_t *task, nxt_str_t *str, + void *ctx, uint16_t field); +static nxt_int_t nxt_http_var_referer(nxt_task_t *task, nxt_str_t *str, + void *ctx, uint16_t field); +static nxt_int_t nxt_http_var_user_agent(nxt_task_t *task, nxt_str_t *str, + void *ctx, uint16_t field); +static nxt_int_t nxt_http_var_arg(nxt_task_t *task, nxt_str_t *str, void *ctx, + uint16_t field); +static nxt_int_t nxt_http_var_header(nxt_task_t *task, nxt_str_t *str, + void *ctx, uint16_t field); +static nxt_int_t nxt_http_var_cookie(nxt_task_t *task, nxt_str_t *str, + void *ctx, uint16_t field); static nxt_var_decl_t nxt_http_vars[] = { - { nxt_string("method"), - &nxt_http_var_method, - 0 }, - - { nxt_string("request_uri"), - &nxt_http_var_request_uri, - 0 }, - - { nxt_string("uri"), - &nxt_http_var_uri, - 0 }, - - { nxt_string("host"), - &nxt_http_var_host, - 0 }, + { + .name = nxt_string("dollar"), + .handler = nxt_http_var_dollar, + }, { + .name = nxt_string("method"), + .handler = nxt_http_var_method, + }, { + .name = nxt_string("request_uri"), + .handler = nxt_http_var_request_uri, + }, { + .name = nxt_string("uri"), + .handler = nxt_http_var_uri, + }, { + .name = nxt_string("host"), + .handler = nxt_http_var_host, + }, { + .name = nxt_string("remote_addr"), + .handler = nxt_http_var_remote_addr, + }, { + .name = nxt_string("time_local"), + .handler = nxt_http_var_time_local, + }, { + .name = nxt_string("request_line"), + .handler = nxt_http_var_request_line, + }, { + .name = nxt_string("status"), + .handler = nxt_http_var_status, + }, { + .name = nxt_string("body_bytes_sent"), + .handler = nxt_http_var_body_bytes_sent, + }, { + .name = nxt_string("header_referer"), + .handler = nxt_http_var_referer, + }, { + .name = nxt_string("header_user_agent"), + .handler = nxt_http_var_user_agent, + }, { + .name = nxt_string("arg"), + .handler = nxt_http_var_arg, + .field_hash = nxt_http_argument_hash, + }, { + .name = nxt_string("header"), + .handler = nxt_http_var_header, + .field_hash = nxt_http_header_hash, + }, { + .name = nxt_string("cookie"), + .handler = nxt_http_var_cookie, + .field_hash = nxt_http_cookie_hash, + }, }; @@ -44,8 +102,16 @@ nxt_http_register_variables(void) static nxt_int_t -nxt_http_var_method(nxt_task_t *task, nxt_var_query_t *query, nxt_str_t *str, - void *ctx) +nxt_http_var_dollar(nxt_task_t *task, nxt_str_t *str, void *ctx, uint16_t field) +{ + nxt_str_set(str, "$"); + + return NXT_OK; +} + + +static nxt_int_t +nxt_http_var_method(nxt_task_t *task, nxt_str_t *str, void *ctx, uint16_t field) { nxt_http_request_t *r; @@ -58,8 +124,8 @@ nxt_http_var_method(nxt_task_t *task, nxt_var_query_t *query, nxt_str_t *str, static nxt_int_t -nxt_http_var_request_uri(nxt_task_t *task, nxt_var_query_t *query, - nxt_str_t *str, void *ctx) +nxt_http_var_request_uri(nxt_task_t *task, nxt_str_t *str, void *ctx, + uint16_t field) { nxt_http_request_t *r; @@ -72,8 +138,7 @@ nxt_http_var_request_uri(nxt_task_t *task, nxt_var_query_t *query, static nxt_int_t -nxt_http_var_uri(nxt_task_t *task, nxt_var_query_t *query, nxt_str_t *str, - void *ctx) +nxt_http_var_uri(nxt_task_t *task, nxt_str_t *str, void *ctx, uint16_t field) { nxt_http_request_t *r; @@ -86,8 +151,7 @@ nxt_http_var_uri(nxt_task_t *task, nxt_var_query_t *query, nxt_str_t *str, static nxt_int_t -nxt_http_var_host(nxt_task_t *task, nxt_var_query_t *query, nxt_str_t *str, - void *ctx) +nxt_http_var_host(nxt_task_t *task, nxt_str_t *str, void *ctx, uint16_t field) { nxt_http_request_t *r; @@ -97,3 +161,323 @@ nxt_http_var_host(nxt_task_t *task, nxt_var_query_t *query, nxt_str_t *str, return NXT_OK; } + + +static nxt_int_t +nxt_http_var_remote_addr(nxt_task_t *task, nxt_str_t *str, void *ctx, + uint16_t field) +{ + nxt_http_request_t *r; + + r = ctx; + + str->length = r->remote->address_length; + str->start = nxt_sockaddr_address(r->remote); + + return NXT_OK; +} + + +static nxt_int_t +nxt_http_var_time_local(nxt_task_t *task, nxt_str_t *str, void *ctx, + uint16_t field) +{ + nxt_http_request_t *r; + + static nxt_time_string_t date_cache = { + (nxt_atomic_uint_t) -1, + nxt_http_log_date, + "%02d/%s/%4d:%02d:%02d:%02d %c%02d%02d", + nxt_length("31/Dec/1986:19:40:00 +0300"), + NXT_THREAD_TIME_LOCAL, + NXT_THREAD_TIME_SEC, + }; + + r = ctx; + + str->length = date_cache.size; + + str->start = nxt_mp_nget(r->mem_pool, str->length); + if (nxt_slow_path(str->start == NULL)) { + return NXT_ERROR; + } + + str->length = nxt_thread_time_string(task->thread, &date_cache, str->start) + - str->start; + + return NXT_OK; +} + + +static u_char * +nxt_http_log_date(u_char *buf, nxt_realtime_t *now, struct tm *tm, + size_t size, const char *format) +{ + u_char sign; + time_t gmtoff; + + static const char *month[] = { "Jan", "Feb", "Mar", "Apr", "May", "Jun", + "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" }; + + gmtoff = nxt_timezone(tm) / 60; + + if (gmtoff < 0) { + gmtoff = -gmtoff; + sign = '-'; + + } else { + sign = '+'; + } + + return nxt_sprintf(buf, buf + size, format, + tm->tm_mday, month[tm->tm_mon], tm->tm_year + 1900, + tm->tm_hour, tm->tm_min, tm->tm_sec, + sign, gmtoff / 60, gmtoff % 60); +} + + +static nxt_int_t +nxt_http_var_request_line(nxt_task_t *task, nxt_str_t *str, void *ctx, + uint16_t field) +{ + size_t length; + u_char *p, *start; + nxt_http_request_t *r; + + r = ctx; + + length = r->method->length + 1 + r->target.length + 1 + r->version.length; + + start = nxt_mp_nget(r->mem_pool, length); + if (nxt_slow_path(start == NULL)) { + return NXT_ERROR; + } + + p = start; + + if (r->method->length != 0) { + p = nxt_cpymem(p, r->method->start, r->method->length); + + if (r->target.length != 0) { + *p++ = ' '; + p = nxt_cpymem(p, r->target.start, r->target.length); + + if (r->version.length != 0) { + *p++ = ' '; + p = nxt_cpymem(p, r->version.start, r->version.length); + } + } + + } else { + *p++ = '-'; + } + + str->start = start; + str->length = p - start; + + return NXT_OK; +} + + +static nxt_int_t +nxt_http_var_body_bytes_sent(nxt_task_t *task, nxt_str_t *str, void *ctx, + uint16_t field) +{ + nxt_off_t bytes; + nxt_http_request_t *r; + + r = ctx; + + str->start = nxt_mp_nget(r->mem_pool, NXT_OFF_T_LEN); + if (nxt_slow_path(str->start == NULL)) { + return NXT_ERROR; + } + + bytes = nxt_http_proto[r->protocol].body_bytes_sent(task, r->proto); + + str->length = nxt_sprintf(str->start, str->start + NXT_OFF_T_LEN, "%O", + bytes) - str->start; + + return NXT_OK; +} + + +static nxt_int_t +nxt_http_var_status(nxt_task_t *task, nxt_str_t *str, void *ctx, uint16_t field) +{ + nxt_http_request_t *r; + + r = ctx; + + str->start = nxt_mp_nget(r->mem_pool, 3); + if (nxt_slow_path(str->start == NULL)) { + return NXT_ERROR; + } + + str->length = nxt_sprintf(str->start, str->start + 3, "%03d", r->status) + - str->start; + + return NXT_OK; +} + + +static nxt_int_t +nxt_http_var_referer(nxt_task_t *task, nxt_str_t *str, void *ctx, + uint16_t field) +{ + nxt_http_request_t *r; + + r = ctx; + + if (r->referer != NULL) { + str->start = r->referer->value; + str->length = r->referer->value_length; + + } else { + nxt_str_null(str); + } + + return NXT_OK; +} + + +static nxt_int_t +nxt_http_var_user_agent(nxt_task_t *task, nxt_str_t *str, void *ctx, + uint16_t field) +{ + nxt_http_request_t *r; + + r = ctx; + + if (r->user_agent != NULL) { + str->start = r->user_agent->value; + str->length = r->user_agent->value_length; + + } else { + nxt_str_null(str); + } + + return NXT_OK; +} + + +static nxt_int_t +nxt_http_var_arg(nxt_task_t *task, nxt_str_t *str, void *ctx, uint16_t field) +{ + nxt_array_t *args; + nxt_var_field_t *vf; + nxt_router_conf_t *rtcf; + nxt_http_request_t *r; + nxt_http_name_value_t *nv, *start; + + r = ctx; + + rtcf = r->conf->socket_conf->router_conf; + + vf = nxt_var_field_get(rtcf->var_fields, field); + + args = nxt_http_arguments_parse(r); + if (nxt_slow_path(args == NULL)) { + return NXT_ERROR; + } + + start = args->elts; + nv = start + args->nelts - 1; + + while (nv >= start) { + + if (vf->hash == nv->hash + && vf->name.length == nv->name_length + && nxt_memcmp(vf->name.start, nv->name, nv->name_length) == 0) + { + str->start = nv->value; + str->length = nv->value_length; + + return NXT_OK; + } + + nv--; + } + + nxt_str_null(str); + + return NXT_OK; +} + + +static nxt_int_t +nxt_http_var_header(nxt_task_t *task, nxt_str_t *str, void *ctx, uint16_t field) +{ + nxt_var_field_t *vf; + nxt_http_field_t *f; + nxt_router_conf_t *rtcf; + nxt_http_request_t *r; + + r = ctx; + + rtcf = r->conf->socket_conf->router_conf; + + vf = nxt_var_field_get(rtcf->var_fields, field); + + nxt_list_each(f, r->fields) { + + if (vf->hash == f->hash + && vf->name.length == f->name_length + && nxt_strncasecmp(vf->name.start, f->name, f->name_length) == 0) + { + str->start = f->value; + str->length = f->value_length; + + return NXT_OK; + } + + } nxt_list_loop; + + nxt_str_null(str); + + return NXT_OK; +} + + +static nxt_int_t +nxt_http_var_cookie(nxt_task_t *task, nxt_str_t *str, void *ctx, uint16_t field) +{ + nxt_array_t *cookies; + nxt_var_field_t *vf; + nxt_router_conf_t *rtcf; + nxt_http_request_t *r; + nxt_http_name_value_t *nv, *end; + + r = ctx; + + rtcf = r->conf->socket_conf->router_conf; + + vf = nxt_var_field_get(rtcf->var_fields, field); + + cookies = nxt_http_cookies_parse(r); + if (nxt_slow_path(cookies == NULL)) { + return NXT_ERROR; + } + + nv = cookies->elts; + end = nv + cookies->nelts; + + while (nv < end) { + + if (vf->hash == nv->hash + && vf->name.length == nv->name_length + && nxt_memcmp(vf->name.start, nv->name, nv->name_length) == 0) + { + str->start = nv->value; + str->length = nv->value_length; + + return NXT_OK; + } + + nv++; + } + + nxt_str_null(str); + + return NXT_OK; +} diff --git a/src/nxt_isolation.c b/src/nxt_isolation.c index e3cb1f22..796da4c6 100644 --- a/src/nxt_isolation.c +++ b/src/nxt_isolation.c @@ -7,7 +7,7 @@ #include <nxt_process.h> #include <nxt_isolation.h> -#if (NXT_HAVE_PIVOT_ROOT) +#if (NXT_HAVE_MNTENT_H) #include <mntent.h> #endif @@ -45,7 +45,7 @@ static int nxt_cdecl nxt_isolation_mount_compare(const void *v1, const void *v2); static void nxt_isolation_unmount_all(nxt_task_t *task, nxt_process_t *process); -#if (NXT_HAVE_PIVOT_ROOT) && (NXT_HAVE_CLONE_NEWNS) +#if (NXT_HAVE_LINUX_PIVOT_ROOT) && (NXT_HAVE_CLONE_NEWNS) static nxt_int_t nxt_isolation_pivot_root(nxt_task_t *task, const char *rootfs); static nxt_int_t nxt_isolation_make_private_mount(nxt_task_t *task, const char *rootfs); @@ -752,7 +752,7 @@ undo: } -#if (NXT_HAVE_PIVOT_ROOT) && (NXT_HAVE_CLONE_NEWNS) +#if (NXT_HAVE_LINUX_PIVOT_ROOT) && (NXT_HAVE_CLONE_NEWNS) nxt_int_t nxt_isolation_change_root(nxt_task_t *task, nxt_process_t *process) @@ -1003,11 +1003,11 @@ fail: nxt_inline int nxt_pivot_root(const char *new_root, const char *old_root) { - return syscall(__NR_pivot_root, new_root, old_root); + return syscall(SYS_pivot_root, new_root, old_root); } -#else /* !(NXT_HAVE_PIVOT_ROOT) || !(NXT_HAVE_CLONE_NEWNS) */ +#else /* !(NXT_HAVE_LINUX_PIVOT_ROOT) || !(NXT_HAVE_CLONE_NEWNS) */ nxt_int_t diff --git a/src/nxt_isolation.h b/src/nxt_isolation.h index 88a5f9e1..b1bfc33c 100644 --- a/src/nxt_isolation.h +++ b/src/nxt_isolation.h @@ -2,8 +2,8 @@ * Copyright (C) NGINX, Inc. */ -#ifndef _NXT_ISOLATION_H_ -#define _NXT_ISOLATION_H_ +#ifndef _NXT_ISOLATION_H_INCLUDED_ +#define _NXT_ISOLATION_H_INCLUDED_ nxt_int_t nxt_isolation_main_prefork(nxt_task_t *task, nxt_process_t *process, @@ -15,4 +15,4 @@ nxt_int_t nxt_isolation_prepare_rootfs(nxt_task_t *task, nxt_int_t nxt_isolation_change_root(nxt_task_t *task, nxt_process_t *process); #endif -#endif /* _NXT_ISOLATION_H_ */ +#endif /* _NXT_ISOLATION_H_INCLUDED_ */ diff --git a/src/nxt_job_resolve.c b/src/nxt_job_resolve.c deleted file mode 100644 index 0f1fb9aa..00000000 --- a/src/nxt_job_resolve.c +++ /dev/null @@ -1,132 +0,0 @@ - -/* - * Copyright (C) Igor Sysoev - * Copyright (C) NGINX, Inc. - */ - -#include <nxt_main.h> - - -void -nxt_job_resolve(nxt_job_resolve_t *jbr) -{ - int err; - u_char *host; - size_t length; - nxt_mp_t *mp; - nxt_uint_t n; - nxt_sockaddr_t *sa; - struct addrinfo hint, *res, *r; - nxt_work_handler_t handler; - - #define NXT_BUFSIZE 64 - u_char buf[NXT_BUFSIZE]; - - handler = jbr->error_handler; - res = NULL; - - length = jbr->name.length + 1; - - if (nxt_fast_path(length <= NXT_BUFSIZE)) { - host = buf; - - } else { - host = nxt_mp_alloc(jbr->job.mem_pool, length); - if (nxt_slow_path(host == NULL)) { - goto fail; - } - } - - nxt_cpystrn(host, jbr->name.start, length); - - nxt_memzero(&hint, sizeof(struct addrinfo)); - hint.ai_socktype = SOCK_STREAM; - - err = getaddrinfo((char *) host, NULL, &hint, &res); - - if (err != 0) { - nxt_thread_log_error(jbr->log_level, - "getaddrinfo(\"%s\") failed (%d: %s)", - host, err, gai_strerror(err)); - goto fail; - } - - n = 0; - for (r = res; r != NULL; r = r->ai_next) { - - switch (r->ai_addr->sa_family) { -#if (NXT_INET6) - case AF_INET6: -#endif - case AF_INET: - n++; - break; - - default: - break; - } - } - - jbr->count = n; - mp = jbr->job.mem_pool; - - jbr->sockaddrs = nxt_mp_alloc(mp, n * sizeof(nxt_sockaddr_t *)); - if (nxt_slow_path(jbr->sockaddrs == NULL)) { - goto fail; - } - - n = 0; - for (r = res; r != NULL; r = r->ai_next) { - - switch (r->ai_addr->sa_family) { -#if (NXT_INET6) - case AF_INET6: - length = NXT_INET6_ADDR_STR_LEN; - break; -#endif - case AF_INET: - length = NXT_INET_ADDR_STR_LEN; - break; - - default: - continue; - } - - sa = nxt_sockaddr_create(mp, r->ai_addr, r->ai_addrlen, length); - if (nxt_slow_path(sa == NULL)) { - goto fail; - } - - jbr->sockaddrs[n++] = sa; - - if (jbr->port != 0) { - - switch (sa->u.sockaddr.sa_family) { - case AF_INET: - sa->u.sockaddr_in.sin_port = jbr->port; - break; -#if (NXT_INET6) - case AF_INET6: - sa->u.sockaddr_in6.sin6_port = jbr->port; - break; -#endif - default: - break; - } - } - } - - handler = jbr->ready_handler; - -fail: - - if (nxt_fast_path(res != NULL)) { - freeaddrinfo(res); - } - - if (host != buf) { - nxt_mp_free(jbr->job.mem_pool, host); - } - - nxt_job_return(jbr->job.task, &jbr->job, handler); -} diff --git a/src/nxt_job_resolve.h b/src/nxt_job_resolve.h deleted file mode 100644 index fef55b99..00000000 --- a/src/nxt_job_resolve.h +++ /dev/null @@ -1,29 +0,0 @@ - -/* - * Copyright (C) Igor Sysoev - * Copyright (C) NGINX, Inc. - */ - -#ifndef _NXT_JOB_RESOLVE_H_INCLUDED_ -#define _NXT_JOB_RESOLVE_H_INCLUDED_ - - -typedef struct { - nxt_job_t job; - nxt_str_t name; - - uint32_t log_level; /* 4 bits */ - in_port_t port; - uint16_t count; - - nxt_sockaddr_t **sockaddrs; - - nxt_work_handler_t ready_handler; - nxt_work_handler_t error_handler; -} nxt_job_resolve_t; - - -void nxt_job_resolve(nxt_job_resolve_t *jbr); - - -#endif /* _NXT_JOB_RESOLVE_H_INCLUDED_ */ diff --git a/src/nxt_main.h b/src/nxt_main.h index 7f812568..dca4b6dc 100644 --- a/src/nxt_main.h +++ b/src/nxt_main.h @@ -146,7 +146,6 @@ typedef void (*nxt_event_conn_handler_t)(nxt_thread_t *thr, nxt_conn_t *c); #include <nxt_job_file.h> #include <nxt_buf_filter.h> -#include <nxt_job_resolve.h> #include <nxt_sockaddr.h> #include <nxt_cache.h> diff --git a/src/nxt_main_process.c b/src/nxt_main_process.c index 03761a10..39a8e112 100644 --- a/src/nxt_main_process.c +++ b/src/nxt_main_process.c @@ -1187,7 +1187,9 @@ nxt_main_listening_socket(nxt_sockaddr_t *sa, nxt_listening_socket_t *ls) #if (NXT_HAVE_UNIX_DOMAIN) - if (sa->u.sockaddr.sa_family == AF_UNIX) { + if (sa->u.sockaddr.sa_family == AF_UNIX + && sa->u.sockaddr_un.sun_path[0] != '\0') + { char *filename; mode_t access; diff --git a/src/nxt_mp.c b/src/nxt_mp.c index d0de2c0e..2bd8cdee 100644 --- a/src/nxt_mp.c +++ b/src/nxt_mp.c @@ -155,7 +155,7 @@ static void *nxt_mp_alloc_large(nxt_mp_t *mp, size_t alignment, size_t size, nxt_bool_t freeable); static intptr_t nxt_mp_rbtree_compare(nxt_rbtree_node_t *node1, nxt_rbtree_node_t *node2); -static nxt_mp_block_t *nxt_mp_find_block(nxt_rbtree_t *tree, u_char *p); +static nxt_mp_block_t *nxt_mp_find_block(nxt_rbtree_t *tree, const u_char *p); static const char *nxt_mp_chunk_free(nxt_mp_t *mp, nxt_mp_block_t *cluster, u_char *p); @@ -830,7 +830,7 @@ nxt_mp_free(nxt_mp_t *mp, void *p) static nxt_mp_block_t * -nxt_mp_find_block(nxt_rbtree_t *tree, u_char *p) +nxt_mp_find_block(nxt_rbtree_t *tree, const u_char *p) { nxt_mp_block_t *block; nxt_rbtree_node_t *node, *sentinel; diff --git a/src/nxt_nncq.h b/src/nxt_nncq.h index 20e7ecff..6c9ab326 100644 --- a/src/nxt_nncq.h +++ b/src/nxt_nncq.h @@ -85,7 +85,7 @@ nxt_nncq_empty(nxt_nncq_t const volatile *q) } -static void +static inline void nxt_nncq_init(nxt_nncq_t volatile *q) { q->head = NXT_NNCQ_SIZE; @@ -94,7 +94,7 @@ nxt_nncq_init(nxt_nncq_t volatile *q) } -static void +static inline void nxt_nncq_enqueue(nxt_nncq_t volatile *q, nxt_nncq_atomic_t val) { nxt_nncq_cycle_t e_cycle, t_cycle; @@ -128,7 +128,7 @@ nxt_nncq_enqueue(nxt_nncq_t volatile *q, nxt_nncq_atomic_t val) } -static nxt_nncq_atomic_t +static inline nxt_nncq_atomic_t nxt_nncq_dequeue(nxt_nncq_t volatile *q) { nxt_nncq_cycle_t e_cycle, h_cycle; diff --git a/src/nxt_nvbcq.h b/src/nxt_nvbcq.h index 2b019dcc..e164615b 100644 --- a/src/nxt_nvbcq.h +++ b/src/nxt_nvbcq.h @@ -64,7 +64,7 @@ nxt_nvbcq_empty(nxt_nvbcq_t const volatile *q) } -static void +static inline void nxt_nvbcq_init(nxt_nvbcq_t volatile *q) { nxt_nvbcq_atomic_t i; @@ -79,7 +79,7 @@ nxt_nvbcq_init(nxt_nvbcq_t volatile *q) } -static void +static inline void nxt_nvbcq_enqueue(nxt_nvbcq_t volatile *q, nxt_nvbcq_atomic_t val) { nxt_nvbcq_atomic_t t, h, i; @@ -110,7 +110,7 @@ nxt_nvbcq_enqueue(nxt_nvbcq_t volatile *q, nxt_nvbcq_atomic_t val) } -static nxt_nvbcq_atomic_t +static inline nxt_nvbcq_atomic_t nxt_nvbcq_dequeue(nxt_nvbcq_t volatile *q) { nxt_nvbcq_atomic_t h, t, i, e; diff --git a/src/nxt_port.h b/src/nxt_port.h index 3b66edfd..3a8da5ad 100644 --- a/src/nxt_port.h +++ b/src/nxt_port.h @@ -53,6 +53,9 @@ struct nxt_port_handlers_s { nxt_port_handler_t data; nxt_port_handler_t app_restart; + /* Status report. */ + nxt_port_handler_t status; + nxt_port_handler_t oosm; nxt_port_handler_t shm_ack; nxt_port_handler_t read_queue; @@ -104,6 +107,7 @@ typedef enum { _NXT_PORT_MSG_DATA = nxt_port_handler_idx(data), _NXT_PORT_MSG_APP_RESTART = nxt_port_handler_idx(app_restart), + _NXT_PORT_MSG_STATUS = nxt_port_handler_idx(status), _NXT_PORT_MSG_OOSM = nxt_port_handler_idx(oosm), _NXT_PORT_MSG_SHM_ACK = nxt_port_handler_idx(shm_ack), @@ -145,6 +149,7 @@ typedef enum { NXT_PORT_MSG_DATA = _NXT_PORT_MSG_DATA, NXT_PORT_MSG_DATA_LAST = nxt_msg_last(_NXT_PORT_MSG_DATA), NXT_PORT_MSG_APP_RESTART = nxt_msg_last(_NXT_PORT_MSG_APP_RESTART), + NXT_PORT_MSG_STATUS = nxt_msg_last(_NXT_PORT_MSG_STATUS), NXT_PORT_MSG_OOSM = nxt_msg_last(_NXT_PORT_MSG_OOSM), NXT_PORT_MSG_SHM_ACK = nxt_msg_last(_NXT_PORT_MSG_SHM_ACK), @@ -174,9 +179,6 @@ typedef struct { /* More Fragments followed. */ uint8_t mf; /* 1 bit */ - - /* Message delivery tracking enabled, next chunk is tracking msg. */ - uint8_t tracking; /* 1 bit */ } nxt_port_msg_t; @@ -186,7 +188,6 @@ typedef struct { size_t share; nxt_fd_t fd[2]; nxt_port_msg_t port_msg; - uint32_t tracking_msg[2]; uint8_t close_fd; /* 1 bit */ uint8_t allocated; /* 1 bit */ } nxt_port_send_msg_t; diff --git a/src/nxt_port_memory.c b/src/nxt_port_memory.c index e799f860..0a4a6c53 100644 --- a/src/nxt_port_memory.c +++ b/src/nxt_port_memory.c @@ -539,137 +539,6 @@ nxt_port_get_port_incoming_mmap(nxt_task_t *task, nxt_pid_t spid, uint32_t id) } -nxt_int_t -nxt_port_mmap_get_tracking(nxt_task_t *task, nxt_port_mmaps_t *mmaps, - nxt_port_mmap_tracking_t *tracking, uint32_t stream) -{ - nxt_chunk_id_t c; - nxt_port_mmap_header_t *hdr; - nxt_port_mmap_handler_t *mmap_handler; - - nxt_debug(task, "request tracking for stream #%uD", stream); - - mmap_handler = nxt_port_mmap_get(task, mmaps, &c, 1, 1); - if (nxt_slow_path(mmap_handler == NULL)) { - return NXT_ERROR; - } - - nxt_port_mmap_handler_use(mmap_handler, 1); - - hdr = mmap_handler->hdr; - - tracking->mmap_handler = mmap_handler; - tracking->tracking = hdr->tracking + c; - - *tracking->tracking = stream; - - nxt_debug(task, "outgoing tracking allocation: %PI->%PI,%d,%d", - hdr->src_pid, hdr->dst_pid, hdr->id, c); - - return NXT_OK; -} - - -nxt_bool_t -nxt_port_mmap_tracking_cancel(nxt_task_t *task, - nxt_port_mmap_tracking_t *tracking, uint32_t stream) -{ - nxt_bool_t res; - nxt_chunk_id_t c; - nxt_port_mmap_header_t *hdr; - nxt_port_mmap_handler_t *mmap_handler; - - mmap_handler = tracking->mmap_handler; - - if (nxt_slow_path(mmap_handler == NULL)) { - return 0; - } - - hdr = mmap_handler->hdr; - - res = nxt_atomic_cmp_set(tracking->tracking, stream, 0); - - nxt_debug(task, "%s tracking for stream #%uD", - (res ? "cancelled" : "failed to cancel"), stream); - - if (!res) { - c = tracking->tracking - hdr->tracking; - nxt_port_mmap_set_chunk_free(hdr->free_tracking_map, c); - } - - nxt_port_mmap_handler_use(mmap_handler, -1); - - return res; -} - - -nxt_int_t -nxt_port_mmap_tracking_write(uint32_t *buf, nxt_port_mmap_tracking_t *t) -{ - nxt_port_mmap_handler_t *mmap_handler; - - mmap_handler = t->mmap_handler; - -#if (NXT_DEBUG) - { - nxt_atomic_t *tracking; - - tracking = mmap_handler->hdr->tracking; - - nxt_assert(t->tracking >= tracking); - nxt_assert(t->tracking < tracking + PORT_MMAP_CHUNK_COUNT); - } -#endif - - buf[0] = mmap_handler->hdr->id; - buf[1] = t->tracking - mmap_handler->hdr->tracking; - - return NXT_OK; -} - -nxt_bool_t -nxt_port_mmap_tracking_read(nxt_task_t *task, nxt_port_recv_msg_t *msg) -{ - nxt_buf_t *b; - nxt_bool_t res; - nxt_chunk_id_t c; - nxt_port_mmap_header_t *hdr; - nxt_port_mmap_handler_t *mmap_handler; - nxt_port_mmap_tracking_msg_t *tracking_msg; - - b = msg->buf; - - if (nxt_buf_used_size(b) < (int) sizeof(nxt_port_mmap_tracking_msg_t)) { - nxt_debug(task, "too small message %O", nxt_buf_used_size(b)); - return 0; - } - - tracking_msg = (nxt_port_mmap_tracking_msg_t *) b->mem.pos; - - b->mem.pos += sizeof(nxt_port_mmap_tracking_msg_t); - mmap_handler = nxt_port_get_port_incoming_mmap(task, msg->port_msg.pid, - tracking_msg->mmap_id); - - if (nxt_slow_path(mmap_handler == NULL)) { - return 0; - } - - hdr = mmap_handler->hdr; - - c = tracking_msg->tracking_id; - res = nxt_atomic_cmp_set(hdr->tracking + c, msg->port_msg.stream, 0); - - nxt_debug(task, "tracking for stream #%uD %s", msg->port_msg.stream, - (res ? "received" : "already cancelled")); - - if (!res) { - nxt_port_mmap_set_chunk_free(hdr->free_tracking_map, c); - } - - return res; -} - - nxt_buf_t * nxt_port_mmap_get_buf(nxt_task_t *task, nxt_port_mmaps_t *mmaps, size_t size) { diff --git a/src/nxt_port_memory.h b/src/nxt_port_memory.h index a2cdf5dd..f1e70964 100644 --- a/src/nxt_port_memory.h +++ b/src/nxt_port_memory.h @@ -15,27 +15,6 @@ typedef struct nxt_port_mmap_handler_s nxt_port_mmap_handler_t; void nxt_port_mmaps_destroy(nxt_port_mmaps_t *port_mmaps, nxt_bool_t free_elts); -typedef struct nxt_port_mmap_tracking_s nxt_port_mmap_tracking_t; - -struct nxt_port_mmap_tracking_s { - void *mmap_handler; - nxt_atomic_t *tracking; -}; - -nxt_int_t -nxt_port_mmap_get_tracking(nxt_task_t *task, nxt_port_mmaps_t *mmaps, - nxt_port_mmap_tracking_t *tracking, uint32_t stream); - -nxt_bool_t -nxt_port_mmap_tracking_cancel(nxt_task_t *task, - nxt_port_mmap_tracking_t *tracking, uint32_t stream); - -nxt_int_t -nxt_port_mmap_tracking_write(uint32_t *buf, nxt_port_mmap_tracking_t *t); - -nxt_bool_t -nxt_port_mmap_tracking_read(nxt_task_t *task, nxt_port_recv_msg_t *msg); - /* * Allocates nxt_but_t structure from task's thread engine mem_pool, assigns * this buf 'mem' pointers to first available shared mem bucket(s). 'size' diff --git a/src/nxt_port_memory_int.h b/src/nxt_port_memory_int.h index d2524ee4..21a05b10 100644 --- a/src/nxt_port_memory_int.h +++ b/src/nxt_port_memory_int.h @@ -84,13 +84,6 @@ struct nxt_port_mmap_msg_s { }; -typedef struct nxt_port_mmap_tracking_msg_s nxt_port_mmap_tracking_msg_t; - -struct nxt_port_mmap_tracking_msg_s { - uint32_t mmap_id; /* Mmap index in nxt_process_t.outgoing. */ - nxt_chunk_id_t tracking_id; /* Tracking index. */ -}; - nxt_inline nxt_bool_t nxt_port_mmap_get_free_chunk(nxt_free_map_t *m, nxt_chunk_id_t *c); @@ -107,7 +100,7 @@ nxt_inline void nxt_port_mmap_set_chunk_free(nxt_free_map_t *m, nxt_chunk_id_t c); nxt_inline nxt_chunk_id_t -nxt_port_mmap_chunk_id(nxt_port_mmap_header_t *hdr, u_char *p) +nxt_port_mmap_chunk_id(nxt_port_mmap_header_t *hdr, const u_char *p) { u_char *mm_start; diff --git a/src/nxt_port_rpc.c b/src/nxt_port_rpc.c index 0cac5cbb..28590933 100644 --- a/src/nxt_port_rpc.c +++ b/src/nxt_port_rpc.c @@ -512,7 +512,6 @@ nxt_port_rpc_close(nxt_task_t *task, nxt_port_t *port) msg.port_msg.mmap = 0; msg.port_msg.nf = 0; msg.port_msg.mf = 0; - msg.port_msg.tracking = 0; msg.size = 0; msg.cancelled = 0; msg.u.data = NULL; diff --git a/src/nxt_port_socket.c b/src/nxt_port_socket.c index 2a51dfb6..5752d5ab 100644 --- a/src/nxt_port_socket.c +++ b/src/nxt_port_socket.c @@ -19,7 +19,7 @@ static uint8_t nxt_port_enqueue_buf(nxt_task_t *task, nxt_port_msg_t *pm, void *qbuf, nxt_buf_t *b); static nxt_int_t nxt_port_msg_chk_insert(nxt_task_t *task, nxt_port_t *port, nxt_port_send_msg_t *msg); -static nxt_port_send_msg_t *nxt_port_msg_alloc(nxt_port_send_msg_t *m); +static nxt_port_send_msg_t *nxt_port_msg_alloc(const nxt_port_send_msg_t *m); static void nxt_port_write_handler(nxt_task_t *task, void *obj, void *data); static nxt_port_send_msg_t *nxt_port_msg_first(nxt_port_t *port); nxt_inline void nxt_port_msg_close_fd(nxt_port_send_msg_t *msg); @@ -332,7 +332,7 @@ nxt_port_msg_chk_insert(nxt_task_t *task, nxt_port_t *port, static nxt_port_send_msg_t * -nxt_port_msg_alloc(nxt_port_send_msg_t *m) +nxt_port_msg_alloc(const nxt_port_send_msg_t *m) { nxt_port_send_msg_t *msg; diff --git a/src/nxt_process.c b/src/nxt_process.c index 82e66a99..738a03bf 100644 --- a/src/nxt_process.c +++ b/src/nxt_process.c @@ -296,6 +296,16 @@ nxt_process_child_fixup(nxt_task_t *task, nxt_process_t *process) } nxt_runtime_process_loop; + if (init->siblings != NULL) { + nxt_queue_each(p, init->siblings, nxt_process_t, link) { + + nxt_debug(task, "remove sibling process %PI", p->pid); + + nxt_process_close_ports(task, p); + + } nxt_queue_loop; + } + return NXT_OK; } @@ -303,8 +313,9 @@ nxt_process_child_fixup(nxt_task_t *task, nxt_process_t *process) static nxt_pid_t nxt_process_create(nxt_task_t *task, nxt_process_t *process) { - nxt_int_t ret; - nxt_pid_t pid; + nxt_int_t ret; + nxt_pid_t pid; + nxt_runtime_t *rt; #if (NXT_HAVE_CLONE) pid = nxt_clone(SIGCHLD | process->isolation.clone.flags); @@ -352,7 +363,20 @@ nxt_process_create(nxt_task_t *task, nxt_process_t *process) process->pid = pid; process->isolated_pid = pid; - nxt_runtime_process_add(task, process); + rt = task->thread->runtime; + + if (rt->is_pid_isolated) { + /* + * Do not register process in runtime with isolated pid. + * Only global pid can be the key to avoid clash. + */ + nxt_assert(!nxt_queue_is_empty(&process->ports)); + + nxt_port_use(task, nxt_process_port_first(process), 1); + + } else { + nxt_runtime_process_add(task, process); + } return pid; } @@ -798,8 +822,6 @@ nxt_process_send_ready(nxt_task_t *task, nxt_process_t *process) } -#if (NXT_HAVE_POSIX_SPAWN) - /* * Linux glibc 2.2 posix_spawn() is implemented via fork()/execve(). * Linux glibc 2.4 posix_spawn() without file actions and spawn @@ -834,52 +856,6 @@ nxt_process_execute(nxt_task_t *task, char *name, char **argv, char **envp) return pid; } -#else - -nxt_pid_t -nxt_process_execute(nxt_task_t *task, char *name, char **argv, char **envp) -{ - nxt_pid_t pid; - - /* - * vfork() is better than fork() because: - * it is faster several times; - * its execution time does not depend on private memory mapping size; - * it has lesser chances to fail due to the ENOMEM error. - */ - - pid = vfork(); - - switch (pid) { - - case -1: - nxt_alert(task, "vfork() failed while executing \"%s\" %E", - name, nxt_errno); - break; - - case 0: - /* A child. */ - nxt_debug(task, "execve(\"%s\")", name); - - (void) execve(name, argv, envp); - - nxt_alert(task, "execve(\"%s\") failed %E", name, nxt_errno); - - exit(1); - nxt_unreachable(); - break; - - default: - /* A parent. */ - nxt_debug(task, "vfork(): %PI", pid); - break; - } - - return pid; -} - -#endif - nxt_int_t nxt_process_daemon(nxt_task_t *task) @@ -1008,6 +984,8 @@ nxt_process_close_ports(nxt_task_t *task, nxt_process_t *process) { nxt_port_t *port; + nxt_process_use(task, process, 1); + nxt_process_port_each(process, port) { nxt_port_close(task, port); @@ -1015,6 +993,8 @@ nxt_process_close_ports(nxt_task_t *task, nxt_process_t *process) nxt_runtime_port_remove(task, port); } nxt_process_port_loop; + + nxt_process_use(task, process, -1); } diff --git a/src/nxt_process.h b/src/nxt_process.h index 694f457e..15fd4e7f 100644 --- a/src/nxt_process.h +++ b/src/nxt_process.h @@ -19,7 +19,7 @@ * fork(2) calls. As we use clone(2) for container, it returns the wrong pid. */ #define nxt_getpid() \ - syscall(__NR_getpid) + syscall(SYS_getpid) #else #define nxt_getpid() \ getpid() @@ -148,6 +148,8 @@ typedef struct { const nxt_port_handlers_t *port_handlers; const nxt_sig_event_t *signals; + + nxt_queue_t *siblings; } nxt_process_init_t; diff --git a/src/nxt_router.c b/src/nxt_router.c index 3a32a363..f02bf3f2 100644 --- a/src/nxt_router.c +++ b/src/nxt_router.c @@ -7,6 +7,7 @@ #include <nxt_router.h> #include <nxt_conf.h> +#include <nxt_status.h> #if (NXT_TLS) #include <nxt_cert.h> #endif @@ -90,17 +91,14 @@ static void nxt_router_conf_data_handler(nxt_task_t *task, nxt_port_recv_msg_t *msg); static void nxt_router_app_restart_handler(nxt_task_t *task, nxt_port_recv_msg_t *msg); -static void nxt_router_remove_pid_handler(nxt_task_t *task, +static void nxt_router_status_handler(nxt_task_t *task, nxt_port_recv_msg_t *msg); -static void nxt_router_access_log_reopen_handler(nxt_task_t *task, +static void nxt_router_remove_pid_handler(nxt_task_t *task, nxt_port_recv_msg_t *msg); static nxt_router_temp_conf_t *nxt_router_temp_conf(nxt_task_t *task); -static void nxt_router_conf_apply(nxt_task_t *task, void *obj, void *data); static void nxt_router_conf_ready(nxt_task_t *task, nxt_router_temp_conf_t *tmcf); -static void nxt_router_conf_error(nxt_task_t *task, - nxt_router_temp_conf_t *tmcf); static void nxt_router_conf_send(nxt_task_t *task, nxt_router_temp_conf_t *tmcf, nxt_port_msg_type_t type); @@ -108,9 +106,10 @@ static nxt_int_t nxt_router_conf_create(nxt_task_t *task, nxt_router_temp_conf_t *tmcf, u_char *start, u_char *end); static nxt_int_t nxt_router_conf_process_static(nxt_task_t *task, nxt_router_conf_t *rtcf, nxt_conf_value_t *conf); -static nxt_int_t nxt_router_conf_process_client_ip(nxt_task_t *task, - nxt_router_temp_conf_t *tmcf, nxt_socket_conf_t *skcf, - nxt_conf_value_t *conf); +static nxt_http_forward_t *nxt_router_conf_forward(nxt_task_t *task, + nxt_mp_t *mp, nxt_conf_value_t *conf); +static nxt_int_t nxt_router_conf_forward_header(nxt_mp_t *mp, + nxt_conf_value_t *conf, nxt_http_forward_header_t *fh); static nxt_app_t *nxt_router_app_find(nxt_queue_t *queue, nxt_str_t *name); static nxt_int_t nxt_router_apps_hash_test(nxt_lvlhsh_query_t *lhq, void *data); @@ -200,27 +199,6 @@ static void nxt_router_req_headers_ack_handler(nxt_task_t *task, static void nxt_router_listen_socket_release(nxt_task_t *task, nxt_socket_conf_t *skcf); -static void nxt_router_access_log_writer(nxt_task_t *task, - nxt_http_request_t *r, nxt_router_access_log_t *access_log); -static u_char *nxt_router_access_log_date(u_char *buf, nxt_realtime_t *now, - struct tm *tm, size_t size, const char *format); -static void nxt_router_access_log_open(nxt_task_t *task, - nxt_router_temp_conf_t *tmcf); -static void nxt_router_access_log_ready(nxt_task_t *task, - nxt_port_recv_msg_t *msg, void *data); -static void nxt_router_access_log_error(nxt_task_t *task, - nxt_port_recv_msg_t *msg, void *data); -static void nxt_router_access_log_use(nxt_thread_spinlock_t *lock, - nxt_router_access_log_t *access_log); -static void nxt_router_access_log_release(nxt_task_t *task, - nxt_thread_spinlock_t *lock, nxt_router_access_log_t *access_log); -static void nxt_router_access_log_reopen_completion(nxt_task_t *task, void *obj, - void *data); -static void nxt_router_access_log_reopen_ready(nxt_task_t *task, - nxt_port_recv_msg_t *msg, void *data); -static void nxt_router_access_log_reopen_error(nxt_task_t *task, - nxt_port_recv_msg_t *msg, void *data); - static void nxt_router_app_port_ready(nxt_task_t *task, nxt_port_recv_msg_t *msg, void *data); static void nxt_router_app_port_error(nxt_task_t *task, @@ -270,7 +248,7 @@ static void nxt_router_get_mmap_handler(nxt_task_t *task, extern const nxt_http_request_state_t nxt_http_websocket; -static nxt_router_t *nxt_router; +nxt_router_t *nxt_router; static const nxt_str_t http_prefix = nxt_string("HTTP_"); static const nxt_str_t empty_prefix = nxt_string(""); @@ -294,6 +272,7 @@ static const nxt_port_handlers_t nxt_router_process_port_handlers = { .get_mmap = nxt_router_get_mmap_handler, .data = nxt_router_conf_data_handler, .app_restart = nxt_router_app_restart_handler, + .status = nxt_router_status_handler, .remove_pid = nxt_router_remove_pid_handler, .access_log = nxt_router_access_log_reopen_handler, .rpc_ready = nxt_port_rpc_handler, @@ -944,6 +923,84 @@ fail: static void +nxt_router_status_handler(nxt_task_t *task, nxt_port_recv_msg_t *msg) +{ + u_char *p; + size_t alloc; + nxt_app_t *app; + nxt_buf_t *b; + nxt_uint_t type; + nxt_port_t *port; + nxt_status_app_t *app_stat; + nxt_event_engine_t *engine; + nxt_status_report_t *report; + + port = nxt_runtime_port_find(task->thread->runtime, + msg->port_msg.pid, + msg->port_msg.reply_port); + if (nxt_slow_path(port == NULL)) { + nxt_alert(task, "nxt_router_status_handler(): reply port not found"); + return; + } + + alloc = sizeof(nxt_status_report_t); + + nxt_queue_each(app, &nxt_router->apps, nxt_app_t, link) { + + alloc += sizeof(nxt_status_app_t) + app->name.length; + + } nxt_queue_loop; + + b = nxt_buf_mem_alloc(port->mem_pool, alloc, 0); + if (nxt_slow_path(b == NULL)) { + type = NXT_PORT_MSG_RPC_ERROR; + goto fail; + } + + report = (nxt_status_report_t *) b->mem.free; + b->mem.free = b->mem.end; + + nxt_memzero(report, sizeof(nxt_status_report_t)); + + nxt_queue_each(engine, &nxt_router->engines, nxt_event_engine_t, link0) { + + report->accepted_conns += engine->accepted_conns_cnt; + report->idle_conns += engine->idle_conns_cnt; + report->closed_conns += engine->closed_conns_cnt; + report->requests += engine->requests_cnt; + + } nxt_queue_loop; + + report->apps_count = 0; + app_stat = report->apps; + p = b->mem.end; + + nxt_queue_each(app, &nxt_router->apps, nxt_app_t, link) { + p -= app->name.length; + + nxt_memcpy(p, app->name.start, app->name.length); + + app_stat->name.length = app->name.length; + app_stat->name.start = (u_char *) (p - b->mem.pos); + + app_stat->active_requests = app->active_requests; + app_stat->pending_processes = app->pending_processes; + app_stat->processes = app->processes; + app_stat->idle_processes = app->idle_processes; + + report->apps_count++; + app_stat++; + } nxt_queue_loop; + + type = NXT_PORT_MSG_RPC_READY_LAST; + +fail: + + nxt_port_socket_write(task, port, type, -1, msg->port_msg.stream, 0, b); +} + + +static void nxt_router_app_process_remove_pid(nxt_task_t *task, nxt_port_t *port, void *data) { @@ -1003,6 +1060,11 @@ nxt_router_temp_conf(nxt_task_t *task) rtcf->mem_pool = mp; + rtcf->var_fields = nxt_array_create(mp, 4, sizeof(nxt_var_field_t)); + if (nxt_slow_path(rtcf->var_fields == NULL)) { + goto fail; + } + tmp = nxt_mp_create(1024, 128, 256, 32); if (nxt_slow_path(tmp == NULL)) { goto fail; @@ -1069,7 +1131,7 @@ nxt_router_app_need_start(nxt_app_t *app) } -static void +void nxt_router_conf_apply(nxt_task_t *task, void *obj, void *data) { nxt_int_t ret; @@ -1225,11 +1287,10 @@ nxt_router_conf_ready(nxt_task_t *task, nxt_router_temp_conf_t *tmcf) } -static void +void nxt_router_conf_error(nxt_task_t *task, nxt_router_temp_conf_t *tmcf) { nxt_app_t *app; - nxt_queue_t new_socket_confs; nxt_socket_t s; nxt_router_t *router; nxt_queue_link_t *qlk; @@ -1252,11 +1313,6 @@ nxt_router_conf_error(nxt_task_t *task, nxt_router_temp_conf_t *tmcf) nxt_free(skcf->listen); } - nxt_queue_init(&new_socket_confs); - nxt_queue_add(&new_socket_confs, &updating_sockets); - nxt_queue_add(&new_socket_confs, &pending_sockets); - nxt_queue_add(&new_socket_confs, &creating_sockets); - rtcf = tmcf->router_conf; nxt_queue_each(app, &tmcf->apps, nxt_app_t, link) { @@ -1483,7 +1539,7 @@ nxt_router_conf_create(nxt_task_t *task, nxt_router_temp_conf_t *tmcf, nxt_mp_t *mp, *app_mp; uint32_t next, next_target; nxt_int_t ret; - nxt_str_t name, path, target; + nxt_str_t name, target; nxt_app_t *app, *prev; nxt_str_t *t, *s, *targets; nxt_uint_t n, i; @@ -1494,16 +1550,15 @@ nxt_router_conf_create(nxt_task_t *task, nxt_router_temp_conf_t *tmcf, nxt_tls_init_t *tls_init; nxt_conf_value_t *certificate; #endif - nxt_conf_value_t *conf, *http, *value, *websocket; + nxt_conf_value_t *root, *conf, *http, *value, *websocket; nxt_conf_value_t *applications, *application; nxt_conf_value_t *listeners, *listener; - nxt_conf_value_t *routes_conf, *static_conf, *client_ip_conf; nxt_socket_conf_t *skcf; + nxt_router_conf_t *rtcf; nxt_http_routes_t *routes; nxt_event_engine_t *engine; nxt_app_lang_module_t *lang; nxt_router_app_conf_t apcf; - nxt_router_access_log_t *access_log; nxt_router_listener_conf_t lscf; static nxt_str_t http_path = nxt_string("/settings/http"); @@ -1520,37 +1575,39 @@ nxt_router_conf_create(nxt_task_t *task, nxt_router_temp_conf_t *tmcf, #endif static nxt_str_t static_path = nxt_string("/settings/http/static"); static nxt_str_t websocket_path = nxt_string("/settings/http/websocket"); + static nxt_str_t forwarded_path = nxt_string("/forwarded"); static nxt_str_t client_ip_path = nxt_string("/client_ip"); - conf = nxt_conf_json_parse(tmcf->mem_pool, start, end, NULL); - if (conf == NULL) { + root = nxt_conf_json_parse(tmcf->mem_pool, start, end, NULL); + if (root == NULL) { nxt_alert(task, "configuration parsing error"); return NXT_ERROR; } - mp = tmcf->router_conf->mem_pool; + rtcf = tmcf->router_conf; + mp = rtcf->mem_pool; - ret = nxt_conf_map_object(mp, conf, nxt_router_conf, - nxt_nitems(nxt_router_conf), tmcf->router_conf); + ret = nxt_conf_map_object(mp, root, nxt_router_conf, + nxt_nitems(nxt_router_conf), rtcf); if (ret != NXT_OK) { nxt_alert(task, "root map error"); return NXT_ERROR; } - if (tmcf->router_conf->threads == 0) { - tmcf->router_conf->threads = nxt_ncpu; + if (rtcf->threads == 0) { + rtcf->threads = nxt_ncpu; } - static_conf = nxt_conf_get_path(conf, &static_path); + conf = nxt_conf_get_path(root, &static_path); - ret = nxt_router_conf_process_static(task, tmcf->router_conf, static_conf); + ret = nxt_router_conf_process_static(task, rtcf, conf); if (nxt_slow_path(ret != NXT_OK)) { return NXT_ERROR; } - router = tmcf->router_conf->router; + router = rtcf->router; - applications = nxt_conf_get_path(conf, &applications_path); + applications = nxt_conf_get_path(root, &applications_path); if (applications != NULL) { next = 0; @@ -1599,7 +1656,7 @@ nxt_router_conf_create(nxt_task_t *task, nxt_router_temp_conf_t *tmcf, nxt_queue_remove(&prev->link); nxt_queue_insert_tail(&tmcf->previous, &prev->link); - ret = nxt_router_apps_hash_add(tmcf->router_conf, prev); + ret = nxt_router_apps_hash_add(rtcf, prev); if (nxt_slow_path(ret != NXT_OK)) { goto fail; } @@ -1734,7 +1791,7 @@ nxt_router_conf_create(nxt_task_t *task, nxt_router_temp_conf_t *tmcf, nxt_queue_insert_tail(&tmcf->apps, &app->link); - ret = nxt_router_apps_hash_add(tmcf->router_conf, app); + ret = nxt_router_apps_hash_add(rtcf, app); if (nxt_slow_path(ret != NXT_OK)) { goto app_fail; } @@ -1785,21 +1842,22 @@ nxt_router_conf_create(nxt_task_t *task, nxt_router_temp_conf_t *tmcf, } } - routes_conf = nxt_conf_get_path(conf, &routes_path); - if (nxt_fast_path(routes_conf != NULL)) { - routes = nxt_http_routes_create(task, tmcf, routes_conf); + conf = nxt_conf_get_path(root, &routes_path); + if (nxt_fast_path(conf != NULL)) { + routes = nxt_http_routes_create(task, tmcf, conf); if (nxt_slow_path(routes == NULL)) { return NXT_ERROR; } - tmcf->router_conf->routes = routes; + + rtcf->routes = routes; } - ret = nxt_upstreams_create(task, tmcf, conf); + ret = nxt_upstreams_create(task, tmcf, root); if (nxt_slow_path(ret != NXT_OK)) { return ret; } - http = nxt_conf_get_path(conf, &http_path); + http = nxt_conf_get_path(root, &http_path); #if 0 if (http == NULL) { nxt_alert(task, "no \"http\" block"); @@ -1807,9 +1865,9 @@ nxt_router_conf_create(nxt_task_t *task, nxt_router_temp_conf_t *tmcf, } #endif - websocket = nxt_conf_get_path(conf, &websocket_path); + websocket = nxt_conf_get_path(root, &websocket_path); - listeners = nxt_conf_get_path(conf, &listeners_path); + listeners = nxt_conf_get_path(root, &listeners_path); if (listeners != NULL) { next = 0; @@ -1889,11 +1947,22 @@ nxt_router_conf_create(nxt_task_t *task, nxt_router_temp_conf_t *tmcf, t->length = nxt_strlen(t->start); } - client_ip_conf = nxt_conf_get_path(listener, &client_ip_path); - ret = nxt_router_conf_process_client_ip(task, tmcf, skcf, - client_ip_conf); - if (nxt_slow_path(ret != NXT_OK)) { - return NXT_ERROR; + conf = nxt_conf_get_path(listener, &forwarded_path); + + if (conf != NULL) { + skcf->forwarded = nxt_router_conf_forward(task, mp, conf); + if (nxt_slow_path(skcf->forwarded == NULL)) { + return NXT_ERROR; + } + } + + conf = nxt_conf_get_path(listener, &client_ip_path); + + if (conf != NULL) { + skcf->client_ip = nxt_router_conf_forward(task, mp, conf); + if (nxt_slow_path(skcf->client_ip == NULL)) { + return NXT_ERROR; + } } #if (NXT_TLS) @@ -1941,7 +2010,7 @@ nxt_router_conf_create(nxt_task_t *task, nxt_router_temp_conf_t *tmcf, #endif skcf->listen->handler = nxt_http_conn_init; - skcf->router_conf = tmcf->router_conf; + skcf->router_conf = rtcf; skcf->router_conf->count++; if (lscf.pass.length != 0) { @@ -1949,8 +2018,7 @@ nxt_router_conf_create(nxt_task_t *task, nxt_router_temp_conf_t *tmcf, /* COMPATIBILITY: listener application. */ } else if (lscf.application.length > 0) { - skcf->action = nxt_http_pass_application(task, - tmcf->router_conf, + skcf->action = nxt_http_pass_application(task, rtcf, &lscf.application); } @@ -1965,36 +2033,13 @@ nxt_router_conf_create(nxt_task_t *task, nxt_router_temp_conf_t *tmcf, goto fail; } - value = nxt_conf_get_path(conf, &access_log_path); + value = nxt_conf_get_path(root, &access_log_path); if (value != NULL) { - nxt_conf_get_string(value, &path); - - access_log = router->access_log; - - if (access_log != NULL && nxt_strstr_eq(&path, &access_log->path)) { - nxt_router_access_log_use(&router->lock, access_log); - - } else { - access_log = nxt_malloc(sizeof(nxt_router_access_log_t) - + path.length); - if (access_log == NULL) { - nxt_alert(task, "failed to allocate access log structure"); - goto fail; - } - - access_log->fd = -1; - access_log->handler = &nxt_router_access_log_writer; - access_log->count = 1; - - access_log->path.length = path.length; - access_log->path.start = (u_char *) access_log - + sizeof(nxt_router_access_log_t); - - nxt_memcpy(access_log->path.start, path.start, path.length); + ret = nxt_router_access_log_create(task, rtcf, value); + if (nxt_slow_path(ret != NXT_OK)) { + goto fail; } - - tmcf->router_conf->access_log = access_log; } nxt_queue_add(&deleting_sockets, &router->sockets); @@ -2129,74 +2174,103 @@ nxt_router_conf_process_static(nxt_task_t *task, nxt_router_conf_t *rtcf, } -static nxt_int_t -nxt_router_conf_process_client_ip(nxt_task_t *task, nxt_router_temp_conf_t *tmcf, - nxt_socket_conf_t *skcf, nxt_conf_value_t *conf) +static nxt_http_forward_t * +nxt_router_conf_forward(nxt_task_t *task, nxt_mp_t *mp, nxt_conf_value_t *conf) { - char c; - size_t i; - nxt_mp_t *mp; - uint32_t hash; - nxt_str_t header; - nxt_conf_value_t *source_conf, *header_conf, *recursive_conf; - nxt_http_client_ip_t *client_ip; + nxt_int_t ret; + nxt_conf_value_t *header_conf, *client_ip_conf, *protocol_conf; + nxt_conf_value_t *source_conf, *recursive_conf; + nxt_http_forward_t *forward; nxt_http_route_addr_rule_t *source; static nxt_str_t header_path = nxt_string("/header"); + static nxt_str_t client_ip_path = nxt_string("/client_ip"); + static nxt_str_t protocol_path = nxt_string("/protocol"); static nxt_str_t source_path = nxt_string("/source"); static nxt_str_t recursive_path = nxt_string("/recursive"); - if (conf == NULL) { - skcf->client_ip = NULL; + header_conf = nxt_conf_get_path(conf, &header_path); - return NXT_OK; - } + if (header_conf != NULL) { + client_ip_conf = nxt_conf_get_path(conf, &header_path); + protocol_conf = NULL; - mp = tmcf->router_conf->mem_pool; + } else { + client_ip_conf = nxt_conf_get_path(conf, &client_ip_path); + protocol_conf = nxt_conf_get_path(conf, &protocol_path); + } source_conf = nxt_conf_get_path(conf, &source_path); - header_conf = nxt_conf_get_path(conf, &header_path); recursive_conf = nxt_conf_get_path(conf, &recursive_path); - if (source_conf == NULL || header_conf == NULL) { - return NXT_ERROR; + if (source_conf == NULL + || (protocol_conf == NULL && client_ip_conf == NULL)) + { + return NULL; } - client_ip = nxt_mp_zget(mp, sizeof(nxt_http_client_ip_t)); - if (nxt_slow_path(client_ip == NULL)) { - return NXT_ERROR; + forward = nxt_mp_zget(mp, sizeof(nxt_http_forward_t)); + if (nxt_slow_path(forward == NULL)) { + return NULL; } source = nxt_http_route_addr_rule_create(task, mp, source_conf); if (nxt_slow_path(source == NULL)) { - return NXT_ERROR; + return NULL; } - client_ip->source = source; - - nxt_conf_get_string(header_conf, &header); + forward->source = source; if (recursive_conf != NULL) { - client_ip->recursive = nxt_conf_get_boolean(recursive_conf); + forward->recursive = nxt_conf_get_boolean(recursive_conf); } - client_ip->header = nxt_str_dup(mp, NULL, &header); - if (nxt_slow_path(client_ip->header == NULL)) { + if (client_ip_conf != NULL) { + ret = nxt_router_conf_forward_header(mp, client_ip_conf, + &forward->client_ip); + if (nxt_slow_path(ret != NXT_OK)) { + return NULL; + } + } + + if (protocol_conf != NULL) { + ret = nxt_router_conf_forward_header(mp, protocol_conf, + &forward->protocol); + if (nxt_slow_path(ret != NXT_OK)) { + return NULL; + } + } + + return forward; +} + + +static nxt_int_t +nxt_router_conf_forward_header(nxt_mp_t *mp, nxt_conf_value_t *conf, + nxt_http_forward_header_t *fh) +{ + char c; + size_t i; + uint32_t hash; + nxt_str_t header; + + nxt_conf_get_string(conf, &header); + + fh->header = nxt_str_dup(mp, NULL, &header); + if (nxt_slow_path(fh->header == NULL)) { return NXT_ERROR; } hash = NXT_HTTP_FIELD_HASH_INIT; - for (i = 0; i < client_ip->header->length; i++) { - c = client_ip->header->start[i]; + for (i = 0; i < fh->header->length; i++) { + c = fh->header->start[i]; hash = nxt_http_field_hash_char(hash, nxt_lowcase(c)); } hash = nxt_http_field_hash_end(hash) & 0xFFFF; - client_ip->header_hash = hash; - - skcf->client_ip = client_ip; + fh->header_hash = hash; return NXT_OK; } @@ -3719,384 +3793,6 @@ nxt_router_conf_release(nxt_task_t *task, nxt_socket_conf_joint_t *joint) static void -nxt_router_access_log_writer(nxt_task_t *task, nxt_http_request_t *r, - nxt_router_access_log_t *access_log) -{ - size_t size; - u_char *buf, *p; - nxt_off_t bytes; - - static nxt_time_string_t date_cache = { - (nxt_atomic_uint_t) -1, - nxt_router_access_log_date, - "%02d/%s/%4d:%02d:%02d:%02d %c%02d%02d", - nxt_length("31/Dec/1986:19:40:00 +0300"), - NXT_THREAD_TIME_LOCAL, - NXT_THREAD_TIME_SEC, - }; - - size = r->remote->address_length - + 6 /* ' - - [' */ - + date_cache.size - + 3 /* '] "' */ - + r->method->length - + 1 /* space */ - + r->target.length - + 1 /* space */ - + r->version.length - + 2 /* '" ' */ - + 3 /* status */ - + 1 /* space */ - + NXT_OFF_T_LEN - + 2 /* ' "' */ - + (r->referer != NULL ? r->referer->value_length : 1) - + 3 /* '" "' */ - + (r->user_agent != NULL ? r->user_agent->value_length : 1) - + 2 /* '"\n' */ - ; - - buf = nxt_mp_nget(r->mem_pool, size); - if (nxt_slow_path(buf == NULL)) { - return; - } - - p = nxt_cpymem(buf, nxt_sockaddr_address(r->remote), - r->remote->address_length); - - p = nxt_cpymem(p, " - - [", 6); - - p = nxt_thread_time_string(task->thread, &date_cache, p); - - p = nxt_cpymem(p, "] \"", 3); - - if (r->method->length != 0) { - p = nxt_cpymem(p, r->method->start, r->method->length); - - if (r->target.length != 0) { - *p++ = ' '; - p = nxt_cpymem(p, r->target.start, r->target.length); - - if (r->version.length != 0) { - *p++ = ' '; - p = nxt_cpymem(p, r->version.start, r->version.length); - } - } - - } else { - *p++ = '-'; - } - - p = nxt_cpymem(p, "\" ", 2); - - p = nxt_sprintf(p, p + 3, "%03d", r->status); - - *p++ = ' '; - - bytes = nxt_http_proto[r->protocol].body_bytes_sent(task, r->proto); - - p = nxt_sprintf(p, p + NXT_OFF_T_LEN, "%O", bytes); - - p = nxt_cpymem(p, " \"", 2); - - if (r->referer != NULL) { - p = nxt_cpymem(p, r->referer->value, r->referer->value_length); - - } else { - *p++ = '-'; - } - - p = nxt_cpymem(p, "\" \"", 3); - - if (r->user_agent != NULL) { - p = nxt_cpymem(p, r->user_agent->value, r->user_agent->value_length); - - } else { - *p++ = '-'; - } - - p = nxt_cpymem(p, "\"\n", 2); - - nxt_fd_write(access_log->fd, buf, p - buf); -} - - -static u_char * -nxt_router_access_log_date(u_char *buf, nxt_realtime_t *now, struct tm *tm, - size_t size, const char *format) -{ - u_char sign; - time_t gmtoff; - - static const char *month[] = { "Jan", "Feb", "Mar", "Apr", "May", "Jun", - "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" }; - - gmtoff = nxt_timezone(tm) / 60; - - if (gmtoff < 0) { - gmtoff = -gmtoff; - sign = '-'; - - } else { - sign = '+'; - } - - return nxt_sprintf(buf, buf + size, format, - tm->tm_mday, month[tm->tm_mon], tm->tm_year + 1900, - tm->tm_hour, tm->tm_min, tm->tm_sec, - sign, gmtoff / 60, gmtoff % 60); -} - - -static void -nxt_router_access_log_open(nxt_task_t *task, nxt_router_temp_conf_t *tmcf) -{ - uint32_t stream; - nxt_int_t ret; - nxt_buf_t *b; - nxt_port_t *main_port, *router_port; - nxt_runtime_t *rt; - nxt_router_access_log_t *access_log; - - access_log = tmcf->router_conf->access_log; - - b = nxt_buf_mem_alloc(tmcf->mem_pool, access_log->path.length + 1, 0); - if (nxt_slow_path(b == NULL)) { - goto fail; - } - - b->completion_handler = nxt_buf_dummy_completion; - - nxt_buf_cpystr(b, &access_log->path); - *b->mem.free++ = '\0'; - - rt = task->thread->runtime; - main_port = rt->port_by_type[NXT_PROCESS_MAIN]; - router_port = rt->port_by_type[NXT_PROCESS_ROUTER]; - - stream = nxt_port_rpc_register_handler(task, router_port, - nxt_router_access_log_ready, - nxt_router_access_log_error, - -1, tmcf); - if (nxt_slow_path(stream == 0)) { - goto fail; - } - - ret = nxt_port_socket_write(task, main_port, NXT_PORT_MSG_ACCESS_LOG, -1, - stream, router_port->id, b); - - if (nxt_slow_path(ret != NXT_OK)) { - nxt_port_rpc_cancel(task, router_port, stream); - goto fail; - } - - return; - -fail: - - nxt_router_conf_error(task, tmcf); -} - - -static void -nxt_router_access_log_ready(nxt_task_t *task, nxt_port_recv_msg_t *msg, - void *data) -{ - nxt_router_temp_conf_t *tmcf; - nxt_router_access_log_t *access_log; - - tmcf = data; - - access_log = tmcf->router_conf->access_log; - - access_log->fd = msg->fd[0]; - - nxt_work_queue_add(&task->thread->engine->fast_work_queue, - nxt_router_conf_apply, task, tmcf, NULL); -} - - -static void -nxt_router_access_log_error(nxt_task_t *task, nxt_port_recv_msg_t *msg, - void *data) -{ - nxt_router_temp_conf_t *tmcf; - - tmcf = data; - - nxt_router_conf_error(task, tmcf); -} - - -static void -nxt_router_access_log_use(nxt_thread_spinlock_t *lock, - nxt_router_access_log_t *access_log) -{ - if (access_log == NULL) { - return; - } - - nxt_thread_spin_lock(lock); - - access_log->count++; - - nxt_thread_spin_unlock(lock); -} - - -static void -nxt_router_access_log_release(nxt_task_t *task, nxt_thread_spinlock_t *lock, - nxt_router_access_log_t *access_log) -{ - if (access_log == NULL) { - return; - } - - nxt_thread_spin_lock(lock); - - if (--access_log->count != 0) { - access_log = NULL; - } - - nxt_thread_spin_unlock(lock); - - if (access_log != NULL) { - - if (access_log->fd != -1) { - nxt_fd_close(access_log->fd); - } - - nxt_free(access_log); - } -} - - -typedef struct { - nxt_mp_t *mem_pool; - nxt_router_access_log_t *access_log; -} nxt_router_access_log_reopen_t; - - -static void -nxt_router_access_log_reopen_handler(nxt_task_t *task, nxt_port_recv_msg_t *msg) -{ - nxt_mp_t *mp; - uint32_t stream; - nxt_int_t ret; - nxt_buf_t *b; - nxt_port_t *main_port, *router_port; - nxt_runtime_t *rt; - nxt_router_access_log_t *access_log; - nxt_router_access_log_reopen_t *reopen; - - access_log = nxt_router->access_log; - - if (access_log == NULL) { - return; - } - - mp = nxt_mp_create(1024, 128, 256, 32); - if (nxt_slow_path(mp == NULL)) { - return; - } - - reopen = nxt_mp_get(mp, sizeof(nxt_router_access_log_reopen_t)); - if (nxt_slow_path(reopen == NULL)) { - goto fail; - } - - reopen->mem_pool = mp; - reopen->access_log = access_log; - - b = nxt_buf_mem_alloc(mp, access_log->path.length + 1, 0); - if (nxt_slow_path(b == NULL)) { - goto fail; - } - - b->completion_handler = nxt_router_access_log_reopen_completion; - - nxt_buf_cpystr(b, &access_log->path); - *b->mem.free++ = '\0'; - - rt = task->thread->runtime; - main_port = rt->port_by_type[NXT_PROCESS_MAIN]; - router_port = rt->port_by_type[NXT_PROCESS_ROUTER]; - - stream = nxt_port_rpc_register_handler(task, router_port, - nxt_router_access_log_reopen_ready, - nxt_router_access_log_reopen_error, - -1, reopen); - if (nxt_slow_path(stream == 0)) { - goto fail; - } - - ret = nxt_port_socket_write(task, main_port, NXT_PORT_MSG_ACCESS_LOG, -1, - stream, router_port->id, b); - - if (nxt_slow_path(ret != NXT_OK)) { - nxt_port_rpc_cancel(task, router_port, stream); - goto fail; - } - - nxt_mp_retain(mp); - - return; - -fail: - - nxt_mp_destroy(mp); -} - - -static void -nxt_router_access_log_reopen_completion(nxt_task_t *task, void *obj, void *data) -{ - nxt_mp_t *mp; - nxt_buf_t *b; - - b = obj; - mp = b->data; - - nxt_mp_release(mp); -} - - -static void -nxt_router_access_log_reopen_ready(nxt_task_t *task, nxt_port_recv_msg_t *msg, - void *data) -{ - nxt_router_access_log_t *access_log; - nxt_router_access_log_reopen_t *reopen; - - reopen = data; - - access_log = reopen->access_log; - - if (access_log == nxt_router->access_log) { - - if (nxt_slow_path(dup2(msg->fd[0], access_log->fd) == -1)) { - nxt_alert(task, "dup2(%FD, %FD) failed %E", - msg->fd[0], access_log->fd, nxt_errno); - } - } - - nxt_fd_close(msg->fd[0]); - nxt_mp_release(reopen->mem_pool); -} - - -static void -nxt_router_access_log_reopen_error(nxt_task_t *task, nxt_port_recv_msg_t *msg, - void *data) -{ - nxt_router_access_log_reopen_t *reopen; - - reopen = data; - - nxt_mp_release(reopen->mem_pool); -} - - -static void nxt_router_thread_exit_handler(nxt_task_t *task, void *obj, void *data) { nxt_port_t *port; @@ -5390,7 +5086,6 @@ nxt_router_app_prepare_request(nxt_task_t *task, msg.pm.mmap = 1; msg.pm.nf = 0; msg.pm.mf = 0; - msg.pm.tracking = 0; nxt_port_mmap_handler_t *mmap_handler = buf->parent; nxt_port_mmap_header_t *hdr = mmap_handler->hdr; @@ -5559,7 +5254,7 @@ nxt_router_prepare_msg(nxt_task_t *task, nxt_http_request_t *r, p = nxt_cpymem(p, nxt_sockaddr_address(r->local), r->local->address_length); *p++ = '\0'; - req->tls = (r->tls != NULL); + req->tls = r->tls; req->websocket_handshake = r->websocket_handshake; req->server_name_length = r->server_name.length; diff --git a/src/nxt_router.h b/src/nxt_router.h index 7e337d27..a6add219 100644 --- a/src/nxt_router.h +++ b/src/nxt_router.h @@ -18,7 +18,7 @@ typedef struct nxt_http_request_s nxt_http_request_t; typedef struct nxt_http_action_s nxt_http_action_t; typedef struct nxt_http_routes_s nxt_http_routes_t; -typedef struct nxt_http_client_ip_s nxt_http_client_ip_t; +typedef struct nxt_http_forward_s nxt_http_forward_t; typedef struct nxt_upstream_s nxt_upstream_t; typedef struct nxt_upstreams_s nxt_upstreams_t; typedef struct nxt_router_access_log_s nxt_router_access_log_t; @@ -43,6 +43,7 @@ typedef struct { uint32_t threads; nxt_mp_t *mem_pool; + nxt_array_t *var_fields; /* of nxt_var_field_t */ nxt_router_t *router; nxt_http_routes_t *routes; @@ -52,6 +53,7 @@ typedef struct { nxt_lvlhsh_t apps_hash; nxt_router_access_log_t *access_log; + nxt_var_t *log_format; } nxt_router_conf_t; @@ -197,7 +199,8 @@ typedef struct { uint8_t discard_unsafe_fields; /* 1 bit */ - nxt_http_client_ip_t *client_ip; + nxt_http_forward_t *forwarded; + nxt_http_forward_t *client_ip; #if (NXT_TLS) nxt_tls_conf_t *tls; @@ -221,7 +224,8 @@ typedef struct { struct nxt_router_access_log_s { void (*handler)(nxt_task_t *task, nxt_http_request_t *r, - nxt_router_access_log_t *access_log); + nxt_router_access_log_t *access_log, + nxt_var_t *format); nxt_fd_t fd; nxt_str_t path; uint32_t count; @@ -235,7 +239,23 @@ nxt_int_t nxt_router_application_init(nxt_router_conf_t *rtcf, nxt_str_t *name, nxt_str_t *target, nxt_http_action_t *action); void nxt_router_listen_event_release(nxt_task_t *task, nxt_listen_event_t *lev, nxt_socket_conf_joint_t *joint); + +void nxt_router_conf_apply(nxt_task_t *task, void *obj, void *data); +void nxt_router_conf_error(nxt_task_t *task, nxt_router_temp_conf_t *tmcf); void nxt_router_conf_release(nxt_task_t *task, nxt_socket_conf_joint_t *joint); +nxt_int_t nxt_router_access_log_create(nxt_task_t *task, + nxt_router_conf_t *rtcf, nxt_conf_value_t *value); +void nxt_router_access_log_open(nxt_task_t *task, nxt_router_temp_conf_t *tmcf); +void nxt_router_access_log_use(nxt_thread_spinlock_t *lock, + nxt_router_access_log_t *access_log); +void nxt_router_access_log_release(nxt_task_t *task, + nxt_thread_spinlock_t *lock, nxt_router_access_log_t *access_log); +void nxt_router_access_log_reopen_handler(nxt_task_t *task, + nxt_port_recv_msg_t *msg); + + +extern nxt_router_t *nxt_router; + #endif /* _NXT_ROUTER_H_INCLUDED_ */ diff --git a/src/nxt_router_access_log.c b/src/nxt_router_access_log.c new file mode 100644 index 00000000..dc2a6687 --- /dev/null +++ b/src/nxt_router_access_log.c @@ -0,0 +1,442 @@ + +/* + * Copyright (C) Igor Sysoev + * Copyright (C) Valentin V. Bartenev + * Copyright (C) NGINX, Inc. + */ + +#include <nxt_router.h> +#include <nxt_conf.h> +#include <nxt_http.h> + + +typedef struct { + nxt_str_t path; + nxt_str_t format; +} nxt_router_access_log_conf_t; + + +typedef struct { + nxt_str_t text; + nxt_router_access_log_t *access_log; +} nxt_router_access_log_ctx_t; + + +static void nxt_router_access_log_writer(nxt_task_t *task, + nxt_http_request_t *r, nxt_router_access_log_t *access_log, + nxt_var_t *format); +static void nxt_router_access_log_write_ready(nxt_task_t *task, void *obj, + void *data); +static void nxt_router_access_log_write_error(nxt_task_t *task, void *obj, + void *data); +static void nxt_router_access_log_ready(nxt_task_t *task, + nxt_port_recv_msg_t *msg, void *data); +static void nxt_router_access_log_error(nxt_task_t *task, + nxt_port_recv_msg_t *msg, void *data); +static void nxt_router_access_log_reopen_completion(nxt_task_t *task, void *obj, + void *data); +static void nxt_router_access_log_reopen_ready(nxt_task_t *task, + nxt_port_recv_msg_t *msg, void *data); +static void nxt_router_access_log_reopen_error(nxt_task_t *task, + nxt_port_recv_msg_t *msg, void *data); + + +static nxt_conf_map_t nxt_router_access_log_conf[] = { + { + nxt_string("path"), + NXT_CONF_MAP_STR, + offsetof(nxt_router_access_log_conf_t, path), + }, + + { + nxt_string("format"), + NXT_CONF_MAP_STR, + offsetof(nxt_router_access_log_conf_t, format), + }, +}; + + +nxt_int_t +nxt_router_access_log_create(nxt_task_t *task, nxt_router_conf_t *rtcf, + nxt_conf_value_t *value) +{ + u_char *p; + nxt_int_t ret; + nxt_str_t str; + nxt_var_t *format; + nxt_router_t *router; + nxt_router_access_log_t *access_log; + nxt_router_access_log_conf_t alcf; + + static nxt_str_t log_format_str = nxt_string("$remote_addr - - " + "[$time_local] \"$request_line\" $status $body_bytes_sent " + "\"$header_referer\" \"$header_user_agent\""); + + alcf.format = log_format_str; + + if (nxt_conf_type(value) == NXT_CONF_STRING) { + nxt_conf_get_string(value, &alcf.path); + + } else { + ret = nxt_conf_map_object(rtcf->mem_pool, value, + nxt_router_access_log_conf, + nxt_nitems(nxt_router_access_log_conf), + &alcf); + if (ret != NXT_OK) { + nxt_alert(task, "access log map error"); + return NXT_ERROR; + } + } + + router = nxt_router; + + access_log = router->access_log; + + if (access_log != NULL && nxt_strstr_eq(&alcf.path, &access_log->path)) { + nxt_router_access_log_use(&router->lock, access_log); + + } else { + access_log = nxt_malloc(sizeof(nxt_router_access_log_t) + + alcf.path.length); + if (access_log == NULL) { + nxt_alert(task, "failed to allocate access log structure"); + return NXT_ERROR; + } + + access_log->fd = -1; + access_log->handler = &nxt_router_access_log_writer; + access_log->count = 1; + + access_log->path.length = alcf.path.length; + access_log->path.start = (u_char *) access_log + + sizeof(nxt_router_access_log_t); + + nxt_memcpy(access_log->path.start, alcf.path.start, alcf.path.length); + } + + str.length = alcf.format.length + 1; + + str.start = nxt_malloc(str.length); + if (str.start == NULL) { + nxt_alert(task, "failed to allocate log format structure"); + return NXT_ERROR; + } + + p = nxt_cpymem(str.start, alcf.format.start, alcf.format.length); + *p = '\n'; + + format = nxt_var_compile(&str, rtcf->mem_pool, rtcf->var_fields, + NXT_VAR_LOGGING); + if (nxt_slow_path(format == NULL)) { + return NXT_ERROR; + } + + rtcf->access_log = access_log; + rtcf->log_format = format; + + return NXT_OK; +} + + +static void +nxt_router_access_log_writer(nxt_task_t *task, nxt_http_request_t *r, + nxt_router_access_log_t *access_log, nxt_var_t *format) +{ + nxt_int_t ret; + nxt_router_access_log_ctx_t *ctx; + + ctx = nxt_mp_get(r->mem_pool, sizeof(nxt_router_access_log_ctx_t)); + if (nxt_slow_path(ctx == NULL)) { + return; + } + + ctx->access_log = access_log; + + if (nxt_var_is_const(format)) { + nxt_var_raw(format, &ctx->text); + + nxt_router_access_log_write_ready(task, r, ctx); + + } else { + ret = nxt_var_query_init(&r->var_query, r, r->mem_pool); + if (nxt_slow_path(ret != NXT_OK)) { + return; + } + + nxt_var_query(task, r->var_query, format, &ctx->text); + nxt_var_query_resolve(task, r->var_query, ctx, + nxt_router_access_log_write_ready, + nxt_router_access_log_write_error); + } +} + + +static void +nxt_router_access_log_write_ready(nxt_task_t *task, void *obj, void *data) +{ + nxt_http_request_t *r; + nxt_router_access_log_ctx_t *ctx; + + r = obj; + ctx = data; + + nxt_fd_write(ctx->access_log->fd, ctx->text.start, ctx->text.length); + + nxt_http_request_close_handler(task, r, r->proto.any); +} + + +static void +nxt_router_access_log_write_error(nxt_task_t *task, void *obj, void *data) +{ + +} + + +void +nxt_router_access_log_open(nxt_task_t *task, nxt_router_temp_conf_t *tmcf) +{ + uint32_t stream; + nxt_int_t ret; + nxt_buf_t *b; + nxt_port_t *main_port, *router_port; + nxt_runtime_t *rt; + nxt_router_access_log_t *access_log; + + access_log = tmcf->router_conf->access_log; + + b = nxt_buf_mem_alloc(tmcf->mem_pool, access_log->path.length + 1, 0); + if (nxt_slow_path(b == NULL)) { + goto fail; + } + + b->completion_handler = nxt_buf_dummy_completion; + + nxt_buf_cpystr(b, &access_log->path); + *b->mem.free++ = '\0'; + + rt = task->thread->runtime; + main_port = rt->port_by_type[NXT_PROCESS_MAIN]; + router_port = rt->port_by_type[NXT_PROCESS_ROUTER]; + + stream = nxt_port_rpc_register_handler(task, router_port, + nxt_router_access_log_ready, + nxt_router_access_log_error, + -1, tmcf); + if (nxt_slow_path(stream == 0)) { + goto fail; + } + + ret = nxt_port_socket_write(task, main_port, NXT_PORT_MSG_ACCESS_LOG, -1, + stream, router_port->id, b); + + if (nxt_slow_path(ret != NXT_OK)) { + nxt_port_rpc_cancel(task, router_port, stream); + goto fail; + } + + return; + +fail: + + nxt_router_conf_error(task, tmcf); +} + + +static void +nxt_router_access_log_ready(nxt_task_t *task, nxt_port_recv_msg_t *msg, + void *data) +{ + nxt_router_temp_conf_t *tmcf; + nxt_router_access_log_t *access_log; + + tmcf = data; + + access_log = tmcf->router_conf->access_log; + + access_log->fd = msg->fd[0]; + + nxt_work_queue_add(&task->thread->engine->fast_work_queue, + nxt_router_conf_apply, task, tmcf, NULL); +} + + +static void +nxt_router_access_log_error(nxt_task_t *task, nxt_port_recv_msg_t *msg, + void *data) +{ + nxt_router_temp_conf_t *tmcf; + + tmcf = data; + + nxt_router_conf_error(task, tmcf); +} + + +void +nxt_router_access_log_use(nxt_thread_spinlock_t *lock, + nxt_router_access_log_t *access_log) +{ + if (access_log == NULL) { + return; + } + + nxt_thread_spin_lock(lock); + + access_log->count++; + + nxt_thread_spin_unlock(lock); +} + + +void +nxt_router_access_log_release(nxt_task_t *task, nxt_thread_spinlock_t *lock, + nxt_router_access_log_t *access_log) +{ + if (access_log == NULL) { + return; + } + + nxt_thread_spin_lock(lock); + + if (--access_log->count != 0) { + access_log = NULL; + } + + nxt_thread_spin_unlock(lock); + + if (access_log != NULL) { + + if (access_log->fd != -1) { + nxt_fd_close(access_log->fd); + } + + nxt_free(access_log); + } +} + + +typedef struct { + nxt_mp_t *mem_pool; + nxt_router_access_log_t *access_log; +} nxt_router_access_log_reopen_t; + + +void +nxt_router_access_log_reopen_handler(nxt_task_t *task, nxt_port_recv_msg_t *msg) +{ + nxt_mp_t *mp; + uint32_t stream; + nxt_int_t ret; + nxt_buf_t *b; + nxt_port_t *main_port, *router_port; + nxt_runtime_t *rt; + nxt_router_access_log_t *access_log; + nxt_router_access_log_reopen_t *reopen; + + access_log = nxt_router->access_log; + + if (access_log == NULL) { + return; + } + + mp = nxt_mp_create(1024, 128, 256, 32); + if (nxt_slow_path(mp == NULL)) { + return; + } + + reopen = nxt_mp_get(mp, sizeof(nxt_router_access_log_reopen_t)); + if (nxt_slow_path(reopen == NULL)) { + goto fail; + } + + reopen->mem_pool = mp; + reopen->access_log = access_log; + + b = nxt_buf_mem_alloc(mp, access_log->path.length + 1, 0); + if (nxt_slow_path(b == NULL)) { + goto fail; + } + + b->completion_handler = nxt_router_access_log_reopen_completion; + + nxt_buf_cpystr(b, &access_log->path); + *b->mem.free++ = '\0'; + + rt = task->thread->runtime; + main_port = rt->port_by_type[NXT_PROCESS_MAIN]; + router_port = rt->port_by_type[NXT_PROCESS_ROUTER]; + + stream = nxt_port_rpc_register_handler(task, router_port, + nxt_router_access_log_reopen_ready, + nxt_router_access_log_reopen_error, + -1, reopen); + if (nxt_slow_path(stream == 0)) { + goto fail; + } + + ret = nxt_port_socket_write(task, main_port, NXT_PORT_MSG_ACCESS_LOG, -1, + stream, router_port->id, b); + + if (nxt_slow_path(ret != NXT_OK)) { + nxt_port_rpc_cancel(task, router_port, stream); + goto fail; + } + + nxt_mp_retain(mp); + + return; + +fail: + + nxt_mp_destroy(mp); +} + + +static void +nxt_router_access_log_reopen_completion(nxt_task_t *task, void *obj, void *data) +{ + nxt_mp_t *mp; + nxt_buf_t *b; + + b = obj; + mp = b->data; + + nxt_mp_release(mp); +} + + +static void +nxt_router_access_log_reopen_ready(nxt_task_t *task, nxt_port_recv_msg_t *msg, + void *data) +{ + nxt_router_access_log_t *access_log; + nxt_router_access_log_reopen_t *reopen; + + reopen = data; + + access_log = reopen->access_log; + + if (access_log == nxt_router->access_log) { + + if (nxt_slow_path(dup2(msg->fd[0], access_log->fd) == -1)) { + nxt_alert(task, "dup2(%FD, %FD) failed %E", + msg->fd[0], access_log->fd, nxt_errno); + } + } + + nxt_fd_close(msg->fd[0]); + nxt_mp_release(reopen->mem_pool); +} + + +static void +nxt_router_access_log_reopen_error(nxt_task_t *task, nxt_port_recv_msg_t *msg, + void *data) +{ + nxt_router_access_log_reopen_t *reopen; + + reopen = data; + + nxt_mp_release(reopen->mem_pool); +} diff --git a/src/nxt_runtime.c b/src/nxt_runtime.c index 46955f1c..d9c9f2ef 100644 --- a/src/nxt_runtime.c +++ b/src/nxt_runtime.c @@ -1408,6 +1408,7 @@ nxt_runtime_process_release(nxt_runtime_t *rt, nxt_process_t *process) nxt_assert(process->use_count == 0); nxt_assert(process->registered == 0); + nxt_assert(nxt_queue_is_empty(&process->ports)); nxt_port_mmaps_destroy(&process->incoming, 1); @@ -1579,11 +1580,11 @@ nxt_runtime_process_add(nxt_task_t *task, nxt_process_t *process) process->registered = 1; - nxt_thread_log_debug("process %PI added", process->pid); + nxt_debug(task, "process %PI added", process->pid); break; default: - nxt_thread_log_debug("process %PI failed to add", process->pid); + nxt_alert(task, "process %PI failed to add", process->pid); break; } @@ -1597,6 +1598,8 @@ nxt_runtime_process_remove(nxt_runtime_t *rt, nxt_process_t *process) nxt_pid_t pid; nxt_lvlhsh_query_t lhq; + nxt_assert(process->registered != 0); + pid = process->pid; nxt_runtime_process_lhq_pid(&lhq, &pid); @@ -1608,9 +1611,9 @@ nxt_runtime_process_remove(nxt_runtime_t *rt, nxt_process_t *process) switch (nxt_lvlhsh_delete(&rt->processes, &lhq)) { case NXT_OK: - rt->nprocesses--; + nxt_assert(lhq.value == process); - process = lhq.value; + rt->nprocesses--; process->registered = 0; @@ -1618,7 +1621,7 @@ nxt_runtime_process_remove(nxt_runtime_t *rt, nxt_process_t *process) break; default: - nxt_thread_log_debug("process %PI remove failed", pid); + nxt_thread_log_alert("process %PI remove failed", pid); break; } diff --git a/src/nxt_sockaddr.c b/src/nxt_sockaddr.c index 730428e4..86c3335e 100644 --- a/src/nxt_sockaddr.c +++ b/src/nxt_sockaddr.c @@ -15,10 +15,6 @@ static nxt_sockaddr_t *nxt_sockaddr_unix_parse(nxt_mp_t *mp, nxt_str_t *addr); static nxt_sockaddr_t *nxt_sockaddr_inet6_parse(nxt_mp_t *mp, nxt_str_t *addr); static nxt_sockaddr_t *nxt_sockaddr_inet_parse(nxt_mp_t *mp, nxt_str_t *addr); -static nxt_int_t nxt_job_sockaddr_unix_parse(nxt_job_sockaddr_parse_t *jbs); -static nxt_int_t nxt_job_sockaddr_inet6_parse(nxt_job_sockaddr_parse_t *jbs); -static nxt_int_t nxt_job_sockaddr_inet_parse(nxt_job_sockaddr_parse_t *jbs); - nxt_sockaddr_t * nxt_sockaddr_cache_alloc(nxt_event_engine_t *engine, nxt_listen_socket_t *ls) @@ -208,8 +204,8 @@ nxt_getsockname(nxt_task_t *task, nxt_mp_t *mp, nxt_socket_t s) #if (NXT_HAVE_UNIX_DOMAIN) case AF_UNIX: length = nxt_length("unix:") + socklen; -#endif break; +#endif case AF_INET: length = NXT_INET_ADDR_STR_LEN; @@ -433,82 +429,6 @@ nxt_sockaddr_cmp(nxt_sockaddr_t *sa1, nxt_sockaddr_t *sa2) } -size_t -nxt_sockaddr_ntop(nxt_sockaddr_t *sa, u_char *buf, u_char *end, nxt_bool_t port) -{ - u_char *p; - - switch (sa->u.sockaddr.sa_family) { - - case AF_INET: - p = (u_char *) &sa->u.sockaddr_in.sin_addr; - - if (port) { - p = nxt_sprintf(buf, end, "%ud.%ud.%ud.%ud:%d", - p[0], p[1], p[2], p[3], - ntohs(sa->u.sockaddr_in.sin_port)); - } else { - p = nxt_sprintf(buf, end, "%ud.%ud.%ud.%ud", - p[0], p[1], p[2], p[3]); - } - - return p - buf; - -#if (NXT_INET6) - - case AF_INET6: - p = buf; - - if (port) { - *p++ = '['; - } - - p = nxt_inet6_ntop(sa->u.sockaddr_in6.sin6_addr.s6_addr, p, end); - - if (port) { - p = nxt_sprintf(p, end, "]:%d", - ntohs(sa->u.sockaddr_in6.sin6_port)); - } - - return p - buf; -#endif - -#if (NXT_HAVE_UNIX_DOMAIN) - - case AF_UNIX: - -#if (NXT_LINUX) - - p = (u_char *) sa->u.sockaddr_un.sun_path; - - if (p[0] == '\0') { - size_t length; - - /* Linux abstract socket address has no trailing zero. */ - - length = sa->socklen - offsetof(struct sockaddr_un, sun_path) - 1; - p = nxt_sprintf(buf, end, "unix:\\0%*s", length, p + 1); - - } else { - p = nxt_sprintf(buf, end, "unix:%s", p); - } - -#else /* !(NXT_LINUX) */ - - p = nxt_sprintf(buf, end, "unix:%s", sa->u.sockaddr_un.sun_path); - -#endif - - return p - buf; - -#endif /* NXT_HAVE_UNIX_DOMAIN */ - - default: - return 0; - } -} - - #if (NXT_INET6) static u_char * @@ -681,8 +601,6 @@ nxt_sockaddr_unix_parse(nxt_mp_t *mp, nxt_str_t *addr) socklen = offsetof(struct sockaddr_un, sun_path) + length + 1; -#if (NXT_LINUX) - /* * Linux unix(7): * @@ -695,9 +613,12 @@ nxt_sockaddr_unix_parse(nxt_mp_t *mp, nxt_str_t *addr) if (path[0] == '@') { path[0] = '\0'; socklen--; - } - +#if !(NXT_LINUX) + nxt_thread_log_error(NXT_LOG_ERR, + "abstract unix domain sockets are not supported"); + return NULL; #endif + } sa = nxt_sockaddr_alloc(mp, socklen, addr->length); @@ -849,338 +770,6 @@ nxt_sockaddr_inet_parse(nxt_mp_t *mp, nxt_str_t *addr) } -void -nxt_job_sockaddr_parse(nxt_job_sockaddr_parse_t *jbs) -{ - u_char *p; - size_t length; - nxt_int_t ret; - nxt_work_handler_t handler; - - nxt_job_set_name(&jbs->resolve.job, "job sockaddr parse"); - - length = jbs->addr.length; - p = jbs->addr.start; - - if (length > 6 && nxt_memcmp(p, "unix:", 5) == 0) { - ret = nxt_job_sockaddr_unix_parse(jbs); - - } else if (length != 0 && *p == '[') { - ret = nxt_job_sockaddr_inet6_parse(jbs); - - } else { - ret = nxt_job_sockaddr_inet_parse(jbs); - } - - switch (ret) { - - case NXT_OK: - handler = jbs->resolve.ready_handler; - break; - - case NXT_ERROR: - handler = jbs->resolve.error_handler; - break; - - default: /* NXT_AGAIN */ - return; - } - - nxt_job_return(jbs->resolve.job.task, &jbs->resolve.job, handler); -} - - -static nxt_int_t -nxt_job_sockaddr_unix_parse(nxt_job_sockaddr_parse_t *jbs) -{ -#if (NXT_HAVE_UNIX_DOMAIN) - size_t length, socklen; - u_char *path; - nxt_mp_t *mp; - nxt_sockaddr_t *sa; - - /* - * Actual sockaddr_un length can be lesser or even larger than defined - * struct sockaddr_un length (see comment in nxt_socket.h). So - * limit maximum Unix domain socket address length by defined sun_path[] - * length because some OSes accept addresses twice larger than defined - * struct sockaddr_un. Also reserve space for a trailing zero to avoid - * ambiguity, since many OSes accept Unix domain socket addresses - * without a trailing zero. - */ - const size_t max_len = sizeof(struct sockaddr_un) - - offsetof(struct sockaddr_un, sun_path) - 1; - - /* cutting "unix:" */ - length = jbs->addr.length - 5; - path = jbs->addr.start + 5; - - if (length > max_len) { - nxt_thread_log_error(jbs->resolve.log_level, - "unix domain socket \"%V\" name is too long", - &jbs->addr); - return NXT_ERROR; - } - - socklen = offsetof(struct sockaddr_un, sun_path) + length + 1; - -#if (NXT_LINUX) - - /* - * Linux unix(7): - * - * abstract: an abstract socket address is distinguished by the fact - * that sun_path[0] is a null byte ('\0'). The socket's address in - * this namespace is given by the additional bytes in sun_path that - * are covered by the specified length of the address structure. - * (Null bytes in the name have no special significance.) - */ - if (path[0] == '\0') { - socklen--; - } - -#endif - - mp = jbs->resolve.job.mem_pool; - - jbs->resolve.sockaddrs = nxt_mp_alloc(mp, sizeof(void *)); - - if (nxt_fast_path(jbs->resolve.sockaddrs != NULL)) { - sa = nxt_sockaddr_alloc(mp, socklen, jbs->addr.length); - - if (nxt_fast_path(sa != NULL)) { - jbs->resolve.count = 1; - jbs->resolve.sockaddrs[0] = sa; - - sa->u.sockaddr_un.sun_family = AF_UNIX; - nxt_memcpy(sa->u.sockaddr_un.sun_path, path, length); - - return NXT_OK; - } - } - - return NXT_ERROR; - -#else /* !(NXT_HAVE_UNIX_DOMAIN) */ - - nxt_thread_log_error(jbs->resolve.log_level, - "unix domain socket \"%V\" is not supported", - &jbs->addr); - return NXT_ERROR; - -#endif -} - - -static nxt_int_t -nxt_job_sockaddr_inet6_parse(nxt_job_sockaddr_parse_t *jbs) -{ -#if (NXT_INET6) - u_char *p, *addr, *addr_end; - size_t length; - nxt_mp_t *mp; - nxt_int_t port; - nxt_sockaddr_t *sa; - struct in6_addr *in6_addr; - - length = jbs->addr.length - 1; - addr = jbs->addr.start + 1; - - addr_end = nxt_memchr(addr, ']', length); - - if (addr_end == NULL) { - goto invalid_address; - } - - mp = jbs->resolve.job.mem_pool; - - jbs->resolve.sockaddrs = nxt_mp_alloc(mp, sizeof(void *)); - - if (nxt_slow_path(jbs->resolve.sockaddrs == NULL)) { - return NXT_ERROR; - } - - sa = nxt_sockaddr_alloc(mp, sizeof(struct sockaddr_in6), - NXT_INET6_ADDR_STR_LEN); - - if (nxt_slow_path(sa == NULL)) { - return NXT_ERROR; - } - - jbs->resolve.count = 1; - jbs->resolve.sockaddrs[0] = sa; - - in6_addr = &sa->u.sockaddr_in6.sin6_addr; - - if (nxt_inet6_addr(in6_addr, addr, addr_end - addr) != NXT_OK) { - goto invalid_address; - } - - p = addr_end + 1; - length = (addr + length) - p; - - if (length == 0) { - jbs->no_port = 1; - port = jbs->resolve.port; - goto found; - } - - if (*p == ':') { - port = nxt_int_parse(p + 1, length - 1); - - if (port >= 1 && port <= 65535) { - port = htons((in_port_t) port); - goto found; - } - } - - nxt_thread_log_error(jbs->resolve.log_level, - "invalid port in \"%V\"", &jbs->addr); - - return NXT_ERROR; - -found: - - sa->u.sockaddr_in6.sin6_family = AF_INET6; - sa->u.sockaddr_in6.sin6_port = (in_port_t) port; - - if (IN6_IS_ADDR_UNSPECIFIED(in6_addr)) { - jbs->wildcard = 1; - } - - return NXT_OK; - -invalid_address: - - nxt_thread_log_error(jbs->resolve.log_level, - "invalid IPv6 address in \"%V\"", &jbs->addr); - return NXT_ERROR; - -#else - - nxt_thread_log_error(jbs->resolve.log_level, - "IPv6 socket \"%V\" is not supported", &jbs->addr); - return NXT_ERROR; - -#endif -} - - -static nxt_int_t -nxt_job_sockaddr_inet_parse(nxt_job_sockaddr_parse_t *jbs) -{ - u_char *p, *host; - size_t length; - nxt_mp_t *mp; - nxt_int_t port; - in_addr_t addr; - nxt_sockaddr_t *sa; - - addr = INADDR_ANY; - - length = jbs->addr.length; - host = jbs->addr.start; - - p = nxt_memchr(host, ':', length); - - if (p == NULL) { - - /* single value port, address, or host name */ - - port = nxt_int_parse(host, length); - - if (port > 0) { - if (port < 1 || port > 65535) { - goto invalid_port; - } - - /* "*:XX" */ - port = htons((in_port_t) port); - jbs->resolve.port = (in_port_t) port; - - } else { - jbs->no_port = 1; - - addr = nxt_inet_addr(host, length); - - if (addr == INADDR_NONE) { - jbs->resolve.name.length = length; - jbs->resolve.name.start = host; - - nxt_job_resolve(&jbs->resolve); - return NXT_AGAIN; - } - - /* "x.x.x.x" */ - port = jbs->resolve.port; - } - - } else { - - /* x.x.x.x:XX or host:XX */ - - p++; - length = (host + length) - p; - port = nxt_int_parse(p, length); - - if (port < 1 || port > 65535) { - goto invalid_port; - } - - port = htons((in_port_t) port); - - length = (p - 1) - host; - - if (length != 1 || host[0] != '*') { - addr = nxt_inet_addr(host, length); - - if (addr == INADDR_NONE) { - jbs->resolve.name.length = length; - jbs->resolve.name.start = host; - jbs->resolve.port = (in_port_t) port; - - nxt_job_resolve(&jbs->resolve); - return NXT_AGAIN; - } - - /* "x.x.x.x:XX" */ - } - } - - mp = jbs->resolve.job.mem_pool; - - jbs->resolve.sockaddrs = nxt_mp_alloc(mp, sizeof(void *)); - if (nxt_slow_path(jbs->resolve.sockaddrs == NULL)) { - return NXT_ERROR; - } - - sa = nxt_sockaddr_alloc(mp, sizeof(struct sockaddr_in), - NXT_INET_ADDR_STR_LEN); - - if (nxt_fast_path(sa != NULL)) { - jbs->resolve.count = 1; - jbs->resolve.sockaddrs[0] = sa; - - jbs->wildcard = (addr == INADDR_ANY); - - sa->u.sockaddr_in.sin_family = AF_INET; - sa->u.sockaddr_in.sin_port = (in_port_t) port; - sa->u.sockaddr_in.sin_addr.s_addr = addr; - - return NXT_OK; - } - - return NXT_ERROR; - -invalid_port: - - nxt_thread_log_error(jbs->resolve.log_level, - "invalid port in \"%V\"", &jbs->addr); - - return NXT_ERROR; -} - - in_addr_t nxt_inet_addr(u_char *buf, size_t length) { diff --git a/src/nxt_sockaddr.h b/src/nxt_sockaddr.h index a8f1b393..0f96f6dd 100644 --- a/src/nxt_sockaddr.h +++ b/src/nxt_sockaddr.h @@ -58,15 +58,6 @@ struct nxt_sockaddr_s { }; -typedef struct { - nxt_job_resolve_t resolve; - nxt_str_t addr; - - uint8_t wildcard; /* 1 bit */ - uint8_t no_port; /* 1 bit */ -} nxt_job_sockaddr_parse_t; - - nxt_sockaddr_t *nxt_sockaddr_cache_alloc(nxt_event_engine_t *engine, nxt_listen_socket_t *ls); void nxt_sockaddr_cache_free(nxt_event_engine_t *engine, nxt_conn_t *c); @@ -88,12 +79,9 @@ NXT_EXPORT void nxt_sockaddr_text(nxt_sockaddr_t *sa); NXT_EXPORT uint32_t nxt_sockaddr_port_number(nxt_sockaddr_t *sa); NXT_EXPORT nxt_bool_t nxt_sockaddr_cmp(nxt_sockaddr_t *sa1, nxt_sockaddr_t *sa2); -NXT_EXPORT size_t nxt_sockaddr_ntop(nxt_sockaddr_t *sa, u_char *buf, - u_char *end, nxt_bool_t port); NXT_EXPORT nxt_sockaddr_t *nxt_sockaddr_parse(nxt_mp_t *mp, nxt_str_t *addr); NXT_EXPORT nxt_sockaddr_t *nxt_sockaddr_parse_optport(nxt_mp_t *mp, nxt_str_t *addr); -NXT_EXPORT void nxt_job_sockaddr_parse(nxt_job_sockaddr_parse_t *jbs); NXT_EXPORT in_addr_t nxt_inet_addr(u_char *buf, size_t len); #if (NXT_INET6) NXT_EXPORT nxt_int_t nxt_inet6_addr(struct in6_addr *in6_addr, u_char *buf, diff --git a/src/nxt_status.c b/src/nxt_status.c new file mode 100644 index 00000000..f8002e86 --- /dev/null +++ b/src/nxt_status.c @@ -0,0 +1,105 @@ + +/* + * Copyright (C) NGINX, Inc. + */ + +#include <nxt_main.h> +#include <nxt_conf.h> +#include <nxt_status.h> + + +nxt_conf_value_t * +nxt_status_get(nxt_status_report_t *report, nxt_mp_t *mp) +{ + size_t i; + nxt_str_t name; + nxt_int_t ret; + nxt_status_app_t *app; + nxt_conf_value_t *status, *obj, *apps, *app_obj; + + static nxt_str_t conns_str = nxt_string("connections"); + static nxt_str_t acc_str = nxt_string("accepted"); + static nxt_str_t active_str = nxt_string("active"); + static nxt_str_t idle_str = nxt_string("idle"); + static nxt_str_t closed_str = nxt_string("closed"); + static nxt_str_t reqs_str = nxt_string("requests"); + static nxt_str_t total_str = nxt_string("total"); + static nxt_str_t apps_str = nxt_string("applications"); + static nxt_str_t procs_str = nxt_string("processes"); + static nxt_str_t run_str = nxt_string("running"); + static nxt_str_t start_str = nxt_string("starting"); + + status = nxt_conf_create_object(mp, 3); + if (nxt_slow_path(status == NULL)) { + return NULL; + } + + obj = nxt_conf_create_object(mp, 4); + if (nxt_slow_path(obj == NULL)) { + return NULL; + } + + nxt_conf_set_member(status, &conns_str, obj, 0); + + nxt_conf_set_member_integer(obj, &acc_str, report->accepted_conns, 0); + nxt_conf_set_member_integer(obj, &active_str, report->accepted_conns + - report->closed_conns + - report->idle_conns, 1); + nxt_conf_set_member_integer(obj, &idle_str, report->idle_conns, 2); + nxt_conf_set_member_integer(obj, &closed_str, report->closed_conns, 3); + + obj = nxt_conf_create_object(mp, 1); + if (nxt_slow_path(obj == NULL)) { + return NULL; + } + + nxt_conf_set_member(status, &reqs_str, obj, 1); + + nxt_conf_set_member_integer(obj, &total_str, report->requests, 0); + + apps = nxt_conf_create_object(mp, report->apps_count); + if (nxt_slow_path(apps == NULL)) { + return NULL; + } + + nxt_conf_set_member(status, &apps_str, apps, 2); + + for (i = 0; i < report->apps_count; i++) { + app = &report->apps[i]; + + app_obj = nxt_conf_create_object(mp, 2); + if (nxt_slow_path(app_obj == NULL)) { + return NULL; + } + + name.length = app->name.length; + name.start = nxt_pointer_to(report, (uintptr_t) app->name.start); + + ret = nxt_conf_set_member_dup(apps, mp, &name, app_obj, i); + if (nxt_slow_path(ret != NXT_OK)) { + return NULL; + } + + obj = nxt_conf_create_object(mp, 3); + if (nxt_slow_path(obj == NULL)) { + return NULL; + } + + nxt_conf_set_member(app_obj, &procs_str, obj, 0); + + nxt_conf_set_member_integer(obj, &run_str, app->processes, 0); + nxt_conf_set_member_integer(obj, &start_str, app->pending_processes, 1); + nxt_conf_set_member_integer(obj, &idle_str, app->idle_processes, 2); + + obj = nxt_conf_create_object(mp, 1); + if (nxt_slow_path(obj == NULL)) { + return NULL; + } + + nxt_conf_set_member(app_obj, &reqs_str, obj, 1); + + nxt_conf_set_member_integer(obj, &active_str, app->active_requests, 0); + } + + return status; +} diff --git a/src/nxt_status.h b/src/nxt_status.h new file mode 100644 index 00000000..a99ac7d0 --- /dev/null +++ b/src/nxt_status.h @@ -0,0 +1,33 @@ + +/* + * Copyright (C) NGINX, Inc. + */ + +#ifndef _NXT_STATUS_H_INCLUDED_ +#define _NXT_STATUS_H_INCLUDED_ + + +typedef struct { + nxt_str_t name; + uint32_t active_requests; + uint32_t pending_processes; + uint32_t processes; + uint32_t idle_processes; +} nxt_status_app_t; + + +typedef struct { + uint64_t accepted_conns; + uint64_t idle_conns; + uint64_t closed_conns; + uint64_t requests; + + size_t apps_count; + nxt_status_app_t apps[]; +} nxt_status_report_t; + + +nxt_conf_value_t *nxt_status_get(nxt_status_report_t *report, nxt_mp_t *mp); + + +#endif /* _NXT_STATUS_H_INCLUDED_ */ diff --git a/src/nxt_string.c b/src/nxt_string.c index b7aef79e..4d89c23c 100644 --- a/src/nxt_string.c +++ b/src/nxt_string.c @@ -338,7 +338,7 @@ nxt_rmemstrn(const u_char *s, const u_char *end, const char *ss, size_t length) size_t -nxt_str_strip(u_char *start, u_char *end) +nxt_str_strip(const u_char *start, u_char *end) { u_char *p; diff --git a/src/nxt_string.h b/src/nxt_string.h index 80cdbb59..a8673c61 100644 --- a/src/nxt_string.h +++ b/src/nxt_string.h @@ -96,7 +96,7 @@ NXT_EXPORT u_char *nxt_memcasestrn(const u_char *s, const u_char *end, const char *ss, size_t length); NXT_EXPORT u_char *nxt_rmemstrn(const u_char *s, const u_char *end, const char *ss, size_t length); -NXT_EXPORT size_t nxt_str_strip(u_char *start, u_char *end); +NXT_EXPORT size_t nxt_str_strip(const u_char *start, u_char *end); typedef struct { diff --git a/src/nxt_time_parse.c b/src/nxt_time_parse.c index 94c43289..63620b09 100644 --- a/src/nxt_time_parse.c +++ b/src/nxt_time_parse.c @@ -22,7 +22,7 @@ nxt_time_parse(const u_char *p, size_t len) nxt_uint_t year, days; const u_char *end; - static nxt_int_t mday[12] = { + static const nxt_int_t mday[12] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }; diff --git a/src/nxt_unit.c b/src/nxt_unit.c index 32bb07ab..e5cb0b58 100644 --- a/src/nxt_unit.c +++ b/src/nxt_unit.c @@ -196,7 +196,8 @@ static int nxt_unit_request_hash_add(nxt_unit_ctx_t *ctx, static nxt_unit_request_info_t *nxt_unit_request_hash_find( nxt_unit_ctx_t *ctx, uint32_t stream, int remove); -static char * nxt_unit_snprint_prefix(char *p, char *end, pid_t pid, int level); +static char * nxt_unit_snprint_prefix(char *p, const char *end, pid_t pid, + int level); static void *nxt_unit_lvlhsh_alloc(void *data, size_t size); static void nxt_unit_lvlhsh_free(void *data, void *p); static int nxt_unit_memcasecmp(const void *p1, const void *p2, size_t length); @@ -584,9 +585,14 @@ fail: static nxt_unit_impl_t * nxt_unit_create(nxt_unit_init_t *init) { - int rc; - nxt_unit_impl_t *lib; - nxt_unit_callbacks_t *cb; + int rc; + nxt_unit_impl_t *lib; + + if (nxt_slow_path(init->callbacks.request_handler == NULL)) { + nxt_unit_alert(NULL, "request_handler is NULL"); + + return NULL; + } lib = nxt_unit_malloc(NULL, sizeof(nxt_unit_impl_t) + init->request_data_size); @@ -629,15 +635,6 @@ nxt_unit_create(nxt_unit_init_t *init) goto fail; } - cb = &lib->callbacks; - - if (cb->request_handler == NULL) { - nxt_unit_alert(NULL, "request_handler is NULL"); - - pthread_mutex_destroy(&lib->mutex); - goto fail; - } - nxt_unit_mmaps_init(&lib->incoming); nxt_unit_mmaps_init(&lib->outgoing); @@ -942,7 +939,6 @@ nxt_unit_ready(nxt_unit_ctx_t *ctx, int ready_fd, uint32_t stream, int queue_fd) msg.mmap = 0; msg.nf = 0; msg.mf = 0; - msg.tracking = 0; nxt_socket_msg_oob_init(&oob, fds); @@ -2644,7 +2640,6 @@ nxt_unit_mmap_buf_send(nxt_unit_request_info_t *req, m.msg.mmap = hdr != NULL && m.mmap_msg.size > 0; m.msg.nf = 0; m.msg.mf = 0; - m.msg.tracking = 0; rc = NXT_UNIT_ERROR; @@ -3077,7 +3072,6 @@ nxt_unit_request_read(nxt_unit_request_info_t *req, void *dst, size_t size) } req->content_length -= res; - size -= res; dst = nxt_pointer_to(dst, res); @@ -3296,7 +3290,6 @@ skip_response_send: msg.mmap = 0; msg.nf = 0; msg.mf = 0; - msg.tracking = 0; (void) nxt_unit_port_send(req->ctx, req->response_port, &msg, sizeof(msg), NULL); @@ -3619,7 +3612,6 @@ nxt_unit_send_oosm(nxt_unit_ctx_t *ctx, nxt_unit_port_t *port) msg.mmap = 0; msg.nf = 0; msg.mf = 0; - msg.tracking = 0; res = nxt_unit_port_send(ctx, lib->router_port, &msg, sizeof(msg), NULL); if (nxt_slow_path(res != sizeof(msg))) { @@ -3816,13 +3808,12 @@ static int nxt_unit_shm_open(nxt_unit_ctx_t *ctx, size_t size) { int fd; - nxt_unit_impl_t *lib; - - lib = nxt_container_of(ctx->unit, nxt_unit_impl_t, unit); #if (NXT_HAVE_MEMFD_CREATE || NXT_HAVE_SHM_OPEN) char name[64]; + nxt_unit_impl_t *lib; + lib = nxt_container_of(ctx->unit, nxt_unit_impl_t, unit); snprintf(name, sizeof(name), NXT_SHM_PREFIX "unit.%d.%p", lib->pid, (void *) (uintptr_t) pthread_self()); #endif @@ -3905,7 +3896,6 @@ nxt_unit_send_mmap(nxt_unit_ctx_t *ctx, nxt_unit_port_t *port, int fd) msg.mmap = 0; msg.nf = 0; msg.mf = 0; - msg.tracking = 0; nxt_socket_msg_oob_init(&oob, fds); @@ -4390,7 +4380,6 @@ nxt_unit_send_shm_ack(nxt_unit_ctx_t *ctx, pid_t pid) msg.mmap = 0; msg.nf = 0; msg.mf = 0; - msg.tracking = 0; res = nxt_unit_port_send(ctx, lib->router_port, &msg, sizeof(msg), NULL); if (nxt_slow_path(res != sizeof(msg))) { @@ -5356,7 +5345,6 @@ nxt_unit_send_port(nxt_unit_ctx_t *ctx, nxt_unit_port_t *dst, m.msg.mmap = 0; m.msg.nf = 0; m.msg.mf = 0; - m.msg.tracking = 0; m.new_port.id = port->id.id; m.new_port.pid = port->id.pid; @@ -6673,7 +6661,7 @@ static const char * nxt_unit_log_levels[] = { static char * -nxt_unit_snprint_prefix(char *p, char *end, pid_t pid, int level) +nxt_unit_snprint_prefix(char *p, const char *end, pid_t pid, int level) { struct tm tm; struct timespec ts; diff --git a/src/nxt_unix.h b/src/nxt_unix.h index d8eaabc3..6bc6be5e 100644 --- a/src/nxt_unix.h +++ b/src/nxt_unix.h @@ -156,9 +156,7 @@ #include <setjmp.h> #include <sched.h> #include <signal.h> -#if (NXT_HAVE_POSIX_SPAWN) #include <spawn.h> -#endif #include <stdarg.h> #include <stddef.h> /* offsetof() */ #include <stdio.h> diff --git a/src/nxt_var.c b/src/nxt_var.c index 0a722d17..f55a2d30 100644 --- a/src/nxt_var.c +++ b/src/nxt_var.c @@ -9,7 +9,7 @@ struct nxt_var_s { size_t length; nxt_uint_t vars; - uint8_t strz; /* 1 bit */ + nxt_var_flags_t flags; u_char data[]; /* @@ -26,19 +26,12 @@ typedef struct { } nxt_var_sub_t; -typedef struct { - nxt_var_t *var; - nxt_str_t *value; -} nxt_var_value_t; - - struct nxt_var_query_s { - nxt_array_t values; /* of nxt_var_value_t */ - nxt_array_t parts; /* of nxt_str_t * */ + nxt_mp_t *pool; nxt_lvlhsh_t cache; - nxt_str_t *spare; + nxt_uint_t waiting; nxt_uint_t failed; /* 1 bit */ @@ -59,16 +52,18 @@ struct nxt_var_query_s { static nxt_int_t nxt_var_hash_test(nxt_lvlhsh_query_t *lhq, void *data); static nxt_var_decl_t *nxt_var_hash_find(nxt_str_t *name); +static nxt_var_decl_t *nxt_var_decl_get(nxt_str_t *name, nxt_array_t *fields, + uint32_t *index); +static nxt_var_field_t *nxt_var_field_add(nxt_array_t *fields, nxt_str_t *name, + uint32_t hash); + static nxt_int_t nxt_var_cache_test(nxt_lvlhsh_query_t *lhq, void *data); -static nxt_str_t *nxt_var_cache_find(nxt_lvlhsh_t *lh, uint32_t index); -static nxt_int_t nxt_var_cache_add(nxt_lvlhsh_t *lh, uint32_t index, - nxt_str_t *value, nxt_mp_t *mp); +static nxt_str_t *nxt_var_cache_value(nxt_task_t *task, nxt_var_query_t *query, + uint32_t index); static u_char *nxt_var_next_part(u_char *start, size_t length, nxt_str_t *part, nxt_bool_t *is_var); -static void nxt_var_query_finish(nxt_task_t *task, nxt_var_query_t *query); - static const nxt_lvlhsh_proto_t nxt_var_hash_proto nxt_aligned(64) = { NXT_LVLHSH_DEFAULT, @@ -91,21 +86,6 @@ static uint32_t nxt_var_count; static nxt_var_handler_t *nxt_var_index; -void -nxt_var_raw(nxt_var_t *var, nxt_str_t *str) -{ - str->length = var->length; - str->start = nxt_var_raw_start(var); -} - - -nxt_bool_t -nxt_var_is_const(nxt_var_t *var) -{ - return (var->vars == 0); -} - - static nxt_int_t nxt_var_hash_test(nxt_lvlhsh_query_t *lhq, void *data) { @@ -134,46 +114,166 @@ nxt_var_hash_find(nxt_str_t *name) } -static nxt_int_t -nxt_var_cache_test(nxt_lvlhsh_query_t *lhq, void *data) +static nxt_var_decl_t * +nxt_var_decl_get(nxt_str_t *name, nxt_array_t *fields, uint32_t *index) { - return NXT_OK; + u_char *p, *end; + int64_t hash; + uint16_t field; + nxt_str_t str; + nxt_var_decl_t *decl; + nxt_var_field_t *f; + + f = NULL; + field = 0; + decl = nxt_var_hash_find(name); + + if (decl == NULL) { + p = name->start; + end = p + name->length; + + while (p < end) { + if (*p++ == '_') { + break; + } + } + + if (p == end) { + return NULL; + } + + str.start = name->start; + str.length = p - 1 - name->start; + + decl = nxt_var_hash_find(&str); + + if (decl != NULL) { + str.start = p; + str.length = end - p; + + hash = decl->field_hash(fields->mem_pool, &str); + if (nxt_slow_path(hash == -1)) { + return NULL; + } + + f = nxt_var_field_add(fields, &str, (uint32_t) hash); + if (nxt_slow_path(f == NULL)) { + return NULL; + } + + field = f->index; + } + } + + if (decl != NULL) { + if (decl->field_hash != NULL && f == NULL) { + return NULL; + } + + if (index != NULL) { + *index = (decl->index << 16) | field; + } + } + + return decl; } -static nxt_str_t * -nxt_var_cache_find(nxt_lvlhsh_t *lh, uint32_t index) +static nxt_var_field_t * +nxt_var_field_add(nxt_array_t *fields, nxt_str_t *name, uint32_t hash) { - nxt_lvlhsh_query_t lhq; + nxt_uint_t i; + nxt_var_field_t *field; - lhq.key_hash = nxt_murmur_hash2_uint32(&index); - lhq.key.length = sizeof(uint32_t); - lhq.key.start = (u_char *) &index; - lhq.proto = &nxt_var_cache_proto; + field = fields->elts; - if (nxt_lvlhsh_find(lh, &lhq) != NXT_OK) { + for (i = 0; i < fields->nelts; i++) { + if (field[i].hash == hash + && nxt_strstr_eq(&field[i].name, name)) + { + return field; + } + } + + field = nxt_array_add(fields); + if (nxt_slow_path(field == NULL)) { return NULL; } - return lhq.value; + field->name = *name; + field->hash = hash; + field->index = fields->nelts - 1; + + return field; +} + + +nxt_var_field_t * +nxt_var_field_get(nxt_array_t *fields, uint16_t index) +{ + nxt_uint_t nfields; + nxt_var_field_t *field; + + field = fields->elts; + nfields = fields->nelts; + + if (nfields > 0 && index <= nfields) { + return &field[index]; + } + + return NULL; } static nxt_int_t -nxt_var_cache_add(nxt_lvlhsh_t *lh, uint32_t index, nxt_str_t *value, - nxt_mp_t *mp) +nxt_var_cache_test(nxt_lvlhsh_query_t *lhq, void *data) { + return NXT_OK; +} + + +static nxt_str_t * +nxt_var_cache_value(nxt_task_t *task, nxt_var_query_t *query, uint32_t index) +{ + nxt_int_t ret; + nxt_str_t *value; nxt_lvlhsh_query_t lhq; + value = query->spare; + + if (value == NULL) { + value = nxt_mp_zget(query->pool, sizeof(nxt_str_t)); + if (nxt_slow_path(value == NULL)) { + return NULL; + } + + query->spare = value; + } + lhq.key_hash = nxt_murmur_hash2_uint32(&index); lhq.replace = 0; lhq.key.length = sizeof(uint32_t); lhq.key.start = (u_char *) &index; lhq.value = value; lhq.proto = &nxt_var_cache_proto; - lhq.pool = mp; + lhq.pool = query->pool; - return nxt_lvlhsh_insert(lh, &lhq); + ret = nxt_lvlhsh_insert(&query->cache, &lhq); + if (nxt_slow_path(ret == NXT_ERROR)) { + return NULL; + } + + if (ret == NXT_OK) { + ret = nxt_var_index[index >> 16](task, value, query->ctx, + index & 0xffff); + if (nxt_slow_path(ret != NXT_OK)) { + return NULL; + } + + query->spare = NULL; + } + + return lhq.value; } @@ -230,10 +330,13 @@ nxt_var_index_init(void) nxt_var_t * -nxt_var_compile(nxt_str_t *str, nxt_mp_t *mp, nxt_bool_t strz) +nxt_var_compile(nxt_str_t *str, nxt_mp_t *mp, nxt_array_t *fields, + nxt_var_flags_t flags) { u_char *p, *end, *next, *src; size_t size; + uint32_t index; + nxt_bool_t strz; nxt_var_t *var; nxt_str_t part; nxt_uint_t n; @@ -241,6 +344,8 @@ nxt_var_compile(nxt_str_t *str, nxt_mp_t *mp, nxt_bool_t strz) nxt_var_sub_t *subs; nxt_var_decl_t *decl; + strz = (flags & NXT_VAR_STRZ) != 0; + n = 0; p = str->start; @@ -266,7 +371,7 @@ nxt_var_compile(nxt_str_t *str, nxt_mp_t *mp, nxt_bool_t strz) var->length = str->length; var->vars = n; - var->strz = strz; + var->flags = flags; subs = nxt_var_subs(var); src = nxt_var_raw_start(var); @@ -284,12 +389,12 @@ nxt_var_compile(nxt_str_t *str, nxt_mp_t *mp, nxt_bool_t strz) next = nxt_var_next_part(p, end - p, &part, &is_var); if (is_var) { - decl = nxt_var_hash_find(&part); + decl = nxt_var_decl_get(&part, fields, &index); if (nxt_slow_path(decl == NULL)) { return NULL; } - subs[n].index = decl->index; + subs[n].index = index; subs[n].length = next - p; subs[n].position = p - str->start; @@ -304,7 +409,7 @@ nxt_var_compile(nxt_str_t *str, nxt_mp_t *mp, nxt_bool_t strz) nxt_int_t -nxt_var_test(nxt_str_t *str, u_char *error) +nxt_var_test(nxt_str_t *str, nxt_array_t *fields, u_char *error) { u_char *p, *end, *next; nxt_str_t part; @@ -325,7 +430,7 @@ nxt_var_test(nxt_str_t *str, u_char *error) } if (is_var) { - decl = nxt_var_hash_find(&part); + decl = nxt_var_decl_get(&part, fields, NULL); if (decl == NULL) { nxt_sprintf(error, error + NXT_MAX_ERROR_STR, @@ -420,6 +525,21 @@ nxt_var_next_part(u_char *start, size_t length, nxt_str_t *part, } +inline void +nxt_var_raw(nxt_var_t *var, nxt_str_t *str) +{ + str->length = var->length; + str->start = nxt_var_raw_start(var); +} + + +inline nxt_bool_t +nxt_var_is_const(nxt_var_t *var) +{ + return (var->vars == 0); +} + + nxt_int_t nxt_var_query_init(nxt_var_query_t **query_p, void *ctx, nxt_mp_t *mp) { @@ -432,14 +552,9 @@ nxt_var_query_init(nxt_var_query_t **query_p, void *ctx, nxt_mp_t *mp) if (nxt_slow_path(query == NULL)) { return NXT_ERROR; } - - nxt_array_init(&query->values, mp, sizeof(nxt_var_value_t)); - nxt_array_init(&query->parts, mp, sizeof(nxt_str_t *)); - - } else { - nxt_array_reset(&query->values); } + query->pool = mp; query->ctx = ctx; *query_p = query; @@ -452,13 +567,13 @@ void nxt_var_query(nxt_task_t *task, nxt_var_query_t *query, nxt_var_t *var, nxt_str_t *str) { - uint32_t index; - nxt_mp_t *mp; - nxt_str_t *value; - nxt_int_t ret; - nxt_uint_t i; - nxt_var_sub_t *subs; - nxt_var_value_t *val; + u_char *p, *src; + size_t length, last, next; + nxt_str_t *value, **part; + nxt_uint_t i; + nxt_bool_t strz, logging; + nxt_array_t parts; + nxt_var_sub_t *subs; if (nxt_var_is_const(var)) { nxt_var_raw(var, str); @@ -469,53 +584,74 @@ nxt_var_query(nxt_task_t *task, nxt_var_query_t *query, nxt_var_t *var, return; } - mp = query->values.mem_pool; + nxt_memzero(&parts, sizeof(nxt_array_t)); + nxt_array_init(&parts, query->pool, sizeof(nxt_str_t *)); + + strz = (var->flags & NXT_VAR_STRZ) != 0; + logging = (var->flags & NXT_VAR_LOGGING) != 0; + subs = nxt_var_subs(var); - value = query->spare; - for (i = 0; i < var->vars; i++) { + length = var->length; - if (value == NULL) { - value = nxt_mp_zget(mp, sizeof(nxt_str_t)); - if (nxt_slow_path(value == NULL)) { - goto fail; - } + for (i = 0; i < var->vars; i++) { + value = nxt_var_cache_value(task, query, subs[i].index); + if (nxt_slow_path(value == NULL)) { + goto fail; } - index = subs[i].index; + part = nxt_array_add(&parts); + if (nxt_slow_path(part == NULL)) { + goto fail; + } - ret = nxt_var_cache_add(&query->cache, index, value, mp); + *part = value; - if (ret != NXT_OK) { - if (nxt_slow_path(ret == NXT_ERROR)) { - goto fail; - } + length += value->length - subs[i].length; - continue; /* NXT_DECLINED */ + if (logging && value->start == NULL) { + length += 1; } + } - ret = nxt_var_index[index](task, query, value, query->ctx); + p = nxt_mp_nget(query->pool, length + strz); + if (nxt_slow_path(p == NULL)) { + goto fail; + } - value = NULL; + str->length = length; + str->start = p; - if (ret != NXT_OK) { - if (nxt_slow_path(ret != NXT_AGAIN)) { - goto fail; - } + part = parts.elts; + src = nxt_var_raw_start(var); + + last = 0; - query->waiting++; + for (i = 0; i < var->vars; i++) { + next = subs[i].position; + + if (next != last) { + p = nxt_cpymem(p, &src[last], next - last); } + + p = nxt_cpymem(p, part[i]->start, part[i]->length); + + if (logging && part[i]->start == NULL) { + *p++ = '-'; + } + + last = next + subs[i].length; } - query->spare = value; + if (last != var->length) { + p = nxt_cpymem(p, &src[last], var->length - last); + } - val = nxt_array_add(&query->values); - if (nxt_slow_path(val == NULL)) { - goto fail; + if (strz) { + *p = '\0'; } - val->var = var; - val->value = str; + nxt_debug(task, "var: \"%*s\" -> \"%V\"", length, src, str); return; @@ -534,7 +670,9 @@ nxt_var_query_resolve(nxt_task_t *task, nxt_var_query_t *query, void *data, query->error = error; if (query->waiting == 0) { - nxt_var_query_finish(task, query); + nxt_work_queue_add(&task->thread->engine->fast_work_queue, + query->failed ? query->error : query->ready, + task, query->ctx, query->data); } } @@ -546,94 +684,8 @@ nxt_var_query_handle(nxt_task_t *task, nxt_var_query_t *query, query->failed |= failed; if (--query->waiting == 0) { - nxt_var_query_finish(task, query); - } -} - - -static void -nxt_var_query_finish(nxt_task_t *task, nxt_var_query_t *query) -{ - u_char *p, *src; - size_t length, last, next; - nxt_str_t *str, **part; - nxt_var_t *var; - nxt_uint_t i, j; - nxt_var_sub_t *subs; - nxt_var_value_t *val; - - if (query->failed) { - goto done; + nxt_work_queue_add(&task->thread->engine->fast_work_queue, + query->failed ? query->error : query->ready, + task, query->ctx, query->data); } - - val = query->values.elts; - - for (i = 0; i < query->values.nelts; i++) { - var = val[i].var; - - subs = nxt_var_subs(var); - length = var->length; - - for (j = 0; j < var->vars; j++) { - str = nxt_var_cache_find(&query->cache, subs[j].index); - - nxt_assert(str != NULL); - - part = nxt_array_add(&query->parts); - - if (nxt_slow_path(part == NULL)) { - query->failed = 1; - goto done; - } - - *part = str; - - length += str->length - subs[j].length; - } - - p = nxt_mp_nget(query->values.mem_pool, length + var->strz); - if (nxt_slow_path(p == NULL)) { - query->failed = 1; - goto done; - } - - val[i].value->length = length; - val[i].value->start = p; - - part = query->parts.elts; - src = nxt_var_raw_start(var); - - last = 0; - - for (j = 0; j < var->vars; j++) { - next = subs[j].position; - - if (next != last) { - p = nxt_cpymem(p, &src[last], next - last); - } - - p = nxt_cpymem(p, part[j]->start, part[j]->length); - - last = next + subs[j].length; - } - - if (last != var->length) { - p = nxt_cpymem(p, &src[last], var->length - last); - } - - if (var->strz) { - *p = '\0'; - } - - nxt_array_reset(&query->parts); - - nxt_debug(task, "var: \"%*s\" -> \"%V\"", var->length, src, - val[i].value); - } - -done: - - nxt_work_queue_add(&task->thread->engine->fast_work_queue, - query->failed ? query->error : query->ready, - task, query->ctx, query->data); } diff --git a/src/nxt_var.h b/src/nxt_var.h index 3b7d0c28..cc7ff502 100644 --- a/src/nxt_var.h +++ b/src/nxt_var.h @@ -12,17 +12,32 @@ typedef struct nxt_var_query_s nxt_var_query_t; typedef nxt_int_t (*nxt_var_handler_t)(nxt_task_t *task, - nxt_var_query_t *query, nxt_str_t *str, - void *ctx); + void *ctx, uint16_t field); + +typedef int64_t (*nxt_var_field_hash_t)(nxt_mp_t *mp, nxt_str_t *str); typedef struct { - nxt_str_t name; - nxt_var_handler_t handler; - uint32_t index; + nxt_str_t name; + nxt_var_handler_t handler; + nxt_var_field_hash_t field_hash; + uint32_t index; } nxt_var_decl_t; +typedef struct { + nxt_str_t name; + uint16_t hash; + uint32_t index; +} nxt_var_field_t; + + +typedef enum { + NXT_VAR_STRZ = 1 << 0, + NXT_VAR_LOGGING = 1 << 1, +} nxt_var_flags_t; + + nxt_inline nxt_bool_t nxt_is_var(nxt_str_t *str) { @@ -30,13 +45,17 @@ nxt_is_var(nxt_str_t *str) } -void nxt_var_raw(nxt_var_t *var, nxt_str_t *str); -nxt_bool_t nxt_var_is_const(nxt_var_t *var); - nxt_int_t nxt_var_register(nxt_var_decl_t *decl, size_t n); nxt_int_t nxt_var_index_init(void); -nxt_var_t *nxt_var_compile(nxt_str_t *str, nxt_mp_t *mp, nxt_bool_t strz); -nxt_int_t nxt_var_test(nxt_str_t *str, u_char *error); + +nxt_var_field_t *nxt_var_field_get(nxt_array_t *fields, uint16_t index); + +nxt_var_t *nxt_var_compile(nxt_str_t *str, nxt_mp_t *mp, nxt_array_t *fields, + nxt_var_flags_t flags); +nxt_int_t nxt_var_test(nxt_str_t *str, nxt_array_t *fields, u_char *error); + +nxt_bool_t nxt_var_is_const(nxt_var_t *var); +void nxt_var_raw(nxt_var_t *var, nxt_str_t *str); nxt_int_t nxt_var_query_init(nxt_var_query_t **query_p, void *ctx, nxt_mp_t *mp); diff --git a/src/nxt_websocket_accept.c b/src/nxt_websocket_accept.c index 05cbcb56..0e2cef58 100644 --- a/src/nxt_websocket_accept.c +++ b/src/nxt_websocket_accept.c @@ -11,8 +11,8 @@ static void nxt_websocket_base64_encode(u_char *d, const uint8_t *s, size_t len) { - u_char c0, c1, c2; - static u_char basis[] = + u_char c0, c1, c2; + static const u_char basis[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; while (len > 2) { diff --git a/src/python/nxt_python_asgi.c b/src/python/nxt_python_asgi.c index 91af8f4b..4ad0857d 100644 --- a/src/python/nxt_python_asgi.c +++ b/src/python/nxt_python_asgi.c @@ -30,6 +30,8 @@ static void nxt_py_asgi_close_handler(nxt_unit_request_info_t *req); static PyObject *nxt_py_asgi_create_http_scope(nxt_unit_request_info_t *req); static PyObject *nxt_py_asgi_create_address(nxt_unit_sptr_t *sptr, uint8_t len, uint16_t port); +static PyObject *nxt_py_asgi_create_ip_address(nxt_unit_sptr_t *sptr, + uint8_t len, uint16_t port); static PyObject *nxt_py_asgi_create_header(nxt_unit_field_t *f); static PyObject *nxt_py_asgi_create_subprotocols(nxt_unit_field_t *f); @@ -736,6 +738,48 @@ fail: static PyObject * nxt_py_asgi_create_address(nxt_unit_sptr_t *sptr, uint8_t len, uint16_t port) { + size_t prefix_len; + nxt_str_t addr; + PyObject *pair, *v; + + addr.length = len; + addr.start = nxt_unit_sptr_get(sptr); + + prefix_len = nxt_length("unix:"); + if (!nxt_str_start(&addr, "unix:", prefix_len)) { + return nxt_py_asgi_create_ip_address(sptr, len, port); + } + +#if NXT_HAVE_UNIX_DOMAIN + pair = PyTuple_New(2); + if (nxt_slow_path(pair == NULL)) { + return NULL; + } + + addr.start += prefix_len; + addr.length -= prefix_len; + + v = PyString_FromStringAndSize((const char *) addr.start, addr.length); + if (nxt_slow_path(v == NULL)) { + Py_DECREF(pair); + + return NULL; + } + + PyTuple_SET_ITEM(pair, 0, v); + PyTuple_SET_ITEM(pair, 1, Py_None); + + return pair; + +#else + return NULL; +#endif +} + + +static PyObject * +nxt_py_asgi_create_ip_address(nxt_unit_sptr_t *sptr, uint8_t len, uint16_t port) +{ char *p, *s; PyObject *pair, *v; diff --git a/src/ruby/nxt_ruby.c b/src/ruby/nxt_ruby.c index 8f4afd35..f316d8a5 100644 --- a/src/ruby/nxt_ruby.c +++ b/src/ruby/nxt_ruby.c @@ -29,7 +29,6 @@ typedef struct { static nxt_int_t nxt_ruby_start(nxt_task_t *task, nxt_process_data_t *data); static VALUE nxt_ruby_init_basic(VALUE arg); -static VALUE nxt_ruby_script_basename(nxt_str_t *script); static VALUE nxt_ruby_hook_procs_load(VALUE path); static VALUE nxt_ruby_hook_register(VALUE arg); @@ -50,7 +49,7 @@ static void *nxt_ruby_thread_create_gvl(void *rctx); static VALUE nxt_ruby_thread_func(VALUE arg); static void *nxt_ruby_unit_run(void *ctx); static void nxt_ruby_ubf(void *ctx); -static int nxt_ruby_init_threads(VALUE script, nxt_ruby_app_conf_t *c); +static int nxt_ruby_init_threads(nxt_ruby_app_conf_t *c); static void nxt_ruby_join_threads(nxt_unit_ctx_t *ctx, nxt_ruby_app_conf_t *c); @@ -261,7 +260,7 @@ static nxt_int_t nxt_ruby_start(nxt_task_t *task, nxt_process_data_t *data) { int state, rc; - VALUE res, path, script; + VALUE res, path; nxt_ruby_ctx_t ruby_ctx; nxt_unit_ctx_t *unit_ctx; nxt_unit_init_t ruby_unit_init; @@ -271,6 +270,8 @@ nxt_ruby_start(nxt_task_t *task, nxt_process_data_t *data) static char *argv[2] = { (char *) "NGINX_Unit", (char *) "-e0" }; + signal(SIGINT, SIG_IGN); + conf = data->app; c = &conf->u.ruby; @@ -283,10 +284,7 @@ nxt_ruby_start(nxt_task_t *task, nxt_process_data_t *data) ruby_options(2, argv); ruby_script("NGINX_Unit"); - script = nxt_ruby_script_basename(&c->script); - ruby_ctx.env = Qnil; - ruby_ctx.script = script; ruby_ctx.io_input = Qnil; ruby_ctx.io_error = Qnil; ruby_ctx.thread = Qnil; @@ -356,7 +354,7 @@ nxt_ruby_start(nxt_task_t *task, nxt_process_data_t *data) goto fail; } - rc = nxt_ruby_init_threads(script, c); + rc = nxt_ruby_init_threads(c); if (nxt_slow_path(rc == NXT_UNIT_ERROR)) { goto fail; } @@ -381,8 +379,8 @@ nxt_ruby_start(nxt_task_t *task, nxt_process_data_t *data) } } - rc = (intptr_t) rb_thread_call_without_gvl(nxt_ruby_unit_run, unit_ctx, - nxt_ruby_ubf, unit_ctx); + rc = (intptr_t) rb_thread_call_without_gvl2(nxt_ruby_unit_run, unit_ctx, + nxt_ruby_ubf, unit_ctx); if (nxt_ruby_hook_procs != Qnil) { rb_protect(nxt_ruby_hook_call, nxt_rb_on_thread_shutdown, &state); @@ -425,37 +423,6 @@ fail: static VALUE -nxt_ruby_script_basename(nxt_str_t *script) -{ - size_t len; - u_char *p, *last; - - last = NULL; - p = script->start + script->length; - - while (p > script->start) { - - if (p[-1] == '/') { - last = p; - break; - } - - p--; - } - - if (last != NULL) { - len = script->length - (last - script->start); - - } else { - last = script->start; - len = script->length; - } - - return rb_str_new((const char *) last, len); -} - - -static VALUE nxt_ruby_init_basic(VALUE arg) { int state; @@ -598,7 +565,7 @@ nxt_ruby_rack_env_create(VALUE arg) rb_ary_push(version, UINT2NUM(NXT_RUBY_RACK_API_VERSION_MAJOR)); rb_ary_push(version, UINT2NUM(NXT_RUBY_RACK_API_VERSION_MINOR)); - rb_hash_aset(hash_env, rb_str_new2("SCRIPT_NAME"), rctx->script); + rb_hash_aset(hash_env, rb_str_new2("SCRIPT_NAME"), rb_str_new("", 0)); rb_hash_aset(hash_env, rb_str_new2("rack.version"), version); rb_hash_aset(hash_env, rb_str_new2("rack.input"), rctx->io_input); rb_hash_aset(hash_env, rb_str_new2("rack.errors"), rctx->io_error); @@ -1393,7 +1360,7 @@ nxt_ruby_ubf(void *ctx) static int -nxt_ruby_init_threads(VALUE script, nxt_ruby_app_conf_t *c) +nxt_ruby_init_threads(nxt_ruby_app_conf_t *c) { int state; uint32_t i; @@ -1415,7 +1382,6 @@ nxt_ruby_init_threads(VALUE script, nxt_ruby_app_conf_t *c) rctx = &nxt_ruby_ctxs[i]; rctx->env = Qnil; - rctx->script = script; rctx->io_input = Qnil; rctx->io_error = Qnil; rctx->thread = Qnil; diff --git a/src/ruby/nxt_ruby.h b/src/ruby/nxt_ruby.h index 3bdd567a..26430021 100644 --- a/src/ruby/nxt_ruby.h +++ b/src/ruby/nxt_ruby.h @@ -22,7 +22,6 @@ typedef struct { VALUE env; - VALUE script; VALUE io_input; VALUE io_error; VALUE thread; diff --git a/test/conftest.py b/test/conftest.py index 904abc32..18851baa 100644 --- a/test/conftest.py +++ b/test/conftest.py @@ -20,9 +20,11 @@ from unit.check.isolation import check_isolation from unit.check.node import check_node from unit.check.regex import check_regex from unit.check.tls import check_openssl +from unit.check.unix_abstract import check_unix_abstract from unit.http import TestHTTP from unit.log import Log from unit.option import option +from unit.status import Status from unit.utils import public_dir from unit.utils import waitforfiles @@ -213,6 +215,7 @@ def pytest_sessionstart(session): check_chroot() check_isolation() + check_unix_abstract() _clear_conf(unit['temp_dir'] + '/control.unit.sock') @@ -427,6 +430,8 @@ def unit_run(state_dir=None): controller['pid'] = pid_by_name(controller['name']) controller['fds'] = _count_fds(controller['pid']) + Status._check_zeros() + return unit_instance diff --git a/test/python/ctx_iter_atexit/wsgi.py b/test/python/ctx_iter_atexit/wsgi.py index b2f12c35..75d40895 100644 --- a/test/python/ctx_iter_atexit/wsgi.py +++ b/test/python/ctx_iter_atexit/wsgi.py @@ -15,7 +15,6 @@ class application: self.start( '200', [ - ('Content-Type', self.environ.get('CONTENT_TYPE')), ('Content-Length', str(len(body))), ], ) diff --git a/test/python/forwarded_header/wsgi.py b/test/python/forwarded_header/wsgi.py new file mode 100644 index 00000000..44d370ab --- /dev/null +++ b/test/python/forwarded_header/wsgi.py @@ -0,0 +1,10 @@ +def application(env, start_response): + start_response( + '200', + [ + ('Content-Length', '0'), + ('Remote-Addr', env.get('REMOTE_ADDR')), + ('Url-Scheme', env.get('wsgi.url_scheme')), + ], + ) + return [] diff --git a/test/test_access_log.py b/test/test_access_log.py index 5d242a1a..b1d89343 100644 --- a/test/test_access_log.py +++ b/test/test_access_log.py @@ -15,6 +15,15 @@ class TestAccessLog(TestApplicationPython): '"' + option.temp_dir + '/access.log"', 'access_log' ), 'access_log configure' + def set_format(self, format): + assert 'success' in self.conf( + { + 'path': option.temp_dir + '/access.log', + 'format': format, + }, + 'access_log', + ), 'access_log format' + def wait_for_record(self, pattern, name='access.log'): return super().wait_for_record(pattern, name) @@ -27,7 +36,6 @@ class TestAccessLog(TestApplicationPython): headers={ 'Host': 'localhost', 'Connection': 'keep-alive', - 'Content-Type': 'text/html', }, start=True, body='01234', @@ -38,15 +46,7 @@ class TestAccessLog(TestApplicationPython): self.wait_for_record(r'"POST / HTTP/1.1" 200 5') is not None ), 'keepalive 1' - resp = self.post( - headers={ - 'Host': 'localhost', - 'Connection': 'close', - 'Content-Type': 'text/html', - }, - sock=sock, - body='0123456789', - ) + resp = self.post(sock=sock, body='0123456789') assert ( self.wait_for_record(r'"POST / HTTP/1.1" 200 10') is not None @@ -263,3 +263,65 @@ Connection: close self.wait_for_record(r'"GET / HTTP/1.1" 200 0 "-" "-"', 'new.log') is not None ), 'change' + + def test_access_log_format(self): + self.load('empty') + + def check_format(format, expect, url='/'): + self.set_format(format) + + assert self.get(url=url)['status'] == 200 + assert self.wait_for_record(expect) is not None, 'found' + + format = 'BLAH\t0123456789' + check_format(format, format) + check_format('$uri $status $uri $status', '/ 200 / 200') + + def test_access_log_variables(self): + self.load('mirror') + + # $time_local + + self.set_format('$uri $time_local $uri') + assert self.get(url='/time_local')['status'] == 200 + assert self.wait_for_record('/time_local') is not None, 'time log' + date = self.search_in_log( + r'^\/time_local (.*) \/time_local$', 'access.log' + )[1] + assert ( + abs( + self.date_to_sec_epoch(date, '%d/%b/%Y:%X %z') + - time.mktime(time.localtime()) + ) + < 5 + ), '$time_local' + + # $request_line + + self.set_format('$request_line') + assert self.get(url='/r_line')['status'] == 200 + assert self.wait_for_record(r'^GET \/r_line HTTP\/1\.1$') is not None + + # $body_bytes_sent + + self.set_format('$uri $body_bytes_sent') + body = '0123456789' * 50 + self.post(url='/bbs', body=body, read_timeout=1) + assert ( + self.wait_for_record(r'^\/bbs ' + str(len(body)) + r'$') is not None + ), '$body_bytes_sent' + + def test_access_log_incorrect(self, skip_alert): + skip_alert(r'failed to apply new conf') + + assert 'error' in self.conf( + option.temp_dir + '/blah/access.log' 'access_log/path', + ), 'access_log path incorrect' + + assert 'error' in self.conf( + { + 'path': option.temp_dir + '/access.log', + 'format': '$remote_add', + }, + 'access_log', + ), 'access_log format incorrect' diff --git a/test/test_asgi_application.py b/test/test_asgi_application.py index 60fcffc1..34dfe18e 100644 --- a/test/test_asgi_application.py +++ b/test/test_asgi_application.py @@ -60,6 +60,16 @@ custom-header: BLAH }, 'headers' assert resp['body'] == body, 'body' + def test_asgi_application_unix(self, temp_dir): + self.load('empty') + + addr = temp_dir + '/sock' + assert 'success' in self.conf( + {"unix:" + addr: {"pass": "applications/empty"}}, 'listeners' + ) + + assert self.get(sock_type='unix', addr=addr)['status'] == 200 + def test_asgi_application_query_string(self): self.load('query_string') @@ -150,15 +160,7 @@ custom-header: BLAH assert self.get()['status'] == 200, 'init' body = '0123456789AB' * 1024 * 1024 # 12 Mb - resp = self.post( - headers={ - 'Host': 'localhost', - 'Connection': 'close', - 'Content-Type': 'text/html', - }, - body=body, - read_buffer_size=1024 * 1024, - ) + resp = self.post(body=body, read_buffer_size=1024 * 1024) assert resp['body'] == body, 'keep-alive 1' @@ -172,7 +174,6 @@ custom-header: BLAH headers={ 'Host': 'localhost', 'Connection': 'keep-alive', - 'Content-Type': 'text/html', }, start=True, body=body, @@ -182,15 +183,7 @@ custom-header: BLAH assert resp['body'] == body, 'keep-alive 1' body = '0123456789' - resp = self.post( - headers={ - 'Host': 'localhost', - 'Connection': 'close', - 'Content-Type': 'text/html', - }, - sock=sock, - body=body, - ) + resp = self.post(sock=sock, body=body) assert resp['body'] == body, 'keep-alive 2' @@ -208,7 +201,6 @@ custom-header: BLAH headers={ 'Host': 'localhost', 'Connection': 'keep-alive', - 'Content-Type': 'text/html', }, start=True, body=body, @@ -226,7 +218,6 @@ custom-header: BLAH headers={ 'Host': 'localhost', 'Connection': 'keep-alive', - 'Content-Type': 'text/html', }, start=True, sock=socks[i], @@ -239,15 +230,7 @@ custom-header: BLAH self.load('mirror', processes=i + 1) for i in range(conns): - resp = self.post( - headers={ - 'Host': 'localhost', - 'Connection': 'close', - 'Content-Type': 'text/html', - }, - sock=socks[i], - body=body, - ) + resp = self.post(sock=socks[i], body=body) assert resp['body'] == body, 'keep-alive close' @@ -264,7 +247,6 @@ custom-header: BLAH headers={ 'Host': 'localhost', 'Connection': 'keep-alive', - 'Content-Type': 'text/html', }, start=True, body=body, @@ -277,16 +259,7 @@ custom-header: BLAH assert self.get()['status'] == 200, 'init' - (resp, sock) = self.post( - headers={ - 'Host': 'localhost', - 'Connection': 'close', - 'Content-Type': 'text/html', - }, - start=True, - sock=sock, - body=body, - ) + (resp, sock) = self.post(start=True, sock=sock, body=body) assert resp['status'] == 200, 'reconfigure 2 keep-alive 2' assert resp['body'] == '', 'reconfigure 2 keep-alive 2 body' diff --git a/test/test_asgi_application_unix_abstract.py b/test/test_asgi_application_unix_abstract.py new file mode 100644 index 00000000..c4ec812f --- /dev/null +++ b/test/test_asgi_application_unix_abstract.py @@ -0,0 +1,23 @@ +from packaging import version +from unit.applications.lang.python import TestApplicationPython + + +class TestASGIApplicationUnixAbstract(TestApplicationPython): + prerequisites = { + 'modules': { + 'python': lambda v: version.parse(v) >= version.parse('3.5') + }, + 'features': ['unix_abstract'], + } + load_module = 'asgi' + + def test_asgi_application_unix_abstract(self): + self.load('empty') + + addr = '\0sock' + assert 'success' in self.conf( + {"unix:@" + addr[1:]: {"pass": "applications/empty"}}, + 'listeners', + ) + + assert self.get(sock_type='unix', addr=addr)['status'] == 200 diff --git a/test/test_client_ip.py b/test/test_client_ip.py index 53e52201..50aa6afc 100644 --- a/test/test_client_ip.py +++ b/test/test_client_ip.py @@ -1,4 +1,5 @@ from unit.applications.lang.python import TestApplicationPython +from unit.option import option class TestClientIP(TestApplicationPython): @@ -15,15 +16,27 @@ class TestClientIP(TestApplicationPython): "client_ip": options, "pass": "applications/client_ip", }, + "unix:" + + option.temp_dir + + "/sock": { + "client_ip": options, + "pass": "applications/client_ip", + }, }, 'listeners', ), 'listeners configure' def get_xff(self, xff, sock_type='ipv4'): - port = 7081 if sock_type == 'ipv4' else 7082 + address = { + 'ipv4': ('127.0.0.1', 7081), + 'ipv6': ('::1', 7082), + 'unix': (option.temp_dir + '/sock', None), + } + (addr, port) = address[sock_type] return self.get( sock_type=sock_type, + addr=addr, port=port, headers={'Connection': 'close', 'X-Forwarded-For': xff}, )['body'] @@ -31,7 +44,7 @@ class TestClientIP(TestApplicationPython): def setup_method(self): self.load('client_ip') - def test_settings_client_ip_single_ip(self): + def test_client_ip_single_ip(self): self.client_ip( {'header': 'X-Forwarded-For', 'source': '123.123.123.123'} ) @@ -59,7 +72,7 @@ class TestClientIP(TestApplicationPython): assert self.get_xff('1.1.1.1') == '127.0.0.1', 'bad source 3' assert self.get_xff('1.1.1.1', 'ipv6') == '1.1.1.1', 'replace 2' - def test_settings_client_ip_ipv4(self): + def test_client_ip_ipv4(self): self.client_ip({'header': 'X-Forwarded-For', 'source': '127.0.0.1'}) assert ( @@ -72,7 +85,7 @@ class TestClientIP(TestApplicationPython): self.get_xff(['8.8.8.8', '127.0.0.1, 10.0.1.1']) == '10.0.1.1' ), 'xff replace multi' - def test_settings_client_ip_ipv6(self): + def test_client_ip_ipv6(self): self.client_ip({'header': 'X-Forwarded-For', 'source': '::1'}) assert self.get_xff('1.1.1.1') == '127.0.0.1', 'bad source ipv4' @@ -85,7 +98,19 @@ class TestClientIP(TestApplicationPython): ]: assert self.get_xff(ip, 'ipv6') == ip, 'replace' - def test_settings_client_ip_recursive(self): + def test_client_ip_unix(self, temp_dir): + self.client_ip({'header': 'X-Forwarded-For', 'source': 'unix'}) + + assert self.get_xff('1.1.1.1') == '127.0.0.1', 'bad source ipv4' + assert self.get_xff('1.1.1.1', 'ipv6') == '::1', 'bad source ipv6' + + for ip in [ + '1.1.1.1', + '::11.22.33.44', + ]: + assert self.get_xff(ip, 'unix') == ip, 'replace' + + def test_client_ip_recursive(self): self.client_ip( { 'header': 'X-Forwarded-For', @@ -118,20 +143,41 @@ class TestClientIP(TestApplicationPython): == '2001:db8:3c4d:15::1a2f:1a2b' ), 'xff chain ipv6' - def test_settings_client_ip_invalid(self): - assert 'error' in self.conf( - { - "http": { - "client_ip": {'header': 'X-Forwarded-For', 'source': []} - } - }, - 'settings', - ), 'empty array source' + def test_client_ip_case_insensitive(self): + self.client_ip({'header': 'x-forwarded-for', 'source': '127.0.0.1'}) + + assert self.get_xff('1.1.1.1') == '1.1.1.1', 'case insensitive' + + def test_client_ip_empty_source(self): + self.client_ip({'header': 'X-Forwarded-For', 'source': []}) + + assert self.get_xff('1.1.1.1') == '127.0.0.1', 'empty source' + + def test_client_ip_invalid(self): assert 'error' in self.conf( { - "http": { - "client_ip": {'header': 'X-Forwarded-For', 'source': 'a'} + "127.0.0.1:7081": { + "client_ip": {"source": '127.0.0.1'}, + "pass": "applications/client_ip", } }, - 'settings', - ), 'empty source invalid' + 'listeners', + ), 'invalid header' + + def check_invalid_source(source): + assert 'error' in self.conf( + { + "127.0.0.1:7081": { + "client_ip": { + "header": "X-Forwarded-For", + "source": source, + }, + "pass": "applications/client_ip", + } + }, + 'listeners', + ), 'invalid source' + + check_invalid_source(None) + check_invalid_source('a') + check_invalid_source(['a']) diff --git a/test/test_configuration.py b/test/test_configuration.py index 4a9d9840..7c612db0 100644 --- a/test/test_configuration.py +++ b/test/test_configuration.py @@ -2,6 +2,7 @@ import socket import pytest from unit.control import TestControl +from unit.option import option class TestConfiguration(TestControl): @@ -226,6 +227,15 @@ class TestConfiguration(TestControl): {"*:7080": {"pass": "applications/app"}}, 'listeners' ), 'listeners no app' + def test_listeners_unix_abstract(self): + if option.system != 'Linux': + assert 'error' in self.try_addr("unix:@sock"), 'abstract at' + + pytest.skip('not yet') + + assert 'error' in self.try_addr("unix:\0soc"), 'abstract \0' + assert 'error' in self.try_addr("unix:\u0000soc"), 'abstract \0 unicode' + def test_listeners_addr(self): assert 'success' in self.try_addr("*:7080"), 'wildcard' assert 'success' in self.try_addr("127.0.0.1:7081"), 'explicit' diff --git a/test/test_forwarded_header.py b/test/test_forwarded_header.py new file mode 100644 index 00000000..eb2f25f8 --- /dev/null +++ b/test/test_forwarded_header.py @@ -0,0 +1,266 @@ +from unit.applications.lang.python import TestApplicationPython + + +class TestForwardedHeader(TestApplicationPython): + prerequisites = {'modules': {'python': 'any'}} + + def forwarded_header(self, forwarded): + assert 'success' in self.conf( + { + "127.0.0.1:7081": { + "forwarded": forwarded, + "pass": "applications/forwarded_header", + }, + "[::1]:7082": { + "forwarded": forwarded, + "pass": "applications/forwarded_header", + }, + }, + 'listeners', + ), 'listeners configure' + + def get_fwd(self, sock_type='ipv4', xff=None, xfp=None): + port = 7081 if sock_type == 'ipv4' else 7082 + + headers = {'Connection': 'close'} + + if xff is not None: + headers['X-Forwarded-For'] = xff + + if xfp is not None: + headers['X-Forwarded-Proto'] = xfp + + return self.get(sock_type=sock_type, port=port, headers=headers)[ + 'headers' + ] + + def get_addr(self, *args, **kwargs): + return self.get_fwd(*args, **kwargs)['Remote-Addr'] + + def get_scheme(self, *args, **kwargs): + return self.get_fwd(*args, **kwargs)['Url-Scheme'] + + def setup_method(self): + self.load('forwarded_header') + + def test_forwarded_header_single_ip(self): + self.forwarded_header( + { + 'client_ip': 'X-Forwarded-For', + 'protocol': 'X-Forwarded-Proto', + 'source': '123.123.123.123', + } + ) + + resp = self.get_fwd(xff='1.1.1.1', xfp='https') + assert resp['Remote-Addr'] == '127.0.0.1', 'both headers addr' + assert resp['Url-Scheme'] == 'http', 'both headers proto' + + assert self.get_addr() == '127.0.0.1', 'ipv4 default addr' + assert self.get_addr('ipv6') == '::1', 'ipv6 default addr' + assert self.get_addr(xff='1.1.1.1') == '127.0.0.1', 'bad source' + assert self.get_addr(xff='blah') == '127.0.0.1', 'bad xff' + assert self.get_addr('ipv6', '1.1.1.1') == '::1', 'bad source ipv6' + + assert self.get_scheme() == 'http', 'ipv4 default proto' + assert self.get_scheme('ipv6') == 'http', 'ipv6 default proto' + assert self.get_scheme(xfp='https') == 'http', 'bad proto' + assert self.get_scheme(xfp='blah') == 'http', 'bad xfp' + assert self.get_scheme('ipv6', xfp='https') == 'http', 'bad proto ipv6' + + self.forwarded_header( + { + 'client_ip': 'X-Forwarded-For', + 'protocol': 'X-Forwarded-Proto', + 'source': '127.0.0.1', + } + ) + + resp = self.get_fwd(xff='1.1.1.1', xfp='https') + assert resp['Remote-Addr'] == '1.1.1.1', 'both headers addr 2' + assert resp['Url-Scheme'] == 'https', 'both headers proto 2' + + assert self.get_addr() == '127.0.0.1', 'ipv4 default addr 2' + assert self.get_addr('ipv6') == '::1', 'ipv6 default addr 2' + assert self.get_addr(xff='1.1.1.1') == '1.1.1.1', 'xff replace' + assert self.get_addr('ipv6', '1.1.1.1') == '::1', 'bad source ipv6 2' + + assert self.get_scheme() == 'http', 'ipv4 default proto 2' + assert self.get_scheme('ipv6') == 'http', 'ipv6 default proto 2' + assert self.get_scheme(xfp='https') == 'https', 'xfp replace' + assert self.get_scheme(xfp='on') == 'https', 'xfp replace 2' + assert ( + self.get_scheme('ipv6', xfp='https') == 'http' + ), 'bad proto ipv6 2' + + self.forwarded_header( + { + 'client_ip': 'X-Forwarded-For', + 'protocol': 'X-Forwarded-Proto', + 'source': '!127.0.0.1', + } + ) + + assert self.get_addr(xff='1.1.1.1') == '127.0.0.1', 'bad source 3' + assert self.get_addr('ipv6', '1.1.1.1') == '1.1.1.1', 'xff replace 2' + assert self.get_scheme(xfp='https') == 'http', 'bad proto 2' + assert self.get_scheme('ipv6', xfp='https') == 'https', 'xfp replace 3' + + def test_forwarded_header_ipv4(self): + self.forwarded_header( + { + 'client_ip': 'X-Forwarded-For', + 'protocol': 'X-Forwarded-Proto', + 'source': '127.0.0.1', + } + ) + + assert ( + self.get_addr(xff='8.8.8.8, 84.23.23.11') == '84.23.23.11' + ), 'xff replace' + assert ( + self.get_addr(xff='8.8.8.8, 84.23.23.11, 127.0.0.1') == '127.0.0.1' + ), 'xff replace 2' + assert ( + self.get_addr(xff=['8.8.8.8', '127.0.0.1, 10.0.1.1']) == '10.0.1.1' + ), 'xff replace multi' + + assert self.get_scheme(xfp='http, https') == 'http', 'xfp replace' + assert ( + self.get_scheme(xfp='http, https, http') == 'http' + ), 'xfp replace 2' + assert ( + self.get_scheme(xfp=['http, https', 'http', 'https']) == 'http' + ), 'xfp replace multi' + + def test_forwarded_header_ipv6(self): + self.forwarded_header( + { + 'client_ip': 'X-Forwarded-For', + 'protocol': 'X-Forwarded-Proto', + 'source': '::1', + } + ) + + assert self.get_addr(xff='1.1.1.1') == '127.0.0.1', 'bad source ipv4' + + for ip in [ + 'f607:7403:1e4b:6c66:33b2:843f:2517:da27', + '2001:db8:3c4d:15::1a2f:1a2b', + '2001::3c4d:15:1a2f:1a2b', + '::11.22.33.44', + ]: + assert self.get_addr('ipv6', ip) == ip, 'replace' + + assert self.get_scheme(xfp='https') == 'http', 'bad source ipv4' + + for proto in ['http', 'https']: + assert self.get_scheme('ipv6', xfp=proto) == proto, 'replace' + + def test_forwarded_header_recursive(self): + self.forwarded_header( + { + 'client_ip': 'X-Forwarded-For', + 'recursive': True, + 'source': ['127.0.0.1', '10.50.0.17', '10.5.2.1'], + } + ) + + assert self.get_addr(xff='1.1.1.1') == '1.1.1.1', 'xff chain' + assert ( + self.get_addr(xff='1.1.1.1, 10.5.2.1') == '1.1.1.1' + ), 'xff chain 2' + assert ( + self.get_addr(xff='8.8.8.8, 1.1.1.1, 10.5.2.1') == '1.1.1.1' + ), 'xff chain 3' + assert ( + self.get_addr(xff='10.50.0.17, 10.5.2.1, 10.5.2.1') == '10.50.0.17' + ), 'xff chain 4' + assert ( + self.get_addr(xff=['8.8.8.8', '1.1.1.1, 127.0.0.1']) == '1.1.1.1' + ), 'xff replace multi' + assert ( + self.get_addr(xff=['8.8.8.8', '1.1.1.1, 127.0.0.1', '10.5.2.1']) + == '1.1.1.1' + ), 'xff replace multi 2' + assert ( + self.get_addr(xff=['10.5.2.1', '10.50.0.17, 1.1.1.1', '10.5.2.1']) + == '1.1.1.1' + ), 'xff replace multi 3' + assert ( + self.get_addr( + xff='8.8.8.8, 2001:db8:3c4d:15::1a2f:1a2b, 127.0.0.1' + ) + == '2001:db8:3c4d:15::1a2f:1a2b' + ), 'xff chain ipv6' + + def test_forwarded_header_case_insensitive(self): + self.forwarded_header( + { + 'client_ip': 'x-forwarded-for', + 'protocol': 'x-forwarded-proto', + 'source': '127.0.0.1', + } + ) + + assert self.get_addr() == '127.0.0.1', 'ipv4 default addr' + assert self.get_addr('ipv6') == '::1', 'ipv6 default addr' + assert self.get_addr(xff='1.1.1.1') == '1.1.1.1', 'replace' + + assert self.get_scheme() == 'http', 'ipv4 default proto' + assert self.get_scheme('ipv6') == 'http', 'ipv6 default proto' + assert self.get_scheme(xfp='https') == 'https', 'replace 1' + assert self.get_scheme(xfp='oN') == 'https', 'replace 2' + + def test_forwarded_header_source_empty(self): + self.forwarded_header( + { + 'client_ip': 'X-Forwarded-For', + 'protocol': 'X-Forwarded-Proto', + 'source': [], + } + ) + + assert self.get_addr(xff='1.1.1.1') == '127.0.0.1', 'empty source xff' + assert self.get_scheme(xfp='https') == 'http', 'empty source xfp' + + def test_forwarded_header_source_range(self): + self.forwarded_header( + { + 'client_ip': 'X-Forwarded-For', + 'protocol': 'X-Forwarded-Proto', + 'source': '127.0.0.0-127.0.0.1', + } + ) + + assert self.get_addr(xff='1.1.1.1') == '1.1.1.1', 'source range' + assert self.get_addr('ipv6', '1.1.1.1') == '::1', 'source range 2' + + def test_forwarded_header_invalid(self): + assert 'error' in self.conf( + { + "127.0.0.1:7081": { + "forwarded": {"source": '127.0.0.1'}, + "pass": "applications/forwarded_header", + } + }, + 'listeners', + ), 'invalid forward' + + def check_invalid_source(source): + assert 'error' in self.conf( + { + "127.0.0.1:7081": { + "forwarded": { + "client_ip": "X-Forwarded-For", + "source": source, + }, + "pass": "applications/forwarded_header", + } + }, + 'listeners', + ), 'invalid source' + + check_invalid_source(None) + check_invalid_source('a') + check_invalid_source(['a']) diff --git a/test/test_go_application.py b/test/test_go_application.py index c8cf3e53..a746c6f4 100644 --- a/test/test_go_application.py +++ b/test/test_go_application.py @@ -95,7 +95,6 @@ class TestGoApplication(TestApplicationGo): headers={ 'Host': 'localhost', 'Connection': 'keep-alive', - 'Content-Type': 'text/html', }, start=True, body=body, @@ -105,16 +104,7 @@ class TestGoApplication(TestApplicationGo): assert resp['body'] == body, 'keep-alive 1' body = '0123456789' - resp = self.post( - headers={ - 'Host': 'localhost', - 'Content-Type': 'text/html', - 'Connection': 'close', - }, - sock=sock, - body=body, - ) - + resp = self.post(sock=sock, body=body) assert resp['body'] == body, 'keep-alive 2' def test_go_application_cookies(self): diff --git a/test/test_node_application.py b/test/test_node_application.py index fc722582..c26c72d0 100644 --- a/test/test_node_application.py +++ b/test/test_node_application.py @@ -124,7 +124,6 @@ class TestNodeApplication(TestApplicationNode): headers={ 'Host': 'localhost', 'Connection': 'keep-alive', - 'Content-Type': 'text/html', }, start=True, body=body, @@ -134,15 +133,7 @@ class TestNodeApplication(TestApplicationNode): assert resp['body'] == '0123456789' * 500, 'keep-alive 1' body = '0123456789' - resp = self.post( - headers={ - 'Host': 'localhost', - 'Connection': 'close', - 'Content-Type': 'text/html', - }, - sock=sock, - body=body, - ) + resp = self.post(sock=sock, body=body) assert resp['body'] == body, 'keep-alive 2' diff --git a/test/test_php_application.py b/test/test_php_application.py index 606ac723..f1dcc995 100644 --- a/test/test_php_application.py +++ b/test/test_php_application.py @@ -226,7 +226,6 @@ opcache.preload_user = %(user)s headers={ 'Host': 'localhost', 'Connection': 'keep-alive', - 'Content-Type': 'text/html', }, start=True, body=body, @@ -236,15 +235,7 @@ opcache.preload_user = %(user)s assert resp['body'] == body, 'keep-alive 1' body = '0123456789' - resp = self.post( - headers={ - 'Host': 'localhost', - 'Connection': 'close', - 'Content-Type': 'text/html', - }, - sock=sock, - body=body, - ) + resp = self.post(sock=sock, body=body) assert resp['body'] == body, 'keep-alive 2' diff --git a/test/test_proxy.py b/test/test_proxy.py index 68ae2394..b0d471e4 100644 --- a/test/test_proxy.py +++ b/test/test_proxy.py @@ -370,7 +370,6 @@ Content-Length: 10 resp = self.post_http10( headers={ 'Host': 'localhost', - 'Content-Type': 'text/html', 'Content-Length': str(len(body)), 'X-Parts': '2', 'X-Delay': '1', @@ -384,7 +383,6 @@ Content-Length: 10 resp = self.post_http10( headers={ 'Host': 'localhost', - 'Content-Type': 'text/html', 'Content-Length': str(len(body)), 'X-Parts': '2', 'X-Delay': '1', @@ -403,7 +401,6 @@ Content-Length: 10 _, sock = self.post_http10( headers={ 'Host': 'localhost', - 'Content-Type': 'text/html', 'Content-Length': '10000', 'X-Parts': '3', 'X-Delay': '1', @@ -419,7 +416,6 @@ Content-Length: 10 _, sock = self.post_http10( headers={ 'Host': 'localhost', - 'Content-Type': 'text/html', 'Content-Length': '10000', 'X-Parts': '3', 'X-Delay': '1', diff --git a/test/test_python_application.py b/test/test_python_application.py index befbd4d8..2ea9a22e 100644 --- a/test/test_python_application.py +++ b/test/test_python_application.py @@ -138,14 +138,7 @@ custom-header: BLAH def test_python_application_ctx_iter_atexit(self): self.load('ctx_iter_atexit') - resp = self.post( - headers={ - 'Host': 'localhost', - 'Connection': 'close', - 'Content-Type': 'text/html', - }, - body='0123456789', - ) + resp = self.post(body='0123456789') assert resp['status'] == 200, 'ctx iter status' assert resp['body'] == '0123456789', 'ctx iter body' @@ -166,7 +159,6 @@ custom-header: BLAH headers={ 'Host': 'localhost', 'Connection': 'keep-alive', - 'Content-Type': 'text/html', }, start=True, body=body, @@ -176,15 +168,7 @@ custom-header: BLAH assert resp['body'] == body, 'keep-alive 1' body = '0123456789' - resp = self.post( - headers={ - 'Host': 'localhost', - 'Connection': 'close', - 'Content-Type': 'text/html', - }, - sock=sock, - body=body, - ) + resp = self.post(sock=sock, body=body) assert resp['body'] == body, 'keep-alive 2' @@ -202,7 +186,6 @@ custom-header: BLAH headers={ 'Host': 'localhost', 'Connection': 'keep-alive', - 'Content-Type': 'text/html', }, start=True, body=body, @@ -220,7 +203,6 @@ custom-header: BLAH headers={ 'Host': 'localhost', 'Connection': 'keep-alive', - 'Content-Type': 'text/html', }, start=True, sock=socks[i], @@ -233,15 +215,7 @@ custom-header: BLAH self.load('mirror', processes=i + 1) for i in range(conns): - resp = self.post( - headers={ - 'Host': 'localhost', - 'Connection': 'close', - 'Content-Type': 'text/html', - }, - sock=socks[i], - body=body, - ) + resp = self.post(sock=socks[i], body=body) assert resp['body'] == body, 'keep-alive close' @@ -258,7 +232,6 @@ custom-header: BLAH headers={ 'Host': 'localhost', 'Connection': 'keep-alive', - 'Content-Type': 'text/html', }, start=True, body=body, @@ -271,16 +244,7 @@ custom-header: BLAH assert self.get()['status'] == 200, 'init' - (resp, sock) = self.post( - headers={ - 'Host': 'localhost', - 'Connection': 'close', - 'Content-Type': 'text/html', - }, - start=True, - sock=sock, - body=body, - ) + (resp, sock) = self.post(start=True, sock=sock, body=body) assert resp['status'] == 200, 'reconfigure 2 keep-alive 2' assert resp['body'] == '', 'reconfigure 2 keep-alive 2 body' diff --git a/test/test_routing.py b/test/test_routing.py index fda429a4..3649b37c 100644 --- a/test/test_routing.py +++ b/test/test_routing.py @@ -1723,18 +1723,26 @@ class TestRouting(TestApplicationPython): addr = temp_dir + '/sock' assert 'success' in self.conf( - {"unix:" + addr: {"pass": "routes"}}, 'listeners' + { + "127.0.0.1:7081": {"pass": "routes"}, + "unix:" + addr: {"pass": "routes"}, + }, + 'listeners', ), 'source listeners configure' self.route_match({"source": "!0.0.0.0/0"}) assert ( self.get(sock_type='unix', addr=addr)['status'] == 200 - ), 'unix ipv4' + ), 'unix ipv4 neg' self.route_match({"source": "!::/0"}) assert ( self.get(sock_type='unix', addr=addr)['status'] == 200 - ), 'unix ipv6' + ), 'unix ipv6 neg' + + self.route_match({"source": "unix"}) + assert self.get(port=7081)['status'] == 404, 'unix ipv4' + assert self.get(sock_type='unix', addr=addr)['status'] == 200, 'unix' def test_routes_match_source(self): self.route_match({"source": "::"}) diff --git a/test/test_ruby_application.py b/test/test_ruby_application.py index 95c75d47..83af39be 100644 --- a/test/test_ruby_application.py +++ b/test/test_ruby_application.py @@ -44,7 +44,7 @@ class TestRubyApplication(TestApplicationRuby): 'Request-Method': 'POST', 'Request-Uri': '/', 'Http-Host': 'localhost', - 'Script-Name': 'config.ru', + 'Script-Name': '', 'Server-Protocol': 'HTTP/1.1', 'Custom-Header': 'blah', 'Rack-Version': '13', @@ -347,7 +347,6 @@ class TestRubyApplication(TestApplicationRuby): headers={ 'Host': 'localhost', 'Connection': 'keep-alive', - 'Content-Type': 'text/html', }, start=True, body=body, @@ -357,15 +356,7 @@ class TestRubyApplication(TestApplicationRuby): assert resp['body'] == body, 'keep-alive 1' body = '0123456789' - resp = self.post( - headers={ - 'Host': 'localhost', - 'Connection': 'close', - 'Content-Type': 'text/html', - }, - sock=sock, - body=body, - ) + resp = self.post(sock=sock, body=body) assert resp['body'] == body, 'keep-alive 2' diff --git a/test/test_static_chroot.py b/test/test_static_chroot.py index b896a9b9..e33a181c 100644 --- a/test/test_static_chroot.py +++ b/test/test_static_chroot.py @@ -14,8 +14,7 @@ class TestStaticChroot(TestApplicationProto): Path(temp_dir + '/assets/index.html').write_text('0123456789') Path(temp_dir + '/assets/dir/file').write_text('blah') - test = Path(__file__) - self.test_path = '/' + test.parent.name + '/' + test.name + self.test_path = '/' + os.path.relpath(Path(__file__)) self._load_conf( { @@ -39,26 +38,18 @@ class TestStaticChroot(TestApplicationProto): assert self.get(url='/dir/file')['status'] == 200, 'default chroot' assert self.get(url='/index.html')['status'] == 200, 'default chroot 2' - assert 'success' in self.conf( - { - "share": temp_dir + "/assets$uri", - "chroot": temp_dir + "/assets/dir", - }, - 'routes/0/action', - ), 'configure chroot' + assert 'success' in self.update_action( + temp_dir + "/assets$uri", temp_dir + "/assets/dir" + ) assert self.get(url='/dir/file')['status'] == 200, 'chroot' assert self.get(url='/index.html')['status'] == 403, 'chroot 403 2' assert self.get(url='/file')['status'] == 403, 'chroot 403' def test_share_chroot_array(self, temp_dir): - assert 'success' in self.conf( - { - "share": ["/blah", temp_dir + "/assets$uri"], - "chroot": temp_dir + "/assets/dir", - }, - 'routes/0/action', - ), 'configure share array' + assert 'success' in self.update_action( + ["/blah", temp_dir + "/assets$uri"], temp_dir + "/assets/dir" + ) assert self.get(url='/dir/file')['status'] == 200, 'share array' assert 'success' in self.update_action( @@ -66,13 +57,9 @@ class TestStaticChroot(TestApplicationProto): ) assert self.get_custom('/dir/file', 'dir') == 200, 'array variable' - assert 'success' in self.conf( - { - "share": ["/blah", "/blah2"], - "chroot": temp_dir + "/assets/dir", - }, - 'routes/0/action', - ), 'configure share array bad' + assert 'success' in self.update_action( + ["/blah", "/blah2"], temp_dir + "/assets/dir" + ) assert self.get()['status'] != 200, 'share array bad' def test_static_chroot_permission(self, is_su, temp_dir): @@ -81,58 +68,30 @@ class TestStaticChroot(TestApplicationProto): os.chmod(temp_dir + '/assets/dir', 0o100) - assert 'success' in self.conf( - { - "share": temp_dir + "/assets$uri", - "chroot": temp_dir + "/assets/dir", - }, - 'routes/0/action', + assert 'success' in self.update_action( + temp_dir + "/assets$uri", temp_dir + "/assets/dir" ), 'configure chroot' assert self.get(url='/dir/file')['status'] == 200, 'chroot' def test_static_chroot_empty(self, temp_dir): - assert 'success' in self.conf( - {"share": temp_dir + "/assets$uri", "chroot": ""}, - 'routes/0/action', - ), 'configure chroot empty absolute' - - assert ( - self.get(url='/dir/file')['status'] == 200 - ), 'chroot empty absolute' - - assert 'success' in self.conf( - {"share": ".$uri", "chroot": ""}, - 'routes/0/action', - ), 'configure chroot empty relative' + assert 'success' in self.update_action(temp_dir + "/assets$uri", "") + assert self.get(url='/dir/file')['status'] == 200, 'empty absolute' - assert ( - self.get(url=self.test_path)['status'] == 200 - ), 'chroot empty relative' + assert 'success' in self.update_action(".$uri", "") + assert self.get(url=self.test_path)['status'] == 200, 'empty relative' def test_static_chroot_relative(self, is_su, temp_dir): if is_su: pytest.skip('does\'t work under root') - assert 'success' in self.conf( - {"share": temp_dir + "/assets$uri", "chroot": "."}, - 'routes/0/action', - ), 'configure relative chroot' - + assert 'success' in self.update_action(temp_dir + "/assets$uri", ".") assert self.get(url='/dir/file')['status'] == 403, 'relative chroot' - assert 'success' in self.conf( - {"share": ".$uri"}, - 'routes/0/action', - ), 'configure relative share' - + assert 'success' in self.conf({"share": ".$uri"}, 'routes/0/action') assert self.get(url=self.test_path)['status'] == 200, 'relative share' - assert 'success' in self.conf( - {"share": ".$uri", "chroot": "."}, - 'routes/0/action', - ), 'configure relative' - + assert 'success' in self.update_action(".$uri", ".") assert self.get(url=self.test_path)['status'] == 200, 'relative' def test_static_chroot_variables(self, temp_dir): @@ -150,64 +109,41 @@ class TestStaticChroot(TestApplicationProto): assert 'success' in self.update_action( temp_dir + '/assets/dir/$host', '$uri/assets/dir' ) - assert self.get_custom(temp_dir, 'file') == 200 def test_static_chroot_variables_buildin_mid(self, temp_dir): assert 'success' in self.update_action( temp_dir + '/assets$uri', temp_dir + '/$host/dir' ) - assert self.get_custom('/dir/file', 'assets') == 200 def test_static_chroot_variables_buildin_end(self, temp_dir): assert 'success' in self.update_action( temp_dir + '/assets$uri', temp_dir + '/assets/$host' ) - assert self.get_custom('/dir/file', 'dir') == 200 def test_static_chroot_slash(self, temp_dir): - assert 'success' in self.conf( - { - "share": temp_dir + "/assets$uri", - "chroot": temp_dir + "/assets/dir/", - }, - 'routes/0/action', - ), 'configure chroot slash end' - + assert 'success' in self.update_action( + temp_dir + "/assets$uri", temp_dir + "/assets/dir/" + ) assert self.get(url='/dir/file')['status'] == 200, 'slash end' assert self.get(url='/dirxfile')['status'] == 403, 'slash end bad' - assert 'success' in self.conf( - { - "share": temp_dir + "/assets$uri", - "chroot": temp_dir + "/assets/dir", - }, - 'routes/0/action', - ), 'configure chroot no slash end' - + assert 'success' in self.update_action( + temp_dir + "/assets$uri", temp_dir + "/assets/dir" + ) assert self.get(url='/dir/file')['status'] == 200, 'no slash end' - assert 'success' in self.conf( - { - "share": temp_dir + "/assets$uri", - "chroot": temp_dir + "/assets/dir/", - }, - 'routes/0/action', - ), 'configure chroot slash end 2' - + assert 'success' in self.update_action( + temp_dir + "/assets$uri", temp_dir + "/assets/dir/" + ) assert self.get(url='/dir/file')['status'] == 200, 'slash end 2' assert self.get(url='/dirxfile')['status'] == 403, 'slash end 2 bad' - assert 'success' in self.conf( - { - "share": temp_dir + "///assets/////$uri", - "chroot": temp_dir + "//assets////dir///", - }, - 'routes/0/action', - ), 'configure chroot multiple slashes' - + assert 'success' in self.update_action( + temp_dir + "///assets/////$uri", temp_dir + "//assets////dir///" + ) assert self.get(url='/dir/file')['status'] == 200, 'multiple slashes' def test_static_chroot_invalid(self, temp_dir): diff --git a/test/test_status.py b/test/test_status.py new file mode 100644 index 00000000..214072d4 --- /dev/null +++ b/test/test_status.py @@ -0,0 +1,223 @@ +import time + +import pytest +from unit.applications.lang.python import TestApplicationPython +from unit.option import option +from unit.status import Status + + +class TestStatus(TestApplicationPython): + prerequisites = {'modules': {'python': 'any'}} + + def test_status(self): + assert 'error' in self.conf_delete('/status'), 'DELETE method' + + def test_status_requests(self, skip_alert): + skip_alert(r'Python failed to import module "blah"') + + assert 'success' in self.conf( + { + "listeners": { + "*:7080": {"pass": "routes"}, + "*:7081": {"pass": "applications/empty"}, + "*:7082": {"pass": "applications/blah"}, + }, + "routes": [{"action": {"return": 200}}], + "applications": { + "empty": { + "type": self.get_application_type(), + "processes": {"spare": 0}, + "path": option.test_dir + '/python/empty', + "working_directory": option.test_dir + '/python/empty', + "module": "wsgi", + }, + "blah": { + "type": self.get_application_type(), + "processes": {"spare": 0}, + "module": "blah", + }, + }, + }, + ) + + Status.init() + + assert self.get()['status'] == 200 + assert Status.get('/requests/total') == 1, '2xx' + + assert self.get(port=7081)['status'] == 200 + assert Status.get('/requests/total') == 2, '2xx app' + + assert ( + self.get(headers={'Host': '/', 'Connection': 'close'})['status'] + == 400 + ) + assert Status.get('/requests/total') == 3, '4xx' + + assert self.get(port=7082)['status'] == 503 + assert Status.get('/requests/total') == 4, '5xx' + + self.http( + b"""GET / HTTP/1.1 +Host: localhost + +GET / HTTP/1.1 +Host: localhost +Connection: close + +""", + raw=True, + ) + assert Status.get('/requests/total') == 6, 'pipeline' + + (_, sock) = self.get(port=7081, no_recv=True, start=True) + + time.sleep(1) + + assert Status.get('/requests/total') == 7, 'no receive' + + sock.close() + + def test_status_connections(self): + def check_connections(accepted, active, idle, closed): + Status.get('/connections') == { + 'accepted': accepted, + 'active': active, + 'idle': idle, + 'closed': closed, + } + + assert 'success' in self.conf( + { + "listeners": { + "*:7080": {"pass": "routes"}, + "*:7081": {"pass": "applications/delayed"}, + }, + "routes": [{"action": {"return": 200}}], + "applications": { + "delayed": { + "type": self.get_application_type(), + "processes": {"spare": 0}, + "path": option.test_dir + "/python/delayed", + "working_directory": option.test_dir + + "/python/delayed", + "module": "wsgi", + }, + }, + }, + ) + + Status.init() + + # accepted, closed + + assert self.get()['status'] == 200 + check_connections(1, 0, 0, 1) + + # idle + + _, sock = self.http(b'', start=True, raw=True, no_recv=True) + check_connections(2, 0, 1, 1) + + self.get(sock=sock) + check_connections(2, 0, 0, 2) + + # active + + (_, sock) = self.get( + headers={ + 'Host': 'localhost', + 'X-Delay': '2', + 'Connection': 'close', + }, + port=7081, + start=True, + read_timeout=1, + ) + check_connections(3, 1, 0, 2) + + self.get(sock=sock) + check_connections(3, 0, 0, 3) + + def test_status_applications(self): + def check_applications(expert): + apps = list(self.conf_get('/status/applications').keys()).sort() + assert apps == expert.sort() + + def check_application(name, running, starting, idle, active): + Status.get('/applications/' + name) == { + 'processes': { + 'running': running, + 'starting': starting, + 'idle': idle, + }, + 'requests': {'active': active}, + } + + self.load('delayed') + Status.init() + + check_applications(['delayed']) + check_application('delayed', 0, 0, 0, 0) + + # idle + + assert self.get()['status'] == 200 + check_application('delayed', 1, 0, 1, 0) + + assert 'success' in self.conf('4', 'applications/delayed/processes') + check_application('delayed', 4, 0, 4, 0) + + # active + + (_, sock) = self.get( + headers={ + 'Host': 'localhost', + 'X-Delay': '2', + 'Connection': 'close', + }, + start=True, + read_timeout=1, + ) + check_application('delayed', 4, 0, 3, 1) + sock.close() + + # starting + + assert 'success' in self.conf( + { + "listeners": { + "*:7080": {"pass": "applications/restart"}, + "*:7081": {"pass": "applications/delayed"}, + }, + "routes": [], + "applications": { + "restart": { + "type": self.get_application_type(), + "processes": {"spare": 0}, + "path": option.test_dir + "/python/restart", + "working_directory": option.test_dir + + "/python/restart", + "module": "longstart", + }, + "delayed": { + "type": self.get_application_type(), + "processes": {"spare": 0}, + "path": option.test_dir + "/python/delayed", + "working_directory": option.test_dir + + "/python/delayed", + "module": "wsgi", + }, + }, + }, + ) + Status.init() + + check_applications(['delayed', 'restart']) + check_application('restart', 0, 0, 0, 0) + check_application('delayed', 0, 0, 0, 0) + + self.get(read_timeout=1) + + check_application('restart', 0, 1, 0, 1) + check_application('delayed', 0, 0, 0, 0) diff --git a/test/test_status_tls.py b/test/test_status_tls.py new file mode 100644 index 00000000..dc3d68da --- /dev/null +++ b/test/test_status_tls.py @@ -0,0 +1,30 @@ +from unit.applications.tls import TestApplicationTLS +from unit.status import Status + + +class TestStatusTLS(TestApplicationTLS): + prerequisites = {'modules': {'openssl': 'any'}} + + def test_status_tls_requests(self): + self.certificate() + + assert 'success' in self.conf( + { + "listeners": { + "*:7080": {"pass": "routes"}, + "*:7081": { + "pass": "routes", + "tls": {"certificate": "default"}, + }, + }, + "routes": [{"action": {"return": 200}}], + "applications": {}, + } + ) + + Status.init() + + assert self.get()['status'] == 200 + assert self.get_ssl(port=7081)['status'] == 200 + + assert Status.get('/requests/total') == 2 diff --git a/test/test_tls.py b/test/test_tls.py index 56ee8298..d4edcbd3 100644 --- a/test/test_tls.py +++ b/test/test_tls.py @@ -1,5 +1,4 @@ import io -import re import ssl import subprocess import time @@ -13,7 +12,7 @@ class TestTLS(TestApplicationTLS): prerequisites = {'modules': {'python': 'any', 'openssl': 'any'}} def openssl_date_to_sec_epoch(self, date): - return self.date_to_sec_epoch(date, '%b %d %H:%M:%S %Y %Z') + return self.date_to_sec_epoch(date, '%b %d %X %Y %Z') def add_tls(self, application='empty', cert='default', port=7080): assert 'success' in self.conf( @@ -506,7 +505,6 @@ basicConstraints = critical,CA:TRUE""" headers={ 'Host': 'localhost', 'Connection': 'keep-alive', - 'Content-Type': 'text/html', }, start=True, body='0123456789', @@ -519,7 +517,6 @@ basicConstraints = critical,CA:TRUE""" headers={ 'Host': 'localhost', 'Connection': 'close', - 'Content-Type': 'text/html', }, sock=sock, body='0123456789', @@ -571,9 +568,7 @@ basicConstraints = critical,CA:TRUE""" assert 'success' in self.conf_delete('/certificates/default') try: - resp = self.get_ssl( - headers={'Host': 'localhost', 'Connection': 'close'}, sock=sock - ) + resp = self.get_ssl(sock=sock) except KeyboardInterrupt: raise @@ -606,7 +601,6 @@ basicConstraints = critical,CA:TRUE""" headers={ 'Host': 'localhost', 'Connection': 'keep-alive', - 'Content-Type': 'text/html', }, start=True, body='0123456789', @@ -617,23 +611,13 @@ basicConstraints = critical,CA:TRUE""" subprocess.check_output(['kill', '-9', app_id]) - skip_alert(r'process .* %s.* exited on signal 9' % app_id) + skip_alert(r'process %s exited on signal 9' % app_id) self.wait_for_record( - re.compile( - r' (?!' + app_id + r'#)(\d+)#\d+ "mirror" application started' - ) + r' (?!' + app_id + r'#)(\d+)#\d+ "mirror" application started' ) - resp = self.post_ssl( - headers={ - 'Host': 'localhost', - 'Connection': 'close', - 'Content-Type': 'text/html', - }, - sock=sock, - body='0123456789', - ) + resp = self.post_ssl(sock=sock, body='0123456789') assert resp['status'] == 200, 'application respawn status' assert resp['body'] == '0123456789', 'application respawn body' diff --git a/test/test_tls_sni.py b/test/test_tls_sni.py index dbd5d900..44cc21e1 100644 --- a/test/test_tls_sni.py +++ b/test/test_tls_sni.py @@ -18,7 +18,7 @@ class TestTLSSNI(TestApplicationTLS): ) def openssl_date_to_sec_epoch(self, date): - return self.date_to_sec_epoch(date, '%b %d %H:%M:%S %Y %Z') + return self.date_to_sec_epoch(date, '%b %d %X %Y %Z') def add_tls(self, cert='default'): assert 'success' in self.conf( diff --git a/test/test_unix_abstract.py b/test/test_unix_abstract.py new file mode 100644 index 00000000..195b0aa7 --- /dev/null +++ b/test/test_unix_abstract.py @@ -0,0 +1,109 @@ +from unit.applications.lang.python import TestApplicationPython +from unit.option import option + + +class TestUnixAbstract(TestApplicationPython): + prerequisites = { + 'modules': {'python': 'any'}, + 'features': ['unix_abstract'], + } + + def test_unix_abstract_source(self): + addr = '\0sock' + + def source(source): + assert 'success' in self.conf( + '"' + source + '"', 'routes/0/match/source' + ) + + assert 'success' in self.conf( + { + "listeners": { + "127.0.0.1:7080": {"pass": "routes"}, + "unix:@" + addr[1:]: {"pass": "routes"}, + }, + "routes": [ + { + "match": {"source": "!0.0.0.0/0"}, + "action": {"return": 200}, + } + ], + "applications": {}, + } + ) + + assert ( + self.get(sock_type='unix', addr=addr)['status'] == 200 + ), 'neg ipv4' + + source("!::/0") + assert ( + self.get(sock_type='unix', addr=addr)['status'] == 200 + ), 'neg ipv6' + + source("unix") + assert self.get()['status'] == 404, 'ipv4' + assert self.get(sock_type='unix', addr=addr)['status'] == 200, 'unix' + + def test_unix_abstract_client_ip(self): + def get_xff(xff, sock_type='ipv4'): + address = { + 'ipv4': ('127.0.0.1', 7080), + 'ipv6': ('::1', 7081), + 'unix': ('\0sock', None), + } + (addr, port) = address[sock_type] + + return self.get( + sock_type=sock_type, + addr=addr, + port=port, + headers={'Connection': 'close', 'X-Forwarded-For': xff}, + )['body'] + + assert 'success' in self.conf( + { + "listeners": { + "127.0.0.1:7080": { + "client_ip": { + "header": "X-Forwarded-For", + "source": "unix", + }, + "pass": "applications/client_ip", + }, + "[::1]:7081": { + "client_ip": { + "header": "X-Forwarded-For", + "source": "unix", + }, + "pass": "applications/client_ip", + }, + "unix:@sock": { + "client_ip": { + "header": "X-Forwarded-For", + "source": "unix", + }, + "pass": "applications/client_ip", + }, + }, + "applications": { + "client_ip": { + "type": self.get_application_type(), + "processes": {"spare": 0}, + "path": option.test_dir + "/python/client_ip", + "working_directory": option.test_dir + + "/python/client_ip", + "module": "wsgi", + } + }, + } + ) + + assert get_xff('1.1.1.1') == '127.0.0.1', 'bad source ipv4' + assert get_xff('1.1.1.1', 'ipv6') == '::1', 'bad source ipv6' + + for ip in [ + '1.1.1.1', + '::11.22.33.44', + ]: + assert get_xff(ip, 'unix') == ip, 'replace' diff --git a/test/test_variables.py b/test/test_variables.py index 71553685..2ddfdc0a 100644 --- a/test/test_variables.py +++ b/test/test_variables.py @@ -18,6 +18,11 @@ class TestVariables(TestApplicationProto): "GETGET": [{"action": {"return": 207}}], "localhost": [{"action": {"return": 208}}], "9?q#a": [{"action": {"return": 209}}], + "blah": [{"action": {"return": 210}}], + "127.0.0.1": [{"action": {"return": 211}}], + "::1": [{"action": {"return": 212}}], + "referer-value": [{"action": {"return": 213}}], + "MSIE": [{"action": {"return": 214}}], }, }, ), 'configure routes' @@ -62,6 +67,74 @@ class TestVariables(TestApplicationProto): check_host('www.localhost', 404) check_host('localhost1', 404) + def test_variables_remote_addr(self): + self.conf_routes("\"routes/$remote_addr\"") + assert self.get()['status'] == 211 + + assert 'success' in self.conf( + {"[::1]:7080": {"pass": "routes/$remote_addr"}}, 'listeners' + ) + assert self.get(sock_type='ipv6')['status'] == 212 + + def test_variables_header_referer(self): + self.conf_routes("\"routes/$header_referer\"") + + def check_referer(referer, status=213): + assert ( + self.get( + headers={ + 'Host': 'localhost', + 'Connection': 'close', + 'Referer': referer, + } + )['status'] + == status + ) + + check_referer('referer-value') + check_referer('', 404) + check_referer('no', 404) + + def test_variables_header_user_agent(self): + self.conf_routes("\"routes/$header_user_agent\"") + + def check_user_agent(user_agent, status=214): + assert ( + self.get( + headers={ + 'Host': 'localhost', + 'Connection': 'close', + 'User-Agent': user_agent, + } + )['status'] + == status + ) + + check_user_agent('MSIE') + check_user_agent('', 404) + check_user_agent('no', 404) + + def test_variables_dollar(self): + assert 'success' in self.conf( + { + "listeners": {"*:7080": {"pass": "routes"}}, + "routes": [{"action": {"return": 301}}], + } + ) + + def check_dollar(location, expect): + assert 'success' in self.conf( + '"' + location + '"', + 'routes/0/action/location', + ) + assert self.get()['headers']['Location'] == expect + + check_dollar( + 'https://${host}${uri}path${dollar}dollar', + 'https://localhost/path$dollar', + ) + check_dollar('path$dollar${dollar}', 'path$$') + def test_variables_many(self): self.conf_routes("\"routes$uri$method\"") assert self.get(url='/5')['status'] == 206, 'many' @@ -124,6 +197,80 @@ class TestVariables(TestApplicationProto): update_pass("applications") assert self.get(url='/3')['status'] == 404 + def test_variables_dynamic(self): + self.conf_routes("\"routes/$header_foo$arg_foo$cookie_foo\"") + + self.get( + url='/?foo=h', + headers={'Foo': 'b', 'Cookie': 'foo=la', 'Connection': 'close'}, + )['status'] = 210 + + def test_variables_dynamic_headers(self): + def check_header(header, status=210): + assert ( + self.get(headers={header: "blah", 'Connection': 'close'})[ + 'status' + ] + == status + ) + + self.conf_routes("\"routes/$header_foo_bar\"") + check_header('foo-bar') + check_header('Foo-Bar') + check_header('foo_bar', 404) + check_header('Foo', 404) + check_header('Bar', 404) + check_header('foobar', 404) + + self.conf_routes("\"routes/$header_Foo_Bar\"") + check_header('Foo-Bar') + check_header('foo-bar') + check_header('foo_bar', 404) + check_header('foobar', 404) + + self.conf_routes("\"routes/$header_foo-bar\"") + check_header('foo_bar', 404) + + def test_variables_dynamic_arguments(self): + self.conf_routes("\"routes/$arg_foo_bar\"") + assert self.get(url='/?foo_bar=blah')['status'] == 210 + assert self.get(url='/?foo_b%61r=blah')['status'] == 210 + assert self.get(url='/?bar&foo_bar=blah&foo')['status'] == 210 + assert self.get(url='/?Foo_bar=blah')['status'] == 404 + assert self.get(url='/?foo-bar=blah')['status'] == 404 + assert self.get()['status'] == 404 + assert self.get(url='/?foo_bar=')['status'] == 404 + assert self.get(url='/?foo_bar=l&foo_bar=blah')['status'] == 210 + assert self.get(url='/?foo_bar=blah&foo_bar=l')['status'] == 404 + + self.conf_routes("\"routes/$arg_foo_b%61r\"") + assert self.get(url='/?foo_b=blah')['status'] == 404 + assert self.get(url='/?foo_bar=blah')['status'] == 404 + + self.conf_routes("\"routes/$arg_f!~\"") + assert self.get(url='/?f=blah')['status'] == 404 + assert self.get(url='/?f!~=blah')['status'] == 404 + + def test_variables_dynamic_cookies(self): + def check_cookie(cookie, status=210): + assert ( + self.get( + headers={ + 'Host': 'localhost', + 'Cookie': cookie, + 'Connection': 'close', + }, + )['status'] + == status + ), 'match cookie' + + self.conf_routes("\"routes/$cookie_foo_bar\"") + check_cookie('foo_bar=blah', 210) + check_cookie('fOo_bar=blah', 404) + assert self.get()['status'] == 404 + check_cookie('foo_bar', 404) + check_cookie('foo_bar=', 404) + def test_variables_invalid(self): def check_variables(routes): assert 'error' in self.conf( @@ -137,3 +284,10 @@ class TestVariables(TestApplicationProto): check_variables("\"routes$uriblah\"") check_variables("\"routes${uri\"") check_variables("\"routes${{uri}\"") + check_variables("\"routes$ar\"") + check_variables("\"routes$arg\"") + check_variables("\"routes$arg_\"") + check_variables("\"routes$cookie\"") + check_variables("\"routes$cookie_\"") + check_variables("\"routes$header\"") + check_variables("\"routes$header_\"") diff --git a/test/unit/applications/lang/go.py b/test/unit/applications/lang/go.py index 04af26e1..3db955f3 100644 --- a/test/unit/applications/lang/go.py +++ b/test/unit/applications/lang/go.py @@ -9,6 +9,11 @@ from unit.option import option class TestApplicationGo(TestApplicationProto): @staticmethod def prepare_env(script, name='app', static=False): + try: + subprocess.check_output(['which', 'go']) + except subprocess.CalledProcessError: + return None + temp_dir = option.temp_dir + '/go/' if not os.path.exists(temp_dir): diff --git a/test/unit/applications/proto.py b/test/unit/applications/proto.py index cd8672ba..f04ee408 100644 --- a/test/unit/applications/proto.py +++ b/test/unit/applications/proto.py @@ -13,21 +13,21 @@ class TestApplicationProto(TestControl): def sec_epoch(self): return time.mktime(time.gmtime()) - def date_to_sec_epoch(self, date, template='%a, %d %b %Y %H:%M:%S %Z'): + def date_to_sec_epoch(self, date, template='%a, %d %b %Y %X %Z'): return time.mktime(time.strptime(date, template)) - def findall(self, pattern, name='unit.log'): + def findall(self, pattern, name='unit.log', flags=re.M): with Log.open(name) as f: - return re.findall(pattern, f.read()) + return re.findall(pattern, f.read(), flags) - def search_in_log(self, pattern, name='unit.log'): + def search_in_log(self, pattern, name='unit.log', flags=re.M): with Log.open(name) as f: - return re.search(pattern, f.read()) + return re.search(pattern, f.read(), flags) - def wait_for_record(self, pattern, name='unit.log', wait=150): + def wait_for_record(self, pattern, name='unit.log', wait=150, flags=re.M): with Log.open(name) as f: for i in range(wait): - found = re.search(pattern, f.read()) + found = re.search(pattern, f.read(), flags) if found is not None: break diff --git a/test/unit/check/unix_abstract.py b/test/unit/check/unix_abstract.py new file mode 100644 index 00000000..5d1f629e --- /dev/null +++ b/test/unit/check/unix_abstract.py @@ -0,0 +1,25 @@ +import json + +from unit.http import TestHTTP +from unit.option import option + +http = TestHTTP() + + +def check_unix_abstract(): + available = option.available + + resp = http.put( + url='/config', + sock_type='unix', + addr=option.temp_dir + '/control.unit.sock', + body=json.dumps( + { + "listeners": {"unix:@sock": {"pass": "routes"}}, + "routes": [], + } + ), + ) + + if 'success' in resp['body']: + available['features']['unix_abstract'] = True diff --git a/test/unit/http.py b/test/unit/http.py index b4a1a17b..b29667c9 100644 --- a/test/unit/http.py +++ b/test/unit/http.py @@ -51,7 +51,7 @@ class TestHTTP: connect_args = addr if sock_type == 'unix' else (addr, port) try: sock.connect(connect_args) - except ConnectionRefusedError: + except (ConnectionRefusedError, FileNotFoundError): sock.close() pytest.fail('Client can\'t connect to the server.') @@ -209,9 +209,7 @@ class TestHTTP: return {} headers_text, body = m.group(1), m.group(2) - - p = re.compile('(.*?)\x0d\x0a?', re.M | re.S) - headers_lines = p.findall(headers_text) + headers_lines = re.findall('(.*?)\x0d\x0a?', headers_text, re.M | re.S) status = re.search( r'^HTTP\/\d\.\d\s(\d+)|$', headers_lines.pop(0) diff --git a/test/unit/status.py b/test/unit/status.py new file mode 100644 index 00000000..17416f17 --- /dev/null +++ b/test/unit/status.py @@ -0,0 +1,45 @@ +from unit.control import TestControl + + +class Status: + _status = None + control = TestControl() + + def _check_zeros(): + assert Status.control.conf_get('/status') == { + 'connections': { + 'accepted': 0, + 'active': 0, + 'idle': 0, + 'closed': 0, + }, + 'requests': {'total': 0}, + 'applications': {}, + } + + def init(status=None): + Status._status = ( + status if status is not None else Status.control.conf_get('/status') + ) + + def diff(): + def find_diffs(d1, d2): + if isinstance(d1, dict) and isinstance(d2, dict): + return { + k: find_diffs(d1.get(k, 0), d2.get(k, 0)) + for k in d1 + if k in d2 + } + else: + return d1 - d2 + + return find_diffs(Status.control.conf_get('/status'), Status._status) + + def get(path='/'): + path = path.split('/')[1:] + diff = Status.diff() + + for p in path: + diff = diff[p] + + return diff @@ -1,5 +1,5 @@ # Copyright (C) NGINX, Inc. -NXT_VERSION=1.27.0 -NXT_VERNUM=12700 +NXT_VERSION=1.28.0 +NXT_VERNUM=12800 |