/** * <a href="http://www.openolat.org"> * OpenOLAT - Online Learning and Training</a><br> * <p> * Licensed under the Apache License, Version 2.0 (the "License"); <br> * you may not use this file except in compliance with the License.<br> * You may obtain a copy of the License at the * <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache homepage</a> * <p> * Unless required by applicable law or agreed to in writing,<br> * software distributed under the License is distributed on an "AS IS" BASIS, <br> * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. <br> * See the License for the specific language governing permissions and <br> * limitations under the License. * <p> * Initial code contributed and copyrighted by<br> * frentix GmbH, http://www.frentix.com * <p> */ package org.olat.core.servlets; import java.io.IOException; import java.util.HashMap; import java.util.Map; import javax.servlet.RequestDispatcher; import javax.servlet.ServletConfig; import javax.servlet.ServletException; import javax.servlet.annotation.MultipartConfig; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.olat.admin.sysinfo.manager.SessionStatsManager; import org.olat.core.CoreSpringFactory; import org.olat.core.commons.persistence.DBFactory; import org.olat.core.commons.services.taskexecutor.TaskExecutorManager; import org.olat.core.commons.services.webdav.WebDAVDispatcher; import org.olat.core.configuration.AbstractOLATModule; import org.olat.core.configuration.AbstractSpringModule; import org.olat.core.configuration.PreWarm; import org.olat.core.dispatcher.Dispatcher; import org.olat.core.dispatcher.DispatcherModule; import org.olat.core.dispatcher.mapper.GlobalMapperRegistry; import org.olat.core.dispatcher.mapper.MapperDispatcher; import org.olat.core.extensions.ExtManager; import org.olat.core.helpers.Settings; import org.olat.core.logging.OLog; import org.olat.core.logging.Tracing; import org.olat.core.logging.activity.ThreadLocalUserActivityLoggerInstaller; import org.olat.core.util.StringHelper; import org.olat.core.util.WebappHelper; import org.olat.core.util.WorkThreadInformations; import org.olat.core.util.event.FrameworkStartupEventChannel; import org.olat.core.util.i18n.I18nManager; import org.olat.core.util.threadlog.RequestBasedLogLevelManager; import org.olat.core.util.threadlog.UserBasedLogLevelManager; @MultipartConfig(fileSizeThreshold=10240) public class OpenOLATServlet extends HttpServlet { private static final long serialVersionUID = -2777749229549683775L; private static final OLog log = Tracing.createLoggerFor(OpenOLATServlet.class); private static final String METHOD_PROPFIND = "PROPFIND"; private static final String METHOD_PROPPATCH = "PROPPATCH"; private static final String METHOD_MKCOL = "MKCOL"; private static final String METHOD_COPY = "COPY"; private static final String METHOD_MOVE = "MOVE"; private static final String METHOD_LOCK = "LOCK"; private static final String METHOD_UNLOCK = "UNLOCK"; private String legacyContext; private DispatcherModule dispatcherModule; private SessionStatsManager sessionStatsManager; private RequestBasedLogLevelManager requestBasedLogLevelManager; private WebDAVDispatcher webDAVDispatcher; private Map<String, Dispatcher> dispatchers; /** * @see javax.servlet.Servlet#init(javax.servlet.ServletConfig) */ @Override public void init(ServletConfig servletConfig) throws ServletException { super.init(servletConfig); requestBasedLogLevelManager = RequestBasedLogLevelManager.getInstance(); if (requestBasedLogLevelManager==null) { log.info("init: RequestBasedLogLevelManager is not configured on this system."); } else { log.info("init: RequestBasedLogLevelManager is configured and will be used."); } if (UserBasedLogLevelManager.getInstance()==null) { log.info("init: UserBasedLogLevelManager is not configured on this system."); } else { log.info("init: UserBasedLogLevelManager is configured and will be used."); } //the servlet.init method gets called after the spring stuff and all the stuff in web.xml is done log.info("Framework has started, sending event to listeners of FrameworkStartupEventChannel"); FrameworkStartupEventChannel.fireEvent(); log.info("FrameworkStartupEvent processed by alle listeners. Webapp has started."); sessionStatsManager = CoreSpringFactory.getImpl(SessionStatsManager.class); dispatcherModule = CoreSpringFactory.getImpl(DispatcherModule.class); dispatchers = new HashMap<String, Dispatcher>(dispatcherModule.getDispatchers()); dispatchers.put(DispatcherModule.PATH_MAPPED, new MapperDispatcher()); dispatchers.put(DispatcherModule.PATH_GLOBAL_MAPPED, GlobalMapperRegistry.getInstance()); webDAVDispatcher = CoreSpringFactory.getImpl(WebDAVDispatcher.class); dispatchers.put(DispatcherModule.WEBDAV_PATH, webDAVDispatcher); Settings settings = CoreSpringFactory.getImpl(Settings.class); if(StringHelper.containsNonWhitespace(settings.getLegacyContext())) { legacyContext = settings.getLegacyContext(); // same pattern as dispatcher: /olat/ if(!legacyContext.startsWith("/")) { legacyContext = "/" + legacyContext; } if(!legacyContext.endsWith("/")) { legacyContext += "/"; } } //preload extensions ExtManager.getInstance().getExtensions(); AbstractOLATModule.printStats(); AbstractSpringModule.printStats(); preWarm(); } private void preWarm() { TaskExecutorManager executor = CoreSpringFactory.getImpl(TaskExecutorManager.class); Map<String,PreWarm> preWarms = CoreSpringFactory.getBeansOfType(PreWarm.class); for(PreWarm preWarm:preWarms.values()) { executor.execute(preWarm); } } @Override protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { /*if(!req.getPathInfo().startsWith("/m/")) { log.info(req.getMethod() + " :: " + req.getPathInfo()); ServletUtil.printOutRequestParameters(req); }*/ Tracing.setUreq(req); ThreadLocalUserActivityLoggerInstaller.initUserActivityLogger(req); WorkThreadInformations.set("Serve request: " + req.getRequestURI()); if(sessionStatsManager != null) { sessionStatsManager.incrementRequest(); sessionStatsManager.incrementConcurrentCounter(); } try{ final String method = req.getMethod(); if (method.equals(METHOD_PROPFIND)) { webDAVDispatcher.execute(req, resp); } else if (method.equals(METHOD_PROPPATCH)) { webDAVDispatcher.execute(req, resp); } else if (method.equals(METHOD_MKCOL)) { webDAVDispatcher.execute(req, resp); } else if (method.equals(METHOD_COPY)) { webDAVDispatcher.execute(req, resp); } else if (method.equals(METHOD_MOVE)) { webDAVDispatcher.execute(req, resp); } else if (method.equals(METHOD_LOCK)) { webDAVDispatcher.execute(req, resp); } else if (method.equals(METHOD_UNLOCK)) { webDAVDispatcher.execute(req, resp); } else { super.service(req, resp); } } finally { if (requestBasedLogLevelManager != null) { requestBasedLogLevelManager.deactivateRequestBasedLogLevel(); } if(sessionStatsManager != null) { sessionStatsManager.decrementConcurrentCounter(); } WorkThreadInformations.unset(); ThreadLocalUserActivityLoggerInstaller.resetUserActivityLogger(); I18nManager.remove18nInfoFromThread(); Tracing.setUreq(null); //let it at the end DBFactory.getInstance().commitAndCloseSession(); } } @Override protected void doOptions(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { String subContext = DispatcherModule.getFirstPath(req); if("/".equals(subContext)) { webDAVDispatcher.doRootOptions(req, resp); } else if("/webdav".equals(subContext) || "/webdav/".equals(subContext)) { webDAVDispatcher.doWebdavOptions(req, resp); } else { super.doOptions(req, resp); } } /** * Called when the HTTP request method is GET. This method just calls the * doPost() method. * * @param request The HTTP request * @param response The HTTP response * @throws ServletException * @throws IOException */ public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { executeUserRequest(request, response); } /** * Called when the HTTP request method is POST. This method provides the main * control logic. * * @param request The HTTP request * @param response The HTTP response * @throws ServletException * @throws IOException */ public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { executeUserRequest(request, response); } @Override protected void doPut(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { webDAVDispatcher.execute(req, resp); } @Override protected void doDelete(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { webDAVDispatcher.execute(req, resp); } @Override protected void doHead(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { String subContext = DispatcherModule.getFirstPath(req); if("/".equals(subContext)) { webDAVDispatcher.execute(req, resp); } else if("/webdav".equals(subContext) || "/webdav/".equals(subContext)) { webDAVDispatcher.execute(req, resp); } else { executeUserRequest(req, resp); } } /** * Initialize tracing with request, this allows debugging information as IP, User-Agent. * @param request * @param response */ private void executeUserRequest(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { if (requestBasedLogLevelManager != null) { requestBasedLogLevelManager.activateRequestBasedLogLevel(request); } final String dispatcherName = DispatcherModule.getFirstPath(request); if(dispatcherName != null && !dispatcherName.startsWith("/webdav")) { String userAgent = request.getHeader("User-Agent"); if(userAgent != null && userAgent.indexOf("BitKinex") >= 0) { //BitKinex isn't allow to see this context response.sendError(HttpServletResponse.SC_FORBIDDEN); return; } } if(legacyContext != null && legacyContext.equals(dispatcherName)) { String uri = request.getRequestURI(); String redirectUri = uri.substring(legacyContext.length() - 1, uri.length()); RequestDispatcher dispatcher = request.getRequestDispatcher(redirectUri); dispatcher.forward(request, response); } else if(dispatchers.containsKey(dispatcherName)) { I18nManager.attachI18nInfoToThread(request); Dispatcher dispatcher = dispatchers.get(dispatcherName); dispatcher.execute(request, response); } else { //root -> redirect to dmz if("/".equals(dispatcherName)) { redirectToDmz(response); } else if("/dmz".equals(dispatcherName)) { redirectToDmz(response); } else { String uri = request.getRequestURI(); if(uri != null && uri.contains("/raw/_noversion_/")) { //cut and redirect int index = uri.indexOf("/raw/_noversion_/"); if(index > 0) { String redirectUri = Settings.getServerContextPathURI() + uri.substring(index, uri.length()); response.sendRedirect(redirectUri); } else { response.sendError(HttpServletResponse.SC_NOT_FOUND); } } else { response.sendError(HttpServletResponse.SC_NOT_FOUND); } } } } private void redirectToDmz(HttpServletResponse response) throws IOException { String dmzUri = WebappHelper.getServletContextPath() + DispatcherModule.getPathDefault(); response.sendRedirect(dmzUri); } }