RequestedModuleNames implements IRequestedModuleNames { RequestedModuleNames(HttpServletRequest request, List<String> idList, byte[] idListHash) throws IOException { final String sourceMethod = "<ctor>"; if (isTraceLogging) { log.entering(RequestedModuleNames.class.getName(), sourceMethod, new Object[]{request.getQueryString(), "<omitted>", TypeUtil.byteArray2String(idListHash)}); } this.idList = idList; this.idListHash = idListHash; moduleQueryArg = request.getParameter(AbstractHttpTransport.REQUESTEDMODULES_REQPARAM); String moduleIdsQueryArg = request.getParameter(AbstractHttpTransport.REQUESTEDMODULEIDS_REQPARAM); excludeEncQueryArg = request.getParameter(AbstractHttpTransport.EXCLUDEENC_REQPARAM); String excludeIdQueryArg = request.getParameter(AbstractHttpTransport.EXCLUDEIDS_REQPARAM); String countParam = request.getParameter(AbstractHttpTransport.REQUESTEDMODULESCOUNT_REQPARAM); if (moduleQueryArg == null) moduleQueryArg = ""; if (moduleIdsQueryArg == null) moduleIdsQueryArg = ""; try { if (countParam != null) { if (moduleQueryArg.length() == 0 && moduleIdsQueryArg.length() == 0) { throw new BadRequestException(request.getQueryString()); } count = Integer.parseInt(request.getParameter(AbstractHttpTransport.REQUESTEDMODULESCOUNT_REQPARAM)); if (count < 1 || count > AbstractHttpTransport.REQUESTED_MODULES_MAX_COUNT) { throw new BadRequestException("count:" + count); } } if (moduleIdsQueryArg.length() > 0) { if (countParam == null) { throw new BadRequestException(request.getQueryString()); } base64decodedIdList = Base64.decodeBase64(moduleIdsQueryArg); if (isTraceLogging) { log.finer("decoded = " + TypeUtil.byteArray2String(base64decodedIdList)); } } IAggregator aggr = (IAggregator)request.getAttribute(IAggregator.AGGREGATOR_REQATTRNAME); Object errModule = aggr.getConfig().getProperty(CONFIGPROP_IDLISTHASHERRMODULE, String.class); String versionErrorHandler = (errModule instanceof String) ? errModule.toString() : null; if (base64decodedIdList != null) { byte[] hash = Arrays.copyOf(base64decodedIdList, idListHash.length); if (!Arrays.equals(hash, idListHash)) { versionError = true; if (isTraceLogging) { log.finer("Invalid hash in request" + TypeUtil.byteArray2String(hash)); } } } boolean failOnVersionError = TypeUtil.asBoolean(request.getParameter(AbstractHttpTransport.FAILONVERSIONERR_REQPARAM)); if (!versionError) { errModule = aggr.getConfig().getProperty(CONFIGPROP_CACHEBUSTERRMODULE, String.class); versionErrorHandler = (errModule instanceof String) ? errModule.toString() : null; String reqCb = (String)request.getAttribute(AbstractHttpTransport.CACHEBUST_REQATTRNAME); String configCb = aggr.getConfig().getCacheBust(); if ((versionErrorHandler != null || failOnVersionError) && reqCb != null && configCb != null && !reqCb.equals(configCb)) { versionError = true; if (isTraceLogging) { log.finer("cache bust version error: " + reqCb + ", " + configCb); } } } if (versionError) { if (versionErrorHandler != null && !failOnVersionError) { request.setAttribute(ILayer.NOCACHE_RESPONSE_REQATTRNAME, Boolean.TRUE); modules = Collections.emptyList(); scripts = Arrays.asList(new String[]{versionErrorHandler}); count = 0;; strRep = "scripts:" + scripts.toString(); if (log.isLoggable(Level.FINER)) { log.exiting(RequestedModuleNames.class.getName(), sourceMethod, this); } return; } throw new BadRequestException("Version Error"); } if (moduleQueryArg.length() > 0) { if (countParam == null && moduleIdsQueryArg.length() > 0) { throw new BadRequestException(request.getQueryString()); } try { moduleQueryArg = URLDecoder.decode(moduleQueryArg, "UTF-8"); } catch (UnsupportedEncodingException e) { throw new BadRequestException(e.getMessage()); } } if (excludeIdQueryArg != null) { if (countParam == null) { throw new BadRequestException(request.getQueryString()); } base64decodedExcludeIdList = Base64.decodeBase64(excludeIdQueryArg); } if (excludeEncQueryArg != null) { if (countParam == null) { throw new BadRequestException(request.getQueryString()); } try { excludeEncQueryArg = URLDecoder.decode(excludeEncQueryArg, "UTF-8"); } catch (UnsupportedEncodingException e) { throw new BadRequestException(e.getMessage()); } } if (count > 0) { StringBuffer sb = new StringBuffer(); sb.append(moduleQueryArg != null ? moduleQueryArg : "").append(":") .append(moduleIdsQueryArg != null ? moduleIdsQueryArg : "").append(":") .append(excludeEncQueryArg != null ? excludeEncQueryArg : "").append(":") .append(excludeIdQueryArg != null ? excludeIdQueryArg : ""); strRep = sb.toString(); } else if (moduleQueryArg.length() > 0){ scripts = Collections.unmodifiableList(Arrays.asList(moduleQueryArg.split("\\s*,\\s*", 0))); modules = Collections.emptyList(); if (aggr.getOptions().isDebugMode() || aggr.getOptions().isDevelopmentMode()) { request.setAttribute(AbstractHttpTransport.WARN_DEPRECATED_USE_OF_MODULES_QUERYARG, Boolean.TRUE); } } } catch (NumberFormatException ex) { throw new BadRequestException(ex.getMessage(), ex); } @SuppressWarnings("deprecation") List<String> required = getNameListFromQueryArg(request, AbstractHttpTransport.REQUIRED_REQPARAM); if (required != null) { if (countParam != null || moduleIdsQueryArg.length() > 0 || moduleQueryArg.length() > 0) { throw new BadRequestException(request.getQueryString()); } deps = required; IAggregator aggr = (IAggregator)request.getAttribute(IAggregator.AGGREGATOR_REQATTRNAME); if (aggr.getOptions().isDebugMode() || aggr.getOptions().isDevelopmentMode()) { request.setAttribute(AbstractHttpTransport.WARN_DEPRECATED_USE_OF_REQUIRED_QUERYARG, Boolean.TRUE); } } List<String> names = getNameListFromQueryArg(request, AbstractHttpTransport.SCRIPTS_REQPARAM); if (names != null) { if (countParam != null || moduleIdsQueryArg.length() > 0 || moduleQueryArg.length() > 0 || required != null) { throw new BadRequestException(request.getQueryString()); } scripts = Collections.unmodifiableList(names); } names = getNameListFromQueryArg(request, AbstractHttpTransport.DEPS_REQPARAM); if (names != null) { if (countParam != null || moduleIdsQueryArg.length() > 0 || moduleQueryArg.length() > 0 || required != null) { throw new BadRequestException(request.getQueryString()); } deps = Collections.unmodifiableList(names); } names = getNameListFromQueryArg(request, AbstractHttpTransport.PRELOADS_REQPARAM); if (names != null) { if (countParam != null || moduleIdsQueryArg.length() > 0 || moduleQueryArg.length() > 0 || required != null) { throw new BadRequestException(request.getQueryString()); } preloads = Collections.unmodifiableList(names); } names = getNameListFromQueryArg(request, AbstractHttpTransport.EXCLUDES_REQPARAM); if (names != null) { if (countParam != null || moduleIdsQueryArg.length() > 0 || moduleQueryArg.length() > 0 || required != null) { throw new BadRequestException(request.getQueryString()); } excludes = Collections.unmodifiableList(names); } if (isTraceLogging) { log.exiting(RequestedModuleNames.class.getName(), sourceMethod, this); } } RequestedModuleNames(HttpServletRequest request, List<String> idList, byte[] idListHash); @Override List<String> getDeps(); @Override List<String> getModules(); @Override List<String> getPreloads(); @Override List<String> getScripts(); @Override List<String> getExcludes(); @Override String toString(); boolean isVersionError(); String toString(boolean decode); static public Pattern NON_PATH_PROP_PATTERN; static public String PLUGIN_PREFIXES_PROP_NAME; }
@Test public void testRequestedModuleNames() throws Exception { IAggregator mockAggregator = TestUtils.createMockAggregator(); Map<String, Object> requestAttributes = new HashMap<String, Object>(); Map<String, String[]> requestParams = new HashMap<String, String[]>(); HttpServletRequest request = TestUtils.createMockRequest(mockAggregator, requestAttributes, requestParams, null, null); EasyMock.replay(mockAggregator, request); requestParams.put(AbstractHttpTransport.SCRIPTS_REQPARAM, new String[]{"script/a, script/b"}); RequestedModuleNames requestedNames = new RequestedModuleNames(request, null, null); assertEquals(Arrays.asList(new String[]{"script/a", "script/b"}), requestedNames.getScripts()); assertTrue(requestedNames.getModules().isEmpty()); assertTrue(requestedNames.getDeps().isEmpty()); assertTrue(requestedNames.getPreloads().isEmpty()); assertTrue(requestedNames.getExcludes().isEmpty()); assertEquals("scripts:[script/a, script/b]", requestedNames.toString()); requestParams.remove(AbstractHttpTransport.SCRIPTS_REQPARAM); requestParams.put(AbstractHttpTransport.DEPS_REQPARAM, new String[]{"dep/a,dep/b"}); requestedNames = new RequestedModuleNames(request, null, null); assertEquals(Arrays.asList(new String[]{"dep/a", "dep/b"}), requestedNames.getDeps()); assertTrue(requestedNames.getModules().isEmpty()); assertTrue(requestedNames.getPreloads().isEmpty()); assertTrue(requestedNames.getExcludes().isEmpty()); assertEquals("deps:[dep/a, dep/b]", requestedNames.toString()); requestParams.remove(AbstractHttpTransport.DEPS_REQPARAM); requestParams.put(AbstractHttpTransport.PRELOADS_REQPARAM, new String[]{"preload/a,preload/b"}); requestedNames = new RequestedModuleNames(request, null, null); assertEquals(Arrays.asList(new String[]{"preload/a", "preload/b"}), requestedNames.getPreloads()); assertTrue(requestedNames.getModules().isEmpty()); assertTrue(requestedNames.getDeps().isEmpty()); assertTrue(requestedNames.getExcludes().isEmpty()); assertEquals("preloads:[preload/a, preload/b]", requestedNames.toString()); requestParams.remove(AbstractHttpTransport.PRELOADS_REQPARAM); requestParams.put(AbstractHttpTransport.EXCLUDES_REQPARAM, new String[]{"exclude/a,exclude/b"}); requestedNames = new RequestedModuleNames(request, null, null); assertEquals(Arrays.asList(new String[]{"exclude/a", "exclude/b"}), requestedNames.getExcludes()); assertTrue(requestedNames.getModules().isEmpty()); assertTrue(requestedNames.getDeps().isEmpty()); assertTrue(requestedNames.getPreloads().isEmpty()); assertEquals("excludes:[exclude/a, exclude/b]", requestedNames.toString()); requestParams.put(AbstractHttpTransport.DEPS_REQPARAM, new String[]{"dep/a,dep/b"}); requestParams.put(AbstractHttpTransport.SCRIPTS_REQPARAM, new String[]{"script/a, script/b"}); requestParams.put(AbstractHttpTransport.PRELOADS_REQPARAM, new String[]{"preload/a,preload/b"}); requestedNames = new RequestedModuleNames(request, null, null); assertEquals(Arrays.asList(new String[]{"script/a", "script/b"}), requestedNames.getScripts()); assertEquals(Arrays.asList(new String[]{"dep/a", "dep/b"}), requestedNames.getDeps()); assertEquals(Arrays.asList(new String[]{"preload/a", "preload/b"}), requestedNames.getPreloads()); assertEquals(Arrays.asList(new String[]{"exclude/a", "exclude/b"}), requestedNames.getExcludes()); assertEquals("scripts:[script/a, script/b]; deps:[dep/a, dep/b]; preloads:[preload/a, preload/b]; excludes:[exclude/a, exclude/b]", requestedNames.toString()); }