package com.itap.voiceemoticon.util;
import com.itap.voiceemoticon.api.util.HttpCaller;
import com.weibo.sdk.android.WeiboParameters;
import com.zenip.weibo.sdk.android.util.Utility;
import org.apache.http.Header;
import org.apache.http.HeaderElement;
import org.apache.http.HeaderElementIterator;
import org.apache.http.HttpEntity;
import org.apache.http.HttpHost;
import org.apache.http.HttpResponse;
import org.apache.http.HttpVersion;
import org.apache.http.StatusLine;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpDelete;
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.ClientConnectionManager;
import org.apache.http.conn.ConnectionKeepAliveStrategy;
import org.apache.http.conn.params.ConnRoutePNames;
import org.apache.http.conn.scheme.LayeredSocketFactory;
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.scheme.SocketFactory;
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.tsccm.ThreadSafeClientConnManager;
import org.apache.http.message.BasicHeaderElementIterator;
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.ExecutionContext;
import org.apache.http.protocol.HTTP;
import org.apache.http.protocol.HttpContext;
import android.text.TextUtils;
import android.util.Log;
import java.io.ByteArrayOutputStream;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.lang.reflect.Field;
import java.net.InetAddress;
import java.net.Socket;
import java.net.URLEncoder;
import java.net.UnknownHostException;
import java.security.KeyManagementException;
import java.security.KeyStore;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.security.UnrecoverableKeyException;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import java.util.HashMap;
import java.util.zip.GZIPInputStream;
import javax.net.ssl.SSLContext;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;
/**
* @author luopeng (luopeng@staff.sina.com.cn)
*/
public class HttpManager {
// private static final String BOUNDARY = "7cd4a6d158c";
private static final String BOUNDARY = getBoundry();
private static final String MP_BOUNDARY = "--" + BOUNDARY;
private static final String END_MP_BOUNDARY = "--" + BOUNDARY + "--";
private static final String MULTIPART_FORM_DATA = "multipart/form-data";
public static final String HTTPMETHOD_POST = "POST";
public static final String HTTPMETHOD_GET = "GET";
private static final int SET_CONNECTION_TIMEOUT = 5 * 1000;
private static final int SET_SOCKET_TIMEOUT = 20 * 1000;
private static ConnectionKeepAliveStrategy sKeeyAliveStrategy = new ConnectionKeepAliveStrategy() {
public long getKeepAliveDuration(HttpResponse response, HttpContext context) {
// Honor 'keep-alive' header
HeaderElementIterator it = new BasicHeaderElementIterator(
response.headerIterator(HTTP.CONN_KEEP_ALIVE));
while (it.hasNext()) {
HeaderElement he = it.nextElement();
String param = he.getName();
String value = he.getValue();
if (value != null && "timeout".equalsIgnoreCase(param)) {
try {
return Long.parseLong(value) * 1000;
} catch (NumberFormatException ignore) {
}
}
}
HttpHost target = (HttpHost)context.getAttribute(ExecutionContext.HTTP_TARGET_HOST);
if ("www.naughty-server.com".equalsIgnoreCase(target.getHostName())) {
// Keep alive for 5 seconds only
return 5 * 1000;
} else {
// otherwise keep alive for 30 seconds
return 30 * 1000;
}
}
};
/**
* @param url 服务器地址
* @param method "GET"or “POST”
* @param params 存放参数的容器
* @param filePath 文件路径,如果 是发送带有照片的微博的话,此参数为图片在sdcard里的绝对路径
* @return 响应结果
* @throws Exception
*/
public static String openUrl(String url, String method, HashMap<String, String> params,
String filePath, String fileName) throws Exception {
String result = "";
try {
HttpClient client = getNewHttpClient();
HttpUriRequest request = null;
ByteArrayOutputStream bos = null;
client.getParams()
.setParameter(ConnRoutePNames.DEFAULT_PROXY, NetStateManager.getAPN());
if (method.equals(HTTPMETHOD_GET)) {
url = url + "?" + encodeUrl(params);
HttpGet get = new HttpGet(url);
request = get;
} else if (method.equals(HTTPMETHOD_POST)) {
HttpPost post = new HttpPost(url);
request = post;
byte[] data = null;
String _contentType = params.get("content-type");
bos = new ByteArrayOutputStream();
if (!TextUtils.isEmpty(filePath)) {
paramToUpload(bos, params);
post.setHeader("Content-Type", MULTIPART_FORM_DATA + "; boundary=" + BOUNDARY);
// Utility.UploadImageUtils.revitionPostImageSize(file);
// imageContentToUpload(bos, file);
audioContentToUpload(bos, filePath, fileName);
} else {
if (_contentType != null) {
params.remove("content-type");
post.setHeader("Content-Type", _contentType);
} else {
post.setHeader("Content-Type", "application/x-www-form-urlencoded");
}
String postParam = encodeParameters(params);
data = postParam.getBytes("UTF-8");
bos.write(data);
}
data = bos.toByteArray();
bos.close();
ByteArrayEntity formEntity = new ByteArrayEntity(data);
post.setEntity(formEntity);
} else if (method.equals("DELETE")) {
request = new HttpDelete(url);
}
HttpResponse response = client.execute(request);
StatusLine status = response.getStatusLine();
int statusCode = status.getStatusCode();
result = readHttpResponse(response);
System.out.println("result = " + result);
return result;
} catch (IOException e) {
throw new Exception(e);
}
}
public static String encodeParameters(HashMap<String, String> httpParams) {
if (null == httpParams) {
return "";
}
StringBuilder buf = new StringBuilder();
int j = 0;
for (String key : httpParams.keySet()) {
if (j != 0) {
buf.append("&");
}
try {
buf.append(URLEncoder.encode(key, "UTF-8")).append("=")
.append(URLEncoder.encode(httpParams.get(key), "UTF-8"));
} catch (java.io.UnsupportedEncodingException neverHappen) {
}
j++;
}
return buf.toString();
}
private static HttpClient getNewHttpClient() {
try {
KeyStore trustStore = KeyStore.getInstance(KeyStore.getDefaultType());
trustStore.load(null, null);
SSLSocketFactory sf = new MySSLSocketFactory(trustStore);
sf.setHostnameVerifier(SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);
HttpParams params = new BasicHttpParams();
HttpConnectionParams.setConnectionTimeout(params, 10000);
HttpConnectionParams.setSoTimeout(params, 10000);
HttpProtocolParams.setVersion(params, HttpVersion.HTTP_1_1);
HttpProtocolParams.setContentCharset(params, HTTP.UTF_8);
SchemeRegistry registry = new SchemeRegistry();
registry.register(new Scheme("http", PlainSocketFactory.getSocketFactory(), 80));
registry.register(new Scheme("https", sf, 443));
ClientConnectionManager ccm = new ThreadSafeClientConnManager(params, registry);
HttpConnectionParams.setConnectionTimeout(params, SET_CONNECTION_TIMEOUT);
HttpConnectionParams.setSoTimeout(params, SET_SOCKET_TIMEOUT);
DefaultHttpClient client = new DefaultHttpClient(ccm, params);
client.setKeepAliveStrategy(sKeeyAliveStrategy);
// workAroundReverseDnsBugInHoneycombAndEarlier(client);
// if (NetState.Mobile == NetStateManager.CUR_NETSTATE) {
// // 获取当前正在使用的APN接入点
// HttpHost proxy = NetStateManager.getAPN();
// if (null != proxy) {
// client.getParams().setParameter(ConnRouteParams.DEFAULT_PROXY,
// proxy);
// }
// }
return client;
} catch (Exception e) {
return new DefaultHttpClient();
}
}
private static void workAroundReverseDnsBugInHoneycombAndEarlier(HttpClient client) {
// Android had a bug where HTTPS made reverse DNS lookups (fixed in Ice
// Cream Sandwich)
// http://code.google.com/p/android/issues/detail?id=13117
SocketFactory socketFactory = new LayeredSocketFactory() {
SSLSocketFactory delegate = SSLSocketFactory.getSocketFactory();
@Override
public Socket createSocket() throws IOException {
return delegate.createSocket();
}
@Override
public Socket connectSocket(Socket sock, String host, int port,
InetAddress localAddress, int localPort, HttpParams params) throws IOException {
return delegate.connectSocket(sock, host, port, localAddress, localPort, params);
}
@Override
public boolean isSecure(Socket sock) throws IllegalArgumentException {
return delegate.isSecure(sock);
}
@Override
public Socket createSocket(Socket socket, String host, int port, boolean autoClose)
throws IOException {
injectHostname(socket, host);
return delegate.createSocket(socket, host, port, autoClose);
}
private void injectHostname(Socket socket, String host) {
try {
Field field = InetAddress.class.getDeclaredField("hostName");
field.setAccessible(true);
field.set(socket.getInetAddress(), host);
} catch (Exception ignored) {
}
}
};
client.getConnectionManager().getSchemeRegistry()
.register(new Scheme("https", socketFactory, 443));
}
private static class MySSLSocketFactory extends SSLSocketFactory {
SSLContext sslContext = SSLContext.getInstance("TLS");
public MySSLSocketFactory(KeyStore truststore) throws NoSuchAlgorithmException,
KeyManagementException, KeyStoreException, UnrecoverableKeyException {
super(truststore);
TrustManager tm = new X509TrustManager() {
public void checkClientTrusted(X509Certificate[] chain, String authType)
throws CertificateException {
}
public void checkServerTrusted(X509Certificate[] chain, String authType)
throws CertificateException {
}
public X509Certificate[] getAcceptedIssuers() {
return null;
}
};
sslContext.init(null, new TrustManager[] {
tm
}, null);
}
@Override
public Socket createSocket(Socket socket, String host, int port, boolean autoClose)
throws IOException, UnknownHostException {
injectHostname(socket, host);
return sslContext.getSocketFactory().createSocket(socket, host, port, autoClose);
}
@Override
public Socket createSocket() throws IOException {
return sslContext.getSocketFactory().createSocket();
}
private void injectHostname(Socket socket, String host) {
try {
Field field = InetAddress.class.getDeclaredField("hostName");
field.setAccessible(true);
field.set(socket.getInetAddress(), host);
} catch (Exception ignored) {
}
}
}
private static void paramToUpload(OutputStream baos, HashMap<String, String> params)
throws Exception {
for (String key : params.keySet()) {
StringBuilder temp = new StringBuilder(10);
temp.setLength(0);
temp.append(MP_BOUNDARY).append("\r\n");
temp.append("content-disposition: form-data; name=\"").append(key).append("\"\r\n\r\n");
temp.append(params.get(key)).append("\r\n");
byte[] res = temp.toString().getBytes();
try {
baos.write(res);
} catch (IOException e) {
throw new Exception(e);
}
}
}
private static void audioContentToUpload(OutputStream out, String filePath, String fileName) throws Exception {
if (filePath == null) {
return;
}
StringBuilder temp = new StringBuilder();
temp.append(MP_BOUNDARY).append("\r\n");
temp.append("Content-Disposition: form-data; name=\"file\"; filename=\"")
.append(fileName).append("\"\r\n");
String filetype = "audio/3gp";
temp.append("Content-Type: ").append(filetype).append("\r\n\r\n");
byte[] res = temp.toString().getBytes();
FileInputStream input = null;
try {
out.write(res);
input = new FileInputStream(filePath);
byte[] buffer = new byte[1024 * 50];
while (true) {
int count = input.read(buffer);
if (count == -1) {
break;
}
out.write(buffer, 0, count);
}
out.write("\r\n".getBytes());
out.write(("\r\n" + END_MP_BOUNDARY).getBytes());
} catch (IOException e) {
throw new Exception(e);
} finally {
if (null != input) {
try {
input.close();
} catch (IOException e) {
throw new Exception(e);
}
}
}
}
private static void imageContentToUpload(OutputStream out, String imgpath) throws Exception {
if (imgpath == null) {
return;
}
StringBuilder temp = new StringBuilder();
temp.append(MP_BOUNDARY).append("\r\n");
temp.append("Content-Disposition: form-data; name=\"pic\"; filename=\"")
.append("news_image").append("\"\r\n");
String filetype = "image/png";
temp.append("Content-Type: ").append(filetype).append("\r\n\r\n");
byte[] res = temp.toString().getBytes();
FileInputStream input = null;
try {
out.write(res);
input = new FileInputStream(imgpath);
byte[] buffer = new byte[1024 * 50];
while (true) {
int count = input.read(buffer);
if (count == -1) {
break;
}
out.write(buffer, 0, count);
}
out.write("\r\n".getBytes());
out.write(("\r\n" + END_MP_BOUNDARY).getBytes());
} catch (IOException e) {
throw new Exception(e);
} finally {
if (null != input) {
try {
input.close();
} catch (IOException e) {
throw new Exception(e);
}
}
}
}
/**
* 读取HttpResponse数据
*
* @param response
* @return
*/
private static String readHttpResponse(HttpResponse response) {
String result = "";
HttpEntity entity = response.getEntity();
InputStream inputStream;
try {
inputStream = entity.getContent();
// ByteArrayOutputStream content = new ByteArrayOutputStream();
//
// Header header = response.getFirstHeader("Content-Encoding");
// if (header != null && header.getValue().toLowerCase().indexOf("gzip") > -1) {
// inputStream = new GZIPInputStream(inputStream);
// }
return HttpCaller.convertStreamToString(inputStream);
} catch (IllegalStateException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return result;
}
/**
* 产生11位的boundary
*/
static String getBoundry() {
StringBuffer _sb = new StringBuffer();
for (int t = 1; t < 12; t++) {
long time = System.currentTimeMillis() + t;
if (time % 3 == 0) {
_sb.append((char)time % 9);
} else if (time % 3 == 1) {
_sb.append((char)(65 + time % 26));
} else {
_sb.append((char)(97 + time % 26));
}
}
return _sb.toString();
}
public static String encodeUrl(HashMap<String, String> parameters) {
if (parameters == null) {
return "";
}
StringBuilder sb = new StringBuilder();
boolean first = true;
for (String key : parameters.keySet()) {
if (first) {
first = false;
} else {
sb.append("&");
}
String value = parameters.get(key);
if (value == null) {
Log.i("encodeUrl", "key:" + key + " 's value is null");
} else {
sb.append(URLEncoder.encode(key) + "=" + URLEncoder.encode(value));
}
}
return sb.toString();
}
}