fix #1264 improve urlLink build
This commit is contained in:
parent
6f1f6cc4a5
commit
e18b59c109
3 changed files with 219 additions and 99 deletions
|
@ -15,8 +15,6 @@
|
|||
*/
|
||||
package org.codelibs.fess.helper;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
|
||||
import org.lastaflute.web.util.LaRequestUtil;
|
||||
|
||||
public class UserAgentHelper {
|
||||
|
@ -25,29 +23,30 @@ public class UserAgentHelper {
|
|||
private static final String USER_AGENT_TYPE = "ViewHelper.UserAgent";
|
||||
|
||||
public UserAgentType getUserAgentType() {
|
||||
final HttpServletRequest request = LaRequestUtil.getRequest();
|
||||
UserAgentType uaType = (UserAgentType) request.getAttribute(USER_AGENT_TYPE);
|
||||
if (uaType == null) {
|
||||
final String userAgent = request.getHeader(USER_AGENT);
|
||||
if (userAgent != null) {
|
||||
if (userAgent.indexOf("MSIE") >= 0 || userAgent.indexOf("Trident") >= 0) {
|
||||
uaType = UserAgentType.IE;
|
||||
} else if (userAgent.indexOf("Firefox") >= 0) {
|
||||
uaType = UserAgentType.FIREFOX;
|
||||
} else if (userAgent.indexOf("Chrome") >= 0) {
|
||||
uaType = UserAgentType.CHROME;
|
||||
} else if (userAgent.indexOf("Safari") >= 0) {
|
||||
uaType = UserAgentType.SAFARI;
|
||||
} else if (userAgent.indexOf("Opera") >= 0) {
|
||||
uaType = UserAgentType.OPERA;
|
||||
}
|
||||
}
|
||||
return LaRequestUtil.getOptionalRequest().map(request -> {
|
||||
UserAgentType uaType = (UserAgentType) request.getAttribute(USER_AGENT_TYPE);
|
||||
if (uaType == null) {
|
||||
uaType = UserAgentType.OTHER;
|
||||
final String userAgent = request.getHeader(USER_AGENT);
|
||||
if (userAgent != null) {
|
||||
if (userAgent.indexOf("MSIE") >= 0 || userAgent.indexOf("Trident") >= 0) {
|
||||
uaType = UserAgentType.IE;
|
||||
} else if (userAgent.indexOf("Firefox") >= 0) {
|
||||
uaType = UserAgentType.FIREFOX;
|
||||
} else if (userAgent.indexOf("Chrome") >= 0) {
|
||||
uaType = UserAgentType.CHROME;
|
||||
} else if (userAgent.indexOf("Safari") >= 0) {
|
||||
uaType = UserAgentType.SAFARI;
|
||||
} else if (userAgent.indexOf("Opera") >= 0) {
|
||||
uaType = UserAgentType.OPERA;
|
||||
}
|
||||
}
|
||||
if (uaType == null) {
|
||||
uaType = UserAgentType.OTHER;
|
||||
}
|
||||
request.setAttribute(USER_AGENT_TYPE, uaType);
|
||||
}
|
||||
request.setAttribute(USER_AGENT_TYPE, uaType);
|
||||
}
|
||||
return uaType;
|
||||
return uaType;
|
||||
}).orElse(UserAgentType.OTHER);
|
||||
}
|
||||
|
||||
public enum UserAgentType {
|
||||
|
|
|
@ -180,26 +180,31 @@ public class ViewHelper {
|
|||
}
|
||||
|
||||
public String getUrlLink(final Map<String, Object> document) {
|
||||
// file protocol
|
||||
String url = DocumentUtil.getValue(document, "url", String.class);
|
||||
final FessConfig fessConfig = ComponentUtil.getFessConfig();
|
||||
String url = DocumentUtil.getValue(document, fessConfig.getIndexFieldUrl(), String.class);
|
||||
|
||||
if (url == null) {
|
||||
// TODO should redirect to a invalid page?
|
||||
return "#";
|
||||
if (StringUtil.isBlank(url)) {
|
||||
return "#not-found-" + DocumentUtil.getValue(document, fessConfig.getIndexFieldDocId(), String.class);
|
||||
}
|
||||
|
||||
final boolean isFileUrl = url.startsWith("smb:") || url.startsWith("ftp:");
|
||||
final boolean isSmbUrl = url.startsWith("smb:");
|
||||
final boolean isFtpUrl = url.startsWith("ftp:");
|
||||
final boolean isSmbOrFtpUrl = isSmbUrl || isFtpUrl;
|
||||
|
||||
// replacing url with mapping data
|
||||
url = pathMappingHelper.replaceUrl(url);
|
||||
|
||||
if (url.startsWith("smb:")) {
|
||||
url = url.replace("smb:", "file:");
|
||||
} else if (url.startsWith("ftp:")) {
|
||||
url = url.replace("ftp:", "file:");
|
||||
if (pathMappingHelper != null) {
|
||||
url = pathMappingHelper.replaceUrl(url);
|
||||
}
|
||||
|
||||
if (url.startsWith("http:") && isFileUrl) {
|
||||
final boolean isHttpUrl = url.startsWith("http:") || url.startsWith("https:");
|
||||
|
||||
if (isSmbUrl) {
|
||||
url = url.replace("smb:", "file:");
|
||||
}
|
||||
|
||||
if (isHttpUrl && isSmbOrFtpUrl) {
|
||||
// smb/ftp->http
|
||||
// encode
|
||||
final StringBuilder buf = new StringBuilder(url.length() + 100);
|
||||
for (final char c : url.toCharArray()) {
|
||||
if (CharUtil.isUrlChar(c)) {
|
||||
|
@ -208,89 +213,96 @@ public class ViewHelper {
|
|||
try {
|
||||
buf.append(URLEncoder.encode(String.valueOf(c), urlLinkEncoding));
|
||||
} catch (final UnsupportedEncodingException e) {
|
||||
// NOP
|
||||
buf.append(c);
|
||||
}
|
||||
}
|
||||
}
|
||||
url = buf.toString();
|
||||
} else if (url.startsWith("file:")) {
|
||||
|
||||
final int pos = url.indexOf(':', 5);
|
||||
final boolean isLocalFile = pos > 0 && pos < 12;
|
||||
|
||||
final UserAgentType ua = userAgentHelper.getUserAgentType();
|
||||
switch (ua) {
|
||||
case IE:
|
||||
if (isLocalFile) {
|
||||
url = url.replaceFirst("file:/+", systemProperties.getProperty("file.protocol.winlocal.ie", "file://"));
|
||||
} else {
|
||||
url = url.replaceFirst("file:/+", systemProperties.getProperty("file.protocol.ie", "file://"));
|
||||
}
|
||||
break;
|
||||
case FIREFOX:
|
||||
if (isLocalFile) {
|
||||
url = url.replaceFirst("file:/+", systemProperties.getProperty("file.protocol.winlocal.firefox", "file://"));
|
||||
} else {
|
||||
url = url.replaceFirst("file:/+", systemProperties.getProperty("file.protocol.firefox", "file://///"));
|
||||
}
|
||||
break;
|
||||
case CHROME:
|
||||
if (isLocalFile) {
|
||||
url = url.replaceFirst("file:/+", systemProperties.getProperty("file.protocol.winlocal.chrome", "file://"));
|
||||
} else {
|
||||
url = url.replaceFirst("file:/+", systemProperties.getProperty("file.protocol.chrome", "file://"));
|
||||
}
|
||||
break;
|
||||
case SAFARI:
|
||||
if (isLocalFile) {
|
||||
url = url.replaceFirst("file:/+", systemProperties.getProperty("file.protocol.winlocal.safari", "file://"));
|
||||
} else {
|
||||
url = url.replaceFirst("file:/+", systemProperties.getProperty("file.protocol.safari", "file:////"));
|
||||
}
|
||||
break;
|
||||
case OPERA:
|
||||
if (isLocalFile) {
|
||||
url = url.replaceFirst("file:/+", systemProperties.getProperty("file.protocol.winlocal.opera", "file://"));
|
||||
} else {
|
||||
url = url.replaceFirst("file:/+", systemProperties.getProperty("file.protocol.opera", "file://"));
|
||||
}
|
||||
break;
|
||||
default:
|
||||
if (isLocalFile) {
|
||||
url = url.replaceFirst("file:/+", systemProperties.getProperty("file.protocol.winlocal.other", "file://"));
|
||||
} else {
|
||||
url = url.replaceFirst("file:/+", systemProperties.getProperty("file.protocol.other", "file://"));
|
||||
}
|
||||
break;
|
||||
}
|
||||
// file, smb/ftp->http
|
||||
url = updateFileProtocol(url);
|
||||
|
||||
if (encodeUrlLink) {
|
||||
return appendQueryParameter(document, url);
|
||||
} else {
|
||||
final String urlLink = appendQueryParameter(document, url).replace("+", "%2B");
|
||||
final String[] values = urlLink.split("#");
|
||||
final StringBuilder buf = new StringBuilder(urlLink.length());
|
||||
}
|
||||
|
||||
// decode
|
||||
if (!isSmbOrFtpUrl) {
|
||||
// file
|
||||
try {
|
||||
buf.append(URLDecoder.decode(values[0], urlLinkEncoding));
|
||||
for (int i = 1; i < values.length - 1; i++) {
|
||||
buf.append('#').append(URLDecoder.decode(values[i], urlLinkEncoding));
|
||||
url = URLDecoder.decode(url.replace("+", "%2B"), urlLinkEncoding);
|
||||
} catch (Exception e) {
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.warn("Failed to decode " + url, e);
|
||||
}
|
||||
} catch (final Exception e) {
|
||||
throw new FessSystemException("Unsupported encoding: " + urlLinkEncoding, e);
|
||||
}
|
||||
if (values.length > 1) {
|
||||
buf.append('#').append(values[values.length - 1]);
|
||||
}
|
||||
return buf.toString();
|
||||
}
|
||||
}
|
||||
// http, ftp
|
||||
// nothing
|
||||
|
||||
return appendQueryParameter(document, url);
|
||||
}
|
||||
|
||||
protected String updateFileProtocol(String url) {
|
||||
final int pos = url.indexOf(':', 5);
|
||||
final boolean isLocalFile = pos > 0 && pos < 12;
|
||||
|
||||
final UserAgentType ua = userAgentHelper.getUserAgentType();
|
||||
switch (ua) {
|
||||
case IE:
|
||||
if (isLocalFile) {
|
||||
url = url.replaceFirst("file:/+", systemProperties.getProperty("file.protocol.winlocal.ie", "file://"));
|
||||
} else {
|
||||
url = url.replaceFirst("file:/+", systemProperties.getProperty("file.protocol.ie", "file://"));
|
||||
}
|
||||
break;
|
||||
case FIREFOX:
|
||||
if (isLocalFile) {
|
||||
url = url.replaceFirst("file:/+", systemProperties.getProperty("file.protocol.winlocal.firefox", "file://"));
|
||||
} else {
|
||||
url = url.replaceFirst("file:/+", systemProperties.getProperty("file.protocol.firefox", "file://///"));
|
||||
}
|
||||
break;
|
||||
case CHROME:
|
||||
if (isLocalFile) {
|
||||
url = url.replaceFirst("file:/+", systemProperties.getProperty("file.protocol.winlocal.chrome", "file://"));
|
||||
} else {
|
||||
url = url.replaceFirst("file:/+", systemProperties.getProperty("file.protocol.chrome", "file://"));
|
||||
}
|
||||
break;
|
||||
case SAFARI:
|
||||
if (isLocalFile) {
|
||||
url = url.replaceFirst("file:/+", systemProperties.getProperty("file.protocol.winlocal.safari", "file://"));
|
||||
} else {
|
||||
url = url.replaceFirst("file:/+", systemProperties.getProperty("file.protocol.safari", "file:////"));
|
||||
}
|
||||
break;
|
||||
case OPERA:
|
||||
if (isLocalFile) {
|
||||
url = url.replaceFirst("file:/+", systemProperties.getProperty("file.protocol.winlocal.opera", "file://"));
|
||||
} else {
|
||||
url = url.replaceFirst("file:/+", systemProperties.getProperty("file.protocol.opera", "file://"));
|
||||
}
|
||||
break;
|
||||
default:
|
||||
if (isLocalFile) {
|
||||
url = url.replaceFirst("file:/+", systemProperties.getProperty("file.protocol.winlocal.other", "file://"));
|
||||
} else {
|
||||
url = url.replaceFirst("file:/+", systemProperties.getProperty("file.protocol.other", "file://"));
|
||||
}
|
||||
break;
|
||||
}
|
||||
return url;
|
||||
}
|
||||
|
||||
protected String appendQueryParameter(final Map<String, Object> document, final String url) {
|
||||
final FessConfig fessConfig = ComponentUtil.getFessConfig();
|
||||
if (fessConfig.isAppendQueryParameter()) {
|
||||
if (url.indexOf('#') >= 0) {
|
||||
return url;
|
||||
}
|
||||
|
||||
final String mimetype = DocumentUtil.getValue(document, fessConfig.getIndexFieldMimetype(), String.class);
|
||||
if (StringUtil.isNotBlank(mimetype)) {
|
||||
if ("application/pdf".equals(mimetype)) {
|
||||
|
|
|
@ -15,9 +15,15 @@
|
|||
*/
|
||||
package org.codelibs.fess.helper;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import org.codelibs.core.io.FileUtil;
|
||||
import org.codelibs.core.misc.DynamicProperties;
|
||||
import org.codelibs.fess.es.config.exentity.PathMapping;
|
||||
import org.codelibs.fess.mylasta.direction.FessConfig;
|
||||
import org.codelibs.fess.unit.UnitFessTestCase;
|
||||
import org.codelibs.fess.util.ComponentUtil;
|
||||
|
@ -31,6 +37,109 @@ public class ViewHelperTest extends UnitFessTestCase {
|
|||
viewHelper.init();
|
||||
}
|
||||
|
||||
public void test_getUrlLink() throws IOException {
|
||||
ComponentUtil.setFessConfig(new FessConfig.SimpleImpl() {
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
public boolean isAppendQueryParameter() {
|
||||
return false;
|
||||
}
|
||||
|
||||
public String getIndexFieldUrl() {
|
||||
return "url";
|
||||
}
|
||||
|
||||
public String getIndexFieldDocId() {
|
||||
return "doc_id";
|
||||
}
|
||||
});
|
||||
|
||||
// http
|
||||
assertUrlLink("http://www.codelibs.org/", //
|
||||
"http://www.codelibs.org/");
|
||||
assertUrlLink("http://www.codelibs.org/あ", //
|
||||
"http://www.codelibs.org/あ");
|
||||
assertUrlLink("http://www.codelibs.org/%E3%81%82", //
|
||||
"http://www.codelibs.org/%E3%81%82");
|
||||
assertUrlLink("http://www.codelibs.org/%z", //
|
||||
"http://www.codelibs.org/%z");
|
||||
assertUrlLink("http://www.codelibs.org/?a=1&b=2", //
|
||||
"http://www.codelibs.org/?a=1&b=2");
|
||||
|
||||
// https
|
||||
assertUrlLink("https://www.codelibs.org/", //
|
||||
"https://www.codelibs.org/");
|
||||
assertUrlLink("https://www.codelibs.org/あ", //
|
||||
"https://www.codelibs.org/あ");
|
||||
assertUrlLink("https://www.codelibs.org/%E3%81%82", //
|
||||
"https://www.codelibs.org/%E3%81%82");
|
||||
assertUrlLink("https://www.codelibs.org/%z", //
|
||||
"https://www.codelibs.org/%z");
|
||||
assertUrlLink("https://www.codelibs.org/?a=1&b=2", //
|
||||
"https://www.codelibs.org/?a=1&b=2");
|
||||
|
||||
// ftp
|
||||
assertUrlLink("ftp://www.codelibs.org/", //
|
||||
"ftp://www.codelibs.org/");
|
||||
assertUrlLink("ftp://www.codelibs.org/あ", //
|
||||
"ftp://www.codelibs.org/あ");
|
||||
assertUrlLink("ftp://www.codelibs.org/%E3%81%82", //
|
||||
"ftp://www.codelibs.org/%E3%81%82");
|
||||
assertUrlLink("ftp://www.codelibs.org/%z", //
|
||||
"ftp://www.codelibs.org/%z");
|
||||
|
||||
viewHelper.userAgentHelper = new UserAgentHelper() {
|
||||
public UserAgentType getUserAgentType() {
|
||||
return UserAgentType.IE;
|
||||
}
|
||||
};
|
||||
File tempFile = File.createTempFile("test", ".properties");
|
||||
FileUtil.writeBytes(tempFile.getAbsolutePath(), new byte[0]);
|
||||
tempFile.deleteOnExit();
|
||||
viewHelper.systemProperties = new DynamicProperties(tempFile);
|
||||
|
||||
// file
|
||||
assertUrlLink("file:/home/taro/test.txt", //
|
||||
"file://home/taro/test.txt");
|
||||
assertUrlLink("file:/home/taro/あ.txt", //
|
||||
"file://home/taro/あ.txt");
|
||||
assertUrlLink("file:/home/taro/%E3%81%82.txt", //
|
||||
"file://home/taro/あ.txt");
|
||||
|
||||
// smb->file
|
||||
assertUrlLink("smb:/home/taro/test.txt", //
|
||||
"file://home/taro/test.txt");
|
||||
assertUrlLink("smb:/home/taro/あ.txt", //
|
||||
"file://home/taro/あ.txt");
|
||||
assertUrlLink("smb:/home/taro/%E3%81%82.txt", //
|
||||
"file://home/taro/%E3%81%82.txt");
|
||||
|
||||
PathMapping pathMapping = new PathMapping();
|
||||
pathMapping.setRegex("ftp:");
|
||||
pathMapping.setReplacement("file:");
|
||||
viewHelper.pathMappingHelper = new PathMappingHelper();
|
||||
viewHelper.pathMappingHelper.cachedPathMappingList = new ArrayList<>();
|
||||
viewHelper.pathMappingHelper.cachedPathMappingList.add(pathMapping);
|
||||
// ftp->file
|
||||
assertUrlLink("ftp:/home/taro/test.txt", //
|
||||
"file://home/taro/test.txt");
|
||||
assertUrlLink("ftp:/home/taro/あ.txt", //
|
||||
"file://home/taro/あ.txt");
|
||||
assertUrlLink("ftp:/home/taro/%E3%81%82.txt", //
|
||||
"file://home/taro/%E3%81%82.txt");
|
||||
|
||||
assertUrlLink(null, "#not-found-docId");
|
||||
assertUrlLink("", "#not-found-docId");
|
||||
assertUrlLink(" ", "#not-found-docId");
|
||||
}
|
||||
|
||||
private void assertUrlLink(String url, String expected) {
|
||||
Map<String, Object> doc = new HashMap<>();
|
||||
doc.put("doc_id", "docId");
|
||||
doc.put("url", url);
|
||||
assertEquals(expected, viewHelper.getUrlLink(doc));
|
||||
}
|
||||
|
||||
public void test_replaceHighlightQueries() {
|
||||
String text;
|
||||
String[] queries;
|
||||
|
|
Loading…
Add table
Reference in a new issue