/* * Copyright (C) 2014 Fastboot Mobile, LLC. * * This program is free software; you can redistribute it and/or modify it under the terms of the * GNU General Public License as published by the Free Software Foundation; either version 3 of * the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See * the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along with this program; * if not, see <http://www.gnu.org/licenses>. */ package com.fastbootmobile.encore.api.common; import android.util.Log; import java.io.BufferedInputStream; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.InputStream; import java.net.HttpURLConnection; import java.net.URL; /** * HTTP GET helper */ public class HttpGet { private static final String TAG = "HttpGet"; /** * Downloads the data from the provided URL. * @param inUrl The URL to get from * @param query The query field. '?' + query will be appended automatically, and the query data * MUST be encoded properly. * @return A string with the data grabbed from the URL */ public static String get(String inUrl, String query, boolean cached) throws IOException, RateLimitException { return new String(getBytes(inUrl, query, cached)); } /** * Downloads the data from the provided URL. * @param inUrl The URL to get from * @param query The query field. '?' + query will be appended automatically, and the query data * MUST be encoded properly. * @return A byte array of the data */ public static byte[] getBytes(String inUrl, String query, boolean cached) throws IOException, RateLimitException { final String formattedUrl = inUrl + (query.isEmpty() ? "" : ("?" + query)); Log.d(TAG, "Formatted URL: " + formattedUrl); URL url = new URL(formattedUrl); HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection(); urlConnection.setRequestProperty("User-Agent","OmniMusic/1.0-dev (http://www.omnirom.org)"); urlConnection.setUseCaches(cached); urlConnection.setInstanceFollowRedirects(true); int maxStale = 60 * 60 * 24 * 28; // tolerate 4-weeks stale urlConnection.addRequestProperty("Cache-Control", "max-stale=" + maxStale); try { final int status = urlConnection.getResponseCode(); // MusicBrainz returns 503 Unavailable on rate limit errors. Parse the JSON anyway. if (status == HttpURLConnection.HTTP_OK) { InputStream in = new BufferedInputStream(urlConnection.getInputStream()); int contentLength = urlConnection.getContentLength(); if (contentLength <= 0) { // No length? Let's allocate 100KB. contentLength = 100 * 1024; } ByteArrayOutputStream baos = new ByteArrayOutputStream(contentLength); byte[] buffer = new byte[2048]; BufferedInputStream bis = new BufferedInputStream(in); int read; while ((read = bis.read(buffer, 0, buffer.length)) > 0) { baos.write(buffer, 0, read); } return baos.toByteArray(); } else if (status == HttpURLConnection.HTTP_NOT_FOUND) { // 404 return new byte[]{}; } else if (status == HttpURLConnection.HTTP_FORBIDDEN) { return new byte[]{}; } else if (status == HttpURLConnection.HTTP_UNAVAILABLE) { throw new RateLimitException(); } else if (status == HttpURLConnection.HTTP_MOVED_TEMP || status == HttpURLConnection.HTTP_MOVED_PERM || status == 307 /* HTTP/1.1 TEMPORARY REDIRECT */ || status == HttpURLConnection.HTTP_SEE_OTHER) { // We've been redirected, follow the new URL final String followUrl = urlConnection.getHeaderField("Location"); Log.e(TAG, "Redirected to: " + followUrl); return getBytes(followUrl, "", cached); } else { Log.e(TAG, "Error when fetching: " + formattedUrl + " (" + urlConnection.getResponseCode() + ")"); return new byte[]{}; } } finally { urlConnection.disconnect(); } } }