com.ksyun.ks3.http.Ks3CoreController Maven / Gradle / Ivy
package com.ksyun.ks3.http;
import com.ksyun.ks3.MD5DigestCalculatingInputStream;
import com.ksyun.ks3.dto.Authorization;
import com.ksyun.ks3.exception.Ks3ClientException;
import com.ksyun.ks3.exception.Ks3ServiceException;
import com.ksyun.ks3.exception.client.CallRemoteFailException;
import com.ksyun.ks3.exception.client.ClientIllegalArgumentException;
import com.ksyun.ks3.exception.client.ClientInvalidDigestException;
import com.ksyun.ks3.service.Ks3ClientConfig;
import com.ksyun.ks3.service.request.Ks3WebServiceRequest;
import com.ksyun.ks3.service.response.Ks3WebServiceResponse;
import com.ksyun.ks3.utils.Base64;
import com.ksyun.ks3.utils.Converter;
import com.ksyun.ks3.utils.StringUtils;
import com.ksyun.ks3.utils.Timer;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.http.Header;
import org.apache.http.HttpEntity;
import org.apache.http.HttpRequest;
import org.apache.http.HttpResponse;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.HttpClient;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.methods.HttpPut;
import org.apache.http.client.methods.HttpRequestBase;
import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.Field;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.HashMap;
import java.util.Map;
/**
* @author lijunwei[[email protected]]
*
* @date 2014年10月14日 下午6:59:38
*
* @description ks3 sdk Ks3WebServiceRequest执行,K3WebServiceResponse解析核心控制器
**/
public class Ks3CoreController {
private static final Log log = LogFactory.getLog(Ks3CoreController.class);
private HttpClientFactory factory = new HttpClientFactory();
private HttpClient client = null;
public , Y> Y execute(
Ks3WebServiceRequest request, Class clazz) {
return execute(new Ks3ClientConfig(), null, request, clazz);
}
public , Y> Y execute(
Authorization auth, Ks3WebServiceRequest request, Class clazz) {
return execute(new Ks3ClientConfig(), auth, request, clazz);
}
public , Y> Y execute(
Ks3ClientConfig ks3config, Authorization auth,
Ks3WebServiceRequest request, Class clazz) {
if (request == null)
throw new Ks3ClientException("request can not be null");
log.debug("Ks3WebServiceRequest:" + request.getClass()
+ ";Ks3WebServiceResponse:" + clazz);
if (ks3config == null)
ks3config = new Ks3ClientConfig();
if (client == null)
client = factory.createHttpClient(ks3config.getHttpClientConfig());
Y result = null;
try {
if (!ks3config.isAllowAnonymous()) {
if (auth == null || StringUtils.isBlank(auth.getAccessKeyId())
|| StringUtils.isBlank(auth.getAccessKeySecret()))
throw new Ks3ClientException(
"AccessKeyId or AccessKeySecret can't be null");
}
if (request == null || clazz == null)
throw new IllegalArgumentException();
result = doExecute(ks3config, auth, request, clazz);
return result;
} catch (RuntimeException e) {
if (e instanceof Ks3ClientException) {
} else {
if (e instanceof IllegalArgumentException) {
ClientIllegalArgumentException ce = new ClientIllegalArgumentException(
e.getMessage());
ce.setStackTrace(e.getStackTrace());
e = ce;
} else
e = new Ks3ClientException(e);
}
log.warn(e);
throw e;
} finally {
request.onFinally();
}
}
private , Y> Y doExecute(
Ks3ClientConfig ks3config, Authorization auth,
Ks3WebServiceRequest request, Class clazz) {
Timer.start();
HttpResponse response = null;
Request req = new Request();
RequestBuilder.buildRequest(request, req, auth, ks3config);
HttpRequestBase httpRequest = RequestBuilder.buildHttpRequest(request,
req, auth, ks3config);
//==解决httpclient4.5.7以后版本会重新编解码uri造成签名失败的问题(exclude:4.5.7,未开放相关接口)
if (httpRequest.getConfig() == null) {
try {
Field defaultConfig = client.getClass().getDeclaredField("defaultConfig");
if (defaultConfig != null) {
defaultConfig.setAccessible(true);
/*Method m=client.getClass().getDeclaredMethod("getConfig");
m.setAccessible(true);*/
RequestConfig reConfig = (RequestConfig) defaultConfig.get(client);
if (reConfig != null) {
httpRequest.setConfig(reConfig);
}
}
} catch (Exception e) {
}
}
//===END
Ks3WebServiceResponse ksResponse = null;
try {
ksResponse = clazz.newInstance();
} catch (InstantiationException e) {
// 正常情况不会抛出
throw new Ks3ClientException("to instantiate " + clazz
+ " has occured an exception:(" + e + ")", e);
} catch (IllegalAccessException e) {
// 正常情况不会抛出
throw new Ks3ClientException("to instantiate " + clazz
+ " has occured an exception:(" + e + ")", e);
}
try {
try {
response = this.requestKs3(httpRequest, ks3config);
} catch (Exception e) {
throw new CallRemoteFailException(e);
} finally {
log.debug("finished send request to ks3 service and recive response from the service : "
+ Timer.end());
}
ksResponse.setHttpRequest(httpRequest);
ksResponse.setHttpResponse(response);
if (!success(ksResponse)) {
throw new Ks3ServiceException(response, StringUtils.join(
ksResponse.expectedStatus(), ",")).convert(ksResponse
.getRequestId());
}
Y result = ksResponse.handleResponse();
Map ret = skipMD5Check(response, req);
if (ret.size() == 2) {
log.debug("returned etag is:" + ret.get("ETag"));
if (!ret.get("ETag").equals(Converter.MD52ETag(ret.get("MD5")))) {
throw new ClientInvalidDigestException(
"Unable to verify integrity of data upload. "
+ "Client calculated content hash didn't match hash calculated by KS3. "
+ "You may need to delete the data stored in KS3.");
}
} else {
log.debug("client MD5 check skipped");
}
log.debug("finished handle response : " + Timer.end());
return result;
} catch (RuntimeException e) {
throw e;
} finally {
ksResponse.onFinally();
log.debug("finished execute : " + Timer.end());
}
}
/**
* 查看返回的状态码是否为期望的状态码
*
* @param kscResponse
* {@link HttpResponse}
* @param kscResponse
* {@link Ks3WebServiceResponse}
* @return 是 : true 否:false
*/
private boolean success(Ks3WebServiceResponse> kscResponse) {
int num = kscResponse.expectedStatus().length;
int code = kscResponse.getHttpResponse().getStatusLine()
.getStatusCode();
for (int i = 0; i < num; i++) {
if (code == kscResponse.expectedStatus()[i])
return true;
}
return false;
}
private Map skipMD5Check(HttpResponse rep, Request req) {
Map map = new HashMap();
InputStream content = req.getContent();
if (content == null
|| !(content instanceof MD5DigestCalculatingInputStream))
return map;
String clientmd5 = Base64
.encodeAsString(((MD5DigestCalculatingInputStream) content)
.getMd5Digest());
Header etagHeader = rep.getFirstHeader(HttpHeaders.ETag.toString());
if (etagHeader == null)
return map;
String etag = etagHeader.getValue();
if (StringUtils.isBlank(etag) || StringUtils.isBlank(clientmd5))
return map;
map.put("ETag", etag);
map.put("MD5", clientmd5);
return map;
}
private void restRequest(HttpRequest req) throws IllegalStateException,
IOException {
HttpEntity entity = null;
if (req instanceof HttpPut) {
entity = ((HttpPut) req).getEntity();
} else if (req instanceof HttpPost) {
entity = ((HttpPost) req).getEntity();
}
if (entity != null) {
InputStream input = entity.getContent();
if (input != null) {
if (input.markSupported()) {
input.reset();
input.mark(-1);
}
}
}
}
private HttpResponse requestKs3(HttpRequestBase httpRequest,Ks3ClientConfig ks3config) throws ClientProtocolException, IOException, URISyntaxException{
HttpResponse response = null;
log.info(httpRequest.getRequestLine());
for (Header header : httpRequest.getAllHeaders()) {
log.info("Request Header->" + header.getName() + ":"
+ header.getValue());
}
response = client.execute(httpRequest);
log.info(response.getStatusLine());
for (Header header : response.getAllHeaders()) {
log.info("Response Header->" + header.getName() + ":"
+ header.getValue());
}
if (response.getStatusLine().getStatusCode() >= 300
&& response.getStatusLine().getStatusCode() < 400
&& response.containsHeader("Location")
&& ks3config.isFlowRedirect()) {
String location = response.getHeaders("Location")[0].getValue();
// TODO 这个只是为了兼容当前api
if (location.startsWith("http")) {
closeResponse(response);
log.debug("returned "
+ response.getStatusLine().getStatusCode()
+ ",retry request to " + location);
restRequest(httpRequest);
httpRequest.setURI(new URI(location));
response = client.execute(httpRequest);
log.info(response.getStatusLine());
for (Header header : response.getAllHeaders()) {
log.info("Response Header->" + header.getName() + ":"
+ header.getValue());
}
}
}
return response;
}
private void closeResponse(HttpResponse httpResponse){
try{
if(httpResponse == null)
return;
HttpEntity entity = httpResponse.getEntity();
if(entity != null){
InputStream input = null;
try{
input = entity.getContent();
}catch(IllegalStateException e){
input = null;
}
if(input != null)
input.close();
}
}catch(Exception e){
log.error("close httpRequest error");
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy