diff --git a/docker/kkfileview-jdk/Dockerfile b/docker/kkfileview-jdk/Dockerfile index 05ea6b57..0fedc49f 100644 --- a/docker/kkfileview-jdk/Dockerfile +++ b/docker/kkfileview-jdk/Dockerfile @@ -2,28 +2,25 @@ FROM ubuntu:20.04 MAINTAINER chenjh "842761733@qq.com" # 内置一些常用的中文字体,避免普遍性乱码 COPY fonts/* /usr/share/fonts/chinese/ -RUN echo "deb http://mirrors.aliyun.com/ubuntu/ focal main restricted universe multiverse\ndeb-src http://mirrors.aliyun.com/ubuntu/ focal main restricted universe multiverse\ndeb http://mirrors.aliyun.com/ubuntu/ focal-security main restricted universe multiverse\ndeb-src http://mirrors.aliyun.com/ubuntu/ focal-security main restricted universe multiverse\ndeb http://mirrors.aliyun.com/ubuntu/ focal-updates main restricted universe multiverse\ndeb-src http://mirrors.aliyun.com/ubuntu/ focal-updates main restricted universe multiverse\ndeb http://mirrors.aliyun.com/ubuntu/ focal-proposed main restricted universe multiverse\ndeb-src http://mirrors.aliyun.com/ubuntu/ focal-proposed main restricted universe multiverse\ndeb http://mirrors.aliyun.com/ubuntu/ focal-backports main restricted universe multiverse\ndeb-src http://mirrors.aliyun.com/ubuntu/ focal-backports main restricted universe multiverse" > /etc/apt/sources.list &&\ +RUN sed -i 's/http:\/\/archive.ubuntu.com/https:\/\/mirrors.aliyun.com/g' /etc/apt/sources.list &&\ apt-get clean && apt-get update &&\ - apt-get install -y locales && apt-get install -y language-pack-zh-hans &&\ + apt-get install -y locales language-pack-zh-hans &&\ localedef -i zh_CN -c -f UTF-8 -A /usr/share/locale/locale.alias zh_CN.UTF-8 && locale-gen zh_CN.UTF-8 &&\ export DEBIAN_FRONTEND=noninteractive &&\ apt-get install -y tzdata && ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime &&\ - apt-get install -y libxrender1 && apt-get install -y libxt6 && apt-get install -y libxext-dev && apt-get install -y libfreetype6-dev &&\ - apt-get install -y wget && apt-get install -y ttf-mscorefonts-installer && apt-get install -y fontconfig &&\ - apt-get install ttf-wqy-microhei &&\ - apt-get install ttf-wqy-zenhei &&\ - apt-get install xfonts-wqy &&\ + apt-get install -y fontconfig ttf-mscorefonts-installer ttf-wqy-microhei ttf-wqy-zenhei xfonts-wqy &&\ + apt-get install -y wget &&\ cd /tmp &&\ wget https://kkfileview.keking.cn/server-jre-8u251-linux-x64.tar.gz &&\ tar -zxf /tmp/server-jre-8u251-linux-x64.tar.gz && mv /tmp/jdk1.8.0_251 /usr/local/ &&\ -# 安装 libreoffice - apt-get install -y libxinerama1 libcairo2 libcups2 libx11-xcb1 &&\ - wget https://kkfileview.keking.cn/LibreOffice_7.1.4_Linux_x86-64_deb.tar.gz -cO libreoffice_deb.tar.gz &&\ - tar -zxf /tmp/libreoffice_deb.tar.gz && cd /tmp/LibreOffice_7.1.4.2_Linux_x86-64_deb/DEBS &&\ +# 安装 libreoffice + apt-get install -y libxrender1 libxinerama1 libxt6 libxext-dev libfreetype6-dev libcairo2 libcups2 libx11-xcb1 libnss3 &&\ + wget https://kkfileview.keking.cn/LibreOffice_7.3.7_Linux_x86-64_deb.tar.gz -cO libreoffice_deb.tar.gz &&\ + tar -zxf /tmp/libreoffice_deb.tar.gz && cd /tmp/LibreOffice_7.3.7.2_Linux_x86-64_deb/DEBS &&\ dpkg -i *.deb &&\ -# 清理临时文件 +# 清理临时文件 rm -rf /tmp/* && rm -rf /var/lib/apt/lists/* &&\ cd /usr/share/fonts/chinese &&\ mkfontscale &&\ @@ -35,4 +32,4 @@ ENV CLASSPATH $JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar ENV PATH $PATH:$JAVA_HOME/bin ENV LANG zh_CN.UTF-8 ENV LC_ALL zh_CN.UTF-8 -ENTRYPOINT ["java","-version"] \ No newline at end of file +CMD ["/bin/bash"] diff --git a/office-plugin/src/main/java/org/artofsolving/jodconverter/office/OfficeUtils.java b/office-plugin/src/main/java/org/artofsolving/jodconverter/office/OfficeUtils.java index d155a2a1..5d567a57 100644 --- a/office-plugin/src/main/java/org/artofsolving/jodconverter/office/OfficeUtils.java +++ b/office-plugin/src/main/java/org/artofsolving/jodconverter/office/OfficeUtils.java @@ -112,6 +112,8 @@ public class OfficeUtils { "/opt/libreoffice7.0", "/opt/libreoffice7.1", "/opt/libreoffice7.2", + "/opt/libreoffice7.3", + "/opt/libreoffice7.4", "/opt/openoffice4", "/usr/lib/openoffice", "/usr/lib/libreoffice" diff --git a/server/src/main/bin/install.sh b/server/src/main/bin/install.sh index 9b35a762..e1dba40f 100644 --- a/server/src/main/bin/install.sh +++ b/server/src/main/bin/install.sh @@ -2,12 +2,12 @@ cd /tmp install_redhat() { - wget https://kkfileview.keking.cn/LibreOffice_7.1.4_Linux_x86-64_rpm.tar.gz -cO LibreOffice_7_rpm.tar.gz && tar -zxf /tmp/LibreOffice_7_rpm.tar.gz && cd /tmp/LibreOffice_7.1.4.2_Linux_x86-64_rpm/RPMS + wget https://kkfileview.keking.cn/LibreOffice_7.3.7_Linux_x86-64_rpm.tar.gz -cO LibreOffice_7_rpm.tar.gz && tar -zxf /tmp/LibreOffice_7_rpm.tar.gz && cd /tmp/LibreOffice_7.3.7.2_Linux_x86-64_rpm/RPMS echo $? if [ $? -eq 0 ];then - yum install -y libXext.x86_64 + yum install -y libSM.x86_64 libXrender.x86_64 libXext.x86_64 yum groupinstall -y "X Window System" - yum localinstall *.rpm + yum localinstall -y *.rpm echo 'install finshed...' else echo 'download package error...' @@ -15,7 +15,7 @@ install_redhat() { } install_ubuntu() { - wget https://kkfileview.keking.cn/LibreOffice_7.1.4_Linux_x86-64_deb.tar.gz -cO LibreOffice_7_deb.tar.gz && tar -zxf /tmp/LibreOffice_7_deb.tar.gz && cd /tmp/LibreOffice_7.1.4.2_Linux_x86-64_deb/DEBS + wget https://kkfileview.keking.cn/LibreOffice_7.3.7_Linux_x86-64_deb.tar.gz -cO LibreOffice_7_deb.tar.gz && tar -zxf /tmp/LibreOffice_7_deb.tar.gz && cd /tmp/LibreOffice_7.3.7.2_Linux_x86-64_deb/DEBS echo $? if [ $? -eq 0 ];then apt-get install -y libxinerama1 libcairo2 libcups2 libx11-xcb1 @@ -33,4 +33,4 @@ if [ -f "/etc/redhat-release" ]; then else apt-get install -y wget install_ubuntu -fi \ No newline at end of file +fi diff --git a/server/src/main/bin/startup.sh b/server/src/main/bin/startup.sh index 94da282e..25d3b49d 100644 --- a/server/src/main/bin/startup.sh +++ b/server/src/main/bin/startup.sh @@ -9,7 +9,7 @@ # Description: v1.1:修改进程启动机制为pid形式。 ############################# # -DIR_HOME=("/opt/openoffice.org3" "/opt/libreoffice" "/opt/libreoffice6.1" "/opt/libreoffice7.0" "/opt/libreoffice7.1" "/opt/openoffice4" "/usr/lib/openoffice" "/usr/lib/libreoffice") +DIR_HOME=("/opt/openoffice.org3" "/opt/libreoffice" "/opt/libreoffice6.1" "/opt/libreoffice7.0" "/opt/libreoffice7.1" "/opt/libreoffice7.2" "/opt/libreoffice7.3" "/opt/libreoffice7.4" "/opt/openoffice4" "/usr/lib/openoffice" "/usr/lib/libreoffice") FLAG= OFFICE_HOME= KKFILEVIEW_BIN_FOLDER=$(cd "$(dirname "$0")" || exit 1 ;pwd) @@ -32,7 +32,7 @@ else grep 'office\.home' ../config/application.properties | grep '!^#' if [ $? -eq 0 ]; then echo "Using customized office.home" - else + else for i in ${DIR_HOME[@]} do if [ -f "$i/program/soffice.bin" ]; then @@ -42,9 +42,9 @@ else fi done if [ ! -n "${FLAG}" ]; then - echo "Installing OpenOffice" + echo "Installing LibreOffice" sh ./install.sh - else + else echo "Detected office component has been installed in $OFFICE_HOME" fi fi diff --git a/server/src/main/java/cn/keking/ServerMain.java b/server/src/main/java/cn/keking/ServerMain.java index 31c44df6..71a25ba4 100644 --- a/server/src/main/java/cn/keking/ServerMain.java +++ b/server/src/main/java/cn/keking/ServerMain.java @@ -1,6 +1,5 @@ package cn.keking; -import cn.keking.config.AppBanner; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.boot.autoconfigure.SpringBootApplication; @@ -23,7 +22,6 @@ public class ServerMain { stopWatch.start(); ConfigurableApplicationContext context = new SpringApplicationBuilder(ServerMain.class) .logStartupInfo(false) - .banner(new AppBanner()) .run(args); stopWatch.stop(); Integer port = context.getBean(ServerProperties.class).getPort(); diff --git a/server/src/main/java/cn/keking/config/AppBanner.java b/server/src/main/java/cn/keking/config/AppBanner.java deleted file mode 100644 index 94e21af9..00000000 --- a/server/src/main/java/cn/keking/config/AppBanner.java +++ /dev/null @@ -1,28 +0,0 @@ -package cn.keking.config; - -import org.springframework.boot.Banner; -import org.springframework.core.env.Environment; - -import java.io.PrintStream; - -/** - * @author kl (http://kailing.pub) - * @since 2021/2/8 - */ -public class AppBanner implements Banner { - @Override - public void printBanner(Environment environment, Class sourceClass, PrintStream out) { - out.println( - " _ _ ______ _ _ __ __ _ \n" + - " | | | | | ____| (_) | | \\ \\ / / (_) \n" + - " | | __ | | __ | |__ _ | | ___ \\ \\ / / _ ___ __ __\n" + - " | |/ / | |/ / | __| | | | | / _ \\ \\ \\/ / | | / _ \\ \\ \\ /\\ / /\n" + - " | < | < | | | | | | | __/ \\ / | | | __/ \\ V V / \n" + - " |_|\\_\\ |_|\\_\\ |_| |_| |_| \\___| \\/ |_| \\___| \\_/\\_/ \n" + - " \n" + - " => Spring Boot :: (v2.4.2) QQ1 :: 613025121\n" + - " => kkFileView :: (v4.1.0-SNAPSHOT) QQ2 :: 484680571\n" + - " => github :: https://github.com/kekingcn/kkFileView\n" + - " => gitee :: https://gitee.com/kekingcn/file-online-preview\n"); - } -} diff --git a/server/src/main/java/cn/keking/service/OfficePluginManager.java b/server/src/main/java/cn/keking/service/OfficePluginManager.java index f6cafef2..3a7d8163 100644 --- a/server/src/main/java/cn/keking/service/OfficePluginManager.java +++ b/server/src/main/java/cn/keking/service/OfficePluginManager.java @@ -120,7 +120,7 @@ public class OfficePluginManager { baos.write(b); } String s = baos.toString(); - if (!"0".equals(s)) { + if (!s.startsWith("0")) { String[] cmd = {"sh", "-c", "ps -ef | grep soffice.bin | grep -v grep | awk '{print \"kill -9 \"$2}' | sh"}; Runtime.getRuntime().exec(cmd); flag = true; diff --git a/server/src/main/java/cn/keking/utils/WebUtils.java b/server/src/main/java/cn/keking/utils/WebUtils.java index 5b04067a..80568f26 100644 --- a/server/src/main/java/cn/keking/utils/WebUtils.java +++ b/server/src/main/java/cn/keking/utils/WebUtils.java @@ -8,6 +8,7 @@ import javax.servlet.ServletRequest; import java.io.UnsupportedEncodingException; import java.net.MalformedURLException; import java.net.URL; +import java.net.URLDecoder; import java.net.URLEncoder; import java.nio.charset.Charset; import java.nio.charset.StandardCharsets; @@ -157,16 +158,16 @@ public class WebUtils { String currentUrl = request.getParameter("currentUrl"); String urlPath = request.getParameter("urlPath"); if (StringUtils.isNotBlank(url)) { - return decodeBase64String(url); + return decodeUrl(url); } if (StringUtils.isNotBlank(currentUrl)) { - return decodeBase64String(currentUrl); + return decodeUrl(currentUrl); } if (StringUtils.isNotBlank(urlPath)) { - return decodeBase64String(urlPath); + return decodeUrl(urlPath); } if (StringUtils.isNotBlank(urls)) { - urls = decodeBase64String(urls); + urls = decodeUrl(urls); String[] images = urls.split("\\|"); return images[0]; } @@ -174,12 +175,20 @@ public class WebUtils { } /** - * 将 Base64 字符串解码,默认使用 UTF-8 + * 将 Base64 字符串解码,再解码URL参数, 默认使用 UTF-8 * @param source 原始 Base64 字符串 * @return decoded string + * + * aHR0cHM6Ly9maWxlLmtla2luZy5jbi9kZW1vL%2BS4reaWhy5wcHR4 -> https://file.keking.cn/demo/%E4%B8%AD%E6%96%87.pptx -> https://file.keking.cn/demo/中文.pptx */ - public static String decodeBase64String(String source) { - return decodeBase64String(source, StandardCharsets.UTF_8); + public static String decodeUrl(String source) { + String url = decodeBase64String(source, StandardCharsets.UTF_8); + try { + url = URLDecoder.decode(url, StandardCharsets.UTF_8.name()); + } catch (UnsupportedEncodingException e) { + throw new RuntimeException(e); + } + return url; } /** diff --git a/server/src/main/java/cn/keking/web/controller/OnlinePreviewController.java b/server/src/main/java/cn/keking/web/controller/OnlinePreviewController.java index c2d09264..b30ec78e 100644 --- a/server/src/main/java/cn/keking/web/controller/OnlinePreviewController.java +++ b/server/src/main/java/cn/keking/web/controller/OnlinePreviewController.java @@ -56,7 +56,7 @@ public class OnlinePreviewController { public String onlinePreview(String url, Model model, HttpServletRequest req) { String fileUrl; try { - fileUrl = WebUtils.decodeBase64String(url); + fileUrl = WebUtils.decodeUrl(url); } catch (Exception ex) { String errorMsg = String.format(BASE64_DECODE_ERROR_MSG, "url"); return otherFilePreview.notSupportedFile(model, errorMsg); @@ -72,20 +72,18 @@ public class OnlinePreviewController { public String picturesPreview(String urls, Model model, HttpServletRequest req) throws UnsupportedEncodingException { String fileUrls; try { - fileUrls = WebUtils.decodeBase64String(urls); + fileUrls = WebUtils.decodeUrl(urls); // 防止XSS攻击 fileUrls = HtmlUtils.htmlEscape(fileUrls); } catch (Exception ex) { String errorMsg = String.format(BASE64_DECODE_ERROR_MSG, "urls"); return otherFilePreview.notSupportedFile(model, errorMsg); } - logger.info("预览文件url:{},urls:{}", fileUrls, urls); // 抽取文件并返回文件列表 String[] images = fileUrls.split("\\|"); List imgUrls = Arrays.asList(images); model.addAttribute("imgUrls", imgUrls); - String currentUrl = req.getParameter("currentUrl"); if (StringUtils.hasText(currentUrl)) { String decodedCurrentUrl = new String(Base64.decodeBase64(currentUrl)); @@ -106,7 +104,7 @@ public class OnlinePreviewController { @GetMapping("/getCorsFile") public void getCorsFile(String urlPath, HttpServletResponse response) { try { - urlPath = WebUtils.decodeBase64String(urlPath); + urlPath = WebUtils.decodeUrl(urlPath); } catch (Exception ex) { logger.error(String.format(BASE64_DECODE_ERROR_MSG, urlPath),ex); return; @@ -116,7 +114,6 @@ public class OnlinePreviewController { logger.info("读取跨域文件异常,可能存在非法访问,urlPath:{}", urlPath); return; } - logger.info("下载跨域pdf文件url:{}", urlPath); try { URL url = WebUtils.normalizedURL(urlPath); diff --git a/server/src/main/resources/banner.txt b/server/src/main/resources/banner.txt new file mode 100644 index 00000000..fccdef64 --- /dev/null +++ b/server/src/main/resources/banner.txt @@ -0,0 +1,14 @@ + + _ _ ______ _ _ __ __ _ + | | | | | ____| (_) | | \ \ / / (_) + | | __ | | __ | |__ _ | | ___ \ \ / / _ ___ __ __ + | |/ / | |/ / | __| | | | | / _ \ \ \/ / | | / _ \ \ \ /\ / / + | < | < | | | | | | | __/ \ / | | | __/ \ V V / + |_|\_\ |_|\_\ |_| |_| |_| \___| \/ |_| \___| \_/\_/ + + => Spring Boot :: ${spring-boot.version} + => kkFileView :: 4.1.0-SNAPSHOT + => Homepage :: https://kkfileview.keking.cn + => Github :: https://github.com/kekingcn/kkFileView + => Gitee :: https://gitee.com/kekingcn/file-online-preview + => QQ Group :: 613025121 484680571 diff --git a/server/src/main/resources/web/index.ftl b/server/src/main/resources/web/index.ftl index bd84fba5..a1023af1 100644 --- a/server/src/main/resources/web/index.ftl +++ b/server/src/main/resources/web/index.ftl @@ -36,15 +36,15 @@ 如果你的项目需要接入文件预览项目,达到对docx、excel、ppt、jpg等文件的预览效果,那么通过在你的项目中加入下面的代码就可以 成功实现:
-                    var url = 'http://127.0.0.1:8080/file/test.txt'; //要预览文件的访问地址
-                    window.open('http://127.0.0.1:8012/onlinePreview?url='+encodeURIComponent(base64Encode(url)));
+var url = 'http://127.0.0.1:8080/file/test.txt'; //要预览文件的访问地址
+window.open('http://127.0.0.1:8012/onlinePreview?url='+encodeURIComponent(base64Encode(url)));
                 
新增多图片同时预览功能,接口如下:
-                    var fileUrl =url1+"|"+"url2";//多文件使用“|”字符隔开
-                    window.open('http://127.0.0.1:8012/picturesPreview?urls='+encodeURIComponent(base64Encode(fileUrl)));
+var fileUrl =url1+'|'+url2;//多url使用'|'字符隔开
+window.open('http://127.0.0.1:8012/picturesPreview?urls='+encodeURIComponent(base64Encode(fileUrl)));
                 
@@ -254,6 +254,33 @@ }) } + function showLoadingDiv() { + var height = window.document.documentElement.clientHeight - 1; + $(".loading_container").css("height", height).show(); + } + + function checkUrl(url){ + //url= 协议://(ftp的登录信息)[IP|域名](:端口号)(/或?请求参数) + var strRegex = '^((https|http|ftp)://)'//(https或http或ftp) + + '(([\\w_!~*\'()\\.&=+$%-]+: )?[\\w_!~*\'()\\.&=+$%-]+@)?' //ftp的user@ 可有可无 + + '(([0-9]{1,3}\\.){3}[0-9]{1,3}' // IP形式的URL- 3位数字.3位数字.3位数字.3位数字 + + '|' // 允许IP和DOMAIN(域名) + + '(localhost)|' //匹配localhost + + '([\\w_!~*\'()-]+\\.)*' // 域名- 至少一个[英文或数字_!~*\'()-]加上. + + '\\w+\\.' // 一级域名 -英文或数字 加上. + + '[a-zA-Z]{1,6})' // 顶级域名- 1-6位英文 + + '(:[0-9]{1,5})?' // 端口- :80 ,1-5位数字 + + '((/?)|' // url无参数结尾 - 斜杆或这没有 + + '(/[\\w_!~*\'()\\.;?:@&=+$,%#-]+)+/?)$';//请求参数结尾- 英文或数字和[]内的各种字符 + var re = new RegExp(strRegex,'i');//i不区分大小写 + //将url做uri转码后再匹配,解除请求参数中的中文和空字符影响 + if (re.test(encodeURI(url))) { + return (true); + } else { + return (false); + } + } + $(function () { $('#table').bootstrapTable({ url: 'listFiles', @@ -278,15 +305,15 @@ $('#preview_by_url').submit(function() { var _url = $("#_url").val(); + if (!checkUrl(_url)) { + alert('请输入正确的url'); + return false; + } var urlField = $(this).find('[name=url]'); var b64Encoded = Base64.encode(_url); urlField.val(b64Encoded); }); - function showLoadingDiv() { - var height = window.document.documentElement.clientHeight - 1; - $(".loading_container").css("height", height).show(); - } $("#btnSubmit").click(function () { showLoadingDiv(); $("#fileUpload").ajaxSubmit({