Index: openacs-4/packages/oacs-dav/tcl/oacs-dav-procs-oracle.xql =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/oacs-dav/tcl/oacs-dav-procs-oracle.xql,v diff -u -N -r1.3.2.4 -r1.3.2.5 --- openacs-4/packages/oacs-dav/tcl/oacs-dav-procs-oracle.xql 18 Apr 2004 15:40:15 -0000 1.3.2.4 +++ openacs-4/packages/oacs-dav/tcl/oacs-dav-procs-oracle.xql 23 Apr 2004 17:22:12 -0000 1.3.2.5 @@ -51,11 +51,12 @@ select ci.item_id, ci.name, - content_item__get_path(ci.item_id,:folder_id) as item_uri, - coalesce(cr.mime_type,'*/*') as mime_type, - cr.content_length, - to_char(o.creation_date, 'YYYY-MM-DD"T"HH:MM:SS.MS"Z"') as creation_date, - to_char(o.last_modified, 'Dy, DD Mon YYYY HH:MM:SS TZ') as last_modified + content_item.get_path(ci.item_id,:folder_id) as item_uri, + nvl(cr.mime_type,'*/*') as mime_type, + nvl(cr.content_length,0) as content_length, + to_char(o.creation_date, 'YYYY-MM-DD"T"HH:MI:SS."000"') as creation_date, + to_char(o.last_modified, 'Dy, Dd Mon YYYY HH:MI:SS "${os_time_zone}"') as last_modified + from cr_items ci, acs_objects o, cr_revisions cr @@ -88,7 +89,7 @@ begin - :1 := content_folder.copy ( + content_folder.copy ( folder_id => :copy_folder_id, target_folder_id => :new_parent_folder_id, creation_user => :user_id, Index: openacs-4/packages/oacs-dav/tcl/oacs-dav-procs.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/oacs-dav/tcl/oacs-dav-procs.tcl,v diff -u -N -r1.4.2.12 -r1.4.2.13 --- openacs-4/packages/oacs-dav/tcl/oacs-dav-procs.tcl 14 Apr 2004 17:40:31 -0000 1.4.2.12 +++ openacs-4/packages/oacs-dav/tcl/oacs-dav-procs.tcl 23 Apr 2004 17:22:12 -0000 1.4.2.13 @@ -1,5 +1,5 @@ # /packages/oacs-dav/tcl/oacs-dav-procs.tcl -ns_log notice "Loading oacs-dav-procs.tcl" +ns_log debug "\nLoading oacs-dav-procs.tcl" ad_library { Support for tDAV tcl webDAV implemenation @@ -12,6 +12,29 @@ namespace eval oacs_dav {} +ad_proc oacs_dav::urlencode { string } { + urlencode allowing characters according to rfc 1738 + http://www.w3.org/Addressing/rfc1738.txt + + "Thus, only alphanumerics, the special characters "$-_.+!*'(),", and + reserved characters used for their reserved purposes may be used + unencoded within a URL." + + ignore + used to encode spaces in query strings + + This is mainly to support MS Web Folders which do not follow the + spec which states that any character may be urlencoded. Web Folders + rejects the entire collection as invalid if a filename contains + one of these characters encoded. + +} { + set encoded_string [ns_urlencode $string] + set encoded_string [string map -nocase \ + {%2d - %5f _ %24 $ %2e . %21 ! %28 ( %29 ) %27 ' %2c ,} $encoded_string] + + return $encoded_string +} + ad_proc oacs_dav::folder_enabled { -folder_id } { @@ -31,16 +54,16 @@ # should be something like "Basic 29234k3j49a" set a [ns_set get [ns_conn headers] Authorization] if {[string length $a]} { - ns_log notice "TDAV auth_check authentication info $a" + ns_log debug "\nTDAV auth_check authentication info $a" # get the second bit, the base64 encoded bit set up [lindex [split $a " "] 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] - ns_log notice "ACS VERSION [ad_acs_version]" + ns_log debug "\nACS VERSION [ad_acs_version]" switch -glob -- [ad_acs_version] { "5.0*" { - ns_log debug "TDAV 5.0 authentication" + ns_log debug "\nTDAV 5.0 authentication" array set auth [auth::authenticate \ -username $user \ -password $password] @@ -49,34 +72,34 @@ -email $user \ -password $password] if {![string equal $auth(auth_status) "ok"]} { - ns_log debug "TDAV 5.0 auth status $auth(auth_status)" + ns_log debug "\nTDAV 5.0 auth status $auth(auth_status)" ns_returnunauthorized return 0 } } - ns_log notice "TDAV: auth_check openacs 5.0 user_id= $auth(user_id)" + ns_log debug "\nTDAV: auth_check openacs 5.0 user_id= $auth(user_id)" ad_conn -set user_id $auth(user_id) return } default { # for 4.6: - ns_log debug "TDAV 4.6 authentication" + ns_log debug "\nTDAV 4.6 authentication" set email [string tolower $user] if {[db_0or1row user_login_user_id_from_email { select user_id, member_state, email_verified_p from cc_users where email = :email}] } { if {[ad_check_password $user_id $password]} { - ns_log notice "TDAV setting user_id $user_id" + ns_log debug "\nTDAV setting user_id $user_id" ad_conn -set user_id $user_id ad_conn -set untrusted_user_id $user_id return } } - ns_log notice "TDAV: openacs user/password not matched" + ns_log debug "\nTDAV: openacs user/password not matched" ns_returnunauthorized return @@ -93,20 +116,20 @@ check is user_id has permission to perform the WebDAV method on the URI } { - ns_log notice "OACS-DAV running oacs_dav::authorize" + ns_log debug "\nOACS-DAV running oacs_dav::authorize" # set common data for all requests oacs_dav::conn_setup set method [string tolower [oacs_dav::conn method]] set item_id [oacs_dav::conn item_id] set user_id [oacs_dav::conn user_id] set folder_id [oacs_dav::conn folder_id] - ns_log notice "OACS-DAV oacs_dav::authorize user_id $user_id method $method item_id $item_id" + ns_log debug "\nOACS-DAV oacs_dav::authorize user_id $user_id method $method item_id $item_id" set authorized_p 0 # if item doesn't exist don't bother checking.... if {[empty_string_p $item_id]} { - if {![string equal $method "put"] && ![string equal $method "mkcol"]} { - ns_log notice "oacs_dav::authorize file not found!!!!!" + if {![string equal "put" $method] && ![string equal "mkcol" $method] && ![string equal "lock" $method]} { + ns_log debug "\noacs_dav::authorize file not found" ns_return 404 text/plain "File Not Found" return filter_return } @@ -125,7 +148,21 @@ -party_id $user_id \ -privilege "delete"] } - lock - + lock { + if {![empty_string_p $item_id]} { + set authorized_p [permission::permission_p \ + -object_id $item_id \ + -party_id $user_id \ + -privilege "write"] + } else { + # if item does not exist yet check for create on + # the collection and create a null lock + set authorized_p [permission::permission_p \ + -object_id $folder_id \ + -party_id $user_id \ + -privilege "create"] + } + } unlock - proppatch { set authorized_p [permission::permission_p \ @@ -240,7 +277,7 @@ @param uri @returns parent_folder_id or empty string if folder does not exist } { - ns_log notice "OACS-DAV:item parent folder_id uri $uri" + array set sn [oacs_dav::request_site_node $uri] set node_id $sn(node_id) set root_folder_id [oacs_dav::request_folder_id $node_id] @@ -250,7 +287,7 @@ } else { set parent_name "/" } - ns_log debug "parent_folder_id urlv $urlv parent_name $parent_name uri $uri" + ns_log debug "\nparent_folder_id urlv $urlv parent_name $parent_name uri $uri" if {[string equal [string trimright $parent_name "/"] [string trimright $sn(url) "/"]]} { # content_item__get_id can't resolve "/" # because it strips the leading and trailing / @@ -276,12 +313,17 @@ } { ad_conn -reset set uri [ns_conn url] + ns_log debug "\nconn_setp uri \"$uri\" " set dav_url_regexp "^[oacs_dav::uri_prefix]" regsub $dav_url_regexp $uri {} uri + if {[empty_string_p $uri]} { + set uri "/" + } oacs_dav::conn -set uri $uri set method [ns_conn method] + ns_log debug "\noacs_dav::conn_setup: uri \"$uri\" method $method" oacs_dav::set_user_id - ns_log debug "oacs_dav::conn_setup: uri $uri method $method user_id [oacs_dav::conn user_id]" + ns_log debug "\noacs_dav::conn_setup: uri \"$uri\" method $method user_id [oacs_dav::conn user_id]" array set sn [oacs_dav::request_site_node $uri] set node_id [oacs_dav::conn -set node_id $sn(node_id)] set package_id [oacs_dav::conn -set package_id $sn(package_id)] @@ -292,7 +334,7 @@ set destination [oacs_dav::conn -set destination [ns_urldecode [ns_set iget [ns_conn headers] Destination]]] } regsub {http://[^/]+/} $destination {/} dest - ns_log debug "oacs_dav::conn_setup destination = $dest" + ns_log debug "\noacs_dav::conn_setup destination = $dest" regsub $dav_url_regexp $dest {} dest oacs_dav::conn -set destination $dest if {![empty_string_p $dest]} { @@ -308,24 +350,24 @@ } else { set parent_url "/" } - ns_log debug "oacs_dav::conn_setup: handle request parent_url $parent_url length urlv [llength $urlv] urlv $urlv" + ns_log debug "\noacs_dav::conn_setup: handle request parent_url $parent_url length urlv [llength $urlv] urlv $urlv" set item_name [lindex $urlv end] if {[empty_string_p $item_name]} { # for propget etc we need the name of the folder # the last element in urlv for a folder is an empty string set item_name [lindex [split [string trimleft $parent_url "/"] "/"] end] } oacs_dav::conn -set item_name $item_name - ns_log debug "oacs_dav::conn_setup: handle request parent_url $parent_url length urlv [llength $urlv] urlv $urlv item_name $item_name" + ns_log debug "\noacs_dav::conn_setup: handle request parent_url $parent_url length urlv [llength $urlv] urlv $urlv item_name $item_name" set parent_id [oacs_dav::item_parent_folder_id $uri] set item_id [oacs_dav::conn -set item_id [db_exec_plsql get_item_id ""]] - ns_log debug "oacs_dav::conn_setup: uri $uri parent_url $parent_url folder_id $folder_id" + ns_log debug "\noacs_dav::conn_setup: uri $uri parent_url $parent_url folder_id $folder_id" if {[string equal [string trimright $uri "/"] [string trimright $sn(url) "/"]]} { set item_id [oacs_dav::conn -set item_id $folder_id] } - ns_log debug "oacs_dav::conn_setup: item_id $item_id" + ns_log debug "\noacs_dav::conn_setup: item_id $item_id" } ad_proc -public oacs_dav::handle_request { uri method args } { @@ -334,16 +376,16 @@ set uri [ns_conn url] set method [string tolower [ns_conn method]] - ns_log debug "oacs_dav::handle_request method=$method uri=$uri" + ns_log debug "\noacs_dav::handle_request method=$method uri=$uri" set item_id [oacs_dav::conn item_id] set folder_id [oacs_dav::conn folder_id] set package_id [oacs_dav::conn package_id] set node_id [oacs_dav::conn node_id] set package_key [apm_package_key_from_id $package_id] - ns_log debug "oacs_dav::handle_request item_id is $item_id" + ns_log debug "\noacs_dav::handle_request item_id is $item_id" if {[empty_string_p $item_id]} { - ns_log debug "oacs_dav::handle_request item_id is empty" + ns_log debug "\noacs_dav::handle_request item_id is empty" # set this to null if nothing exists, only valid on PUT or MKCOL # to create a new item, otherwise we bail # item for URI does not exist @@ -359,10 +401,14 @@ set content_type [acs_sc_call dav_put_type get_type "" $package_key] } + } + lock { + # asssume resource on NULL LOCK + set content_type "content_revision" } default { # return a 404 or other error - ns_log notice "oacs_dav::handle_request: 404 handle request Item not found method $method URI $uri" + ns_log debug "\noacs_dav::handle_request: 404 handle request Item not found method $method URI $uri" ns_return 404 text/html "File Not Found" return } @@ -393,13 +439,13 @@ # probably should catch this - ns_log debug "oacs_dav::handle_request method $method uri $uri item_id $item_id folder_id $folder_id package_id $package_id node_id $node_id content_type $content_type args $args" + ns_log debug "\noacs_dav::handle_request method $method uri $uri item_id $item_id folder_id $folder_id package_id $package_id node_id $node_id content_type $content_type args $args" set response [acs_sc_call dav $method "" $content_type] # here the sc impl might return us some data, # then we would probably have to send that to tDAV for processing - ns_log debug "DAV: response is \"$response\"" + ns_log debug "\nDAV: response is \"$response\"" if {![string equal -nocase "get" $method] && ![string equal -nocase "head" $method]} { @@ -414,10 +460,7 @@ # if you want to serve up DAV content at a different URL # you still need to mount a package in the site-map # might change later when we figure out how to actually use it - ns_log notice "OACS-DAV!! uri $uri" -# if {[empty_string_p $uri]} { -# set uri [ns_conn url] -# } + ns_log debug "\nOACS-DAV!! uri $uri" set sn [site_node::get -url $uri] return $sn } @@ -508,14 +551,14 @@ # check that destination exists and is WebDAV enabled # when depth is 0 copy just the folder # when depth is 1 copy contents -ns_log notice "DAV Folder Copy dest $target_uri parent_id $new_parent_folder_id" + ns_log debug "\nDAV Folder Copy dest $target_uri parent_id $new_parent_folder_id" if {[empty_string_p $new_parent_folder_id]} { return [list 409] } set dest_item_id [db_string get_dest_id "" -default ""] if {![empty_string_p $dest_item_id]} { - ns_log notice "DAV Folder Copy Folder Exists item_id $dest_item_id overwrite $overwrite" + ns_log debug "\n ----- \n DAV Folder Copy Folder Exists item_id $dest_item_id overwrite $overwrite \n ----- \n" if {![string equal -nocase $overwrite "T"]} { return [list 412] } elseif {![permission::permission_p \ @@ -530,14 +573,17 @@ return [list 423] } db_exec_plsql delete_for_copy "" + set response [list 204] + ns_log debug "\n ----- \n CONTENT_FOLDER::COPY OVERWRITING RETURNING 204 \n ----- \n" + } else { + set response [list 201] } - db_transaction { db_exec_plsql copy_folder "" } on_error { return [list 500] } - set response [list 201] + tdav::copy_props $uri $target_uri return $response } @@ -564,9 +610,9 @@ } set dest_item_id [db_string get_dest_id "" -default ""] - ns_log debug "@DAV@@ folder move new_name $new_name dest_id $dest_item_id new_folder_id $new_parent_folder_id" + ns_log debug "\n@DAV@@ folder move new_name $new_name dest_id $dest_item_id new_folder_id $new_parent_folder_id \n" if {![empty_string_p $dest_item_id]} { - ns_log notice "DAV Folder Move Folder Exists item_id $dest_item_id overwrite $overwrite" + if {![string equal -nocase $overwrite "T"]} { return [list 412] } elseif {![permission::permission_p \ @@ -581,10 +627,13 @@ return [list 423] } - db_exec_plsql delete_for_move "" - ns_log debug "CONTEXT IDS [db_list get_ids "select object_id from acs_objects where context_id=:dest_item_id"]" + set response [list 204] + ns_log debug "\n ----- \n CONTENT_FOLDER::MOVE OVERWRITING RETURNING 204 \n ----- \n" + } else { + set response [list 201] } + # don't let anyone move root DAV folders in the # dav_site_node_folder_map if {![string equal [db_string site_node_folder ""] 0]} { @@ -594,13 +643,13 @@ db_transaction { if {![string equal $cur_parent_folder_id $new_parent_folder_id]} { - ns_log debug "@@DAV@@ move folder $move_folder_id" + ns_log debug "\n@@DAV@@ move folder $move_folder_id" db_exec_plsql move_folder "" } elseif {![empty_string_p $new_name]} { - ns_log debug "@@DAV@@ move folder rename $move_folder_id to $new_name" + ns_log debug "\n@@DAV@@ move folder rename $move_folder_id to $new_name" db_exec_plsql rename_folder "" } - set response [list 204] + } on_error { return [list 500] } @@ -625,7 +674,7 @@ if {[catch {db_exec_plsql delete_folder ""} errmsg]} { ns_log error "content_folder::delete $errmsg" set response [list 500] -# ns_log debug "CONTEXT IDS [db_list get_ids "select object_id from acs_objects where context_id=:item_id"]" +# ns_log debug "\nCONTEXT IDS [db_list get_ids "select object_id from acs_objects where context_id=:item_id"]" } else { set response [list 204] tdav::delete_props $uri @@ -642,16 +691,17 @@ set depth [oacs_dav::conn depth] set encoded_uri [list] foreach fragment [split [ad_conn url] "/"] { - lappend encoded_uri [ns_urlencode $fragment] + lappend encoded_uri [oacs_dav::urlencode $fragment] } - # MS Web Folders can't handle encoded . in filenames so decode it - regsub -all {%2e} $encoded_uri {.} encoded_uri + set folder_uri "[ad_url][join $encoded_uri "/"]" - if {![string match */ $folder_uri]} { - append folder_uri "/" - } - + # this is wacky, but MS Web Folders usually (but not always) + # requests a collection without a trailing slash + # if you return a propfind with the href for the collection + # with a trailing slash, sometimes (but not always) it will + # get confused and show the collection as a member of itself + regsub {/$} $folder_uri {} folder_uri if {[empty_string_p $depth]} { set depth 0 } @@ -671,15 +721,16 @@ # is "D" the namespace?? lappend properties [list "D" "getcontentlength"] $content_length - ns_log debug "DAVEB item_id $item_id folder_id $folder_id $item_uri" +# ns_log debug "\nDAVEB item_id $item_id folder_id $folder_id $item_uri" if {$item_id == $folder_id} { - set item_uri "" + set item_uri "/" } else { set encoded_uri [list] foreach fragment [split $item_uri "/"] { - lappend encoded_uri [ns_urlencode $fragment] + lappend encoded_uri [oacs_dav::urlencode $fragment] +# ns_log debug "\npropfind: fragment \"$fragment\" encoded_uri \"$encoded_uri\" " } - set item_uri "[join $encoded_uri "/"]" + set item_uri "/[join $encoded_uri "/"]" } @@ -756,7 +807,7 @@ set ret_code 423 set body "Resource is locked." } else { - ns_log notice "tdav::check_lock_for_unlock = [tdav::check_lock_for_unlock $uri]]" + ns_log debug "\ntdav::check_lock_for_unlock = [tdav::check_lock_for_unlock $uri]]" tdav::remove_lock $uri set ret_code 204 set body "" @@ -825,8 +876,6 @@ return $response } - ns_log debug "oacs_dav::impl::content_revision::put parent_id=$parent_id item_id=$item_id root_folder_id=$root_folder_id name=$name tmp_filename=$tmp_filename" - # create new item if necessary db_transaction { set mime_type [cr_filename_to_mime_type $name] @@ -842,6 +891,14 @@ $tmp_size \ $mime_type \ $name] + + if {[file exists [tdav::get_lock_file $uri]]} { + # if there is a null lock use 204 + set response [list 204] + } else { + set response [list 201] + } + } else { set revision_id [cr_import_content \ -item_id $item_id \ @@ -851,10 +908,10 @@ $tmp_size \ $mime_type \ $name] + set response [list 204] } db_dml set_live_revision "" - set response [list 201] } on_error { set response [list 500] ns_log error "oacs_dav::impl::content_revision::put: $errmsg" @@ -876,6 +933,9 @@ set depth [oacs_dav::conn depth] set prop_req [oacs_dav::conn prop_req] + + set os_time_zone [clock format [clock seconds] -format %Z] + # find the values db_1row get_properties "" set etag "1f9a-400-3948d0f5" @@ -960,8 +1020,9 @@ return [list 409] } set dest_item_id [db_string get_dest_id "" -default ""] +ns_log debug "\nDAV Revision Copy dest $target_uri parent_id $new_parent_folder_id" if {![empty_string_p $dest_item_id]} { - + ns_log debug "\n ----- \n DAV Revision Copy Folder Exists item_id $dest_item_id overwrite $overwrite \n ----- \n" if {![string equal -nocase $overwrite "T"]} { return [list 412] } elseif {![permission::permission_p \ @@ -972,13 +1033,14 @@ } # according to the spec copy with overwrite means # delete then copy - ns_log notice "oacs_dav::revision::copy checking for lock on target" + ns_log debug "\noacs_dav::revision::copy checking for lock on target" if {![string equal "unlocked" [tdav::check_lock $target_uri]]} { return [list 423] } db_exec_plsql delete_for_copy "" set response [list 204] + ns_log debug "\n ----- \n CONTENT_REVISION::COPY OVERWRITING RETURNING 204 \n ----- \n" } else { set response [list 201] } @@ -1016,9 +1078,10 @@ if {![string equal "unlocked" [tdav::check_lock $uri]]} { return [list 423] } +ns_log debug "\nDAV Revision move dest $target_uri parent_id $new_parent_folder_id" set dest_item_id [db_string get_dest_id "" -default ""] if {![empty_string_p $dest_item_id]} { - + ns_log debug "\n ----- \n DAV Revision move Folder Exists item_id $dest_item_id overwrite $overwrite \n ----- \n" if {![string equal -nocase $overwrite "T"]} { return [list 412] } elseif {![permission::permission_p \ @@ -1033,6 +1096,7 @@ db_exec_plsql delete_for_move "" set response [list 204] + ns_log debug "\n ----- \n CONTENT_REVISION::MOVE OVERWRITING RETURNING 204 \n ----- \n" } else { set response [list 201] } @@ -1093,7 +1157,7 @@ set ret_code 423 set body "Resource is locked." } else { - ns_log notice "tdav::check_lock_for_unlock = [tdav::check_lock_for_unlock $uri]]" + ns_log debug "\ntdav::check_lock_for_unlock = [tdav::check_lock_for_unlock $uri]]" tdav::remove_lock $uri set ret_code 204 set body "" Index: openacs-4/packages/oacs-dav/tcl/tDAV-procs.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/oacs-dav/tcl/tDAV-procs.tcl,v diff -u -N -r1.2.2.3 -r1.2.2.4 --- openacs-4/packages/oacs-dav/tcl/tDAV-procs.tcl 10 Apr 2004 00:34:33 -0000 1.2.2.3 +++ openacs-4/packages/oacs-dav/tcl/tDAV-procs.tcl 23 Apr 2004 17:22:12 -0000 1.2.2.4 @@ -295,7 +295,8 @@ proc tdav::read_lock {uri} { set f [open [tdav::get_lock_file $uri] {CREAT RDONLY}] - + file start $[tdav::get_lock_file $uri] file_info + set t $file_info(mtime) set s [read $f] set e "list ${s}" set l [eval $e] @@ -329,6 +330,22 @@ # throw errors } + +# tdav::check_lock_timeout +# +# check if lock has timed out +# +# Arguments: +# uri URI of request +# +# Results: + +proc tdav::check_lock_timeout { uri } { + + + +} + # tdav::check_lock # # Compare existing lock to lock token provided @@ -351,16 +368,21 @@ regsub {^/} $uri {} uri # if lock exists, work. if not, just return. if {[file exists [tdav::get_lock_file $uri]]} { + set lockinfo [tdav::read_lock $uri] set hdr [ns_set iget [ns_conn headers] If] + + # the If header exists, work, otherwise 423 + if {[info exists hdr] && [string length $hdr]} { set token "" # add ? in the token re in case there is a conditional () # in the header regexp {(]+)>\s+)?\(<([^>]+)>\)} $hdr nil maybe hdr_uri token - set ftk [lindex [tdav::read_lock $uri] 3] - + + set ftk [lindex $lockinfo 3] + if {![info exists token] || ![string equal $token $ftk]} { ns_log Debug "tdav::check_lock: token mismatch $ftk expected hdr: $hdr token: $token" ns_return 423 {text/plain} {} @@ -1058,7 +1080,9 @@ set owner "" } set depth [ns_set iget [ns_conn headers] Depth] - if ![string length $depth] { + set timeout [ns_set iget [ns_conn headers] Timeout] + tdav::conn -set lock_timeout $timeout + if {![string length $depth]} { set depth 0 } tdav::conn -set depth $depth @@ -1071,34 +1095,47 @@ return filter_ok } -proc tdav::set_lock {uri depth type scope owner} { +proc tdav::set_lock {uri depth type scope owner timeout} { set token "opaquelocktoken:[ns_rand 2147483647]" - set lock [list $type $scope $owner $token] + set lock [list $type $scope $owner $token $timeout] tdav::write_lock $uri $lock return $token + } proc tdav::webdav_lock {} { set scope [tdav::conn lock_scope] set type [tdav::conn lock_type] set owner [tdav::conn lock_owner] - set uri [ns_conn url] regsub {^/} $uri {} uri set entry [file join [ns_info pageroot] $uri] set filename [lindex [file split $entry] end] set existing_lock_token [tdav::conn lock_token] - if {![file exists $entry]} { - set ret_code 404 - } elseif {![string equal "unlocked" [tdav::check_lock $uri]]} { +# if {![file exists $entry]} { +# set ret_code 404 +# } else + if {![string equal "unlocked" [tdav::check_lock $uri]]} { set ret_code 423 tdav::respond [list $ret_code] } else { set depth [tdav::conn depth] - set token [tdav::set_lock $uri $depth $type $scope $owner] + set timeout [tdav::conn timeout] + if {[string equal "" $timeout]} { + #probably make this a paramter? + set timeout 180 + } + if {![empty_string_p $existing_lock_token]} { + + set old_lock [tdav::read_lock $uri] + set new_lock [list [lindex $old_lock 0] [lindex $old_lock 1] [lindex $old_lock 2] [lindex $old_lock 3] $timeout] + tdav::write_lock $uri $new_lock + } else { + set token [tdav::set_lock $uri $depth $type $scope $owner] + } set ret_code 200 - tdav::respond [list $ret_code [list depth $depth token $token timeout "" owner $owner scope $scope type $type]] + tdav::respond [list $ret_code [list depth $depth token $token timeout $timeout owner $owner scope $scope type $type]] } } @@ -1143,7 +1180,7 @@ } -proc tdav::return_unauthorized { {realm "tbl"} } { +proc tdav::return_unauthorized { {realm ""} } { ns_set put [ns_conn outputheaders] "WWW-Authenticate" [subst {Basic realm="$realm"}] ns_return 401 {text/plain} "Unauthorized\n" } @@ -1167,6 +1204,7 @@ set response_body [encoding convertto utf-8 $response_body] } } + ns_log debug "\n ----- tdav litmus headers ----- \n [ns_set iget [ns_conn headers] X-Litmus] \n -----\n" ns_log debug "\n ----- tdav::response response_body ----- \n $response_body \n ----- end ----- \n" ns_return $response_code $mime_type $response_body } @@ -1215,24 +1253,9 @@ return [list $body] } -proc tdav::respond::put { response } { - set body "" - set mime_type text/plain - if {[string equal "201" [lindex $response 0]]} { - set body [subst { - - 201 Created - -

Created

- Resource [ns_conn url] has been created. -


-
AOLserver/3.0 at [ns_info hostname] Port [if {[ns_conn port] == 0} {return 80} else {return [ns_conn port]}]
- - }] - set mime_type text/html - } - return [list $body $mime_type] +proc tdav::respond::put { response } { + return $response } proc tdav::respond::proppatch { response } { @@ -1271,21 +1294,22 @@ set body "" switch -- [lindex $response 0] { 415 { - set body "" +# set body "" } 490 { - set body "" +# set body "" } 201 { - set body " - -201 Created - -

Created

-

Collection [ns_conn url] has been created.

-
-
- " +# set body " +# +# 201 Created +# +#

Created

+#

Collection [ns_conn url] has been created.

+#
+#
+# " + } 405 { set body " @@ -1304,12 +1328,6 @@ # response lindex 1 # we don't have to check the tdav fs props or lock properties # they should already be there - -# dom createNodeCmd elementNode node::response -# dom createNodeCmd elementNode node::href -# dom createNodeCmd elementNode node::propstat -# dom createNodeCmd elementNode node::prop -# dom createNodeCmd elementNode tdav::text set d [dom createDocumentNS "DAV:" "D:multistatus"] set n [$d documentElement] @@ -1368,21 +1386,25 @@ $prop appendChild $pnode } + + set supportedlock [$d createElement D:supportedlock] -# set lockentry [$d createElement D:lockentry] -# set lockscope [$d createElement D:lockscope] -# set exclusive [$d createElement D:exclusive] -# set locktype [$d createElement D:locktype] -# set write_type [$d createElement D:write] -# -# $locktype appendChild $write_type -# $lockscope appendChild $exclusive -# -# $lockentry appendChild $lockscope -# $lockentry appendChild $locktype -# -# $prop appendChild $lockentry + set lockentry [$d createElement D:lockentry] + set lockscope [$d createElement D:lockscope] + set exclusive [$d createElement D:exclusive] + set locktype [$d createElement D:locktype] + set write_type [$d createElement D:write] + + $supportedlock appendChild $lockentry + + $locktype appendChild $write_type + $lockscope appendChild $exclusive + $lockentry appendChild $lockscope + $lockentry appendChild $locktype + + $prop appendChild $supportedlock + $propstat appendChild $prop set status [$d createElement D:status] @@ -1391,21 +1413,7 @@ $status appendChild $status_text $propstat appendChild $status - # i'll have to learn more about what this lock entry is -# append mst_body { -# -# -# -# -# -# -# -# -# HTTP/1.1 200 OK -# -# } - }