A quote from the Python 3 documentation:
| When interactive, stdout and stderr streams are line-buffered.
| Otherwise, they are block-buffered like regular text files.
As a result, if an exception occurred and PyErr_Print() was called, its output
could be buffered but not printed to the log for a while (ultimately, until
the interpreter finalization). If the application process crashed shortly,
the backtrace was completely lost.
Buffering can be disabled by redefining the sys.stderr stream object.
However, interference with standard environment objects was deemed undesirable.
Instead, sys.stderr.flush() is called every time after printing exceptions.
A potential advantage here is that lines from backtraces won't be mixed
with other lines in the log.
PyObject_HasAttrString() is just a wrapper over PyObject_GetAttrString(),
while PyObject_CallMethod() calls it as the first step. As a result,
PyObject_GetAttrString() was called twice if close() was present.
To get rid of PyObject_HasAttrString() while keeping the same behaviour,
the PyObject_CallMethod() call has been decomposed into separate calls of
PyObject_GetAttrString() and PyObject_CallFunction().
On success, PyObject_CallMethod() returns a new reference to
the result of the call, which previously got lost.
Also, error logging on failure was added.
The issue was introduced by b0148ec28c4d.
According to the documentation, PyObject_GetIter():
| Raises TypeError and returns NULL if the object cannot be iterated.
Previously, this exception wasn't printed or cleared and remained unhandled.
According to the documentation, PyIter_Next():
| If there are no remaining values, returns NULL with no exception set.
| If an error occurs while retrieving the item, returns NULL and passes
| along the exception.
Previously, this exception wasn't properly handled and the response was
finalized as successful.
This issue was introduced in b0148ec28c4d.
A check for PyErr_Occurred() located in the code below might print this
traceback or occasionally catch an exception from one of the two response
close() calls.
Albeit that exceptions from the close() calls also need to be catched,
it's clear that this particular check wasn't supposed to do so. This is
another issue and it will be fixed later.
Python 3.8 has 'tp_print' field in PyTypeObject struct. This field is
attributed as deprecated. So, clang generates warning (which is turned to
error) as a result of initializing this field. From the other hand, it is
impossible to omit this field in positional initialization. The solution
is to use designated initializer.
Silencing usage message during configure python.
This is related to #331 issue on GitHub.
According to CGI/1.1 RFC 3875:
The server MUST set this variable; if the Script-URI does not include a
query component, the QUERY_STRING MUST be defined as an empty string ("").
Python's PEP 333(3) allows omitting it in WSGI interface; PHP docs force no
requirements; PSGI and Rack specifications require it even if empty.
When nginx proxies requests over FastCGI, it always provides QUERY_STRING.
and some PHP apps have been observed to fail if it is missing (see issue
#201 on GitHub).
A drawback of this change (besides a small overhead) is that there will be
no easy way to tell a missing query string from an empty one (i.e. requests
with or without the "?" character); yet, it's negligible compared to the
possible benefits of wider application compatibility.
This closes#226 issue on GitHub.
Previously, the nxt_router_prepare_msg() function expected server host among
other headers unmodified. It's not true anymore since normalization of the
Host header has been introduced in 77aad2c142a0.
The nxt_unit_split_host() function was removed. It didn't work correctly with
IPv6 literals. Anyway, after 77aad2c142a0 the port splitting is done in router
while Host header processing.
PyErr_Print() writes traceback to "sys.stderr", which is a file object that
can buffer the output. If the process exits immediately, the buffer can be
destroyed before flushing to the log. As a result, the user doesn't see
the traceback.
Now Py_Finalize() is also called in case of any errors during initialization.
It finalizes the interpreter and flushes all data.
Previously, passing 0 resulted in reading the whole body and all negative
values raised an exception.
Now the behaviour is in consistentance with io.RawIOBase.read() interface,
and passing 0 returns empty (byte) string, while -1 results in reading the
whole body.
An application can store request related functions and mistakenly call them
outside of request processing. Previously this resulted in segmentation
fault due to unset nxt_python_run_ctx. Now an exception will be raised.
Configuration and building example:
./configure
./configure python
./configure php
./configure go
make all
or
./configure
make nginext
./configure python
make python
./configure php
make php
./configure go
make go
Modules configuration options and building examples:
./configure python --module=python2 --config=python2.7-config
make python2
./configure php --module=php7 --config=php7.0-config
--lib-path=/usr/local/php7.0
make php7
./configure go --go=go1.6 --go-path=${HOME}/go1.6
make go1.6