Esempio n. 1
0
int uwsgi_go_request(struct wsgi_request *wsgi_req) {
	/* Standard GO request */
        if (!wsgi_req->uh.pktsize) {
                uwsgi_log("Invalid GO request. skip.\n");
                return -1;
        }

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

	wsgi_req->async_environ = uwsgi_go_helper_env_new_c(wsgi_req);
	int i;
	for(i=0;i<wsgi_req->var_cnt;i++) {
        	uwsgi_go_helper_env_add_c(wsgi_req->async_environ, wsgi_req->hvec[i].iov_base, wsgi_req->hvec[i].iov_len, 
					wsgi_req->hvec[i+1].iov_base, wsgi_req->hvec[i+1].iov_len);
		i++;
	}


	uwsgi_go_helper_request_c(wsgi_req->async_environ, wsgi_req);

	return UWSGI_OK;
}
Esempio n. 2
0
static int uwsgi_glusterfs_request(struct wsgi_request *wsgi_req) {
	char filename[PATH_MAX+1];
	/* Standard GlusterFS request */
        if (!wsgi_req->uh->pktsize) {
                uwsgi_log( "Empty GlusterFS request. skip.\n");
                return -1;
        }

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

	// blocks empty paths
	if (wsgi_req->path_info_len == 0 || wsgi_req->path_info_len > PATH_MAX) {
                uwsgi_403(wsgi_req);
                return UWSGI_OK;
	}

        wsgi_req->app_id = uwsgi_get_app_id(wsgi_req, wsgi_req->appid, wsgi_req->appid_len, glusterfs_plugin.modifier1);
	if (wsgi_req->app_id == -1 && !uwsgi.no_default_app && uwsgi.default_app > -1) {
        	if (uwsgi_apps[uwsgi.default_app].modifier1 == glusterfs_plugin.modifier1) {
                	wsgi_req->app_id = uwsgi.default_app;
                }
        }
        if (wsgi_req->app_id == -1) {
                uwsgi_404(wsgi_req);
                return UWSGI_OK;
        }

        struct uwsgi_app *ua = &uwsgi_apps[wsgi_req->app_id];

	memcpy(filename, wsgi_req->path_info, wsgi_req->path_info_len);
	filename[wsgi_req->path_info_len] = 0;

	glfs_fd_t *fd = glfs_open((glfs_t *) ua->interpreter, filename, O_RDONLY);
	if (!fd) {
                uwsgi_404(wsgi_req);
                return UWSGI_OK;
	}
	

	struct stat st;
	if (glfs_fstat(fd, &st)) {
		uwsgi_403(wsgi_req);
                return UWSGI_OK;
	}	

	if (uwsgi_response_prepare_headers(wsgi_req, "200 OK", 6)) goto end;
	size_t mime_type_len = 0;
        char *mime_type = uwsgi_get_mime_type(wsgi_req->path_info, wsgi_req->path_info_len, &mime_type_len);
        if (mime_type) {
        	if (uwsgi_response_add_content_type(wsgi_req, mime_type, mime_type_len)) goto end;
        }

        if (uwsgi_response_add_last_modified(wsgi_req, (uint64_t) st.st_mtime)) goto end;
	if (uwsgi_response_add_content_length(wsgi_req, st.st_size)) goto end;

	// skip body on HEAD
	if (uwsgi_strncmp(wsgi_req->method, wsgi_req->method_len, "HEAD", 4)) {
		size_t remains = st.st_size;
		while(remains > 0) {
			char buf[8192];
			ssize_t rlen = glfs_read (fd, buf, UMIN(remains, 8192), 0);
			if (rlen <= 0) goto end;
			if (uwsgi_response_write_body_do(wsgi_req, buf, rlen)) goto end;
			remains -= rlen;
		}
	}

end:
	glfs_close(fd);
	return UWSGI_OK;
}
Esempio n. 3
0
File: webdav.c Progetto: 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;
}
Esempio n. 4
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;
}
Esempio n. 5
0
static int uwsgi_ssh_request(struct wsgi_request *wsgi_req) {


#if !defined(UWSGI_PLUGIN_API) || UWSGI_PLUGIN_API == 1
	if (!wsgi_req->uh->pktsize)
#else
	if (!wsgi_req->len)
#endif
	{
		uwsgi_log("[SSH] skipping empty request.\n");
		return -1;
	}

	if (uwsgi_parse_vars(wsgi_req)) {
		uwsgi_error("uwsgi_ssh_request()/uwsgi_parse_vars()");
		return -1;
	}

	if (wsgi_req->path_info_len == 0 ||
		wsgi_req->path_info_len > PATH_MAX ||
		wsgi_req->path_info[wsgi_req->path_info_len - 1] == '/') {
		uwsgi_403(wsgi_req);
		return UWSGI_OK;
	}

	wsgi_req->app_id = uwsgi_get_app_id(wsgi_req, wsgi_req->appid, wsgi_req->appid_len, libssh2_plugin.modifier1);

	if (wsgi_req->app_id == -1 && !uwsgi.no_default_app && uwsgi.default_app > -1) {
		if (uwsgi_apps[uwsgi.default_app].modifier1 == libssh2_plugin.modifier1) {
			wsgi_req->app_id = uwsgi.default_app;
		}
	}

	if (wsgi_req->app_id == -1) {
		uwsgi_404(wsgi_req);
		return UWSGI_OK;
	}

	struct uwsgi_app *ua = &uwsgi_apps[wsgi_req->app_id];
	struct uwsgi_ssh_mountpoint *usm_list = (struct uwsgi_ssh_mountpoint *) ua->callable;

	char *complete_filepath = NULL;
	char *filepath = NULL;

	if (wsgi_req->path_info_len > ua->mountpoint_len &&
		memcmp(wsgi_req->path_info, ua->mountpoint, ua->mountpoint_len) == 0) {

		filepath = uwsgi_strncopy(
			wsgi_req->path_info + ua->mountpoint_len,
			wsgi_req->path_info_len - ua->mountpoint_len
		);

	} else {
		filepath = uwsgi_strncopy(wsgi_req->path_info, wsgi_req->path_info_len);
	}

	complete_filepath = uwsgi_concat2(usm_list->path, filepath);
	free(filepath);

	int return_status = 500;
	struct uwsgi_ssh_mountpoint *usm = usm_list;

	do {
		return_status = uwsgi_ssh_request_file(
			wsgi_req,
			complete_filepath,
			usm
		);

	} while (return_status == 500 && ((usm = usm->next) != NULL));

	free(complete_filepath);

	switch (return_status) {
		case 404:
			uwsgi_404(wsgi_req);
			break;

		case 500:
		default:
			uwsgi_500(wsgi_req);
	}

	return 0;
}
Esempio n. 6
0
File: rados.c Progetto: Nikolo/uwsgi
static int uwsgi_rados_request(struct wsgi_request *wsgi_req) {
	char filename[PATH_MAX+1];
	if (!wsgi_req->len) {
		uwsgi_log( "Empty request. skip.\n");
		return -1;
	}

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

	// blocks empty paths
	if (wsgi_req->path_info_len == 0 || wsgi_req->path_info_len > PATH_MAX) {
		uwsgi_403(wsgi_req);
		return UWSGI_OK;
	}

	wsgi_req->app_id = uwsgi_get_app_id(wsgi_req, wsgi_req->appid, wsgi_req->appid_len, rados_plugin.modifier1);
	if (wsgi_req->app_id == -1 && !uwsgi.no_default_app && uwsgi.default_app > -1) {
		if (uwsgi_apps[uwsgi.default_app].modifier1 == rados_plugin.modifier1) {
			wsgi_req->app_id = uwsgi.default_app;
		}
	}
	if (wsgi_req->app_id == -1) {
		uwsgi_404(wsgi_req);
		return UWSGI_OK;
	}

	struct uwsgi_app *ua = &uwsgi_apps[wsgi_req->app_id];

	if (wsgi_req->path_info_len > ua->mountpoint_len &&
		memcmp(wsgi_req->path_info, ua->mountpoint, ua->mountpoint_len) == 0) {

		memcpy(filename, wsgi_req->path_info+ua->mountpoint_len, wsgi_req->path_info_len-ua->mountpoint_len);
		filename[wsgi_req->path_info_len-ua->mountpoint_len] = 0;

	} else {
		memcpy(filename, wsgi_req->path_info, wsgi_req->path_info_len);
		filename[wsgi_req->path_info_len] = 0;
	}
	
	// in multithread mode the memory is different (as we need a ctx for each thread) !!!
	rados_ioctx_t ctx;
	if (uwsgi.threads > 1) {
		rados_ioctx_t *ctxes = (rados_ioctx_t *) ua->responder0;
		ctx = ctxes[wsgi_req->async_id];
	}
	else {
		ctx = (rados_ioctx_t) ua->responder0;
	}
	struct uwsgi_rados_mountpoint *urmp = (struct uwsgi_rados_mountpoint *) ua->responder1;
	uint64_t stat_size = 0;
	time_t stat_mtime = 0;

	struct uwsgi_rados_io *urio = &urados.urio[wsgi_req->async_id];

	if (uwsgi.async > 0) {
	// no need to lock here (the rid protect us)
        	if (pipe(urio->fds)) {
                	uwsgi_error("uwsgi_rados_read_async()/pipe()");
			uwsgi_500(wsgi_req);
			return UWSGI_OK;
        	}
	}
	
	int ret = -1;
	int timeout = urmp->timeout ? urmp->timeout : urados.timeout;

	if (!uwsgi_strncmp(wsgi_req->method, wsgi_req->method_len, "OPTIONS", 7)) {
		if (uwsgi_response_prepare_headers(wsgi_req, "200 OK", 6)) goto end;
		if (uwsgi_response_add_header(wsgi_req, "Dav", 3, "1", 1)) goto end;	
		struct uwsgi_buffer *ub_allow = uwsgi_buffer_new(64);
		if (uwsgi_buffer_append(ub_allow, "OPTIONS, GET, HEAD", 18)) {
			uwsgi_buffer_destroy(ub_allow);
			goto end;
		}
		if (urmp->allow_put) {
			if (uwsgi_buffer_append(ub_allow, ", PUT", 5)) {
				uwsgi_buffer_destroy(ub_allow);
				goto end;
			}
		}
		if (urmp->allow_delete) {
			if (uwsgi_buffer_append(ub_allow, ", DELETE", 8)) {
				uwsgi_buffer_destroy(ub_allow);
				goto end;
			}
		}
		if (urmp->allow_mkcol) {
			if (uwsgi_buffer_append(ub_allow, ", MKCOL", 7)) {
				uwsgi_buffer_destroy(ub_allow);
				goto end;
			}
		}
		if (urmp->allow_propfind) {
			if (uwsgi_buffer_append(ub_allow, ", PROPFIND", 10)) {
				uwsgi_buffer_destroy(ub_allow);
				goto end;
			}
		}

		uwsgi_response_add_header(wsgi_req, "Allow", 5, ub_allow->buf, ub_allow->pos);
		uwsgi_buffer_destroy(ub_allow);
                goto end;
	}

	// empty paths are mapped to propfind
	if (wsgi_req->path_info_len == 1 && wsgi_req->path_info[0] == '/') {
		if (urmp->allow_propfind && !uwsgi_strncmp(wsgi_req->method, wsgi_req->method_len, "PROPFIND", 8)) {
			uwsgi_rados_propfind(wsgi_req, ctx, NULL, 0, 0, timeout);
			goto end;
		}
                uwsgi_405(wsgi_req);
		goto end;
	}

	// MKCOL does not require stat
	if (!uwsgi_strncmp(wsgi_req->method, wsgi_req->method_len, "MKCOL", 5)) {
                if (!urmp->allow_mkcol) {
                        uwsgi_405(wsgi_req);
                        goto end;
                }
                ret = rados_pool_create(urmp->cluster, filename);
		if (ret < 0) {
			if (ret == -EEXIST) {
                        	uwsgi_405(wsgi_req);
			}
			else {
                        	uwsgi_500(wsgi_req);
			}
                        goto end;
                }
                uwsgi_response_prepare_headers(wsgi_req, "201 Created", 11);
                goto end;
	}

	if (uwsgi.async > 0) {
		ret = uwsgi_rados_async_stat(urio, ctx, filename, &stat_size, &stat_mtime, timeout);	
	}
	else {
		ret = rados_stat(ctx, filename, &stat_size, &stat_mtime);
	}

	// PUT AND MKCOL can be used for non-existent objects
	if (!uwsgi_strncmp(wsgi_req->method, wsgi_req->method_len, "PUT", 3)) {
		if (!urmp->allow_put) {
			uwsgi_405(wsgi_req);
			goto end;
		}
		if (ret == 0) {
			if (uwsgi_rados_delete(wsgi_req, ctx, filename, timeout)) {
				uwsgi_500(wsgi_req);
				goto end;
			}
		}	
		if (uwsgi_rados_put(wsgi_req, ctx, filename, urmp->put_buffer_size, timeout)) {
			uwsgi_500(wsgi_req);
			goto end;
		}
		uwsgi_response_prepare_headers(wsgi_req, "201 Created", 11);	
		goto end;
	}
	else if (ret < 0) {
		if (ret == -ENOENT)
			uwsgi_404(wsgi_req);
		else
			uwsgi_403(wsgi_req);
		goto end;
	}

	if (!uwsgi_strncmp(wsgi_req->method, wsgi_req->method_len, "DELETE", 6)) {
		if (!urmp->allow_delete) {
			uwsgi_405(wsgi_req);
                        goto end;
		}
		if (uwsgi_rados_delete(wsgi_req, ctx, filename, timeout)) {
			uwsgi_403(wsgi_req);
                        goto end;
		}
		uwsgi_response_prepare_headers(wsgi_req, "200 OK", 6);
		goto end;
	}

	if (!uwsgi_strncmp(wsgi_req->method, wsgi_req->method_len, "PROPFIND", 8)) {
		if (!urmp->allow_propfind) {
			uwsgi_405(wsgi_req);
                        goto end;
		}
		uwsgi_rados_propfind(wsgi_req, ctx, filename, stat_size, stat_mtime, timeout);
		goto end;
	}

	if (uwsgi_strncmp(wsgi_req->method, wsgi_req->method_len, "HEAD", 4) && uwsgi_strncmp(wsgi_req->method, wsgi_req->method_len, "GET", 3)) {
		uwsgi_405(wsgi_req);
		goto end;
	}

	uint64_t offset = 0;
	uint64_t remains = stat_size;
	uwsgi_request_fix_range_for_size(wsgi_req, remains);
	switch (wsgi_req->range_parsed) {
		case UWSGI_RANGE_INVALID:
			if (uwsgi_response_prepare_headers(wsgi_req,
						"416 Requested Range Not Satisfiable", 35))
				goto end;
			if (uwsgi_response_add_content_range(wsgi_req, -1, -1, stat_size))
				goto end;
			return 0;
		case UWSGI_RANGE_VALID:
			offset = wsgi_req->range_from;
			remains = wsgi_req->range_to - wsgi_req->range_from + 1;
			if (uwsgi_response_prepare_headers(wsgi_req, "206 Partial Content", 19))
				goto end;
			break;
		default: /* UWSGI_RANGE_NOT_PARSED */
			if (uwsgi_response_prepare_headers(wsgi_req, "200 OK", 6)) return -1;
	}

	size_t mime_type_len = 0;
	char *mime_type = uwsgi_get_mime_type(wsgi_req->path_info, wsgi_req->path_info_len, &mime_type_len);
	if (mime_type) {
		if (uwsgi_response_add_content_type(wsgi_req, mime_type, mime_type_len)) goto end;
	}

	if (uwsgi_response_add_last_modified(wsgi_req, (uint64_t) stat_mtime)) goto end;
        // set Content-Length to actual result size
	if (uwsgi_response_add_content_length(wsgi_req, remains)) goto end;
        if (wsgi_req->range_parsed == UWSGI_RANGE_VALID) {
                // here use the original size !!!
                if (uwsgi_response_add_content_range(wsgi_req, wsgi_req->range_from, wsgi_req->range_to, stat_size))
                        goto end;
        }

	// skip body on HEAD
	if (uwsgi_strncmp(wsgi_req->method, wsgi_req->method_len, "HEAD", 4)) {
		if (uwsgi.async > 0) {
			if (uwsgi_rados_read_async(wsgi_req, ctx, filename, offset, remains, urmp->buffer_size, timeout)) goto end;
		}
		else {
			if (uwsgi_rados_read_sync(wsgi_req, ctx, filename, offset, remains, urmp->buffer_size)) goto end;
		}
	}

end:
	if (uwsgi.async > 0) {
		close(urio->fds[0]);
		close(urio->fds[1]);
	}
	return UWSGI_OK;
}
Esempio n. 7
0
static int uwsgi_lua_request(struct wsgi_request *wsgi_req) {

	int i;
	const char *http, *http2;
	size_t slen, slen2;
	char *ptrbuf;
	lua_State *L = ulua.L[wsgi_req->async_id];

	if (wsgi_req->async_status == UWSGI_AGAIN) {
		if ((i = lua_pcall(L, 0, 1, 0)) == 0) {
			if (lua_type(L, -1) == LUA_TSTRING) {
				http = lua_tolstring(L, -1, &slen);
				uwsgi_response_write_body_do(wsgi_req, (char *)http, slen);
			}
			lua_pop(L, 1);
			lua_pushvalue(L, -1);
			return UWSGI_AGAIN;
		}
		goto clear;
	}

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

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

	// put function in the stack
	//lua_getfield(L, LUA_GLOBALSINDEX, "run");
	lua_pushvalue(L, -1);

	// put cgi vars in the stack

	lua_newtable(L);
	lua_pushstring(L, "");
	lua_setfield(L, -2, "CONTENT_TYPE");
	for(i=0;i<wsgi_req->var_cnt;i++) {
		lua_pushlstring(L, (char *)wsgi_req->hvec[i+1].iov_base, wsgi_req->hvec[i+1].iov_len);
		// transform it in a valid c string TODO this is ugly
		ptrbuf = wsgi_req->hvec[i].iov_base+wsgi_req->hvec[i].iov_len;
		*ptrbuf = 0;
		lua_setfield(L, -2, (char *)wsgi_req->hvec[i].iov_base);
		i++;
	}


	// put "input" table
	lua_newtable(L);
	lua_pushcfunction(L, uwsgi_lua_input);
	lua_setfield(L, -2, "read");
	lua_setfield(L, -2, "input");

#ifdef UWSGI_DEBUG
	uwsgi_log("stack pos %d\n", lua_gettop(L));
#endif

	// call function
	i = lua_pcall(L, 1, 3, 0);
	if (i != 0) {
		uwsgi_log("%s\n", lua_tostring(L, -1));
		lua_pop(L, 1);
                lua_pushvalue(L, -1);
		goto clear;
	}

	//uwsgi_log("%d %s %s %s\n",i,lua_typename(L, lua_type(L, -3)), lua_typename(L, lua_type(L, -2)) ,  lua_typename(L, lua_type(L, -1)));

	// send status
	if (lua_type(L, -3) == LUA_TSTRING || lua_type(L, -3) == LUA_TNUMBER) {
		http = lua_tolstring(L, -3, &slen);
		uwsgi_response_prepare_headers(wsgi_req, (char *) http, slen);
	}
	else {
		uwsgi_log("[uwsgi-lua] invalid response status !!!\n");
		// let's continue 
	}

	// send headers

	lua_pushnil(L);
	while(lua_next(L, -3) != 0) {
		http = lua_tolstring(L, -2, &slen);
		http2 = lua_tolstring(L, -1, &slen2);
		uwsgi_response_add_header(wsgi_req, (char *) http, slen, (char *) http2, slen2);
		lua_pop(L, 1);
	}

	// send body with coroutine
	lua_pushvalue(L, -1);

	while ( (i = lua_pcall(L, 0, 1, 0)) == 0) {
		if (lua_type(L, -1) == LUA_TSTRING) {
			http = lua_tolstring(L, -1, &slen);
			uwsgi_response_write_body_do(wsgi_req, (char *)http, slen);
		}
		lua_pop(L, 1);
		lua_pushvalue(L, -1);
		if (uwsgi.async > 1) {
			return UWSGI_AGAIN;
		}
	}

clear:
	lua_pop(L, 4);
	// set frequency
	lua_gc(L, LUA_GCCOLLECT, 0);

	return UWSGI_OK;

}
Esempio n. 8
0
static int uwsgi_cgi_request(struct wsgi_request *wsgi_req) {

	char full_path[PATH_MAX];
	char tmp_path[PATH_MAX];
	struct stat cgi_stat;
	int need_free = 0;
	int is_a_file = 0;
	int discard_base = 0;
	size_t docroot_len = 0;
	size_t full_path_len = 0;
	char *helper = NULL;
	char *path_info = NULL;
	char *script_name = NULL;

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


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

	char *docroot = NULL;

	// check for file availability (and 'runnability')
	if (uc.from_docroot) {
		docroot = wsgi_req->document_root;	
		docroot_len = wsgi_req->document_root_len;	
	}
	else {
		docroot = uwsgi_cgi_get_docroot(wsgi_req->path_info, wsgi_req->path_info_len, &need_free, &is_a_file, &discard_base, &script_name);
		if (docroot)
			docroot_len = strlen(docroot);
	}

	if (docroot == NULL || docroot_len == 0) {
		uwsgi_404(wsgi_req);
		return UWSGI_OK;
	}

	memcpy(full_path, docroot, docroot_len);

	if (!is_a_file) {

		*(full_path+docroot_len) = '/';
		*(full_path+docroot_len+1) = 0;

		if (uwsgi_cgi_walk(wsgi_req, full_path, docroot, docroot_len, discard_base, &path_info)) {
			if (need_free)
				free(docroot);
			return UWSGI_OK;
		}

		if (realpath(full_path, tmp_path) == NULL) {
			if (need_free)
				free(docroot);
			uwsgi_404(wsgi_req);
			return UWSGI_OK;
		}

		full_path_len = strlen(tmp_path);
		// add +1 to copy the null byte
		memcpy(full_path, tmp_path, full_path_len+1);

		if (uwsgi_starts_with(full_path, full_path_len, docroot, docroot_len)) {
			if (need_free)
				free(docroot);
                	uwsgi_log("CGI security error: %s is not under %s\n", full_path, docroot);
                	return -1;
        	}

	}
	else {
		*(full_path+docroot_len) = 0;
		path_info = wsgi_req->path_info+discard_base;
	}

	if (stat(full_path, &cgi_stat)) {
		uwsgi_404(wsgi_req);
		if (need_free)
			free(docroot);
		return UWSGI_OK;
	}

	if (S_ISDIR(cgi_stat.st_mode)) {

		// add / to directories
		if (wsgi_req->path_info_len == 0 || (wsgi_req->path_info_len > 0 && wsgi_req->path_info[wsgi_req->path_info_len-1] != '/')) {
			uwsgi_redirect_to_slash(wsgi_req);
			if (need_free)
                        	free(docroot);
                	return UWSGI_OK;
		}
		struct uwsgi_string_list *ci = uc.index;
		full_path[full_path_len] = '/';
		full_path_len++;
		int found = 0;
		while(ci) {
			if (full_path_len + ci->len + 1 < PATH_MAX) {
				// add + 1 to ensure null byte
				memcpy(full_path+full_path_len, ci->value, ci->len + 1);
				if (!access(full_path, R_OK)) {
					
					found = 1;
					break;
				}
			}
			ci = ci->next;
		}

		if (!found) {
			uwsgi_404(wsgi_req);
			if (need_free)
				free(docroot);
			return UWSGI_OK;
		}

	}

	full_path_len = strlen(full_path);

	int cgi_allowed = 1;
	struct uwsgi_string_list *allowed = uc.allowed_ext;
	while(allowed) {
		cgi_allowed = 0;
		if (full_path_len >= allowed->len) {
			if (!uwsgi_strncmp(full_path+(full_path_len-allowed->len), allowed->len, allowed->value, allowed->len)) {
				cgi_allowed = 1;
				break;
			}
		}
		allowed = allowed->next;
	}

	if (!cgi_allowed) {
		uwsgi_403(wsgi_req);
		if (need_free)
			free(docroot);
		return UWSGI_OK;
	}

	// get the helper
	if (!is_a_file) {
		helper = uwsgi_cgi_get_helper(full_path);

		if (helper == NULL) {
			if (access(full_path, X_OK)) {
				uwsgi_error("access()");
				uwsgi_403(wsgi_req);
                		if (need_free)
                        		free(docroot);
				return UWSGI_OK;
			}
		}
	}

	int ret = uwsgi_cgi_run(wsgi_req, docroot, docroot_len, full_path, helper, path_info, script_name, is_a_file, discard_base);
	if (need_free) free(docroot);
	return ret;
}
Esempio n. 9
0
File: xslt.c Progetto: AGoodId/uwsgi
static int uwsgi_request_xslt(struct wsgi_request *wsgi_req) {

	char *xmlfile = NULL;
	char *output = NULL;
        int output_rlen = 0;

	char filename[PATH_MAX+1];
	size_t filename_len = 0;
	char stylesheet[PATH_MAX+1];
	size_t stylesheet_len = 0;
	
	char *params = NULL;

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

	// set default values
	if (!uxslt.content_type_len) {
		if (!uxslt.content_type) {
			uxslt.content_type = "text/html";
		}
		uxslt.content_type_len = strlen(uxslt.content_type);
	}

	struct uwsgi_string_list *usl = uxslt.docroot;

	// first check for static docroots
	if (usl) {
		while(usl) {
			xmlfile = uwsgi_concat3n(usl->value, usl->len, "/", 1, wsgi_req->path_info, wsgi_req->path_info_len);
			if (uwsgi_is_file(xmlfile)) {
				break;
			}
			free(xmlfile);
			xmlfile = NULL;
			usl = usl->next;
		}	
	}
	// fallback to DOCUMENT_ROOT
	else {
		if (wsgi_req->document_root_len == 0) {
			uwsgi_403(wsgi_req);
			return UWSGI_OK;
		}

		xmlfile = uwsgi_concat3n(wsgi_req->document_root, wsgi_req->document_root_len, "/", 1, wsgi_req->path_info, wsgi_req->path_info_len);
	}

	if (!xmlfile) {
		uwsgi_404(wsgi_req);
		return UWSGI_OK;
	}

	// we have the full path, check if it is valid
	if (!uwsgi_expand_path(xmlfile, strlen(xmlfile), filename)) {
		free(xmlfile);
		uwsgi_404(wsgi_req);
		return UWSGI_OK;
	}

	free(xmlfile);

	if (!uwsgi_is_file(filename)) {
		uwsgi_403(wsgi_req);
		return UWSGI_OK;
	}
	filename_len = strlen(filename);

	// now search for the xslt file
	
	int found = 0;

	// first check for specific vars
	usl = uxslt.var;
	while(usl) {
		uint16_t rlen;
		char *value = uwsgi_get_var(wsgi_req, usl->value, usl->len, &rlen);
		if (value) {
			memcpy(stylesheet, value, rlen);
			stylesheet[rlen] = 0;
			stylesheet_len = rlen;
			found = 1;
			break;
		}
		usl = usl->next;
	}

	if (found) goto apply;

	// then check for custom extensions
	if (uxslt.ext) {
		usl = uxslt.ext;
		while(usl) {
			char *tmp_path = uwsgi_concat2n(filename, filename_len, usl->value, usl->len);
			if (uwsgi_is_file(tmp_path)) {
				stylesheet_len = filename_len + usl->len;
				memcpy(stylesheet, tmp_path, stylesheet_len);
				stylesheet[stylesheet_len] = 0;
				free(tmp_path);
				found = 1;
				break;
			}
			free(tmp_path);
			usl = usl->next;
		}
	}
	// use default extensions .xsl/.xslt
	else {
		char *tmp_path = uwsgi_concat2n(filename, filename_len, ".xsl", 4);
                if (uwsgi_is_file(tmp_path)) {
                	stylesheet_len = filename_len + 4;
                        memcpy(stylesheet, tmp_path, stylesheet_len);
			stylesheet[stylesheet_len] = 0;
                        free(tmp_path);
			goto apply;	
		}
                free(tmp_path);
		tmp_path = uwsgi_concat2n(filename, filename_len, ".xslt", 5);
                if (uwsgi_is_file(tmp_path)) {
                        stylesheet_len = filename_len + 5;
                        memcpy(stylesheet, tmp_path, stylesheet_len);
			stylesheet[stylesheet_len] = 0;
			found = 1;
                }
                free(tmp_path);
	}

	if (found) goto apply;

	// finally check for static stylesheets
	usl = uxslt.stylesheet;
	while(usl) {
		if (uwsgi_is_file(usl->value)) {
			memcpy(stylesheet, usl->value, usl->len);
			stylesheet_len = usl->len;
			stylesheet[stylesheet_len] = 0;
			found = 1;
			break;
		}
		usl = usl->next;
	}

	if (found) goto apply;
	
	uwsgi_404(wsgi_req);
	return UWSGI_OK;

apply:
	if (wsgi_req->query_string_len > 0) {
		params = uwsgi_concat2n(wsgi_req->query_string, wsgi_req->query_string_len, "", 0);
	}
	// we have both the file and the stylesheet, let's run the engine
	output = uwsgi_xslt_apply(filename, stylesheet, params, &output_rlen);
	if (params) free(params);
	if (!output) {
		uwsgi_500(wsgi_req);
		return UWSGI_OK;
	}

	// prepare headers
	if (uwsgi_response_prepare_headers(wsgi_req, "200 OK", 6)) {
		uwsgi_500(wsgi_req);
		goto end;
	}
	// content_length
	if (uwsgi_response_add_content_length(wsgi_req, output_rlen)) {
		uwsgi_500(wsgi_req);
		goto end;
	}
	// content_type
	if (uwsgi_response_add_content_type(wsgi_req, uxslt.content_type, uxslt.content_type_len)) {
		uwsgi_500(wsgi_req);
		goto end;
	}

	uwsgi_response_write_body_do(wsgi_req, output, output_rlen);

end:
	xmlFree(output);
	return UWSGI_OK;
}
Esempio n. 10
0
static int uwsgi_rados_request(struct wsgi_request *wsgi_req) {
	char filename[PATH_MAX+1];
	if (!wsgi_req->uh->pktsize) {
		uwsgi_log( "Empty request. skip.\n");
		return -1;
	}

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

	// blocks empty paths
	if (wsgi_req->path_info_len == 0 || wsgi_req->path_info_len > PATH_MAX) {
		uwsgi_403(wsgi_req);
		return UWSGI_OK;
	}

	wsgi_req->app_id = uwsgi_get_app_id(wsgi_req, wsgi_req->appid, wsgi_req->appid_len, rados_plugin.modifier1);
	if (wsgi_req->app_id == -1 && !uwsgi.no_default_app && uwsgi.default_app > -1) {
		if (uwsgi_apps[uwsgi.default_app].modifier1 == rados_plugin.modifier1) {
			wsgi_req->app_id = uwsgi.default_app;
		}
	}
	if (wsgi_req->app_id == -1) {
		uwsgi_404(wsgi_req);
		return UWSGI_OK;
	}

	struct uwsgi_app *ua = &uwsgi_apps[wsgi_req->app_id];

	if (wsgi_req->path_info_len > ua->mountpoint_len &&
		memcmp(wsgi_req->path_info, ua->mountpoint, ua->mountpoint_len) == 0) 
	{
		memcpy(filename, wsgi_req->path_info+ua->mountpoint_len, wsgi_req->path_info_len-ua->mountpoint_len);
	} else {
		memcpy(filename, wsgi_req->path_info, wsgi_req->path_info_len);
	}
	filename[wsgi_req->path_info_len] = 0;
	
	struct {
		uint64_t size;
		time_t mtime;
	} st;
	rados_ioctx_t ctx = ua->responder1;
	
	int r = rados_stat(ctx, filename, &st.size, &st.mtime);
	if (r < 0) {
		if (r == -ENOENT)
			uwsgi_404(wsgi_req);
		else
			uwsgi_403(wsgi_req);
		return UWSGI_OK;
	}
	

	if (uwsgi_response_prepare_headers(wsgi_req, "200 OK", 6)) goto end;
	size_t mime_type_len = 0;
	char *mime_type = uwsgi_get_mime_type(wsgi_req->path_info, wsgi_req->path_info_len, &mime_type_len);
	if (mime_type) {
		if (uwsgi_response_add_content_type(wsgi_req, mime_type, mime_type_len)) goto end;
	}

	if (uwsgi_response_add_last_modified(wsgi_req, (uint64_t) st.mtime)) goto end;
	if (uwsgi_response_add_content_length(wsgi_req, st.size)) goto end;

	// skip body on HEAD
	if (uwsgi_strncmp(wsgi_req->method, wsgi_req->method_len, "HEAD", 4)) {
		size_t remains = st.size;
		if (uwsgi.async > 1) {
			if (uwsgi_rados_read_async(wsgi_req, ctx, filename, remains)) goto end;
		}
		else {
			if (uwsgi_rados_read_sync(wsgi_req, ctx, filename, remains)) goto end;
		}
	}

end:
	return UWSGI_OK;
}