| /******************************************************************************* |
| * Licensed to the Apache Software Foundation (ASF) under one |
| * or more contributor license agreements. See the NOTICE file |
| * distributed with this work for additional information |
| * regarding copyright ownership. The ASF licenses this file |
| * to you under the Apache License, Version 2.0 (the |
| * "License"); you may not use this file except in compliance |
| * with the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, |
| * software distributed under the License is distributed on an |
| * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
| * KIND, either express or implied. See the License for the |
| * specific language governing permissions and limitations |
| * under the License. |
| *******************************************************************************/ |
| package org.apache.ofbiz.product.category; |
| |
| import java.io.IOException; |
| import java.net.URL; |
| import java.util.ArrayList; |
| import java.util.Collection; |
| import java.util.HashSet; |
| import java.util.Iterator; |
| import java.util.List; |
| import java.util.Map; |
| import java.util.Set; |
| |
| import javax.servlet.Filter; |
| import javax.servlet.FilterChain; |
| import javax.servlet.FilterConfig; |
| import javax.servlet.RequestDispatcher; |
| import javax.servlet.ServletException; |
| import javax.servlet.ServletRegistration; |
| import javax.servlet.ServletRequest; |
| import javax.servlet.ServletResponse; |
| import javax.servlet.http.HttpServletRequest; |
| import javax.servlet.http.HttpServletResponse; |
| |
| import org.apache.oro.text.regex.Pattern; |
| import org.apache.oro.text.regex.Perl5Matcher; |
| import org.apache.ofbiz.base.util.Debug; |
| import org.apache.ofbiz.base.util.StringUtil; |
| import org.apache.ofbiz.base.util.UtilHttp; |
| import org.apache.ofbiz.base.util.UtilValidate; |
| import org.apache.ofbiz.webapp.control.ConfigXMLReader; |
| import org.apache.ofbiz.webapp.control.ConfigXMLReader.ControllerConfig; |
| import org.apache.ofbiz.webapp.control.ControlFilter; |
| import org.apache.ofbiz.webapp.control.WebAppConfigurationException; |
| |
| /** |
| * SeoContextFilter - Restricts access to raw files and configures servlet objects. |
| */ |
| public class SeoContextFilter implements Filter { |
| |
| public static final String module = SeoContextFilter.class.getName(); |
| |
| protected Set<String> WebServlets = new HashSet<>(); |
| private FilterConfig config; |
| private String allowedPaths = ""; |
| private String redirectPath = ""; |
| private String errorCode = ""; |
| private List<String> allowedPathList = new ArrayList<String>(); |
| |
| public void init(FilterConfig config) throws ServletException { |
| this.config = config; |
| allowedPaths = config.getInitParameter("allowedPaths"); |
| redirectPath = config.getInitParameter("redirectPath"); |
| errorCode = config.getInitParameter("errorCode"); |
| if (UtilValidate.isNotEmpty(allowedPaths)) { |
| allowedPathList = StringUtil.split(allowedPaths, ":"); |
| } |
| |
| Map<String, ? extends ServletRegistration> servletRegistrations = config.getServletContext().getServletRegistrations(); |
| for (String key : servletRegistrations.keySet()) { |
| Collection<String> servlets = servletRegistrations.get(key).getMappings(); |
| for (String servlet : servlets) { |
| if (servlet.endsWith("/*")) { |
| servlet = servlet.substring(0, servlet.length() - 2); |
| if (UtilValidate.isNotEmpty(servlet) && !WebServlets.contains(servlet)) { |
| WebServlets.add(servlet); |
| } |
| } |
| } |
| } |
| } |
| |
| /** |
| * @see javax.servlet.Filter#doFilter(javax.servlet.ServletRequest, javax.servlet.ServletResponse, javax.servlet.FilterChain) |
| */ |
| public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { |
| HttpServletRequest httpRequest = (HttpServletRequest) request; |
| HttpServletResponse httpResponse = (HttpServletResponse) response; |
| |
| String uri = httpRequest.getRequestURI(); |
| boolean forwarded = forwardUri(httpResponse, uri); |
| if (forwarded) { |
| return; |
| } |
| |
| URL controllerConfigURL = ConfigXMLReader.getControllerConfigURL(config.getServletContext()); |
| ControllerConfig controllerConfig = null; |
| Map<String, ConfigXMLReader.RequestMap> requestMaps = null; |
| try { |
| controllerConfig = ConfigXMLReader.getControllerConfig(controllerConfigURL); |
| requestMaps = controllerConfig.getRequestMapMap(); |
| } catch (WebAppConfigurationException e) { |
| Debug.logError(e, "Exception thrown while parsing controller.xml file: ", module); |
| throw new ServletException(e); |
| } |
| Set<String> uris = requestMaps.keySet(); |
| |
| // test to see if we have come through the control servlet already, if not do the processing |
| String requestPath = null; |
| String contextUri = null; |
| if (httpRequest.getAttribute(ControlFilter.FORWARDED_FROM_SERVLET) == null) { |
| requestPath = httpRequest.getServletPath(); |
| if (requestPath == null) requestPath = ""; |
| if (requestPath.lastIndexOf("/") > 0) { |
| if (requestPath.indexOf("/") == 0) { |
| requestPath = "/" + requestPath.substring(1, requestPath.indexOf("/", 1)); |
| } else { |
| requestPath = requestPath.substring(1, requestPath.indexOf("/")); |
| } |
| } |
| |
| String requestInfo = httpRequest.getServletPath(); |
| if (requestInfo == null) requestInfo = ""; |
| if (requestInfo.lastIndexOf("/") >= 0) { |
| requestInfo = requestInfo.substring(0, requestInfo.lastIndexOf("/")) + "/*"; |
| } |
| |
| StringBuilder contextUriBuffer = new StringBuilder(); |
| if (httpRequest.getContextPath() != null) { |
| contextUriBuffer.append(httpRequest.getContextPath()); |
| } |
| if (httpRequest.getServletPath() != null) { |
| contextUriBuffer.append(httpRequest.getServletPath()); |
| } |
| if (httpRequest.getPathInfo() != null) { |
| contextUriBuffer.append(httpRequest.getPathInfo()); |
| } |
| contextUri = contextUriBuffer.toString(); |
| |
| List<String> pathItemList = StringUtil.split(httpRequest.getPathInfo(), "/"); |
| String viewName = ""; |
| if (pathItemList != null) { |
| viewName = pathItemList.get(0); |
| } |
| |
| String requestUri = UtilHttp.getRequestUriFromTarget(httpRequest.getRequestURI()); |
| |
| // check to make sure the requested url is allowed |
| if (!allowedPathList.contains(requestPath) && !allowedPathList.contains(requestInfo) && !allowedPathList.contains(httpRequest.getServletPath()) |
| && !allowedPathList.contains(requestUri) && !allowedPathList.contains("/" + viewName) |
| && (UtilValidate.isEmpty(requestPath) && UtilValidate.isEmpty(httpRequest.getServletPath()) && !uris.contains(viewName))) { |
| String filterMessage = "[Filtered request]: " + contextUri; |
| |
| if (redirectPath == null) { |
| if (UtilValidate.isEmpty(viewName)) { |
| // redirect without any url change in browser |
| RequestDispatcher rd = request.getRequestDispatcher(SeoControlServlet.defaultPage); |
| rd.forward(request, response); |
| } else { |
| int error = 404; |
| if (UtilValidate.isNotEmpty(errorCode)) { |
| try { |
| error = Integer.parseInt(errorCode); |
| } catch (NumberFormatException nfe) { |
| Debug.logWarning(nfe, "Error code specified would not parse to Integer : " + errorCode, module); |
| } |
| } |
| filterMessage = filterMessage + " (" + error + ")"; |
| httpResponse.sendError(error, contextUri); |
| request.setAttribute("filterRequestUriError", contextUri); |
| } |
| } else { |
| filterMessage = filterMessage + " (" + redirectPath + ")"; |
| if (!redirectPath.toLowerCase().startsWith("http")) { |
| redirectPath = httpRequest.getContextPath() + redirectPath; |
| } |
| // httpResponse.sendRedirect(redirectPath); |
| if (uri.equals("") || uri.equals("/")) { |
| // redirect without any url change in browser |
| RequestDispatcher rd = request.getRequestDispatcher(redirectPath); |
| rd.forward(request, response); |
| } else { |
| // redirect with url change in browser |
| httpResponse.setStatus(SeoConfigUtil.getDefaultResponseCode()); |
| httpResponse.setHeader("Location", redirectPath); |
| } |
| } |
| Debug.logWarning(filterMessage, module); |
| return; |
| } else if ((allowedPathList.contains(requestPath) || allowedPathList.contains(requestInfo) || allowedPathList.contains(httpRequest.getServletPath()) |
| || allowedPathList.contains(requestUri) || allowedPathList.contains("/" + viewName)) |
| && !WebServlets.contains(httpRequest.getServletPath())) { |
| request.setAttribute(SeoControlServlet.REQUEST_IN_ALLOW_LIST, Boolean.TRUE); |
| } |
| } |
| |
| |
| // we're done checking; continue on |
| chain.doFilter(httpRequest, httpResponse); |
| } |
| |
| @Override |
| public void destroy() { |
| |
| } |
| |
| /** |
| * Forward a uri according to forward pattern regular expressions. Note: this is developed for Filter usage. |
| * |
| * @param uri String to reverse transform |
| * @return String |
| */ |
| protected static boolean forwardUri(HttpServletResponse response, String uri) { |
| Perl5Matcher matcher = new Perl5Matcher(); |
| boolean foundMatch = false; |
| Integer responseCodeInt = null; |
| |
| if (SeoConfigUtil.checkUseUrlRegexp() && SeoConfigUtil.getSeoPatterns() != null && SeoConfigUtil.getForwardReplacements() != null) { |
| Iterator<String> keys = SeoConfigUtil.getSeoPatterns().keySet().iterator(); |
| while (keys.hasNext()) { |
| String key = keys.next(); |
| Pattern pattern = SeoConfigUtil.getSeoPatterns().get(key); |
| String replacement = SeoConfigUtil.getForwardReplacements().get(key); |
| if (matcher.matches(uri, pattern)) { |
| for (int i = matcher.getMatch().groups(); i > 0; i--) { |
| replacement = replacement.replaceAll("\\$" + i, matcher.getMatch().group(i)); |
| } |
| uri = replacement; |
| responseCodeInt = SeoConfigUtil.getForwardResponseCodes().get(key); |
| foundMatch = true; |
| // be careful, we don't break after finding a match |
| } |
| } |
| } |
| |
| if (foundMatch) { |
| if (responseCodeInt == null) { |
| response.setStatus(SeoConfigUtil.getDefaultResponseCode()); |
| } else { |
| response.setStatus(responseCodeInt.intValue()); |
| } |
| response.setHeader("Location", uri); |
| } else { |
| Debug.logInfo("Can NOT forward this url: " + uri, module); |
| } |
| return foundMatch; |
| } |
| } |