Exemplo n.º 1
0
static dav_error *
dav_rawx_get_resource(request_rec *r, const char *root_dir, const char *label,
	int use_checked_in, dav_resource **result_resource)
{
	(void) use_checked_in;
	*result_resource = NULL;

	dav_rawx_server_conf *conf = request_get_server_config(r);

	/* Check if client allowed to work with us */
	if (conf->enabled_acl) {
#if MODULE_MAGIC_COOKIE == 0x41503234UL /* "AP24" */
		if (!authorized_personal_only(r->connection->client_ip, conf->rawx_conf->acl))
#else
		if (!authorized_personal_only(r->connection->remote_ip, conf->rawx_conf->acl))
#endif
		{
			return server_create_and_stat_error(conf, r->pool,
					HTTP_UNAUTHORIZED, 0, "Permission Denied (APO)");
		}
	}

	/* Create private resource context descriptor */
	dav_resource_private ctx = {0};
	ctx.pool = r->pool;
	ctx.request = r;

	dav_error *e = rawx_repo_check_request(r, root_dir, label, use_checked_in,
			&ctx, result_resource);
	/* Return in case we have an error or
	 * if result_resource != null because it was an info request */
	if (e || *result_resource) {
		return e;
	}

	/* Build the hashed path */
	if (conf->hash_width <= 0 || conf->hash_depth <= 0) {
		apr_snprintf(ctx.dirname, sizeof(ctx.dirname),
			"%.*s", (int)sizeof(conf->docroot), conf->docroot);
	} else {
		e = rawx_repo_configure_hash_dir(r, &ctx);
		if ( NULL != e) {
			return e;
		}
	}
	DAV_DEBUG_REQ(r, 0, "Hashed directory: %.*s", (int)sizeof(ctx.dirname), ctx.dirname);

	/* All the checks on the URL have passed, now build a resource */
	dav_resource *resource = apr_pcalloc(r->pool, sizeof(*resource));
	resource->type = DAV_RESOURCE_TYPE_REGULAR;
	resource->info = apr_pcalloc(r->pool, sizeof(ctx));;
	memcpy(resource->info, &ctx, sizeof(ctx));
	resource->hooks = &dav_hooks_repository_rawx;
	resource->pool = r->pool;
	memset(&(resource->info->comp_ctx), 0, sizeof(struct compression_ctx_s));

	resource->info->fullpath = apr_pstrcat(resource->pool,
		resource->info->dirname, resource->info->hex_chunkid,
		resource->info->file_extension,
		NULL);

	/* init compression context structure if we are in get method */
	if (r->method_number == M_GET && !ctx.update_only) {
		resource_init_decompression(resource, conf);
	}

	/* Check the chunk's existence */
	int flags = (r->method_number == M_GET ||
			r->method_number == M_OPTIONS ||
			r->method_number == M_DELETE)?
				 RESOURCE_STAT_CHUNK_READ_ATTRS : 0;
	if (r->method_number == M_PUT || r->method_number == M_POST)
		flags |= RESOURCE_STAT_CHUNK_PENDING;

	resource_stat_chunk(resource, flags);

	if (r->method_number == M_PUT || r->method_number == M_POST ||
			r->method_number == M_MOVE ||
			(r->method_number == M_GET && ctx.update_only)) {
		request_load_chunk_info_from_headers(r, &(resource->info->chunk));
		const char *missing = check_chunk_info(&resource->info->chunk);
		if (missing != NULL) {
			return server_create_and_stat_error(request_get_server_config(r), r->pool,
				HTTP_BAD_REQUEST, 0, apr_pstrcat(r->pool, "missing or invalid header ", missing, NULL));
		}
	}

	if (r->method_number == M_POST || r->method_number == M_PUT) {
		if (resource->info->chunk.chunk_id) {
			if (0 != apr_strnatcasecmp(resource->info->chunk.chunk_id, resource->info->hex_chunkid))
				return server_create_and_stat_error(request_get_server_config(r), r->pool,
						HTTP_BAD_REQUEST, 0, "chunk-id mismatch");
		}
		if (resource->exists)
			return server_create_and_stat_error(request_get_server_config(r), r->pool,
				HTTP_CONFLICT, 0, "Resource busy or already exists");
		request_parse_query(r, resource);
	}

	*result_resource = resource;
	return NULL;
}
Exemplo n.º 2
0
request_cgi_env_t * request_init_cgi_env(void) {

	request_cgi_env_t *env;
	const gchar *e;

	env = g_malloc0(sizeof(request_cgi_env_t));
	if (env == NULL) {
		DEBUG_PRINT("Out of memory (env)");
		return NULL;
	}

	/* get hostname and port */
	e = g_getenv("HTTP_HOST");
	if (e == NULL) {
		DEBUG_PRINT("No hostname given");
		request_free_cgi_env(env);
		return NULL;
	}
	env->hostname = g_strdup(e);
	if (env->hostname == NULL) {
		DEBUG_PRINT("Out of memory for HTTP_HOST");
		request_free_cgi_env(env);
		return NULL;
	}
	e = g_getenv("SERVER_PORT");
	if (e == NULL) {
		env->port=80;
	} else {
		env->port = (unsigned int)strtoul(e, NULL, 10);

		/* XXX fix up... port 0 is mostly reserved */
		if (env->port==0) env->port=80;
	}

	/* get resow root path */
	e = g_getenv("SCRIPT_NAME");
	if (e == NULL) {
		DEBUG_PRINT("SCRIPT_NAME (base path) not set");
		request_free_cgi_env(env);
		return NULL;
	}
	env->resow_root = g_strdup(e);
	if (env->resow_root == NULL) {
		DEBUG_PRINT("Out of memory for SCRIPT_NAME");
		request_free_cgi_env(env);
		return NULL;
	}

	/* determine request method */
	e = g_getenv("REQUEST_METHOD");
	if (e == NULL) {
		DEBUG_PRINT("No request method");
		request_free_cgi_env(env);
		return NULL;
	}

	env->method = 0;
	if (!g_ascii_strcasecmp(e, "GET")) env->method = HTTP_METHOD_GET;
	else if (!g_ascii_strcasecmp(e, "POST")) env->method = HTTP_METHOD_POST;
	else if (!g_ascii_strcasecmp(e, "PUT")) env->method = HTTP_METHOD_PUT;
	else if (!g_ascii_strcasecmp(e, "DELETE"))
		env->method = HTTP_METHOD_DELETE;
	else {
		DEBUG_PRINT("Unknown HTTP method");
		request_free_cgi_env(env);
		return NULL;
	}

	/* store full request */
	e = g_getenv("REQUEST_URI");
	if (e == NULL) {
		DEBUG_PRINT("Unknown REQUEST_URI not set");
		request_free_cgi_env(env);
		return NULL;
	}
	env->uri = g_strdup(e);
	if (env->uri == NULL) {
		DEBUG_PRINT("Out of memory for REQUEST_URI");
		request_free_cgi_env(env);
		return NULL;
	}
	
	/* store path part */
	e = g_getenv("PATH_INFO");
	if (e == NULL) e="";
	env->path_part = g_strdup(e);
	if (env->path_part == NULL) {
		DEBUG_PRINT("Out of memory for PATH_INFO");
		request_free_cgi_env(env);
		return NULL;
	}

	/* calc uri path */
	if (http_request_get_uri_path(env)!=0) {
		DEBUG_PRINT("Out of memory for uri path");
		request_free_cgi_env(env);
		return NULL;
	}
	
	/* store parameters into a hash structure */
	e = g_getenv("QUERY_STRING");
	if (e == NULL) e="";
	env->query_parameters = g_hash_table_new_full
		(g_str_hash, g_str_equal, g_free, g_free);
	if (env->query_parameters == NULL) {
		DEBUG_PRINT("Out of memory for QUERY_STRING");
		request_free_cgi_env(env);
		return NULL;
	}
	if (request_parse_query(e, env->query_parameters)!=0) {
		DEBUG_PRINT("Out of memory for QUERY_STRING in parser");
		request_free_cgi_env(env);
		return NULL;
	}

	/* parse HTTP_ACCEPT header */
	e = g_getenv("HTTP_ACCEPT");
	if (e == NULL) e="";
	env->accept_datatype = request_parse_accepts_properties(e, "*/*");
	if (env->accept_datatype == NULL) {
		DEBUG_PRINT("request_parse_accepts_properties on HTTP_ACCEPT returned NULL");
		request_free_cgi_env(env);
		return NULL;
	}

	/* parse HTTP_ACCEPT_LANGUAGE header */
	e = g_getenv("HTTP_ACCEPT_LANGUAGE");
	if (e == NULL) e="";
	env->accept_language = request_parse_accepts_properties(e, "en");
	if (env->accept_language == NULL) {
		DEBUG_PRINT("request_parse_accepts_properties on HTTP_ACCEPT_LANGUAGE returned NULL");
		request_free_cgi_env(env);
		return NULL;
	}

	/* parse HTTP_ACCEPT_ENCODING header */
	e = g_getenv("HTTP_ACCEPT_ENCODING");
	if (e == NULL) e="";
	env->accept_encoding = request_parse_accepts_properties(e, NULL);

	/* content length */
	e = g_getenv("CONTENT_LENGTH");
	if (e!=NULL) {
		env->content_length=strtoul(e, NULL, 10);
	} else env->content_length=0;
	/*
fprintf(stderr, "CL: %li\n", env->content_length);
fprintf(stderr, "R: (%u) %s\n", env->method, env->uri);
system("env > /tmp/env");
*/

	e = g_getenv("CONTENT_TYPE");
	if (e != NULL) {
		env->content_type=g_strdup(e);
		if (strcmp(e,"application/x-www-form-urlencoded")==0) {
			/* parse form data */
			gchar *formdata;

			formdata=request_get_form_data(env->content_length);
			if (formdata == NULL) {
				DEBUG_PRINT("Out of memory for form data");
				request_free_cgi_env(env);
				return NULL;
			}
			env->form_parameters = g_hash_table_new_full
				(g_str_hash, g_str_equal, g_free, g_free);
			if (env->form_parameters == NULL) {
				DEBUG_PRINT("Out of memory for form");
				g_free(formdata);
				request_free_cgi_env(env);
				return NULL;
			}
			if (request_parse_query(formdata,
				env->form_parameters)!=0) {
				DEBUG_PRINT("Out of memory for parsing form");
				g_free(formdata);
				request_free_cgi_env(env);
				return NULL;
			}
			env->content_length=0; /* clear; nothing more to read */
			g_free(formdata);
		} else env->form_parameters=NULL;
	} else {
		env->content_type=NULL;
		env->form_parameters=NULL;
	}

	if ((e = g_getenv("HTTP_IF_NONE_MATCH"))!=NULL) {
		env->if_none_match=g_strdup(e);
	}
	if ((e = g_getenv("HTTP_IF_MATCH"))!=NULL) {
		env->if_match=g_strdup(e);
	}

	return env;
}