webdavservlet.java
来自「RESIN 3.2 最新源码」· Java 代码 · 共 1,536 行 · 第 1/3 页
JAVA
1,536 行
String pathInfo = req.getPathInfo(); if (pathInfo == null) pathInfo = "/"; int depth = Integer.MAX_VALUE; if (! _path.exists(pathInfo, req, app)) { res.sendError(res.SC_NOT_FOUND); return; } String destURI = getDestination(req); if (destURI == null) { res.sendError(403, "Forbidden"); return; } String prefix = req.getContextPath(); if (req.getServletPath() != null) prefix += req.getServletPath(); if (! destURI.startsWith(prefix)) { res.sendError(403, "Forbidden"); return; } String destPath = destURI.substring(prefix.length()); if (destPath.equals(pathInfo)) { res.sendError(403, "Forbidden"); return; } else if (destPath.startsWith(pathInfo) && (pathInfo.endsWith("/") || destPath.startsWith(pathInfo + '/'))) { res.sendError(403, "Forbidden"); return; } else if (pathInfo.startsWith(destPath) && (destPath.endsWith("/") || pathInfo.startsWith(destPath + '/'))) { res.sendError(403, "Forbidden"); return; } String overwrite = req.getHeader("Overwrite"); if (overwrite == null) overwrite = "T"; if (! _path.exists(destPath, req, app)) { res.setStatus(res.SC_CREATED); } else if (! overwrite.equals("F")) { removeRecursive(destPath, req); res.setStatus(204, "No Content"); } else { res.sendError(412, "Overwrite not allowed for MOVE"); return; } if (! _path.exists(getParent(destPath), req, app)) { res.sendError(409, "MOVE needs parent of destination"); return; } if (_path.rename(pathInfo, destPath, req, app)) { // try renaming directly res.setStatus(204, "No Content"); } else if (_path.isFile(pathInfo, req, app)) { HashMap<AttributeName,String> props = getProperties(pathInfo, req, app); OutputStream os = _path.openWrite(destPath, req, app); WriteStream ws = Vfs.openWrite(os); try { InputStream is = _path.openRead(pathInfo, req, app); try { ws.writeStream(is); } finally { is.close(); } } finally { ws.close(); } setProperties(props, destPath, req, app); _path.remove(pathInfo, req, app); } else { moveRecursive(pathInfo, destPath, req); res.setStatus(204, "No Content"); } } private String getDestination(HttpServletRequest request) { String dest = request.getHeader("Destination"); dest = java.net.URLDecoder.decode(dest); if (dest.startsWith("/")) return dest; String prefix = request.getScheme() + "://"; String host = request.getHeader("Host"); if (host != null) prefix = prefix + host.toLowerCase(); if (dest.startsWith(prefix)) return dest.substring(prefix.length()); else return null; } private void moveRecursive(String srcPath, String destPath, HttpServletRequest req) throws IOException { ServletContext app = getServletContext(); if (_path.isDirectory(srcPath, req, app)) { _path.mkdir(destPath, req, app); String []list = _path.list(srcPath, req, app); for (int i = 0; i < list.length; i++) { try { moveRecursive(lookup(srcPath, list[i]), lookup(destPath, list[i]), req); } catch (IOException e) { log.log(Level.WARNING, e.toString(), e); } } _path.remove(srcPath, req, app); } else { HashMap<AttributeName,String> props = getProperties(srcPath, req, app); OutputStream os = _path.openWrite(destPath, req, app); WriteStream rs = Vfs.openWrite(os); try { InputStream is = _path.openRead(srcPath, req, app); try { rs.writeStream(is); } finally { is.close(); } } finally { rs.close(); os.close(); } setProperties(props, destPath, req, app); _path.remove(srcPath, req, app); } } /** * Grabs all the properties from a path. */ private HashMap<AttributeName,String> getProperties(String pathInfo, HttpServletRequest req, ServletContext app) throws IOException { HashMap<AttributeName,String> properties = null; Iterator<AttributeName> iter = _path.getAttributeNames(pathInfo, req, app); while (iter.hasNext()) { AttributeName name = iter.next(); String value = _path.getAttribute(name, pathInfo, req, app); if (properties == null) properties = new HashMap<AttributeName,String>(); properties.put(name, value); } return properties; } /** * Sets all the properties for a path. */ private void setProperties(HashMap<AttributeName,String> map, String pathInfo, HttpServletRequest req, ServletContext app) throws IOException { if (map == null) return; Iterator<AttributeName> iter = map.keySet().iterator(); while (iter.hasNext()) { AttributeName name = iter.next(); String value = map.get(name); _path.setAttribute(name, value, pathInfo, req, app); } } private void handleGet(HttpServletRequest req, HttpServletResponse res, WriteStream out) throws ServletException, IOException { ServletContext app = getServletContext(); String pathInfo = req.getPathInfo(); if (pathInfo == null) pathInfo = "/"; String mimeType = app.getMimeType(pathInfo); res.setContentType(mimeType); if (! _path.isFile(pathInfo, req, app) || ! _path.canRead(pathInfo, req, app)) { res.sendError(res.SC_NOT_FOUND); return; } long length = _path.getLength(pathInfo, req, app); res.setContentLength((int) length); if ("HTTP/1.1".equals(req.getProtocol())) { res.setDateHeader("Last-Modified", _path.getLastModified(pathInfo, req, app)); res.setHeader("Cache-Control", "private"); } if (req.getMethod().equals("HEAD")) return; OutputStream os = res.getOutputStream(); InputStream is = _path.openRead(pathInfo, req, app); ReadStream rs = Vfs.openRead(is); try { rs.writeToStream(os); } finally { rs.close(); } } protected void startMultistatus(HttpServletResponse res, WriteStream out) throws IOException { res.setStatus(207, "Multistatus"); res.setContentType("text/xml; charset=\"utf-8\""); out.println("<?xml version=\"1.0\"?>"); out.println("<D:multistatus xmlns:D=\"DAV:\">"); } protected void sendError(HttpServletResponse res, WriteStream out, int status, String statusText, String message) throws IOException { if (statusText == null) res.setStatus(status); else res.setStatus(status, statusText); res.setContentType("text/html"); if (statusText != null) { out.print("<title>"); out.print(statusText); out.println("</title>"); out.print("<h1>"); out.print(statusText); out.println("</h1>"); out.println(message); } else { out.print("<title>"); out.print(message); out.println("</title>"); out.print("<h1>"); out.print(message); out.println("</h1>"); } } private void handleDirectory(HttpServletRequest req, HttpServletResponse res, WriteStream out, String pathInfo) throws IOException, ServletException { ServletContext app = getServletContext(); res.setContentType("text/html"); out.println("<title>Directory of " + pathInfo + "</title>"); out.println("<h1>Directory of " + pathInfo + "</h1>"); String []list = _path.list(pathInfo, req, app); for (int i = 0; i < list.length; i++) { out.println("<a href=\"" + list[i] + "\">" + list[i] + "</a><br>"); } } private String escapeXml(String data) { CharBuffer cb = CharBuffer.allocate(); for (int i = 0; i < data.length(); i++) { char ch = data.charAt(i); switch (ch) { case '<': cb.append("<"); break; case '>': cb.append(">"); break; case '&': cb.append("&"); break; default: cb.append(ch); break; } } return cb.close(); } protected String getParent(String pathInfo) { int p = pathInfo.lastIndexOf('/', pathInfo.length() - 2); if (p < 0) return "/"; else return pathInfo.substring(0, p); } protected String lookup(String parent, String child) { if (parent.endsWith("/")) return parent + child; else return parent + '/' + child; } public void destroy() { _path.destroy(); } static class PropfindHandler extends org.xml.sax.helpers.DefaultHandler { ArrayList<AttributeName> properties = new ArrayList<AttributeName>(); boolean inProp; boolean isPropname; ArrayList<AttributeName> getProperties() { return properties; } boolean isPropname() { return isPropname; } public void startElement (String uri, String localName, String qName, Attributes attributes) throws SAXException { if (localName.equals("prop")) inProp = true; else if (localName.equals("propname")) isPropname = true; else if (inProp) { if (qName.indexOf(':') > 0 && uri.equals("")) throw new SAXException("illegal empty namespace"); properties.add(new AttributeName(uri, localName, qName)); } } public void endElement (String uri, String localName, String qName) throws SAXException { if (localName.equals("prop")) inProp = false; } } static class ProppatchHandler extends org.xml.sax.helpers.DefaultHandler { ArrayList<ProppatchCommand> _commands = new ArrayList<ProppatchCommand>(); boolean _inProp; boolean _inSet; boolean _inRemove; boolean _isPropname; AttributeName _attributeName; CharBuffer _value; boolean isPropname() { return _isPropname; } ArrayList<ProppatchCommand> getCommands() { return _commands; } public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException { if (localName.equals("set")) _inSet = true; else if (localName.equals("remove")) _inRemove = true; else if (localName.equals("prop")) _inProp = true; else if (localName.equals("propname")) _isPropname = true; else if (! _inProp) { } else if (_attributeName == null) { _attributeName = new AttributeName(uri, localName, qName); _value = CharBuffer.allocate(); } else { int p = qName.indexOf(':'); if (p > 0) _value.append("<" + qName + " xmlns:" + qName.substring(p + 1) + "=\"" + uri + "\">"); else _value.append("<" + qName + " xmlns=\"" + uri + "\">"); } } public void characters(char []buffer, int offset, int length) { if (_value != null) _value.append(buffer, offset, length); } public void endElement (String uri, String localName, String qName) throws SAXException { if (localName.equals("prop")) _inProp = false; else if (localName.equals("set")) _inSet = false; else if (localName.equals("remove")) _inRemove = false; else if (_attributeName == null) { } else if (localName.equals(_attributeName.getLocal()) && uri.equals(_attributeName.getNamespace())) { if (_inSet) { _commands.add(new ProppatchCommand(ProppatchCommand.SET, _attributeName, _value.close())); } else if (_inRemove) { _commands.add(new ProppatchCommand(ProppatchCommand.REMOVE, _attributeName, _value.close())); } _value = null; _attributeName = null; } else { _value.append("</" + qName + ">"); } } } static class ProppatchCommand { public static int SET = 0; public static int REMOVE = 1; public static int CHANGE = 2; private int _code; private AttributeName _name; private String _value; ProppatchCommand(int code, AttributeName name, String value) { _code = code; _name = name; _value = value; } int getCode() { return _code; } AttributeName getName() { return _name; } String getValue() { return _value; } }}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?