NewPipe/app/src/main/java/org/schabi/newpipe/Downloader.java

281 lines
9.8 KiB
Java
Raw Normal View History

2015-09-04 00:15:03 +00:00
package org.schabi.newpipe;
import android.support.annotation.Nullable;
import android.text.TextUtils;
2018-09-26 22:50:57 +00:00
import org.schabi.newpipe.extractor.DownloadRequest;
2018-09-02 23:22:59 +00:00
import org.schabi.newpipe.extractor.DownloadResponse;
import org.schabi.newpipe.extractor.exceptions.ReCaptchaException;
import org.schabi.newpipe.extractor.utils.Localization;
2016-12-07 18:22:27 +00:00
import java.io.IOException;
2018-02-22 12:25:56 +00:00
import java.io.InputStream;
2018-09-02 23:22:59 +00:00
import java.io.Serializable;
import java.util.Collections;
import java.util.HashMap;
2018-09-02 23:22:59 +00:00
import java.util.List;
import java.util.Map;
2018-02-20 15:24:43 +00:00
import java.util.concurrent.TimeUnit;
2015-09-04 00:15:03 +00:00
2018-09-02 23:22:59 +00:00
import okhttp3.MediaType;
2018-02-20 15:24:43 +00:00
import okhttp3.OkHttpClient;
import okhttp3.Request;
2018-09-02 23:22:59 +00:00
import okhttp3.RequestBody;
2018-02-20 15:24:43 +00:00
import okhttp3.Response;
import okhttp3.ResponseBody;
2015-12-24 13:55:33 +00:00
/*
* Created by Christian Schabesberger on 28.01.16.
2015-09-04 00:15:03 +00:00
*
2016-01-28 22:27:16 +00:00
* Copyright (C) Christian Schabesberger 2016 <chris.schabesberger@mailbox.org>
2015-09-04 00:15:03 +00:00
* Downloader.java is part of NewPipe.
*
* NewPipe 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.
*
* NewPipe 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 NewPipe. If not, see <http://www.gnu.org/licenses/>.
*/
2016-02-18 10:50:22 +00:00
public class Downloader implements org.schabi.newpipe.extractor.Downloader {
public static final String USER_AGENT = "Mozilla/5.0 (Windows NT 6.1; WOW64; rv:43.0) Gecko/20100101 Firefox/43.0";
2015-09-04 00:15:03 +00:00
private static Downloader instance;
private String mCookies;
private final OkHttpClient client;
2016-12-07 21:09:24 +00:00
private Downloader(OkHttpClient.Builder builder) {
this.client = builder
.readTimeout(30, TimeUnit.SECONDS)
//.cache(new Cache(new File(context.getExternalCacheDir(), "okhttp"), 16 * 1024 * 1024))
.build();
}
2018-02-20 15:24:43 +00:00
/**
* It's recommended to call exactly once in the entire lifetime of the application.
*
* @param builder if null, default builder will be used
*/
public static Downloader init(@Nullable OkHttpClient.Builder builder) {
return instance = new Downloader(builder != null ? builder : new OkHttpClient.Builder());
}
2016-12-07 21:09:24 +00:00
public static Downloader getInstance() {
return instance;
}
public String getCookies() {
return mCookies;
2016-12-07 21:16:28 +00:00
}
public void setCookies(String cookies) {
mCookies = cookies;
2016-12-07 21:16:28 +00:00
}
2018-04-08 11:08:19 +00:00
/**
* Get the size of the content that the url is pointing by firing a HEAD request.
*
* @param url an url pointing to the content
* @return the size of the content, in bytes
*/
public long getContentLength(String url) throws IOException {
Response response = null;
try {
final Request request = new Request.Builder()
.head().url(url)
.addHeader("User-Agent", USER_AGENT)
.build();
response = client.newCall(request).execute();
String contentLength = response.header("Content-Length");
return contentLength == null ? -1 : Long.parseLong(contentLength);
2018-04-08 11:08:19 +00:00
} catch (NumberFormatException e) {
throw new IOException("Invalid content length", e);
} finally {
if (response != null) {
response.close();
}
}
}
/**
* Download the text file at the supplied URL as in download(String),
* but set the HTTP header field "Accept-Language" to the supplied string.
*
* @param siteUrl the URL of the text file to return the contents of
2018-10-22 10:25:50 +00:00
* @param localization the language and country (usually a 2-character code) to set
* @return the contents of the specified text file
*/
@Override
2018-10-22 10:25:50 +00:00
public String download(String siteUrl, Localization localization) throws IOException, ReCaptchaException {
Map<String, String> requestProperties = new HashMap<>();
2018-10-22 10:25:50 +00:00
requestProperties.put("Accept-Language", localization.getLanguage());
return download(siteUrl, requestProperties);
}
/**
* Download the text file at the supplied URL as in download(String),
* but set the HTTP headers included in the customProperties map.
*
* @param siteUrl the URL of the text file to return the contents of
* @param customProperties set request header properties
* @return the contents of the specified text file
* @throws IOException
*/
@Override
public String download(String siteUrl, Map<String, String> customProperties) throws IOException, ReCaptchaException {
2018-02-22 12:25:56 +00:00
return getBody(siteUrl, customProperties).string();
}
public InputStream stream(String siteUrl) throws IOException {
try {
return getBody(siteUrl, Collections.emptyMap()).byteStream();
} catch (ReCaptchaException e) {
throw new IOException(e.getMessage(), e.getCause());
}
}
private ResponseBody getBody(String siteUrl, Map<String, String> customProperties) throws IOException, ReCaptchaException {
final Request.Builder requestBuilder = new Request.Builder()
2018-09-02 23:22:59 +00:00
.method("GET", null).url(siteUrl);
2018-02-20 15:24:43 +00:00
for (Map.Entry<String, String> header : customProperties.entrySet()) {
requestBuilder.addHeader(header.getKey(), header.getValue());
}
2018-09-02 23:22:59 +00:00
if (!customProperties.containsKey("User-Agent")) {
requestBuilder.header("User-Agent", USER_AGENT);
}
if (!TextUtils.isEmpty(mCookies)) {
requestBuilder.addHeader("Cookie", mCookies);
2018-02-20 15:24:43 +00:00
}
final Request request = requestBuilder.build();
final Response response = client.newCall(request).execute();
final ResponseBody body = response.body();
2018-02-20 15:24:43 +00:00
if (response.code() == 429) {
throw new ReCaptchaException("reCaptcha Challenge requested");
}
if (body == null) {
response.close();
return null;
}
2018-02-22 12:25:56 +00:00
return body;
}
/**
* Download (via HTTP) the text file located at the supplied URL, and return its contents.
* Primarily intended for downloading web pages.
*
* @param siteUrl the URL of the text file to download
* @return the contents of the specified text file
*/
@Override
public String download(String siteUrl) throws IOException, ReCaptchaException {
return download(siteUrl, Collections.emptyMap());
2015-09-04 00:15:03 +00:00
}
2018-09-02 23:22:59 +00:00
@Override
2018-09-26 22:50:57 +00:00
public DownloadResponse get(String siteUrl, DownloadRequest request) throws IOException, ReCaptchaException {
2018-09-02 23:22:59 +00:00
final Request.Builder requestBuilder = new Request.Builder()
.method("GET", null).url(siteUrl);
2018-09-26 22:50:57 +00:00
Map<String, List<String>> requestHeaders = request.getRequestHeaders();
2018-09-02 23:22:59 +00:00
// set custom headers in request
for (Map.Entry<String, List<String>> pair : requestHeaders.entrySet()) {
for(String value : pair.getValue()){
requestBuilder.addHeader(pair.getKey(), value);
}
}
if (!requestHeaders.containsKey("User-Agent")) {
requestBuilder.header("User-Agent", USER_AGENT);
}
if (!TextUtils.isEmpty(mCookies)) {
requestBuilder.addHeader("Cookie", mCookies);
}
2018-09-26 22:50:57 +00:00
final Request okRequest = requestBuilder.build();
final Response response = client.newCall(okRequest).execute();
2018-09-02 23:22:59 +00:00
final ResponseBody body = response.body();
if (response.code() == 429) {
throw new ReCaptchaException("reCaptcha Challenge requested");
}
if (body == null) {
response.close();
return null;
}
return new DownloadResponse(body.string(), response.headers().toMultimap());
}
@Override
public DownloadResponse get(String siteUrl) throws IOException, ReCaptchaException {
2018-09-26 22:50:57 +00:00
return get(siteUrl, DownloadRequest.emptyRequest);
2018-09-02 23:22:59 +00:00
}
@Override
2018-09-26 22:50:57 +00:00
public DownloadResponse post(String siteUrl, DownloadRequest request) throws IOException, ReCaptchaException {
2018-09-02 23:22:59 +00:00
2018-09-26 22:50:57 +00:00
Map<String, List<String>> requestHeaders = request.getRequestHeaders();
2018-09-02 23:22:59 +00:00
if(null == requestHeaders.get("Content-Type") || requestHeaders.get("Content-Type").isEmpty()){
// content type header is required. maybe throw an exception here
return null;
}
String contentType = requestHeaders.get("Content-Type").get(0);
2018-09-26 22:50:57 +00:00
RequestBody okRequestBody = null;
if(null != request.getRequestBody()){
okRequestBody = RequestBody.create(MediaType.parse(contentType), request.getRequestBody());
}
2018-09-02 23:22:59 +00:00
final Request.Builder requestBuilder = new Request.Builder()
.method("POST", okRequestBody).url(siteUrl);
// set custom headers in request
for (Map.Entry<String, List<String>> pair : requestHeaders.entrySet()) {
for(String value : pair.getValue()){
requestBuilder.addHeader(pair.getKey(), value);
}
}
if (!requestHeaders.containsKey("User-Agent")) {
requestBuilder.header("User-Agent", USER_AGENT);
}
if (!TextUtils.isEmpty(mCookies)) {
requestBuilder.addHeader("Cookie", mCookies);
}
2018-09-26 22:50:57 +00:00
final Request okRequest = requestBuilder.build();
final Response response = client.newCall(okRequest).execute();
2018-09-02 23:22:59 +00:00
final ResponseBody body = response.body();
if (response.code() == 429) {
throw new ReCaptchaException("reCaptcha Challenge requested");
}
if (body == null) {
response.close();
return null;
}
return new DownloadResponse(body.string(), response.headers().toMultimap());
}
}