예제 #1
0
static dav_error *
__build_chunk_full_path(const dav_resource *resource, char **full_path)
{
	
	const request_rec *r = resource->info->request;
	dav_rawx_server_conf *conf = request_get_server_config(r);

	if(strlen(r->uri) < 65)
		return server_create_and_stat_error(request_get_server_config(r), r->pool,
				HTTP_BAD_REQUEST, 0, apr_pstrcat(r->pool, "Cannot parse request uri ", r->uri, NULL));
	char *p = NULL;

	uint i_p = 1;
	uint i_uri = 1;
		
	p = apr_palloc(r->pool, (65 + 1 + (conf->hash_depth * conf->hash_width) + conf->hash_depth));

	p[0] = '/';

	for (int i = 0; i < conf->hash_depth ; i++) {
		for (int j = 0; j < conf->hash_width ; j++)
			p[i_p++] = r->uri[i_uri++];
		p[i_p++] = '/';
	}
		
	memcpy(p + i_p, r->uri + 1, 64);
	i_p += 64;
	p[i_p] = '\0';

	*full_path = apr_pstrcat(r->pool, conf->docroot, p, NULL);

	return NULL;
}
예제 #2
0
static dav_error *
_load_request_info(const dav_resource *resource, char **full_path, struct storage_policy_s **sp)
{
	dav_error *e = NULL;
	const request_rec *r = resource->info->request;

	/* configure full path */
	e = __build_chunk_full_path(resource, full_path);
	if (NULL != e)
		return e;

	DAV_DEBUG_REQ(r, 0, "Chunk path build from request: %s", *full_path);
	
	/* init loaded storage policy */
	const char *pol_name = apr_table_get(r->headers_in, "storage-policy");
	if (!pol_name) {
		return server_create_and_stat_error(request_get_server_config(r), r->pool,
				HTTP_BAD_REQUEST, 0, "No storage-policy specified");
	}
	DAV_DEBUG_REQ(r, 0, "Policy found in request: %s", pol_name);

	dav_rawx_server_conf *conf = resource_get_server_config(resource);

	*sp = storage_policy_init(conf->rawx_conf->ni, pol_name);
	apr_pool_cleanup_register(r->pool, *sp, apr_storage_policy_clean, apr_pool_cleanup_null);

	return NULL;
}
예제 #3
0
static dav_error *
_update_chunk_storage(const dav_resource *resource, const char *path, const struct data_treatments_s *dt, GHashTable *comp_opt)
{
	GError *e = NULL;
	dav_error *de = NULL;
	const char *c = NULL;
	const request_rec *r = resource->info->request;
	c = g_hash_table_lookup(comp_opt, NS_COMPRESSION_OPTION);
	if(NULL != c && 0 == g_ascii_strcasecmp(c, NS_COMPRESSION_ON)) {
		DAV_DEBUG_REQ(r, 0, "In place chunk is compressed, uncompress it");
		if(1 != uncompress_chunk(path, TRUE, &e)) {
			de = server_create_and_stat_error(request_get_server_config(r),
					r->pool, HTTP_INTERNAL_SERVER_ERROR, 0,
					apr_pstrcat(r->pool, "Failed to uncompress chunk : ",
					((NULL != e)? e->message : "No error specified"), NULL));
			if(NULL != e)
				g_clear_error(&e);
			return de;
		}
		DAV_DEBUG_REQ(r, 0, "Chunk uncompressed");
	}

	if(COMPRESSION == data_treatments_get_type(dt)) {
		DAV_DEBUG_REQ(r, 0, "Re compressing chunk");
		const char *algo = data_treatments_get_param(dt, DT_KEY_ALGO);
		const char *bs = data_treatments_get_param(dt, DT_KEY_BLOCKSIZE);
		if(!algo || !bs) {
			return server_create_and_stat_error(request_get_server_config(r),
					r->pool, HTTP_INTERNAL_SERVER_ERROR, 0,
					apr_pstrcat(r->pool, "Cannot compress chunk, missing info: ",
						algo, "|", bs, NULL));
		}

		if(1 != compress_chunk(path, algo, g_ascii_strtoll(bs, NULL, 10), TRUE, &e)) {
			de = server_create_and_stat_error(request_get_server_config(r),
					r->pool, HTTP_INTERNAL_SERVER_ERROR, 0,
					apr_pstrcat(r->pool, "Failed to compress chunk : ",
						((NULL != e)? e->message : "No error specified"), NULL));
			if(NULL != e)
				g_clear_error(&e);
			return de;
		}
	}

	return NULL;
}
예제 #4
0
dav_error *
dav_rainx_info_get_resource(request_rec *r, const char *root_dir, const char *label,
	int use_checked_in, dav_resource **result_resource)
{
	(void) root_dir;
	(void) label;
	(void) use_checked_in;

	DAV_XDEBUG_REQ(r, 0, "%s(...)", __FUNCTION__);
	*result_resource = NULL;

	if (r->method_number != M_GET)
		return server_create_and_stat_error(request_get_server_config(r), r->pool,
				HTTP_BAD_REQUEST, 0, apr_pstrdup(r->pool, "Invalid request method, only GET"));

	*result_resource = __build_req_resource(r, &dav_hooks_repository_rainxinfo, __gen_info);
	(*result_resource)->info->type = INFO;
	return NULL;
}
예제 #5
0
static dav_resource*
__get_chunkupdate_resource(const request_rec *r, const dav_hooks_repository *hooks)
{
	dav_resource *resource;

	DAV_XDEBUG_REQ(r, 0, "%s(...)", __FUNCTION__);
	
	resource = apr_pcalloc(r->pool, sizeof(*resource));
	resource->type = DAV_RESOURCE_TYPE_PRIVATE;
	resource->hooks = hooks;
	resource->pool = r->pool;
	resource->exists = 1;
	resource->collection = 0;

	resource->info = apr_pcalloc(r->pool, sizeof(struct dav_resource_private));
	resource->info->pool = r->pool;
	resource->info->conf = request_get_server_config(r);
	resource->info->request = r;

	return resource;
}
예제 #6
0
dav_rawx_server_conf*
resource_get_server_config(const dav_resource *resource)
{
	return request_get_server_config(resource->info->request);
}
예제 #7
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;
}