summaryrefslogtreecommitdiffhomepage
path: root/src/nxt_http_route.c (follow)
AgeCommit message (Collapse)AuthorFilesLines
2024-08-20http: Add "if" option to the "match" objectZhidao HONG1-4/+42
This feature allows users to specify conditions to check if one route is matched. It is used the same way as the "if" option in the access log. Example: { "match": { "if": "`${headers['User-Agent'].split('/')[0] == 'curl'}`" }, "action": { "return": 204 } }
2024-08-20http: Refactor route pass queryZhidao HONG1-26/+15
2024-05-07Convert 0-sized arrays to true flexible array membersAndrew Clayton1-7/+7
Declaring a 0-sized array (e.g 'char arr[0];') as the last member of a structure is a GNU extension that was used to implement flexible array members (FAMs) before they were standardised in C99 as simply '[]'. The GNU extension itself was introduced to work around a hack of declaring 1-sized arrays to mean a variable-length object. The advantage of the 0-sized (and true FAMs) is that they don't count towards the size of the structure. Unit already declares some true FAMs, but it also declared some 0-sized arrays. Converting these 0-sized arrays to true FAMs is not only good for consistency but will also allow better compiler checks now (as in a C99 FAM *must* be the last member of a structure and the compiler will warn otherwise) and in the future as doing this fixes a bunch of warnings (treated as errors in Unit by default) when compiled with -O2 -Warray-bounds -Wstrict-flex-arrays -fstrict-flex-arrays=3 (Note -Warray-bounds is enabled by -Wall and -Wstrict-flex-arrays seems to also be enabled via -Wall -Wextra, the -02 is required to make -fstrict-flex-arrays more effective, =3 is the default on at least GCC 14) such as CC build/src/nxt_upstream.o src/nxt_upstream.c: In function ‘nxt_upstreams_create’: src/nxt_upstream.c:56:18: error: array subscript i is outside array bounds of ‘nxt_upstream_t[0]’ {aka ‘struct nxt_upstream_s[]’} [-Werror=array-bounds=] 56 | string = nxt_str_dup(mp, &upstreams->upstream[i].name, &name); | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ In file included from src/nxt_upstream.c:9: src/nxt_upstream.h:55:48: note: while referencing ‘upstream’ 55 | nxt_upstream_t upstream[0]; | ^~~~~~~~ Making our flexible array members proper C99 FAMs and ensuring any >0 sized trailing arrays in structures are really normal arrays will allow to enable various compiler options (such as the above and more) that will help keep our array usage safe. Changing 0-sized arrays to FAMs should have no effect on structure layouts/sizes (they both have a size of 0, although doing a sizeof() on a FAM will result in a compiler error). Looking at pahole(1) output for the nxt_http_route_ruleset_t structure for the [0] and [] cases... $ pahole -C nxt_http_route_ruleset_t /tmp/build/src/nxt_http_route.o typedef struct { uint32_t items; /* 0 4 */ /* XXX 4 bytes hole, try to pack */ nxt_http_route_rule_t * rule[]; /* 8 0 */ /* size: 8, cachelines: 1, members: 2 */ /* sum members: 4, holes: 1, sum holes: 4 */ /* last cacheline: 8 bytes */ } nxt_http_route_ruleset_t; $ pahole -C nxt_http_route_ruleset_t build/src/nxt_http_route.o typedef struct { uint32_t items; /* 0 4 */ /* XXX 4 bytes hole, try to pack */ nxt_http_route_rule_t * rule[]; /* 8 0 */ /* size: 8, cachelines: 1, members: 2 */ /* sum members: 4, holes: 1, sum holes: 4 */ /* last cacheline: 8 bytes */ } nxt_http_route_ruleset_t; Also checking with the size(1) command on the effected object files shows no changes to their sizes $ for file in build/src/nxt_upstream.o \ build/src/nxt_upstream_round_robin.o \ build/src/nxt_h1proto.o \ build/src/nxt_http_route.o \ build/src/nxt_http_proxy.o \ build/src/python/*.o; do \ size -G /tmp/${file} $file; echo; done text data bss total filename 640 418 0 1058 /tmp/build/src/nxt_upstream.o 640 418 0 1058 build/src/nxt_upstream.o text data bss total filename 929 351 0 1280 /tmp/build/src/nxt_upstream_round_robin.o 929 351 0 1280 build/src/nxt_upstream_round_robin.o text data bss total filename 11707 8281 16 20004 /tmp/build/src/nxt_h1proto.o 11707 8281 16 20004 build/src/nxt_h1proto.o text data bss total filename 8319 3101 0 11420 /tmp/build/src/nxt_http_route.o 8319 3101 0 11420 build/src/nxt_http_route.o text data bss total filename 1495 1056 0 2551 /tmp/build/src/nxt_http_proxy.o 1495 1056 0 2551 build/src/nxt_http_proxy.o text data bss total filename 4321 2895 0 7216 /tmp/build/src/python/nxt_python_asgi_http-python.o 4321 2895 0 7216 build/src/python/nxt_python_asgi_http-python.o text data bss total filename 4231 2266 0 6497 /tmp/build/src/python/nxt_python_asgi_lifespan-python.o 4231 2266 0 6497 build/src/python/nxt_python_asgi_lifespan-python.o text data bss total filename 12051 6090 8 18149 /tmp/build/src/python/nxt_python_asgi-python.o 12051 6090 8 18149 build/src/python/nxt_python_asgi-python.o text data bss total filename 28 1963 432 2423 /tmp/build/src/python/nxt_python_asgi_str-python.o 28 1963 432 2423 build/src/python/nxt_python_asgi_str-python.o text data bss total filename 5818 3518 0 9336 /tmp/build/src/python/nxt_python_asgi_websocket-python.o 5818 3518 0 9336 build/src/python/nxt_python_asgi_websocket-python.o text data bss total filename 4391 2089 168 6648 /tmp/build/src/python/nxt_python-python.o 4391 2089 168 6648 build/src/python/nxt_python-python.o text data bss total filename 9095 5909 152 15156 /tmp/build/src/python/nxt_python_wsgi-python.o 9095 5909 152 15156 build/src/python/nxt_python_wsgi-python.o Link: <https://lwn.net/Articles/908817/> Link: <https://people.kernel.org/kees/bounded-flexible-arrays-in-c> Signed-off-by: Andrew Clayton <a.clayton@nginx.com>
2024-04-25Constify a bunch of static local variablesAndrew Clayton1-2/+2
A common pattern was to declare variables in functions like static nxt_str_t ... Not sure why static, as they were being treated more like string literals (and of course they are _not_ thread safe), let's actually make them constants (qualifier wise). This handles core code conversion. Reviewed-by: Zhidao HONG <z.hong@f5.com> Signed-off-by: Andrew Clayton <a.clayton@nginx.com>
2024-03-11Router: match when pattern and tested string are both zero lengthAndrei Zeliankou1-0/+4
Otherwise, undefined behaviour will be triggered. Can be reproduced by test/test_routing.py::test_routes_match_host_empty with enabled UndefinedBehaviorSanitizer: src/nxt_http_route.c:2141:17: runtime error: applying zero offset to null pointer #0 0x100562588 in nxt_http_route_test_rule nxt_http_route.c:2091 #1 0x100564ed8 in nxt_http_route_handler nxt_http_route.c:1574 #2 0x10055188c in nxt_http_request_action nxt_http_request.c:570 #3 0x10052b1a0 in nxt_h1p_request_body_read nxt_h1proto.c:998 #4 0x100449c38 in nxt_event_engine_start nxt_event_engine.c:542 #5 0x100436828 in nxt_thread_trampoline nxt_thread.c:126 #6 0x18133e030 in _pthread_start+0x84 (libsystem_pthread.dylib:arm64e+0x7030) #7 0x181338e38 in thread_start+0x4 (libsystem_pthread.dylib:arm64e+0x1e38) SUMMARY: UndefinedBehaviorSanitizer: undefined-behavior src/nxt_http_route.c:2141:17 Reviewed-by: Andrew Clayton <a.clayton@nginx.com>
2023-08-09HTTP: controlling response headers support.Zhidao HONG1-0/+12
2023-08-09HTTP: stored matched action in nxt_http_request_t.Zhidao HONG1-0/+5
No functional changes.
2023-04-20HTTP: added basic URI rewrite.Zhidao HONG1-4/+16
This commit introduced the basic URI rewrite. It allows users to change request URI. Note the "rewrite" option ignores the contained query if any and the query from the request is preserverd. An example: "routes": [ { "match": { "uri": "/v1/test" }, "action": { "return": 200 } }, { "action": { "rewrite": "/v1$uri", "pass": "routes" } } ] Reviewed-by: Alejandro Colomar <alx@nginx.com>
2023-03-21HTTP: added route logging.Alejandro Colomar1-0/+12
- Configuration: added "/config/settings/http/log_route". Type: bool Default: false This adds configurability to the error log. It allows enabling and disabling logs related to how the router performs selection of the routes. - HTTP: logging request line. Log level: [notice] The request line is essential to understand which logs correspond to which request when reading the logs. - HTTP: logging route that's been discarded. Log level: [info] - HTTP: logging route whose action is selected. Log level: [notice] - HTTP: logging when "fallback" action is taken. Log level: [notice] Closes: <https://github.com/nginx/unit/issues/758> Link: <https://github.com/nginx/unit/pull/824> Link: <https://github.com/nginx/unit/pull/839> Suggested-by: Timo Stark <t.stark@nginx.com> Suggested-by: Mark L Wood-Patrick <mwoodpatrick@gmail.com> Suggested-by: Liam Crilly <liam@nginx.com> Tested-by: Liam Crilly <liam@nginx.com> Acked-by: Artem Konev <a.konev@f5.com> Cc: Andrew Clayton <a.clayton@nginx.com> Cc: Andrei Zeliankou <zelenkov@nginx.com> Reviewed-by: Zhidao Hong <z.hong@f5.com> Signed-off-by: Alejandro Colomar <alx@nginx.com>
2023-03-21HTTP: rewrote while loop as for loop.Alejandro Colomar1-7/+3
This considerably simplifies the function, and will also help log the iteration in which we are, which corresponds to the route array element. Link: <https://github.com/nginx/unit/pull/824> Link: <https://github.com/nginx/unit/pull/839> Reviewed-by: Andrew Clayton <a.clayton@nginx.com> Tested-by: Liam Crilly <liam@nginx.com> Reviewed-by: Zhidao Hong <z.hong@f5.com> Signed-off-by: Alejandro Colomar <alx@nginx.com>
2022-11-20Basic njs support.Zhidao HONG1-1/+1
2022-11-20Var: separating nxt_tstr_t from nxt_var_t.Zhidao HONG1-20/+24
It's for the introduction of njs support. For each option that supports native variable and JS template literals introduced next, it's unified as template string. No functional changes.
2022-11-04Removed the unsafe nxt_memchr() wrapper for memchr(3).Alejandro Colomar1-2/+2
The casts are unnecessary, since memchr(3)'s argument is 'const void *'. It might have been necessary in the times of K&R, where 'void *' didn't exist. Nowadays, it's unnecessary, and _very_ unsafe, since casts can hide all classes of bugs by silencing most compiler warnings. The changes from nxt_memchr() to memchr(3) were scripted: $ find src/ -type f \ | grep '\.[ch]$' \ | xargs sed -i 's/nxt_memchr/memchr/' Reviewed-by: Andrew Clayton <a.clayton@nginx.com> Signed-off-by: Alejandro Colomar <alx@nginx.com>
2022-11-04Removed the unsafe nxt_memcmp() wrapper for memcmp(3).Alejandro Colomar1-9/+9
The casts are unnecessary, since memcmp(3)'s arguments are 'void *'. It might have been necessary in the times of K&R, where 'void *' didn't exist. Nowadays, it's unnecessary, and _very_ unsafe, since casts can hide all classes of bugs by silencing most compiler warnings. The changes from nxt_memcmp() to memcmp(3) were scripted: $ find src/ -type f \ | grep '\.[ch]$' \ | xargs sed -i 's/nxt_memcmp/memcmp/' Reviewed-by: Andrew Clayton <a.clayton@nginx.com> Signed-off-by: Alejandro Colomar <alx@nginx.com>
2022-07-26Supporting UNIX sockets in address matching.Alejandro Colomar1-0/+7
This closes #645 issue on GitHub. (Also moved a changelog line that was misplaced in a previous commit.)
2022-07-14Var: dynamic variables support.Zhidao HONG1-5/+9
This commit adds the variables $arg_NAME, $header_NAME, and $cookie_NAME.
2022-06-20Router: forwared header replacement.Zhidao HONG1-3/+2
2022-05-19HTTP: generalized uri encoding.Zhidao HONG1-103/+33
No functional changes.
2022-05-30Static: supporting new "index" option.Alejandro Colomar1-0/+5
This supports a new option "index" that configures a custom index file name to be served when a directory is requested. This initial support only allows a single fixed string. An example: { "share": "/www/data/static/$uri", "index": "lookatthis.htm" } When <example.com/foo/bar/> is requested, </www/data/static/foo/bar/lookatthis.html> is served. Default is "index.html". === nxt_conf_validator.c: Accept "index" as a member of "share", and make sure it's a string. === I tried this feature in my own computer, where I tried the following: - Setting "index" to "lookatthis.htm", and check that the correct file is being served (check both a different name and a different extension). - Not setting "index", and check that <index.html> is being served. - Settind "index" to an array of strings, and check that the configuration fails: { "error": "Invalid configuration.", "detail": "The \"index\" value must be a string, but not an array." }
2022-05-18HTTP: generalized argument and cookie parsing.Zhidao HONG1-291/+3
No functional changes.
2022-05-16Supporting empty Location URIs.Alejandro Colomar1-1/+1
An empty string in Location was being handled specially by not sending a Location header. This may occur after variable resolution, so we need to consider this scenario. The obsolete RFC 2616 defined the Location header as consisting of an absolute URI <https://www.rfc-editor.org/rfc/rfc2616#section-14.30>, which cannot be an empty string. However, the current RFC 7231 allows the Location to be a relative URI <https://www.rfc-editor.org/rfc/rfc7231#section-7.1.2>, and a relative URI may be an empty string <https://stackoverflow.com/a/43338457>. Due to these considerations, this patch allows sending an empty Location header without handling this case specially. This behavior will probably be more straightforward to users, too. It also simplifies the code, which is now more readable, fast, and conformant to the current RFC. We're skipping an allocation at request time in a common case such as "action": {"return": 404}
2022-04-26Fixed indentation.Alejandro Colomar1-2/+2
Some lines (incorrectly) had an indentation of 3 or 5, or 7 or 9, or 11 or 13, or 15 or 17 spaces instead of 4, 8, 12, or 16. Fix them. Found with: $ find src -type f | xargs grep -n '^ [^ ]'; $ find src -type f | xargs grep -n '^ [^ *]'; $ find src -type f | xargs grep -n '^ [^ ]'; $ find src -type f | xargs grep -n '^ [^ *]'; $ find src -type f | xargs grep -n '^ [^ +]'; $ find src -type f | xargs grep -n '^ [^ *+]'; $ find src -type f | xargs grep -n '^ [^ +]'; $ find src -type f | xargs grep -n '^ [^ *+]';
2022-04-26Removed special cases for non-NXT_CONF_VALUE_ARRAY.Alejandro Colomar1-45/+6
The previous commit added more generic APIs for handling NXT_CONF_VALUE_ARRAY and non-NXT_CONF_VALUE_ARRAY together. Modify calling code to remove special cases for arrays and non-arrays, taking special care that the path for non arrays is logically equivalent to the previous special cased code. Use the now-generic array code only.
2021-11-05Router: matching query string support.Zhidao HONG1-0/+45
The "query" option matches decoded arguments, including plus ('+') to space (' '). Like "uri", it can be a string or an array of strings.
2021-11-05HTTP: removed surplus check for r->args is not NULL.Zhidao HONG1-4/+0
2021-11-05Router: fixed nxt_http_route_arguments_parse().Zhidao HONG1-20/+11
A valid query string argument is a string of "key=value\[&key=value ...\]" pairs with non-empty keys. The fix removes invalid empty arguments.
2021-09-28Static: variables in the "chroot" option.Zhidao HONG1-2/+2
2021-09-07Router: refactored variable pass.Zhidao HONG1-45/+52
Since the "pass" option supports both strings and variables, a generic nxt_var_t structure can be used in the configuration phase, and the "name" field in actions is redundant. No functional changes.
2021-08-12Router: client IP address replacement.Oisin Canty1-8/+4
This commit introduces the replacement of the client address based on the value of a specified HTTP header. This is intended for use when Unit is placed behind a reverse proxy like nginx or a CDN. You must specify the source addresses of the trusted proxies. This can be accomplished with any valid IP pattern supported by Unit's match block: ["10.0.0.1", "10.4.0.0/16", "!192.168.1.1"] The feature is configured per listener. The client address replacement functionality only operates when there is a source IP match and the specified header is present. Typically this would be an 'X-Forwarded-For' header. { "listeners": { "127.0.0.1:8080": { "client_ip": { "header": "X-Forwarded-For", "source": [ "10.0.0.0/8" ] }, "pass": "applications/my_app" }, } } If a request occurs and Unit receives a header like below: "X-Forwarded-For: 84.123.23.23" By default, Unit trusts the last rightmost IP in the header, so REMOTE_ADDR will be set to 84.123.23.23 if the connection originated from 10.0.0.0/8. If Unit runs behind consecutive reverse proxies and receives a header similar to the following: "X-Forwarded-For: 84.123.23.23, 10.0.0.254" You will need to enable "recursive" checking, which walks the header from last address to first and chooses the first non-trusted address it finds. { "listeners": { "127.0.0.1:8080": { "client_ip": { "header": "X-Forwarded-For", "source": [ "10.0.0.0/8" ] "recursive": true, }, "pass": "applications/my_app" }, } } If a connection from 10.0.0.0/8 occurs, the chain is walked. Here, 10.0.0.254 is also a trusted address so the client address will be replaced with 84.123.23.23. If all IP addresses in the header are trusted, the client address is set to the first address in the header: If 10.0.0.0/8 is trusted and "X-Forwarded-For: 10.0.0.3, 10.0.0.2, 10.0.0.1", the client address will be replaced with 10.0.0.3.
2021-08-05Router: fixed crash when matching an empty address pattern array.Oisin Canty1-0/+5
A crash would occur when the router tried to match an against an empty address pattern array. The following configuration was used to reproduce the issue: { "listeners": { "127.0.0.1:8082": { "pass": "routes" } }, "routes": [ { "match": { "source": [] }, "action": { "return": 200 } } ] }
2021-08-02Router: fixed segmentation fault.Zhidao HONG1-0/+4
In the case that routes or upstreams is empty and the pass option is a variable. If the resolved pass is routes or upstreams, a segment error occurred.
2021-07-24Router: split nxt_http_app_conf_t from nxt_http_action_t.Zhidao HONG1-23/+3
No functional changes.
2021-07-26Router: renamed nxt_http_proxy_create() as nxt_http_proxy_init().Zhidao HONG1-10/+2
No functional changes.
2021-07-23Router: split nxt_http_static_conf_t from nxt_http_action_t.Zhidao HONG1-84/+17
No functional changes.
2021-05-24Router: split nxt_http_return_conf_t from nxt_http_action_t.Zhidao HONG1-87/+43
No functional changes.
2021-05-06Static: implemented MIME filteringOisin Canty1-12/+29
2021-04-29Static: support for openat2() features.Zhidao HONG1-1/+62
Support for chrooting, rejecting symlinks, and rejecting crossing mounting points on a per-request basis during static file serving.
2021-04-22Router: grouped app and share fields in nxt_http_action_t.Zhidao HONG1-19/+27
This is a prerequisite for further introduction of openat2() features. No functional changes.
2021-02-01Fixed building by GCC 10 with -flto and -O2.Valentin Bartenev1-0/+6
This closes #467 issue on GitHub.
2020-11-17Router: matching regular expressions support.Axel Duch1-13/+86
2020-10-07Router: fixed "not empty" pattern matching.Valentin Bartenev1-4/+0
The "!" pattern should be opposite to "", i.e. match only non-empty values. But after 3c00af54b937 it was equal to "!*", which is wrong.
2020-08-28Router: fixed "pass" to upstreams.hongzhidao1-1/+5
Messed up return values in nxt_upstream_find() caused error in applying any configuration with a valid "pass" value in router configuration pointing to upstream. That wasn't the case in "listeners" objects, where the return value wasn't checked. Also, it caused segfault in cases where the "pass" option was configured with variables and resulting value was pointing to a non-existent upstream. Added missing return checks as well to catch possible memory allocation errors. The bug was introduced in d32bc428f46b. This closes #472 issue on GitHub.
2020-08-13Fixed typo in return value check.Valentin Bartenev1-1/+1
Found by Coverity (CID 361277).
2020-08-13Basic variables support.Valentin Bartenev1-71/+136
2020-07-24Minor changes and renaming an NJS artifact to NXT.Axel Duch1-3/+3
This is partially related to #434 issue on Github. Thanks to 洪志道 (Hong Zhi Dao).
2020-07-10Router: route patterns multi wildcards fix.Axel Duch1-3/+6
Matching 'start' and 'end' position now adjusted to avoid false matching. This is related to #434 issue on Github. Thanks to 洪志道 (Hong Zhi Dao).
2020-07-04Router: route patterns multi wildcards support.Axel Duch1-113/+205
2020-05-15Router: removed two unused assignments.Valentin Bartenev1-3/+0
This should resolve some static analyzers warnings.
2020-05-14Router: decode uri and args.Axel Duch1-57/+221
2020-05-14PHP: implemented "targets" option.Valentin Bartenev1-3/+18
This allows to specify multiple subsequent targets inside PHP applications. For example: { "listeners": { "*:80": { "pass": "routes" } }, "routes": [ { "match": { "uri": "/info" }, "action": { "pass": "applications/my_app/phpinfo" } }, { "match": { "uri": "/hello" }, "action": { "pass": "applications/my_app/hello" } }, { "action": { "pass": "applications/my_app/rest" } } ], "applications": { "my_app": { "type": "php", "targets": { "phpinfo": { "script": "phpinfo.php", "root": "/www/data/admin", }, "hello": { "script": "hello.php", "root": "/www/data/test", }, "rest": { "root": "/www/data/example.com", "index": "index.php" }, } } } }