Search in sources :

Example 1 with DavContext

use of com.zimbra.cs.dav.DavContext in project zm-mailbox by Zimbra.

the class Lock method handle.

@Override
public void handle(DavContext ctxt) throws DavException, IOException, ServiceException {
    LockMgr lockmgr = LockMgr.getInstance();
    LockMgr.Lock lock = null;
    if (ctxt.hasRequestMessage()) {
        DavContext.Depth depth = ctxt.getDepth();
        if (depth == Depth.one)
            throw new DavException("invalid depth", HttpServletResponse.SC_BAD_REQUEST, null);
        String d = (depth == Depth.zero) ? "0" : depth.toString();
        LockMgr.LockScope scope = LockScope.shared;
        LockMgr.LockType type = LockType.write;
        Document req = ctxt.getRequestMessage();
        Element top = req.getRootElement();
        if (!top.getName().equals(DavElements.P_LOCKINFO))
            throw new DavException("msg " + top.getName() + " not allowed in LOCK", HttpServletResponse.SC_BAD_REQUEST, null);
        Element e = top.element(DavElements.E_LOCKSCOPE);
        @SuppressWarnings("unchecked") List<Element> ls = e.elements();
        for (Element v : ls) {
            if (v.getQName().equals(DavElements.E_EXCLUSIVE))
                scope = LockScope.exclusive;
            else if (v.getQName().equals(DavElements.E_SHARED))
                scope = LockScope.shared;
            else
                throw new DavException("unrecognized scope element " + v.toString(), HttpServletResponse.SC_BAD_REQUEST, null);
        }
        e = top.element(DavElements.E_LOCKTYPE);
        @SuppressWarnings("unchecked") List<Element> lt = e.elements();
        for (Element v : lt) {
            if (v.getQName().equals(DavElements.E_WRITE))
                type = LockType.write;
            else
                throw new DavException("unrecognized type element " + v.toString(), HttpServletResponse.SC_BAD_REQUEST, null);
        }
        String owner;
        e = top.element(DavElements.E_OWNER);
        if (e != null && e.elementIterator(DavElements.E_HREF).hasNext()) {
            Element ownerElem = (Element) e.elementIterator(DavElements.E_HREF).next();
            owner = ownerElem.getText();
        } else {
            owner = ctxt.getAuthAccount().getName();
        }
        lock = lockmgr.createLock(ctxt, owner, ctxt.getUri(), type, scope, d);
        ctxt.getResponse().addHeader(DavProtocol.HEADER_LOCK_TOKEN, lock.toLockTokenHeader());
    } else {
        // refresh lock
        String token = ctxt.getRequest().getHeader(DavProtocol.HEADER_IF);
        if (token == null) {
            throw new DavException("no request body", HttpServletResponse.SC_BAD_REQUEST, null);
        }
        token = token.trim();
        int len = token.length();
        if (token.charAt(0) == '(' && token.charAt(len - 1) == ')') {
            token = token.substring(1, len - 1);
        }
        List<LockMgr.Lock> locks = lockmgr.getLocks(ctxt.getUri());
        for (LockMgr.Lock l : locks) {
            if (l.token.equals(LockMgr.Lock.parseLockTokenHeader(token))) {
                l.extendExpiration();
                lock = l;
                break;
            }
        }
        if (lock == null) {
            throw new DavException("Lock does not exist", HttpServletResponse.SC_PRECONDITION_FAILED, null);
        }
    }
    ctxt.getDavResponse().addProperty(ctxt, new LockDiscovery(lock));
    ctxt.setStatus(HttpServletResponse.SC_OK);
    sendResponse(ctxt);
}
Also used : LockMgr(com.zimbra.cs.dav.LockMgr) DavException(com.zimbra.cs.dav.DavException) Element(org.dom4j.Element) Depth(com.zimbra.cs.dav.DavContext.Depth) Document(org.dom4j.Document) LockDiscovery(com.zimbra.cs.dav.property.LockDiscovery) LockScope(com.zimbra.cs.dav.LockMgr.LockScope) LockType(com.zimbra.cs.dav.LockMgr.LockType) DavContext(com.zimbra.cs.dav.DavContext)

Example 2 with DavContext

use of com.zimbra.cs.dav.DavContext in project zm-mailbox by Zimbra.

the class DavServlet method service.

@Override
public void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    ZimbraLog.clearContext();
    addRemoteIpToLoggingContext(req);
    ZimbraLog.addUserAgentToContext(req.getHeader(DavProtocol.HEADER_USER_AGENT));
    //bug fix - send 400 for Range requests
    String rangeHeader = req.getHeader(DavProtocol.HEADER_RANGE);
    if (null != rangeHeader) {
        sendError(resp, HttpServletResponse.SC_BAD_REQUEST, "Range header not supported", null, Level.debug);
        return;
    }
    RequestType rtype = getAllowedRequestType(req);
    ZimbraLog.dav.debug("Allowable request types %s", rtype);
    if (rtype == RequestType.none) {
        sendError(resp, HttpServletResponse.SC_NOT_ACCEPTABLE, "Not an allowed request type", null, Level.debug);
        return;
    }
    logRequestInfo(req);
    Account authUser = null;
    DavContext ctxt;
    try {
        AuthToken at = AuthProvider.getAuthToken(req, false);
        if (at != null && (at.isExpired() || !at.isRegistered())) {
            at = null;
        }
        if (at != null && (rtype == RequestType.both || rtype == RequestType.authtoken)) {
            authUser = Provisioning.getInstance().get(AccountBy.id, at.getAccountId());
        } else if (at == null && (rtype == RequestType.both || rtype == RequestType.password)) {
            AuthUtil.AuthResult result = AuthUtil.basicAuthRequest(req, resp, true, this);
            if (result.sendErrorCalled) {
                logResponseInfo(resp);
                return;
            }
            authUser = result.authorizedAccount;
        }
        if (authUser == null) {
            try {
                sendError(resp, HttpServletResponse.SC_UNAUTHORIZED, "Authentication failed", null, Level.debug);
            } catch (Exception e) {
            }
            return;
        }
        ZimbraLog.addToContext(ZimbraLog.C_ANAME, authUser.getName());
        ctxt = new DavContext(req, resp, authUser);
    } catch (AuthTokenException e) {
        sendError(resp, HttpServletResponse.SC_INTERNAL_SERVER_ERROR, "error getting authenticated user", e);
        return;
    } catch (ServiceException e) {
        sendError(resp, HttpServletResponse.SC_INTERNAL_SERVER_ERROR, "error getting authenticated user", e);
        return;
    }
    DavMethod method = sMethods.get(req.getMethod());
    if (method == null) {
        setAllowHeader(resp);
        sendError(resp, HttpServletResponse.SC_METHOD_NOT_ALLOWED, "Not an allowed method", null, Level.debug);
        return;
    }
    long t0 = System.currentTimeMillis();
    CacheStates cache = null;
    try {
        if (ZimbraLog.dav.isDebugEnabled()) {
            try {
                Upload upload = ctxt.getUpload();
                if (upload.getSize() > 0 && upload.getContentType().startsWith("text")) {
                    if (ZimbraLog.dav.isDebugEnabled()) {
                        StringBuilder logMsg = new StringBuilder("REQUEST\n").append(new String(ByteUtil.readInput(upload.getInputStream(), -1, 20480), "UTF-8"));
                        ZimbraLog.dav.debug(logMsg.toString());
                    }
                }
            } catch (DavException de) {
                throw de;
            } catch (Exception e) {
                ZimbraLog.dav.debug("ouch", e);
            }
        }
        cache = checkCachedResponse(ctxt, authUser);
        if (!ctxt.isResponseSent() && !isProxyRequest(ctxt, method)) {
            method.checkPrecondition(ctxt);
            method.handle(ctxt);
            method.checkPostcondition(ctxt);
            if (!ctxt.isResponseSent()) {
                resp.setStatus(ctxt.getStatus());
            }
        }
        if (!ctxt.isResponseSent()) {
            logResponseInfo(resp);
        }
    } catch (DavException e) {
        if (e.getCause() instanceof MailServiceException.NoSuchItemException || e.getStatus() == HttpServletResponse.SC_NOT_FOUND)
            ZimbraLog.dav.info(ctxt.getUri() + " not found");
        else if (e.getStatus() == HttpServletResponse.SC_MOVED_TEMPORARILY || e.getStatus() == HttpServletResponse.SC_MOVED_PERMANENTLY)
            ZimbraLog.dav.info("sending redirect");
        try {
            if (e.isStatusSet()) {
                resp.setStatus(e.getStatus());
                if (e.hasErrorMessage())
                    e.writeErrorMsg(resp.getOutputStream());
                if (ZimbraLog.dav.isDebugEnabled()) {
                    ZimbraLog.dav.info("sending http error %d because: %s", e.getStatus(), e.getMessage(), e);
                } else {
                    ZimbraLog.dav.info("sending http error %d because: %s", e.getStatus(), e.getMessage());
                }
                if (e.getCause() != null)
                    ZimbraLog.dav.debug("exception: ", e.getCause());
            } else {
                sendError(resp, HttpServletResponse.SC_INTERNAL_SERVER_ERROR, "error handling method " + method.getName(), e);
            }
        } catch (IllegalStateException ise) {
            ZimbraLog.dav.debug("can't write error msg", ise);
        }
    } catch (ServiceException e) {
        if (e instanceof MailServiceException.NoSuchItemException) {
            sendError(resp, HttpServletResponse.SC_NOT_FOUND, ctxt.getUri() + " not found", null, Level.info);
            return;
        }
        sendError(resp, HttpServletResponse.SC_INTERNAL_SERVER_ERROR, "error handling method " + method.getName(), e);
    } catch (Exception e) {
        try {
            sendError(resp, HttpServletResponse.SC_INTERNAL_SERVER_ERROR, "error handling method " + method.getName(), e);
        } catch (Exception ex) {
        }
    } finally {
        long t1 = System.currentTimeMillis();
        ZimbraLog.dav.info("DavServlet operation " + method.getName() + " to " + req.getPathInfo() + " (depth: " + ctxt.getDepth().name() + ") finished in " + (t1 - t0) + "ms");
        if (cache != null)
            cacheCleanUp(ctxt, cache);
        ctxt.cleanup();
    }
}
Also used : Account(com.zimbra.cs.account.Account) DavException(com.zimbra.cs.dav.DavException) Upload(com.zimbra.cs.service.FileUploadServlet.Upload) ServletException(javax.servlet.ServletException) XmlParseException(com.zimbra.common.soap.XmlParseException) ServiceException(com.zimbra.common.service.ServiceException) IOException(java.io.IOException) AuthTokenException(com.zimbra.cs.account.AuthTokenException) DavException(com.zimbra.cs.dav.DavException) MailServiceException(com.zimbra.cs.mailbox.MailServiceException) ServiceException(com.zimbra.common.service.ServiceException) MailServiceException(com.zimbra.cs.mailbox.MailServiceException) AuthTokenException(com.zimbra.cs.account.AuthTokenException) AuthToken(com.zimbra.cs.account.AuthToken) MailServiceException(com.zimbra.cs.mailbox.MailServiceException) DavContext(com.zimbra.cs.dav.DavContext)

Example 3 with DavContext

use of com.zimbra.cs.dav.DavContext in project zm-mailbox by Zimbra.

the class UrlNamespace method getCollectionAtUrl.

/* Returns Collection at the specified URL. */
public static Collection getCollectionAtUrl(DavContext ctxt, String url) throws DavException {
    UrlComponents uc = parseUrl(url);
    int lastPos = uc.path.length() - 1;
    if (uc.path.endsWith("/"))
        lastPos--;
    int index = uc.path.lastIndexOf('/', lastPos);
    String path;
    if (index == -1)
        path = "/";
    else
        path = uc.path.substring(0, index);
    String user = uc.user;
    if (user == null)
        user = ctxt.getUser();
    DavResource rsc = getResourceAt(new DavContext(ctxt, path), user, path);
    if (rsc instanceof Collection)
        return (Collection) rsc;
    throw new DavException("invalid uri", HttpServletResponse.SC_NOT_FOUND, null);
}
Also used : DavException(com.zimbra.cs.dav.DavException) DavContext(com.zimbra.cs.dav.DavContext) Mountpoint(com.zimbra.cs.mailbox.Mountpoint)

Aggregations

DavContext (com.zimbra.cs.dav.DavContext)3 DavException (com.zimbra.cs.dav.DavException)3 ServiceException (com.zimbra.common.service.ServiceException)1 XmlParseException (com.zimbra.common.soap.XmlParseException)1 Account (com.zimbra.cs.account.Account)1 AuthToken (com.zimbra.cs.account.AuthToken)1 AuthTokenException (com.zimbra.cs.account.AuthTokenException)1 Depth (com.zimbra.cs.dav.DavContext.Depth)1 LockMgr (com.zimbra.cs.dav.LockMgr)1 LockScope (com.zimbra.cs.dav.LockMgr.LockScope)1 LockType (com.zimbra.cs.dav.LockMgr.LockType)1 LockDiscovery (com.zimbra.cs.dav.property.LockDiscovery)1 MailServiceException (com.zimbra.cs.mailbox.MailServiceException)1 Mountpoint (com.zimbra.cs.mailbox.Mountpoint)1 Upload (com.zimbra.cs.service.FileUploadServlet.Upload)1 IOException (java.io.IOException)1 ServletException (javax.servlet.ServletException)1 Document (org.dom4j.Document)1 Element (org.dom4j.Element)1