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; }
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; }