On 6/16/21 8:04 PM, Jonas Smedegaard wrote:
> [ replying via bugreport ]
> 
> Quoting Thomas Goirand (2021-06-16 19:20:44)
>> Can I NMU uwsgi as per the discussion with the release team? Should it 
>> be 2.0.19.1-7.1 or 2.0.19.1-8? Should I also open a merge request on 
>> Salsa?
> 
> Yes, please use standard procedure for NMUs - i.e. release as -7.1 and 
> share the changes with nmudiff (not using salsa).
> 
> 
> Thanks,
> 
>  - Jonas

Hi Jonas,

Thanks for your trust.
Please find the debdiff between 2.0.19.1-7 and 2.0.19.1-7.1 that I have
just uploaded.

I will remove the moreinfo tag of #989851 once the buildd are done with
rebuilding -7.1. I'm changing the title to have #989851 reflect the NMU
version rather than -8.

Cheers,

Thomas Goirand (zigo)
diff -Nru uwsgi-2.0.19.1/debian/changelog uwsgi-2.0.19.1/debian/changelog
--- uwsgi-2.0.19.1/debian/changelog     2021-05-28 07:56:03.000000000 +0200
+++ uwsgi-2.0.19.1/debian/changelog     2021-06-11 11:08:33.000000000 +0200
@@ -1,3 +1,12 @@
+uwsgi (2.0.19.1-7.1) unstable; urgency=medium
+
+  [ Thomas Goirand ]
+  * Non-maintainer upload.
+  * Add upstream patch to support Transfer-Encoding: chuncked, necessary for
+    OpenStack Glance and Swift over uwsgi.
+
+ -- Thomas Goirand <z...@debian.org>  Fri, 11 Jun 2021 11:08:33 +0200
+
 uwsgi (2.0.19.1-7) unstable; urgency=medium
 
   * add patch cherry-picked upstream
diff -Nru uwsgi-2.0.19.1/debian/patches/Add_support_for_chunked_encoding.patch 
uwsgi-2.0.19.1/debian/patches/Add_support_for_chunked_encoding.patch
--- uwsgi-2.0.19.1/debian/patches/Add_support_for_chunked_encoding.patch        
1970-01-01 01:00:00.000000000 +0100
+++ uwsgi-2.0.19.1/debian/patches/Add_support_for_chunked_encoding.patch        
2021-06-11 11:08:33.000000000 +0200
@@ -0,0 +1,241 @@
+Subject: preliminary implementation of #1428
+ This implements support for transfer-encoding: chuncked
+Author: Unbit <i...@unbit.it>
+Date: Thu, 9 Nov 2017 16:40:44 +0100
+Last-Update: 2021-06-11
+
+Index: uwsgi/core/chunked.c
+===================================================================
+--- uwsgi.orig/core/chunked.c
++++ uwsgi/core/chunked.c
+@@ -83,6 +83,83 @@ static ssize_t uwsgi_chunked_readline(st
+ 
+ */
+ 
++struct uwsgi_buffer *uwsgi_chunked_read_smart(struct wsgi_request *wsgi_req, 
size_t len, int timeout) {
++      // check for buffer
++      if (!wsgi_req->body_chunked_buf)
++              wsgi_req->body_chunked_buf = uwsgi_buffer_new(uwsgi.page_size);
++      // first case: asking for all
++      if (!len) {
++              for(;;) {
++                      size_t chunked_len = 0;
++                      char *buf = uwsgi_chunked_read(wsgi_req, &chunked_len, 
timeout, 0);
++                      if (chunked_len == 0) {
++                              struct uwsgi_buffer *ret = 
uwsgi_buffer_new(wsgi_req->body_chunked_buf->pos);
++                              if (uwsgi_buffer_append(ret, 
wsgi_req->body_chunked_buf->buf, wsgi_req->body_chunked_buf->pos)) {
++                                      uwsgi_buffer_destroy(ret);
++                                      return NULL;
++                              }
++                              
uwsgi_buffer_decapitate(wsgi_req->body_chunked_buf, 
wsgi_req->body_chunked_buf->pos);
++                              return ret;
++                      }
++                      if (uwsgi_buffer_append(wsgi_req->body_chunked_buf, 
buf, chunked_len)) {
++                              return NULL;
++                      }
++              }
++      }
++
++      // asking for littler part
++      if (len <= wsgi_req->body_chunked_buf->pos) {
++              struct uwsgi_buffer *ret = uwsgi_buffer_new(len);
++              if (uwsgi_buffer_append(ret, wsgi_req->body_chunked_buf->buf, 
len)) {
++                      uwsgi_buffer_destroy(ret);
++                      return NULL;
++              }
++              uwsgi_buffer_decapitate(wsgi_req->body_chunked_buf, len);
++              return ret;
++      }
++
++      // more data required
++      size_t remains = len;
++      struct uwsgi_buffer *ret = uwsgi_buffer_new(remains);
++      if (wsgi_req->body_chunked_buf->pos > 0) {
++              if (uwsgi_buffer_append(ret, wsgi_req->body_chunked_buf->buf, 
wsgi_req->body_chunked_buf->pos)) {
++                      uwsgi_buffer_destroy(ret);
++                      return NULL;
++              }
++              remains -= wsgi_req->body_chunked_buf->pos;
++              uwsgi_buffer_decapitate(wsgi_req->body_chunked_buf, 
wsgi_req->body_chunked_buf->pos);
++      }
++
++      while(remains) {
++              size_t chunked_len = 0;
++                char *buf = uwsgi_chunked_read(wsgi_req, &chunked_len, 
timeout, 0);
++                if (chunked_len == 0) {
++                      break;
++              }
++              if (uwsgi_buffer_append(wsgi_req->body_chunked_buf, buf, 
chunked_len)) {
++                      uwsgi_buffer_destroy(ret);
++                      return NULL;
++              }
++
++              if (chunked_len > remains) {
++                      if (uwsgi_buffer_append(ret, 
wsgi_req->body_chunked_buf->buf, wsgi_req->body_chunked_buf->pos - (chunked_len 
- remains))) {
++                                uwsgi_buffer_destroy(ret);
++                                return NULL;
++                        }
++                        uwsgi_buffer_decapitate(wsgi_req->body_chunked_buf, 
wsgi_req->body_chunked_buf->pos - (chunked_len - remains));
++                        return ret;
++              }
++              remains -= chunked_len;
++      }
++
++      if (uwsgi_buffer_append(ret, wsgi_req->body_chunked_buf->buf, 
wsgi_req->body_chunked_buf->pos)) {
++              uwsgi_buffer_destroy(ret);
++              return NULL;
++      }
++      uwsgi_buffer_decapitate(wsgi_req->body_chunked_buf, 
wsgi_req->body_chunked_buf->pos);
++      return ret;
++}
++
+ char *uwsgi_chunked_read(struct wsgi_request *wsgi_req, size_t *len, int 
timeout, int nb) {
+ 
+       if (!wsgi_req->chunked_input_buf) {
+Index: uwsgi/core/protocol.c
+===================================================================
+--- uwsgi.orig/core/protocol.c
++++ uwsgi/core/protocol.c
+@@ -560,6 +560,12 @@ static int uwsgi_proto_check_22(struct w
+                 wsgi_req->scheme_len = len;
+         }
+ 
++      if (!uwsgi_proto_key("HTTP_TRANSFER_ENCODING", 22)) {
++              if (!uwsgi_strnicmp(buf, len, "chunked", 7)) {
++                      wsgi_req->body_is_chunked = 1;
++              }
++      }
++
+       return 0;
+ }
+ 
+Index: uwsgi/core/utils.c
+===================================================================
+--- uwsgi.orig/core/utils.c
++++ uwsgi/core/utils.c
+@@ -1182,6 +1182,10 @@ void uwsgi_close_request(struct wsgi_req
+               uwsgi_buffer_destroy(wsgi_req->chunked_input_buf);
+       }
+ 
++      if (wsgi_req->body_chunked_buf) {
++              uwsgi_buffer_destroy(wsgi_req->body_chunked_buf);
++      }
++
+       // free websocket engine
+       if (wsgi_req->websocket_buf) {
+               uwsgi_buffer_destroy(wsgi_req->websocket_buf);
+Index: uwsgi/plugins/python/python_plugin.c
+===================================================================
+--- uwsgi.orig/plugins/python/python_plugin.c
++++ uwsgi/plugins/python/python_plugin.c
+@@ -174,6 +174,8 @@ struct uwsgi_option uwsgi_python_options
+ 
+       {"python-worker-override", required_argument, 0, "override worker with 
the specified python script", uwsgi_opt_set_str, &up.worker_override, 0},
+ 
++      {"wsgi-manage-chunked-input", no_argument, 0, "manage chunked input via 
the wsgi.input_terminated extension", uwsgi_opt_true, 
&up.wsgi_manage_chunked_input, 0},
++
+       {0, 0, 0, 0, 0, 0, 0},
+ };
+ 
+Index: uwsgi/plugins/python/uwsgi_python.h
+===================================================================
+--- uwsgi.orig/plugins/python/uwsgi_python.h
++++ uwsgi/plugins/python/uwsgi_python.h
+@@ -214,6 +214,8 @@ struct uwsgi_python {
+       int wsgi_disable_file_wrapper;
+ 
+       char *worker_override;
++
++      int wsgi_manage_chunked_input;
+ };
+ 
+ 
+Index: uwsgi/plugins/python/wsgi_handlers.c
+===================================================================
+--- uwsgi.orig/plugins/python/wsgi_handlers.c
++++ uwsgi/plugins/python/wsgi_handlers.c
+@@ -62,7 +62,20 @@ static PyObject *uwsgi_Input_read(uwsgi_
+       ssize_t rlen = 0;
+ 
+       UWSGI_RELEASE_GIL
+-      char *buf = uwsgi_request_body_read(wsgi_req, arg_len, &rlen);
++      char *buf = NULL;
++      if (wsgi_req->body_is_chunked && up.wsgi_manage_chunked_input) {
++              struct uwsgi_buffer *ubuf = uwsgi_chunked_read_smart(wsgi_req, 
arg_len, uwsgi.socket_timeout);
++              UWSGI_GET_GIL
++              if (!ubuf) {
++                              return PyErr_Format(PyExc_IOError, "error 
during chunked read(%ld) on wsgi.input", arg_len);
++              }
++              PyObject *ret = PyString_FromStringAndSize(ubuf->buf, 
ubuf->pos);
++              uwsgi_buffer_destroy(ubuf);
++              return ret;
++      }
++      else {
++              buf = uwsgi_request_body_read(wsgi_req, arg_len, &rlen);
++      }
+       UWSGI_GET_GIL
+       if (buf == uwsgi.empty) {
+               return PyString_FromString("");
+Index: uwsgi/plugins/python/wsgi_subhandler.c
+===================================================================
+--- uwsgi.orig/plugins/python/wsgi_subhandler.c
++++ uwsgi/plugins/python/wsgi_subhandler.c
+@@ -179,6 +179,15 @@ void *uwsgi_request_subhandler_wsgi(stru
+ 
+         PyDict_SetItemString(wsgi_req->async_environ, "wsgi.input", 
wsgi_req->async_input);
+ 
++      if (up.wsgi_manage_chunked_input) {
++              if (wsgi_req->body_is_chunked) {
++                      PyDict_SetItemString(wsgi_req->async_environ, 
"wsgi.input_terminated", Py_True);
++              }
++              else {
++                      PyDict_SetItemString(wsgi_req->async_environ, 
"wsgi.input_terminated", Py_False);
++              }
++      }
++
+       if (!up.wsgi_disable_file_wrapper)
+               PyDict_SetItemString(wsgi_req->async_environ, 
"wsgi.file_wrapper", wi->sendfile);
+ 
+Index: uwsgi/t/python/wsgi_chunked.py
+===================================================================
+--- /dev/null
++++ uwsgi/t/python/wsgi_chunked.py
+@@ -0,0 +1,16 @@
++def application(environ, start_response):
++    print(environ)
++    start_response('200 OK', [])
++    if not environ['wsgi.input_terminated']:
++        return []
++#    print(environ['wsgi.input'].read())
++    data = environ['wsgi.input'].read(2)
++    print(data)
++    data = environ['wsgi.input'].read(2)
++    print(data)
++    data = environ['wsgi.input'].read(2)
++    print(data)
++    data = environ['wsgi.input'].read(6)
++    print(data)
++    print(environ['wsgi.input'].read())
++    return [data]
+Index: uwsgi/uwsgi.h
+===================================================================
+--- uwsgi.orig/uwsgi.h
++++ uwsgi/uwsgi.h
+@@ -1617,6 +1617,9 @@ struct wsgi_request {
+       // used for protocol parsers requiring EOF signaling
+       int proto_parser_eof;
+ 
++      int body_is_chunked;
++      struct uwsgi_buffer *body_chunked_buf;
++
+       // 64bit range, deprecates size_t __range_from, __range_to
+       enum uwsgi_range range_parsed;
+       int64_t range_from;
+@@ -4506,6 +4509,7 @@ struct uwsgi_buffer *uwsgi_websocket_rec
+ struct uwsgi_buffer *uwsgi_websocket_recv_nb(struct wsgi_request *);
+ 
+ char *uwsgi_chunked_read(struct wsgi_request *, size_t *, int, int);
++struct uwsgi_buffer *uwsgi_chunked_read_smart(struct wsgi_request *, size_t, 
int);
+ 
+ uint16_t uwsgi_be16(char *);
+ uint32_t uwsgi_be32(char *);
diff -Nru uwsgi-2.0.19.1/debian/patches/series 
uwsgi-2.0.19.1/debian/patches/series
--- uwsgi-2.0.19.1/debian/patches/series        2021-05-28 07:43:30.000000000 
+0200
+++ uwsgi-2.0.19.1/debian/patches/series        2021-06-11 11:08:33.000000000 
+0200
@@ -20,3 +20,4 @@
 1016_readline.patch
 1017_python3-compat.patch
 2001_ensure_verbose_build.patch
+Add_support_for_chunked_encoding.patch

Reply via email to