001/* 002 * (C) Copyright 2006-2011 Nuxeo SA (http://nuxeo.com/) and contributors. 003 * 004 * All rights reserved. This program and the accompanying materials 005 * are made available under the terms of the GNU Lesser General Public License 006 * (LGPL) version 2.1 which accompanies this distribution, and is available at 007 * http://www.gnu.org/licenses/lgpl.html 008 * 009 * This library is distributed in the hope that it will be useful, 010 * but WITHOUT ANY WARRANTY; without even the implied warranty of 011 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 012 * Lesser General Public License for more details. 013 * 014 * Contributors: 015 * Gagnavarslan ehf 016 */ 017package org.nuxeo.ecm.webdav.service; 018 019import java.io.IOException; 020 021import javax.servlet.Filter; 022import javax.servlet.FilterChain; 023import javax.servlet.FilterConfig; 024import javax.servlet.ServletException; 025import javax.servlet.ServletRequest; 026import javax.servlet.ServletResponse; 027import javax.servlet.http.HttpServletRequest; 028import javax.servlet.http.HttpServletResponse; 029 030import org.apache.commons.lang.StringUtils; 031import org.nuxeo.ecm.platform.web.common.requestcontroller.filter.BufferingHttpServletResponse; 032import org.nuxeo.runtime.transaction.TransactionHelper; 033import org.nuxeo.runtime.transaction.TransactionRuntimeException; 034 035/** 036 * Windows Integration Request filter, bound to /nuxeo. Allows Windows user agents to bind to the root as the expect 037 * (not /nuxeo/site/dav) and still work. 038 */ 039public class WIRequestFilter implements Filter { 040 041 public static String WEBDAV_USERAGENT = "Microsoft-WebDAV-MiniRedir"; 042 043 public static String MSOFFICE_USERAGENT = "Microsoft Office Existence Discovery"; 044 045 public static final String BACKEND_KEY = "org.nuxeo.ecm.webdav.service.backend"; 046 047 @Override 048 public void init(FilterConfig filterConfig) throws ServletException { 049 } 050 051 @Override 052 public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, 053 ServletException { 054 055 HttpServletRequest httpRequest = (HttpServletRequest) request; 056 HttpServletResponse httpResponse = (HttpServletResponse) response; 057 058 if (!isWIRequest(httpRequest)) { 059 chain.doFilter(request, response); 060 return; 061 } 062 063 // do what WebEngineFilter does: 064 // - start a transaction 065 // - do response buffering 066 boolean txStarted = false; 067 boolean ok = false; 068 try { 069 if (!TransactionHelper.isTransactionActive()) { 070 txStarted = TransactionHelper.startTransaction(); 071 if (!txStarted) { 072 throw new ServletException("A transaction is needed."); 073 } 074 response = new BufferingHttpServletResponse(httpResponse); 075 } 076 chain.doFilter(request, response); 077 ok = true; 078 } finally { 079 if (txStarted) { 080 try { 081 if (!ok) { 082 TransactionHelper.setTransactionRollbackOnly(); 083 } 084 TransactionHelper.commitOrRollbackTransaction(); 085 } catch (TransactionRuntimeException e) { 086 // commit failed, report this to the client before stopping buffering 087 ((HttpServletResponse) response).sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, 088 e.getMessage()); 089 throw e; 090 } finally { 091 ((BufferingHttpServletResponse) response).stopBuffering(); 092 } 093 } 094 } 095 } 096 097 @Override 098 public void destroy() { 099 } 100 101 private boolean isWIRequest(HttpServletRequest request) { 102 String ua = request.getHeader("User-Agent"); 103 return StringUtils.isNotEmpty(ua) && (ua.contains(WEBDAV_USERAGENT) || ua.contains(MSOFFICE_USERAGENT)); 104 } 105 106}