13713094c56d25e25df2a508dbee4aea869ffdea1Ficus Kirkpatrick/* 23713094c56d25e25df2a508dbee4aea869ffdea1Ficus Kirkpatrick * Copyright (C) 2011 The Android Open Source Project 33713094c56d25e25df2a508dbee4aea869ffdea1Ficus Kirkpatrick * 43713094c56d25e25df2a508dbee4aea869ffdea1Ficus Kirkpatrick * Licensed under the Apache License, Version 2.0 (the "License"); 53713094c56d25e25df2a508dbee4aea869ffdea1Ficus Kirkpatrick * you may not use this file except in compliance with the License. 63713094c56d25e25df2a508dbee4aea869ffdea1Ficus Kirkpatrick * You may obtain a copy of the License at 73713094c56d25e25df2a508dbee4aea869ffdea1Ficus Kirkpatrick * 83713094c56d25e25df2a508dbee4aea869ffdea1Ficus Kirkpatrick * http://www.apache.org/licenses/LICENSE-2.0 93713094c56d25e25df2a508dbee4aea869ffdea1Ficus Kirkpatrick * 103713094c56d25e25df2a508dbee4aea869ffdea1Ficus Kirkpatrick * Unless required by applicable law or agreed to in writing, software 113713094c56d25e25df2a508dbee4aea869ffdea1Ficus Kirkpatrick * distributed under the License is distributed on an "AS IS" BASIS, 123713094c56d25e25df2a508dbee4aea869ffdea1Ficus Kirkpatrick * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 133713094c56d25e25df2a508dbee4aea869ffdea1Ficus Kirkpatrick * See the License for the specific language governing permissions and 143713094c56d25e25df2a508dbee4aea869ffdea1Ficus Kirkpatrick * limitations under the License. 153713094c56d25e25df2a508dbee4aea869ffdea1Ficus Kirkpatrick */ 163713094c56d25e25df2a508dbee4aea869ffdea1Ficus Kirkpatrick 173713094c56d25e25df2a508dbee4aea869ffdea1Ficus Kirkpatrickpackage com.android.volley.toolbox; 183713094c56d25e25df2a508dbee4aea869ffdea1Ficus Kirkpatrick 199c19fc62ddd9d1b371cb3ead4e10bb5ff1100a6cJeff Sharkeyimport android.os.SystemClock; 209c19fc62ddd9d1b371cb3ead4e10bb5ff1100a6cJeff Sharkey 213713094c56d25e25df2a508dbee4aea869ffdea1Ficus Kirkpatrickimport com.android.volley.AuthFailureError; 223713094c56d25e25df2a508dbee4aea869ffdea1Ficus Kirkpatrickimport com.android.volley.Cache; 233713094c56d25e25df2a508dbee4aea869ffdea1Ficus Kirkpatrickimport com.android.volley.Network; 243713094c56d25e25df2a508dbee4aea869ffdea1Ficus Kirkpatrickimport com.android.volley.NetworkError; 253713094c56d25e25df2a508dbee4aea869ffdea1Ficus Kirkpatrickimport com.android.volley.NetworkResponse; 263713094c56d25e25df2a508dbee4aea869ffdea1Ficus Kirkpatrickimport com.android.volley.NoConnectionError; 273713094c56d25e25df2a508dbee4aea869ffdea1Ficus Kirkpatrickimport com.android.volley.Request; 283713094c56d25e25df2a508dbee4aea869ffdea1Ficus Kirkpatrickimport com.android.volley.RetryPolicy; 293713094c56d25e25df2a508dbee4aea869ffdea1Ficus Kirkpatrickimport com.android.volley.ServerError; 303713094c56d25e25df2a508dbee4aea869ffdea1Ficus Kirkpatrickimport com.android.volley.TimeoutError; 313713094c56d25e25df2a508dbee4aea869ffdea1Ficus Kirkpatrickimport com.android.volley.VolleyError; 323713094c56d25e25df2a508dbee4aea869ffdea1Ficus Kirkpatrickimport com.android.volley.VolleyLog; 333713094c56d25e25df2a508dbee4aea869ffdea1Ficus Kirkpatrick 343713094c56d25e25df2a508dbee4aea869ffdea1Ficus Kirkpatrickimport org.apache.http.Header; 353713094c56d25e25df2a508dbee4aea869ffdea1Ficus Kirkpatrickimport org.apache.http.HttpEntity; 363713094c56d25e25df2a508dbee4aea869ffdea1Ficus Kirkpatrickimport org.apache.http.HttpResponse; 373713094c56d25e25df2a508dbee4aea869ffdea1Ficus Kirkpatrickimport org.apache.http.HttpStatus; 383713094c56d25e25df2a508dbee4aea869ffdea1Ficus Kirkpatrickimport org.apache.http.StatusLine; 393713094c56d25e25df2a508dbee4aea869ffdea1Ficus Kirkpatrickimport org.apache.http.conn.ConnectTimeoutException; 403713094c56d25e25df2a508dbee4aea869ffdea1Ficus Kirkpatrickimport org.apache.http.impl.cookie.DateUtils; 413713094c56d25e25df2a508dbee4aea869ffdea1Ficus Kirkpatrick 423713094c56d25e25df2a508dbee4aea869ffdea1Ficus Kirkpatrickimport java.io.IOException; 433713094c56d25e25df2a508dbee4aea869ffdea1Ficus Kirkpatrickimport java.io.InputStream; 443713094c56d25e25df2a508dbee4aea869ffdea1Ficus Kirkpatrickimport java.net.MalformedURLException; 453713094c56d25e25df2a508dbee4aea869ffdea1Ficus Kirkpatrickimport java.net.SocketTimeoutException; 463713094c56d25e25df2a508dbee4aea869ffdea1Ficus Kirkpatrickimport java.util.Date; 473713094c56d25e25df2a508dbee4aea869ffdea1Ficus Kirkpatrickimport java.util.HashMap; 483713094c56d25e25df2a508dbee4aea869ffdea1Ficus Kirkpatrickimport java.util.Map; 493713094c56d25e25df2a508dbee4aea869ffdea1Ficus Kirkpatrick 503713094c56d25e25df2a508dbee4aea869ffdea1Ficus Kirkpatrick/** 513713094c56d25e25df2a508dbee4aea869ffdea1Ficus Kirkpatrick * A network performing Volley requests over an {@link HttpStack}. 523713094c56d25e25df2a508dbee4aea869ffdea1Ficus Kirkpatrick */ 533713094c56d25e25df2a508dbee4aea869ffdea1Ficus Kirkpatrickpublic class BasicNetwork implements Network { 543713094c56d25e25df2a508dbee4aea869ffdea1Ficus Kirkpatrick protected static final boolean DEBUG = VolleyLog.DEBUG; 553713094c56d25e25df2a508dbee4aea869ffdea1Ficus Kirkpatrick 563713094c56d25e25df2a508dbee4aea869ffdea1Ficus Kirkpatrick private static int SLOW_REQUEST_THRESHOLD_MS = 3000; 573713094c56d25e25df2a508dbee4aea869ffdea1Ficus Kirkpatrick 58c4cbfcb8d044cea99e2471ce5c401cd959b6cdfeScott Barta private static int DEFAULT_POOL_SIZE = 4096; 59c4cbfcb8d044cea99e2471ce5c401cd959b6cdfeScott Barta 603713094c56d25e25df2a508dbee4aea869ffdea1Ficus Kirkpatrick protected final HttpStack mHttpStack; 613713094c56d25e25df2a508dbee4aea869ffdea1Ficus Kirkpatrick 62c4cbfcb8d044cea99e2471ce5c401cd959b6cdfeScott Barta protected final ByteArrayPool mPool; 63c4cbfcb8d044cea99e2471ce5c401cd959b6cdfeScott Barta 643713094c56d25e25df2a508dbee4aea869ffdea1Ficus Kirkpatrick /** 653713094c56d25e25df2a508dbee4aea869ffdea1Ficus Kirkpatrick * @param httpStack HTTP stack to be used 663713094c56d25e25df2a508dbee4aea869ffdea1Ficus Kirkpatrick */ 673713094c56d25e25df2a508dbee4aea869ffdea1Ficus Kirkpatrick public BasicNetwork(HttpStack httpStack) { 68c4cbfcb8d044cea99e2471ce5c401cd959b6cdfeScott Barta // If a pool isn't passed in, then build a small default pool that will give us a lot of 69c4cbfcb8d044cea99e2471ce5c401cd959b6cdfeScott Barta // benefit and not use too much memory. 70c4cbfcb8d044cea99e2471ce5c401cd959b6cdfeScott Barta this(httpStack, new ByteArrayPool(DEFAULT_POOL_SIZE)); 71c4cbfcb8d044cea99e2471ce5c401cd959b6cdfeScott Barta } 72c4cbfcb8d044cea99e2471ce5c401cd959b6cdfeScott Barta 73c4cbfcb8d044cea99e2471ce5c401cd959b6cdfeScott Barta /** 74c4cbfcb8d044cea99e2471ce5c401cd959b6cdfeScott Barta * @param httpStack HTTP stack to be used 75c4cbfcb8d044cea99e2471ce5c401cd959b6cdfeScott Barta * @param pool a buffer pool that improves GC performance in copy operations 76c4cbfcb8d044cea99e2471ce5c401cd959b6cdfeScott Barta */ 77c4cbfcb8d044cea99e2471ce5c401cd959b6cdfeScott Barta public BasicNetwork(HttpStack httpStack, ByteArrayPool pool) { 783713094c56d25e25df2a508dbee4aea869ffdea1Ficus Kirkpatrick mHttpStack = httpStack; 79c4cbfcb8d044cea99e2471ce5c401cd959b6cdfeScott Barta mPool = pool; 803713094c56d25e25df2a508dbee4aea869ffdea1Ficus Kirkpatrick } 813713094c56d25e25df2a508dbee4aea869ffdea1Ficus Kirkpatrick 823713094c56d25e25df2a508dbee4aea869ffdea1Ficus Kirkpatrick @Override 833713094c56d25e25df2a508dbee4aea869ffdea1Ficus Kirkpatrick public NetworkResponse performRequest(Request<?> request) throws VolleyError { 849c19fc62ddd9d1b371cb3ead4e10bb5ff1100a6cJeff Sharkey long requestStart = SystemClock.elapsedRealtime(); 853713094c56d25e25df2a508dbee4aea869ffdea1Ficus Kirkpatrick while (true) { 863713094c56d25e25df2a508dbee4aea869ffdea1Ficus Kirkpatrick HttpResponse httpResponse = null; 873713094c56d25e25df2a508dbee4aea869ffdea1Ficus Kirkpatrick byte[] responseContents = null; 883713094c56d25e25df2a508dbee4aea869ffdea1Ficus Kirkpatrick Map<String, String> responseHeaders = new HashMap<String, String>(); 893713094c56d25e25df2a508dbee4aea869ffdea1Ficus Kirkpatrick try { 903713094c56d25e25df2a508dbee4aea869ffdea1Ficus Kirkpatrick // Gather headers. 913713094c56d25e25df2a508dbee4aea869ffdea1Ficus Kirkpatrick Map<String, String> headers = new HashMap<String, String>(); 923713094c56d25e25df2a508dbee4aea869ffdea1Ficus Kirkpatrick addCacheHeaders(headers, request.getCacheEntry()); 933713094c56d25e25df2a508dbee4aea869ffdea1Ficus Kirkpatrick httpResponse = mHttpStack.performRequest(request, headers); 943713094c56d25e25df2a508dbee4aea869ffdea1Ficus Kirkpatrick StatusLine statusLine = httpResponse.getStatusLine(); 953713094c56d25e25df2a508dbee4aea869ffdea1Ficus Kirkpatrick 963713094c56d25e25df2a508dbee4aea869ffdea1Ficus Kirkpatrick responseHeaders = convertHeaders(httpResponse.getAllHeaders()); 973713094c56d25e25df2a508dbee4aea869ffdea1Ficus Kirkpatrick // Handle cache validation. 983713094c56d25e25df2a508dbee4aea869ffdea1Ficus Kirkpatrick if (statusLine.getStatusCode() == HttpStatus.SC_NOT_MODIFIED) { 993713094c56d25e25df2a508dbee4aea869ffdea1Ficus Kirkpatrick return new NetworkResponse(HttpStatus.SC_NOT_MODIFIED, 1003713094c56d25e25df2a508dbee4aea869ffdea1Ficus Kirkpatrick request.getCacheEntry().data, responseHeaders, true); 1013713094c56d25e25df2a508dbee4aea869ffdea1Ficus Kirkpatrick } 1023713094c56d25e25df2a508dbee4aea869ffdea1Ficus Kirkpatrick 1033713094c56d25e25df2a508dbee4aea869ffdea1Ficus Kirkpatrick responseContents = entityToBytes(httpResponse.getEntity()); 1043713094c56d25e25df2a508dbee4aea869ffdea1Ficus Kirkpatrick // if the request is slow, log it. 1059c19fc62ddd9d1b371cb3ead4e10bb5ff1100a6cJeff Sharkey long requestLifetime = SystemClock.elapsedRealtime() - requestStart; 1063713094c56d25e25df2a508dbee4aea869ffdea1Ficus Kirkpatrick logSlowRequests(requestLifetime, request, responseContents, statusLine); 1073713094c56d25e25df2a508dbee4aea869ffdea1Ficus Kirkpatrick 1083713094c56d25e25df2a508dbee4aea869ffdea1Ficus Kirkpatrick if (statusLine.getStatusCode() != HttpStatus.SC_OK) { 1093713094c56d25e25df2a508dbee4aea869ffdea1Ficus Kirkpatrick throw new IOException(); 1103713094c56d25e25df2a508dbee4aea869ffdea1Ficus Kirkpatrick } 1113713094c56d25e25df2a508dbee4aea869ffdea1Ficus Kirkpatrick return new NetworkResponse(HttpStatus.SC_OK, 1123713094c56d25e25df2a508dbee4aea869ffdea1Ficus Kirkpatrick responseContents, responseHeaders, false); 1133713094c56d25e25df2a508dbee4aea869ffdea1Ficus Kirkpatrick } catch (SocketTimeoutException e) { 1143713094c56d25e25df2a508dbee4aea869ffdea1Ficus Kirkpatrick attemptRetryOnException("socket", request, new TimeoutError()); 1153713094c56d25e25df2a508dbee4aea869ffdea1Ficus Kirkpatrick } catch (ConnectTimeoutException e) { 1163713094c56d25e25df2a508dbee4aea869ffdea1Ficus Kirkpatrick attemptRetryOnException("connection", request, new TimeoutError()); 1173713094c56d25e25df2a508dbee4aea869ffdea1Ficus Kirkpatrick } catch (MalformedURLException e) { 1183713094c56d25e25df2a508dbee4aea869ffdea1Ficus Kirkpatrick throw new RuntimeException("Bad URL " + request.getUrl(), e); 1193713094c56d25e25df2a508dbee4aea869ffdea1Ficus Kirkpatrick } catch (IOException e) { 1203713094c56d25e25df2a508dbee4aea869ffdea1Ficus Kirkpatrick int statusCode = 0; 1213713094c56d25e25df2a508dbee4aea869ffdea1Ficus Kirkpatrick NetworkResponse networkResponse = null; 1223713094c56d25e25df2a508dbee4aea869ffdea1Ficus Kirkpatrick if (httpResponse != null) { 1233713094c56d25e25df2a508dbee4aea869ffdea1Ficus Kirkpatrick statusCode = httpResponse.getStatusLine().getStatusCode(); 1243713094c56d25e25df2a508dbee4aea869ffdea1Ficus Kirkpatrick } else { 1253713094c56d25e25df2a508dbee4aea869ffdea1Ficus Kirkpatrick throw new NoConnectionError(e); 1263713094c56d25e25df2a508dbee4aea869ffdea1Ficus Kirkpatrick } 1273713094c56d25e25df2a508dbee4aea869ffdea1Ficus Kirkpatrick VolleyLog.e("Unexpected response code %d for %s", statusCode, request.getUrl()); 1283713094c56d25e25df2a508dbee4aea869ffdea1Ficus Kirkpatrick if (responseContents != null) { 1293713094c56d25e25df2a508dbee4aea869ffdea1Ficus Kirkpatrick networkResponse = new NetworkResponse(statusCode, responseContents, 1303713094c56d25e25df2a508dbee4aea869ffdea1Ficus Kirkpatrick responseHeaders, false); 1313713094c56d25e25df2a508dbee4aea869ffdea1Ficus Kirkpatrick if (statusCode == HttpStatus.SC_UNAUTHORIZED || 1323713094c56d25e25df2a508dbee4aea869ffdea1Ficus Kirkpatrick statusCode == HttpStatus.SC_FORBIDDEN) { 1333713094c56d25e25df2a508dbee4aea869ffdea1Ficus Kirkpatrick attemptRetryOnException("auth", 1343713094c56d25e25df2a508dbee4aea869ffdea1Ficus Kirkpatrick request, new AuthFailureError(networkResponse)); 1353713094c56d25e25df2a508dbee4aea869ffdea1Ficus Kirkpatrick } else { 1363713094c56d25e25df2a508dbee4aea869ffdea1Ficus Kirkpatrick // TODO: Only throw ServerError for 5xx status codes. 1373713094c56d25e25df2a508dbee4aea869ffdea1Ficus Kirkpatrick throw new ServerError(networkResponse); 1383713094c56d25e25df2a508dbee4aea869ffdea1Ficus Kirkpatrick } 1393713094c56d25e25df2a508dbee4aea869ffdea1Ficus Kirkpatrick } else { 1403713094c56d25e25df2a508dbee4aea869ffdea1Ficus Kirkpatrick throw new NetworkError(networkResponse); 1413713094c56d25e25df2a508dbee4aea869ffdea1Ficus Kirkpatrick } 1423713094c56d25e25df2a508dbee4aea869ffdea1Ficus Kirkpatrick } 1433713094c56d25e25df2a508dbee4aea869ffdea1Ficus Kirkpatrick } 1443713094c56d25e25df2a508dbee4aea869ffdea1Ficus Kirkpatrick } 1453713094c56d25e25df2a508dbee4aea869ffdea1Ficus Kirkpatrick 1463713094c56d25e25df2a508dbee4aea869ffdea1Ficus Kirkpatrick /** 1473713094c56d25e25df2a508dbee4aea869ffdea1Ficus Kirkpatrick * Logs requests that took over SLOW_REQUEST_THRESHOLD_MS to complete. 1483713094c56d25e25df2a508dbee4aea869ffdea1Ficus Kirkpatrick */ 1493713094c56d25e25df2a508dbee4aea869ffdea1Ficus Kirkpatrick private void logSlowRequests(long requestLifetime, Request<?> request, 1503713094c56d25e25df2a508dbee4aea869ffdea1Ficus Kirkpatrick byte[] responseContents, StatusLine statusLine) { 1513713094c56d25e25df2a508dbee4aea869ffdea1Ficus Kirkpatrick if (DEBUG || requestLifetime > SLOW_REQUEST_THRESHOLD_MS) { 1523713094c56d25e25df2a508dbee4aea869ffdea1Ficus Kirkpatrick VolleyLog.d("HTTP response for request=<%s> [lifetime=%d], [size=%s], " + 1533713094c56d25e25df2a508dbee4aea869ffdea1Ficus Kirkpatrick "[rc=%d], [retryCount=%s]", request, requestLifetime, 1543713094c56d25e25df2a508dbee4aea869ffdea1Ficus Kirkpatrick responseContents != null ? responseContents.length : "null", 1553713094c56d25e25df2a508dbee4aea869ffdea1Ficus Kirkpatrick statusLine.getStatusCode(), request.getRetryPolicy().getCurrentRetryCount()); 1563713094c56d25e25df2a508dbee4aea869ffdea1Ficus Kirkpatrick } 1573713094c56d25e25df2a508dbee4aea869ffdea1Ficus Kirkpatrick } 1583713094c56d25e25df2a508dbee4aea869ffdea1Ficus Kirkpatrick 1593713094c56d25e25df2a508dbee4aea869ffdea1Ficus Kirkpatrick /** 1603713094c56d25e25df2a508dbee4aea869ffdea1Ficus Kirkpatrick * Attempts to prepare the request for a retry. If there are no more attempts remaining in the 1613713094c56d25e25df2a508dbee4aea869ffdea1Ficus Kirkpatrick * request's retry policy, a timeout exception is thrown. 1623713094c56d25e25df2a508dbee4aea869ffdea1Ficus Kirkpatrick * @param request The request to use. 1633713094c56d25e25df2a508dbee4aea869ffdea1Ficus Kirkpatrick */ 1643713094c56d25e25df2a508dbee4aea869ffdea1Ficus Kirkpatrick private static void attemptRetryOnException(String logPrefix, Request<?> request, 1653713094c56d25e25df2a508dbee4aea869ffdea1Ficus Kirkpatrick VolleyError exception) throws VolleyError { 1663713094c56d25e25df2a508dbee4aea869ffdea1Ficus Kirkpatrick RetryPolicy retryPolicy = request.getRetryPolicy(); 1673713094c56d25e25df2a508dbee4aea869ffdea1Ficus Kirkpatrick int oldTimeout = request.getTimeoutMs(); 1683713094c56d25e25df2a508dbee4aea869ffdea1Ficus Kirkpatrick 1693713094c56d25e25df2a508dbee4aea869ffdea1Ficus Kirkpatrick try { 1703713094c56d25e25df2a508dbee4aea869ffdea1Ficus Kirkpatrick retryPolicy.retry(exception); 1713713094c56d25e25df2a508dbee4aea869ffdea1Ficus Kirkpatrick } catch (VolleyError e) { 1723713094c56d25e25df2a508dbee4aea869ffdea1Ficus Kirkpatrick request.addMarker( 1733713094c56d25e25df2a508dbee4aea869ffdea1Ficus Kirkpatrick String.format("%s-timeout-giveup [timeout=%s]", logPrefix, oldTimeout)); 1743713094c56d25e25df2a508dbee4aea869ffdea1Ficus Kirkpatrick throw e; 1753713094c56d25e25df2a508dbee4aea869ffdea1Ficus Kirkpatrick } 1763713094c56d25e25df2a508dbee4aea869ffdea1Ficus Kirkpatrick request.addMarker(String.format("%s-retry [timeout=%s]", logPrefix, oldTimeout)); 1773713094c56d25e25df2a508dbee4aea869ffdea1Ficus Kirkpatrick } 1783713094c56d25e25df2a508dbee4aea869ffdea1Ficus Kirkpatrick 1793713094c56d25e25df2a508dbee4aea869ffdea1Ficus Kirkpatrick private void addCacheHeaders(Map<String, String> headers, Cache.Entry entry) { 1803713094c56d25e25df2a508dbee4aea869ffdea1Ficus Kirkpatrick // If there's no cache entry, we're done. 1813713094c56d25e25df2a508dbee4aea869ffdea1Ficus Kirkpatrick if (entry == null) { 1823713094c56d25e25df2a508dbee4aea869ffdea1Ficus Kirkpatrick return; 1833713094c56d25e25df2a508dbee4aea869ffdea1Ficus Kirkpatrick } 1843713094c56d25e25df2a508dbee4aea869ffdea1Ficus Kirkpatrick 1853713094c56d25e25df2a508dbee4aea869ffdea1Ficus Kirkpatrick if (entry.etag != null) { 1863713094c56d25e25df2a508dbee4aea869ffdea1Ficus Kirkpatrick headers.put("If-None-Match", entry.etag); 1873713094c56d25e25df2a508dbee4aea869ffdea1Ficus Kirkpatrick } 1883713094c56d25e25df2a508dbee4aea869ffdea1Ficus Kirkpatrick 1893713094c56d25e25df2a508dbee4aea869ffdea1Ficus Kirkpatrick if (entry.serverDate > 0) { 1903713094c56d25e25df2a508dbee4aea869ffdea1Ficus Kirkpatrick Date refTime = new Date(entry.serverDate); 1913713094c56d25e25df2a508dbee4aea869ffdea1Ficus Kirkpatrick headers.put("If-Modified-Since", DateUtils.formatDate(refTime)); 1923713094c56d25e25df2a508dbee4aea869ffdea1Ficus Kirkpatrick } 1933713094c56d25e25df2a508dbee4aea869ffdea1Ficus Kirkpatrick } 1943713094c56d25e25df2a508dbee4aea869ffdea1Ficus Kirkpatrick 1953713094c56d25e25df2a508dbee4aea869ffdea1Ficus Kirkpatrick protected void logError(String what, String url, long start) { 1969c19fc62ddd9d1b371cb3ead4e10bb5ff1100a6cJeff Sharkey long now = SystemClock.elapsedRealtime(); 1973713094c56d25e25df2a508dbee4aea869ffdea1Ficus Kirkpatrick VolleyLog.v("HTTP ERROR(%s) %d ms to fetch %s", what, (now - start), url); 1983713094c56d25e25df2a508dbee4aea869ffdea1Ficus Kirkpatrick } 1993713094c56d25e25df2a508dbee4aea869ffdea1Ficus Kirkpatrick 2003713094c56d25e25df2a508dbee4aea869ffdea1Ficus Kirkpatrick /** Reads the contents of HttpEntity into a byte[]. */ 201c4cbfcb8d044cea99e2471ce5c401cd959b6cdfeScott Barta private byte[] entityToBytes(HttpEntity entity) throws IOException, ServerError { 202c4cbfcb8d044cea99e2471ce5c401cd959b6cdfeScott Barta PoolingByteArrayOutputStream bytes = 203c4cbfcb8d044cea99e2471ce5c401cd959b6cdfeScott Barta new PoolingByteArrayOutputStream(mPool, (int) entity.getContentLength()); 204c4cbfcb8d044cea99e2471ce5c401cd959b6cdfeScott Barta byte[] buffer = null; 2053713094c56d25e25df2a508dbee4aea869ffdea1Ficus Kirkpatrick try { 2063713094c56d25e25df2a508dbee4aea869ffdea1Ficus Kirkpatrick InputStream in = entity.getContent(); 2073713094c56d25e25df2a508dbee4aea869ffdea1Ficus Kirkpatrick if (in == null) { 2083713094c56d25e25df2a508dbee4aea869ffdea1Ficus Kirkpatrick throw new ServerError(); 2093713094c56d25e25df2a508dbee4aea869ffdea1Ficus Kirkpatrick } 210c4cbfcb8d044cea99e2471ce5c401cd959b6cdfeScott Barta buffer = mPool.getBuf(1024); 2113713094c56d25e25df2a508dbee4aea869ffdea1Ficus Kirkpatrick int count; 2123713094c56d25e25df2a508dbee4aea869ffdea1Ficus Kirkpatrick while ((count = in.read(buffer)) != -1) { 2133713094c56d25e25df2a508dbee4aea869ffdea1Ficus Kirkpatrick bytes.write(buffer, 0, count); 2143713094c56d25e25df2a508dbee4aea869ffdea1Ficus Kirkpatrick } 2153713094c56d25e25df2a508dbee4aea869ffdea1Ficus Kirkpatrick return bytes.toByteArray(); 2163713094c56d25e25df2a508dbee4aea869ffdea1Ficus Kirkpatrick } finally { 2173713094c56d25e25df2a508dbee4aea869ffdea1Ficus Kirkpatrick try { 2183713094c56d25e25df2a508dbee4aea869ffdea1Ficus Kirkpatrick // Close the InputStream and release the resources by "consuming the content". 2193713094c56d25e25df2a508dbee4aea869ffdea1Ficus Kirkpatrick entity.consumeContent(); 2203713094c56d25e25df2a508dbee4aea869ffdea1Ficus Kirkpatrick } catch (IOException e) { 2213713094c56d25e25df2a508dbee4aea869ffdea1Ficus Kirkpatrick // This can happen if there was an exception above that left the entity in 2223713094c56d25e25df2a508dbee4aea869ffdea1Ficus Kirkpatrick // an invalid state. 2233713094c56d25e25df2a508dbee4aea869ffdea1Ficus Kirkpatrick VolleyLog.v("Error occured when calling consumingContent"); 2243713094c56d25e25df2a508dbee4aea869ffdea1Ficus Kirkpatrick } 225c4cbfcb8d044cea99e2471ce5c401cd959b6cdfeScott Barta mPool.returnBuf(buffer); 226c4cbfcb8d044cea99e2471ce5c401cd959b6cdfeScott Barta bytes.close(); 2273713094c56d25e25df2a508dbee4aea869ffdea1Ficus Kirkpatrick } 2283713094c56d25e25df2a508dbee4aea869ffdea1Ficus Kirkpatrick } 2293713094c56d25e25df2a508dbee4aea869ffdea1Ficus Kirkpatrick 2303713094c56d25e25df2a508dbee4aea869ffdea1Ficus Kirkpatrick /** 2313713094c56d25e25df2a508dbee4aea869ffdea1Ficus Kirkpatrick * Converts Headers[] to Map<String, String>. 2323713094c56d25e25df2a508dbee4aea869ffdea1Ficus Kirkpatrick */ 2333713094c56d25e25df2a508dbee4aea869ffdea1Ficus Kirkpatrick private static Map<String, String> convertHeaders(Header[] headers) { 2343713094c56d25e25df2a508dbee4aea869ffdea1Ficus Kirkpatrick Map<String, String> result = new HashMap<String, String>(); 2353713094c56d25e25df2a508dbee4aea869ffdea1Ficus Kirkpatrick for (int i = 0; i < headers.length; i++) { 2363713094c56d25e25df2a508dbee4aea869ffdea1Ficus Kirkpatrick result.put(headers[i].getName(), headers[i].getValue()); 2373713094c56d25e25df2a508dbee4aea869ffdea1Ficus Kirkpatrick } 2383713094c56d25e25df2a508dbee4aea869ffdea1Ficus Kirkpatrick return result; 2393713094c56d25e25df2a508dbee4aea869ffdea1Ficus Kirkpatrick } 2403713094c56d25e25df2a508dbee4aea869ffdea1Ficus Kirkpatrick} 241