private HttpURLConnection downloadFrom(Uri uri, int maxRedirects) throws IOException {
    HttpURLConnection connection = openConnectionTo(uri);
    if (mUserAgent != null) {
      connection.setRequestProperty("User-Agent", mUserAgent);
    }
    if (mRequestHeaders != null) {
      for (Map.Entry<String, String> entry : mRequestHeaders.entrySet()) {
        connection.setRequestProperty(entry.getKey(), entry.getValue());
      }
    }
    connection.setConnectTimeout(mHttpConnectionTimeout);
    int responseCode = connection.getResponseCode();

    if (isHttpSuccess(responseCode)) {
      return connection;

    } else if (isHttpRedirect(responseCode)) {
      String nextUriString = connection.getHeaderField("Location");
      connection.disconnect();

      Uri nextUri = (nextUriString == null) ? null : Uri.parse(nextUriString);
      String originalScheme = uri.getScheme();

      if (maxRedirects > 0
          && nextUri != null
          && !Objects.equal(nextUri.getScheme(), originalScheme)) {
        return downloadFrom(nextUri, maxRedirects - 1);
      } else {
        String message =
            maxRedirects == 0
                ? error("URL %s follows too many redirects", uri.toString())
                : error(
                    "URL %s returned %d without a valid redirect", uri.toString(), responseCode);
        throw new IOException(message);
      }

    } else {
      connection.disconnect();
      throw new IOException(
          String.format("Image URL %s returned HTTP code %d", uri.toString(), responseCode));
    }
  }
Network fetcher that uses the simplest Android stack.

<p>Apps requiring more sophisticated networking should implement their own {@link
NetworkFetcher}.
imagepipeline/src/main/java/com/facebook/imagepipeline/producers/HttpUrlConnectionNetworkFetcher.java