@@ -260,6 +260,16 @@ func (b *backend) PropPatch(r *http.Request, update *internal.PropertyUpdate) (*
260260}
261261
262262func (b * backend ) Put (w http.ResponseWriter , r * http.Request ) error {
263+ if lock := b .resourceLock (r .URL .Path ); lock != nil {
264+ token , err := internal .ParseSubmittedToken (r .Header )
265+ if err != nil {
266+ return err
267+ }
268+ if token != lock .Href {
269+ return & internal.HTTPError {Code : http .StatusLocked }
270+ }
271+ }
272+
263273 ifNoneMatch := ConditionalMatch (r .Header .Get ("If-None-Match" ))
264274 ifMatch := ConditionalMatch (r .Header .Get ("If-Match" ))
265275
@@ -292,6 +302,16 @@ func (b *backend) Put(w http.ResponseWriter, r *http.Request) error {
292302}
293303
294304func (b * backend ) Delete (r * http.Request ) error {
305+ if lock := b .resourceLock (r .URL .Path ); lock != nil {
306+ token , err := internal .ParseSubmittedToken (r .Header )
307+ if err != nil {
308+ return err
309+ }
310+ if token != lock .Href {
311+ return & internal.HTTPError {Code : http .StatusLocked }
312+ }
313+ }
314+
295315 ifNoneMatch := ConditionalMatch (r .Header .Get ("If-None-Match" ))
296316 ifMatch := ConditionalMatch (r .Header .Get ("If-Match" ))
297317
@@ -322,6 +342,16 @@ func (b *backend) Mkcol(r *http.Request) error {
322342}
323343
324344func (b * backend ) Copy (r * http.Request , dest * internal.Href , recursive , overwrite bool ) (created bool , err error ) {
345+ if lock := b .resourceLock (dest .Path ); lock != nil {
346+ token , err := internal .ParseSubmittedToken (r .Header )
347+ if err != nil {
348+ return false , err
349+ }
350+ if token != lock .Href {
351+ return false , & internal.HTTPError {Code : http .StatusLocked }
352+ }
353+ }
354+
325355 options := CopyOptions {
326356 NoRecursive : ! recursive ,
327357 NoOverwrite : ! overwrite ,
@@ -334,6 +364,37 @@ func (b *backend) Copy(r *http.Request, dest *internal.Href, recursive, overwrit
334364}
335365
336366func (b * backend ) Move (r * http.Request , dest * internal.Href , overwrite bool ) (created bool , err error ) {
367+ // Check source and destination locks
368+ var conditions [][]internal.Condition
369+ hif := r .Header .Get ("If" )
370+ if hif == "" {
371+ conditions = nil
372+ } else {
373+ var err error
374+ conditions , err = internal .ParseConditions (hif )
375+ if err != nil {
376+ return false , & internal.HTTPError {http .StatusBadRequest , err }
377+ }
378+ }
379+ srcLock := b .resourceLock (r .URL .Path )
380+ destLock := b .resourceLock (dest .Path )
381+ for _ , conds := range conditions {
382+ if len (conds ) == 0 {
383+ continue
384+ }
385+ if len (conds ) > 1 {
386+ return false , internal .HTTPErrorf (http .StatusBadRequest , "webdav: multiple conditions are not supported in the If header field" )
387+ }
388+ if (conds [0 ].Resource == "" || conds [0 ].Resource == r .URL .Path ) && srcLock != nil && conds [0 ].Token == srcLock .Href {
389+ srcLock = nil
390+ } else if (conds [0 ].Resource == dest .Path ) && destLock != nil && conds [0 ].Token == destLock .Href {
391+ destLock = nil
392+ }
393+ }
394+ if srcLock != nil || destLock != nil {
395+ return false , & internal.HTTPError {Code : http .StatusLocked }
396+ }
397+
337398 options := MoveOptions {
338399 NoOverwrite : ! overwrite ,
339400 }
0 commit comments