accepting buffer is an option: --wsgi-accept-buffer

This commit is contained in:
Unbit
2013-10-05 12:32:49 +02:00
parent c90c639348
commit a0082b5b98
3 changed files with 24 additions and 19 deletions
+2 -1
View File
@@ -156,7 +156,8 @@ struct uwsgi_option uwsgi_python_options[] = {
{"wsgi-env-behavior", required_argument, 0, "set the strategy for allocating/deallocating the WSGI env", uwsgi_opt_set_str, &up.wsgi_env_behaviour, 0},
{"start_response-nodelay", no_argument, 0, "send WSGI http headers as soon as possible (PEP violation)", uwsgi_opt_true, &up.start_response_nodelay, 0},
{"wsgi-strict", no_argument, 0, "expect the WSGI callable to return ONLY strings (python 2.x) or bytes (python 3.x), and disable non-iterable optimizations", uwsgi_opt_true, &up.wsgi_strict, 0},
{"wsgi-strict", no_argument, 0, "try to be fully PEP compliant disabling optimizations", uwsgi_opt_true, &up.wsgi_strict, 0},
{"wsgi-accept-buffer", no_argument, 0, "accept CPython buffer-compliant objects as WSGI response in addition to string/bytes", uwsgi_opt_true, &up.wsgi_accept_buffer, 0},
{"python-version", no_argument, 0, "report python version", uwsgi_opt_pyver, NULL, UWSGI_OPT_IMMEDIATE},
+1
View File
@@ -181,6 +181,7 @@ struct uwsgi_python {
char *programname;
int wsgi_strict;
int wsgi_accept_buffer;
char *raw;
PyObject *raw_callable;
+21 -18
View File
@@ -8,39 +8,42 @@ extern PyTypeObject uwsgi_InputType;
/*
Albeit PEP 333/3333 is clear about what kind of return object we must
expect from a WSGI callable, we use the buffer api to optimize for lower-level
expect from a WSGI callable, we CAN use the buffer api to optimize for lower-level
returns type: bytes, bytearray, array.array
the "strict" behaviour can be forced with --wsgi-strict
to enable this optimization add --wsgi-accept-buffer
NOTE: this is a violation of the standards !!! use only if you know the implications !!!
*/
int uwsgi_python_send_body(struct wsgi_request *wsgi_req, PyObject *chunk) {
if (!up.wsgi_accept_buffer && !wsgi_req->is_raw) goto strict;
#if defined(PYTHREE) || defined(Py_TPFLAGS_HAVE_NEWBUFFER)
Py_buffer pbuf;
int has_buffer = 0;
#endif
char *content = NULL;
size_t content_len = 0;
if (!up.wsgi_strict) {
#if defined(PYTHREE) || defined(Py_TPFLAGS_HAVE_NEWBUFFER)
if (PyObject_CheckBuffer(chunk)) {
if (!PyObject_GetBuffer(chunk, &pbuf, PyBUF_SIMPLE)) {
content = (char *) pbuf.buf;
content_len = (size_t) pbuf.len;
has_buffer = 1;
goto found;
}
if (PyObject_CheckBuffer(chunk)) {
if (!PyObject_GetBuffer(chunk, &pbuf, PyBUF_SIMPLE)) {
content = (char *) pbuf.buf;
content_len = (size_t) pbuf.len;
has_buffer = 1;
goto found;
}
#else
if (PyObject_CheckReadBuffer(chunk)) {
if (!PyObject_AsCharBuffer(chunk, (const char **) &content, (Py_ssize_t *) &content_len)) {
PyErr_Clear();
goto found;
}
}
#endif
}
#else
if (PyObject_CheckReadBuffer(chunk)) {
if (!PyObject_AsCharBuffer(chunk, (const char **) &content, (Py_ssize_t *) &content_len)) {
PyErr_Clear();
goto found;
}
}
#endif
strict:
// fallback
if (PyString_Check(chunk)) {
content = PyString_AsString(chunk);