(* $Id: webdav_xml.mli 1 2011-08-26 21:00:39Z gerd $ *) (** Parsing and printing XML for WebDAV messages *) open Webdav_http (** {2 Properties} *) type property = 'node Pxp_document.extension Pxp_document.node as 'node (** A property is an XML tree. It is required that the XML tree is namespace-aware. For trees passed in to this module, the DTD object can be arbitrary. The character encoding must be UTF-8 ([`Enc_utf8]). The root node of the property tree must be an XML element. Namespace processing is done as in PXP, i.e. namespace prefixes are normalized. For checking that a property has a certain name, one should either: - use the pair [(localname, namespace_uri)] as compound name - define prefixes in the namespace manager for the expected namespace URIs, and use the normalized name (the argument of [T_element]) Example for the first method (assumed [p] is a [property]): {[ p#localname = "notes" && p#namespace_uri = "http://www.w3.org/1999/xhtml" ]} Example for the second method: {[ let m = namespace_manager() m # add_namespace "h" "http://www.w3.org/1999/xhtml"; let r = parse_multistatus_body ~namespace_manager:m ... let p = List.hd ((List.hd r) # propstat) (* p : property *) match p # node_type with | T_element "h:notes" -> true | _ -> false ]} The values of the properties are also normalized in this way, and must be handled accordingly. There is no guarantee that the prefixes are presented in the same way as they come from the server. *) val create_propname : ?namespace_manager:Pxp_dtd.namespace_manager -> string -> property (** Creates a property element without children. This element can be used in PROPFIND queries as property name The passed string must have the form "prefix:localname", and the prefix must be declared in the namespace manager. The default namespace manager only defines the prefix "DAV". Example: {[ create_propname "DAV:creationdate" ]} *) val propname_creationdate : property val propname_displayname : property val propname_getcontentlanguage : property val propname_getcontentlength : property val propname_getcontenttype : property val propname_getetag : property val propname_getlastmodified : property val propname_resourcetype : property (** Standard WebDAV properties *) val decode_string : property -> string (** Returns the included string from any property *) val decode_creationdate : property -> float val decode_displayname : property -> string val decode_getcontentlanguage : property -> string val decode_getcontentlength : property -> int64 val decode_getcontenttype : property -> string * (string * string) list val decode_getetag : property -> Nethttp.etag val decode_getlastmodified : property -> float val decode_resourcetype : property -> bool (** Decodes standard WebDAV properties *) val encode_string : string -> string -> property (** [encode_string name value]: Creates a property with [name] that includes the [value] as string *) val encode_creationdate : float -> property val encode_displayname : string -> property val encode_getcontentlanguage : string -> property val encode_getcontentlength : int64 -> property val encode_getcontenttype : string * (string * string) list -> property val encode_getetag : Nethttp.etag -> property val encode_getlastmodified : float -> property val encode_resourcetype : bool -> property (** Encodes standard WebDAV properties *) (** {2 Precondition/postcondition elements} *) type prepost_code = 'node Pxp_document.extension Pxp_document.node as 'node (** A precondition/postcondition element. Works in the same way as [property]. *) type known_prepost_code = [ `No_external_entities | `Preserved_live_properties | `Propfind_finite_depth | `Cannot_modify_protected_property ] (** The precondition/postcondition codes this implementation understands *) val create_prepost_code : ?namespace_manager:Pxp_dtd.namespace_manager -> string -> prepost_code (** Creates a pre/postcondition code without children. Content, if any, can be added to the returned XML node. The passed string must have the form "prefix:localname", and the prefix must be declared in the namespace manager. The default namespace manager only defines the prefix "DAV". Example: {[ create_propname "DAV:no-external-entities" ]} *) val parse_prepost_code : prepost_code -> known_prepost_code (** Checks whether the pre/postcondition code is known and returns the code. Raise [Not_found] if unknown *) val emit_prepost_code : known_prepost_code -> prepost_code (** reverse *) (** {2 General XML stuff} *) val namespace_manager : unit -> Pxp_dtd.namespace_manager (** The namespace manager used by XML trees that are returned from this module. Defines the prefixes: - ["DAV"]: This is the prefix for WebDAV requests *) val check_dtd : Pxp_dtd.dtd -> unit (** Checks whether the DTD satisfies the minimum requirements: - The encoding is UTF-8 - There are no element, attribute, or notation declarations - Checking such declarations is turned off - All entities are internal - The namespace manager defines "DAV". *) val dtd : unit -> Pxp_dtd.dtd (** The DTD used by XML trees that are returned from this module. This DTD can also be used for trees generated by the user. *) (** {2 URLs} *) val url_path : ?strip_prefix:string -> string -> string (** Extracts the URL path from a URL. Parsing is error-tolerant to some extent. It is checked, however, whether the resulting string is UTF-8. *) (** {2 Support for [propstat]} *) (** Same as {!Webdav_client_methods.propstat_t} *) class type propstat_t = object method properties : property list method status : webdav_status method status_code : int method status_text : string method status_protocol : string method error : prepost_code list method responsedescription : string end val create_propstat : properties:property list -> status:webdav_status -> ?status_code:int -> ?status_text:string -> ?status_protocol:string -> ?error:prepost_code list -> ?responsedescription:string -> unit -> propstat_t (** Creates a [propstat_t]. - The [status_code] method will return the code corresponding to the [status] argument unless the [status_code] argument overrides it - The [status_text] method will return the text corresponding to the [status] argument unless the [status_text] argument overrides it - The [status_protocol] method will return {!Webdav_http.webdav_proto} unless the [status_protocol] argument overrides it *) (** {2 Support for [response]} *) (** Same as {!Webdav_client_methods.response_t} *) class type response_t = object method href : string list method paths : string list method status : webdav_status method status_code : int method status_text : string method status_protocol : string method propstat : propstat_t list method prop_creationdate : float option method prop_displayname : string option method prop_getcontentlanguage : string option method prop_getcontentlength : int64 option method prop_getcontenttype : string option method prop_getcontenttype_decoded : (string * (string * string) list) option method prop_getetag : string option method prop_getetag_decoded : Nethttp.etag option method prop_getlastmodified : float option method prop_resourcetype_is_collection : bool option method find_prop : string -> property * propstat_t method error : prepost_code list method responsedescription : string method location : string option end val create_status_response : href:string list -> status:webdav_status -> ?status_code:int -> ?status_text:string -> ?status_protocol:string -> ?error:prepost_code list -> ?responsedescription:string -> ?location:string -> ?strip_prefix:string -> unit -> response_t (** Creates the kind of [response_t] that includes a [status] element, but no [propstat] elements. In the returned object, the [propstat] method returns the empty list. The [href] list must contain at least one element. [status], [status_code], [status_text], and [status_protocol] are handled as in {!Webdav_xml.create_propstat}. If [strip_prefix] is passed, this prefix is removed from all paths that are returned via the [paths] method. *) val create_propstat_response : href:string -> propstat:propstat_t list -> ?error:prepost_code list -> ?responsedescription:string -> ?location:string -> ?strip_prefix:string -> unit -> response_t (** Create the kind of [response_t] that includes [propstat] elements but no [status] element. In the returned object, the [status] method returns [`Ok]. The [propstat] list must contain at least one element. If [strip_prefix] is passed, this prefix is removed from the single path returned via the [paths] method. *) (** {2 Support for [multistatus]} *) class type multistatus_t = object method responses : response_t list method responsedescription : string end val create_multistatus : responses:response_t list -> ?responsedescription:string -> unit -> multistatus_t val parse_multistatus_body : ?strip_prefix:string -> ?namespace_manager:Pxp_dtd.namespace_manager -> content_type:string -> Netchannels.in_obj_channel -> multistatus_t (** Parses the body of a [`Multi_status] response. It is required to pass the [content_type] from the HTTP header (for extracting the character encoding). Optionally, one can pass an initialized namespace manager. This is useful to enforce that certain XML prefixes are used for the expected namespaces. It is expected that the prefix "DAV" is bound to the namespace URI "DAV:". There is no guarantee that the display prefixes are preserved. [strip_prefix]: If passed, this path prefix is removed from the paths returned by the [paths] method. Also, it is considered an error if a path is found not within this prefix. *) val write_multistatus_body : ?namespace_manager:Pxp_dtd.namespace_manager -> Netchannels.out_obj_channel -> multistatus_t -> unit (** Outputs this multistatus response object to the output channel. The character encoding is always UTF-8. *) (** {2 Support for [PROPFIND]} *) (** Same as {!Webdav_client_methods.propfind_request} *) type propfind_request = [ `Prop of property list | `Propname | `Allprop of property list ] val parse_propfind_request : ?namespace_manager:Pxp_dtd.namespace_manager -> content_type:string -> Netchannels.in_obj_channel -> propfind_request (** Parses the body of a [propfind] request body. See also {!Webdav_xml.parse_multistatus_body} for the meaning of [namespace_manager] and [content_type]. *) val write_propfind_request : ?namespace_manager:Pxp_dtd.namespace_manager -> Netchannels.out_obj_channel -> propfind_request -> unit (** Writes the XML request for the PROPFIND method. The request will always be UTF-8-encoded. The passed properties (i.e. XML trees) can use any DTD and any namespace manager. In the generated XML text namespace prefixes are preserved (the prefix as returned by the [display_prefix] method of the property nodes). *) (** {2 Support for [PROPPATCH]} *) (** Same as {!Webdav_client_methods.proppatch_instruction} *) type proppatch_instruction = [ `Remove of property list | `Set of property list ] (** Same as {!Webdav_client_methods.proppatch_request} *) type proppatch_request = proppatch_instruction list val parse_proppatch_request : ?namespace_manager:Pxp_dtd.namespace_manager -> content_type:string -> Netchannels.in_obj_channel -> proppatch_request (** Parses the body of a [proppatch] request body. See also {!Webdav_xml.parse_multistatus_body} for the meaning of [namespace_manager] and [content_type]. *) val write_proppatch_request : ?namespace_manager:Pxp_dtd.namespace_manager -> Netchannels.out_obj_channel -> proppatch_request -> unit (** Writes the XML request for the PROPPATCH method. The request will always be UTF-8-encoded. The passed properties (i.e. XML trees) can use any DTD and any namespace manager. In the generated XML text namespace prefixes are preserved (the prefix as returned by the [display_prefix] method of the property nodes). *)