Script 'mail_helper' called by obssrc
Hello community,

here is the log from the commit of package python-bjoern for openSUSE:Factory 
checked in at 2022-10-12 18:26:44
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/python-bjoern (Old)
 and      /work/SRC/openSUSE:Factory/.python-bjoern.new.2275 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "python-bjoern"

Wed Oct 12 18:26:44 2022 rev:10 rq:1010198 version:3.2.2

Changes:
--------
--- /work/SRC/openSUSE:Factory/python-bjoern/python-bjoern.changes      
2020-06-24 15:49:23.708533019 +0200
+++ /work/SRC/openSUSE:Factory/.python-bjoern.new.2275/python-bjoern.changes    
2022-10-12 18:28:25.826183715 +0200
@@ -1,0 +2,13 @@
+Wed Oct 12 02:47:21 UTC 2022 - Yogalakshmi Arunachalam <[email protected]>
+
+- Update to version 3.2.2:
+  * #228, 235 Fix libev paths (Ian Swanson, Nicolas Damgaard Larsen)
+  * #234 Set ``wsgi.input_terminated`` (Nathan Hoad)
+  * Update PyPI description
+  * #173 Fix segfault with old interpreters (Goldstein)
+  * #171 Implement FileWrapper.close()
+  * Fix FileWrapper/sendfile with offset
+  * #184 Fix compile flags
+  * #218 Fix SERVER_PORT (Souheil Chelfouh)
+
+-------------------------------------------------------------------

Old:
----
  bjoern-3.1.0.tar.gz

New:
----
  bjoern-3.2.2.tar.gz

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ python-bjoern.spec ++++++
--- /var/tmp/diff_new_pack.FJ0wZ8/_old  2022-10-12 18:28:26.190184516 +0200
+++ /var/tmp/diff_new_pack.FJ0wZ8/_new  2022-10-12 18:28:26.194184525 +0200
@@ -1,7 +1,7 @@
 #
 # spec file for package python-bjoern
 #
-# Copyright (c) 2020 SUSE LLC
+# Copyright (c) 2022 SUSE LLC
 #
 # All modifications and additions to the file contributed by third parties
 # remain the property of their copyright owners, unless otherwise agreed
@@ -18,7 +18,7 @@
 
 %{?!python_module:%define python_module() python-%{**} python3-%{**}}
 Name:           python-bjoern
-Version:        3.1.0
+Version:        3.2.2
 Release:        0
 Summary:        A screamingly fast Python 2 + 3 WSGI server written in C
 License:        BSD-2-Clause

++++++ bjoern-3.1.0.tar.gz -> bjoern-3.2.2.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/bjoern-3.1.0/.gitmodules new/bjoern-3.2.2/.gitmodules
--- old/bjoern-3.1.0/.gitmodules        2019-10-19 14:58:30.000000000 +0200
+++ new/bjoern-3.2.2/.gitmodules        2021-04-21 14:03:05.000000000 +0200
@@ -1,6 +1,6 @@
 [submodule "http-parser"]
   path = http-parser
-  url = git://github.com/joyent/http-parser
+  url = https://github.com/joyent/http-parser
 [submodule "statsd-c-client"]
   path = statsd-c-client
   url = https://github.com/romanbsd/statsd-c-client
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/bjoern-3.1.0/CHANGELOG new/bjoern-3.2.2/CHANGELOG
--- old/bjoern-3.1.0/CHANGELOG  2019-11-03 10:44:04.000000000 +0100
+++ new/bjoern-3.2.2/CHANGELOG  2022-09-11 20:40:07.000000000 +0200
@@ -1,3 +1,18 @@
+3.2.2 (Sep 11, 2022)
+    - #228, 235 Fix libev paths (Ian Swanson, Nicolas Damgaard Larsen)
+    - #234 Set ``wsgi.input_terminated`` (Nathan Hoad)
+    - Update PyPI description
+
+3.2.1 (Feb 14, 2022)
+    - Fix release
+
+3.2.0 (Feb 13, 2022)
+    - #173 Fix segfault with old interpreters (Goldstein)
+    - #171 Implement FileWrapper.close()
+    - Fix FileWrapper/sendfile with offset
+    - #184 Fix compile flags
+    - #218 Fix SERVER_PORT (Souheil Chelfouh)
+
 3.1.0 (Nov 3, 2019)
     - #169 Fix blocking accept() (Ionut Negru)
     - #164 Add support for statsd metrics/events (Mohammad Gufran)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/bjoern-3.1.0/Makefile new/bjoern-3.2.2/Makefile
--- old/bjoern-3.1.0/Makefile   2019-11-03 10:43:15.000000000 +0100
+++ new/bjoern-3.2.2/Makefile   2022-09-11 20:37:14.000000000 +0200
@@ -59,8 +59,8 @@
        CFLAGS='-Os' make
 
 _bjoernmodule:
-       @echo ' -> ' $(CC) $(CPPFLAGS) $(CFLAGS) $(LDFLAGS) $(objects) -o 
$(BUILD_DIR)/_bjoern.so
-       @$(CC) $(CPPFLAGS) $(CFLAGS) $(LDFLAGS) $(objects) -o 
$(BUILD_DIR)/_bjoern.so
+       @echo ' -> ' $(CC) $(CPPFLAGS) $(CFLAGS) $(objects) $(LDFLAGS) -o 
$(BUILD_DIR)/_bjoern.so
+       @$(CC) $(CPPFLAGS) $(CFLAGS) $(objects) $(LDFLAGS) -o 
$(BUILD_DIR)/_bjoern.so
        @PYTHONPATH=$$PYTHONPATH:$(BUILD_DIR) ${PYTHON} -c "import bjoern"
 
 again: clean all
@@ -82,6 +82,9 @@
 clean:
        @rm -rf $(BUILD_DIR)/*
 
+distclean:
+       @rm -rf dist/
+
 AB             = ab -c 100 -n 10000
 TEST_URL       = "http://127.0.0.1:8080/a/b/c?k=v&k2=v2";
 
@@ -113,11 +116,15 @@
           echo; echo; \
           tail -n +25 /proc/$$(pgrep -n ${PYTHON})/smaps'
 
-upload:
-       ${PYTHON} setup.py sdist upload
+packages:
+       ${PYTHON} setup.py sdist
+       $(MAKE) -C packaging all
+
+upload: packages
+       twine upload dist/*.tar.gz dist/*.whl
 
 $(HTTP_PARSER_OBJ):
        $(MAKE) -C $(HTTP_PARSER_DIR) http_parser.o CFLAGS_DEBUG_EXTRA=-fPIC 
CFLAGS_FAST_EXTRA=-fPIC
 
 $(STATSD_CLIENT_OBJ):
-       $(MAKE) -C $(STATSD_CLIENT_DIR) statsd-client.o 
CFLAGS_DEBUG_EXTRA=-fPIC CFLAGS_FAST_EXTRA=-fPIC
+       $(MAKE) -C $(STATSD_CLIENT_DIR) statsd-client.o CFLAGS=-fPIC
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/bjoern-3.1.0/PKG-INFO new/bjoern-3.2.2/PKG-INFO
--- old/bjoern-3.1.0/PKG-INFO   2019-11-03 10:45:13.000000000 +0100
+++ new/bjoern-3.2.2/PKG-INFO   2022-09-11 20:48:02.896385400 +0200
@@ -1,16 +1,111 @@
-Metadata-Version: 1.1
+Metadata-Version: 2.1
 Name: bjoern
-Version: 3.1.0
+Version: 3.2.2
 Summary: A screamingly fast Python 2 + 3 WSGI server written in C.
 Home-page: https://github.com/jonashaag/bjoern
 Author: Jonas Haag
 Author-email: [email protected]
 License: 2-clause BSD
-Description: UNKNOWN
-Platform: UNKNOWN
 Classifier: Development Status :: 4 - Beta
 Classifier: License :: OSI Approved :: BSD License
 Classifier: Programming Language :: C
 Classifier: Programming Language :: Python :: 2
 Classifier: Programming Language :: Python :: 3
 Classifier: Topic :: Internet :: WWW/HTTP :: WSGI :: Server
+License-File: LICENSE
+
+bjoern: Fast And Ultra-Lightweight HTTP/1.1 WSGI Server
+=======================================================
+
+.. image:: https://badges.gitter.im/Join%20Chat.svg
+   :alt: Join the chat at https://gitter.im/jonashaag/bjoern
+   :target: 
https://gitter.im/jonashaag/bjoern?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge
+
+A screamingly fast, ultra-lightweight WSGI_ server for CPython 2 and CPython 3,
+written in C using Marc Lehmann's high performance libev_ event loop and
+Ryan Dahl's http-parser_.
+
+Why It's Cool
+~~~~~~~~~~~~~
+bjoern is the *fastest*, *smallest* and *most lightweight* WSGI server out 
there,
+featuring
+
+* ~ 1000 lines of C code
+* Memory footprint ~ 600KB
+* Python 2 and Python 3 support (thanks @yanghao!)
+* Single-threaded and without coroutines or other crap
+* Can bind to TCP `host:port` addresses and Unix sockets (thanks @k3d3!)
+* Full persistent connection ("*keep-alive*") support in both HTTP/1.0 and 1.1,
+  including support for HTTP/1.1 chunked responses
+
+Installation
+~~~~~~~~~~~~
+``pip install bjoern``. See `wiki 
<https://github.com/jonashaag/bjoern/wiki/Installation>`_ for details.
+
+Usage
+~~~~~
+
+Flask example
+-------------
+
+.. code-block:: python
+
+   from flask import Flask
+
+   app = Flask(__name__)
+
+   @app.route("/")
+   def hello_world():
+       return "Hello, World!"
+
+   if __name__ == "__main__":
+       import bjoern
+
+       bjoern.run(app, "127.0.0.1", 8000)
+
+
+Advanced usage
+--------------
+
+.. code-block:: python
+
+   # Bind to TCP host/port pair:
+   bjoern.run(wsgi_application, host, port)
+
+   # TCP host/port pair, enabling SO_REUSEPORT if available.
+   bjoern.run(wsgi_application, host, port, reuse_port=True)
+
+   # Bind to Unix socket:
+   bjoern.run(wsgi_application, 'unix:/path/to/socket')
+
+   # Bind to abstract Unix socket: (Linux only)
+   bjoern.run(wsgi_application, 'unix:@socket_name')
+
+   # Enable statsd metrics. See instrumentation.md for details.
+   bjoern.run(wsgi_application, host, port, statsd=...)
+
+Alternatively, the mainloop can be run separately:
+
+.. code-block:: python
+
+   bjoern.listen(wsgi_application, host, port)
+   bjoern.run()
+
+   # With metrics. See instrumentation.md for details.
+   bjoern.listen(wsgi_application, host, port)
+   bjoern.run(statsd=...)
+
+You can also simply pass a Python socket(-like) object. Note that you are 
responsible
+for initializing and cleaning up the socket in that case.
+
+.. code-block:: python
+
+   bjoern.server_run(socket_object, wsgi_application)
+   bjoern.server_run(filedescriptor_as_integer, wsgi_application)
+
+   # This needs manual compilation with `WANT_STATSD=yes`
+   bjoern.server_run(socket_object, wsgi_application, enable_statsd=True)
+
+.. _WSGI:         http://www.python.org/dev/peps/pep-0333/
+.. _libev:        http://software.schmorp.de/pkg/libev.html
+.. _http-parser:  https://github.com/joyent/http-parser
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/bjoern-3.1.0/README.rst new/bjoern-3.2.2/README.rst
--- old/bjoern-3.1.0/README.rst 2019-10-19 14:58:30.000000000 +0200
+++ new/bjoern-3.2.2/README.rst 2021-04-21 14:03:05.000000000 +0200
@@ -28,7 +28,30 @@
 
 Usage
 ~~~~~
-::
+
+Flask example
+-------------
+
+.. code-block:: python
+
+   from flask import Flask
+
+   app = Flask(__name__)
+
+   @app.route("/")
+   def hello_world():
+       return "Hello, World!"
+
+   if __name__ == "__main__":
+       import bjoern
+
+       bjoern.run(app, "127.0.0.1", 8000)
+
+
+Advanced usage
+--------------
+
+.. code-block:: python
 
    # Bind to TCP host/port pair:
    bjoern.run(wsgi_application, host, port)
@@ -45,7 +68,9 @@
    # Enable statsd metrics. See instrumentation.md for details.
    bjoern.run(wsgi_application, host, port, statsd=...)
 
-Alternatively, the mainloop can be run separately::
+Alternatively, the mainloop can be run separately:
+
+.. code-block:: python
 
    bjoern.listen(wsgi_application, host, port)
    bjoern.run()
@@ -55,7 +80,9 @@
    bjoern.run(statsd=...)
 
 You can also simply pass a Python socket(-like) object. Note that you are 
responsible
-for initializing and cleaning up the socket in that case. ::
+for initializing and cleaning up the socket in that case.
+
+.. code-block:: python
 
    bjoern.server_run(socket_object, wsgi_application)
    bjoern.server_run(filedescriptor_as_integer, wsgi_application)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/bjoern-3.1.0/bjoern/_bjoernmodule.c 
new/bjoern-3.2.2/bjoern/_bjoernmodule.c
--- old/bjoern-3.1.0/bjoern/_bjoernmodule.c     2019-11-03 10:44:28.000000000 
+0100
+++ new/bjoern-3.2.2/bjoern/_bjoernmodule.c     2022-09-11 20:38:11.000000000 
+0200
@@ -164,7 +164,7 @@
 #endif
 
   PyModule_AddObject(bjoern_module, "features", features);
-  PyModule_AddObject(bjoern_module, "version", Py_BuildValue("(iii)", 3, 1, 
0));
+  PyModule_AddObject(bjoern_module, "version", Py_BuildValue("(iii)", 3, 2, 
2));
 
 #if PY_MAJOR_VERSION >= 3
   return bjoern_module;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/bjoern-3.1.0/bjoern/filewrapper.c 
new/bjoern-3.2.2/bjoern/filewrapper.c
--- old/bjoern-3.1.0/bjoern/filewrapper.c       2019-07-15 11:19:46.000000000 
+0200
+++ new/bjoern-3.2.2/bjoern/filewrapper.c       2019-12-14 17:37:17.000000000 
+0100
@@ -8,13 +8,6 @@
   return FW_self->fd;
 }
 
-void FileWrapper_Done(PyObject *self)
-{
-  if (FW_self->fd != -1) {
-    PyFile_DecUseCount((PyFileObject*)FW_self->file);
-  }
-}
-
 static PyObject*
 FileWrapper_New(PyTypeObject* cls, PyObject* args, PyObject* kwargs)
 {
@@ -67,6 +60,23 @@
   PyObject_FREE(self);
 }
 
+PyObject* FileWrapper_close(PyObject* self)
+{
+  if (PyObject_HasAttr(FW_self->file, _close)) {
+    return PyObject_CallMethodObjArgs(FW_self->file, _close, NULL);
+  } else {
+    Py_RETURN_NONE;
+  }
+  if (FW_self->fd != -1) {
+    PyFile_DecUseCount((PyFileObject*)FW_self->file);
+  }
+}
+
+static PyMethodDef FileWrapper_methods[] = {
+    {"close", (PyCFunction) FileWrapper_close, METH_NOARGS, NULL},
+    {NULL}  /* Sentinel */
+};
+
 PyTypeObject FileWrapper_Type = {
   PyVarObject_HEAD_INIT(NULL, 0)
   "FileWrapper",                    /* tp_name (__name__)                     
*/
@@ -81,4 +91,5 @@
   FileWrapper_Type.tp_iter = FileWrapper_Iter;
   FileWrapper_Type.tp_iternext = FileWrapper_IterNext;
   FileWrapper_Type.tp_flags |= Py_TPFLAGS_DEFAULT;
+  FileWrapper_Type.tp_methods = FileWrapper_methods;
 }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/bjoern-3.1.0/bjoern/filewrapper.h 
new/bjoern-3.2.2/bjoern/filewrapper.h
--- old/bjoern-3.1.0/bjoern/filewrapper.h       2019-07-15 11:19:46.000000000 
+0200
+++ new/bjoern-3.2.2/bjoern/filewrapper.h       2019-12-14 17:37:17.000000000 
+0100
@@ -13,4 +13,3 @@
 
 void _init_filewrapper(void);
 int FileWrapper_GetFd(PyObject *self);
-void FileWrapper_Done(PyObject *self);
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/bjoern-3.1.0/bjoern/py2py3.h 
new/bjoern-3.2.2/bjoern/py2py3.h
--- old/bjoern-3.1.0/bjoern/py2py3.h    2019-09-12 09:31:24.000000000 +0200
+++ new/bjoern-3.2.2/bjoern/py2py3.h    2019-12-14 17:37:17.000000000 +0100
@@ -15,6 +15,11 @@
 #define _PEP3333_BytesLatin1_FromUnicode(u) PyUnicode_AsLatin1String(u)
 #define _PEP3333_String_FromUTF8String(data) PyUnicode_FromString(data)
 #define _PEP3333_String_FromLatin1StringAndSize(data, len) 
PyUnicode_DecodeLatin1(data, len, "replace")
+// Shouldn't use FromFormat here because of Python bug:
+// https://bugs.python.org/issue33817
+// While problem with PyUnicode_FromString("") was not reported, it's still 
better
+// to create empty string without formatting
+#define _PEP3333_String_Empty() PyUnicode_FromString("")
 #define _PEP3333_String_FromFormat(...) PyUnicode_FromFormat(__VA_ARGS__)
 #define _PEP3333_String_GET_SIZE(u) PyUnicode_GET_LENGTH(u)
 #define _PEP3333_String_Concat(u1, u2) PyUnicode_Concat(u1, u2)
@@ -31,6 +36,10 @@
 #define _PEP3333_Bytes_Resize(bytes, len) _PyString_Resize(bytes, len)
 #define _PEP3333_BytesLatin1_FromUnicode(u) (Py_INCREF(u),u)
 #define _PEP3333_String_FromUTF8String(data) PyString_FromString(data) // 
Assume UTF8
+// Can't use FromFormat here because of Python bug:
+// https://bugs.python.org/issue33817
+// Arguments (NULL, 0) will create empty string, it's explicitly allowed
+#define _PEP3333_String_Empty() PyString_FromStringAndSize(NULL, 0)
 #define _PEP3333_String_FromFormat(...) PyString_FromFormat(__VA_ARGS__)
 #define _PEP3333_String_GET_SIZE(u) PyString_GET_SIZE(u)
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/bjoern-3.1.0/bjoern/request.c 
new/bjoern-3.2.2/bjoern/request.c
--- old/bjoern-3.1.0/bjoern/request.c   2019-09-12 09:31:24.000000000 +0200
+++ new/bjoern-3.2.2/bjoern/request.c   2022-09-11 20:37:14.000000000 +0200
@@ -50,7 +50,8 @@
 void Request_clean(Request* request)
 {
   if(request->iterable) {
-    /* Call 'iterable.close()' if available */
+    /* Call 'iterable.close()' if available. This will also call into 
FileWrapper_close()
+     * if 'iterable' is a FileWrapper object. */
     PyObject* close_method = PyObject_GetAttr(request->iterable, _close);
     if(close_method == NULL) {
       if(PyErr_ExceptionMatches(PyExc_AttributeError))
@@ -349,6 +350,16 @@
       PyTuple_Pack(2, _FromLong(1), _FromLong(0))
     );
 
+    /* dct['wsgi.input_terminated'] = True
+     * (Tell Flask/other WSGI apps that the input has been terminated, so that 
chunked
+     * transfer-encoding can be used in requests. This can be hard coded as 
bjoern
+     * provides the body as a BytesIO object.) */
+    PyDict_SetItemString(
+      wsgi_base_dict,
+      "wsgi.input_terminated",
+      Py_True
+    );
+
     /* dct['wsgi.url_scheme'] = 'http'
      * (This can be hard-coded as there is no TLS support in bjoern.) */
     Py_INCREF(_http);
@@ -398,14 +409,14 @@
       PyDict_SetItemString(wsgi_base_dict, "SERVER_NAME", server_info->host);
 
       if (server_info->port == Py_None) {
-      PyDict_SetItemString(wsgi_base_dict, "SERVER_PORT", 
_PEP3333_String_FromFormat(""));
+      PyDict_SetItemString(wsgi_base_dict, "SERVER_PORT", 
_PEP3333_String_Empty());
       } else {
-        PyDict_SetItemString(wsgi_base_dict, "SERVER_PORT", 
_PEP3333_String_FromFormat("%i", server_info->port));
+        PyDict_SetItemString(wsgi_base_dict, "SERVER_PORT", 
_PEP3333_String_FromFormat("%S", server_info->port));
       }
      } else {
       /* SERVER_NAME is required, but not usefull with UNIX type sockets */
-      PyDict_SetItemString(wsgi_base_dict, "SERVER_NAME", 
_PEP3333_String_FromFormat(""));
-      PyDict_SetItemString(wsgi_base_dict, "SERVER_PORT", 
_PEP3333_String_FromFormat(""));
+      PyDict_SetItemString(wsgi_base_dict, "SERVER_NAME", 
_PEP3333_String_Empty());
+      PyDict_SetItemString(wsgi_base_dict, "SERVER_PORT", 
_PEP3333_String_Empty());
     }
   }
 }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/bjoern-3.1.0/bjoern/server.c 
new/bjoern-3.2.2/bjoern/server.c
--- old/bjoern-3.1.0/bjoern/server.c    2019-11-03 10:42:57.000000000 +0100
+++ new/bjoern-3.2.2/bjoern/server.c    2022-09-11 20:37:14.000000000 +0200
@@ -24,7 +24,6 @@
 #endif
 
 #define READ_BUFFER_SIZE 64*1024
-#define Py_XCLEAR(obj) do { if(obj) { Py_DECREF(obj); obj = NULL; } } while(0)
 #define GIL_LOCK(n) PyGILState_STATE _gilstate_##n = PyGILState_Ensure()
 #define GIL_UNLOCK(n) PyGILState_Release(_gilstate_##n)
 
@@ -255,7 +254,7 @@
         assert(PyErr_Occurred());
         PyErr_Print();
         assert(!request->state.chunked_response);
-        Py_XCLEAR(request->iterator);
+        Py_CLEAR(request->iterator);
         request->current_chunk = _PEP3333_Bytes_FromString(
           http_error_messages[HTTP_SERVER_ERROR]);
         STATSD_INCREMENT("req.error.internal");
@@ -380,9 +379,16 @@
    */
   if(request->current_chunk) {
     /* Phase A) -- current_chunk contains the HTTP headers */
-    do_send_chunk(request);
-    // Either we have headers left to send, or current_chunk has been set to
-    // NULL and we'll fall into Phase B) on the next invocation.
+    if (do_send_chunk(request)) {
+      /* Headers left to send */
+    } else {
+      /* Done with headers, current_chunk has been set to NULL
+       * and we'll fall into Phase B) on the next invocation. */
+      request->current_chunk_p = lseek(FileWrapper_GetFd(request->iterable), 
0, SEEK_CUR);
+      if (request->current_chunk_p == -1) {
+        return aborted;
+      }
+    }
     return not_yet_done;
   } else {
     /* Phase B) */
@@ -500,11 +506,9 @@
     if (handle_nonzero_errno(request)) {
       return true;
     } else {
-      FileWrapper_Done(request->iterable);
       return false;
     }
   case 0:
-    FileWrapper_Done(request->iterable);
     return false;
   default:
     request->current_chunk_p += bytes_sent;
@@ -522,7 +526,7 @@
     /* Serious transmission failure. Hang up. */
     fprintf(stderr, "Client %d hit errno %d\n", request->client_fd, errno);
     Py_XDECREF(request->current_chunk);
-    Py_XCLEAR(request->iterator);
+    Py_CLEAR(request->iterator);
     request->state.keep_alive = false;
     return false;
   }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/bjoern-3.1.0/bjoern/wsgi.c 
new/bjoern-3.2.2/bjoern/wsgi.c
--- old/bjoern-3.1.0/bjoern/wsgi.c      2019-09-12 10:14:48.000000000 +0200
+++ new/bjoern-3.2.2/bjoern/wsgi.c      2022-09-11 20:37:14.000000000 +0200
@@ -182,22 +182,32 @@
   return true;
 }
 
-static inline bool
-inspect_headers(Request* request)
+static inline PyObject*
+clean_headers(PyObject* headers, bool* found_content_length)
 {
-  Py_ssize_t i;
-  PyObject* tuple;
 
-  if(!PyList_Check(request->headers)) {
-    TYPE_ERROR("start response argument 2", "a list of 2-tuples", 
request->headers);
+  if(!PyList_Check(headers)) {
+    TYPE_ERROR("start response argument 2", "a list of 2-tuples", headers);
     return NULL;
   }
 
-  for(i=0; i<PyList_GET_SIZE(request->headers); ++i) {
-    tuple = PyList_GET_ITEM(request->headers, i);
+  for(Py_ssize_t i=0; i<PyList_GET_SIZE(headers); ++i) {
+    PyObject* tuple = PyList_GET_ITEM(headers, i);
+    if(!PyTuple_Check(tuple) || PyTuple_GET_SIZE(tuple) != 2) {
+      TYPE_ERROR_INNER("start_response argument 2", "a list of 2-tuples 
(field: str, value: str)",
+        "(found invalid '%.200s' object at position %zd)", 
Py_TYPE(tuple)->tp_name, i);
+      return NULL;
+    }
+  }
+
+  /* Create copy of headers list that we may modify */
+  PyObject* new_headers = PyList_New(PyList_GET_SIZE(headers));
+  if (new_headers == NULL) {
+    return NULL;
+  }
 
-    if(!PyTuple_Check(tuple) || PyTuple_GET_SIZE(tuple) != 2)
-      goto err;
+  for(Py_ssize_t i=0; i<PyList_GET_SIZE(headers); ++i) {
+    PyObject* tuple = PyList_GET_ITEM(headers, i);
 
     PyObject* unicode_field = PyTuple_GET_ITEM(tuple, 0);
     PyObject* unicode_value = PyTuple_GET_ITEM(tuple, 1);
@@ -206,26 +216,23 @@
     PyObject* bytes_value = _PEP3333_BytesLatin1_FromUnicode(unicode_value);
 
     if (bytes_field == NULL || bytes_value == NULL) {
+      TYPE_ERROR_INNER("start_response argument 2", "a list of 2-tuples 
(field: str, value: str)",
+        "(found invalid ('%.200s', '%.200s') tuple at position %zd)", 
Py_TYPE(unicode_field)->tp_name, Py_TYPE(unicode_value)->tp_name, i);
+      Py_DECREF(new_headers);
       Py_XDECREF(bytes_field);
       Py_XDECREF(bytes_value);
-      goto err;
+      return NULL;
     }
 
-    PyList_SET_ITEM(request->headers, i, PyTuple_Pack(2, bytes_field, 
bytes_value));
-    Py_DECREF(tuple);
+    PyList_SET_ITEM(new_headers, i, PyTuple_Pack(2, bytes_field, bytes_value));
 
     if(!strncasecmp(_PEP3333_Bytes_AS_DATA(bytes_field), "Content-Length", 
_PEP3333_Bytes_GET_SIZE(bytes_field)))
-      request->state.response_length_unknown = false;
+      *found_content_length = true;
 
     Py_DECREF(bytes_field);
     Py_DECREF(bytes_value);
   }
-  return true;
-
-err:
-  TYPE_ERROR_INNER("start_response argument 2", "a list of 2-tuples (field: 
str, value: str)",
-    "(found invalid '%.200s' object at position %zd)", 
Py_TYPE(tuple)->tp_name, i);
-  return false;
+  return new_headers;
 }
 
 
@@ -336,7 +343,8 @@
 
   PyObject* exc_info = NULL;
   PyObject* status_unicode = NULL;
-  if(!PyArg_UnpackTuple(args, "start_response", 2, 3, &status_unicode, 
&request->headers, &exc_info))
+  PyObject* headers = NULL;
+  if(!PyArg_UnpackTuple(args, "start_response", 2, 3, &status_unicode, 
&headers, &exc_info))
     return NULL;
 
   if(exc_info && exc_info != Py_None) {
@@ -372,13 +380,14 @@
     return NULL;
   }
 
-  if(!inspect_headers(request)) {
-    request->headers = NULL;
+
+  bool found_content_length = false;
+  request->headers = clean_headers(headers, &found_content_length);
+  if (request->headers == NULL) {
     return NULL;
   }
 
-  Py_INCREF(request->headers);
-
+  request->state.response_length_unknown = !found_content_length;
   request->state.start_response_called = true;
 
   Py_RETURN_NONE;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/bjoern-3.1.0/bjoern.egg-info/PKG-INFO 
new/bjoern-3.2.2/bjoern.egg-info/PKG-INFO
--- old/bjoern-3.1.0/bjoern.egg-info/PKG-INFO   2019-11-03 10:45:13.000000000 
+0100
+++ new/bjoern-3.2.2/bjoern.egg-info/PKG-INFO   2022-09-11 20:48:02.000000000 
+0200
@@ -1,16 +1,111 @@
-Metadata-Version: 1.1
+Metadata-Version: 2.1
 Name: bjoern
-Version: 3.1.0
+Version: 3.2.2
 Summary: A screamingly fast Python 2 + 3 WSGI server written in C.
 Home-page: https://github.com/jonashaag/bjoern
 Author: Jonas Haag
 Author-email: [email protected]
 License: 2-clause BSD
-Description: UNKNOWN
-Platform: UNKNOWN
 Classifier: Development Status :: 4 - Beta
 Classifier: License :: OSI Approved :: BSD License
 Classifier: Programming Language :: C
 Classifier: Programming Language :: Python :: 2
 Classifier: Programming Language :: Python :: 3
 Classifier: Topic :: Internet :: WWW/HTTP :: WSGI :: Server
+License-File: LICENSE
+
+bjoern: Fast And Ultra-Lightweight HTTP/1.1 WSGI Server
+=======================================================
+
+.. image:: https://badges.gitter.im/Join%20Chat.svg
+   :alt: Join the chat at https://gitter.im/jonashaag/bjoern
+   :target: 
https://gitter.im/jonashaag/bjoern?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge
+
+A screamingly fast, ultra-lightweight WSGI_ server for CPython 2 and CPython 3,
+written in C using Marc Lehmann's high performance libev_ event loop and
+Ryan Dahl's http-parser_.
+
+Why It's Cool
+~~~~~~~~~~~~~
+bjoern is the *fastest*, *smallest* and *most lightweight* WSGI server out 
there,
+featuring
+
+* ~ 1000 lines of C code
+* Memory footprint ~ 600KB
+* Python 2 and Python 3 support (thanks @yanghao!)
+* Single-threaded and without coroutines or other crap
+* Can bind to TCP `host:port` addresses and Unix sockets (thanks @k3d3!)
+* Full persistent connection ("*keep-alive*") support in both HTTP/1.0 and 1.1,
+  including support for HTTP/1.1 chunked responses
+
+Installation
+~~~~~~~~~~~~
+``pip install bjoern``. See `wiki 
<https://github.com/jonashaag/bjoern/wiki/Installation>`_ for details.
+
+Usage
+~~~~~
+
+Flask example
+-------------
+
+.. code-block:: python
+
+   from flask import Flask
+
+   app = Flask(__name__)
+
+   @app.route("/")
+   def hello_world():
+       return "Hello, World!"
+
+   if __name__ == "__main__":
+       import bjoern
+
+       bjoern.run(app, "127.0.0.1", 8000)
+
+
+Advanced usage
+--------------
+
+.. code-block:: python
+
+   # Bind to TCP host/port pair:
+   bjoern.run(wsgi_application, host, port)
+
+   # TCP host/port pair, enabling SO_REUSEPORT if available.
+   bjoern.run(wsgi_application, host, port, reuse_port=True)
+
+   # Bind to Unix socket:
+   bjoern.run(wsgi_application, 'unix:/path/to/socket')
+
+   # Bind to abstract Unix socket: (Linux only)
+   bjoern.run(wsgi_application, 'unix:@socket_name')
+
+   # Enable statsd metrics. See instrumentation.md for details.
+   bjoern.run(wsgi_application, host, port, statsd=...)
+
+Alternatively, the mainloop can be run separately:
+
+.. code-block:: python
+
+   bjoern.listen(wsgi_application, host, port)
+   bjoern.run()
+
+   # With metrics. See instrumentation.md for details.
+   bjoern.listen(wsgi_application, host, port)
+   bjoern.run(statsd=...)
+
+You can also simply pass a Python socket(-like) object. Note that you are 
responsible
+for initializing and cleaning up the socket in that case.
+
+.. code-block:: python
+
+   bjoern.server_run(socket_object, wsgi_application)
+   bjoern.server_run(filedescriptor_as_integer, wsgi_application)
+
+   # This needs manual compilation with `WANT_STATSD=yes`
+   bjoern.server_run(socket_object, wsgi_application, enable_statsd=True)
+
+.. _WSGI:         http://www.python.org/dev/peps/pep-0333/
+.. _libev:        http://software.schmorp.de/pkg/libev.html
+.. _http-parser:  https://github.com/joyent/http-parser
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/bjoern-3.1.0/setup.py new/bjoern-3.2.2/setup.py
--- old/bjoern-3.1.0/setup.py   2019-11-03 10:44:14.000000000 +0100
+++ new/bjoern-3.2.2/setup.py   2022-09-11 20:38:01.000000000 +0200
@@ -2,6 +2,8 @@
 import glob
 from setuptools import setup, Extension
 
+long_description = open(os.path.join(os.path.dirname(__file__), 
"README.rst")).read()
+
 WANT_SIGINT_HANDLING = os.environ.get('BJOERN_WANT_SIGINT_HANDLING', True)
 WANT_SIGNAL_HANDLING = os.environ.get('BJOERN_WANT_SIGNAL_HANDLING', True)
 SIGNAL_CHECK_INTERVAL = os.environ.get('BJOERN_SIGNAL_CHECK_INTERVAL', '0.1')
@@ -30,11 +32,13 @@
     '_bjoern',
     sources       = SOURCE_FILES,
     libraries     = ['ev'],
-    include_dirs  = ['http-parser', 'statsd-c-client', '/usr/include/libev', 
'/opt/local/include'],
+    include_dirs  = ['http-parser', 'statsd-c-client', '/usr/include/libev',
+                     '/opt/local/include', '/opt/homebrew/include', 
'/usr/local/include'],
+    library_dirs  = ['/opt/homebrew/lib/', '/usr/local/lib'],
     define_macros = compile_flags,
     extra_compile_args = ['-std=c99', '-fno-strict-aliasing', '-fcommon',
                           '-fPIC', '-Wall', '-Wextra', '-Wno-unused-parameter',
-                          '-Wno-missing-field-initializers', '-g']
+                          '-Wno-missing-field-initializers', '-g'],
 )
 
 setup(
@@ -44,7 +48,8 @@
     license      = '2-clause BSD',
     url          = 'https://github.com/jonashaag/bjoern',
     description  = 'A screamingly fast Python 2 + 3 WSGI server written in C.',
-    version      = '3.1.0',
+    version      = '3.2.2',
+    long_description = long_description,
     classifiers  = ['Development Status :: 4 - Beta',
                     'License :: OSI Approved :: BSD License',
                     'Programming Language :: C',
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/bjoern-3.1.0/tests/interrupt-during-request.py 
new/bjoern-3.2.2/tests/interrupt-during-request.py
--- old/bjoern-3.1.0/tests/interrupt-during-request.py  2019-07-15 
11:19:46.000000000 +0200
+++ new/bjoern-3.2.2/tests/interrupt-during-request.py  2022-09-11 
20:37:14.000000000 +0200
@@ -3,7 +3,11 @@
 import bjoern
 import os
 import signal
-import httplib
+
+try:
+    from http import client as httplib
+except ImportError:  # Py 2
+    import httplib
 
 HOST = ('127.0.0.1', 9000)
 
@@ -22,7 +26,7 @@
 def requester():
     conn = httplib.HTTPConnection(*HOST)
     conn.request("GET", "/")
-    conn.getresponse()
+    print(conn.getresponse().read())
 
 
 threading.Thread(target=requester).start()
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/bjoern-3.1.0/tests/keep-alive-behaviour.py 
new/bjoern-3.2.2/tests/keep-alive-behaviour.py
--- old/bjoern-3.1.0/tests/keep-alive-behaviour.py      2019-07-15 
11:19:46.000000000 +0200
+++ new/bjoern-3.2.2/tests/keep-alive-behaviour.py      2021-04-21 
14:03:05.000000000 +0200
@@ -1,10 +1,11 @@
 import os
 import random
+import socket
+
 try:
+    from http import client as httplib
+except ImportError:  # Py 2
     import httplib
-except ImportError:
-    import http.client as httplib
-import socket
 
 HOST = ('127.0.0.1', 9000)
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/bjoern-3.1.0/tests/reuse_port.py 
new/bjoern-3.2.2/tests/reuse_port.py
--- old/bjoern-3.1.0/tests/reuse_port.py        2019-07-15 11:19:46.000000000 
+0200
+++ new/bjoern-3.2.2/tests/reuse_port.py        2021-04-21 14:03:05.000000000 
+0200
@@ -1,10 +1,14 @@
 import os
 import time
 import sys
-import httplib
 import subprocess
 from collections import defaultdict
 
+try:
+    from http import client as httplib
+except ImportError:  # Py 2
+    import httplib
+
 
 N_PROCESSES = 3
 N_REQUESTS_PER_PROCESS = 100

Reply via email to