Author: shijh
Date: Wed Jun 27 05:48:59 2018 New Revision: 1834465 URL: http://svn.apache.org/viewvc?rev=1834465&view=rev Log: Implemented: Add method attribute to request-map to controll a uri can be called GET or POST only OFBIZ-10438 ControlServlet.java returned to the previous doGet/doPost structure. Thanks: Mathieu Lirzin for the contribution. Added: ofbiz/ofbiz-framework/trunk/framework/webapp/src/main/java/org/apache/ofbiz/webapp/control/MethodNotAllowedException.java (with props) Modified: ofbiz/ofbiz-framework/trunk/framework/webapp/config/WebappUiLabels.xml ofbiz/ofbiz-framework/trunk/framework/webapp/src/main/java/org/apache/ofbiz/webapp/control/ControlServlet.java ofbiz/ofbiz-framework/trunk/framework/webapp/src/main/java/org/apache/ofbiz/webapp/control/RequestHandler.java ofbiz/ofbiz-framework/trunk/framework/webapp/src/test/java/org/apache/ofbiz/webapp/control/RequestHandlerTests.java Modified: ofbiz/ofbiz-framework/trunk/framework/webapp/config/WebappUiLabels.xml URL: http://svn.apache.org/viewvc/ofbiz/ofbiz-framework/trunk/framework/webapp/config/WebappUiLabels.xml?rev=1834465&r1=1834464&r2=1834465&view=diff ============================================================================== --- ofbiz/ofbiz-framework/trunk/framework/webapp/config/WebappUiLabels.xml (original) +++ ofbiz/ofbiz-framework/trunk/framework/webapp/config/WebappUiLabels.xml Wed Jun 27 05:48:59 2018 @@ -340,7 +340,7 @@ <value xml:lang="zh-TW">æ²æå®æäºä»¶</value> </property> <property key="RequestMethodNotMatchConfig"> - <value xml:lang="en">[{0}] is restricted to be a [{1}] request, cannot be called by [{2}] method.</value> - <value xml:lang="zh">[{0}]å¿ é¡»ä½¿ç¨[{1}]æ¹æ³è¯·æ±ï¼ä¸è½ç¨[{2}]æ¹æ³è¯·æ±ã</value> + <value xml:lang="en">[{0}] cannot be called by [{1}] method.</value> + <value xml:lang="zh">[{0}]ä¸è½ç¨[{1}]æ¹æ³è¯·æ±ã</value> </property> </resource> Modified: ofbiz/ofbiz-framework/trunk/framework/webapp/src/main/java/org/apache/ofbiz/webapp/control/ControlServlet.java URL: http://svn.apache.org/viewvc/ofbiz/ofbiz-framework/trunk/framework/webapp/src/main/java/org/apache/ofbiz/webapp/control/ControlServlet.java?rev=1834465&r1=1834464&r2=1834465&view=diff ============================================================================== --- ofbiz/ofbiz-framework/trunk/framework/webapp/src/main/java/org/apache/ofbiz/webapp/control/ControlServlet.java (original) +++ ofbiz/ofbiz-framework/trunk/framework/webapp/src/main/java/org/apache/ofbiz/webapp/control/ControlServlet.java Wed Jun 27 05:48:59 2018 @@ -19,7 +19,6 @@ package org.apache.ofbiz.webapp.control; import java.io.IOException; -import java.net.URL; import java.util.Enumeration; import javax.servlet.RequestDispatcher; @@ -30,14 +29,11 @@ import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpSession; -import javax.ws.rs.core.MultivaluedMap; import org.apache.ofbiz.base.util.Debug; import org.apache.ofbiz.base.util.UtilCodec; import org.apache.ofbiz.base.util.UtilGenerics; import org.apache.ofbiz.base.util.UtilHttp; -import org.apache.ofbiz.base.util.UtilMisc; -import org.apache.ofbiz.base.util.UtilProperties; import org.apache.ofbiz.base.util.UtilTimer; import org.apache.ofbiz.base.util.UtilValidate; import org.apache.ofbiz.base.util.template.FreeMarkerWorker; @@ -49,7 +45,6 @@ import org.apache.ofbiz.entity.transacti import org.apache.ofbiz.entity.transaction.TransactionUtil; import org.apache.ofbiz.security.Security; import org.apache.ofbiz.service.LocalDispatcher; -import org.apache.ofbiz.webapp.control.ConfigXMLReader.RequestMap; import org.apache.ofbiz.webapp.stats.ServerHitBin; import org.apache.ofbiz.webapp.stats.VisitHandler; import org.apache.ofbiz.widget.renderer.VisualTheme; @@ -63,9 +58,6 @@ import freemarker.ext.servlet.ServletCon public class ControlServlet extends HttpServlet { public static final String module = ControlServlet.class.getName(); - private static final String METHOD_GET = "GET"; - private static final String METHOD_POST = "POST"; - private static final String REQUEST_METHOD_ALL = "all"; public ControlServlet() { super(); @@ -88,20 +80,20 @@ public class ControlServlet extends Http } /** - * Handle every HTTP methods. - * @see javax.servlet.http.HttpServlet#service + * @see javax.servlet.http.HttpServlet#doPost */ @Override - protected void service(HttpServletRequest request, HttpServletResponse response) + protected void doPost(HttpServletRequest request, HttpServletResponse response) + throws ServletException, IOException { + doGet(request, response); + } + + /** + * @see javax.servlet.http.HttpServlet#doGet + */ + @Override + protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { - String method = request.getMethod(); - if (!matchRequestMethod(request, response, method)) { - return; - } - if (!method.equals(METHOD_GET) && !method.equals(METHOD_POST)) { - super.service(request, response); - return; - } long requestStartTime = System.currentTimeMillis(); RequestHandler requestHandler = this.getRequestHandler(); HttpSession session = request.getSession(); @@ -221,6 +213,12 @@ public class ControlServlet extends Http try { // the ServerHitBin call for the event is done inside the doRequest method requestHandler.doRequest(request, response, null, userLogin, delegator); + } catch (MethodNotAllowedException e) { + response.setContentType("text/plain"); + response.setCharacterEncoding(request.getCharacterEncoding()); + response.setStatus(HttpServletResponse.SC_METHOD_NOT_ALLOWED); + response.getWriter().print(e.getMessage()); + Debug.logError(e.getMessage(), module); } catch (RequestHandlerException e) { Throwable throwable = e.getNested() != null ? e.getNested() : e; if (throwable instanceof IOException) { @@ -388,29 +386,4 @@ public class ControlServlet extends Http } if (Debug.verboseOn()) Debug.logVerbose("--- End ServletContext Attributes ---", module); } - - private boolean matchRequestMethod(HttpServletRequest request, HttpServletResponse response, String method) { - URL controllerConfigUrl = ConfigXMLReader.getControllerConfigURL(request.getServletContext()); - try { - ConfigXMLReader.ControllerConfig controllerConfig = ConfigXMLReader.getControllerConfig(controllerConfigUrl); - MultivaluedMap<String, RequestMap> requestMapMap = controllerConfig.getRequestMapMultiMap(); - if (UtilValidate.isEmpty(requestMapMap)) { - return true; - } - String uri = RequestHandler.getRequestUri(request.getPathInfo()); - RequestMap requestMap = requestMapMap.getFirst(uri); - if (UtilValidate.isEmpty(requestMap) || UtilValidate.isEmpty(requestMap.method) || REQUEST_METHOD_ALL.equalsIgnoreCase(requestMap.method) || method.equalsIgnoreCase(requestMap.method)) { - return true; - } - String errMsg = UtilProperties.getMessage("WebappUiLabels", "RequestMethodNotMatchConfig", UtilMisc.toList(uri, requestMap.method, method), UtilHttp.getLocale(request)); - response.setContentType("text/plain"); - response.setCharacterEncoding(request.getCharacterEncoding()); - response.setStatus(HttpServletResponse.SC_METHOD_NOT_ALLOWED); - response.getWriter().print(errMsg); - Debug.logError(errMsg, module); - } catch (WebAppConfigurationException | IOException e) { - Debug.logError("Error while loading " + controllerConfigUrl, module); - } - return false; - } } Added: ofbiz/ofbiz-framework/trunk/framework/webapp/src/main/java/org/apache/ofbiz/webapp/control/MethodNotAllowedException.java URL: http://svn.apache.org/viewvc/ofbiz/ofbiz-framework/trunk/framework/webapp/src/main/java/org/apache/ofbiz/webapp/control/MethodNotAllowedException.java?rev=1834465&view=auto ============================================================================== --- ofbiz/ofbiz-framework/trunk/framework/webapp/src/main/java/org/apache/ofbiz/webapp/control/MethodNotAllowedException.java (added) +++ ofbiz/ofbiz-framework/trunk/framework/webapp/src/main/java/org/apache/ofbiz/webapp/control/MethodNotAllowedException.java Wed Jun 27 05:48:59 2018 @@ -0,0 +1,9 @@ +package org.apache.ofbiz.webapp.control; + +class MethodNotAllowedException extends RequestHandlerException { + private static final long serialVersionUID = -8765719278480440687L; + + MethodNotAllowedException(String str) { + super(str); + } +} Propchange: ofbiz/ofbiz-framework/trunk/framework/webapp/src/main/java/org/apache/ofbiz/webapp/control/MethodNotAllowedException.java ------------------------------------------------------------------------------ svn:eol-style = native Propchange: ofbiz/ofbiz-framework/trunk/framework/webapp/src/main/java/org/apache/ofbiz/webapp/control/MethodNotAllowedException.java ------------------------------------------------------------------------------ svn:keywords = Date Rev Author URL Id Propchange: ofbiz/ofbiz-framework/trunk/framework/webapp/src/main/java/org/apache/ofbiz/webapp/control/MethodNotAllowedException.java ------------------------------------------------------------------------------ svn:mime-type = text/plain Modified: ofbiz/ofbiz-framework/trunk/framework/webapp/src/main/java/org/apache/ofbiz/webapp/control/RequestHandler.java URL: http://svn.apache.org/viewvc/ofbiz/ofbiz-framework/trunk/framework/webapp/src/main/java/org/apache/ofbiz/webapp/control/RequestHandler.java?rev=1834465&r1=1834464&r2=1834465&view=diff ============================================================================== --- ofbiz/ofbiz-framework/trunk/framework/webapp/src/main/java/org/apache/ofbiz/webapp/control/RequestHandler.java (original) +++ ofbiz/ofbiz-framework/trunk/framework/webapp/src/main/java/org/apache/ofbiz/webapp/control/RequestHandler.java Wed Jun 27 05:48:59 2018 @@ -24,6 +24,8 @@ import java.io.IOException; import java.io.Serializable; import java.net.URL; import java.security.cert.X509Certificate; + +import java.util.Collection; import java.util.Collections; import java.util.Enumeration; import java.util.HashMap; @@ -31,8 +33,6 @@ import java.util.List; import java.util.Locale; import java.util.Map; import java.util.Optional; -import java.util.function.Predicate; -import java.util.stream.Stream; import javax.servlet.ServletContext; import javax.servlet.http.HttpServletRequest; @@ -74,12 +74,77 @@ import org.apache.ofbiz.widget.model.The public class RequestHandler { public static final String module = RequestHandler.class.getName(); - private final String defaultStatusCodeString = UtilProperties.getPropertyValue("requestHandler", "status-code", "302"); + private final static String defaultStatusCodeString = + UtilProperties.getPropertyValue("requestHandler", "status-code", "302"); private final ViewFactory viewFactory; private final EventFactory eventFactory; private final URL controllerConfigURL; private final boolean trackServerHit; private final boolean trackVisit; + private Controller ctrl; + + static class Controller { + private final MultivaluedMap<String, RequestMap> requestMapMap; + private final Map<String, ConfigXMLReader.ViewMap> viewMapMap; + private String statusCodeString; + private final String defaultRequest; + private final Map<String, ConfigXMLReader.Event> firstVisitEventList; + private final Map<String, ConfigXMLReader.Event> preprocessorEventList; + private final Map<String, ConfigXMLReader.Event> postprocessorEventList; + private final String protectView; + + Controller(ConfigXMLReader.ControllerConfig ccfg) + throws WebAppConfigurationException { + preprocessorEventList = ccfg.getPreprocessorEventList(); + postprocessorEventList = ccfg.getPostprocessorEventList(); + requestMapMap = ccfg.getRequestMapMultiMap(); + viewMapMap = ccfg.getViewMapMap(); + defaultRequest = ccfg.getDefaultRequest(); + firstVisitEventList = ccfg.getFirstVisitEventList(); + protectView = ccfg.getProtectView(); + + String status = ccfg.getStatusCode(); + statusCodeString = UtilValidate.isEmpty(status) + ? defaultStatusCodeString + : status; + } + + public MultivaluedMap<String, RequestMap> getRequestMapMap() { + return requestMapMap; + } + + public Map<String, ConfigXMLReader.ViewMap> getViewMapMap() { + return viewMapMap; + } + + public String getStatusCodeString() { + return statusCodeString; + } + + public String getDefaultRequest() { + return defaultRequest; + } + + public void setStatusCodeString(String statusCodeString) { + this.statusCodeString = statusCodeString; + } + + public Map<String, ConfigXMLReader.Event> getFirstVisitEventList() { + return firstVisitEventList; + } + + public Map<String, ConfigXMLReader.Event> getPreprocessorEventList() { + return preprocessorEventList; + } + + public Map<String, ConfigXMLReader.Event> getPostprocessorEventList() { + return postprocessorEventList; + } + + public String getProtectView() { + return protectView; + } + } public static RequestHandler getRequestHandler(ServletContext servletContext) { RequestHandler rh = (RequestHandler) servletContext.getAttribute("_REQUEST_HANDLER_"); @@ -117,26 +182,56 @@ public class RequestHandler { } /** - * Find a request map in {@code reqMaps} matching {@code req}. - * Otherwise fall back to the one matching {@code defaultReq}. + * Find a collection of request maps in {@code ctrl} matching {@code req}. + * Otherwise fall back to matching the {@code defaultReq} field. * - * @param reqMaps The dictionary associating URI to request maps + * @param ctrl The controller containing the current configuration * @param req The HTTP request to match - * @param defaultReq the default request which serves as a fallback. - * @return an request map {@code Optional} + * @return a collection of request maps which might be empty */ - static Optional<RequestMap> resolveURI(MultivaluedMap<String, RequestMap> reqMaps, - HttpServletRequest req, String defaultReq) { - String path = getRequestUri(req.getPathInfo()); - List<RequestMap> rmaps = reqMaps.get(path); - if (rmaps == null && defaultReq != null) { - rmaps = reqMaps.get(defaultReq); - } - List<RequestMap> frmaps = (rmaps != null) ? rmaps : Collections.emptyList(); - return Stream.of(req.getMethod(), "all", "") - .map(verb -> (Predicate<String>) verb::equalsIgnoreCase) - .flatMap(p -> frmaps.stream().filter(m -> p.test(m.method))) - .findFirst(); + static Collection<RequestMap> resolveURI(Controller ctrl, + HttpServletRequest req) { + Map<String, List<RequestMap>> requestMapMap = ctrl.getRequestMapMap(); + Map<String, ConfigXMLReader.ViewMap> viewMapMap = ctrl.getViewMapMap(); + String defaultRequest = ctrl.getDefaultRequest(); + String path = req.getPathInfo(); + String requestUri = getRequestUri(path); + String viewUri = getOverrideViewUri(path); + Collection<RequestMap> rmaps; + if (requestMapMap.containsKey(requestUri) + && !viewMapMap.containsKey(viewUri)) { + rmaps = requestMapMap.get(requestUri); + } else if (defaultRequest != null) { + rmaps = requestMapMap.get(defaultRequest); + } else { + rmaps = null; + } + return rmaps != null ? rmaps : Collections.emptyList(); + } + + /** + * Find the request map matching {@code method}. + * Otherwise fall back to the one matching the "all" and "" special methods + * in that respective order. + * + * @param method the HTTP method to match + * @param rmaps the collection of request map candidates + * @return a request map {@code Optional} + */ + static Optional<RequestMap> resolveMethod(String method, + Collection<RequestMap> rmaps) { + for (RequestMap map : rmaps) { + if (map.method.equalsIgnoreCase(method)) { + return Optional.of(map); + } + } + if (method.isEmpty()) { + return Optional.empty(); + } else if (method.equals("all")) { + return resolveMethod("", rmaps); + } else { + return resolveMethod("all", rmaps); + } } public void doRequest(HttpServletRequest request, HttpServletResponse response, String requestUri) throws RequestHandlerException, RequestHandlerExceptionAllowExternalRequests { @@ -154,33 +249,17 @@ public class RequestHandler { long startTime = System.currentTimeMillis(); HttpSession session = request.getSession(); - // get the controllerConfig once for this method so we don't have to get it over and over inside the method - ConfigXMLReader.ControllerConfig controllerConfig = this.getControllerConfig(); - MultivaluedMap<String, ConfigXMLReader.RequestMap> requestMapMap = null; - String statusCodeString = null; + // Parse controller config. try { - requestMapMap = controllerConfig.getRequestMapMultiMap(); - statusCodeString = controllerConfig.getStatusCode(); + ctrl = new Controller(getControllerConfig()); } catch (WebAppConfigurationException e) { Debug.logError(e, "Exception thrown while parsing controller.xml file: ", module); throw new RequestHandlerException(e); } - if (UtilValidate.isEmpty(statusCodeString)) { - statusCodeString = defaultStatusCodeString; - } // workaround if we are in the root webapp String cname = UtilHttp.getApplicationName(request); - // Set the fallback default request. - String defaultRequest = null; - try { - defaultRequest = controllerConfig.getDefaultRequest(); - } catch (WebAppConfigurationException e) { - Debug.logError(e, "Exception thrown while parsing controller.xml file: ", module); - throw new RequestHandlerException(e); - } - // Grab data from request object to process String defaultRequestUri = RequestHandler.getRequestUri(request.getPathInfo()); if (request.getAttribute("targetRequestUri") == null) { @@ -191,32 +270,32 @@ public class RequestHandler { } } - String overrideViewUri = RequestHandler.getOverrideViewUri(request.getPathInfo()); - - String requestMissingErrorMessage = "Unknown request [" + defaultRequestUri + "]; this request does not exist or cannot be called directly."; - RequestMap requestMap = - resolveURI(requestMapMap, request, defaultRequest).orElse(null); - - // check for override view - if (overrideViewUri != null) { - try { - ConfigXMLReader.ViewMap viewMap = - controllerConfig.getViewMapMap().get(overrideViewUri); - if (viewMap == null && defaultRequest != null) { - requestMap = requestMapMap.getFirst(defaultRequest); - } - } catch (WebAppConfigurationException e) { - Debug.logError(e, "Exception thrown while parsing controller.xml file: ", module); - throw new RequestHandlerException(e); + String requestMissingErrorMessage = "Unknown request [" + + defaultRequestUri + + "]; this request does not exist or cannot be called directly."; + + String path = request.getPathInfo(); + String requestUri = getRequestUri(path); + String overrideViewUri = getOverrideViewUri(path); + + Collection<RequestMap> rmaps = resolveURI(ctrl, request); + if (rmaps.isEmpty()) { + if (throwRequestHandlerExceptionOnMissingLocalRequest) { + throw new RequestHandlerException(requestMissingErrorMessage); + } else { + throw new RequestHandlerExceptionAllowExternalRequests(); } } - // if no matching request is found in the controller, depending on throwRequestHandlerExceptionOnMissingLocalRequest - // we throw a RequestHandlerException or RequestHandlerExceptionAllowExternalRequests - if (requestMap == null) { - if (throwRequestHandlerExceptionOnMissingLocalRequest) throw new RequestHandlerException(requestMissingErrorMessage); - else throw new RequestHandlerExceptionAllowExternalRequests(); - } + String method = request.getMethod(); + RequestMap requestMap = resolveMethod(method, rmaps) + .orElseThrow(() -> { + String msg = UtilProperties.getMessage("WebappUiLabels", + "RequestMethodNotMatchConfig", + UtilMisc.toList(requestUri, method), + UtilHttp.getLocale(request)); + return new MethodNotAllowedException(msg); + }); String eventReturn = null; if (requestMap.metrics != null && requestMap.metrics.getThreshold() != 0.0 && requestMap.metrics.getTotalEvents() > 3 && requestMap.metrics.getThreshold() < requestMap.metrics.getServiceRate()) { @@ -228,7 +307,7 @@ public class RequestHandler { // Check for chained request. if (chain != null) { String chainRequestUri = RequestHandler.getRequestUri(chain); - requestMap = requestMapMap.getFirst(chainRequestUri); + requestMap = ctrl.getRequestMapMap().getFirst(chainRequestUri); if (requestMap == null) { throw new RequestHandlerException("Unknown chained request [" + chainRequestUri + "]; this request does not exist"); } @@ -252,11 +331,11 @@ public class RequestHandler { // Check to make sure we are allowed to access this request directly. (Also checks if this request is defined.) // If the request cannot be called, or is not defined, check and see if there is a default-request we can process if (!requestMap.securityDirectRequest) { - if (defaultRequest == null || !requestMapMap.getFirst(defaultRequest).securityDirectRequest) { + if (ctrl.getDefaultRequest() == null || !ctrl.getRequestMapMap().getFirst(ctrl.getDefaultRequest()).securityDirectRequest) { // use the same message as if it was missing for security reasons, ie so can't tell if it is missing or direct request is not allowed throw new RequestHandlerException(requestMissingErrorMessage); } else { - requestMap = requestMapMap.getFirst(defaultRequest); + requestMap = ctrl.getRequestMapMap().getFirst(ctrl.getDefaultRequest()); } } // Check if we SHOULD be secure and are not. @@ -299,7 +378,7 @@ public class RequestHandler { String newUrl = RequestHandler.makeUrl(request, response, urlBuf.toString()); if (newUrl.toUpperCase().startsWith("HTTPS")) { // if we are supposed to be secure, redirect secure. - callRedirect(newUrl, response, request, statusCodeString); + callRedirect(newUrl, response, request, ctrl.getStatusCodeString()); return; } } @@ -344,63 +423,52 @@ public class RequestHandler { if (Debug.infoOn()) Debug.logInfo("This is the first request in this visit." + showSessionId(request), module); session.setAttribute("_FIRST_VISIT_EVENTS_", "complete"); - try { - for (ConfigXMLReader.Event event: controllerConfig.getFirstVisitEventList().values()) { - try { - String returnString = this.runEvent(request, response, event, null, "firstvisit"); - if (returnString == null || "none".equalsIgnoreCase(returnString)) { - interruptRequest = true; - } else if (!"success".equalsIgnoreCase(returnString)) { - throw new EventHandlerException("First-Visit event did not return 'success'."); - } - } catch (EventHandlerException e) { - Debug.logError(e, module); + for (ConfigXMLReader.Event event: ctrl.getFirstVisitEventList().values()) { + try { + String returnString = this.runEvent(request, response, event, null, "firstvisit"); + if (returnString == null || "none".equalsIgnoreCase(returnString)) { + interruptRequest = true; + } else if (!"success".equalsIgnoreCase(returnString)) { + throw new EventHandlerException("First-Visit event did not return 'success'."); } + } catch (EventHandlerException e) { + Debug.logError(e, module); } - } catch (WebAppConfigurationException e) { - Debug.logError(e, "Exception thrown while parsing controller.xml file: ", module); - throw new RequestHandlerException(e); } } // Invoke the pre-processor (but NOT in a chain) - try { - for (ConfigXMLReader.Event event: controllerConfig.getPreprocessorEventList().values()) { - try { - String returnString = this.runEvent(request, response, event, null, "preprocessor"); - if (returnString == null || "none".equalsIgnoreCase(returnString)) { - interruptRequest = true; - } else if (!"success".equalsIgnoreCase(returnString)) { - if (!returnString.contains(":_protect_:")) { - throw new EventHandlerException("Pre-Processor event [" + event.invoke + "] did not return 'success'."); - } else { // protect the view normally rendered and redirect to error response view - returnString = returnString.replace(":_protect_:", ""); - if (returnString.length() > 0) { - request.setAttribute("_ERROR_MESSAGE_", returnString); - } - eventReturn = null; - // check to see if there is a "protect" response, if so it's ok else show the default_error_response_view - if (!requestMap.requestResponseMap.containsKey("protect")) { - String protectView = controllerConfig.getProtectView(); - if (protectView != null) { - overrideViewUri = protectView; - } else { - overrideViewUri = EntityUtilProperties.getPropertyValue("security", "default.error.response.view", delegator); - overrideViewUri = overrideViewUri.replace("view:", ""); - if ("none:".equals(overrideViewUri)) { - interruptRequest = true; - } + for (ConfigXMLReader.Event event: ctrl.getPreprocessorEventList().values()) { + try { + String returnString = this.runEvent(request, response, event, null, "preprocessor"); + if (returnString == null || "none".equalsIgnoreCase(returnString)) { + interruptRequest = true; + } else if (!"success".equalsIgnoreCase(returnString)) { + if (!returnString.contains(":_protect_:")) { + throw new EventHandlerException("Pre-Processor event [" + event.invoke + "] did not return 'success'."); + } else { // protect the view normally rendered and redirect to error response view + returnString = returnString.replace(":_protect_:", ""); + if (returnString.length() > 0) { + request.setAttribute("_ERROR_MESSAGE_", returnString); + } + eventReturn = null; + // check to see if there is a "protect" response, if so it's ok else show the default_error_response_view + if (!requestMap.requestResponseMap.containsKey("protect")) { + if (ctrl.getProtectView() != null) { + overrideViewUri = ctrl.getProtectView(); + } else { + overrideViewUri = EntityUtilProperties.getPropertyValue("security", "default.error.response.view", delegator); + overrideViewUri = overrideViewUri.replace("view:", ""); + if ("none:".equals(overrideViewUri)) { + interruptRequest = true; } } } } - } catch (EventHandlerException e) { - Debug.logError(e, module); } + } catch (EventHandlerException e) { + Debug.logError(e, module); } - } catch (WebAppConfigurationException e) { - Debug.logError(e, "Exception thrown while parsing controller.xml file: ", module); - throw new RequestHandlerException(e); } } @@ -420,8 +488,7 @@ public class RequestHandler { // Invoke the security handler // catch exceptions and throw RequestHandlerException if failed. if (Debug.verboseOn()) Debug.logVerbose("[RequestHandler]: AuthRequired. Running security check. " + showSessionId(request), module); - ConfigXMLReader.Event checkLoginEvent = - requestMapMap.getFirst("checkLogin").event; + ConfigXMLReader.Event checkLoginEvent = ctrl.getRequestMapMap().getFirst("checkLogin").event; String checkLoginReturnString = null; try { @@ -434,9 +501,9 @@ public class RequestHandler { eventReturn = checkLoginReturnString; // if the request is an ajax request we don't want to return the default login check if (!"XMLHttpRequest".equals(request.getHeader("X-Requested-With"))) { - requestMap = requestMapMap.getFirst("checkLogin"); + requestMap = ctrl.getRequestMapMap().getFirst("checkLogin"); } else { - requestMap = requestMapMap.getFirst("ajaxCheckLogin"); + requestMap = ctrl.getRequestMapMap().getFirst("ajaxCheckLogin"); } } } @@ -568,7 +635,7 @@ public class RequestHandler { redirectTarget += "?" + queryString; } - callRedirect(makeLink(request, response, redirectTarget), response, request, statusCodeString); + callRedirect(makeLink(request, response, redirectTarget), response, request, ctrl.getStatusCodeString()); return; } } @@ -615,41 +682,35 @@ public class RequestHandler { // ======== handle views ======== // first invoke the post-processor events. - try { - for (ConfigXMLReader.Event event: controllerConfig.getPostprocessorEventList().values()) { - try { - String returnString = this.runEvent(request, response, event, requestMap, "postprocessor"); - if (returnString != null && !"success".equalsIgnoreCase(returnString)) { - throw new EventHandlerException("Post-Processor event did not return 'success'."); - } - } catch (EventHandlerException e) { - Debug.logError(e, module); + for (ConfigXMLReader.Event event: ctrl.getPostprocessorEventList().values()) { + try { + String returnString = this.runEvent(request, response, event, requestMap, "postprocessor"); + if (returnString != null && !"success".equalsIgnoreCase(returnString)) { + throw new EventHandlerException("Post-Processor event did not return 'success'."); } + } catch (EventHandlerException e) { + Debug.logError(e, module); } - } catch (WebAppConfigurationException e) { - Debug.logError(e, "Exception thrown while parsing controller.xml file: ", module); - throw new RequestHandlerException(e); } String responseStatusCode = nextRequestResponse.statusCode; if(UtilValidate.isNotEmpty(responseStatusCode)) - statusCodeString = responseStatusCode; - + ctrl.setStatusCodeString(responseStatusCode); if ("url".equals(nextRequestResponse.type)) { if (Debug.verboseOn()) Debug.logVerbose("[RequestHandler.doRequest]: Response is a URL redirect." + showSessionId(request), module); - callRedirect(nextRequestResponse.value, response, request, statusCodeString); + callRedirect(nextRequestResponse.value, response, request, ctrl.getStatusCodeString()); } else if ("cross-redirect".equals(nextRequestResponse.type)) { // check for a cross-application redirect if (Debug.verboseOn()) Debug.logVerbose("[RequestHandler.doRequest]: Response is a Cross-Application redirect." + showSessionId(request), module); String url = nextRequestResponse.value.startsWith("/") ? nextRequestResponse.value : "/" + nextRequestResponse.value; - callRedirect(url + this.makeQueryString(request, nextRequestResponse), response, request, statusCodeString); + callRedirect(url + this.makeQueryString(request, nextRequestResponse), response, request, ctrl.getStatusCodeString()); } else if ("request-redirect".equals(nextRequestResponse.type)) { if (Debug.verboseOn()) Debug.logVerbose("[RequestHandler.doRequest]: Response is a Request redirect." + showSessionId(request), module); - callRedirect(makeLinkWithQueryString(request, response, "/" + nextRequestResponse.value, nextRequestResponse), response, request, statusCodeString); + callRedirect(makeLinkWithQueryString(request, response, "/" + nextRequestResponse.value, nextRequestResponse), response, request, ctrl.getStatusCodeString()); } else if ("request-redirect-noparam".equals(nextRequestResponse.type)) { if (Debug.verboseOn()) Debug.logVerbose("[RequestHandler.doRequest]: Response is a Request redirect with no parameters." + showSessionId(request), module); - callRedirect(makeLink(request, response, nextRequestResponse.value), response, request, statusCodeString); + callRedirect(makeLink(request, response, nextRequestResponse.value), response, request, ctrl.getStatusCodeString()); } else if ("view".equals(nextRequestResponse.type)) { if (Debug.verboseOn()) Debug.logVerbose("[RequestHandler.doRequest]: Response is a view." + showSessionId(request), module); Modified: ofbiz/ofbiz-framework/trunk/framework/webapp/src/test/java/org/apache/ofbiz/webapp/control/RequestHandlerTests.java URL: http://svn.apache.org/viewvc/ofbiz/ofbiz-framework/trunk/framework/webapp/src/test/java/org/apache/ofbiz/webapp/control/RequestHandlerTests.java?rev=1834465&r1=1834464&r2=1834465&view=diff ============================================================================== --- ofbiz/ofbiz-framework/trunk/framework/webapp/src/test/java/org/apache/ofbiz/webapp/control/RequestHandlerTests.java (original) +++ ofbiz/ofbiz-framework/trunk/framework/webapp/src/test/java/org/apache/ofbiz/webapp/control/RequestHandlerTests.java Wed Jun 27 05:48:59 2018 @@ -20,15 +20,22 @@ package org.apache.ofbiz.webapp.control; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; + +import java.util.Collection; +import java.util.HashMap; +import java.util.Map; + import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertSame; +import static org.junit.Assert.assertThat; import static org.junit.Assert.assertTrue; +import static org.hamcrest.CoreMatchers.*; import javax.servlet.http.HttpServletRequest; import javax.ws.rs.core.MultivaluedHashMap; import javax.ws.rs.core.MultivaluedMap; import org.apache.ofbiz.webapp.control.ConfigXMLReader.RequestMap; +import org.apache.ofbiz.webapp.control.ConfigXMLReader.ViewMap; import org.junit.Before; import org.junit.Test; import org.w3c.dom.Element; @@ -36,12 +43,19 @@ import org.w3c.dom.Element; public class RequestHandlerTests { public static class ResolveURITests { private MultivaluedMap<String,RequestMap> reqMaps; + private Map<String, ViewMap> viewMaps; private HttpServletRequest req; private Element dummyElement; + private RequestHandler.Controller ctrl; @Before public void setUp() { + ctrl = mock(RequestHandler.Controller.class); reqMaps = new MultivaluedHashMap<>(); + viewMaps = new HashMap<>(); + when(ctrl.getDefaultRequest()).thenReturn(null); + when(ctrl.getRequestMapMap()).thenReturn(reqMaps); + when(ctrl.getViewMapMap()).thenReturn(viewMaps); req = mock(HttpServletRequest.class); dummyElement = mock(Element.class); when(dummyElement.getAttribute("method")).thenReturn("all"); @@ -55,7 +69,9 @@ public class RequestHandlerTests { reqMaps.putSingle("foo", foo); reqMaps.putSingle("bar", bar); when(req.getPathInfo()).thenReturn("/foo"); - assertSame(foo, RequestHandler.resolveURI(reqMaps, req, null).get()); + assertThat(RequestHandler.resolveURI(ctrl, req), + both(hasItem(foo)).and(not(hasItem(bar)))); + assertThat(RequestHandler.resolveURI(ctrl, req).size(), is(1)); } @Test @@ -66,9 +82,9 @@ public class RequestHandlerTests { RequestMap foo = new RequestMap(dummyElement); - assertFalse(RequestHandler.resolveURI(reqMaps, req, null).isPresent()); + assertTrue(RequestHandler.resolveURI(ctrl, req).isEmpty()); reqMaps.putSingle("foo", foo); - assertTrue(RequestHandler.resolveURI(reqMaps, req, null).isPresent()); + assertFalse(RequestHandler.resolveURI(ctrl, req).isEmpty()); } @Test @@ -82,63 +98,38 @@ public class RequestHandlerTests { when(req.getPathInfo()).thenReturn("/foo"); when(req.getMethod()).thenReturn("GET"); - assertSame(foo, RequestHandler.resolveURI(reqMaps, req, null).get()); + assertThat(RequestHandler.resolveURI(ctrl, req), hasItem(foo)); when(req.getPathInfo()).thenReturn("/bar"); when(req.getMethod()).thenReturn("PUT"); - assertSame(bar, RequestHandler.resolveURI(reqMaps, req, null).get()); + assertThat(RequestHandler.resolveURI(ctrl, req), hasItem(bar)); } + @Test - public void resolveURICatchAll() throws RequestHandlerException { - when(req.getPathInfo()).thenReturn("/foo"); + public void resolveURIDefault() throws Exception { RequestMap foo = new RequestMap(dummyElement); - when(req.getMethod()).thenReturn("get"); - assertFalse(RequestHandler.resolveURI(reqMaps, req, null).isPresent()); - when(req.getMethod()).thenReturn("post"); - assertFalse(RequestHandler.resolveURI(reqMaps, req, null).isPresent()); - when(req.getMethod()).thenReturn("put"); - assertFalse(RequestHandler.resolveURI(reqMaps, req, null).isPresent()); - when(req.getMethod()).thenReturn("delete"); - assertFalse(RequestHandler.resolveURI(reqMaps, req, null).isPresent()); - + RequestMap bar = new RequestMap(dummyElement); reqMaps.putSingle("foo", foo); - when(req.getMethod()).thenReturn("get"); - assertTrue(RequestHandler.resolveURI(reqMaps, req, null).isPresent()); - when(req.getMethod()).thenReturn("post"); - assertTrue(RequestHandler.resolveURI(reqMaps, req, null).isPresent()); - when(req.getMethod()).thenReturn("put"); - assertTrue(RequestHandler.resolveURI(reqMaps, req, null).isPresent()); - when(req.getMethod()).thenReturn("delete"); - assertTrue(RequestHandler.resolveURI(reqMaps, req, null).isPresent()); - } - - @Test - public void resolveURISegregate() throws RequestHandlerException { - when(dummyElement.getAttribute("method")).thenReturn("put"); - RequestMap fooPut = new RequestMap(dummyElement); - when(dummyElement.getAttribute("method")).thenReturn("all"); - RequestMap fooAll = new RequestMap(dummyElement); - reqMaps.putSingle("foo", fooAll); - reqMaps.add("foo", fooPut); + reqMaps.putSingle("bar", bar); - when(req.getPathInfo()).thenReturn("/foo"); - when(req.getMethod()).thenReturn("put"); - assertSame(fooPut, RequestHandler.resolveURI(reqMaps, req, null).get()); - when(req.getMethod()).thenReturn("get"); - assertSame(fooAll, RequestHandler.resolveURI(reqMaps, req, null).get()); + when(req.getPathInfo()).thenReturn("/baz"); + when(ctrl.getDefaultRequest()).thenReturn("bar"); + assertThat(RequestHandler.resolveURI(ctrl, req), hasItem(bar)); } @Test - public void resolveURIDefault() throws Exception { + public void resolveURIOverrideView() throws Exception { RequestMap foo = new RequestMap(dummyElement); RequestMap bar = new RequestMap(dummyElement); reqMaps.putSingle("foo", foo); reqMaps.putSingle("bar", bar); - when(req.getPathInfo()).thenReturn("/bar"); - when(req.getMethod()).thenReturn("get"); - assertSame(bar, RequestHandler.resolveURI(reqMaps, req, "bar").get()); + viewMaps.put("baz", new ViewMap(dummyElement)); + + when(req.getPathInfo()).thenReturn("/foo/baz"); + when(ctrl.getDefaultRequest()).thenReturn("bar"); + assertThat(RequestHandler.resolveURI(ctrl, req), hasItem(bar)); } @Test @@ -149,8 +140,41 @@ public class RequestHandlerTests { reqMaps.putSingle("bar", bar); when(req.getPathInfo()).thenReturn("/baz"); - when(req.getMethod()).thenReturn("get"); - assertFalse(RequestHandler.resolveURI(reqMaps, req, null).isPresent()); + assertTrue(RequestHandler.resolveURI(ctrl, req).isEmpty()); + } + + @Test + public void resolveMethodCatchAll() throws RequestHandlerException { + when(req.getPathInfo()).thenReturn("/foo"); + RequestMap foo = new RequestMap(dummyElement); + Collection<RequestMap> rmaps = RequestHandler.resolveURI(ctrl, req); + assertFalse(RequestHandler.resolveMethod("get", rmaps).isPresent()); + assertFalse(RequestHandler.resolveMethod("post", rmaps).isPresent()); + assertFalse(RequestHandler.resolveMethod("put", rmaps).isPresent()); + assertFalse(RequestHandler.resolveMethod("delete", rmaps).isPresent()); + + reqMaps.putSingle("foo", foo); + Collection<RequestMap> rmaps2 = RequestHandler.resolveURI(ctrl, req); + assertTrue(RequestHandler.resolveMethod("get", rmaps2).isPresent()); + assertTrue(RequestHandler.resolveMethod("post", rmaps2).isPresent()); + assertTrue(RequestHandler.resolveMethod("put", rmaps2).isPresent()); + assertTrue(RequestHandler.resolveMethod("delete", rmaps2).isPresent()); + } + + @Test + public void resolveMethodBasic() throws RequestHandlerException { + when(dummyElement.getAttribute("method")).thenReturn("put"); + RequestMap fooPut = new RequestMap(dummyElement); + when(dummyElement.getAttribute("method")).thenReturn("all"); + RequestMap fooAll = new RequestMap(dummyElement); + reqMaps.putSingle("foo", fooAll); + reqMaps.add("foo", fooPut); + + when(req.getPathInfo()).thenReturn("/foo"); + Collection<RequestMap> rmaps = RequestHandler.resolveURI(ctrl, req); + assertThat(rmaps, hasItems(fooPut, fooAll)); + assertThat(RequestHandler.resolveMethod("put", rmaps).get(), is(fooPut)); + assertThat(RequestHandler.resolveMethod("get", rmaps).get(), is(fooAll)); } } } |
Free forum by Nabble | Edit this page |