package org.lodder.subtools.sublibrary.util.http;
import java.io.ByteArrayInputStream;
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLConnection;
import java.net.URLEncoder;
import java.util.Map;
import java.util.Map.Entry;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.zip.GZIPInputStream;
import org.apache.commons.io.IOUtils;
import org.apache.commons.io.input.BOMInputStream;
import org.lodder.subtools.sublibrary.util.Files;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class HttpClient {
private CookieManager cookieManager;
private static final Logger LOGGER = LoggerFactory.getLogger(HttpClient.class);
public HttpClient() {
}
public void setCookieManager(CookieManager cookieManager) {
this.cookieManager = cookieManager;
}
public void validate() throws HttpClientSetupException {
if (cookieManager == null)
throw new HttpClientSetupException("CookieManager is not initialized");
}
public String doGet(URL url, String userAgent) throws IOException, HttpClientException, HttpClientSetupException {
validate();
URLConnection conn = null;
conn = url.openConnection();
cookieManager.setCookies(conn);
if (userAgent != null && userAgent.length() > 0)
conn.setRequestProperty("user-agent", userAgent);
int respCode = ((HttpURLConnection) conn).getResponseCode();
if (respCode == 200) {
String result = IOUtils.toString(conn.getInputStream());
((HttpURLConnection) conn).disconnect();
return result;
}
throw new HttpClientException((HttpURLConnection) conn);
}
public String doPost(URL url, String userAgent, Map<String, String> data)
throws HttpClientSetupException, HttpClientException {
validate();
HttpURLConnection conn = null;
StringBuilder urlParameters = new StringBuilder();
try {
for (Entry<String, String> entry : data.entrySet()) {
if (urlParameters.length() > 0)
urlParameters.append("&");
urlParameters.append(entry.getKey()).append("=").append(URLEncoder.encode(entry.getValue(), "UTF-8"));
}
conn = (HttpURLConnection) url.openConnection();
cookieManager.setCookies(conn);
conn.setRequestMethod("POST");
if (userAgent.length() > 0)
conn.setRequestProperty("user-agent", userAgent);
conn.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
conn.setRequestProperty("Content-Length",
"" + Integer.toString(urlParameters.toString().getBytes("UTF-8").length));
conn.setUseCaches(false);
conn.setDoInput(true);
conn.setDoOutput(true);
conn.setInstanceFollowRedirects(false);
try (DataOutputStream out = new DataOutputStream(conn.getOutputStream())) {
out.writeBytes(urlParameters.toString());
out.flush();
out.close();
}
cookieManager.storeCookies(conn);
if (conn.getResponseCode() == 302) {
if (isUrl(conn.getHeaderField("Location"))) {
return doGet(new URL(conn.getHeaderField("Location")), userAgent);
}
}
String result = IOUtils.toString(conn.getInputStream());
((HttpURLConnection) conn).disconnect();
return result;
} catch (UnsupportedEncodingException e) {
throw new HttpClientException(e, null);
} catch (IOException e) {
throw new HttpClientException(e, conn);
} finally {
if (conn != null) {
conn.disconnect();
}
}
}
public boolean doDownloadFile(URL url, final File file) {
LOGGER.debug("doDownloadFile: URL [{}], file [{}]", url, file);
boolean success = true;
InputStream in = null;
try {
if (url.getFile().endsWith(".gz")) {
in = new GZIPInputStream(url.openStream());
} else {
in = getInputStream(url);
}
byte[] data = IOUtils.toByteArray(in);
in.close();
if (url.getFile().endsWith(".zip") || Files.isZipFile(new ByteArrayInputStream(data))) {
Files.unzip(new ByteArrayInputStream(data), file, ".srt");
} else {
if (Files.isGZipCompressed(data)) {
data = Files.decompressGZip(data);
}
String content = new String(data, "UTF-8");
if (content.contains("Daily Download count exceeded")) {
LOGGER.error("Download problem: Addic7ed Daily Download count exceeded!");
success = false;
} else {
try (FileOutputStream outputStream = new FileOutputStream(file)) {
IOUtils.write(data, outputStream);
}
}
}
} catch (Exception e) {
success = false;
LOGGER.error("Download problem", e);
} finally {
if (in != null)
try {
in.close();
} catch (IOException e) {
success = false;
LOGGER.error("Download problem", e);
}
}
return success;
}
private InputStream getInputStream(URL url) throws Exception {
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
cookieManager.setCookies(conn);
conn.addRequestProperty("User-Agent", "Mozilla");
conn.addRequestProperty("Referer", url.toString());
conn.setInstanceFollowRedirects(false);
int status = conn.getResponseCode();
cookieManager.storeCookies(conn);
if (status != HttpURLConnection.HTTP_OK) {
if (status == HttpURLConnection.HTTP_MOVED_TEMP || status == HttpURLConnection.HTTP_MOVED_PERM
|| status == HttpURLConnection.HTTP_SEE_OTHER) {
if (HttpClient.isUrl(conn.getHeaderField("Location"))) {
url = new URL(conn.getHeaderField("Location"));
} else {
String protocol = url.getProtocol();
String host = conn.getURL().getHost();
url = new URL(protocol + "://" + host + "/"
+ conn.getHeaderField("Location").trim().replaceAll(" ", "%20"));
}
return getInputStream(url);
}
throw new Exception("error: " + status);
} else {
return conn.getInputStream();
}
}
public static boolean isUrl(String str) {
Pattern urlPattern = Pattern.compile(
"((https?|ftp|gopher|telnet|file):((//)|(\\\\\\\\))+[\\\\w\\\\d:#@%/;$()~_?\\\\+-=\\\\\\\\\\\\.&]*)",
Pattern.CASE_INSENSITIVE);
Matcher matcher = urlPattern.matcher(str);
return matcher.find();
}
public String downloadText(URL url) throws IOException {
String html = IOUtils.toString(url.openConnection().getInputStream());
String content = "";
try (BOMInputStream bomIn = new BOMInputStream(IOUtils.toInputStream(html))) {
content = IOUtils.toString(bomIn);
}
return content;
}
}