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);
}
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();
}
}
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);
}
Aggregations