@@ -262,6 +262,16 @@ func (b *backend) PropPatch(r *http.Request, update *internal.PropertyUpdate) (*
262262}
263263
264264func (b * backend ) Put (w http.ResponseWriter , r * http.Request ) error {
265+ if lock := b .resourceLock (r .URL .Path ); lock != nil {
266+ token , err := internal .ParseSubmittedToken (r .Header )
267+ if err != nil {
268+ return err
269+ }
270+ if token != lock .Href {
271+ return & internal.HTTPError {Code : http .StatusLocked }
272+ }
273+ }
274+
265275 ifNoneMatch := ConditionalMatch (r .Header .Get ("If-None-Match" ))
266276 ifMatch := ConditionalMatch (r .Header .Get ("If-Match" ))
267277
@@ -294,6 +304,16 @@ func (b *backend) Put(w http.ResponseWriter, r *http.Request) error {
294304}
295305
296306func (b * backend ) Delete (r * http.Request ) error {
307+ if lock := b .resourceLock (r .URL .Path ); lock != nil {
308+ token , err := internal .ParseSubmittedToken (r .Header )
309+ if err != nil {
310+ return err
311+ }
312+ if token != lock .Href {
313+ return & internal.HTTPError {Code : http .StatusLocked }
314+ }
315+ }
316+
297317 ifNoneMatch := ConditionalMatch (r .Header .Get ("If-None-Match" ))
298318 ifMatch := ConditionalMatch (r .Header .Get ("If-Match" ))
299319
@@ -324,6 +344,16 @@ func (b *backend) Mkcol(r *http.Request) error {
324344}
325345
326346func (b * backend ) Copy (r * http.Request , dest * internal.Href , recursive , overwrite bool ) (created bool , err error ) {
347+ if lock := b .resourceLock (dest .Path ); lock != nil {
348+ token , err := internal .ParseSubmittedToken (r .Header )
349+ if err != nil {
350+ return false , err
351+ }
352+ if token != lock .Href {
353+ return false , & internal.HTTPError {Code : http .StatusLocked }
354+ }
355+ }
356+
327357 options := CopyOptions {
328358 NoRecursive : ! recursive ,
329359 NoOverwrite : ! overwrite ,
@@ -336,6 +366,37 @@ func (b *backend) Copy(r *http.Request, dest *internal.Href, recursive, overwrit
336366}
337367
338368func (b * backend ) Move (r * http.Request , dest * internal.Href , overwrite bool ) (created bool , err error ) {
369+ // Check source and destination locks
370+ var conditions [][]internal.Condition
371+ hif := r .Header .Get ("If" )
372+ if hif == "" {
373+ conditions = nil
374+ } else {
375+ var err error
376+ conditions , err = internal .ParseConditions (hif )
377+ if err != nil {
378+ return false , & internal.HTTPError {http .StatusBadRequest , err }
379+ }
380+ }
381+ srcLock := b .resourceLock (r .URL .Path )
382+ destLock := b .resourceLock (dest .Path )
383+ for _ , conds := range conditions {
384+ if len (conds ) == 0 {
385+ continue
386+ }
387+ if len (conds ) > 1 {
388+ return false , internal .HTTPErrorf (http .StatusBadRequest , "webdav: multiple conditions are not supported in the If header field" )
389+ }
390+ if (conds [0 ].Resource == "" || conds [0 ].Resource == r .URL .Path ) && srcLock != nil && conds [0 ].Token == srcLock .Href {
391+ srcLock = nil
392+ } else if (conds [0 ].Resource == dest .Path ) && destLock != nil && conds [0 ].Token == destLock .Href {
393+ destLock = nil
394+ }
395+ }
396+ if srcLock != nil || destLock != nil {
397+ return false , & internal.HTTPError {Code : http .StatusLocked }
398+ }
399+
339400 options := MoveOptions {
340401 NoOverwrite : ! overwrite ,
341402 }
0 commit comments