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.
- *
- *
- * - Fetches the remote file and upload it (/fetch-upload), POST
- *
- *
- *
- * @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.
*