001/* 002 * (C) Copyright 2006-2011 Nuxeo SA (http://nuxeo.com/) and others. 003 * 004 * Licensed under the Apache License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * 008 * http://www.apache.org/licenses/LICENSE-2.0 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 013 * See the License for the specific language governing permissions and 014 * limitations under the License. 015 * 016 * Contributors: 017 * Gagnavarslan ehf 018 */ 019package org.nuxeo.ecm.webdav.service; 020 021import java.io.IOException; 022 023import javax.servlet.Filter; 024import javax.servlet.FilterChain; 025import javax.servlet.FilterConfig; 026import javax.servlet.ServletException; 027import javax.servlet.ServletRequest; 028import javax.servlet.ServletResponse; 029import javax.servlet.http.HttpServletRequest; 030import javax.servlet.http.HttpServletResponse; 031 032import org.apache.commons.lang3.StringUtils; 033import org.apache.commons.logging.Log; 034import org.apache.commons.logging.LogFactory; 035import org.nuxeo.ecm.platform.web.common.requestcontroller.filter.BufferingHttpServletResponse; 036import org.nuxeo.runtime.transaction.TransactionHelper; 037import org.nuxeo.runtime.transaction.TransactionRuntimeException; 038 039/** 040 * Windows Integration Request filter, bound to /nuxeo. Allows Windows user agents to bind to the root as the expect 041 * (not /nuxeo/site/dav) and still work. 042 */ 043public class WIRequestFilter implements Filter { 044 045 private static final Log log = LogFactory.getLog(WIRequestFilter.class); 046 047 public static final String WEBDAV_USERAGENT = "Microsoft-WebDAV-MiniRedir"; 048 049 public static final String MSOFFICE_USERAGENT = "Microsoft Office Existence Discovery"; 050 051 public static final String BACKEND_KEY = "org.nuxeo.ecm.webdav.service.backend"; 052 053 @Override 054 public void init(FilterConfig filterConfig) throws ServletException { 055 } 056 057 @Override 058 public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, 059 ServletException { 060 061 HttpServletRequest httpRequest = (HttpServletRequest) request; 062 HttpServletResponse httpResponse = (HttpServletResponse) response; 063 064 if (!isWIRequest(httpRequest)) { 065 chain.doFilter(request, response); 066 return; 067 } 068 069 // do what WebEngineFilter does: 070 // - start a transaction 071 // - do response buffering 072 boolean txStarted = false; 073 boolean ok = false; 074 try { 075 if (!TransactionHelper.isTransactionActive()) { 076 txStarted = TransactionHelper.startTransaction(); 077 if (!txStarted) { 078 throw new ServletException("A transaction is needed."); 079 } 080 response = new BufferingHttpServletResponse(httpResponse); 081 } 082 chain.doFilter(request, response); 083 ok = true; 084 } finally { 085 if (txStarted) { 086 try { 087 if (!ok) { 088 TransactionHelper.setTransactionRollbackOnly(); 089 } 090 TransactionHelper.commitOrRollbackTransaction(); 091 } catch (TransactionRuntimeException e) { 092 // commit failed, report this to the client before stopping buffering 093 ((HttpServletResponse) response).sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, 094 e.getMessage()); 095 log.error(e); // don't rethrow inside finally 096 } finally { 097 ((BufferingHttpServletResponse) response).stopBuffering(); 098 } 099 } 100 } 101 } 102 103 @Override 104 public void destroy() { 105 } 106 107 private boolean isWIRequest(HttpServletRequest request) { 108 String ua = request.getHeader("User-Agent"); 109 return StringUtils.isNotEmpty(ua) && (ua.contains(WEBDAV_USERAGENT) || ua.contains(MSOFFICE_USERAGENT)); 110 } 111 112}