Age | Commit message (Collapse) | Author | Files | Lines |
|
As was pointed out by the cppcheck[0] static code analysis utility we
were doing void pointer arithmetic on src->elts which is technically
undefined behaviour.
While GCC allows this by treating the size of void as 1[1]. Same with
Clang. Other compilers I'm not sure about, so lets just be safe and cast
src->nelts to (char *) where sizeof(char) is guaranteed to be 1.
[0]: https://cppcheck.sourceforge.io/
[1]: https://gcc.gnu.org/onlinedocs/gcc/Pointer-Arith.html
|
|
No functional changes.
|
|
|
|
The message tracking is unused since 1d84b9e4b459 commit.
This fixes the issue found by Coverity (CID 376263).
|
|
No functional changes.
|
|
No functional changes.
|
|
No functional changes.
|
|
|
|
|
|
|
|
Before Node.js v16.14.0 the "format" value in defaultResolve
was ignored so error was hidden. For more information see:
https://github.com/nodejs/node/pull/40980
|
|
|
|
|
|
|
|
|
|
|
|
|
|
This supports a new variable $request_uri that contains the path
and the query (See RFC 3986, section 3). Its contents are percent
encoded. This is useful for example to redirect HTTP to HTTPS:
{
"return": "301",
"location": "https://$host$request_uri"
}
When <http://example.com/foo%23bar?baz> is requested, the server
redirects to <https://example.com/foo%23bar?baz>.
===
Testing:
//diff --git a/src/nxt_http_return.c b/src/nxt_http_return.c
//index 82c9156..adeb3a1 100644
//--- a/src/nxt_http_return.c
//+++ b/src/nxt_http_return.c
//@@ -196,6 +196,7 @@ nxt_http_return_send_ready(nxt_task_t *task,
void *obj, void *data)
// field->value = ctx->encoded.start;
// field->value_length = ctx->encoded.length;
// }
//+ fprintf(stderr, "ALX: target[%1$i]: <%2$.*1$s>\n",
(int)r->target.length, r->target.start);
//
// r->state = &nxt_http_return_send_state;
//
{
"listeners": {
"*:81": {
"pass": "routes/ru"
}
},
"routes": {
"ru": [{
"action": {
"return": 301,
"location": "$request_uri"
}
}]
}
}
$ curl -i http://localhost:81/*foo%2Abar?baz#arg
HTTP/1.1 301 Moved Permanently
Location: /*foo%2Abar?baz
Server: Unit/1.27.0
Date: Mon, 30 May 2022 16:04:30 GMT
Content-Length: 0
$ sudo cat /usr/local/unit.log | grep ALX
ALX: target[15]: </*foo%2Abar?baz>
|
|
|
|
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."
}
|
|
|
|
Before this patch, if "index" was a file, but not a regular file
nor a directory, so it may have been for example a FIFO, Unit
returned 404. But if "index" was a directory, Unit returned 301.
For consistency, this patch makes Unit return 404 for every
non-regular file, including directories.
|
|
Casts are usually very dangerous, disabling most compiler warnings
and basically removing type safety. This change adds 'const' to a
pointer where we don't need to write, improving type safety, and
that also allows removing some casts.
|
|
No functional changes.
|
|
|
|
|
|
nxt_str_null() setted the loc.start pointer to NULL, which was
being passed to memcpy(3) through nxt_debug(). That caused
Undefined Behavior, so we now pass an empty string.
|
|
|
|
|
|
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}
|
|
|
|
Having a configurable index filename will require adding an index
field to this structure. The most natural name for that field is
'index', so the current index field should be renamed to allow for
that. A sensible name is 'share_idx', since it's the index of the
shares array in 'nxt_http_static_conf_t'.
Instead of 'share_index' I opted for the shorter 'share_idx'.
Also, when 'index' allows an array of filenames in a following
commit, another similar variable 'index_idx' should be created,
and having a different prefix and suffix seems more readable than
for example 'index_index'.
|
|
|
|
|
|
This closes #654 issue on Github.
|
|
|
|
|
|
A new behaviour was introduced in OpenSSL 1.1.1e, when a peer does not send
close_notify before closing the connection. Previously, it was to return
SSL_ERROR_SYSCALL with errno 0, known since at least OpenSSL 0.9.7, and is
handled gracefully in unitd. Now it returns SSL_ERROR_SSL with a distinct
reason SSL_R_UNEXPECTED_EOF_WHILE_READING ("unexpected eof while reading").
This leads to critical errors seen in nginx within various routines such as
SSL_do_handshake(), SSL_read(), SSL_shutdown(). The behaviour was restored
in OpenSSL 1.1.1f, but presents in OpenSSL 3.0 by default.
Use of the SSL_OP_IGNORE_UNEXPECTED_EOF option added in OpenSSL 3.0 allows
setting a compatible behaviour to return SSL_ERROR_ZERO_RETURN:
https://git.openssl.org/?p=openssl.git;a=commitdiff;h=09b90e0
See for additional details: https://github.com/openssl/openssl/issues/11381
|
|
The macro is used to suppress deprecation warnings with OpenSSL 3.0.
Unlike OPENSSL_API_COMPAT, it works well with OpenSSL built with no-deprecated.
In particular, it doesn't unhide various macros in OpenSSL includes, which are
meant to be hidden under OPENSSL_NO_DEPRECATED.
|
|
|
|
|
|
|
|
|
|
We had a mix of styles for declaring function-like macros:
Style A:
#define \
foo() \
do { \
... \
} while (0)
Style B:
#define foo() \
do { \
... \
} while (0)
We had a similar number of occurences of each style:
$ grep -rnI '^\w*(.*\\' | wc -l
244
$ grep -rn 'define.*(.*)' | wc -l
239
(Those regexes aren't perfect, but a very decent approximation.)
Real examples:
$ find src -type f | xargs sed -n '/^nxt_double_is_zero/,/^$/p'
nxt_double_is_zero(f) \
(fabs(f) <= FLT_EPSILON)
$ find src -type f | xargs sed -n '/define nxt_http_field_set/,/^$/p'
#define nxt_http_field_set(_field, _name, _value) \
do { \
(_field)->name_length = nxt_length(_name); \
(_field)->value_length = nxt_length(_value); \
(_field)->name = (u_char *) _name; \
(_field)->value = (u_char *) _value; \
} while (0)
I'd like to standardize on a single style for them, and IMO,
having the identifier in the same line as #define is a better
option for the following reasons:
- Programmers are used to `#define foo() ...` (readability).
- One less line of code.
- The program for finding them is really simple (see below).
function grep_ngx_func()
{
if (($# != 1)); then
>&2 echo "Usage: ${FUNCNAME[0]} <func>";
return 1;
fi;
find src -type f \
| grep '\.[ch]$' \
| xargs grep -l "$1" \
| sort \
| xargs pcregrep -Mn "(?s)^\$[\w\s*]+?^$1\(.*?^}";
find src -type f \
| grep '\.[ch]$' \
| xargs grep -l "$1" \
| sort \
| xargs pcregrep -Mn "(?s)define $1\(.*?^$" \
| sed -E '1s/^[^:]+:[0-9]+:/&\n\n/';
}
$ grep_ngx_func
Usage: grep_ngx_func <func>
$ grep_ngx_func nxt_http_field_set
src/nxt_http.h:98:
#define nxt_http_field_set(_field, _name, _value) \
do { \
(_field)->name_length = nxt_length(_name); \
(_field)->value_length = nxt_length(_value); \
(_field)->name = (u_char *) _name; \
(_field)->value = (u_char *) _value; \
} while (0)
$ grep_ngx_func nxt_sprintf
src/nxt_sprintf.c:56:
u_char * nxt_cdecl
nxt_sprintf(u_char *buf, u_char *end, const char *fmt, ...)
{
u_char *p;
va_list args;
va_start(args, fmt);
p = nxt_vsprintf(buf, end, fmt, args);
va_end(args);
return p;
}
................
Scripted change:
................
$ find src -type f \
| grep '\.[ch]$' \
| xargs sed -i '/define *\\$/{N;s/ *\\\n/ /;s/ //}'
|
|
|
|
|
|
............
Description:
............
Before this commit, the encoded URI could be calculated at
configuration time. Now, since variables can only be resolved at
request time, we have different situations:
- "location" contains no variables:
In this case, we still encode the URI in the conf structure, at
configuration time, and then we just copy the resulting string
to the ctx structure at request time.
- "location" contains variables:
In this case, we compile the var string at configure time, then
when we resolve it at request time, and then we encode the
string.
In both cases, as was being done before, if the string is empty,
either before or after resolving variables, we skip the encoding.
...........
Usefulness:
...........
An example of why this feature may be useful is redirecting HTTP
to HTTPS with something like:
"action": {
"return": 301,
"location": "https://${host}${uri}"
}
.....
Bugs:
.....
This feature conflicts with the relevant RFCs in the following:
'$' is used for Unit variables, but '$' is a reserved character in
a URI, to be used as a sub-delimiter. However, it's almost never
used as that, and in fact, other parts of Unit already conflict
with '$' being a reserved character for use as a sub-delimiter, so
this is at least consistent in that sense. VBart suggested an
easy workaround if we ever need it: adding a variable '$sign'
which resolves to a literal '$'.
......
Notes:
......
An empty string is handled as if "location" wasn't specified at
all, so no Location header is sent.
This is incorrect, and the code is slightly misleading.
The Location header consists of a URI-reference[1], which might be
a relative one, which itself might consist of an empty string[2].
[1]: <https://www.rfc-editor.org/rfc/rfc7231#section-7.1.2>
[2]: <https://stackoverflow.com/a/43338457>
Now that we have variables, it's more likely that an empty
Location header will be requested, and we should handle it
correctly.
I think in a future commit we should modify the code to allow
differentiating between an unset "location" and an empty one,
which should be treated as any other "location" string.
.................
Testing (manual):
.................
{
"listeners": {
"*:80": {
"pass": "routes/str"
},
"*:81": {
"pass": "routes/empty"
},
"*:82": {
"pass": "routes/var"
},
"*:83": {
"pass": "routes/enc-str"
},
"*:84": {
"pass": "routes/enc-var"
}
},
"routes": {
"str": [
{
"action": {
"return": 301,
"location": "foo"
}
}
],
"empty": [
{
"action": {
"return": 301,
"location": ""
}
}
],
"var": [
{
"action": {
"return": 301,
"location": "$host"
}
}
],
"enc-str": [
{
"action": {
"return": 301,
"location": "f%23o#o"
}
}
],
"enc-var": [
{
"action": {
"return": 301,
"location": "f%23o${host}#o"
}
}
]
}
}
$ curl --dump-header - localhost:80
HTTP/1.1 301 Moved Permanently
Location: foo
Server: Unit/1.27.0
Date: Thu, 07 Apr 2022 23:30:06 GMT
Content-Length: 0
$ curl --dump-header - localhost:81
HTTP/1.1 301 Moved Permanently
Server: Unit/1.27.0
Date: Thu, 07 Apr 2022 23:30:08 GMT
Content-Length: 0
$ curl --dump-header - localhost:82
HTTP/1.1 301 Moved Permanently
Location: localhost
Server: Unit/1.27.0
Date: Thu, 07 Apr 2022 23:30:15 GMT
Content-Length: 0
$ curl --dump-header - -H "Host: bar" localhost:82
HTTP/1.1 301 Moved Permanently
Location: bar
Server: Unit/1.27.0
Date: Thu, 07 Apr 2022 23:30:23 GMT
Content-Length: 0
$ curl --dump-header - -H "Host: " localhost:82
HTTP/1.1 301 Moved Permanently
Server: Unit/1.27.0
Date: Thu, 07 Apr 2022 23:30:29 GMT
Content-Length: 0
$ curl --dump-header - localhost:83
HTTP/1.1 301 Moved Permanently
Location: f%23o#o
Server: Unit/1.27.0
Date: Sat, 09 Apr 2022 11:22:23 GMT
Content-Length: 0
$ curl --dump-header - -H "Host: " localhost:84
HTTP/1.1 301 Moved Permanently
Location: f%23o#o
Server: Unit/1.27.0
Date: Sat, 09 Apr 2022 11:22:44 GMT
Content-Length: 0
$ curl --dump-header - -H "Host: alx" localhost:84
HTTP/1.1 301 Moved Permanently
Location: f%23oalx#o
Server: Unit/1.27.0
Date: Sat, 09 Apr 2022 11:22:52 GMT
Content-Length: 0
$ curl --dump-header - -H "Host: a#l%23x" localhost:84
HTTP/1.1 301 Moved Permanently
Location: f%2523oa#l%2523x%23o
Server: Unit/1.27.0
Date: Sat, 09 Apr 2022 11:23:09 GMT
Content-Length: 0
$ curl --dump-header - -H "Host: b##ar" localhost:82
HTTP/1.1 301 Moved Permanently
Location: b#%23ar
Server: Unit/1.27.0
Date: Sat, 09 Apr 2022 11:25:01 GMT
Content-Length: 0
|
|
Add -fdeclspec to NXT_RUBY_CFLAGS for Clang, if it's available.
Clang incorrectly reports 1 for __has_declspec_attribute(x) in
some cases, such as MacOS or Cygwin. That causes ruby code to
break. ruby added -fdeclspec to their CFLAGS in 2019 to
workaround this bug, since it enables __declspec() and therefore,
the compiler behavior matches what it reports.
Since we don't know what are all the architectures that trigger
the clang bug, let's add the flag for all of them (especially
since it should be harmless).
Add this workaround only at the time of configuring the ruby
module. This way we don't clutter the global NXT_CFLAGS with an
unnecessary flag.
Link: unit bug <https://github.com/nginx/unit/issues/653>
Link: ruby bug <https://bugs.ruby-lang.org/issues/18616>
Link: LLVM bug <https://github.com/llvm/llvm-project/issues/49958>
Commit: LLVM: Add -fdeclspec <d170c4b57a91adc74ca89c6d4af616a00323b12c>
Commit: ruby: Use -fdeclspec <0958e19ffb047781fe1506760c7cbd8d7fe74e57>
|
|
When testing some configurations of compilers and OSes, I noticed
that clang(1) 13 on Debian caused a function to be compiled but
unused, and the compiler triggered a compile error.
To avoid that error, use __attribute__((__unused__)). Let's call
our wrapper NXT_MAYBE_UNUSED, since it describes itself more
precisely than the GCC attribute name. It's also the name that
C2x (likely C23) has given to the standard attribute, which is
[[maybe_unused]], so it's also likely to be more readable because
of that name being in ISO C.
|
|
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 '^ [^ *+]';
|