Пример #1
0
static int manage_raw_response(struct wsgi_request *wsgi_req) {
	int ret = 0;
	if (!wsgi_req->async_force_again) {
		ret = uwsgi_python_send_body(wsgi_req, (PyObject *) wsgi_req->async_result);
		if (ret == 0) {
			if (PyInt_Check((PyObject *) wsgi_req->async_result) || PyObject_HasAttrString((PyObject *) wsgi_req->async_result, "fileno")) {
				// is it a file ?
				int fd = PyObject_AsFileDescriptor((PyObject *) wsgi_req->async_result);
				if (fd >= 0) {
					wsgi_req->sendfile_fd = fd;
					uwsgi_response_sendfile_do(wsgi_req, fd, 0, 0);
					wsgi_req->sendfile_fd = -1;
					return UWSGI_OK;
				}
			}
		}
	}
	if (ret == 0) {
		if (!wsgi_req->async_placeholder) {
			wsgi_req->async_placeholder = PyObject_GetIter((PyObject *) wsgi_req->async_result);
			if (!wsgi_req->async_placeholder)
				return UWSGI_OK;
		}

		PyObject *pychunk = PyIter_Next((PyObject *) wsgi_req->async_placeholder);
		if (!pychunk)
			return UWSGI_OK;
		ret = uwsgi_python_send_body(wsgi_req, pychunk);
		if (ret == 0) {
			if (PyInt_Check(pychunk) || PyObject_HasAttrString(pychunk, "fileno")) {
				// is it a file ?
				int fd = PyObject_AsFileDescriptor(pychunk);
				if (fd >= 0) {
					wsgi_req->sendfile_fd = fd;
					uwsgi_response_sendfile_do(wsgi_req, fd, 0, 0);
					wsgi_req->sendfile_fd = -1;
				}
			}
		}
		Py_DECREF(pychunk);
		return UWSGI_AGAIN;
	}
	return UWSGI_OK;
}
Пример #2
0
int uwsgi_response_subhandler_wsgi(struct wsgi_request *wsgi_req) {

	PyObject *pychunk;

	// return or yield ?
	// in strict mode we do not optimize apps directly returning strings (or bytes)
	if (!up.wsgi_strict) {
		if (uwsgi_python_send_body(wsgi_req, (PyObject *)wsgi_req->async_result)) goto clear;
	}

	if (wsgi_req->sendfile_obj == wsgi_req->async_result) {
		if (wsgi_req->sendfile_fd >= 0) {
			UWSGI_RELEASE_GIL
			uwsgi_response_sendfile_do(wsgi_req, wsgi_req->sendfile_fd, 0, 0);
			UWSGI_GET_GIL
		}
                // we do not have an iterable, check for read() method
		else if (PyObject_HasAttrString((PyObject *)wsgi_req->async_result, "read")) {
Пример #3
0
int uwsgi_response_subhandler_wsgi(struct wsgi_request *wsgi_req) {

	PyObject *pychunk = NULL;
	const char* chunk = NULL;
	Py_ssize_t chunk_size = 0;

	// return or yield ?
	PyObject *async_result = wsgi_req->async_result;

	if (PyObject_AsCharBuffer(async_result,	&chunk, &chunk_size)<0) {
		PyErr_Clear();

		// is one element list
		if (PyList_Check(async_result) &&
			PyList_GET_SIZE(async_result)==1) {
			PyObject *elem = PyList_GET_ITEM(async_result, 0);
			if (PyObject_AsCharBuffer(elem, &chunk, &chunk_size)<0) {
				PyErr_Clear();
			}
		}
	}

	if(chunk) {
		UWSGI_RELEASE_GIL
		uwsgi_response_write_body_do(wsgi_req, (char*)chunk, chunk_size);
		UWSGI_GET_GIL
		uwsgi_py_check_write_errors {
			uwsgi_py_write_exception(wsgi_req);
		}
		goto clear;
	}

	if (wsgi_req->sendfile_obj == async_result) {
		if (wsgi_req->sendfile_fd >= 0) {
			UWSGI_RELEASE_GIL
			uwsgi_response_sendfile_do(wsgi_req, wsgi_req->sendfile_fd, 0, 0);
			UWSGI_GET_GIL
		}
		// we do not have an iterable, check for read() method
		else if (PyObject_HasAttrString(async_result, "read")) {
Пример #4
0
int uwsgi_jvm_object_to_response_body(struct wsgi_request *wsgi_req, jobject body) {

	// check for string
	if (uwsgi_jvm_object_is_instance(body, ujvm.str_class)) {
                char *c_body = uwsgi_jvm_str2c(body);
                size_t c_body_len = uwsgi_jvm_strlen(body);
                uwsgi_response_write_body_do(wsgi_req, c_body, c_body_len);
                uwsgi_jvm_release_chars(body, c_body);
		return 0;
        }

	// check for string array
	if (uwsgi_jvm_object_is_instance(body, ujvm.str_array_class)) {
		size_t items = uwsgi_jvm_array_len(body);
		size_t i;
		for(i=0;i<items;i++) {
			jobject chunk = uwsgi_jvm_array_get(body, i);
                        if (!chunk) return 0;
                        if (!uwsgi_jvm_object_is_instance(chunk, ujvm.str_class)) {
                                uwsgi_log("body array item must be java/lang/String !!!\n");
                                uwsgi_jvm_local_unref(chunk);
				return 0;
                        }
                        char *c_body = uwsgi_jvm_str2c(chunk);
                        size_t c_body_len = uwsgi_jvm_strlen(chunk);
                        int ret = uwsgi_response_write_body_do(wsgi_req, c_body, c_body_len);
                        uwsgi_jvm_release_chars(chunk, c_body);
                        uwsgi_jvm_local_unref(chunk);
                        if (ret) return 0;
		}
	}

	// check for bytearray
	if (uwsgi_jvm_object_is_instance(body, ujvm.bytearray_class)) {
		char *c_body = uwsgi_jvm_bytearray2c(body);
                size_t c_body_len = uwsgi_jvm_array_len(body);
                uwsgi_response_write_body_do(wsgi_req, c_body, c_body_len);
                uwsgi_jvm_release_bytearray(body, c_body);
                return 0;
	}

	// check for iterable
        jobject chunks = uwsgi_jvm_auto_iterator(body);
        if (chunks) {
                while(uwsgi_jvm_iterator_hasNext(chunks)) {
                        jobject chunk = uwsgi_jvm_iterator_next(chunks);
                        if (!chunk) goto done;
			int ret = -1;
                        if (uwsgi_jvm_object_is_instance(chunk, ujvm.str_class)) {
                        	char *c_body = uwsgi_jvm_str2c(chunk);
                        	size_t c_body_len = uwsgi_jvm_strlen(chunk);
                        	ret = uwsgi_response_write_body_do(wsgi_req, c_body, c_body_len);
                        	uwsgi_jvm_release_chars(chunk, c_body);
                        	uwsgi_jvm_local_unref(chunk);
				if (ret) goto done;
				continue;
			}

			if (uwsgi_jvm_object_is_instance(chunk, ujvm.bytearray_class)) {
                        	char *c_body = uwsgi_jvm_bytearray2c(chunk);
                        	size_t c_body_len = uwsgi_jvm_array_len(chunk);
                        	ret = uwsgi_response_write_body_do(wsgi_req, c_body, c_body_len);
                        	uwsgi_jvm_release_bytearray(chunk, c_body);
                        	uwsgi_jvm_local_unref(chunk);
				if (ret) goto done;
				continue;
			}

			jobject str_o = uwsgi_jvm_to_string(chunk);
			if (str_o) {
				char *c_body = uwsgi_jvm_str2c(str_o);
                                size_t c_body_len = uwsgi_jvm_strlen(str_o);
                                ret = uwsgi_response_write_body_do(wsgi_req, c_body, c_body_len);
                                uwsgi_jvm_release_chars(str_o, c_body);
				uwsgi_jvm_local_unref(str_o);
				uwsgi_jvm_local_unref(chunk);
                                if (ret) goto done;
				continue;
			}

			uwsgi_log("body iterable item must be java/lang/String or array of bytes!!!\n");
                        uwsgi_jvm_local_unref(chunk);
                        goto done;
                }
done:
                uwsgi_jvm_local_unref(chunks);
		return 0;
        }

        if (uwsgi_jvm_object_is_instance(body, ujvm.file_class)) {
                jobject j_filename = uwsgi_jvm_filename(body);
                if (!j_filename) return 0;
                char *c_filename = uwsgi_jvm_str2c(j_filename);
                int fd = open(c_filename, O_RDONLY);
                if (fd < 0) {
                        uwsgi_error("java/io/File.open()");
                        goto done2;
                }
                uwsgi_response_sendfile_do(wsgi_req, fd, 0, 0);
done2:
                uwsgi_jvm_release_chars(j_filename, c_filename);
                uwsgi_jvm_local_unref(j_filename);
		return 0;
        }

        if (uwsgi_jvm_object_is_instance(body, ujvm.input_stream_class)) {
                uwsgi_jvm_consume_input_stream(wsgi_req, 8192, body);
		return 0;
        }

	return -1;
}
Пример #5
0
int uwsgi_real_file_serve(struct wsgi_request *wsgi_req, char *real_filename, size_t real_filename_len, struct stat *st) {

	size_t mime_type_size = 0;
	char http_last_modified[49];

	if (uwsgi.threads > 1)
		pthread_mutex_lock(&uwsgi.lock_static);

	char *mime_type = uwsgi_get_mime_type(real_filename, real_filename_len, &mime_type_size);

	if (uwsgi.threads > 1)
		pthread_mutex_unlock(&uwsgi.lock_static);

	if (wsgi_req->if_modified_since_len) {
		time_t ims = parse_http_date(wsgi_req->if_modified_since, wsgi_req->if_modified_since_len);
		if (st->st_mtime <= ims) {
			uwsgi_response_prepare_headers(wsgi_req, "304 Not Modified", 16); 
			return uwsgi_response_write_headers_do(wsgi_req);
		}
	}
#ifdef UWSGI_DEBUG
	uwsgi_log("[uwsgi-fileserve] file %s found\n", real_filename);
#endif

	size_t fsize = st->st_size;
        if (wsgi_req->range_to) {
        	fsize = wsgi_req->range_to - wsgi_req->range_from;
                if (fsize > (size_t)st->st_size) {
                	fsize = st->st_size;
                }
        }
	else {
        	// reset in case of inconsistent size
        	if (wsgi_req->range_from > fsize) {
        		wsgi_req->range_from = 0;
                	fsize = 0 ;
        	}
		else {
			fsize -= wsgi_req->range_from;
		}
	}

	// HTTP status
	if (fsize > 0 && (wsgi_req->range_from || wsgi_req->range_to)) {
		if (uwsgi_response_prepare_headers(wsgi_req, "206 Partial Content", 19)) return -1;
	}
	else {
		if (uwsgi_response_prepare_headers(wsgi_req, "200 OK", 6)) return -1;
	}

#ifdef UWSGI_PCRE
	uwsgi_add_expires(wsgi_req, real_filename, real_filename_len, st);
	uwsgi_add_expires_path_info(wsgi_req, st);
	uwsgi_add_expires_uri(wsgi_req, st);
#endif

	// Content-Type (if available)
	if (mime_type_size > 0 && mime_type) {
		if (uwsgi_response_add_content_type(wsgi_req, mime_type, mime_type_size)) return -1;
		// check for content-type related headers
		uwsgi_add_expires_type(wsgi_req, mime_type, mime_type_size, st);
	}

	// increase static requests counter
	uwsgi.workers[uwsgi.mywid].cores[wsgi_req->async_id].static_requests++;

	// nginx
	if (uwsgi.file_serve_mode == 1) {
		if (uwsgi_response_add_header(wsgi_req, "X-Accel-Redirect", 16, real_filename, real_filename_len)) return -1;
		// this is the final header (\r\n added)
		int size = set_http_date(st->st_mtime, http_last_modified);
		if (uwsgi_response_add_header(wsgi_req, "Last-Modified", 13, http_last_modified, size)) return -1;
	}
	// apache
	else if (uwsgi.file_serve_mode == 2) {
		if (uwsgi_response_add_header(wsgi_req, "X-Sendfile", 10, real_filename, real_filename_len)) return -1;
		// this is the final header (\r\n added)
		int size = set_http_date(st->st_mtime, http_last_modified);
		if (uwsgi_response_add_header(wsgi_req, "Last-Modified", 13, http_last_modified, size)) return -1;
	}
	// raw
	else {
		// here we need to choose if we want the gzip variant;
		if (uwsgi_static_want_gzip(wsgi_req, real_filename, real_filename_len, st)) {
			if (uwsgi_response_add_header(wsgi_req, "Content-Encoding", 16, "gzip", 4)) return -1;
		}
		// set Content-Length (to fsize NOT st->st_size)
		if (uwsgi_response_add_content_length(wsgi_req, fsize)) return -1;
		if (fsize > 0 && (wsgi_req->range_from || wsgi_req->range_to)) {
			// here use teh original size !!!
			if (uwsgi_response_add_content_range(wsgi_req, wsgi_req->range_from, wsgi_req->range_to, st->st_size)) return -1;
		}
		int size = set_http_date(st->st_mtime, http_last_modified);
		if (uwsgi_response_add_header(wsgi_req, "Last-Modified", 13, http_last_modified, size)) return -1;

		// if it is a HEAD request just skip transfer
		if (!uwsgi_strncmp(wsgi_req->method, wsgi_req->method_len, "HEAD", 4)) {
			wsgi_req->status = 200;
			return 0;
		}

		// Ok, the file must be transferred from uWSGI
		// offloading will be automatically managed
		int fd = open(real_filename, O_RDONLY);
		if (fd < 0) return -1;
		// fd will be closed in the following function
		uwsgi_response_sendfile_do(wsgi_req, fd, wsgi_req->range_from, fsize);
	}

	wsgi_req->status = 200;
	return 0;
}