103928aee4356845252ac6b662d5c72c29903813eJake Slack// 203928aee4356845252ac6b662d5c72c29903813eJake Slack// ======================================================================== 303928aee4356845252ac6b662d5c72c29903813eJake Slack// Copyright (c) 1995-2014 Mort Bay Consulting Pty. Ltd. 403928aee4356845252ac6b662d5c72c29903813eJake Slack// ------------------------------------------------------------------------ 503928aee4356845252ac6b662d5c72c29903813eJake Slack// All rights reserved. This program and the accompanying materials 603928aee4356845252ac6b662d5c72c29903813eJake Slack// are made available under the terms of the Eclipse Public License v1.0 703928aee4356845252ac6b662d5c72c29903813eJake Slack// and Apache License v2.0 which accompanies this distribution. 803928aee4356845252ac6b662d5c72c29903813eJake Slack// 903928aee4356845252ac6b662d5c72c29903813eJake Slack// The Eclipse Public License is available at 1003928aee4356845252ac6b662d5c72c29903813eJake Slack// http://www.eclipse.org/legal/epl-v10.html 1103928aee4356845252ac6b662d5c72c29903813eJake Slack// 1203928aee4356845252ac6b662d5c72c29903813eJake Slack// The Apache License v2.0 is available at 1303928aee4356845252ac6b662d5c72c29903813eJake Slack// http://www.opensource.org/licenses/apache2.0.php 1403928aee4356845252ac6b662d5c72c29903813eJake Slack// 1503928aee4356845252ac6b662d5c72c29903813eJake Slack// You may elect to redistribute this code under either of these licenses. 1603928aee4356845252ac6b662d5c72c29903813eJake Slack// ======================================================================== 1703928aee4356845252ac6b662d5c72c29903813eJake Slack// 1803928aee4356845252ac6b662d5c72c29903813eJake Slack 1903928aee4356845252ac6b662d5c72c29903813eJake Slackpackage org.eclipse.jetty.servlets; 2003928aee4356845252ac6b662d5c72c29903813eJake Slack 2103928aee4356845252ac6b662d5c72c29903813eJake Slackimport java.io.File; 2203928aee4356845252ac6b662d5c72c29903813eJake Slackimport java.io.FileOutputStream; 2303928aee4356845252ac6b662d5c72c29903813eJake Slackimport java.io.IOException; 2403928aee4356845252ac6b662d5c72c29903813eJake Slackimport java.io.InputStream; 2503928aee4356845252ac6b662d5c72c29903813eJake Slackimport java.io.OutputStream; 2603928aee4356845252ac6b662d5c72c29903813eJake Slackimport java.net.URI; 2703928aee4356845252ac6b662d5c72c29903813eJake Slackimport java.net.URISyntaxException; 2803928aee4356845252ac6b662d5c72c29903813eJake Slackimport java.util.Arrays; 2903928aee4356845252ac6b662d5c72c29903813eJake Slackimport java.util.HashSet; 3003928aee4356845252ac6b662d5c72c29903813eJake Slackimport java.util.Set; 3103928aee4356845252ac6b662d5c72c29903813eJake Slackimport java.util.concurrent.ConcurrentHashMap; 3203928aee4356845252ac6b662d5c72c29903813eJake Slackimport java.util.concurrent.ConcurrentMap; 3303928aee4356845252ac6b662d5c72c29903813eJake Slack 3403928aee4356845252ac6b662d5c72c29903813eJake Slackimport javax.servlet.Filter; 3503928aee4356845252ac6b662d5c72c29903813eJake Slackimport javax.servlet.FilterChain; 3603928aee4356845252ac6b662d5c72c29903813eJake Slackimport javax.servlet.FilterConfig; 3703928aee4356845252ac6b662d5c72c29903813eJake Slackimport javax.servlet.ServletContext; 3803928aee4356845252ac6b662d5c72c29903813eJake Slackimport javax.servlet.ServletException; 3903928aee4356845252ac6b662d5c72c29903813eJake Slackimport javax.servlet.ServletRequest; 4003928aee4356845252ac6b662d5c72c29903813eJake Slackimport javax.servlet.ServletResponse; 4103928aee4356845252ac6b662d5c72c29903813eJake Slackimport javax.servlet.UnavailableException; 4203928aee4356845252ac6b662d5c72c29903813eJake Slackimport javax.servlet.http.HttpServletRequest; 4303928aee4356845252ac6b662d5c72c29903813eJake Slackimport javax.servlet.http.HttpServletResponse; 4403928aee4356845252ac6b662d5c72c29903813eJake Slackimport javax.servlet.http.HttpServletResponseWrapper; 4503928aee4356845252ac6b662d5c72c29903813eJake Slack 4603928aee4356845252ac6b662d5c72c29903813eJake Slackimport org.eclipse.jetty.util.IO; 4703928aee4356845252ac6b662d5c72c29903813eJake Slackimport org.eclipse.jetty.util.URIUtil; 4803928aee4356845252ac6b662d5c72c29903813eJake Slack 4903928aee4356845252ac6b662d5c72c29903813eJake Slack/** 5003928aee4356845252ac6b662d5c72c29903813eJake Slack * PutFilter 5103928aee4356845252ac6b662d5c72c29903813eJake Slack * 5203928aee4356845252ac6b662d5c72c29903813eJake Slack * A Filter that handles PUT, DELETE and MOVE methods. 5303928aee4356845252ac6b662d5c72c29903813eJake Slack * Files are hidden during PUT operations, so that 404's result. 5403928aee4356845252ac6b662d5c72c29903813eJake Slack * 5503928aee4356845252ac6b662d5c72c29903813eJake Slack * The following init parameters pay be used:<ul> 5603928aee4356845252ac6b662d5c72c29903813eJake Slack * <li><b>baseURI</b> - The file URI of the document root for put content. 5703928aee4356845252ac6b662d5c72c29903813eJake Slack * <li><b>delAllowed</b> - boolean, if true DELETE and MOVE methods are supported. 5803928aee4356845252ac6b662d5c72c29903813eJake Slack * <li><b>putAtomic</b> - boolean, if true PUT files are written to a temp location and moved into place. 5903928aee4356845252ac6b662d5c72c29903813eJake Slack * </ul> 6003928aee4356845252ac6b662d5c72c29903813eJake Slack * 6103928aee4356845252ac6b662d5c72c29903813eJake Slack */ 6203928aee4356845252ac6b662d5c72c29903813eJake Slackpublic class PutFilter implements Filter 6303928aee4356845252ac6b662d5c72c29903813eJake Slack{ 6403928aee4356845252ac6b662d5c72c29903813eJake Slack public final static String __PUT="PUT"; 6503928aee4356845252ac6b662d5c72c29903813eJake Slack public final static String __DELETE="DELETE"; 6603928aee4356845252ac6b662d5c72c29903813eJake Slack public final static String __MOVE="MOVE"; 6703928aee4356845252ac6b662d5c72c29903813eJake Slack public final static String __OPTIONS="OPTIONS"; 6803928aee4356845252ac6b662d5c72c29903813eJake Slack 6903928aee4356845252ac6b662d5c72c29903813eJake Slack Set<String> _operations = new HashSet<String>(); 7003928aee4356845252ac6b662d5c72c29903813eJake Slack private ConcurrentMap<String,String> _hidden = new ConcurrentHashMap<String, String>(); 7103928aee4356845252ac6b662d5c72c29903813eJake Slack 7203928aee4356845252ac6b662d5c72c29903813eJake Slack private ServletContext _context; 7303928aee4356845252ac6b662d5c72c29903813eJake Slack private String _baseURI; 7403928aee4356845252ac6b662d5c72c29903813eJake Slack private boolean _delAllowed; 7503928aee4356845252ac6b662d5c72c29903813eJake Slack private boolean _putAtomic; 7603928aee4356845252ac6b662d5c72c29903813eJake Slack private File _tmpdir; 7703928aee4356845252ac6b662d5c72c29903813eJake Slack 7803928aee4356845252ac6b662d5c72c29903813eJake Slack 7903928aee4356845252ac6b662d5c72c29903813eJake Slack /* ------------------------------------------------------------ */ 8003928aee4356845252ac6b662d5c72c29903813eJake Slack public void init(FilterConfig config) throws ServletException 8103928aee4356845252ac6b662d5c72c29903813eJake Slack { 8203928aee4356845252ac6b662d5c72c29903813eJake Slack _context=config.getServletContext(); 8303928aee4356845252ac6b662d5c72c29903813eJake Slack 8403928aee4356845252ac6b662d5c72c29903813eJake Slack _tmpdir=(File)_context.getAttribute("javax.servlet.context.tempdir"); 8503928aee4356845252ac6b662d5c72c29903813eJake Slack 8603928aee4356845252ac6b662d5c72c29903813eJake Slack if (_context.getRealPath("/")==null) 8703928aee4356845252ac6b662d5c72c29903813eJake Slack throw new UnavailableException("Packed war"); 8803928aee4356845252ac6b662d5c72c29903813eJake Slack 8903928aee4356845252ac6b662d5c72c29903813eJake Slack String b = config.getInitParameter("baseURI"); 9003928aee4356845252ac6b662d5c72c29903813eJake Slack if (b != null) 9103928aee4356845252ac6b662d5c72c29903813eJake Slack { 9203928aee4356845252ac6b662d5c72c29903813eJake Slack _baseURI=b; 9303928aee4356845252ac6b662d5c72c29903813eJake Slack } 9403928aee4356845252ac6b662d5c72c29903813eJake Slack else 9503928aee4356845252ac6b662d5c72c29903813eJake Slack { 9603928aee4356845252ac6b662d5c72c29903813eJake Slack File base=new File(_context.getRealPath("/")); 9703928aee4356845252ac6b662d5c72c29903813eJake Slack _baseURI=base.toURI().toString(); 9803928aee4356845252ac6b662d5c72c29903813eJake Slack } 9903928aee4356845252ac6b662d5c72c29903813eJake Slack 10003928aee4356845252ac6b662d5c72c29903813eJake Slack _delAllowed = getInitBoolean(config,"delAllowed"); 10103928aee4356845252ac6b662d5c72c29903813eJake Slack _putAtomic = getInitBoolean(config,"putAtomic"); 10203928aee4356845252ac6b662d5c72c29903813eJake Slack 10303928aee4356845252ac6b662d5c72c29903813eJake Slack _operations.add(__OPTIONS); 10403928aee4356845252ac6b662d5c72c29903813eJake Slack _operations.add(__PUT); 10503928aee4356845252ac6b662d5c72c29903813eJake Slack if (_delAllowed) 10603928aee4356845252ac6b662d5c72c29903813eJake Slack { 10703928aee4356845252ac6b662d5c72c29903813eJake Slack _operations.add(__DELETE); 10803928aee4356845252ac6b662d5c72c29903813eJake Slack _operations.add(__MOVE); 10903928aee4356845252ac6b662d5c72c29903813eJake Slack } 11003928aee4356845252ac6b662d5c72c29903813eJake Slack } 11103928aee4356845252ac6b662d5c72c29903813eJake Slack 11203928aee4356845252ac6b662d5c72c29903813eJake Slack /* ------------------------------------------------------------ */ 11303928aee4356845252ac6b662d5c72c29903813eJake Slack private boolean getInitBoolean(FilterConfig config,String name) 11403928aee4356845252ac6b662d5c72c29903813eJake Slack { 11503928aee4356845252ac6b662d5c72c29903813eJake Slack String value = config.getInitParameter(name); 11603928aee4356845252ac6b662d5c72c29903813eJake Slack return value != null && value.length() > 0 && (value.startsWith("t") || value.startsWith("T") || value.startsWith("y") || value.startsWith("Y") || value.startsWith("1")); 11703928aee4356845252ac6b662d5c72c29903813eJake Slack } 11803928aee4356845252ac6b662d5c72c29903813eJake Slack 11903928aee4356845252ac6b662d5c72c29903813eJake Slack /* ------------------------------------------------------------ */ 12003928aee4356845252ac6b662d5c72c29903813eJake Slack public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException 12103928aee4356845252ac6b662d5c72c29903813eJake Slack { 12203928aee4356845252ac6b662d5c72c29903813eJake Slack HttpServletRequest request=(HttpServletRequest)req; 12303928aee4356845252ac6b662d5c72c29903813eJake Slack HttpServletResponse response=(HttpServletResponse)res; 12403928aee4356845252ac6b662d5c72c29903813eJake Slack 12503928aee4356845252ac6b662d5c72c29903813eJake Slack String servletPath =request.getServletPath(); 12603928aee4356845252ac6b662d5c72c29903813eJake Slack String pathInfo = request.getPathInfo(); 12703928aee4356845252ac6b662d5c72c29903813eJake Slack String pathInContext = URIUtil.addPaths(servletPath, pathInfo); 12803928aee4356845252ac6b662d5c72c29903813eJake Slack 12903928aee4356845252ac6b662d5c72c29903813eJake Slack String resource = URIUtil.addPaths(_baseURI,pathInContext); 13003928aee4356845252ac6b662d5c72c29903813eJake Slack 13103928aee4356845252ac6b662d5c72c29903813eJake Slack String method = request.getMethod(); 13203928aee4356845252ac6b662d5c72c29903813eJake Slack boolean op = _operations.contains(method); 13303928aee4356845252ac6b662d5c72c29903813eJake Slack 13403928aee4356845252ac6b662d5c72c29903813eJake Slack if (op) 13503928aee4356845252ac6b662d5c72c29903813eJake Slack { 13603928aee4356845252ac6b662d5c72c29903813eJake Slack File file = null; 13703928aee4356845252ac6b662d5c72c29903813eJake Slack try 13803928aee4356845252ac6b662d5c72c29903813eJake Slack { 13903928aee4356845252ac6b662d5c72c29903813eJake Slack if (method.equals(__OPTIONS)) 14003928aee4356845252ac6b662d5c72c29903813eJake Slack handleOptions(chain,request, response); 14103928aee4356845252ac6b662d5c72c29903813eJake Slack else 14203928aee4356845252ac6b662d5c72c29903813eJake Slack { 14303928aee4356845252ac6b662d5c72c29903813eJake Slack file=new File(new URI(resource)); 14403928aee4356845252ac6b662d5c72c29903813eJake Slack boolean exists = file.exists(); 14503928aee4356845252ac6b662d5c72c29903813eJake Slack if (exists && !passConditionalHeaders(request, response, file)) 14603928aee4356845252ac6b662d5c72c29903813eJake Slack return; 14703928aee4356845252ac6b662d5c72c29903813eJake Slack 14803928aee4356845252ac6b662d5c72c29903813eJake Slack if (method.equals(__PUT)) 14903928aee4356845252ac6b662d5c72c29903813eJake Slack handlePut(request, response,pathInContext, file); 15003928aee4356845252ac6b662d5c72c29903813eJake Slack else if (method.equals(__DELETE)) 15103928aee4356845252ac6b662d5c72c29903813eJake Slack handleDelete(request, response, pathInContext, file); 15203928aee4356845252ac6b662d5c72c29903813eJake Slack else if (method.equals(__MOVE)) 15303928aee4356845252ac6b662d5c72c29903813eJake Slack handleMove(request, response, pathInContext, file); 15403928aee4356845252ac6b662d5c72c29903813eJake Slack else 15503928aee4356845252ac6b662d5c72c29903813eJake Slack throw new IllegalStateException(); 15603928aee4356845252ac6b662d5c72c29903813eJake Slack } 15703928aee4356845252ac6b662d5c72c29903813eJake Slack } 15803928aee4356845252ac6b662d5c72c29903813eJake Slack catch(Exception e) 15903928aee4356845252ac6b662d5c72c29903813eJake Slack { 16003928aee4356845252ac6b662d5c72c29903813eJake Slack _context.log(e.toString(),e); 16103928aee4356845252ac6b662d5c72c29903813eJake Slack response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR); 16203928aee4356845252ac6b662d5c72c29903813eJake Slack } 16303928aee4356845252ac6b662d5c72c29903813eJake Slack } 16403928aee4356845252ac6b662d5c72c29903813eJake Slack else 16503928aee4356845252ac6b662d5c72c29903813eJake Slack { 16603928aee4356845252ac6b662d5c72c29903813eJake Slack if (isHidden(pathInContext)) 16703928aee4356845252ac6b662d5c72c29903813eJake Slack response.sendError(HttpServletResponse.SC_NOT_FOUND); 16803928aee4356845252ac6b662d5c72c29903813eJake Slack else 16903928aee4356845252ac6b662d5c72c29903813eJake Slack chain.doFilter(request,response); 17003928aee4356845252ac6b662d5c72c29903813eJake Slack return; 17103928aee4356845252ac6b662d5c72c29903813eJake Slack } 17203928aee4356845252ac6b662d5c72c29903813eJake Slack } 17303928aee4356845252ac6b662d5c72c29903813eJake Slack 17403928aee4356845252ac6b662d5c72c29903813eJake Slack /* ------------------------------------------------------------ */ 17503928aee4356845252ac6b662d5c72c29903813eJake Slack private boolean isHidden(String pathInContext) 17603928aee4356845252ac6b662d5c72c29903813eJake Slack { 17703928aee4356845252ac6b662d5c72c29903813eJake Slack return _hidden.containsKey(pathInContext); 17803928aee4356845252ac6b662d5c72c29903813eJake Slack } 17903928aee4356845252ac6b662d5c72c29903813eJake Slack 18003928aee4356845252ac6b662d5c72c29903813eJake Slack /* ------------------------------------------------------------ */ 18103928aee4356845252ac6b662d5c72c29903813eJake Slack public void destroy() 18203928aee4356845252ac6b662d5c72c29903813eJake Slack { 18303928aee4356845252ac6b662d5c72c29903813eJake Slack } 18403928aee4356845252ac6b662d5c72c29903813eJake Slack 18503928aee4356845252ac6b662d5c72c29903813eJake Slack /* ------------------------------------------------------------------- */ 18603928aee4356845252ac6b662d5c72c29903813eJake Slack public void handlePut(HttpServletRequest request, HttpServletResponse response, String pathInContext, File file) throws ServletException, IOException 18703928aee4356845252ac6b662d5c72c29903813eJake Slack { 18803928aee4356845252ac6b662d5c72c29903813eJake Slack boolean exists = file.exists(); 18903928aee4356845252ac6b662d5c72c29903813eJake Slack if (pathInContext.endsWith("/")) 19003928aee4356845252ac6b662d5c72c29903813eJake Slack { 19103928aee4356845252ac6b662d5c72c29903813eJake Slack if (!exists) 19203928aee4356845252ac6b662d5c72c29903813eJake Slack { 19303928aee4356845252ac6b662d5c72c29903813eJake Slack if (!file.mkdirs()) 19403928aee4356845252ac6b662d5c72c29903813eJake Slack response.sendError(HttpServletResponse.SC_FORBIDDEN); 19503928aee4356845252ac6b662d5c72c29903813eJake Slack else 19603928aee4356845252ac6b662d5c72c29903813eJake Slack { 19703928aee4356845252ac6b662d5c72c29903813eJake Slack response.setStatus(HttpServletResponse.SC_CREATED); 19803928aee4356845252ac6b662d5c72c29903813eJake Slack response.flushBuffer(); 19903928aee4356845252ac6b662d5c72c29903813eJake Slack } 20003928aee4356845252ac6b662d5c72c29903813eJake Slack } 20103928aee4356845252ac6b662d5c72c29903813eJake Slack else 20203928aee4356845252ac6b662d5c72c29903813eJake Slack { 20303928aee4356845252ac6b662d5c72c29903813eJake Slack response.setStatus(HttpServletResponse.SC_OK); 20403928aee4356845252ac6b662d5c72c29903813eJake Slack response.flushBuffer(); 20503928aee4356845252ac6b662d5c72c29903813eJake Slack } 20603928aee4356845252ac6b662d5c72c29903813eJake Slack } 20703928aee4356845252ac6b662d5c72c29903813eJake Slack else 20803928aee4356845252ac6b662d5c72c29903813eJake Slack { 20903928aee4356845252ac6b662d5c72c29903813eJake Slack boolean ok=false; 21003928aee4356845252ac6b662d5c72c29903813eJake Slack try 21103928aee4356845252ac6b662d5c72c29903813eJake Slack { 21203928aee4356845252ac6b662d5c72c29903813eJake Slack _hidden.put(pathInContext,pathInContext); 21303928aee4356845252ac6b662d5c72c29903813eJake Slack File parent = file.getParentFile(); 21403928aee4356845252ac6b662d5c72c29903813eJake Slack parent.mkdirs(); 21503928aee4356845252ac6b662d5c72c29903813eJake Slack int toRead = request.getContentLength(); 21603928aee4356845252ac6b662d5c72c29903813eJake Slack InputStream in = request.getInputStream(); 21703928aee4356845252ac6b662d5c72c29903813eJake Slack 21803928aee4356845252ac6b662d5c72c29903813eJake Slack 21903928aee4356845252ac6b662d5c72c29903813eJake Slack if (_putAtomic) 22003928aee4356845252ac6b662d5c72c29903813eJake Slack { 22103928aee4356845252ac6b662d5c72c29903813eJake Slack File tmp=File.createTempFile(file.getName(),null,_tmpdir); 22203928aee4356845252ac6b662d5c72c29903813eJake Slack OutputStream out = new FileOutputStream(tmp,false); 22303928aee4356845252ac6b662d5c72c29903813eJake Slack if (toRead >= 0) 22403928aee4356845252ac6b662d5c72c29903813eJake Slack IO.copy(in, out, toRead); 22503928aee4356845252ac6b662d5c72c29903813eJake Slack else 22603928aee4356845252ac6b662d5c72c29903813eJake Slack IO.copy(in, out); 22703928aee4356845252ac6b662d5c72c29903813eJake Slack out.close(); 22803928aee4356845252ac6b662d5c72c29903813eJake Slack 22903928aee4356845252ac6b662d5c72c29903813eJake Slack if (!tmp.renameTo(file)) 23003928aee4356845252ac6b662d5c72c29903813eJake Slack throw new IOException("rename from "+tmp+" to "+file+" failed"); 23103928aee4356845252ac6b662d5c72c29903813eJake Slack } 23203928aee4356845252ac6b662d5c72c29903813eJake Slack else 23303928aee4356845252ac6b662d5c72c29903813eJake Slack { 23403928aee4356845252ac6b662d5c72c29903813eJake Slack OutputStream out = new FileOutputStream(file,false); 23503928aee4356845252ac6b662d5c72c29903813eJake Slack if (toRead >= 0) 23603928aee4356845252ac6b662d5c72c29903813eJake Slack IO.copy(in, out, toRead); 23703928aee4356845252ac6b662d5c72c29903813eJake Slack else 23803928aee4356845252ac6b662d5c72c29903813eJake Slack IO.copy(in, out); 23903928aee4356845252ac6b662d5c72c29903813eJake Slack out.close(); 24003928aee4356845252ac6b662d5c72c29903813eJake Slack } 24103928aee4356845252ac6b662d5c72c29903813eJake Slack 24203928aee4356845252ac6b662d5c72c29903813eJake Slack response.setStatus(exists ? HttpServletResponse.SC_OK : HttpServletResponse.SC_CREATED); 24303928aee4356845252ac6b662d5c72c29903813eJake Slack response.flushBuffer(); 24403928aee4356845252ac6b662d5c72c29903813eJake Slack ok=true; 24503928aee4356845252ac6b662d5c72c29903813eJake Slack } 24603928aee4356845252ac6b662d5c72c29903813eJake Slack catch (Exception ex) 24703928aee4356845252ac6b662d5c72c29903813eJake Slack { 24803928aee4356845252ac6b662d5c72c29903813eJake Slack _context.log(ex.toString(),ex); 24903928aee4356845252ac6b662d5c72c29903813eJake Slack response.sendError(HttpServletResponse.SC_FORBIDDEN); 25003928aee4356845252ac6b662d5c72c29903813eJake Slack } 25103928aee4356845252ac6b662d5c72c29903813eJake Slack finally 25203928aee4356845252ac6b662d5c72c29903813eJake Slack { 25303928aee4356845252ac6b662d5c72c29903813eJake Slack if (!ok) 25403928aee4356845252ac6b662d5c72c29903813eJake Slack { 25503928aee4356845252ac6b662d5c72c29903813eJake Slack try 25603928aee4356845252ac6b662d5c72c29903813eJake Slack { 25703928aee4356845252ac6b662d5c72c29903813eJake Slack if (file.exists()) 25803928aee4356845252ac6b662d5c72c29903813eJake Slack file.delete(); 25903928aee4356845252ac6b662d5c72c29903813eJake Slack } 26003928aee4356845252ac6b662d5c72c29903813eJake Slack catch(Exception e) 26103928aee4356845252ac6b662d5c72c29903813eJake Slack { 26203928aee4356845252ac6b662d5c72c29903813eJake Slack _context.log(e.toString(),e); 26303928aee4356845252ac6b662d5c72c29903813eJake Slack } 26403928aee4356845252ac6b662d5c72c29903813eJake Slack } 26503928aee4356845252ac6b662d5c72c29903813eJake Slack _hidden.remove(pathInContext); 26603928aee4356845252ac6b662d5c72c29903813eJake Slack } 26703928aee4356845252ac6b662d5c72c29903813eJake Slack } 26803928aee4356845252ac6b662d5c72c29903813eJake Slack } 26903928aee4356845252ac6b662d5c72c29903813eJake Slack 27003928aee4356845252ac6b662d5c72c29903813eJake Slack /* ------------------------------------------------------------------- */ 27103928aee4356845252ac6b662d5c72c29903813eJake Slack public void handleDelete(HttpServletRequest request, HttpServletResponse response, String pathInContext, File file) throws ServletException, IOException 27203928aee4356845252ac6b662d5c72c29903813eJake Slack { 27303928aee4356845252ac6b662d5c72c29903813eJake Slack try 27403928aee4356845252ac6b662d5c72c29903813eJake Slack { 27503928aee4356845252ac6b662d5c72c29903813eJake Slack // delete the file 27603928aee4356845252ac6b662d5c72c29903813eJake Slack if (file.delete()) 27703928aee4356845252ac6b662d5c72c29903813eJake Slack { 27803928aee4356845252ac6b662d5c72c29903813eJake Slack response.setStatus(HttpServletResponse.SC_NO_CONTENT); 27903928aee4356845252ac6b662d5c72c29903813eJake Slack response.flushBuffer(); 28003928aee4356845252ac6b662d5c72c29903813eJake Slack } 28103928aee4356845252ac6b662d5c72c29903813eJake Slack else 28203928aee4356845252ac6b662d5c72c29903813eJake Slack response.sendError(HttpServletResponse.SC_FORBIDDEN); 28303928aee4356845252ac6b662d5c72c29903813eJake Slack } 28403928aee4356845252ac6b662d5c72c29903813eJake Slack catch (SecurityException sex) 28503928aee4356845252ac6b662d5c72c29903813eJake Slack { 28603928aee4356845252ac6b662d5c72c29903813eJake Slack _context.log(sex.toString(),sex); 28703928aee4356845252ac6b662d5c72c29903813eJake Slack response.sendError(HttpServletResponse.SC_FORBIDDEN); 28803928aee4356845252ac6b662d5c72c29903813eJake Slack } 28903928aee4356845252ac6b662d5c72c29903813eJake Slack } 29003928aee4356845252ac6b662d5c72c29903813eJake Slack 29103928aee4356845252ac6b662d5c72c29903813eJake Slack /* ------------------------------------------------------------------- */ 29203928aee4356845252ac6b662d5c72c29903813eJake Slack public void handleMove(HttpServletRequest request, HttpServletResponse response, String pathInContext, File file) 29303928aee4356845252ac6b662d5c72c29903813eJake Slack throws ServletException, IOException, URISyntaxException 29403928aee4356845252ac6b662d5c72c29903813eJake Slack { 29503928aee4356845252ac6b662d5c72c29903813eJake Slack String newPath = URIUtil.canonicalPath(request.getHeader("new-uri")); 29603928aee4356845252ac6b662d5c72c29903813eJake Slack if (newPath == null) 29703928aee4356845252ac6b662d5c72c29903813eJake Slack { 29803928aee4356845252ac6b662d5c72c29903813eJake Slack response.sendError(HttpServletResponse.SC_BAD_REQUEST); 29903928aee4356845252ac6b662d5c72c29903813eJake Slack return; 30003928aee4356845252ac6b662d5c72c29903813eJake Slack } 30103928aee4356845252ac6b662d5c72c29903813eJake Slack 30203928aee4356845252ac6b662d5c72c29903813eJake Slack String contextPath = request.getContextPath(); 30303928aee4356845252ac6b662d5c72c29903813eJake Slack if (contextPath != null && !newPath.startsWith(contextPath)) 30403928aee4356845252ac6b662d5c72c29903813eJake Slack { 30503928aee4356845252ac6b662d5c72c29903813eJake Slack response.sendError(HttpServletResponse.SC_METHOD_NOT_ALLOWED); 30603928aee4356845252ac6b662d5c72c29903813eJake Slack return; 30703928aee4356845252ac6b662d5c72c29903813eJake Slack } 30803928aee4356845252ac6b662d5c72c29903813eJake Slack String newInfo = newPath; 30903928aee4356845252ac6b662d5c72c29903813eJake Slack if (contextPath != null) 31003928aee4356845252ac6b662d5c72c29903813eJake Slack newInfo = newInfo.substring(contextPath.length()); 31103928aee4356845252ac6b662d5c72c29903813eJake Slack 31203928aee4356845252ac6b662d5c72c29903813eJake Slack String new_resource = URIUtil.addPaths(_baseURI,newInfo); 31303928aee4356845252ac6b662d5c72c29903813eJake Slack File new_file=new File(new URI(new_resource)); 31403928aee4356845252ac6b662d5c72c29903813eJake Slack 31503928aee4356845252ac6b662d5c72c29903813eJake Slack file.renameTo(new_file); 31603928aee4356845252ac6b662d5c72c29903813eJake Slack 31703928aee4356845252ac6b662d5c72c29903813eJake Slack response.setStatus(HttpServletResponse.SC_NO_CONTENT); 31803928aee4356845252ac6b662d5c72c29903813eJake Slack response.flushBuffer(); 31903928aee4356845252ac6b662d5c72c29903813eJake Slack } 32003928aee4356845252ac6b662d5c72c29903813eJake Slack 32103928aee4356845252ac6b662d5c72c29903813eJake Slack /* ------------------------------------------------------------ */ 32203928aee4356845252ac6b662d5c72c29903813eJake Slack public void handleOptions(FilterChain chain, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException 32303928aee4356845252ac6b662d5c72c29903813eJake Slack { 32403928aee4356845252ac6b662d5c72c29903813eJake Slack chain.doFilter(request,new HttpServletResponseWrapper(response) 32503928aee4356845252ac6b662d5c72c29903813eJake Slack { 32603928aee4356845252ac6b662d5c72c29903813eJake Slack @Override 32703928aee4356845252ac6b662d5c72c29903813eJake Slack public void setHeader(String name, String value) 32803928aee4356845252ac6b662d5c72c29903813eJake Slack { 32903928aee4356845252ac6b662d5c72c29903813eJake Slack if ("Allow".equalsIgnoreCase(name)) 33003928aee4356845252ac6b662d5c72c29903813eJake Slack { 33103928aee4356845252ac6b662d5c72c29903813eJake Slack Set<String> options = new HashSet<String>(); 33203928aee4356845252ac6b662d5c72c29903813eJake Slack options.addAll(Arrays.asList(value.split(" *, *"))); 33303928aee4356845252ac6b662d5c72c29903813eJake Slack options.addAll(_operations); 33403928aee4356845252ac6b662d5c72c29903813eJake Slack value=null; 33503928aee4356845252ac6b662d5c72c29903813eJake Slack for (String o : options) 33603928aee4356845252ac6b662d5c72c29903813eJake Slack value=value==null?o:(value+", "+o); 33703928aee4356845252ac6b662d5c72c29903813eJake Slack } 33803928aee4356845252ac6b662d5c72c29903813eJake Slack 33903928aee4356845252ac6b662d5c72c29903813eJake Slack super.setHeader(name,value); 34003928aee4356845252ac6b662d5c72c29903813eJake Slack } 34103928aee4356845252ac6b662d5c72c29903813eJake Slack }); 34203928aee4356845252ac6b662d5c72c29903813eJake Slack 34303928aee4356845252ac6b662d5c72c29903813eJake Slack } 34403928aee4356845252ac6b662d5c72c29903813eJake Slack 34503928aee4356845252ac6b662d5c72c29903813eJake Slack /* ------------------------------------------------------------ */ 34603928aee4356845252ac6b662d5c72c29903813eJake Slack /* 34703928aee4356845252ac6b662d5c72c29903813eJake Slack * Check modification date headers. 34803928aee4356845252ac6b662d5c72c29903813eJake Slack */ 34903928aee4356845252ac6b662d5c72c29903813eJake Slack protected boolean passConditionalHeaders(HttpServletRequest request, HttpServletResponse response, File file) throws IOException 35003928aee4356845252ac6b662d5c72c29903813eJake Slack { 35103928aee4356845252ac6b662d5c72c29903813eJake Slack long date = 0; 35203928aee4356845252ac6b662d5c72c29903813eJake Slack 35303928aee4356845252ac6b662d5c72c29903813eJake Slack if ((date = request.getDateHeader("if-unmodified-since")) > 0) 35403928aee4356845252ac6b662d5c72c29903813eJake Slack { 35503928aee4356845252ac6b662d5c72c29903813eJake Slack if (file.lastModified() / 1000 > date / 1000) 35603928aee4356845252ac6b662d5c72c29903813eJake Slack { 35703928aee4356845252ac6b662d5c72c29903813eJake Slack response.sendError(HttpServletResponse.SC_PRECONDITION_FAILED); 35803928aee4356845252ac6b662d5c72c29903813eJake Slack return false; 35903928aee4356845252ac6b662d5c72c29903813eJake Slack } 36003928aee4356845252ac6b662d5c72c29903813eJake Slack } 36103928aee4356845252ac6b662d5c72c29903813eJake Slack 36203928aee4356845252ac6b662d5c72c29903813eJake Slack if ((date = request.getDateHeader("if-modified-since")) > 0) 36303928aee4356845252ac6b662d5c72c29903813eJake Slack { 36403928aee4356845252ac6b662d5c72c29903813eJake Slack if (file.lastModified() / 1000 <= date / 1000) 36503928aee4356845252ac6b662d5c72c29903813eJake Slack { 36603928aee4356845252ac6b662d5c72c29903813eJake Slack response.reset(); 36703928aee4356845252ac6b662d5c72c29903813eJake Slack response.setStatus(HttpServletResponse.SC_NOT_MODIFIED); 36803928aee4356845252ac6b662d5c72c29903813eJake Slack response.flushBuffer(); 36903928aee4356845252ac6b662d5c72c29903813eJake Slack return false; 37003928aee4356845252ac6b662d5c72c29903813eJake Slack } 37103928aee4356845252ac6b662d5c72c29903813eJake Slack } 37203928aee4356845252ac6b662d5c72c29903813eJake Slack return true; 37303928aee4356845252ac6b662d5c72c29903813eJake Slack } 37403928aee4356845252ac6b662d5c72c29903813eJake Slack} 375