Index: openacs-4/packages/xotcl-core/tcl/50-protocol-handler-procs.tcl
===================================================================
RCS file: /usr/local/cvsroot/openacs-4/packages/xotcl-core/tcl/50-protocol-handler-procs.tcl,v
diff -u -r1.7 -r1.8
--- openacs-4/packages/xotcl-core/tcl/50-protocol-handler-procs.tcl 6 Jun 2012 06:48:21 -0000 1.7
+++ openacs-4/packages/xotcl-core/tcl/50-protocol-handler-procs.tcl 29 Jul 2013 08:44:14 -0000 1.8
@@ -27,8 +27,7 @@
# get the second bit, the base64 encoded bit
set up [lindex [split $ah " "] 1]
# after decoding, it should be user:password; get the username
- set user [lindex [split [ns_uudecode $up] ":"] 0]
- set password [lindex [split [ns_uudecode $up] ":"] 1]
+ lassign [split [ns_uudecode $up] ":"] user password
array set auth [auth::authenticate \
-username $user \
-authority_id [::auth::get_register_authority] \
@@ -59,23 +58,25 @@
ProtocolHandler ad_instproc initialize {} {
Setup connection object and authenticate user
} {
- my instvar uri method urlv destination
+ my instvar uri method url urlv destination
ad_conn -reset
# Make sure, there is no ::ad_conn(request); otherwise the
# developer support will add all its output to a single var, which
# can lead easily to running out of resources in busy sites. When
# unset, the developer support will create its own id.
catch {unset ::ad_conn(request)}
set uri [ns_urldecode [ns_conn url]]
+ if {[string length $uri] < [string length $url]} {append uri /}
set url_regexp "^[my url]"
- #my log "--conn_setup: uri '$uri' my url='[my url]' con='[ns_conn url]'"
regsub $url_regexp $uri {} uri
if {![regexp {^[./]} $uri]} {set uri /$uri}
+ #my log "--conn_setup: uri '$uri' my url='[my url]' con='[ns_conn url]'"
my set_user_id
set method [string toupper [ns_conn method]]
#my log "--conn_setup: uri '$uri' method $method"
set urlv [split [string trimright $uri "/"] "/"]
+ my set user_agent [ns_set iget [ns_conn headers] user-agent]
set destination [ns_urldecode [ns_set iget [ns_conn headers] Destination]]
if {$destination ne ""} {
regsub {https?://[^/]+/} $destination {/} dest
@@ -124,6 +125,7 @@
} {
set filter_url [my url]*
set url [my url]/*
+ set root [string trimright [my url] /]
#
# Methods defined by RFC 2086 (19.6.1 Additional Request Methods):
#
@@ -176,11 +178,17 @@
DELETE LOCK UNLOCK OPTIONS
REPORT
} {
- ns_register_filter preauth $method $filter_url [self]
- ns_register_proc $method $url [self] handle_request
+ ns_register_filter preauth $method $filter_url [self]
+ ns_register_filter preauth $method $root [self]
+ ns_register_proc $method $url [self] handle_request
+ ns_register_proc $method $root [self] handle_request
+
+
#my log "--ns_register_filter preauth $method $filter_url [self]"
#my log "--ns_register_proc $method $url [self] handle_request"
}
+ ns_register_proc OPTIONS / ::xo::minimalProctocolHandler OPTIONS
+ ns_register_proc PROPFIND / ::xo::minimalProctocolHandler PROPFIND
}
ProtocolHandler ad_instproc get_package_id {} {
@@ -213,18 +221,121 @@
}
#
+ # Formatting methods
+ #
+ ProtocolHandler instproc tcl_time_to_iso8601 {datetime} {
+ # RFC2518 requires this just for creationdate
+ if {$datetime eq ""} return ""
+ set tcl_time [::xo::db::tcl_date $datetime tz]
+ return [clock format [clock scan $tcl_time] -format "%Y-%m-%dT%H:%M:%SZ" -gmt 1]
+ }
+
+ ProtocolHandler instproc http_date {seconds} {
+ # HTTP-Date as defined in RFC2068#section-3.3.1
+ return "[clock format $seconds -format {%a, %d %b %Y %T} -gmt 1] GMT"
+ }
+
+ ProtocolHandler instproc tcl_time_to_http_date {datetime} {
+ # RFC2518 requires this e.g. for getlastmodified
+ if {$datetime eq ""} return ""
+ return [my http_date [clock scan [::xo::db::tcl_date $datetime tz]]]
+ }
+
+ ProtocolHandler instproc multiStatus {body} {
+ append _ {} \n \
+ {} $body \n \n
+ }
+
+ ProtocolHandler instproc multiStatusResonse {
+ -href:required
+ -propstats:required
+ {-propstatus true}
+ } {
+ #my log "multiStatusResonse href $href propstats $propstats"
+ append reply \n \
+ {} \
+ "\n$href\n"
+ # The multi-status respons has 2 formats
+ # - with (used in PROPFIND and PROPPATCH)
+ # - without (used in other cases, e.g. DELETE, COPY, MOVE for collections)
+ # http://www.webdav.org/specs/rfc4918.html#multi-status.response
+ #
+ foreach {props status} $propstats {
+ if {$propstatus} {
+ append reply \n
+ if {[llength $props] > 0} {
+ append reply \n
+ foreach {name value} $props {
+ if {$value ne ""} {
+ append reply <$name>$value$name>\n
+ } else {
+ append reply <$name/>\n
+ }
+ }
+ append reply \n
+ } else {
+ append reply \n
+ }
+ append reply $status\n\n
+ } else {
+ append reply $status\n
+ }
+ }
+ append reply \n
+ }
+
+ ProtocolHandler instproc multiStatusError {status} {
+ lappend davprops \
+ D:getlastmodified "" \
+ D:getcontentlength "" \
+ D:creationdate "" \
+ D:resourcetype ""
+ set r [my multiStatus [my multiStatusResonse \
+ -href [ns_urldecode [ns_conn url]] \
+ -propstats [list $davprops $status]]]
+ my log multiStatusError=$r
+ ns_return 207 text/xml $r
+ }
+
+ #
# Some dummy HTTP methods
#
ProtocolHandler instproc GET {} {
my log "--GET method"
- ns_return 200 text/plain GET-[my uri]
+ ns_return 200 text/plain GET-[my set uri]
}
ProtocolHandler instproc PUT {} {
my log "--PUT method [ns_conn content]"
ns_return 201 text/plain "received put with content-length [string length [ns_conn content]]"
}
+
+ ProtocolHandler instproc OPTIONS {} {
+ ns_set put [ns_conn outputheaders] Allow OPTIONS
+ ns_return 200 text/plain {}
+ }
+
ProtocolHandler instproc PROPFIND {} {
- my log "--PROPFIND [ns_conn content]"
- ns_return 204 text/xml {}
+ #my log "--ProtocolHandler PROPFIND [ns_conn content]"
+ # when GET is not supported on this resource, the get* properties are not be sent
+ # see http://www.webdav.org/specs/rfc4918.html, 9.1.5
+ lappend davprops \
+ lp1:resourcetype \
+ lp1:creationdate [my tcl_time_to_iso8601 "2013-06-30 01:21:22.648325+02"] \
+ D:supportedlock {} \
+ D:lockdiscovery {}
+
+ ns_return 207 text/xml [my multiStatus \
+ [my multiStatusResonse \
+ -href [my set uri] \
+ -propstats [list $davprops "HTTP/1.1 200 OK"]]]
}
+
+ ::xo::ProtocolHandler create ::xo::minimalProctocolHandler
+ ::xo::minimalProctocolHandler proc OPTIONS {args} {
+ ns_set put [ns_conn outputheaders] Allow OPTIONS
+ ns_return 200 text/plain {}
+ }
+ ::xo::minimalProctocolHandler proc PROPFIND {args} {
+ my multiStatusError "HTTP/1.1 403 Forbidden"
+ }
}
\ No newline at end of file