package org.sina.android.http;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.SocketTimeoutException;
import java.net.URI;
import java.net.URL;
import java.net.URLDecoder;
import java.net.UnknownHostException;
import java.security.KeyStore;
import org.aisen.weibo.sina.support.utils.AppSettings;
import org.apache.commons.httpclient.methods.PostMethod;
import org.apache.commons.httpclient.methods.multipart.FilePart;
import org.apache.commons.httpclient.methods.multipart.MultipartRequestEntity;
import org.apache.commons.httpclient.methods.multipart.Part;
import org.apache.commons.httpclient.methods.multipart.StringPart;
import org.apache.commons.httpclient.params.HttpMethodParams;
import org.apache.http.HttpEntity;
import org.apache.http.HttpHost;
import org.apache.http.HttpResponse;
import org.apache.http.HttpVersion;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.methods.HttpUriRequest;
import org.apache.http.conn.ConnectTimeoutException;
import org.apache.http.conn.params.ConnRouteParams;
import org.apache.http.conn.scheme.PlainSocketFactory;
import org.apache.http.conn.scheme.Scheme;
import org.apache.http.conn.scheme.SchemeRegistry;
import org.apache.http.conn.ssl.SSLSocketFactory;
import org.apache.http.entity.ByteArrayEntity;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.impl.conn.SingleClientConnManager;
import org.apache.http.params.BasicHttpParams;
import org.apache.http.params.HttpConnectionParams;
import org.apache.http.params.HttpParams;
import org.apache.http.params.HttpProtocolParams;
import org.apache.http.protocol.HTTP;
import org.sina.android.core.SinaErrorMsgUtil;
import android.text.TextUtils;
import com.alibaba.fastjson.JSON;
import com.m.common.params.Params;
import com.m.common.params.ParamsUtil;
import com.m.common.settings.Setting;
import com.m.common.utils.Logger;
import com.m.common.utils.SystemUtility;
import com.m.common.utils.SystemUtility.NetWorkType;
import com.m.support.bizlogic.ABaseBizlogic;
import com.m.support.network.HttpConfig;
import com.m.support.network.HttpUtility;
import com.m.support.task.TaskException;
public class HttpsUtility implements HttpUtility {
private static final int connectTimeout = 8 * 1000;
private static final int soTimeout = 8 * 1000;
protected HttpClient getHttpsClient() throws TaskException {
BasicHttpParams httpParameters = new BasicHttpParams();
HttpConnectionParams.setConnectionTimeout(httpParameters, connectTimeout);
HttpConnectionParams.setSoTimeout(httpParameters, soTimeout);
HttpClient client = null;
try {
KeyStore keyStore = KeyStore.getInstance(KeyStore.getDefaultType());
keyStore.load(null, null);
// 如果不设置这里,会报no peer certificate错误
SSLSocketFactory sf = new MSSLSocketFactory(keyStore);
sf.setHostnameVerifier(SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);
SchemeRegistry schemeRegistry = new SchemeRegistry();
schemeRegistry.register(new Scheme("https", sf, 443));
schemeRegistry.register(new Scheme("http", PlainSocketFactory.getSocketFactory(), 80));
HttpParams params = new BasicHttpParams();
HttpProtocolParams.setVersion(params, HttpVersion.HTTP_1_1);
HttpProtocolParams.setContentCharset(params, HTTP.UTF_8);
SingleClientConnManager clientManager = new SingleClientConnManager(params, schemeRegistry);
client = new DefaultHttpClient(clientManager, httpParameters);
} catch (Exception e) {
e.printStackTrace();
throw new TaskException(TaskException.TaskError.timeout.toString());
}
HttpHost proxy = SystemUtility.getProxy();
if (proxy != null)
client.getParams().setParameter(ConnRouteParams.DEFAULT_PROXY, proxy);
return client;
}
@Override
public <T> T doGet(HttpConfig config, Setting action, Params params, Class<T> responseCls) throws TaskException {
// 是否有网络连接
if (SystemUtility.getNetworkType() == NetWorkType.none)
throw new TaskException(TaskException.TaskError.noneNetwork.toString());
String url = config.baseUrl + action.getValue();
if (params != null && params.getVaules().size() > 0) {
url += "?";
url += ParamsUtil.encodeToURLParams(params);
}
Logger.i(ABaseBizlogic.TAG, String.format("url ---> %s", url));
HttpGet httpGet = null;
URL uRL = null;
try {
uRL = new URL(url);
URI uri = new URI(uRL.getProtocol(), uRL.getHost(), uRL.getPath(), uRL.getQuery(), null);
httpGet = new HttpGet(uri);
} catch (Exception e) {
e.printStackTrace();
httpGet = new HttpGet(url);
}
configHttpHeader(httpGet, config);
return executeClient(httpGet, responseCls);
}
@Override
public <T> T doPost(HttpConfig config, Setting action, Params params, Class<T> responseCls, Object requestObj) throws TaskException {
// 是否有网络连接
if (SystemUtility.getNetworkType() == NetWorkType.none)
throw new TaskException(TaskException.TaskError.noneNetwork.toString());
String url = config.baseUrl + action.getValue();
Logger.i(ABaseBizlogic.TAG, String.format("url ---> %s", url));
HttpPost httpPost = new HttpPost(url);
String postStringEntity = null;
if (requestObj != null) {
if (requestObj instanceof Params)
postStringEntity = encodeNetParamsByContentType((Params) requestObj, config.contentType);
else
postStringEntity = JSON.toJSONString(postStringEntity);
}
else if (params != null && params.size() != 0) {
postStringEntity = encodeNetParamsByContentType(params, config.contentType);
}
Logger.d(ABaseBizlogic.TAG, String.format("post entity --->%s", postStringEntity));
ByteArrayEntity entity;
try {
entity = new ByteArrayEntity(postStringEntity.getBytes());
httpPost.setEntity(entity);
} catch (Exception e) {
e.printStackTrace();
throw new TaskException(TaskException.TaskError.resultIllegal.toString());
}
configHttpHeader(httpPost, config);
return executeClient(httpPost, responseCls);
}
public <T> T uploadFile(HttpConfig config, Setting action, Params params, File file, Params headers, Class<T> responseClazz) throws TaskException {
try {
PostMethod postMethod = new PostMethod((config.baseUrl + action.getValue()));
FilePart fp = null;
try {
fp = new FilePart("pic", file.getName(), file);
} catch (FileNotFoundException e) {
e.printStackTrace();
}
postMethod.addRequestHeader("Authorization", config.authrization);
int index = 0;
Part[] part = new Part[params.size() + 1];
for (String key : params.getKeys())
part[index++] = new StringPart(key, ParamsUtil.encode(params.getParameter(key)));
part[index] = fp;
MultipartRequestEntity mrp = new MultipartRequestEntity(part, postMethod.getParams());
postMethod.setRequestEntity(mrp);
if (headers != null)
for (String key : headers.getKeys())
postMethod.addRequestHeader(key, ParamsUtil.encode(headers.getParameter(key)));
// 执行postMethod
org.apache.commons.httpclient.HttpClient httpClient = new org.apache.commons.httpclient.HttpClient();
httpClient.getHttpConnectionManager().getParams().setConnectionTimeout(connectTimeout);
postMethod.getParams().setParameter(HttpMethodParams.SO_TIMEOUT, soTimeout);
postMethod.getParams().setParameter(HttpMethodParams.HTTP_CONTENT_CHARSET, "utf-8");
httpClient.executeMethod(postMethod);
Logger.v(ABaseBizlogic.TAG, String.format("upload file's response body = %s", postMethod.getResponseBodyAsString()));
T result = null;
try {
result = JSON.parseObject(postMethod.getResponseBodyAsString(), responseClazz);
} catch (Exception e) {
e.printStackTrace();
throw new TaskException(TaskException.TaskError.timeout.toString());
}
return result;
} catch (SocketTimeoutException e) {
e.printStackTrace();
throw new TaskException(TaskException.TaskError.timeout.toString());
} catch (ConnectTimeoutException e) {
e.printStackTrace();
throw new TaskException(TaskException.TaskError.timeout.toString());
} catch (ClientProtocolException e) {
e.printStackTrace();
throw new TaskException(TaskException.TaskError.timeout.toString());
} catch (UnknownHostException e) {
e.printStackTrace();
throw new TaskException(TaskException.TaskError.timeout.toString());
} catch (IOException e) {
e.printStackTrace();
throw new TaskException(TaskException.TaskError.timeout.toString());
}
}
@SuppressWarnings("deprecation")
private <T> T executeClient(HttpUriRequest request, Class<T> responseCls) throws TaskException {
if (AppSettings.isNetworkDelay()) {
try {
Thread.sleep(10 * 1000);
} catch (Exception e) {
}
}
try {
HttpResponse httpResponse = getHttpsClient().execute(request);
String responseStr = readResponse(httpResponse);
if (!TextUtils.isEmpty(responseStr) && AppSettings.isTraditional()) {
// 太耗时,取消这里的统一转换
// long time = System.currentTimeMillis();
// int length = responseStr.length();
// ZHConverter converter = ZHConverter.getInstance(ZHConverter.TRADITIONAL);
// responseStr = converter.convert(responseStr);
// Logger.w(String.format("文字长度%s,简繁体转换耗时%sms", String.valueOf(length), String.valueOf(System.currentTimeMillis() - time)));
}
if (httpResponse.getStatusLine().getStatusCode() / 100 == 2) {
T result = null;
try {
result = JSON.parseObject(responseStr, responseCls);
} catch (Exception e) {
e.printStackTrace();
throw new TaskException(TaskException.TaskError.timeout.toString());
}
return result;
} else {
responseStr = URLDecoder.decode(responseStr);
throw SinaErrorMsgUtil.transToException(responseStr);
}
} catch (SocketTimeoutException e) {
e.printStackTrace();
throw new TaskException(TaskException.TaskError.timeout.toString());
} catch (ConnectTimeoutException e) {
e.printStackTrace();
throw new TaskException(TaskException.TaskError.timeout.toString());
} catch (ClientProtocolException e) {
e.printStackTrace();
throw new TaskException(TaskException.TaskError.timeout.toString());
} catch (UnknownHostException e) {
e.printStackTrace();
throw new TaskException(TaskException.TaskError.timeout.toString());
} catch (IOException e) {
e.printStackTrace();
throw new TaskException(TaskException.TaskError.timeout.toString());
}
}
@SuppressWarnings("unused")
private HttpClient getHttpClient() {
BasicHttpParams httpParameters = new BasicHttpParams();
HttpConnectionParams.setConnectionTimeout(httpParameters, connectTimeout);
HttpConnectionParams.setSoTimeout(httpParameters, soTimeout);
HttpClient client = new DefaultHttpClient(httpParameters);
HttpHost proxy = SystemUtility.getProxy();
if (proxy != null)
client.getParams().setParameter(ConnRouteParams.DEFAULT_PROXY, proxy);
return client;
}
private void configHttpHeader(HttpUriRequest request, HttpConfig config) {
if (!TextUtils.isEmpty(config.contentType))
request.setHeader("Content-Type", config.contentType);
if (!TextUtils.isEmpty(config.authrization))
request.setHeader("Authorization", config.authrization);
}
private static String readResponse(HttpResponse response) throws IllegalStateException, IOException {
String result = "";
HttpEntity entity = response.getEntity();
InputStream inputStream;
inputStream = entity.getContent();
ByteArrayOutputStream content = new ByteArrayOutputStream();
int len = 0;
byte[] sBuffer = new byte[256 * 1024];
while ((len = inputStream.read(sBuffer)) != -1) {
content.write(sBuffer, 0, len);
}
result = new String(content.toByteArray());
content.close();
Logger.v(ABaseBizlogic.TAG, result);
return result;
}
/**
* 根据contentType类型组织网络请求参数列表
*
* @param params
* @param contentType
* @return
*/
private static String encodeNetParamsByContentType(Params params, String contentType) {
if ("application/x-www-form-urlencoded".equals(contentType)) {
return ParamsUtil.encodeToURLParams(params);
} else if ("application/json".equals(contentType)) {
return ParamsUtil.encodeParamsToJson(params);
}
return null;
}
/**
* 将上传文件的参数放到post实体中
* <p>
* 发送一个文件,格式详情具体可以参照,在Key与value之间,必须\r\n\r\n,否则system error<br>
* <a href="http://www.w3.org/TR/html401/interact/forms.html#h-17.13.4.1">
* <p>
* <a href="http://yefeng.iteye.com/blog/315847">
* <p>
*
* @param out
* @param params
*/
private static final String boundary = "4a5b6c7d8e9f";
@SuppressWarnings("unused")
private static void parseFileUploadParams(OutputStream out, Params params, byte[] file) throws IOException {
StringBuffer buffer = new StringBuffer();
for (String key : params.getKeys()) {
buffer.append("--").append(boundary);
buffer.append("\r\n");
buffer.append("Content-Disposition: form-data; name=" + "\"" + key + "\"");
buffer.append("\r\n\r\n");// 每一行必须以\r\n结尾,包括最后一行
buffer.append(ParamsUtil.encode(params.getParameter(key)));
buffer.append("\r\n");
}
String imageKey = "pic";
if (params.containsKey("imageKey")) {
imageKey = params.getParameter("imageKey");
}
buffer.append("--" + boundary);
buffer.append("\r\n");
buffer.append("Content-Disposition: form-data; name=").append("\"").append(imageKey).append("\"").append(";").append("filename=")
.append("\"").append("lovesong.jpg").append("\"");
buffer.append("Content-Type: " + "image/jpge");
buffer.append("\r\n\r\n");
out.write(buffer.toString().getBytes());
// Logger.d(TAG, "form-data = " + buffer.toString());
out.write(file);
out.write(("\r\n--" + boundary + "--\r\n").getBytes());
}
}