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("&lt;");        break;      case '>':        cb.append("&gt;");        break;      case '&':        cb.append("&amp;");        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 + -
显示快捷键?