|
@@ -4,14 +4,18 @@ import java.io.File;
|
|
import java.io.FileInputStream;
|
|
import java.io.FileInputStream;
|
|
import java.io.FileNotFoundException;
|
|
import java.io.FileNotFoundException;
|
|
import java.io.InputStream;
|
|
import java.io.InputStream;
|
|
-import java.io.UnsupportedEncodingException;
|
|
|
|
-import java.security.MessageDigest;
|
|
|
|
|
|
+import java.security.InvalidKeyException;
|
|
import java.security.NoSuchAlgorithmException;
|
|
import java.security.NoSuchAlgorithmException;
|
|
|
|
+import java.security.SignatureException;
|
|
import java.text.SimpleDateFormat;
|
|
import java.text.SimpleDateFormat;
|
|
-import java.util.Date;
|
|
|
|
|
|
+import java.util.Base64;
|
|
|
|
+import java.util.Calendar;
|
|
import java.util.Locale;
|
|
import java.util.Locale;
|
|
import java.util.TimeZone;
|
|
import java.util.TimeZone;
|
|
|
|
|
|
|
|
+import javax.crypto.Mac;
|
|
|
|
+import javax.crypto.spec.SecretKeySpec;
|
|
|
|
+
|
|
import org.apache.commons.compress.utils.IOUtils;
|
|
import org.apache.commons.compress.utils.IOUtils;
|
|
import org.apache.commons.lang3.StringUtils;
|
|
import org.apache.commons.lang3.StringUtils;
|
|
import org.apache.http.HttpStatus;
|
|
import org.apache.http.HttpStatus;
|
|
@@ -25,17 +29,14 @@ import org.apache.http.impl.client.HttpClients;
|
|
import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
|
|
import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
|
|
import org.apache.http.util.EntityUtils;
|
|
import org.apache.http.util.EntityUtils;
|
|
|
|
|
|
-import com.upyun.UpException;
|
|
|
|
-import com.upyun.UpYunUtils;
|
|
|
|
-
|
|
|
|
import cn.com.qmth.examcloud.commons.exception.ExamCloudRuntimeException;
|
|
import cn.com.qmth.examcloud.commons.exception.ExamCloudRuntimeException;
|
|
import cn.com.qmth.examcloud.commons.exception.StatusException;
|
|
import cn.com.qmth.examcloud.commons.exception.StatusException;
|
|
import cn.com.qmth.examcloud.commons.logging.ExamCloudLog;
|
|
import cn.com.qmth.examcloud.commons.logging.ExamCloudLog;
|
|
import cn.com.qmth.examcloud.commons.logging.ExamCloudLogFactory;
|
|
import cn.com.qmth.examcloud.commons.logging.ExamCloudLogFactory;
|
|
-import cn.com.qmth.examcloud.web.bootstrap.PropertyHolder;
|
|
|
|
|
|
+import cn.com.qmth.examcloud.commons.util.MD5;
|
|
|
|
|
|
/**
|
|
/**
|
|
- * upyun SDK定制版
|
|
|
|
|
|
+ * upyun client
|
|
*
|
|
*
|
|
* @author WANGWEI
|
|
* @author WANGWEI
|
|
* @date 2018年11月21日
|
|
* @date 2018年11月21日
|
|
@@ -68,6 +69,8 @@ public class UpYunClient {
|
|
|
|
|
|
private final String METHOD_PUT = "PUT";
|
|
private final String METHOD_PUT = "PUT";
|
|
|
|
|
|
|
|
+ private final String METHOD_DELETE = "DELETE";
|
|
|
|
+
|
|
private final String DATE = "Date";
|
|
private final String DATE = "Date";
|
|
|
|
|
|
private final String AUTHORIZATION = "Authorization";
|
|
private final String AUTHORIZATION = "Authorization";
|
|
@@ -78,12 +81,6 @@ public class UpYunClient {
|
|
|
|
|
|
private RequestConfig requestConfig;
|
|
private RequestConfig requestConfig;
|
|
|
|
|
|
- private String testUrl;
|
|
|
|
-
|
|
|
|
- private String base64Auth = null;
|
|
|
|
-
|
|
|
|
- private boolean unsafe;
|
|
|
|
-
|
|
|
|
private String domain;
|
|
private String domain;
|
|
|
|
|
|
/**
|
|
/**
|
|
@@ -105,13 +102,7 @@ public class UpYunClient {
|
|
this.userName = userName;
|
|
this.userName = userName;
|
|
this.password = password;
|
|
this.password = password;
|
|
this.domain = domain;
|
|
this.domain = domain;
|
|
- this.md5Password = md5(password);
|
|
|
|
-
|
|
|
|
- base64Auth = "Basic " + org.apache.commons.codec.binary.Base64
|
|
|
|
- .encodeBase64String((userName + ":" + password).getBytes());
|
|
|
|
- unsafe = false;
|
|
|
|
-
|
|
|
|
- testUrl = PropertyHolder.getString("$upyun.testUrl");
|
|
|
|
|
|
+ this.md5Password = MD5.encrypt32(password);
|
|
}
|
|
}
|
|
|
|
|
|
/**
|
|
/**
|
|
@@ -146,9 +137,6 @@ public class UpYunClient {
|
|
public UpYunPathInfo writeFile(String filePath, InputStream in) {
|
|
public UpYunPathInfo writeFile(String filePath, InputStream in) {
|
|
String path = formatPath(filePath);
|
|
String path = formatPath(filePath);
|
|
String url = "https://" + API_DOMAIN + path;
|
|
String url = "https://" + API_DOMAIN + path;
|
|
- if (filePath.endsWith(".test")) {
|
|
|
|
- url = testUrl;
|
|
|
|
- }
|
|
|
|
|
|
|
|
HttpPut httpPut = new HttpPut(url);
|
|
HttpPut httpPut = new HttpPut(url);
|
|
httpPut.setConfig(this.requestConfig);
|
|
httpPut.setConfig(this.requestConfig);
|
|
@@ -157,16 +145,10 @@ public class UpYunClient {
|
|
long s = System.currentTimeMillis();
|
|
long s = System.currentTimeMillis();
|
|
try {
|
|
try {
|
|
|
|
|
|
- String date = getGMTDate();
|
|
|
|
|
|
+ String date = getDate();
|
|
|
|
+ String authorization = sign(userName, md5Password, METHOD_PUT, path, date, "", "");
|
|
|
|
+ httpPut.addHeader(AUTHORIZATION, authorization);
|
|
httpPut.addHeader(DATE, date);
|
|
httpPut.addHeader(DATE, date);
|
|
-
|
|
|
|
- if (unsafe) {
|
|
|
|
- httpPut.addHeader(AUTHORIZATION, base64Auth);
|
|
|
|
- } else {
|
|
|
|
- httpPut.addHeader(AUTHORIZATION, UpYunUtils
|
|
|
|
- .sign(METHOD_PUT, date, path, userName, this.md5Password, null).trim());
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
httpPut.addHeader(MKDIR, "true");
|
|
httpPut.addHeader(MKDIR, "true");
|
|
|
|
|
|
httpPut.setEntity(new InputStreamEntity(in));
|
|
httpPut.setEntity(new InputStreamEntity(in));
|
|
@@ -179,8 +161,6 @@ public class UpYunClient {
|
|
}
|
|
}
|
|
} catch (StatusException e) {
|
|
} catch (StatusException e) {
|
|
throw e;
|
|
throw e;
|
|
- } catch (UpException e) {
|
|
|
|
- throw new ExamCloudRuntimeException(e);
|
|
|
|
} catch (Exception e) {
|
|
} catch (Exception e) {
|
|
throw new ExamCloudRuntimeException(e);
|
|
throw new ExamCloudRuntimeException(e);
|
|
} finally {
|
|
} finally {
|
|
@@ -208,9 +188,6 @@ public class UpYunClient {
|
|
public void deleteFile(String filePath) {
|
|
public void deleteFile(String filePath) {
|
|
String path = formatPath(filePath);
|
|
String path = formatPath(filePath);
|
|
String url = "https://" + API_DOMAIN + path;
|
|
String url = "https://" + API_DOMAIN + path;
|
|
- if (filePath.endsWith(".test")) {
|
|
|
|
- url = testUrl;
|
|
|
|
- }
|
|
|
|
|
|
|
|
HttpDelete httpDelete = new HttpDelete(url);
|
|
HttpDelete httpDelete = new HttpDelete(url);
|
|
httpDelete.setConfig(this.requestConfig);
|
|
httpDelete.setConfig(this.requestConfig);
|
|
@@ -218,17 +195,11 @@ public class UpYunClient {
|
|
|
|
|
|
long s = System.currentTimeMillis();
|
|
long s = System.currentTimeMillis();
|
|
try {
|
|
try {
|
|
-
|
|
|
|
- String date = getGMTDate();
|
|
|
|
|
|
+ String date = getDate();
|
|
|
|
+ String authorization = sign(userName, md5Password, METHOD_DELETE, path, date, "", "");
|
|
|
|
+ httpDelete.addHeader(AUTHORIZATION, authorization);
|
|
httpDelete.addHeader(DATE, date);
|
|
httpDelete.addHeader(DATE, date);
|
|
|
|
|
|
- if (unsafe) {
|
|
|
|
- httpDelete.addHeader(AUTHORIZATION, base64Auth);
|
|
|
|
- } else {
|
|
|
|
- httpDelete.addHeader(AUTHORIZATION, UpYunUtils
|
|
|
|
- .sign(METHOD_PUT, date, path, userName, this.md5Password, null).trim());
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
response = httpclient.execute(httpDelete);
|
|
response = httpclient.execute(httpDelete);
|
|
int statusCode = response.getStatusLine().getStatusCode();
|
|
int statusCode = response.getStatusLine().getStatusCode();
|
|
|
|
|
|
@@ -238,8 +209,6 @@ public class UpYunClient {
|
|
}
|
|
}
|
|
} catch (StatusException e) {
|
|
} catch (StatusException e) {
|
|
throw e;
|
|
throw e;
|
|
- } catch (UpException e) {
|
|
|
|
- throw new ExamCloudRuntimeException(e);
|
|
|
|
} catch (Exception e) {
|
|
} catch (Exception e) {
|
|
throw new ExamCloudRuntimeException(e);
|
|
throw new ExamCloudRuntimeException(e);
|
|
} finally {
|
|
} finally {
|
|
@@ -255,7 +224,7 @@ public class UpYunClient {
|
|
}
|
|
}
|
|
|
|
|
|
/**
|
|
/**
|
|
- * 格式化路径参数,去除前后的空格并确保以"/"开头,最后添加"/空间名"
|
|
|
|
|
|
+ * 格式化路径参数
|
|
* <p>
|
|
* <p>
|
|
* 最终构成的格式:"/空间名/文件路径"
|
|
* 最终构成的格式:"/空间名/文件路径"
|
|
*
|
|
*
|
|
@@ -279,50 +248,35 @@ public class UpYunClient {
|
|
return SEPARATOR + bucketName + path;
|
|
return SEPARATOR + bucketName + path;
|
|
}
|
|
}
|
|
|
|
|
|
- /**
|
|
|
|
- * 对字符串进行 MD5 加密
|
|
|
|
- *
|
|
|
|
- * @param str
|
|
|
|
- * 待加密字符串
|
|
|
|
- * @return 加密后字符串
|
|
|
|
- */
|
|
|
|
- private static String md5(String str) {
|
|
|
|
- char hexDigits[] = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd',
|
|
|
|
- 'e', 'f'};
|
|
|
|
- MessageDigest md5 = null;
|
|
|
|
- try {
|
|
|
|
- md5 = MessageDigest.getInstance("MD5");
|
|
|
|
- md5.update(str.getBytes("UTF-8"));
|
|
|
|
- } catch (NoSuchAlgorithmException e) {
|
|
|
|
- e.printStackTrace();
|
|
|
|
- throw new RuntimeException(e.getMessage());
|
|
|
|
- } catch (UnsupportedEncodingException e) {
|
|
|
|
- e.printStackTrace();
|
|
|
|
- throw new RuntimeException(e.getMessage());
|
|
|
|
- }
|
|
|
|
- byte[] encodedValue = md5.digest();
|
|
|
|
- int j = encodedValue.length;
|
|
|
|
- char finalValue[] = new char[j * 2];
|
|
|
|
- int k = 0;
|
|
|
|
- for (int i = 0; i < j; i++) {
|
|
|
|
- byte encoded = encodedValue[i];
|
|
|
|
- finalValue[k++] = hexDigits[encoded >> 4 & 0xf];
|
|
|
|
- finalValue[k++] = hexDigits[encoded & 0xf];
|
|
|
|
- }
|
|
|
|
|
|
+ private String getDate() {
|
|
|
|
+ Calendar calendar = Calendar.getInstance();
|
|
|
|
+ SimpleDateFormat dateFormat = new SimpleDateFormat("EEE, dd MMM yyyy HH:mm:ss z",
|
|
|
|
+ Locale.US);
|
|
|
|
+ dateFormat.setTimeZone(TimeZone.getTimeZone("GMT"));
|
|
|
|
+ return dateFormat.format(calendar.getTime());
|
|
|
|
+ }
|
|
|
|
|
|
- return new String(finalValue);
|
|
|
|
|
|
+ private byte[] hashHmac(String data, String key)
|
|
|
|
+ throws SignatureException, NoSuchAlgorithmException, InvalidKeyException {
|
|
|
|
+ SecretKeySpec signingKey = new SecretKeySpec(key.getBytes(), "HmacSHA1");
|
|
|
|
+ Mac mac = Mac.getInstance("HmacSHA1");
|
|
|
|
+ mac.init(signingKey);
|
|
|
|
+ return mac.doFinal(data.getBytes());
|
|
}
|
|
}
|
|
|
|
|
|
- /**
|
|
|
|
- * 获取 GMT 格式时间戳
|
|
|
|
- *
|
|
|
|
- * @return GMT 格式时间戳
|
|
|
|
- */
|
|
|
|
- private String getGMTDate() {
|
|
|
|
- SimpleDateFormat formater = new SimpleDateFormat("EEE, dd MMM yyyy HH:mm:ss 'GMT'",
|
|
|
|
- Locale.US);
|
|
|
|
- formater.setTimeZone(TimeZone.getTimeZone("GMT"));
|
|
|
|
- return formater.format(new Date());
|
|
|
|
|
|
+ private String sign(String key, String secret, String method, String uri, String date,
|
|
|
|
+ String policy, String md5) throws Exception {
|
|
|
|
+ String value = method + "&" + uri + "&" + date;
|
|
|
|
+ if (policy != null && policy.length() > 0) {
|
|
|
|
+ value = value + "&" + policy;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if (md5 != null && md5.length() > 0) {
|
|
|
|
+ value = value + "&" + md5;
|
|
|
|
+ }
|
|
|
|
+ byte[] hmac = hashHmac(value, secret);
|
|
|
|
+ String sign = Base64.getEncoder().encodeToString(hmac);
|
|
|
|
+ return "UPYUN " + key + ":" + sign;
|
|
}
|
|
}
|
|
|
|
|
|
}
|
|
}
|