172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project/* 272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project * Copyright (C) 2008 Esmertec AG. 372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project * Copyright (C) 2008 The Android Open Source Project 472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project * 572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License"); 672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project * you may not use this file except in compliance with the License. 772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project * You may obtain a copy of the License at 872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project * 972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project * http://www.apache.org/licenses/LICENSE-2.0 1072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project * 1172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project * Unless required by applicable law or agreed to in writing, software 1272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS, 1372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project * See the License for the specific language governing permissions and 1572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project * limitations under the License. 1672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project */ 1772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 1872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectpackage com.android.mms.transaction; 19812391ad832f3fdac054ad3a50af563da16e99b5Wei Huang 2072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport org.apache.http.HttpEntity; 2172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport org.apache.http.HttpHost; 2272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport org.apache.http.HttpRequest; 2372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport org.apache.http.HttpResponse; 2472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport org.apache.http.StatusLine; 2572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport org.apache.http.client.methods.HttpGet; 2672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport org.apache.http.client.methods.HttpPost; 2772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport org.apache.http.conn.params.ConnRouteParams; 2872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport org.apache.http.params.HttpParams; 2972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport org.apache.http.params.HttpProtocolParams; 30293000e15498b71a4986d7247e60fe8bdaa05a4bWei Huangimport org.apache.http.params.HttpConnectionParams; 31dd374f47c61f4fed8e6702c1f9d3f33ac5b77d02Tom Taylorimport org.apache.http.Header; 3272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 3386a1cf79bf92dbb2b9d09431379bff6de83c2581Tom Taylorimport com.android.mms.MmsConfig; 34812391ad832f3fdac054ad3a50af563da16e99b5Wei Huangimport com.android.mms.LogTag; 3586a1cf79bf92dbb2b9d09431379bff6de83c2581Tom Taylor 3672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport android.content.Context; 374d33cdcbb402a87ffeeaddb58237c70c4608c6f5Dianne Hackbornimport android.net.http.AndroidHttpClient; 3889e7af1acc0b62f2822ace8df6d56f4c6d37a40fChristian Gustafssonimport android.telephony.TelephonyManager; 3989e7af1acc0b62f2822ace8df6d56f4c6d37a40fChristian Gustafssonimport android.text.TextUtils; 40dd374f47c61f4fed8e6702c1f9d3f33ac5b77d02Tom Taylorimport android.util.Config; 4172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport android.util.Log; 4272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 43208b7834ee01388a5fecacf00a9c1e1b8ffc5240Matthias Thomaeimport java.io.ByteArrayOutputStream; 44dd374f47c61f4fed8e6702c1f9d3f33ac5b77d02Tom Taylorimport java.io.DataInputStream; 45208b7834ee01388a5fecacf00a9c1e1b8ffc5240Matthias Thomaeimport java.io.InputStream; 4672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport java.io.IOException; 4772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport java.net.SocketException; 4872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport java.net.URI; 4972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport java.net.URISyntaxException; 5072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectimport java.util.Locale; 5172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 5272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Projectpublic class HttpUtils { 53812391ad832f3fdac054ad3a50af563da16e99b5Wei Huang private static final String TAG = LogTag.TRANSACTION; 54812391ad832f3fdac054ad3a50af563da16e99b5Wei Huang 550ecc26df09777835cfa8dbfd3c48ca7b7fa7f011Tom Taylor private static final boolean DEBUG = false; 560ecc26df09777835cfa8dbfd3c48ca7b7fa7f011Tom Taylor private static final boolean LOCAL_LOGV = DEBUG ? Config.LOGD : Config.LOGV; 570ecc26df09777835cfa8dbfd3c48ca7b7fa7f011Tom Taylor 5872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project public static final int HTTP_POST_METHOD = 1; 5972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project public static final int HTTP_GET_METHOD = 2; 6072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 61208b7834ee01388a5fecacf00a9c1e1b8ffc5240Matthias Thomae private static final int MMS_READ_BUFFER = 4096; 62208b7834ee01388a5fecacf00a9c1e1b8ffc5240Matthias Thomae 6372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project // This is the value to use for the "Accept-Language" header. 6472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project // Once it becomes possible for the user to change the locale 6572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project // setting, this should no longer be static. We should call 6672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project // getHttpAcceptLanguage instead. 6772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project private static final String HDR_VALUE_ACCEPT_LANGUAGE; 6872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 6972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project static { 70c122ca5ebd2ccac240002425a567718a9577568cTom Taylor HDR_VALUE_ACCEPT_LANGUAGE = getCurrentAcceptLanguage(Locale.getDefault()); 7172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 7272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 7372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project // Definition for necessary HTTP headers. 7472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project private static final String HDR_KEY_ACCEPT = "Accept"; 7572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project private static final String HDR_KEY_ACCEPT_LANGUAGE = "Accept-Language"; 7672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 7772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project private static final String HDR_VALUE_ACCEPT = 7872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project "*/*, application/vnd.wap.mms-message, application/vnd.wap.sic"; 7972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 8072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project private HttpUtils() { 8172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project // To forbidden instantiate this class. 8272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 8372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 8472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project /** 8572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project * A helper method to send or retrieve data through HTTP protocol. 8672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project * 8772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project * @param token The token to identify the sending progress. 8872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project * @param url The URL used in a GET request. Null when the method is 8972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project * HTTP_POST_METHOD. 9072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project * @param pdu The data to be POST. Null when the method is HTTP_GET_METHOD. 9172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project * @param method HTTP_POST_METHOD or HTTP_GET_METHOD. 9272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project * @return A byte array which contains the response data. 9372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project * If an HTTP error code is returned, an IOException will be thrown. 9472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project * @throws IOException if any error occurred on network interface or 9572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project * an HTTP error code(>=400) returned from the server. 9672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project */ 9772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project protected static byte[] httpConnection(Context context, long token, 9872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project String url, byte[] pdu, int method, boolean isProxySet, 9972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project String proxyHost, int proxyPort) throws IOException { 10072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project if (url == null) { 10172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project throw new IllegalArgumentException("URL must not be null."); 10272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 10372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 104472cecc82e384f0c81d2a7885ade3db702213d82Tom Taylor if (Log.isLoggable(LogTag.TRANSACTION, Log.VERBOSE)) { 10572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project Log.v(TAG, "httpConnection: params list"); 10672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project Log.v(TAG, "\ttoken\t\t= " + token); 10772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project Log.v(TAG, "\turl\t\t= " + url); 10872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project Log.v(TAG, "\tmethod\t\t= " 10972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project + ((method == HTTP_POST_METHOD) ? "POST" 11072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project : ((method == HTTP_GET_METHOD) ? "GET" : "UNKNOWN"))); 11172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project Log.v(TAG, "\tisProxySet\t= " + isProxySet); 11272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project Log.v(TAG, "\tproxyHost\t= " + proxyHost); 11372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project Log.v(TAG, "\tproxyPort\t= " + proxyPort); 11472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project // TODO Print out binary data more readable. 11572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project //Log.v(TAG, "\tpdu\t\t= " + Arrays.toString(pdu)); 11672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 11772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 11872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project AndroidHttpClient client = null; 11972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 12072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project try { 12172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project // Make sure to use a proxy which supports CONNECT. 12272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project URI hostUrl = new URI(url); 12372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project HttpHost target = new HttpHost( 12472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project hostUrl.getHost(), hostUrl.getPort(), 12572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project HttpHost.DEFAULT_SCHEME_NAME); 12672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 127d62a959cf2e7d261e296f82831942a9a99320175Dan Egnor client = createHttpClient(context); 12872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project HttpRequest req = null; 12972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project switch(method) { 13072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project case HTTP_POST_METHOD: 13172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project ProgressCallbackEntity entity = new ProgressCallbackEntity( 13272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project context, token, pdu); 13372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project // Set request content type. 13472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project entity.setContentType("application/vnd.wap.mms-message"); 13572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 13672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project HttpPost post = new HttpPost(url); 13772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project post.setEntity(entity); 13872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project req = post; 13972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project break; 14072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project case HTTP_GET_METHOD: 14172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project req = new HttpGet(url); 14272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project break; 14372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project default: 14472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project Log.e(TAG, "Unknown HTTP method: " + method 14572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project + ". Must be one of POST[" + HTTP_POST_METHOD 14672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project + "] or GET[" + HTTP_GET_METHOD + "]."); 14772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project return null; 14872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 14972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 15072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project // Set route parameters for the request. 15172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project HttpParams params = client.getParams(); 15272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project if (isProxySet) { 15372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project ConnRouteParams.setDefaultProxy( 15472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project params, new HttpHost(proxyHost, proxyPort)); 15572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 15672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project req.setParams(params); 15772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 15872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project // Set necessary HTTP headers for MMS transmission. 15972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project req.addHeader(HDR_KEY_ACCEPT, HDR_VALUE_ACCEPT); 16072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project { 16189e7af1acc0b62f2822ace8df6d56f4c6d37a40fChristian Gustafsson String xWapProfileTagName = MmsConfig.getUaProfTagName(); 16286a1cf79bf92dbb2b9d09431379bff6de83c2581Tom Taylor String xWapProfileUrl = MmsConfig.getUaProfUrl(); 16372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 16472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project if (xWapProfileUrl != null) { 1651b37c93a3b67483ee9b0ad604a2e1e9d8aaa84d9Wei Huang if (Log.isLoggable(LogTag.TRANSACTION, Log.VERBOSE)) { 1661b37c93a3b67483ee9b0ad604a2e1e9d8aaa84d9Wei Huang Log.d(LogTag.TRANSACTION, 1671b37c93a3b67483ee9b0ad604a2e1e9d8aaa84d9Wei Huang "[HttpUtils] httpConn: xWapProfUrl=" + xWapProfileUrl); 1681b37c93a3b67483ee9b0ad604a2e1e9d8aaa84d9Wei Huang } 16989e7af1acc0b62f2822ace8df6d56f4c6d37a40fChristian Gustafsson req.addHeader(xWapProfileTagName, xWapProfileUrl); 17089e7af1acc0b62f2822ace8df6d56f4c6d37a40fChristian Gustafsson } 17189e7af1acc0b62f2822ace8df6d56f4c6d37a40fChristian Gustafsson } 17289e7af1acc0b62f2822ace8df6d56f4c6d37a40fChristian Gustafsson 17389e7af1acc0b62f2822ace8df6d56f4c6d37a40fChristian Gustafsson // Extra http parameters. Split by '|' to get a list of value pairs. 17489e7af1acc0b62f2822ace8df6d56f4c6d37a40fChristian Gustafsson // Separate each pair by the first occurrence of ':' to obtain a name and 17589e7af1acc0b62f2822ace8df6d56f4c6d37a40fChristian Gustafsson // value. Replace the occurrence of the string returned by 17689e7af1acc0b62f2822ace8df6d56f4c6d37a40fChristian Gustafsson // MmsConfig.getHttpParamsLine1Key() with the users telephone number inside 17789e7af1acc0b62f2822ace8df6d56f4c6d37a40fChristian Gustafsson // the value. 17889e7af1acc0b62f2822ace8df6d56f4c6d37a40fChristian Gustafsson String extraHttpParams = MmsConfig.getHttpParams(); 17989e7af1acc0b62f2822ace8df6d56f4c6d37a40fChristian Gustafsson 18089e7af1acc0b62f2822ace8df6d56f4c6d37a40fChristian Gustafsson if (extraHttpParams != null) { 18189e7af1acc0b62f2822ace8df6d56f4c6d37a40fChristian Gustafsson String line1Number = ((TelephonyManager)context 18289e7af1acc0b62f2822ace8df6d56f4c6d37a40fChristian Gustafsson .getSystemService(Context.TELEPHONY_SERVICE)) 18389e7af1acc0b62f2822ace8df6d56f4c6d37a40fChristian Gustafsson .getLine1Number(); 18489e7af1acc0b62f2822ace8df6d56f4c6d37a40fChristian Gustafsson String line1Key = MmsConfig.getHttpParamsLine1Key(); 18589e7af1acc0b62f2822ace8df6d56f4c6d37a40fChristian Gustafsson String paramList[] = extraHttpParams.split("\\|"); 18689e7af1acc0b62f2822ace8df6d56f4c6d37a40fChristian Gustafsson 18789e7af1acc0b62f2822ace8df6d56f4c6d37a40fChristian Gustafsson for (String paramPair : paramList) { 18889e7af1acc0b62f2822ace8df6d56f4c6d37a40fChristian Gustafsson String splitPair[] = paramPair.split(":", 2); 18989e7af1acc0b62f2822ace8df6d56f4c6d37a40fChristian Gustafsson 19089e7af1acc0b62f2822ace8df6d56f4c6d37a40fChristian Gustafsson if (splitPair.length == 2) { 19189e7af1acc0b62f2822ace8df6d56f4c6d37a40fChristian Gustafsson String name = splitPair[0].trim(); 19289e7af1acc0b62f2822ace8df6d56f4c6d37a40fChristian Gustafsson String value = splitPair[1].trim(); 19389e7af1acc0b62f2822ace8df6d56f4c6d37a40fChristian Gustafsson 19489e7af1acc0b62f2822ace8df6d56f4c6d37a40fChristian Gustafsson if (line1Key != null) { 19589e7af1acc0b62f2822ace8df6d56f4c6d37a40fChristian Gustafsson value = value.replace(line1Key, line1Number); 19689e7af1acc0b62f2822ace8df6d56f4c6d37a40fChristian Gustafsson } 19789e7af1acc0b62f2822ace8df6d56f4c6d37a40fChristian Gustafsson if (!TextUtils.isEmpty(name) && !TextUtils.isEmpty(value)) { 19889e7af1acc0b62f2822ace8df6d56f4c6d37a40fChristian Gustafsson req.addHeader(name, value); 19989e7af1acc0b62f2822ace8df6d56f4c6d37a40fChristian Gustafsson } 20089e7af1acc0b62f2822ace8df6d56f4c6d37a40fChristian Gustafsson } 20172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 20272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 20372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project req.addHeader(HDR_KEY_ACCEPT_LANGUAGE, HDR_VALUE_ACCEPT_LANGUAGE); 20472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 20572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project HttpResponse response = client.execute(target, req); 20672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project StatusLine status = response.getStatusLine(); 20772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project if (status.getStatusCode() != 200) { // HTTP 200 is success. 20872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project throw new IOException("HTTP error: " + status.getReasonPhrase()); 20972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 21072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 21172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project HttpEntity entity = response.getEntity(); 21272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project byte[] body = null; 21372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project if (entity != null) { 21472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project try { 215dd374f47c61f4fed8e6702c1f9d3f33ac5b77d02Tom Taylor if (entity.getContentLength() > 0) { 216dd374f47c61f4fed8e6702c1f9d3f33ac5b77d02Tom Taylor body = new byte[(int) entity.getContentLength()]; 217dd374f47c61f4fed8e6702c1f9d3f33ac5b77d02Tom Taylor DataInputStream dis = new DataInputStream(entity.getContent()); 218dd374f47c61f4fed8e6702c1f9d3f33ac5b77d02Tom Taylor try { 219dd374f47c61f4fed8e6702c1f9d3f33ac5b77d02Tom Taylor dis.readFully(body); 220dd374f47c61f4fed8e6702c1f9d3f33ac5b77d02Tom Taylor } finally { 221dd374f47c61f4fed8e6702c1f9d3f33ac5b77d02Tom Taylor try { 222dd374f47c61f4fed8e6702c1f9d3f33ac5b77d02Tom Taylor dis.close(); 223dd374f47c61f4fed8e6702c1f9d3f33ac5b77d02Tom Taylor } catch (IOException e) { 224dd374f47c61f4fed8e6702c1f9d3f33ac5b77d02Tom Taylor Log.e(TAG, "Error closing input stream: " + e.getMessage()); 225dd374f47c61f4fed8e6702c1f9d3f33ac5b77d02Tom Taylor } 226208b7834ee01388a5fecacf00a9c1e1b8ffc5240Matthias Thomae } 227dd374f47c61f4fed8e6702c1f9d3f33ac5b77d02Tom Taylor } 228dd374f47c61f4fed8e6702c1f9d3f33ac5b77d02Tom Taylor if (entity.isChunked()) { 229dd374f47c61f4fed8e6702c1f9d3f33ac5b77d02Tom Taylor Log.v(TAG, "httpConnection: transfer encoding is chunked"); 230dd374f47c61f4fed8e6702c1f9d3f33ac5b77d02Tom Taylor int bytesTobeRead = MmsConfig.getMaxMessageSize(); 231dd374f47c61f4fed8e6702c1f9d3f33ac5b77d02Tom Taylor byte[] tempBody = new byte[bytesTobeRead]; 232dd374f47c61f4fed8e6702c1f9d3f33ac5b77d02Tom Taylor DataInputStream dis = new DataInputStream(entity.getContent()); 23372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project try { 234dd374f47c61f4fed8e6702c1f9d3f33ac5b77d02Tom Taylor int bytesRead = 0; 235dd374f47c61f4fed8e6702c1f9d3f33ac5b77d02Tom Taylor int offset = 0; 236dd374f47c61f4fed8e6702c1f9d3f33ac5b77d02Tom Taylor boolean readError = false; 237dd374f47c61f4fed8e6702c1f9d3f33ac5b77d02Tom Taylor do { 238dd374f47c61f4fed8e6702c1f9d3f33ac5b77d02Tom Taylor try { 239dd374f47c61f4fed8e6702c1f9d3f33ac5b77d02Tom Taylor bytesRead = dis.read(tempBody, offset, bytesTobeRead); 240dd374f47c61f4fed8e6702c1f9d3f33ac5b77d02Tom Taylor } catch (IOException e) { 241dd374f47c61f4fed8e6702c1f9d3f33ac5b77d02Tom Taylor readError = true; 242dd374f47c61f4fed8e6702c1f9d3f33ac5b77d02Tom Taylor Log.e(TAG, "httpConnection: error reading input stream" 243dd374f47c61f4fed8e6702c1f9d3f33ac5b77d02Tom Taylor + e.getMessage()); 244dd374f47c61f4fed8e6702c1f9d3f33ac5b77d02Tom Taylor break; 245dd374f47c61f4fed8e6702c1f9d3f33ac5b77d02Tom Taylor } 246dd374f47c61f4fed8e6702c1f9d3f33ac5b77d02Tom Taylor if (bytesRead > 0) { 247dd374f47c61f4fed8e6702c1f9d3f33ac5b77d02Tom Taylor bytesTobeRead -= bytesRead; 248dd374f47c61f4fed8e6702c1f9d3f33ac5b77d02Tom Taylor offset += bytesRead; 249dd374f47c61f4fed8e6702c1f9d3f33ac5b77d02Tom Taylor } 250dd374f47c61f4fed8e6702c1f9d3f33ac5b77d02Tom Taylor } while (bytesRead >= 0 && bytesTobeRead > 0); 251dd374f47c61f4fed8e6702c1f9d3f33ac5b77d02Tom Taylor if (bytesRead == -1 && offset > 0 && !readError) { 252dd374f47c61f4fed8e6702c1f9d3f33ac5b77d02Tom Taylor // offset is same as total number of bytes read 253dd374f47c61f4fed8e6702c1f9d3f33ac5b77d02Tom Taylor // bytesRead will be -1 if the data was read till the eof 254dd374f47c61f4fed8e6702c1f9d3f33ac5b77d02Tom Taylor body = new byte[offset]; 255dd374f47c61f4fed8e6702c1f9d3f33ac5b77d02Tom Taylor System.arraycopy(tempBody, 0, body, 0, offset); 256dd374f47c61f4fed8e6702c1f9d3f33ac5b77d02Tom Taylor Log.v(TAG, "httpConnection: Chunked response length [" 257dd374f47c61f4fed8e6702c1f9d3f33ac5b77d02Tom Taylor + Integer.toString(offset) + "]"); 258dd374f47c61f4fed8e6702c1f9d3f33ac5b77d02Tom Taylor } else { 259dd374f47c61f4fed8e6702c1f9d3f33ac5b77d02Tom Taylor Log.e(TAG, "httpConnection: Response entity too large or empty"); 260dd374f47c61f4fed8e6702c1f9d3f33ac5b77d02Tom Taylor } 261dd374f47c61f4fed8e6702c1f9d3f33ac5b77d02Tom Taylor } finally { 262dd374f47c61f4fed8e6702c1f9d3f33ac5b77d02Tom Taylor try { 263dd374f47c61f4fed8e6702c1f9d3f33ac5b77d02Tom Taylor dis.close(); 264dd374f47c61f4fed8e6702c1f9d3f33ac5b77d02Tom Taylor } catch (IOException e) { 265dd374f47c61f4fed8e6702c1f9d3f33ac5b77d02Tom Taylor Log.e(TAG, "Error closing input stream: " + e.getMessage()); 266dd374f47c61f4fed8e6702c1f9d3f33ac5b77d02Tom Taylor } 26772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 26872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 26972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } finally { 270dd374f47c61f4fed8e6702c1f9d3f33ac5b77d02Tom Taylor if (entity != null) { 271dd374f47c61f4fed8e6702c1f9d3f33ac5b77d02Tom Taylor entity.consumeContent(); 272dd374f47c61f4fed8e6702c1f9d3f33ac5b77d02Tom Taylor } 27372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 27472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 27572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project return body; 27672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } catch (URISyntaxException e) { 2777a17eaedae4c54b72f420380ec7129a15442cbbcTom Taylor handleHttpConnectionException(e, url); 27872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } catch (IllegalStateException e) { 2797a17eaedae4c54b72f420380ec7129a15442cbbcTom Taylor handleHttpConnectionException(e, url); 28072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } catch (IllegalArgumentException e) { 2817a17eaedae4c54b72f420380ec7129a15442cbbcTom Taylor handleHttpConnectionException(e, url); 28272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } catch (SocketException e) { 2837a17eaedae4c54b72f420380ec7129a15442cbbcTom Taylor handleHttpConnectionException(e, url); 28472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } catch (Exception e) { 2857a17eaedae4c54b72f420380ec7129a15442cbbcTom Taylor handleHttpConnectionException(e, url); 28672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 28772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project finally { 28872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project if (client != null) { 28972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project client.close(); 29072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 29172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 29272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project return null; 29372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 29472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 2957a17eaedae4c54b72f420380ec7129a15442cbbcTom Taylor private static void handleHttpConnectionException(Exception exception, String url) 29672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project throws IOException { 29772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project // Inner exception should be logged to make life easier. 2987a17eaedae4c54b72f420380ec7129a15442cbbcTom Taylor Log.e(TAG, "Url: " + url + "\n" + exception.getMessage()); 2997a17eaedae4c54b72f420380ec7129a15442cbbcTom Taylor IOException e = new IOException(exception.getMessage()); 3007a17eaedae4c54b72f420380ec7129a15442cbbcTom Taylor e.initCause(exception); 3017a17eaedae4c54b72f420380ec7129a15442cbbcTom Taylor throw e; 30272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 30372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 304d62a959cf2e7d261e296f82831942a9a99320175Dan Egnor private static AndroidHttpClient createHttpClient(Context context) { 3051a0ec0c1576cab49e02a1dab796ed2be33f0a0a5Wei Huang String userAgent = MmsConfig.getUserAgent(); 306d62a959cf2e7d261e296f82831942a9a99320175Dan Egnor AndroidHttpClient client = AndroidHttpClient.newInstance(userAgent, context); 30772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project HttpParams params = client.getParams(); 30872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project HttpProtocolParams.setContentCharset(params, "UTF-8"); 309293000e15498b71a4986d7247e60fe8bdaa05a4bWei Huang 310293000e15498b71a4986d7247e60fe8bdaa05a4bWei Huang // set the socket timeout 311293000e15498b71a4986d7247e60fe8bdaa05a4bWei Huang int soTimeout = MmsConfig.getHttpSocketTimeout(); 312293000e15498b71a4986d7247e60fe8bdaa05a4bWei Huang 3131a0ec0c1576cab49e02a1dab796ed2be33f0a0a5Wei Huang if (Log.isLoggable(LogTag.TRANSACTION, Log.DEBUG)) { 3141a0ec0c1576cab49e02a1dab796ed2be33f0a0a5Wei Huang Log.d(TAG, "[HttpUtils] createHttpClient w/ socket timeout " + soTimeout + " ms, " 3151a0ec0c1576cab49e02a1dab796ed2be33f0a0a5Wei Huang + ", UA=" + userAgent); 316293000e15498b71a4986d7247e60fe8bdaa05a4bWei Huang } 317293000e15498b71a4986d7247e60fe8bdaa05a4bWei Huang HttpConnectionParams.setSoTimeout(params, soTimeout); 31872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project return client; 31972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 32072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 321c122ca5ebd2ccac240002425a567718a9577568cTom Taylor private static final String ACCEPT_LANG_FOR_US_LOCALE = "en-US"; 322c122ca5ebd2ccac240002425a567718a9577568cTom Taylor 32372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project /** 32472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project * Return the Accept-Language header. Use the current locale plus 32572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project * US if we are in a different locale than US. 326c122ca5ebd2ccac240002425a567718a9577568cTom Taylor * This code copied from the browser's WebSettings.java 327c122ca5ebd2ccac240002425a567718a9577568cTom Taylor * @return Current AcceptLanguage String. 32872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project */ 329c122ca5ebd2ccac240002425a567718a9577568cTom Taylor public static String getCurrentAcceptLanguage(Locale locale) { 330c122ca5ebd2ccac240002425a567718a9577568cTom Taylor StringBuilder buffer = new StringBuilder(); 331c122ca5ebd2ccac240002425a567718a9577568cTom Taylor addLocaleToHttpAcceptLanguage(buffer, locale); 332c122ca5ebd2ccac240002425a567718a9577568cTom Taylor 333c122ca5ebd2ccac240002425a567718a9577568cTom Taylor if (!Locale.US.equals(locale)) { 334c122ca5ebd2ccac240002425a567718a9577568cTom Taylor if (buffer.length() > 0) { 335c122ca5ebd2ccac240002425a567718a9577568cTom Taylor buffer.append(", "); 33672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 337c122ca5ebd2ccac240002425a567718a9577568cTom Taylor buffer.append(ACCEPT_LANG_FOR_US_LOCALE); 33872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 339c122ca5ebd2ccac240002425a567718a9577568cTom Taylor 340c122ca5ebd2ccac240002425a567718a9577568cTom Taylor return buffer.toString(); 34172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 34272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 343c122ca5ebd2ccac240002425a567718a9577568cTom Taylor /** 344c122ca5ebd2ccac240002425a567718a9577568cTom Taylor * Convert obsolete language codes, including Hebrew/Indonesian/Yiddish, 345c122ca5ebd2ccac240002425a567718a9577568cTom Taylor * to new standard. 346c122ca5ebd2ccac240002425a567718a9577568cTom Taylor */ 347c122ca5ebd2ccac240002425a567718a9577568cTom Taylor private static String convertObsoleteLanguageCodeToNew(String langCode) { 348c122ca5ebd2ccac240002425a567718a9577568cTom Taylor if (langCode == null) { 349c122ca5ebd2ccac240002425a567718a9577568cTom Taylor return null; 350c122ca5ebd2ccac240002425a567718a9577568cTom Taylor } 351c122ca5ebd2ccac240002425a567718a9577568cTom Taylor if ("iw".equals(langCode)) { 352c122ca5ebd2ccac240002425a567718a9577568cTom Taylor // Hebrew 353c122ca5ebd2ccac240002425a567718a9577568cTom Taylor return "he"; 354c122ca5ebd2ccac240002425a567718a9577568cTom Taylor } else if ("in".equals(langCode)) { 355c122ca5ebd2ccac240002425a567718a9577568cTom Taylor // Indonesian 356c122ca5ebd2ccac240002425a567718a9577568cTom Taylor return "id"; 357c122ca5ebd2ccac240002425a567718a9577568cTom Taylor } else if ("ji".equals(langCode)) { 358c122ca5ebd2ccac240002425a567718a9577568cTom Taylor // Yiddish 359c122ca5ebd2ccac240002425a567718a9577568cTom Taylor return "yi"; 360c122ca5ebd2ccac240002425a567718a9577568cTom Taylor } 361c122ca5ebd2ccac240002425a567718a9577568cTom Taylor return langCode; 362c122ca5ebd2ccac240002425a567718a9577568cTom Taylor } 36372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project 364c122ca5ebd2ccac240002425a567718a9577568cTom Taylor private static void addLocaleToHttpAcceptLanguage(StringBuilder builder, 365c122ca5ebd2ccac240002425a567718a9577568cTom Taylor Locale locale) { 366c122ca5ebd2ccac240002425a567718a9577568cTom Taylor String language = convertObsoleteLanguageCodeToNew(locale.getLanguage()); 36772735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project if (language != null) { 36872735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project builder.append(language); 36972735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project String country = locale.getCountry(); 37072735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project if (country != null) { 37172735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project builder.append("-"); 37272735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project builder.append(country); 37372735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 37472735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 37572735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project } 37672735c62aba8fd2a9420a0f9f83d22543e3c164fThe Android Open Source Project} 377