/* * Copyright 2012-2017 CodeLibs Project and the Others. * * Licensed 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.codelibs.fess.app.web.go; import java.io.IOException; import java.io.UnsupportedEncodingException; 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; import org.codelibs.fess.Constants; import org.codelibs.fess.app.web.base.FessSearchAction; import org.codelibs.fess.app.web.error.ErrorAction; import org.codelibs.fess.crawler.util.CharUtil; import org.codelibs.fess.es.log.exentity.ClickLog; import org.codelibs.fess.helper.PathMappingHelper; import org.codelibs.fess.helper.SearchLogHelper; import org.codelibs.fess.helper.ViewHelper; import org.codelibs.fess.util.ComponentUtil; import org.codelibs.fess.util.DocumentUtil; import org.dbflute.util.DfTypeUtil; 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; public class GoAction extends FessSearchAction { // =================================================================================== // Constant // private static final Logger logger = LoggerFactory.getLogger(GoAction.class); @Resource protected PathMappingHelper pathMappingHelper; // =================================================================================== // Attribute // // =================================================================================== // Hook // ====== // =================================================================================== // Search Execute // ============== @Execute public ActionResponse index(final GoForm form) throws IOException { validate(form, messages -> {}, () -> asHtml(virtualHost(path_Error_ErrorJsp))); if (isLoginRequired()) { return redirectToLogin(); } Map<String, Object> doc = null; try { doc = searchService.getDocumentByDocId(form.docId, new String[] { fessConfig.getIndexFieldUrl(), fessConfig.getIndexFieldConfigId() }, getUserBean()).orElse(null); } catch (final Exception e) { logger.warn("Failed to request: " + form.docId, e); } if (doc == null) { saveError(messages -> messages.addErrorsDocidNotFound(GLOBAL, form.docId)); return redirect(ErrorAction.class); } final String url = DocumentUtil.getValue(doc, fessConfig.getIndexFieldUrl(), String.class); if (url == null) { saveError(messages -> messages.addErrorsDocumentNotFound(GLOBAL, form.docId)); return redirect(ErrorAction.class); } if (fessConfig.isSearchLog()) { final String userSessionId = userInfoHelper.getUserCode(); if (userSessionId != null) { final SearchLogHelper searchLogHelper = ComponentUtil.getSearchLogHelper(); final ClickLog clickLog = new ClickLog(); clickLog.setUrl(url); clickLog.setRequestedAt(systemHelper.getCurrentTimeAsLocalDateTime()); clickLog.setQueryRequestedAt(DfTypeUtil.toLocalDateTime(Long.parseLong(form.rt))); clickLog.setUserSessionId(userSessionId); clickLog.setDocId(form.docId); clickLog.setQueryId(form.queryId); if (form.order != null) { clickLog.setOrder(form.order); } searchLogHelper.addClickLog(clickLog); } } String hash; if (StringUtil.isNotBlank(form.hash)) { final String value = URLUtil.decode(form.hash, Constants.UTF_8); final StringBuilder buf = new StringBuilder(value.length() + 100); for (final char c : value.toCharArray()) { if (CharUtil.isUrlChar(c) || c == ' ') { buf.append(c); } else { try { buf.append(URLEncoder.encode(String.valueOf(c), Constants.UTF_8)); } catch (final UnsupportedEncodingException e) { // NOP } } } hash = buf.toString(); } else { hash = StringUtil.EMPTY; } final String targetUrl = pathMappingHelper.replaceUrl(url); if (isFileSystemPath(targetUrl)) { if (fessConfig.isSearchFileProxyEnabled()) { final ViewHelper viewHelper = ComponentUtil.getViewHelper(); try { final StreamResponse response = viewHelper.asContentResponse(doc); if (response.getHttpStatus().orElse(200) == 404) { logger.debug("Not found: " + targetUrl); saveError(messages -> messages.addErrorsNotFoundOnFileSystem(GLOBAL, targetUrl)); return redirect(ErrorAction.class); } return response; } catch (final Exception e) { logger.warn("Failed to load: " + doc, e); saveError(messages -> messages.addErrorsNotLoadFromServer(GLOBAL, targetUrl)); return redirect(ErrorAction.class); } } else { return redirect(targetUrl + hash); } } else { return redirect(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:"); } }