<feed xmlns='http://www.w3.org/2005/Atom'>
<title>unit.git/src, branch str-v1</title>
<subtitle>Universal Web Application Server</subtitle>
<link rel='alternate' type='text/html' href='https://git.sigsegv.uk/unit.git/'/>
<entry>
<title>Added nxt_usts2str() to make C strings from nxt_str_t.</title>
<updated>2022-11-12T19:39:48+00:00</updated>
<author>
<name>Alejandro Colomar</name>
<email>alx@nginx.com</email>
</author>
<published>2022-10-27T11:22:19+00:00</published>
<link rel='alternate' type='text/html' href='https://git.sigsegv.uk/unit.git/commit/?id=b2571ebac22180eb3fb6568726f82293d2dd8be3'/>
<id>b2571ebac22180eb3fb6568726f82293d2dd8be3</id>
<content type='text'>
This function is identical to nxt_ustr2str(), except that it takes
a nxt_str_t structure as input, instead of a 'u_char *' and a size.

The documentation of the function:

/*
 * SYNOPSIS
 *   void nxt_usts2str(char dst[restrict .src-&gt;length+1],
 *                     const nxt_str_t *restrict src);
 *
 * ARGUMENTS
 *      dst     Pointer to the first byte of the destination buffer.
 *      src     Pointer to the source Unterminated STring Structure.
 *
 * DESCRIPTION
 *      Copy a string from the source nxt_str_t, which may be
 *      not-NUL-terminated, into a NUL-terminated string in the
 *      destination buffer.
 *
 * CAVEATS
 *      If the destination buffer is not wider than the source buffer
 *      at least by 1 byte, the behavior is undefined.
 *
 * EXAMPLES
 *      nxt_str_t  src = nxt_string("0123456789");
 *      char       dst[src.length + 1];
 *
 *      nxt_usts2str(dst, &amp;src);
 *
 * SEE ALSO
 *      ustr2str(3), strlcpy(3), strscpy(9)
 */

Suggested-by: Andrew Clayton &lt;a.clayton@nginx.com&gt;
Signed-off-by: Alejandro Colomar &lt;alx@nginx.com&gt;
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
This function is identical to nxt_ustr2str(), except that it takes
a nxt_str_t structure as input, instead of a 'u_char *' and a size.

The documentation of the function:

/*
 * SYNOPSIS
 *   void nxt_usts2str(char dst[restrict .src-&gt;length+1],
 *                     const nxt_str_t *restrict src);
 *
 * ARGUMENTS
 *      dst     Pointer to the first byte of the destination buffer.
 *      src     Pointer to the source Unterminated STring Structure.
 *
 * DESCRIPTION
 *      Copy a string from the source nxt_str_t, which may be
 *      not-NUL-terminated, into a NUL-terminated string in the
 *      destination buffer.
 *
 * CAVEATS
 *      If the destination buffer is not wider than the source buffer
 *      at least by 1 byte, the behavior is undefined.
 *
 * EXAMPLES
 *      nxt_str_t  src = nxt_string("0123456789");
 *      char       dst[src.length + 1];
 *
 *      nxt_usts2str(dst, &amp;src);
 *
 * SEE ALSO
 *      ustr2str(3), strlcpy(3), strscpy(9)
 */

Suggested-by: Andrew Clayton &lt;a.clayton@nginx.com&gt;
Signed-off-by: Alejandro Colomar &lt;alx@nginx.com&gt;
</pre>
</div>
</content>
</entry>
<entry>
<title>Added nxt_ustr2str() to make C strings from fixed-width buffers.</title>
<updated>2022-11-12T19:39:48+00:00</updated>
<author>
<name>Alejandro Colomar</name>
<email>alx@nginx.com</email>
</author>
<published>2022-10-25T16:42:52+00:00</published>
<link rel='alternate' type='text/html' href='https://git.sigsegv.uk/unit.git/commit/?id=2461a61574db338ed830de7cce1264cd321ccb2a'/>
<id>2461a61574db338ed830de7cce1264cd321ccb2a</id>
<content type='text'>
This function makes it easy to transform a fixed-width buffer
(which is how we represent strings in Unit most of the time) into
a proper C string (NUL-terminated).  We need to do this when
interfacing libraries or the kernel, where most APIs expect
NUL-terminated strings.

The implementation is similar to strncpy_s(3), but avoids the
unnecessary runtime checks.  It's better to wrap the function in a
macro and do as many static_assert(3)s as one considers necessary;
in fact, if in the future C allows backwards VLA syntax, static
analysis could be better than those static_assert(3)s.

We use char for NUL-terminated strings, and u_char for the
*u*nterminated strings.

The documentation for the function:

/*
 * SYNOPSIS
 *   void ustr2str(char dst[restrict .n+1],
 *                 const u_char src[restrict .n],
 *                 size_t n);
 *
 * ARGUMENTS
 *	dst	Pointer to the first byte of the destination buffer.
 *	src	Pointer to the first byte of the source string.
 *	n	Size of 'src'.
 *
 * DESCRIPTION
 *	Copy a string from the fixed-width source string, which may be
 *	not-NUL-terminated, into a NUL-terminated string in the
 *	destination buffer.
 *
 * CAVEATS
 *	If the destination buffer is not wider than the source buffer
 *	at least by 1 byte, the behavior is undefined.
 *
 *	Use of this function normally indicates a problem in the design
 *	of the strings, since normally it's better to guarantee that all
 *	strings are properly terminated.  The main use for this function
 *	is to interface with some standard buffers, such as those
 *	defined in utmp(7), which for historical reasons are not
 *	guaranteed to be terminated.
 *
 * EXAMPLES
 *	u_char  src[10] = "0123456789";  // not NUL-terminated
 *	char    dst[sizeof(src) + 1];
 *
 *	static_assert(lengthof(src) &lt; lengthof(dst))
 *	ustr2str(dst, src, lengthof(src));
 *
 * SEE ALSO
 *	nxt_sts2str(3), strlcpy(3), strscpy(9)
 */

Cc: Andrew Clayton &lt;a.clayton@nginx.com&gt;
Signed-off-by: Alejandro Colomar &lt;alx@nginx.com&gt;
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
This function makes it easy to transform a fixed-width buffer
(which is how we represent strings in Unit most of the time) into
a proper C string (NUL-terminated).  We need to do this when
interfacing libraries or the kernel, where most APIs expect
NUL-terminated strings.

The implementation is similar to strncpy_s(3), but avoids the
unnecessary runtime checks.  It's better to wrap the function in a
macro and do as many static_assert(3)s as one considers necessary;
in fact, if in the future C allows backwards VLA syntax, static
analysis could be better than those static_assert(3)s.

We use char for NUL-terminated strings, and u_char for the
*u*nterminated strings.

The documentation for the function:

/*
 * SYNOPSIS
 *   void ustr2str(char dst[restrict .n+1],
 *                 const u_char src[restrict .n],
 *                 size_t n);
 *
 * ARGUMENTS
 *	dst	Pointer to the first byte of the destination buffer.
 *	src	Pointer to the first byte of the source string.
 *	n	Size of 'src'.
 *
 * DESCRIPTION
 *	Copy a string from the fixed-width source string, which may be
 *	not-NUL-terminated, into a NUL-terminated string in the
 *	destination buffer.
 *
 * CAVEATS
 *	If the destination buffer is not wider than the source buffer
 *	at least by 1 byte, the behavior is undefined.
 *
 *	Use of this function normally indicates a problem in the design
 *	of the strings, since normally it's better to guarantee that all
 *	strings are properly terminated.  The main use for this function
 *	is to interface with some standard buffers, such as those
 *	defined in utmp(7), which for historical reasons are not
 *	guaranteed to be terminated.
 *
 * EXAMPLES
 *	u_char  src[10] = "0123456789";  // not NUL-terminated
 *	char    dst[sizeof(src) + 1];
 *
 *	static_assert(lengthof(src) &lt; lengthof(dst))
 *	ustr2str(dst, src, lengthof(src));
 *
 * SEE ALSO
 *	nxt_sts2str(3), strlcpy(3), strscpy(9)
 */

Cc: Andrew Clayton &lt;a.clayton@nginx.com&gt;
Signed-off-by: Alejandro Colomar &lt;alx@nginx.com&gt;
</pre>
</div>
</content>
</entry>
<entry>
<title>Workarounded Ruby bug.</title>
<updated>2022-11-12T19:39:48+00:00</updated>
<author>
<name>Alejandro Colomar</name>
<email>alx@nginx.com</email>
</author>
<published>2022-10-28T00:36:33+00:00</published>
<link rel='alternate' type='text/html' href='https://git.sigsegv.uk/unit.git/commit/?id=44c24fe163b580a985cb11486f54191c437d3356'/>
<id>44c24fe163b580a985cb11486f54191c437d3356</id>
<content type='text'>
Ruby redefines memcpy(3) in public headers.  Or at least they did until
they fixed it 4 months ago.  We need to undefine their broken definition.

Link: &lt;https://bugs.ruby-lang.org/issues/18893&gt;
Signed-off-by: Alejandro Colomar &lt;alx@nginx.com&gt;
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
Ruby redefines memcpy(3) in public headers.  Or at least they did until
they fixed it 4 months ago.  We need to undefine their broken definition.

Link: &lt;https://bugs.ruby-lang.org/issues/18893&gt;
Signed-off-by: Alejandro Colomar &lt;alx@nginx.com&gt;
</pre>
</div>
</content>
</entry>
<entry>
<title>Split nxt_str_t struct declaration and definition.</title>
<updated>2022-11-12T19:22:07+00:00</updated>
<author>
<name>Alejandro Colomar</name>
<email>alx@nginx.com</email>
</author>
<published>2022-10-30T12:13:09+00:00</published>
<link rel='alternate' type='text/html' href='https://git.sigsegv.uk/unit.git/commit/?id=04245f26f6f9dbca1bfb14ee084ba90ae91b5e07'/>
<id>04245f26f6f9dbca1bfb14ee084ba90ae91b5e07</id>
<content type='text'>
This allows using the type in declarations before it's actually
defined, and also to move the typedef to another file.

Signed-off-by: Alejandro Colomar &lt;alx@nginx.com&gt;
Reviewed-by: Andrew Clayton &lt;a.clayton@nginx.com&gt;
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
This allows using the type in declarations before it's actually
defined, and also to move the typedef to another file.

Signed-off-by: Alejandro Colomar &lt;alx@nginx.com&gt;
Reviewed-by: Andrew Clayton &lt;a.clayton@nginx.com&gt;
</pre>
</div>
</content>
</entry>
<entry>
<title>Added nxt_char_cast() macro for casting safely.</title>
<updated>2022-11-12T19:22:07+00:00</updated>
<author>
<name>Alejandro Colomar</name>
<email>alx@kernel.org</email>
</author>
<published>2022-11-11T23:48:10+00:00</published>
<link rel='alternate' type='text/html' href='https://git.sigsegv.uk/unit.git/commit/?id=b08dc96589cdbe65c206d36e2cd516b24967d394'/>
<id>b08dc96589cdbe65c206d36e2cd516b24967d394</id>
<content type='text'>
This macro is similar to C++'s static_cast().  It allows a very-limited
set of casts to be performed, but rejects most casts.  Basically, it
only allows converting from char to u_char and vice-versa, while
respecting the const qualifier.

See the _Generic(3) manual page for more details and examples.

Cc: Andrew Clayton &lt;a.clayton@nginx.com&gt;
Signed-off-by: Alejandro Colomar &lt;alx@kernel.org&gt;
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
This macro is similar to C++'s static_cast().  It allows a very-limited
set of casts to be performed, but rejects most casts.  Basically, it
only allows converting from char to u_char and vice-versa, while
respecting the const qualifier.

See the _Generic(3) manual page for more details and examples.

Cc: Andrew Clayton &lt;a.clayton@nginx.com&gt;
Signed-off-by: Alejandro Colomar &lt;alx@kernel.org&gt;
</pre>
</div>
</content>
</entry>
<entry>
<title>Using nxt_nitems() instead of sizeof() for strings (arrays).</title>
<updated>2022-11-12T19:22:07+00:00</updated>
<author>
<name>Alejandro Colomar</name>
<email>alx@nginx.com</email>
</author>
<published>2022-10-29T21:23:06+00:00</published>
<link rel='alternate' type='text/html' href='https://git.sigsegv.uk/unit.git/commit/?id=317a217bf8fa6c31c1b48193941a50ef64c155ab'/>
<id>317a217bf8fa6c31c1b48193941a50ef64c155ab</id>
<content type='text'>
sizeof() should never be used to get the size of an array.  It is
very unsafe, since arrays easily decay to pointers, and sizeof()
applied to a pointer gives false results that compile and produce
silent bugs.

It's better to use nxt_items(), which implements sizeof()
division, which recent compilers warn when used with pointers.

This change would have avoided a bug that we almost introduced
recently by using:

    nxt_str_set(&amp;port, (r-&gt;tls ? "https://" : "http://"));

which in the macro expansion runs:

    (&amp;port)-&gt;length = nxt_length((r-&gt;tls ? : "https://" : "http://"));

which evaluates to:

    port.length = sizeof(r-&gt;tls ? "https://" : "http://") - 1;

which evaluates to:

    port.length = 8 - 1;

Of course, we didn't want a compile-time-constant 8 there, but
rather the length of the string.

Link: &lt;https://stackoverflow.com/a/57537491&gt;
Cc: Andrew Clayton &lt;a.clayton@nginx.com&gt;
Signed-off-by: Alejandro Colomar &lt;alx@nginx.com&gt;
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
sizeof() should never be used to get the size of an array.  It is
very unsafe, since arrays easily decay to pointers, and sizeof()
applied to a pointer gives false results that compile and produce
silent bugs.

It's better to use nxt_items(), which implements sizeof()
division, which recent compilers warn when used with pointers.

This change would have avoided a bug that we almost introduced
recently by using:

    nxt_str_set(&amp;port, (r-&gt;tls ? "https://" : "http://"));

which in the macro expansion runs:

    (&amp;port)-&gt;length = nxt_length((r-&gt;tls ? : "https://" : "http://"));

which evaluates to:

    port.length = sizeof(r-&gt;tls ? "https://" : "http://") - 1;

which evaluates to:

    port.length = 8 - 1;

Of course, we didn't want a compile-time-constant 8 there, but
rather the length of the string.

Link: &lt;https://stackoverflow.com/a/57537491&gt;
Cc: Andrew Clayton &lt;a.clayton@nginx.com&gt;
Signed-off-by: Alejandro Colomar &lt;alx@nginx.com&gt;
</pre>
</div>
</content>
</entry>
<entry>
<title>Removed the unsafe nxt_memchr() wrapper for memchr(3).</title>
<updated>2022-11-03T23:30:50+00:00</updated>
<author>
<name>Alejandro Colomar</name>
<email>alx@nginx.com</email>
</author>
<published>2022-11-02T20:45:40+00:00</published>
<link rel='alternate' type='text/html' href='https://git.sigsegv.uk/unit.git/commit/?id=ebf02266a2cd663ad4744d3b8c07e211b8f38da1'/>
<id>ebf02266a2cd663ad4744d3b8c07e211b8f38da1</id>
<content type='text'>
The casts are unnecessary, since memchr(3)'s argument is 'const void *'.
It might have been necessary in the times of K&amp;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 &lt;a.clayton@nginx.com&gt;
Signed-off-by: Alejandro Colomar &lt;alx@nginx.com&gt;
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
The casts are unnecessary, since memchr(3)'s argument is 'const void *'.
It might have been necessary in the times of K&amp;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 &lt;a.clayton@nginx.com&gt;
Signed-off-by: Alejandro Colomar &lt;alx@nginx.com&gt;
</pre>
</div>
</content>
</entry>
<entry>
<title>Removed the unsafe nxt_memcmp() wrapper for memcmp(3).</title>
<updated>2022-11-03T23:30:27+00:00</updated>
<author>
<name>Alejandro Colomar</name>
<email>alx@nginx.com</email>
</author>
<published>2022-11-02T20:45:40+00:00</published>
<link rel='alternate' type='text/html' href='https://git.sigsegv.uk/unit.git/commit/?id=1b05161107112f09c15b128090284bb6de5b4f70'/>
<id>1b05161107112f09c15b128090284bb6de5b4f70</id>
<content type='text'>
The casts are unnecessary, since memcmp(3)'s arguments are 'void *'.
It might have been necessary in the times of K&amp;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 &lt;a.clayton@nginx.com&gt;
Signed-off-by: Alejandro Colomar &lt;alx@nginx.com&gt;
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
The casts are unnecessary, since memcmp(3)'s arguments are 'void *'.
It might have been necessary in the times of K&amp;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 &lt;a.clayton@nginx.com&gt;
Signed-off-by: Alejandro Colomar &lt;alx@nginx.com&gt;
</pre>
</div>
</content>
</entry>
<entry>
<title>PHP: allowed to specify URLs without a trailing '/'.</title>
<updated>2022-11-02T14:22:39+00:00</updated>
<author>
<name>Andrew Clayton</name>
<email>a.clayton@nginx.com</email>
</author>
<published>2022-09-16T13:38:53+00:00</published>
<link rel='alternate' type='text/html' href='https://git.sigsegv.uk/unit.git/commit/?id=a03274456b54cbc39e220b9dd73c3fc3fb935e46'/>
<id>a03274456b54cbc39e220b9dd73c3fc3fb935e46</id>
<content type='text'>
Both @lucatacconi &amp; @mwoodpatrick reported what appears to be the same
issue on GitHub. Namely that when using the PHP language module and
trying to access a URL that is a directory but without specifying the
trailing '/', they were getting a '503 Service Unavailable' error.

Note: This is when _not_ using the 'script' option.

E.g with the following config

  {
      "listeners": {
          "[::1]:8080": {
              "pass": "applications/php"
          }
      },

      "applications": {
          "php": {
              "type": "php",
              "root": "/var/tmp/unit-php"
          }
      }
  }

and with a directory path of /var/tmp/unit-php/foo containing an
index.php, you would see the following

  $ curl http://localhost/foo
  &lt;title&gt;Error 503&lt;/title&gt;
  Error 503

However

  $ curl http://localhost/foo/

would work and serve up the index.php

This commit fixes the above so you get the desired behaviour without
specifying the trailing '/' by doing the following

  1] If the URL doesn't end in .php and doesn't have a trailing '/'
     then check if the requested path is a directory.

  2) If it is a directory then create a 301 re-direct pointing to it.
     This matches the behaviour of the likes of nginx, Apache and
     lighttpd.

     This also matches the behaviour of the "share" action in Unit.

This doesn't effect the behaviour of the 'script' option which bypasses
the nxt_php_dynamic_request() function.

This also adds a couple of tests to test/test_php_application.py to
ensure this continues to work.

Closes: &lt;https://github.com/nginx/unit/issues/717&gt;
Closes: &lt;https://github.com/nginx/unit/issues/753&gt;
Signed-off-by: Andrew Clayton &lt;a.clayton@nginx.com&gt;
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
Both @lucatacconi &amp; @mwoodpatrick reported what appears to be the same
issue on GitHub. Namely that when using the PHP language module and
trying to access a URL that is a directory but without specifying the
trailing '/', they were getting a '503 Service Unavailable' error.

Note: This is when _not_ using the 'script' option.

E.g with the following config

  {
      "listeners": {
          "[::1]:8080": {
              "pass": "applications/php"
          }
      },

      "applications": {
          "php": {
              "type": "php",
              "root": "/var/tmp/unit-php"
          }
      }
  }

and with a directory path of /var/tmp/unit-php/foo containing an
index.php, you would see the following

  $ curl http://localhost/foo
  &lt;title&gt;Error 503&lt;/title&gt;
  Error 503

However

  $ curl http://localhost/foo/

would work and serve up the index.php

This commit fixes the above so you get the desired behaviour without
specifying the trailing '/' by doing the following

  1] If the URL doesn't end in .php and doesn't have a trailing '/'
     then check if the requested path is a directory.

  2) If it is a directory then create a 301 re-direct pointing to it.
     This matches the behaviour of the likes of nginx, Apache and
     lighttpd.

     This also matches the behaviour of the "share" action in Unit.

This doesn't effect the behaviour of the 'script' option which bypasses
the nxt_php_dynamic_request() function.

This also adds a couple of tests to test/test_php_application.py to
ensure this continues to work.

Closes: &lt;https://github.com/nginx/unit/issues/717&gt;
Closes: &lt;https://github.com/nginx/unit/issues/753&gt;
Signed-off-by: Andrew Clayton &lt;a.clayton@nginx.com&gt;
</pre>
</div>
</content>
</entry>
<entry>
<title>Fixed some function definitions.</title>
<updated>2022-10-28T02:18:33+00:00</updated>
<author>
<name>Andrew Clayton</name>
<email>a.clayton@nginx.com</email>
</author>
<published>2022-10-27T23:54:01+00:00</published>
<link rel='alternate' type='text/html' href='https://git.sigsegv.uk/unit.git/commit/?id=58248a6220540db89e69c928a5d8ad6be2a326fb'/>
<id>58248a6220540db89e69c928a5d8ad6be2a326fb</id>
<content type='text'>
Future releases of GCC will render function definitions like

  func()

invalid by default. See the previous commit 09f88c9 ("Fixed main()
prototypes in auto tests.") for details.

Such functions should be defined like

  func(void)

This is a good thing to do regardless of the upcoming GCC changes.

Reviewed-by: Alejandro Colomar &lt;alx@nginx.com&gt;
Signed-off-by: Andrew Clayton &lt;a.clayton@nginx.com&gt;
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
Future releases of GCC will render function definitions like

  func()

invalid by default. See the previous commit 09f88c9 ("Fixed main()
prototypes in auto tests.") for details.

Such functions should be defined like

  func(void)

This is a good thing to do regardless of the upcoming GCC changes.

Reviewed-by: Alejandro Colomar &lt;alx@nginx.com&gt;
Signed-off-by: Andrew Clayton &lt;a.clayton@nginx.com&gt;
</pre>
</div>
</content>
</entry>
</feed>
