(w http.ResponseWriter, r *http.Request)
| 563 | } |
| 564 | |
| 565 | func (h *Handler) handleLock(w http.ResponseWriter, r *http.Request) (retStatus int, retErr error) { |
| 566 | duration, err := parseTimeout(r.Header.Get("Timeout")) |
| 567 | if err != nil { |
| 568 | return http.StatusBadRequest, err |
| 569 | } |
| 570 | li, status, err := readLockInfo(r.Body) |
| 571 | if err != nil { |
| 572 | return status, err |
| 573 | } |
| 574 | |
| 575 | ctx := r.Context() |
| 576 | user := ctx.Value(conf.UserKey).(*model.User) |
| 577 | token, ld, now, created := "", LockDetails{}, time.Now(), false |
| 578 | if li == (lockInfo{}) { |
| 579 | // An empty lockInfo means to refresh the lock. |
| 580 | ih, ok := parseIfHeader(r.Header.Get("If")) |
| 581 | if !ok { |
| 582 | return http.StatusBadRequest, errInvalidIfHeader |
| 583 | } |
| 584 | if len(ih.lists) == 1 && len(ih.lists[0].conditions) == 1 { |
| 585 | token = ih.lists[0].conditions[0].Token |
| 586 | } |
| 587 | if token == "" { |
| 588 | return http.StatusBadRequest, errInvalidLockToken |
| 589 | } |
| 590 | ld, err = h.LockSystem.Refresh(now, token, duration) |
| 591 | if err != nil { |
| 592 | if err == ErrNoSuchLock { |
| 593 | return http.StatusPreconditionFailed, err |
| 594 | } |
| 595 | return http.StatusInternalServerError, err |
| 596 | } |
| 597 | |
| 598 | } else { |
| 599 | // Section 9.10.3 says that "If no Depth header is submitted on a LOCK request, |
| 600 | // then the request MUST act as if a "Depth:infinity" had been submitted." |
| 601 | depth := infiniteDepth |
| 602 | if hdr := r.Header.Get("Depth"); hdr != "" { |
| 603 | depth = parseDepth(hdr) |
| 604 | if depth != 0 && depth != infiniteDepth { |
| 605 | // Section 9.10.3 says that "Values other than 0 or infinity must not be |
| 606 | // used with the Depth header on a LOCK method". |
| 607 | return http.StatusBadRequest, errInvalidDepth |
| 608 | } |
| 609 | } |
| 610 | reqPath, status, err := h.stripPrefix(r.URL.Path) |
| 611 | if err != nil { |
| 612 | return status, err |
| 613 | } |
| 614 | reqPath, err = user.JoinPath(reqPath) |
| 615 | if err != nil { |
| 616 | return http.StatusForbidden, err |
| 617 | } |
| 618 | meta, err := op.GetNearestMeta(reqPath) |
| 619 | if err != nil && !errors.Is(errors.Cause(err), errs.MetaNotFound) { |
| 620 | return http.StatusInternalServerError, err |
| 621 | } |
| 622 | if !common.CanWrite(user, meta, reqPath) { |
no test coverage detected