Roxen.git
/
server
/
base_server
/
module.pike
version
»
Context lines:
10
20
40
80
file
none
3
Roxen.git/server/base_server/module.pike:1:
// This file is part of Roxen WebServer. // Copyright © 1996 - 2001, Roxen IS.
-
// $Id: module.pike,v 1.
203
2004/05/
12
20
:
20
:
44
mast
Exp $
+
// $Id: module.pike,v 1.
204
2004/05/
13
13
:
40
:
52
grubba
Exp $
#include <module_constants.h> #include <module.h> #include <request_trace.h> constant __pragma_save_parent__ = 1; inherit "basic_defvar"; mapping(string:array(int)) error_log=([]);
Roxen.git/server/base_server/module.pike:1267:
continue; } string|array(Parser.XML.Tree.SimpleNode)|mapping(string:mixed) dest_val = destination_properties->query_property(property_name); if (dest_val == source_val) { TRACE_LEAVE("Destination already has the correct value."); continue; } mapping(string:mixed) subres = destination_properties->set_property(property_name, source_val);
-
if (behavior
== PROPERTY_OMIT
) {
+
if (
!
behavior) {
TRACE_LEAVE("Omit verify."); continue; }
-
if ((behavior
==
PROPERTY
_
ALIVE
) && (subres->error < 300)) {
+
if ((
intp(
behavior
)
||
behavior[property
_
name]
) && (subres->error < 300)) {
// FIXME: Check that if the property was live in source, // it is still live in destination. // This is likely already so, since we're in the same module. } if ((subres->error < 300) || (subres->error == Protocols.HTTP.HTTP_CONFLICT)) { // Ok, or read-only property. TRACE_LEAVE("Copy ok or read-only property."); continue; }
Roxen.git/server/base_server/module.pike:1375:
return Roxen.http_status(Protocols.HTTP.HTTP_PRECOND_FAILED); } } // Create the new collection. TRACE_LEAVE("Make a new collection."); mapping(string:mixed) res = make_collection(destination, id); if (res && res->error >= 300) return res; return copy_properties(source, destination, behavior, id) || res; }
+
//! Used by the default @[recurse_copy_files] to copy a single file.
mapping(string:mixed) copy_file(string source, string destination, PropertyBehavior behavior, Overwrite overwrite, RequestID id) { SIMPLE_TRACE_ENTER(this, "copy_file(%O, %O, %O, %O, %O)\n", source, destination, behavior, overwrite, id); TRACE_LEAVE("Not implemented."); return Roxen.http_status (Protocols.HTTP.HTTP_NOT_IMPL); } mapping(string:mixed) recurse_copy_files(string source, string destination, int depth,
-
mapping(string:
PropertyBehavior
)
behavior,
+
PropertyBehavior behavior,
Overwrite overwrite, RequestID id) { SIMPLE_TRACE_ENTER(this, "recurse_copy_files(%O, %O, %O, %O, %O)\n", source, destination, depth, behavior, id); string src_tmp = has_suffix(source, "/")?source:(source+"/"); string dst_tmp = has_suffix(destination, "/")?destination:(destination+"/"); if ((src_tmp == dst_tmp) || has_prefix(src_tmp, dst_tmp) || has_prefix(dst_tmp, src_tmp)) { TRACE_LEAVE("Source and destination overlap.");
Roxen.git/server/base_server/module.pike:1415:
// Note: Already got an extra TRACE_ENTER level on entry here. Stat st = stat_file(source, id); if (!st) { TRACE_LEAVE("Source not found."); return 0; /* FIXME: 404? */ } // FIXME: Check destination? if (st->isdir) { mapping(string:mixed) res =
-
copy_collection(source, destination,
-
behavior
[loc+source] || behavior[0]
,
-
overwrite, result, id);
+
copy_collection(source, destination, behavior, overwrite, result, id);
if (res && res->error >= 300) { // RFC 2518 8.8.3 and 8.8.8 (error minimization). TRACE_LEAVE("Copy of collection failed."); return res; } if (depth <= 0) { TRACE_LEAVE("Non-recursive copy of collection done."); return res; } depth--;
Roxen.git/server/base_server/module.pike:1442:
subsrc, subdst, depth); mapping(string:mixed) sub_res = recurse(subsrc, subdst, depth); if (sub_res && (sub_res->error != 204) && (sub_res->error != 201)) { result->add_status(subdst, sub_res->error, sub_res->rettext); } } TRACE_LEAVE(""); return res; } else { TRACE_LEAVE("");
-
return copy_file(source, destination,
-
behavior
[query_location()+source] ||
-
behavior[0]
,
-
overwrite, id);
+
return copy_file(source, destination, behavior, overwrite, id);
} }; int start_ms_size = id->multi_status_size(); mapping(string:mixed) res = recurse (source, destination, depth); if (res && res->error != 204 && res->error != 201) return res; else if (id->multi_status_size() != start_ms_size) return ([]); else return res; }
-
+
//! Move/rename a single file.
+
static mapping(string:mixed) move_file(string source, string destination,
+
PropertyBehavior behavior,
+
Overwrite overwrite, RequestID id)
+
{
+
// Fall back to find_file().
+
RequestID tmp_id = id->clone_me();
+
tmp_id->not_query = query_location() + source;
+
tmp_id->misc["new-uri"] = query_location() + destination;
+
tmp_id->request_headers->destination =
+
id->url_base() + query_location()[1..] + destination;
+
tmp_id->method = "MOVE";
+
mapping(string:mixed) res = find_file(source, tmp_id);
+
if (!res || res->error != 501) return res;
+
// Not implemented. Fall back to COPY + DELETE.
+
res = copy_file(source, destination, behavior, overwrite, id);
+
if (res && res->error >= 300) {
+
// Copy failed.
+
return res;
+
}
+
return delete_file(source, id);
+
}
+
+
//! Move/rename a collection (aka directory) and all it's content.
+
static mapping(string:mixed) move_collection(string source, string destination,
+
PropertyBehavior behavior,
+
Overwrite overwrite, RequestID id)
+
{
+
// Fall back to find_file().
+
RequestID tmp_id = id->clone_me();
+
tmp_id->not_query = query_location() + source;
+
tmp_id->misc["new-uri"] = query_location() + destination;
+
tmp_id->request_headers->destination =
+
id->url_base() + query_location()[1..] + destination;
+
tmp_id->method = "MOVE";
+
mapping(string:mixed) res = find_file(source, tmp_id);
+
if (!res || res->error != 501) return res;
+
// Not implemented. Fall back to COPY + DELETE.
+
MultiStatus.Prefixed result =
+
id->get_multi_status()->prefix (id->url_base() + query_location()[1..]);
+
res = copy_collection(source, destination, behavior, overwrite, result, id);
+
if (res && (res->error >= 300 || !sizeof(res))) {
+
// Copy failed.
+
return res;
+
}
+
int fail;
+
foreach(find_dir(source, id), string filename) {
+
string subsrc = combine_path_unix(source, filename);
+
string subdst = combine_path_unix(destination, filename);
+
SIMPLE_TRACE_ENTER(this, "Recursive move from %O to %O\n",
+
subsrc, subdst);
+
mapping(string:mixed) sub_res =
+
recurse_move_file(subsrc, subdst, behavior, overwrite, id);
+
if (sub_res && (sub_res->error != 204) && (sub_res->error != 201)) {
+
result->add_status(subdst, sub_res->error, sub_res->rettext);
+
if (sub_res->error >= 300) {
+
// Failed to move some content.
+
fail = 1;
+
}
+
}
+
}
+
if (fail) return ([]);
+
return delete_file(source, id);
+
}
+
+
//! Move/rename a file or collection (aka directory).
+
mapping(string:mixed) recurse_move_file(string source, string destination,
+
PropertyBehavior behavior,
+
Overwrite overwrite, RequestID id)
+
{
+
Stat st = stat_file(source, id);
+
if (!st) return 0;
+
+
if (st->isdir) {
+
return move_collection(source, destination, behavior, overwrite, id);
+
}
+
return move_file(source, destination, behavior, overwrite, id);
+
}
+
string real_file(string f, RequestID id){} void add_api_function( string name, function f, void|array(string) types) { _api_functions[name] = ({ f, types }); } mapping api_functions() { return _api_functions;