/* * 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.jmeter.protocol.http.parser; import java.net.URL; import java.nio.charset.Charset; import java.util.Collections; import java.util.Iterator; import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.Validate; import org.apache.commons.lang3.tuple.ImmutableTriple; import org.apache.commons.lang3.tuple.Triple; import org.apache.jmeter.util.JMeterUtils; import org.slf4j.LoggerFactory; import org.slf4j.Logger; import com.github.benmanes.caffeine.cache.Caffeine; import com.github.benmanes.caffeine.cache.LoadingCache; /** * CSS Parser used to extract from CSS files external urls * * @since 3.0 */ public class CssParser implements LinkExtractorParser { private static final URLCollection EMPTY_URL_COLLECTION = new URLCollection(Collections.emptyList()); private static final Logger LOG = LoggerFactory.getLogger(CssParser.class); /** * */ private static final LoadingCache<Triple<String, URL, Charset>, URLCollection> CSS_URL_CACHE; static { final int cacheSize = JMeterUtils.getPropDefault( "css.parser.cache.size", 400); CSS_URL_CACHE = Caffeine.newBuilder().maximumSize(cacheSize) .build(new CssParserCacheLoader()); } /** * * @see org.apache.jmeter.protocol.http.parser.LinkExtractorParser#getEmbeddedResourceURLs * (java.lang.String, byte[], java.net.URL, java.lang.String) */ @Override public Iterator<URL> getEmbeddedResourceURLs(String userAgent, byte[] data, final URL baseUrl, String encoding) throws LinkExtractorParseException { try { final String cssContent = new String(data, encoding); final Charset charset = Charset.forName(encoding); final Triple<String, URL, Charset> triple = ImmutableTriple.of( cssContent, baseUrl, charset); final URLCollection urlCollection = orDefault(CSS_URL_CACHE.get(triple), EMPTY_URL_COLLECTION); if (LOG.isDebugEnabled()) { LOG.debug("Parsed:" + baseUrl + ", got:" + StringUtils.join(urlCollection, ",")); } return urlCollection.iterator(); } catch (Exception e) { throw new LinkExtractorParseException(e); } } private URLCollection orDefault(URLCollection urlCollection, URLCollection defaultValue) { if (urlCollection == null) { return Validate.notNull(defaultValue); } return urlCollection; } @Override public boolean isReusable() { return true; } }