Ejemplo n.º 1
0
static PyObject *uwsgi_Input_read(uwsgi_Input *self, PyObject *args) {

	long arg_len = 0;

	if (!PyArg_ParseTuple(args, "|l:read", &arg_len)) {
		return NULL;
	}

	struct wsgi_request *wsgi_req = self->wsgi_req;
	ssize_t rlen = 0;

	UWSGI_RELEASE_GIL
	char *buf = uwsgi_request_body_read(wsgi_req, arg_len, &rlen);
	UWSGI_GET_GIL
	if (buf == uwsgi.empty) {
		return PyString_FromString("");
	}

	if (buf) {
		return PyString_FromStringAndSize(buf, rlen);
	}

	// error ?
	if (rlen < 0) {
       		return PyErr_Format(PyExc_IOError, "error during read(%ld) on wsgi.input", arg_len);
	}

	// timeout ?
       	return PyErr_Format(PyExc_IOError, "timeout during read(%ld) on wsgi.input", arg_len);
		
}
Ejemplo n.º 2
0
Archivo: webdav.c Proyecto: JuanS/uwsgi
static int uwsgi_wevdav_manage_put(struct wsgi_request *wsgi_req) {
	char filename[PATH_MAX];
        size_t filename_len = uwsgi_webdav_expand_path(wsgi_req, wsgi_req->path_info, wsgi_req->path_info_len, filename);
        // the collection does not exist, search for the last /
        if (!filename_len) {
		filename_len = uwsgi_webdav_expand_fake_path(wsgi_req, wsgi_req->path_info, wsgi_req->path_info_len, filename);
		if (!filename_len) {
                        uwsgi_response_prepare_headers(wsgi_req, "409 Conflict", 12);
                        return UWSGI_OK;
                }
        }

	int fd = open(filename, O_WRONLY | O_CREAT, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
	if (fd < 0) {
		uwsgi_403(wsgi_req);
                return UWSGI_OK;
	}

	if (uwsgi_response_prepare_headers(wsgi_req, "201 Created", 11)) goto end;
	
	size_t remains = wsgi_req->post_cl;
	while(remains > 0) {
		ssize_t body_len = 0;
		char *body =  uwsgi_request_body_read(wsgi_req, UMIN(remains, 32768) , &body_len);
		if (!body || body == uwsgi.empty) break;
		if (write(fd, body, body_len) != body_len) goto end;
	}

end:
	close(fd);
	return UWSGI_OK;
}
Ejemplo n.º 3
0
int uwsgi_proxy_nb(struct wsgi_request *wsgi_req, char *addr, struct uwsgi_buffer *ub, size_t remains, int timeout) {

        int fd = uwsgi_connect(addr, 0, 1);
        if (fd < 0) {
		return -1;
        }

        int ret = uwsgi.wait_write_hook(fd, timeout);
        if (ret <= 0) {
		goto end;
        }

        // send the request (+ remaining data)
	if (ub) {
        	if (uwsgi_write_true_nb(fd, ub->buf, ub->pos, timeout)) {
			goto end;
        	}
	}

        // send the body
        while(remains > 0) {
                ssize_t rlen = 0;
                char *buf = uwsgi_request_body_read(wsgi_req, 8192, &rlen);
                if (!buf) {
			goto end;
                }
                if (buf == uwsgi.empty) break;
                // write data to the node
                if (uwsgi_write_true_nb(fd, buf, rlen, timeout)) {
			goto end;
                }
                remains -= rlen;
        }

        // read the response
        for(;;) {
                char buf[8192];
                ssize_t rlen = uwsgi_read_true_nb(fd, buf, 8192, timeout);
                if (rlen > 0) {
                        if (uwsgi_response_write_body_do(wsgi_req, buf, rlen)) {
                                break;
                        }
                        continue;
                }
                break;
        }

	close(fd);
	return 0;
end:
	close(fd);
	return -1;
}
Ejemplo n.º 4
0
JNIEXPORT jint JNICALL uwsgi_jvm_request_body_read(JNIEnv *env, jobject o) {
	struct wsgi_request *wsgi_req = current_wsgi_req();
	ssize_t rlen = 0;
        char *chunk = uwsgi_request_body_read(wsgi_req, 1, &rlen);
	if (!chunk) {
		uwsgi_jvm_throw_io("error reading request body");	
		return -1;
	}
	if (chunk == uwsgi.empty) {
		return -1;
	}
	uint8_t byte = chunk[0];
	return (jint) byte;
}
Ejemplo n.º 5
0
JNIEXPORT jint JNICALL uwsgi_jvm_request_body_read_bytearray(JNIEnv *env, jobject o, jobject b) {
	struct wsgi_request *wsgi_req = current_wsgi_req();
	ssize_t rlen = 0;
	size_t len = uwsgi_jvm_array_len(b);
	char *chunk = uwsgi_request_body_read(wsgi_req, len, &rlen);
        if (!chunk) {
                uwsgi_jvm_throw_io("error reading request body");
                return -1;
        }
        if (chunk == uwsgi.empty) {
                return -1;
        }
	char *buf = (char *) (*ujvm_env)->GetByteArrayElements(ujvm_env, b, JNI_FALSE);
        if (!buf) return -1;
	memcpy(buf, chunk, rlen);
	 (*ujvm_env)->ReleaseByteArrayElements(ujvm_env, b, (jbyte *) buf, 0);
        return rlen;
}
Ejemplo n.º 6
0
static int uwsgi_lua_input(lua_State *L) {

	struct wsgi_request *wsgi_req = current_wsgi_req();
	ssize_t sum = 0;

	int n = lua_gettop(L);

	if (n > 1) {
		sum = lua_tonumber(L, 2);
	}

	ssize_t rlen = 0;

        char *buf = uwsgi_request_body_read(wsgi_req, sum, &rlen);
        if (buf) {
		lua_pushlstring(L, buf, rlen);
                return 1;
        }

	return 0;
}
Ejemplo n.º 7
0
static int sapi_uwsgi_read_post(char *buffer, uint count_bytes TSRMLS_DC)
{
	uint read_bytes = 0;
	ssize_t len;
	int fd = -1;
	
	struct wsgi_request *wsgi_req = (struct wsgi_request *) SG(server_context);

        count_bytes = MIN(count_bytes, wsgi_req->post_cl - SG(read_post_bytes));

        while (read_bytes < count_bytes) {
		ssize_t rlen = 0;
		char *buf = uwsgi_request_body_read(wsgi_req, count_bytes - read_bytes, &rlen);
		if (buf == uwsgi.empty) break;
		if (buf) {
			read_bytes += rlen;
			continue;
		}
		break;
        }

        return read_bytes;
}
Ejemplo n.º 8
0
Archivo: webdav.c Proyecto: JuanS/uwsgi
static int uwsgi_webdav_request(struct wsgi_request *wsgi_req) {

	if (!udav.mountpoints) {
		uwsgi_500(wsgi_req);
		return -1;
	}

	if (uwsgi_parse_vars(wsgi_req)) {
		return -1;
	}

	if (wsgi_req->path_info_len == 0) {
		uwsgi_403(wsgi_req);
		return UWSGI_OK;
	}

	wsgi_req->app_id = uwsgi_get_app_id(wsgi_req, wsgi_req->appid, wsgi_req->appid_len, webdav_plugin.modifier1);
        if (wsgi_req->app_id == -1) {
                uwsgi_403(wsgi_req);
                return UWSGI_OK;
        }

	// non lockables methods...

	if (!uwsgi_strncmp(wsgi_req->method, wsgi_req->method_len, "OPTIONS", 7)) {
		return uwsgi_wevdav_manage_options(wsgi_req);
	}

	if (!uwsgi_strncmp(wsgi_req->method, wsgi_req->method_len, "GET", 3)) {
		return uwsgi_wevdav_manage_get(wsgi_req, 1);
	}

	if (!uwsgi_strncmp(wsgi_req->method, wsgi_req->method_len, "HEAD", 4)) {
		return uwsgi_wevdav_manage_get(wsgi_req, 0);
	}

	if (!uwsgi_strncmp(wsgi_req->method, wsgi_req->method_len, "PROPFIND", 8)) {
		if (wsgi_req->post_cl > 0) {
			ssize_t body_len = 0;
			char *body = uwsgi_request_body_read(wsgi_req, wsgi_req->post_cl, &body_len);
#ifdef UWSGI_DEBUG
			uwsgi_log("%.*s\n", body_len, body);
#endif
			xmlDoc *doc = xmlReadMemory(body, body_len, NULL, NULL, 0);
			if (!doc) goto end;
			uwsgi_wevdav_manage_propfind(wsgi_req, doc);
			xmlFreeDoc(doc);
		}
		else {
			uwsgi_wevdav_manage_propfind(wsgi_req, NULL);
		}
	}

	if (!uwsgi_strncmp(wsgi_req->method, wsgi_req->method_len, "REPORT", 6)) {
                if (wsgi_req->post_cl > 0) {
                        ssize_t body_len = 0;
                        char *body = uwsgi_request_body_read(wsgi_req, wsgi_req->post_cl, &body_len);
#ifdef UWSGI_DEBUG
                        uwsgi_log("%.*s\n", body_len, body);
#endif
                        xmlDoc *doc = xmlReadMemory(body, body_len, NULL, NULL, 0);
                        if (!doc) goto end;
                        xmlFreeDoc(doc);
                }
        }


	// lockable methods ...
	// check for locking

	if (!uwsgi_strncmp(wsgi_req->method, wsgi_req->method_len, "PUT", 3)) {
		return uwsgi_wevdav_manage_put(wsgi_req);
	}

	if (!uwsgi_strncmp(wsgi_req->method, wsgi_req->method_len, "DELETE", 6)) {
		return uwsgi_wevdav_manage_delete(wsgi_req);
	}

	if (!uwsgi_strncmp(wsgi_req->method, wsgi_req->method_len, "MKCOL", 5)) {
		return uwsgi_wevdav_manage_mkcol(wsgi_req);
	}

	if (!uwsgi_strncmp(wsgi_req->method, wsgi_req->method_len, "MKCALENDAR", 10)) {
		if (wsgi_req->post_cl == 0)
                        goto end;
                ssize_t body_len = 0;
                char *body = uwsgi_request_body_read(wsgi_req, wsgi_req->post_cl, &body_len);
#ifdef UWSGI_DEBUG
                uwsgi_log("%.*s\n", body_len, body);
#endif
                xmlDoc *doc = xmlReadMemory(body, body_len, NULL, NULL, 0);
                if (!doc) goto end;
                uwsgi_wevdav_manage_mkcalendar(wsgi_req, doc);
                xmlFreeDoc(doc);
	}

	if (!uwsgi_strncmp(wsgi_req->method, wsgi_req->method_len, "COPY", 4)) {
		return uwsgi_wevdav_manage_copy(wsgi_req);
	}

	if (!uwsgi_strncmp(wsgi_req->method, wsgi_req->method_len, "MOVE", 4)) {
		return uwsgi_wevdav_manage_move(wsgi_req);
	}

	if (!uwsgi_strncmp(wsgi_req->method, wsgi_req->method_len, "LOCK", 4)) {
		if (wsgi_req->post_cl > 0) {
			ssize_t body_len = 0;
                	char *body = uwsgi_request_body_read(wsgi_req, wsgi_req->post_cl, &body_len);
#ifdef UWSGI_DEBUG
                	uwsgi_log("%.*s\n", body_len, body);
#endif
			xmlDoc *doc = xmlReadMemory(body, body_len, NULL, NULL, 0);
			if (!doc) goto end;
                	xmlFreeDoc(doc);
		}	
		return uwsgi_wevdav_manage_lock(wsgi_req);
	}

	if (!uwsgi_strncmp(wsgi_req->method, wsgi_req->method_len, "PROPPATCH", 9)) {
                if (wsgi_req->post_cl == 0)
                        goto end;
                ssize_t body_len = 0;
                char *body = uwsgi_request_body_read(wsgi_req, wsgi_req->post_cl, &body_len);
#ifdef UWSGI_DEBUG
                uwsgi_log("%.*s\n", body_len, body);
#endif
                xmlDoc *doc = xmlReadMemory(body, body_len, NULL, NULL, 0);
                if (!doc) goto end;
		uwsgi_wevdav_manage_proppatch(wsgi_req, doc);
                xmlFreeDoc(doc);
        }

end:
	return UWSGI_OK;
}
Ejemplo n.º 9
0
static int uwsgi_rpc_request(struct wsgi_request *wsgi_req) {

	// this is the list of args
	char *argv[UMAX8];
	// this is the size of each argument
	uint16_t argvs[UMAX8];
	// maximum number of supported arguments
	uint8_t argc = 0xff;
	// response output
	char response_buf[UMAX16];

	/* Standard RPC request */
        if (!wsgi_req->uh->pktsize) {
                uwsgi_log("Empty RPC request. skip.\n");
                return -1;
        }

	if (wsgi_req->uh->modifier2 == 2) {
		if (uwsgi_parse_vars(wsgi_req)) {
                	uwsgi_log("Invalid RPC request. skip.\n");
                	return -1;
		}

		if (wsgi_req->path_info_len == 0) {
			uwsgi_500(wsgi_req);
			return UWSGI_OK;
		}

		char *args = NULL;
		if (wsgi_req->path_info[0] == '/') {
			args = uwsgi_concat2n(wsgi_req->path_info+1, wsgi_req->path_info_len-1, "", 0);
		}
		else {
			args = uwsgi_concat2n(wsgi_req->path_info, wsgi_req->path_info_len, "", 0);
		}

		argc = 0;
		argv[0] = strtok(args, "/");
		if (!argv[0]) {
			free(args);
			uwsgi_500(wsgi_req);
			return UWSGI_OK;
		}
		char *p = strtok(NULL, "/");
		while(p) {
			argc++;
			argv[argc] = p;
			argvs[argc] = strlen(p);
			p = strtok(NULL, "/");
		}
		
		wsgi_req->uh->pktsize = uwsgi_rpc(argv[0], argc, argv+1, argvs+1, response_buf);
		free(args);

		if (!wsgi_req->uh->pktsize) {
			uwsgi_404(wsgi_req);
			return UWSGI_OK;
		}
		if (uwsgi_response_prepare_headers(wsgi_req, "200 OK", 6)) return 1;
		if (uwsgi_response_add_content_length(wsgi_req, wsgi_req->uh->pktsize)) return -1;
		uint16_t ctype_len = 0;
		char *ctype = uwsgi_get_var(wsgi_req, "HTTP_ACCEPT", 11, &ctype_len);
		if (ctype && strcmp(ctype, "*/*") && strcmp(ctype, "*")) {
			if (uwsgi_response_add_content_type(wsgi_req, ctype, ctype_len)) return -1;
		}
		else {
			if (uwsgi_response_add_content_type(wsgi_req, "application/binary", 18)) return -1;
		}
		goto sendbody;
	}

#ifdef UWSGI_XML_LIBXML2
	if (wsgi_req->uh->modifier2 == 3) {
		if (wsgi_req->post_cl == 0) {
			uwsgi_500(wsgi_req);
			return UWSGI_OK;
		}
		ssize_t body_len = 0;
                char *body = uwsgi_request_body_read(wsgi_req, wsgi_req->post_cl, &body_len);	
		xmlDoc *doc = xmlReadMemory(body, body_len, NULL, NULL, 0);
                if (!doc) {
			uwsgi_500(wsgi_req);
			return UWSGI_OK;
		}
                int ret = uwsgi_rpc_xmlrpc(wsgi_req, doc, argv, argvs, &argc, response_buf);
                xmlFreeDoc(doc);
		if (ret) {
			uwsgi_500(wsgi_req);
		}
		return UWSGI_OK;
	}
#endif

	if (uwsgi_parse_array(wsgi_req->buffer, wsgi_req->uh->pktsize, argv, argvs, &argc)) {
                uwsgi_log("Invalid RPC request. skip.\n");
                return -1;
	}

	// call the function (output will be in wsgi_req->buffer)
	wsgi_req->uh->pktsize = uwsgi_rpc(argv[0], argc-1, argv+1, argvs+1, response_buf);

	// using modifier2 we may want a raw output
	if (wsgi_req->uh->modifier2 == 0) {
		if (uwsgi_response_write_body_do(wsgi_req, (char *) wsgi_req->uh, 4)) {
			return -1;
		}
	}


sendbody:
	// write the response
	uwsgi_response_write_body_do(wsgi_req, response_buf, wsgi_req->uh->pktsize);
	
	return UWSGI_OK;
}
Ejemplo n.º 10
0
Archivo: cache.c Proyecto: Algy/uwsgi
// this function does not use the magic api internally to avoid too much copy
static void manage_magic_context(struct wsgi_request *wsgi_req, struct uwsgi_cache_magic_context *ucmc) {

	struct uwsgi_buffer *ub = NULL;
	struct uwsgi_cache *uc = uwsgi.caches;

	if (ucmc->cache_len > 0) {
		uc = uwsgi_cache_by_namelen(ucmc->cache, ucmc->cache_len);
		if (!uc) return;
	}

	if (!uc) return;

	// cache get
	if (!uwsgi_strncmp(ucmc->cmd, ucmc->cmd_len, "get", 3)) {
		uint64_t vallen = 0;
		uint64_t expires = 0;
		uwsgi_rlock(uc->lock);
		char *value = uwsgi_cache_get3(uc, ucmc->key, ucmc->key_len, &vallen, &expires);
		if (!value) {
			uwsgi_rwunlock(uc->lock);
			return;
		}
		// we are still locked !!!
		ub = uwsgi_buffer_new(uwsgi.page_size);
		ub->pos = 4;
		if (uwsgi_buffer_append_keyval(ub, "status", 6, "ok", 2)) goto error;
		if (uwsgi_buffer_append_keynum(ub, "size", 4, vallen)) goto error;
		if (expires) {
			if (uwsgi_buffer_append_keynum(ub, "expires", 7, expires)) goto error;
		}
		if (uwsgi_buffer_set_uh(ub, 111, 17)) goto error;
		if (uwsgi_buffer_append(ub, value, vallen)) goto error;
		// unlock !!!
		uwsgi_rwunlock(uc->lock);
		uwsgi_response_write_body_do(wsgi_req, ub->buf, ub->pos);
		uwsgi_buffer_destroy(ub);
		return;	
	}

	// cache exists
	if (!uwsgi_strncmp(ucmc->cmd, ucmc->cmd_len, "exists", 6)) {
                uwsgi_rlock(uc->lock);
                if (!uwsgi_cache_exists2(uc, ucmc->key, ucmc->key_len)) {
                        uwsgi_rwunlock(uc->lock);
                        return;
                }
                // we are still locked !!!
                ub = uwsgi_buffer_new(uwsgi.page_size);
                ub->pos = 4;
                if (uwsgi_buffer_append_keyval(ub, "status", 6, "ok", 2)) goto error;
                if (uwsgi_buffer_set_uh(ub, 111, 17)) goto error;
                // unlock !!!
                uwsgi_rwunlock(uc->lock);
                uwsgi_response_write_body_do(wsgi_req, ub->buf, ub->pos);
                uwsgi_buffer_destroy(ub);
                return;
        }

	// cache del
        if (!uwsgi_strncmp(ucmc->cmd, ucmc->cmd_len, "del", 3)) {
                uwsgi_wlock(uc->lock);
                if (uwsgi_cache_del2(uc, ucmc->key, ucmc->key_len, 0, 0)) {
                        uwsgi_rwunlock(uc->lock);
                        return;
                }
                // we are still locked !!!
                ub = uwsgi_buffer_new(uwsgi.page_size);
                ub->pos = 4;
                if (uwsgi_buffer_append_keyval(ub, "status", 6, "ok", 2)) goto error;
                if (uwsgi_buffer_set_uh(ub, 111, 17)) goto error;
                // unlock !!!
                uwsgi_rwunlock(uc->lock);
                uwsgi_response_write_body_do(wsgi_req, ub->buf, ub->pos);
                uwsgi_buffer_destroy(ub);
                return;
        }

	// cache clear
        if (!uwsgi_strncmp(ucmc->cmd, ucmc->cmd_len, "clear", 5)) {
		uint64_t i;
		uwsgi_wlock(uc->lock);
		for (i = 1; i < uwsgi.caches->max_items; i++) {
			if (uwsgi_cache_del2(uc, NULL, 0, i, 0)) {
                                uwsgi_rwunlock(uc->lock);
                                return;
                        }	
		}
                // we are still locked !!!
                ub = uwsgi_buffer_new(uwsgi.page_size);
                ub->pos = 4;
                if (uwsgi_buffer_append_keyval(ub, "status", 6, "ok", 2)) goto error;
                if (uwsgi_buffer_set_uh(ub, 111, 17)) goto error;
                // unlock !!!
                uwsgi_rwunlock(uc->lock);
                uwsgi_response_write_body_do(wsgi_req, ub->buf, ub->pos);
                uwsgi_buffer_destroy(ub);
                return;
        }

	// cache set
	if (!uwsgi_strncmp(ucmc->cmd, ucmc->cmd_len, "set", 3) || !uwsgi_strncmp(ucmc->cmd, ucmc->cmd_len, "update", 6)) {
		if (ucmc->size == 0 || ucmc->size > uc->max_item_size) return;
		wsgi_req->post_cl = ucmc->size;
		// read the value
		ssize_t rlen = 0;
		char *value = uwsgi_request_body_read(wsgi_req, ucmc->size, &rlen);
		if (rlen != (ssize_t) ucmc->size) return;
		// ok let's lock
		uwsgi_wlock(uc->lock);
		if (uwsgi_cache_set2(uc, ucmc->key, ucmc->key_len, value, ucmc->size, ucmc->expires, ucmc->cmd_len > 3 ? UWSGI_CACHE_FLAG_UPDATE : 0)) {
			uwsgi_rwunlock(uc->lock);
			return;
		}
		// we are still locked !!!
		ub = uwsgi_buffer_new(uwsgi.page_size);
		ub->pos = 4;
                if (uwsgi_buffer_append_keyval(ub, "status", 6, "ok", 2)) goto error;
		if (uwsgi_buffer_set_uh(ub, 111, 17)) goto error;
		// unlock !!!
		uwsgi_rwunlock(uc->lock);
		uwsgi_response_write_body_do(wsgi_req, ub->buf, ub->pos);
                uwsgi_buffer_destroy(ub);
                return;
	}

	return;
error:
	uwsgi_rwunlock(uc->lock);
	uwsgi_buffer_destroy(ub);
}
Ejemplo n.º 11
0
Archivo: rados.c Proyecto: Nikolo/uwsgi
static void uwsgi_rados_propfind(struct wsgi_request *wsgi_req, rados_ioctx_t ctx, char *key, uint64_t size, time_t mtime, int timeout) {
	// consume the body
	size_t remains = wsgi_req->post_cl;
        while(remains > 0) {
                ssize_t body_len = 0;
                char *body =  uwsgi_request_body_read(wsgi_req, UMIN(remains, 32768), &body_len);
                if (!body || body == uwsgi.empty) break;
		remains -= body_len;
	}

	if (uwsgi_response_prepare_headers(wsgi_req, "207 Multi-Status", 16)) return;
	if (uwsgi_response_add_content_type(wsgi_req, "text/xml; charset=\"utf-8\"", 25)) return;
	struct uwsgi_buffer *ub = uwsgi_webdav_multistatus_new();
	if (!ub) return;
	if (key) {
		size_t mime_type_len = 0;
        	char *mime_type = uwsgi_get_mime_type(key, strlen(key), &mime_type_len);
		char *slashed = uwsgi_concat2("/", key);
		if (uwsgi_webdav_propfind_item_add(ub, slashed, strlen(key)+1, size, mtime, mime_type, mime_type_len, NULL, 0, NULL, 0)) {
			free(slashed);
			goto end;
		}
		free(slashed);
		if (uwsgi_webdav_multistatus_close(ub)) goto end;
		uwsgi_response_write_body_do(wsgi_req, ub->buf, ub->pos);
		goto end;
	}
	// request for /
	size_t depth = 0;
	uint16_t http_depth_len = 0;
        char *http_depth = uwsgi_get_var(wsgi_req, "HTTP_DEPTH", 10, &http_depth_len);
        if (http_depth) {
                depth = uwsgi_str_num(http_depth, http_depth_len);
        }

	if (depth == 0) {
		if (uwsgi_webdav_propfind_item_add(ub, "/", 1, 0, 0, NULL, 0, NULL, 0, NULL, 0)) {
                        goto end;
                }
                if (uwsgi_webdav_multistatus_close(ub)) goto end;
                uwsgi_response_write_body_do(wsgi_req, ub->buf, ub->pos);
		goto end;
	}

	struct uwsgi_rados_io *urio = &urados.urio[wsgi_req->async_id];
	rados_list_ctx_t ctx_list;
	if (rados_objects_list_open(ctx, &ctx_list) < 0) {
		goto end;
	}

	char *entry = NULL;
	while(rados_objects_list_next(ctx_list, (const char **)&entry, NULL) == 0) {
		uint64_t stat_size = 0;
		time_t stat_mtime = 0;
		if (uwsgi.async > 0) {
        		if (uwsgi_rados_async_stat(urio, ctx, entry, &stat_size, &stat_mtime, timeout) < 0) goto end;
        	}
        	else {
                	if (rados_stat(ctx, entry, &stat_size, &stat_mtime) < 0) goto end;
        	}

		size_t mime_type_len = 0;
                char *mime_type = uwsgi_get_mime_type(entry, strlen(entry), &mime_type_len);
                char *slashed = uwsgi_concat2("/", entry);
                if (uwsgi_webdav_propfind_item_add(ub, slashed, strlen(entry)+1, stat_size, stat_mtime, mime_type, mime_type_len, NULL, 0, NULL, 0)) {
                        free(slashed);
                        goto end;
                }
                free(slashed);
                if (uwsgi_response_write_body_do(wsgi_req, ub->buf, ub->pos)) goto end;
		// reset buffer;
		ub->pos = 0;
	}
	rados_objects_list_close(ctx_list);
        if (uwsgi_webdav_multistatus_close(ub)) goto end;
        uwsgi_response_write_body_do(wsgi_req, ub->buf, ub->pos);

end:
	uwsgi_buffer_destroy(ub);
}
Ejemplo n.º 12
0
Archivo: rados.c Proyecto: Nikolo/uwsgi
static int uwsgi_rados_put(struct wsgi_request *wsgi_req, rados_ioctx_t ctx, char *key, size_t buffer_size, int timeout) {
	struct uwsgi_rados_io *urio = &urados.urio[wsgi_req->async_id];
	size_t remains = wsgi_req->post_cl;
	uint64_t off = 0;
	int ret;
	const char* method;
	int truncate = remains == 0;
#ifdef HAS_RADOS_POOL_REQUIRES_ALIGNMENT2
	if (!truncate && !rados_ioctx_pool_requires_alignment2(ctx, &ret) && ret) {
		uint64_t alignment;
		if (rados_ioctx_pool_required_alignment2(ctx, &alignment)) {
			/* ignore error here */
		} else
#else
	if (!truncate && rados_ioctx_pool_requires_alignment(ctx)) {
		uint64_t alignment = rados_ioctx_pool_required_alignment(ctx);
#endif
		if (buffer_size <= alignment) {
			buffer_size = alignment;
		} else if (buffer_size <= alignment * 2) {
			buffer_size = alignment * 2;
		} else if (alignment) {
			buffer_size -= buffer_size % alignment;
		}
	}
        while(truncate || remains > 0) {
                ssize_t body_len = 0;
                char *body = "\x00";
		if (!truncate) {
			body = uwsgi_request_body_read(wsgi_req, UMIN(remains, buffer_size) , &body_len);
			if (!body || body == uwsgi.empty) goto error;
		} else {
			truncate = 0;
		}
		if (uwsgi.async < 1) {
			if (off == 0) {
				ret = rados_write_full(ctx, key, body, body_len);
				method = "rados_write_full()";
			} else {
				ret = rados_write(ctx, key, body, body_len, off);
				method = "rados_write()";
			}
			if (ret < 0) {
				uwsgi_log("uwsgi_rados_put():%s() %s\n", method, strerror(-ret));
				return -1;
			}
		}
		else {
			// increase request counter
        		pthread_mutex_lock(&urio->mutex);
        		urio->rid++;
        		pthread_mutex_unlock(&urio->mutex);

			struct uwsgi_rados_cb *urcb = uwsgi_malloc(sizeof(struct uwsgi_rados_cb));
        		// map the current request id to the callback
        		urcb->rid = urio->rid;
        		// map urio to the callback
        		urcb->urio = urio;

        		rados_completion_t comp;
			// use safe for write
        		if (rados_aio_create_completion(urcb, NULL, uwsgi_rados_read_async_cb, &comp) < 0) {
                		free(urcb);
                		goto error;
        		}
			if (off == 0) {
				ret = rados_aio_write_full(ctx, key, comp, body, body_len);
				method = "rados_aio_write_full";
			} else {
				ret = rados_aio_write(ctx, key, comp, body, body_len, off);
				method = "rados_aio_write";
			}
			if (ret < 0) {
				uwsgi_log("uwsgi_rados_put():%s() %s\n", method, strerror(-ret));
				free(urcb);
				rados_aio_release(comp);
				goto error;
			}

        		// wait for the callback to be executed
        		if (uwsgi.wait_read_hook(urio->fds[0], timeout) <= 0) {
                		rados_aio_release(comp);
                		goto error;
        		}
        		char ack = 1;
        		if (read(urio->fds[0], &ack, 1) != 1) {
                		rados_aio_release(comp);
                		uwsgi_error("uwsgi_rados_read_async()/read()");
                		goto error;
        		}

        		if (rados_aio_is_safe_and_cb(comp)) {
				ret = rados_aio_get_return_value(comp);
				if (ret < 0) {
					uwsgi_log("uwsgi_rados_put():%s() %s\n", method, strerror(-ret));
                			rados_aio_release(comp);
					goto error;
				}
				
        		}
        		rados_aio_release(comp);
		}
		remains -= body_len;
		off += body_len;
        }	

	return 0;

error:
	return -1;
}

// async stat
static int uwsgi_rados_async_stat(struct uwsgi_rados_io *urio, rados_ioctx_t ctx, const char *key, uint64_t *stat_size, time_t *stat_mtime, int timeout) {
	int ret = -1;
        // increase request counter
        pthread_mutex_lock(&urio->mutex);
        urio->rid++;
        pthread_mutex_unlock(&urio->mutex);

	struct uwsgi_rados_cb *urcb = uwsgi_malloc(sizeof(struct uwsgi_rados_cb));
        // map the current request id to the callback
        urcb->rid = urio->rid;
        // map urio to the callback
        urcb->urio = urio;

	rados_completion_t comp;
	if (rados_aio_create_completion(urcb, uwsgi_rados_read_async_cb, NULL, &comp) < 0) {
        	free(urcb);
		goto end;
	}
	if (rados_aio_stat(ctx, key, comp, stat_size, stat_mtime) < 0) {
		free(urcb);
                rados_aio_release(comp);
		goto end;
	}	

	// wait for the callback to be executed
        if (uwsgi.wait_read_hook(urio->fds[0], timeout) <= 0) {
        	rados_aio_release(comp);
		goto end;
        }
        char ack = 1;
        if (read(urio->fds[0], &ack, 1) != 1) {
        	rados_aio_release(comp);
                uwsgi_error("uwsgi_rados_read_async()/read()");
		goto end;
        }

	if (rados_aio_is_complete_and_cb(comp)) {
        	ret = rados_aio_get_return_value(comp);
        }
        rados_aio_release(comp);

end:
	return ret;
}
Ejemplo n.º 13
0
static int uwsgi_cgi_run(struct wsgi_request *wsgi_req, char *docroot, size_t docroot_len, char *full_path, char *helper, char *path_info, char *script_name, int is_a_file, int discard_base) {

	int cgi_pipe[2];
	int post_pipe[2];
	int nargs = 0;
	int waitpid_status;
	int i;
	char **argv;

	char *command = full_path;

	if (is_a_file) {
                command = docroot;
        }

	if (pipe(cgi_pipe)) {
		uwsgi_error("uwsgi_cgi_run()/pipe()");
		return UWSGI_OK;
	}

	if (pipe(post_pipe)) {
		close(cgi_pipe[0]);
		close(cgi_pipe[1]);
		uwsgi_error("uwsgi_cgi_run()/pipe()");
		return UWSGI_OK;
	}

	pid_t cgi_pid = fork();

	if (cgi_pid < 0) {
		uwsgi_error("uwsgi_cgi_run()/fork()");
		close(cgi_pipe[0]);
		close(cgi_pipe[1]);
		close(post_pipe[0]);
		close(post_pipe[1]);
		return UWSGI_OK;
	}

	if (cgi_pid > 0) {

		close(cgi_pipe[1]);
		close(post_pipe[0]);

		uwsgi_socket_nb(cgi_pipe[0]);
		uwsgi_socket_nb(post_pipe[1]);

		// ok start sending post data...
		size_t remains = wsgi_req->post_cl;
		while(remains > 0) {
                	ssize_t rlen = 0;
                	char *buf = uwsgi_request_body_read(wsgi_req, 8192, &rlen);
                	if (!buf) {
				goto clear2;
                	}
                	if (buf == uwsgi.empty) break;
                	// write data to the node
                	if (uwsgi_write_true_nb(post_pipe[1], buf, rlen, uc.timeout)) {
				goto clear2;
                	}
                	remains -= rlen;
        	}

		// wait for data
		char *buf = uwsgi_malloc(uc.buffer_size);

		int completed = uwsgi_cgi_parse(wsgi_req, cgi_pipe[0], buf, uc.buffer_size);
		if (completed < 0) {
			uwsgi_log("invalid CGI response !!!\n");
			kill_on_error
			goto clear;
		}