Beispiel #1
0
PyObject *py_uwsgi_write(PyObject * self, PyObject * args) {
	PyObject *data;
	char *content;
	size_t content_len;

	struct wsgi_request *wsgi_req = py_current_wsgi_req();

	data = PyTuple_GetItem(args, 0);
	if (PyString_Check(data)) {
		content = PyString_AsString(data);
		content_len = PyString_Size(data);
		UWSGI_RELEASE_GIL
		uwsgi_response_write_body_do(wsgi_req, content, content_len);
		UWSGI_GET_GIL
		// this is a special case for the write callable
		// no need to honout write-errors-exception-only
		if (wsgi_req->write_errors > uwsgi.write_errors_tolerance && !uwsgi.disable_write_exception) {
                        uwsgi_py_write_set_exception(wsgi_req);
			return NULL;
		}
	}

	Py_INCREF(Py_None);
	return Py_None;
}
Beispiel #2
0
PyObject *py_eventfd_write(PyObject * self, PyObject * args) {
	int fd, timeout = 0;

	struct wsgi_request *wsgi_req = py_current_wsgi_req();

	if (!PyArg_ParseTuple(args, "i|i", &fd, &timeout)) {
		return NULL;
	}

	if (async_add_fd_write(wsgi_req, fd, timeout)) {
		return PyErr_Format(PyExc_IOError, "unable to fd %d to the event queue", fd);
	}

	return PyString_FromString("");
}
Beispiel #3
0
PyObject *py_uwsgi_spit(PyObject * self, PyObject * args) {
    PyObject *headers, *head;
    PyObject *h_key, *h_value;
    PyObject *exc_info = NULL;
    size_t i;

    struct wsgi_request *wsgi_req = py_current_wsgi_req();

    // avoid double sending of headers
    if (wsgi_req->headers_sent) {
        return PyErr_Format(PyExc_IOError, "headers already sent");
    }

    // this must be done before headers management
    if (PyTuple_Size(args) > 2) {
        exc_info = PyTuple_GetItem(args, 2);
        if (exc_info && exc_info != Py_None) {
            PyObject *exc_type = PyTuple_GetItem(exc_info, 0);
            PyObject *exc_val = PyTuple_GetItem(exc_info, 1);
            PyObject *exc_tb = PyTuple_GetItem(exc_info, 2);

            if (!exc_type || !exc_val || !exc_tb) {
                return NULL;
            }

            Py_INCREF(exc_type);
            Py_INCREF(exc_val);
            Py_INCREF(exc_tb);
            // in this way, error will be reported to the log
            PyErr_Restore(exc_type, exc_val, exc_tb);

            // the error is reported, let's continue...
            // return NULL
        }
    }

    head = PyTuple_GetItem(args, 0);
    if (!head) {
        return PyErr_Format(PyExc_TypeError, "start_response() takes at least 2 arguments");
    }

#ifdef PYTHREE
    // check for web3
    if ((self != Py_None && !PyUnicode_Check(head)) || (self == Py_None && !PyBytes_Check(head))) {
#else
    if (!PyString_Check(head)) {
#endif
        return PyErr_Format(PyExc_TypeError, "http status must be a string");
    }

    char *status_line = NULL;
    size_t status_line_len = 0;
#ifdef PYTHREE
    PyObject *zero = NULL;
    PyObject *zero2 = NULL;
    if (self != Py_None) {
        zero = PyUnicode_AsASCIIString(head);
        if (!zero) {
            return PyErr_Format(PyExc_TypeError, "http status string must be encodable in latin1");
        }
        status_line = PyBytes_AsString(zero);
        status_line_len = PyBytes_Size(zero);
    }
    else {
        status_line = PyBytes_AsString(head);
        status_line_len = PyBytes_Size(head);
    }
#else
    status_line = PyString_AsString(head);
    status_line_len = PyString_Size(head);
#endif
    if (uwsgi_response_prepare_headers(wsgi_req, status_line, status_line_len)) {
#ifdef PYTHREE
        Py_DECREF(zero);
#endif
        goto end;
    }

#ifdef PYTHREE
    Py_DECREF(zero);
#endif

    headers = PyTuple_GetItem(args, 1);
    if (!headers) {
        return PyErr_Format(PyExc_TypeError, "start_response() takes at least 2 arguments");
    }

    if (!PyList_Check(headers)) {
        return PyErr_Format(PyExc_TypeError, "http headers must be in a python list");
    }

    size_t h_count = PyList_Size(headers);

    for (i = 0; i < h_count; i++) {
        head = PyList_GetItem(headers, i);
        if (!head) {
            return NULL;
        }
        if (!PyTuple_Check(head)) {
            return PyErr_Format(PyExc_TypeError, "http header must be defined in a tuple");
        }
        h_key = PyTuple_GetItem(head, 0);
        if (!h_key) {
            return PyErr_Format(PyExc_TypeError, "http header must be a 2-item tuple");
        }
#ifdef PYTHREE
        if ((self != Py_None && !PyUnicode_Check(h_key)) || (self == Py_None && !PyBytes_Check(h_key))) {
#else
        if (!PyString_Check(h_key)) {
#endif
            return PyErr_Format(PyExc_TypeError, "http header key must be a string");
        }
        h_value = PyTuple_GetItem(head, 1);
        if (!h_value) {
            return PyErr_Format(PyExc_TypeError, "http header must be a 2-item tuple");
        }
#ifdef PYTHREE
        if ((self != Py_None && !PyUnicode_Check(h_value)) || (self == Py_None && !PyBytes_Check(h_value))) {
#else
        if (!PyString_Check(h_value)) {
#endif
            return PyErr_Format(PyExc_TypeError, "http header value must be a string");
        }


        char *k = NULL;
        size_t kl = 0;
        char *v = NULL;
        size_t vl = 0;

#ifdef PYTHREE
        if (self != Py_None) {
            zero = PyUnicode_AsASCIIString(h_key);
            if (!zero) {
                return PyErr_Format(PyExc_TypeError, "http header must be encodable in latin1");
            }
            k = PyBytes_AsString(zero);
            kl = PyBytes_Size(zero);
        }
        else {
            k = PyBytes_AsString(h_key);
            kl = PyBytes_Size(h_key);
        }
#else
        k = PyString_AsString(h_key);
        kl = PyString_Size(h_key);
#endif

#ifdef PYTHREE
        if (self != Py_None) {
            zero2 = PyUnicode_AsASCIIString(h_value);
            if (!zero2) {
                return PyErr_Format(PyExc_TypeError, "http header must be encodable in latin1");
            }
            v = PyBytes_AsString(zero2);
            vl = PyBytes_Size(zero2);
        }
        else {
            v = PyBytes_AsString(h_value);
            vl = PyBytes_Size(h_value);
        }
#else
        v = PyString_AsString(h_value);
        vl = PyString_Size(h_value);
#endif

        if (uwsgi_response_add_header(wsgi_req, k, kl, v, vl)) {
#ifdef PYTHREE
            Py_DECREF(zero);
            Py_DECREF(zero2);
#endif
            return PyErr_Format(PyExc_TypeError, "unable to add header to the response");
        }

#ifdef PYTHREE
        Py_DECREF(zero);
        Py_DECREF(zero2);
#endif

    }

    if (up.start_response_nodelay) {
        UWSGI_RELEASE_GIL
        if (uwsgi_response_write_headers_do(wsgi_req)) {
            UWSGI_GET_GIL
            return PyErr_Format(PyExc_IOError, "unable to directly send headers");
        }
        UWSGI_GET_GIL
    }

end:
    Py_INCREF(up.wsgi_writeout);
    return up.wsgi_writeout;
}