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.
154
2004/03/03
16
:
25
:
24
grubba
Exp $
+
// $Id: module.pike,v 1.
155
2004/03/03
17
:
36
:
06
mast
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:468:
//"DAV:isstructureddocument", // draft-hopmann-collection-props-00 1.7 //"DAV:isroot", // MS uses this. >); } return res; } //! Returns the value of the specified property, or an error code //! mapping. //!
+
//! The default implementation takes care of the most important RFC
+
//! 2518 properties.
+
//!
//! @param st //! If set, this should be the stat that corresponds to @[path]. Its //! only purpose is to save a call to @[stat_file] when the stat //! already has been retrieved. //! //! @note //! Returning a string is shorthand for returning an array //! with a single text node. string|array(Parser.XML.Tree.Node)|mapping(string:mixed) query_property(string path, string prop_name, RequestID id, void|Stat st) { if (!st) { st = stat_file(path, id); if (!st)
-
return Roxen.http_
low_answer
(
404
, "No such file or directory.");
+
return Roxen.http_
status (Protocols.HTTP.HTTP
_
NOT_FOUND
,
+
"No such file or directory.");
} switch(prop_name) { case "DAV:creationdate": // RFC2518 13.1 int t = st->ctime; if (t > st->atime) t = st->atime; if (t > st->mtime) t = st->mtime; return Roxen.iso8601_date_time(t); // MS kludge. case "DAV:displayname": // RFC2518 13.2 return combine_path(query_location(), path); case "DAV:getcontentlanguage":// RFC2518 13.3
Roxen.git/server/base_server/module.pike:590:
break; } #ifdef DAV_DEBUG report_debug("query_property(): Unimplemented property:%O\n", prop_name); #endif /* DAV_DEBUG */ // RFC 2518 8.1: // A request to retrieve the value of a property which does not // exist is an error and MUST be noted, if the response uses a // multistatus XML element, with a response XML element which // contains a 404 (Not Found) status value.
-
return Roxen.http_
low_answer
(
404
, "No such property.");
+
return Roxen.http_
status (Protocols.HTTP.HTTP
_
NOT_FOUND
, "No such property.");
} //! Attempt to set property @[prop_name] for @[path] to @[value]. //! //! @param value //! Value to set the node to. //! The case of an array of a single text node is special cased, //! and is sent as a @expr{string@}. //! //! @param context
Roxen.git/server/base_server/module.pike:637:
RequestID id, mixed context) { switch(prop_name) { case "http://apache.org/dav/props/executable": // FIXME: Could probably be implemented R/W. // FALL_THROUGH case "DAV:displayname": // 13.2 case "DAV:getcontentlength": // 13.4 case "DAV:getcontenttype": // 13.5 case "DAV:getlastmodified": // 13.7
-
return Roxen.http_
low_answer
(
409
,
+
return Roxen.http_
status (Protocols.HTTP.HTTP
_
CONFLICT
,
"Attempt to set read-only property."); } return set_dead_property(path, prop_name, value, id, context); } //! Attempt to set dead property @[prop_name] for @[path] to @[value]. //! //! @param context //! The value returned by @[patch_property_start()]. //!
Roxen.git/server/base_server/module.pike:674:
//! @note //! RFC 2518: Dead Property - A property whose semantics and syntax //! are not enforced by the server. The server only records the //! value of a dead property; the client is responsible for //! maintaining the consistency of the syntax and semantics of a //! dead property. mapping(string:mixed) set_dead_property(string path, string prop_name, array(Parser.XML.Tree.Node) value, RequestID id, mixed context) {
-
return Roxen.http_
low_answer
(
405
,
+
return Roxen.http_
status (Protocols.HTTP.HTTP
_
METHOD_INVALID
,
"Setting of dead properties is not supported."); } //! Attempt to remove the property @[prop_name] for @[path]. //! //! @param context //! The value returned by @[patch_property_start()]. //! //! @note //! Actual removal of the property should be done first
Roxen.git/server/base_server/module.pike:702:
//! The default implementation does not support deletion. mapping(string:mixed) remove_property(string path, string prop_name, RequestID id, mixed context) { switch(prop_name) { case "http://apache.org/dav/props/executable": case "DAV:displayname": // 13.2 case "DAV:getcontentlength": // 13.4 case "DAV:getcontenttype": // 13.5 case "DAV:getlastmodified": // 13.7
-
return Roxen.http_
low_answer
(
409
,
+
return Roxen.http_
status (Protocols.HTTP.HTTP
_
CONFLICT
,
"Attempt to remove a read-only property."); } // RFC 2518 12.13.1: // Specifying the removal of a property that does not exist // is not an error. return 0; }
-
//!
Default
implementation
of
some
RFC
2518
properties
.
+
//!
RFC
2518 PROPFIND
implementation
for
a
single
resource
(i
.
e. not
+
//! recursive).
//! //! @param path //! @[query_location()]-relative path. //! @param mode
-
//! Query
-
mode. Currently one of
+
//! Query
mode. Currently one of
//! @string mode //! @value "DAV:propname"
-
//! Query
after
names of supported properties.
+
//! Query names of supported properties.
//! @value "DAV:allprop"
-
//! Query
after
all properties and their values.
+
//! Query all properties and their values.
//! @value "DAV:prop"
-
//! Query
after
properties specified by @[filt] and
-
//!
their values.
+
//! Query properties specified by @[filt] and their values.
//! @endstring //! @param result //! Result object. //! @param id //! Id of the current request. //! @param filt //! Optional multiset of requested properties. If this parameter //! is @expr{0@} (zero) then all available properties are requested. //! @param st //! If set, this should be the stat that corresponds to @[path]. Its
Roxen.git/server/base_server/module.pike:775:
foreach(indices(filt), string prop_name) { result->add_property(path, prop_name, query_property(path, prop_name, id, st)); } return 0; } // FIXME: Unsupported DAV operation. return 0; }
+
//! RFC 2518 PROPFIND implementation with recursion according to
+
//! @[depth]. See @[find_properties] for details.
void recurse_find_properties(string path, string mode, int depth, MultiStatus result, RequestID id, multiset(string)|void filt, void|Stat st) { if (!st) { st = stat_file(path, id); if (!st) { return; } } mapping(string:mixed) ret = find_properties(path, mode, result, id, filt, st); if (ret) { result->add_response(path, XMLStatusNode(ret->error));
-
+
if (ret->rettext) {
+
Parser.XML.Tree.ElementNode descr =
+
Parser.XML.Tree.ElementNode ("DAV:responsedescription", ([]));
+
descr->add_child (Parser.XML.Tree.TextNode (ret->rettext));
+
result->add_response (path, descr);
+
}
return; } if ((depth <= 0) || !st->isdir) return; depth--; foreach(find_dir(path, id) || ({}), string filename) { recurse_find_properties(combine_path(path, filename), mode, depth, result, id, filt); } return; }
Roxen.git/server/base_server/module.pike:869:
int any_failed; foreach(results, mapping(string:mixed) answer) { if (any_failed = (answer && (answer->error >= 300))) { break; } } if (any_failed) { // Unroll and fail any succeeded items. int i; mapping(string:mixed) answer =
-
Roxen.http_
low_answer
(
424
, "Failed dependency.");
+
Roxen.http_
status (Protocols.HTTP.DAV
_
FAILED_DEP
, "Failed dependency.");
for(i = 0; i < sizeof(results); i++) { if (!results[i] || results[i]->error < 300) { result->add_property(path, instructions[i]->property_name, answer); } else { result->add_property(path, instructions[i]->property_name, results[i]); } } patch_property_unroll(path, id, context);
Roxen.git/server/base_server/module.pike:930:
patch_property_unroll (path, id, context); else patch_property_commit (path, id, context); return result; } mapping copy_file(string path, string dest, int(-1..1) behavior, RequestID id) { werror("copy_file(%O, %O, %O, %O)\n", path, dest, behavior, id);
-
return Roxen.http_
low_answer(501,
"Not implemented
.
"
);
+
return Roxen.http_
status
(
Protocols
.
HTTP.HTTP_NOT_IMPL
);
} void recurse_copy_files(string path, int depth, string dest_prefix, string dest_suffix, mapping(string:int(-1..1)) behavior, MultiStatus result, RequestID id) { Stat st = stat_file(path, id); if (!st) return; if (!dest_prefix) {