fix #1615 groovy and function support

This commit is contained in:
Shinsuke Sugaya 2018-04-19 22:24:59 +09:00
parent 119a3d99bd
commit 12c07bd508
4 changed files with 78 additions and 34 deletions

View file

@ -21,7 +21,6 @@ import java.net.URLEncoder;
import java.util.Map;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import org.codelibs.core.lang.StringUtil;
import org.codelibs.core.net.URLUtil;
@ -40,7 +39,6 @@ import org.lastaflute.web.Execute;
import org.lastaflute.web.response.ActionResponse;
import org.lastaflute.web.response.HtmlResponse;
import org.lastaflute.web.response.StreamResponse;
import org.lastaflute.web.util.LaRequestUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@ -146,31 +144,13 @@ public class GoAction extends FessSearchAction {
return redirect(ErrorAction.class);
}
} else {
return redirect(targetUrl + hash);
return HtmlResponse.fromRedirectPathAsIs(targetUrl + hash);
}
} else {
return redirect(targetUrl + hash);
return HtmlResponse.fromRedirectPathAsIs(DocumentUtil.encodeUrl(targetUrl + hash));
}
}
protected ActionResponse redirect(final String url) {
final HttpServletRequest request2 = LaRequestUtil.getRequest();
final String enc = request2.getCharacterEncoding() == null ? Constants.UTF_8 : request2.getCharacterEncoding();
final StringBuilder buf = new StringBuilder(url.length() + 100);
for (final char c : url.toCharArray()) {
if (CharUtil.isUrlChar(c)) {
buf.append(c);
} else {
try {
buf.append(URLEncoder.encode(String.valueOf(c), enc));
} catch (final UnsupportedEncodingException e) {
buf.append(c);
}
}
}
return HtmlResponse.fromRedirectPathAsIs(buf.toString());
}
protected boolean isFileSystemPath(final String url) {
return url.startsWith("file:") || url.startsWith("smb:") || url.startsWith("ftp:");
}

View file

@ -15,22 +15,30 @@
*/
package org.codelibs.fess.es.config.exentity;
import java.util.function.BiFunction;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.codelibs.core.lang.StringUtil;
import org.codelibs.fess.es.config.bsentity.BsPathMapping;
import org.codelibs.fess.util.ComponentUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* @author FreeGen
*/
public class PathMapping extends BsPathMapping {
private static final Logger logger = LoggerFactory.getLogger(PathMapping.class);
private static final long serialVersionUID = 1L;
private Pattern regexPattern;
protected Pattern userAgentPattern;
private Pattern userAgentPattern;
protected Pattern regexPattern;
protected BiFunction<String, Matcher, String> pathMapper;
public String getId() {
return asDocMeta().id();
@ -48,11 +56,23 @@ public class PathMapping extends BsPathMapping {
asDocMeta().version(version);
}
public Matcher getMatcher(final CharSequence input) {
public String process(final String input) {
if (regexPattern == null) {
regexPattern = Pattern.compile(getRegex());
}
return regexPattern.matcher(input);
final Matcher matcher = regexPattern.matcher(input);
if (matcher.find()) {
if (pathMapper == null) {
final String replacement = StringUtil.isNotBlank(getReplacement()) ? getReplacement() : StringUtil.EMPTY;
pathMapper = ComponentUtil.getPathMappingHelper().createPathMatcher(matcher, replacement);
}
try {
return pathMapper.apply(input, matcher);
} catch (Exception e) {
logger.warn("Failed to apply " + pathMapper, e);
}
}
return input;
}
public boolean hasUAMathcer() {

View file

@ -19,6 +19,7 @@ import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.function.BiFunction;
import java.util.regex.Matcher;
import javax.annotation.PostConstruct;
@ -28,6 +29,8 @@ import org.codelibs.fess.Constants;
import org.codelibs.fess.es.config.exbhv.PathMappingBhv;
import org.codelibs.fess.es.config.exentity.PathMapping;
import org.codelibs.fess.util.ComponentUtil;
import org.codelibs.fess.util.DocumentUtil;
import org.codelibs.fess.util.GroovyUtil;
import org.lastaflute.di.core.factory.SingletonLaContainerFactory;
import org.lastaflute.web.util.LaRequestUtil;
import org.slf4j.Logger;
@ -37,6 +40,10 @@ public class PathMappingHelper {
private static final Logger logger = LoggerFactory.getLogger(PathMappingHelper.class);
private static final String FUNCTION_ENCODEURL_MATCHER = "function:encodeUrl";
private static final String GROOVY_MATCHER = "groovy:";
private final Map<String, List<PathMapping>> pathMappingMap = new HashMap<>();
volatile List<PathMapping> cachedPathMappingList = null;
@ -126,18 +133,31 @@ public class PathMappingHelper {
return replaceUrl(cachedPathMappingList, url);
}
public BiFunction<String, Matcher, String> createPathMatcher(final Matcher matcher, final String replacement) {
if (replacement.equals(FUNCTION_ENCODEURL_MATCHER)) {
return (u, m) -> DocumentUtil.encodeUrl(u);
} else if (replacement.startsWith(GROOVY_MATCHER)) {
final String template = replacement.substring(GROOVY_MATCHER.length());
return (u, m) -> {
final Map<String, Object> paramMap = new HashMap<>();
paramMap.put("url", u);
paramMap.put("matcher", m);
final Object value = GroovyUtil.evaluate(template, paramMap);
if (value == null) {
return u;
}
return value.toString();
};
} else {
return (u, m) -> m.replaceAll(replacement);
}
}
private String replaceUrl(final List<PathMapping> pathMappingList, final String url) {
String newUrl = url;
for (final PathMapping pathMapping : pathMappingList) {
if (matchUserAgent(pathMapping)) {
final Matcher matcher = pathMapping.getMatcher(newUrl);
if (matcher.find()) {
String replacement = pathMapping.getReplacement();
if (replacement == null) {
replacement = StringUtil.EMPTY;
}
newUrl = matcher.replaceAll(replacement);
}
newUrl = pathMapping.process(newUrl);
}
}
return newUrl;

View file

@ -15,11 +15,16 @@
*/
package org.codelibs.fess.util;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.util.Date;
import java.util.List;
import java.util.Map;
import org.codelibs.fess.Constants;
import org.codelibs.fess.crawler.util.CharUtil;
import org.codelibs.fess.taglib.FessFunctions;
import org.lastaflute.web.util.LaRequestUtil;
public final class DocumentUtil {
@ -107,4 +112,23 @@ public final class DocumentUtil {
}
return null;
}
public static String encodeUrl(final String url) {
final String enc =
LaRequestUtil.getOptionalRequest().filter(req -> req.getCharacterEncoding() != null).map(req -> req.getCharacterEncoding())
.orElse(Constants.UTF_8);
final StringBuilder buf = new StringBuilder(url.length() + 100);
for (final char c : url.toCharArray()) {
if (CharUtil.isUrlChar(c)) {
buf.append(c);
} else {
try {
buf.append(URLEncoder.encode(String.valueOf(c), enc));
} catch (final UnsupportedEncodingException e) {
buf.append(c);
}
}
}
return buf.toString();
}
}