diff --git a/src/main/java/org/b3log/symphony/processor/FetchUploadProcessor.java b/src/main/java/org/b3log/symphony/processor/FetchUploadProcessor.java deleted file mode 100644 index 700628b3e..000000000 --- a/src/main/java/org/b3log/symphony/processor/FetchUploadProcessor.java +++ /dev/null @@ -1,175 +0,0 @@ -/* - * Symphony - A modern community (forum/BBS/SNS/blog) platform written in Java. - * Copyright (C) 2012-present, b3log.org - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see . - */ -package org.b3log.symphony.processor; - -import com.qiniu.storage.Configuration; -import com.qiniu.storage.UploadManager; -import com.qiniu.util.Auth; -import jodd.http.HttpRequest; -import jodd.http.HttpResponse; -import org.apache.commons.io.IOUtils; -import org.apache.commons.lang.StringUtils; -import org.apache.logging.log4j.Level; -import org.apache.logging.log4j.LogManager; -import org.apache.logging.log4j.Logger; -import org.b3log.latke.Keys; -import org.b3log.latke.Latkes; -import org.b3log.latke.http.HttpMethod; -import org.b3log.latke.http.RequestContext; -import org.b3log.latke.http.annotation.After; -import org.b3log.latke.http.annotation.Before; -import org.b3log.latke.http.annotation.RequestProcessing; -import org.b3log.latke.http.annotation.RequestProcessor; -import org.b3log.latke.ioc.Inject; -import org.b3log.latke.service.LangPropsService; -import org.b3log.latke.util.Strings; -import org.b3log.symphony.model.Common; -import org.b3log.symphony.processor.middleware.LoginCheckMidware; -import org.b3log.symphony.processor.middleware.stopwatch.StopwatchEndAdvice; -import org.b3log.symphony.processor.middleware.stopwatch.StopwatchStartAdvice; -import org.b3log.symphony.service.OptionQueryService; -import org.b3log.symphony.util.*; -import org.json.JSONObject; - -import java.io.FileOutputStream; -import java.io.OutputStream; -import java.net.InetAddress; -import java.net.URL; -import java.nio.file.Path; -import java.nio.file.Paths; -import java.util.UUID; - -/** - * Fetch file and upload processor. - *

- *

- *

- * - * @author Liang Ding - * @version 1.0.2.0, May 8, 2019 - * @since 1.5.0 - */ -@RequestProcessor -public class FetchUploadProcessor { - - /** - * Logger. - */ - private static final Logger LOGGER = LogManager.getLogger(FetchUploadProcessor.class); - - /** - * Option query service. - */ - @Inject - private OptionQueryService optionQueryService; - - /** - * Language service. - */ - @Inject - private LangPropsService langPropsService; - - /** - * Fetches the remote file and upload it. - * - * @param context the specified context - */ - @RequestProcessing(value = "/fetch-upload", method = HttpMethod.POST) - @Before({StopwatchStartAdvice.class, LoginCheckMidware.class}) - @After({StopwatchEndAdvice.class}) - public void fetchUpload(final RequestContext context) { - final JSONObject result = Results.newFail(); - context.renderJSONPretty(result); - final JSONObject data = new JSONObject(); - - final JSONObject requestJSONObject = context.requestJSON(); - final String originalURL = requestJSONObject.optString(Common.URL); - if (!Strings.isURL(originalURL) || !StringUtils.startsWithIgnoreCase(originalURL, "http")) { - return; - } - - byte[] bytes; - String contentType; - try { - final String host = new URL(originalURL).getHost(); - final String hostIp = InetAddress.getByName(host).getHostAddress(); - if (Networks.isInnerAddress(hostIp)) { - return; - } - - final HttpRequest req = HttpRequest.get(originalURL).header(Common.USER_AGENT, Symphonys.USER_AGENT_BOT); - final HttpResponse res = req.connectionTimeout(3000).timeout(5000).send(); - res.close(); - if (200 != res.statusCode()) { - return; - } - - bytes = res.bodyBytes(); - contentType = res.contentType(); - } catch (final Exception e) { - LOGGER.log(Level.ERROR, "Fetch file [url=" + originalURL + "] failed", e); - - return; - } - - final String suffix = Headers.getSuffix(contentType); - final String[] allowedSuffixArray = Symphonys.UPLOAD_SUFFIX.split(","); - if (!Strings.containsIgnoreCase(suffix, allowedSuffixArray)) { - String msg = langPropsService.get("invalidFileSuffixLabel"); - msg = StringUtils.replace(msg, "${suffix}", suffix); - result.put(Keys.MSG, msg); - - return; - } - - String fileName = UUID.randomUUID().toString().replace("-", "") + "." + suffix; - - if (Symphonys.QN_ENABLED) { - final Auth auth = Auth.create(Symphonys.UPLOAD_QINIU_AK, Symphonys.UPLOAD_QINIU_SK); - final UploadManager uploadManager = new UploadManager(new Configuration()); - - try { - uploadManager.put(bytes, "e/" + fileName, auth.uploadToken(Symphonys.UPLOAD_QINIU_BUCKET), - null, contentType, false); - } catch (final Exception e) { - LOGGER.log(Level.ERROR, "Uploads to Qiniu failed", e); - } - - data.put(Common.URL, Symphonys.UPLOAD_QINIU_DOMAIN + "/e/" + fileName); - data.put("originalURL", originalURL); - } else { - fileName = FileUploadProcessor.genFilePath(fileName); - final Path path = Paths.get(Symphonys.UPLOAD_LOCAL_DIR, fileName); - path.getParent().toFile().mkdirs(); - try (final OutputStream output = new FileOutputStream(Symphonys.UPLOAD_LOCAL_DIR + fileName)) { - IOUtils.write(bytes, output); - } catch (final Exception e) { - LOGGER.log(Level.ERROR, "Writes output stream failed", e); - } - - data.put(Common.URL, Latkes.getServePath() + "/upload/" + fileName); - data.put("originalURL", originalURL); - } - - result.put(Common.DATA, data); - result.put(Keys.CODE, StatusCodes.SUCC); - result.put(Keys.MSG, ""); - } -} diff --git a/src/main/java/org/b3log/symphony/processor/FileUploadProcessor.java b/src/main/java/org/b3log/symphony/processor/FileUploadProcessor.java index 1f0baedff..7a6fa4346 100644 --- a/src/main/java/org/b3log/symphony/processor/FileUploadProcessor.java +++ b/src/main/java/org/b3log/symphony/processor/FileUploadProcessor.java @@ -20,6 +20,8 @@ import com.qiniu.storage.Configuration; import com.qiniu.storage.UploadManager; import com.qiniu.util.Auth; +import jodd.http.HttpRequest; +import jodd.http.HttpResponse; import jodd.io.FileUtil; import jodd.net.MimeTypes; import org.apache.commons.codec.digest.DigestUtils; @@ -32,9 +34,9 @@ import org.b3log.latke.Keys; import org.b3log.latke.Latkes; import org.b3log.latke.http.*; -import org.b3log.latke.http.annotation.RequestProcessing; -import org.b3log.latke.http.annotation.RequestProcessor; +import org.b3log.latke.ioc.BeanManager; import org.b3log.latke.ioc.Inject; +import org.b3log.latke.ioc.Singleton; import org.b3log.latke.service.LangPropsService; import org.b3log.latke.util.Strings; import org.b3log.latke.util.URLs; @@ -47,6 +49,8 @@ import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.OutputStream; +import java.net.InetAddress; +import java.net.URL; import java.nio.file.Path; import java.nio.file.Paths; import java.util.*; @@ -60,10 +64,10 @@ * * @author Liang Ding * @author Liyuan Li - * @version 2.0.1.8, Nov 5, 2019 + * @version 3.0.0.0, Feb 11, 2020 * @since 1.4.0 */ -@RequestProcessor +@Singleton public class FileUploadProcessor { /** @@ -77,12 +81,23 @@ public class FileUploadProcessor { @Inject private LangPropsService langPropsService; + /** + * Register request handlers. + */ + public static void register() { + final BeanManager beanManager = BeanManager.getInstance(); + + final FileUploadProcessor fileUploadProcessor = beanManager.getReference(FileUploadProcessor.class); + Dispatcher.get("/upload/{yyyy}/{MM}/{file}", fileUploadProcessor::getFile); + Dispatcher.post("/upload", fileUploadProcessor::uploadFile); + Dispatcher.post("/fetch-upload", fileUploadProcessor::fetchUpload); + } + /** * Gets file by the specified URL. * * @param context the specified context */ - @RequestProcessing(value = "/upload/{yyyy}/{MM}/{file}", method = HttpMethod.GET) public void getFile(final RequestContext context) { if (QN_ENABLED) { return; @@ -138,7 +153,6 @@ public void getFile(final RequestContext context) { * * @param context the specified context */ - @RequestProcessing(value = "/upload", method = HttpMethod.POST) public void uploadFile(final RequestContext context) { final JSONObject result = Results.newFail(); context.renderJSONPretty(result); @@ -257,6 +271,89 @@ public void uploadFile(final RequestContext context) { result.put(Keys.MSG, ""); } + /** + * Fetches the remote file and upload it. + * + * @param context the specified context + */ + public void fetchUpload(final RequestContext context) { + final JSONObject result = Results.newFail(); + context.renderJSONPretty(result); + final JSONObject data = new JSONObject(); + + final JSONObject requestJSONObject = context.requestJSON(); + final String originalURL = requestJSONObject.optString(Common.URL); + if (!Strings.isURL(originalURL) || !StringUtils.startsWithIgnoreCase(originalURL, "http")) { + return; + } + + byte[] bytes; + String contentType; + try { + final String host = new URL(originalURL).getHost(); + final String hostIp = InetAddress.getByName(host).getHostAddress(); + if (Networks.isInnerAddress(hostIp)) { + return; + } + + final HttpRequest req = HttpRequest.get(originalURL).header(Common.USER_AGENT, Symphonys.USER_AGENT_BOT); + final HttpResponse res = req.connectionTimeout(3000).timeout(5000).send(); + res.close(); + if (200 != res.statusCode()) { + return; + } + + bytes = res.bodyBytes(); + contentType = res.contentType(); + } catch (final Exception e) { + LOGGER.log(Level.ERROR, "Fetch file [url=" + originalURL + "] failed", e); + + return; + } + + final String suffix = Headers.getSuffix(contentType); + final String[] allowedSuffixArray = Symphonys.UPLOAD_SUFFIX.split(","); + if (!Strings.containsIgnoreCase(suffix, allowedSuffixArray)) { + String msg = langPropsService.get("invalidFileSuffixLabel"); + msg = StringUtils.replace(msg, "${suffix}", suffix); + result.put(Keys.MSG, msg); + + return; + } + + String fileName = UUID.randomUUID().toString().replace("-", "") + "." + suffix; + + if (Symphonys.QN_ENABLED) { + final Auth auth = Auth.create(Symphonys.UPLOAD_QINIU_AK, Symphonys.UPLOAD_QINIU_SK); + final UploadManager uploadManager = new UploadManager(new Configuration()); + + try { + uploadManager.put(bytes, "e/" + fileName, auth.uploadToken(Symphonys.UPLOAD_QINIU_BUCKET), null, contentType, false); + } catch (final Exception e) { + LOGGER.log(Level.ERROR, "Uploads to Qiniu failed", e); + } + + data.put(Common.URL, Symphonys.UPLOAD_QINIU_DOMAIN + "/e/" + fileName); + data.put("originalURL", originalURL); + } else { + fileName = FileUploadProcessor.genFilePath(fileName); + final Path path = Paths.get(Symphonys.UPLOAD_LOCAL_DIR, fileName); + path.getParent().toFile().mkdirs(); + try (final OutputStream output = new FileOutputStream(Symphonys.UPLOAD_LOCAL_DIR + fileName)) { + IOUtils.write(bytes, output); + } catch (final Exception e) { + LOGGER.log(Level.ERROR, "Writes output stream failed", e); + } + + data.put(Common.URL, Latkes.getServePath() + "/upload/" + fileName); + data.put("originalURL", originalURL); + } + + result.put(Common.DATA, data); + result.put(Keys.CODE, StatusCodes.SUCC); + result.put(Keys.MSG, ""); + } + /** * Generates upload file path for the specified file name. *