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(); } }