package com.rafali.flickruploader;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.MalformedURLException;
import java.net.SocketTimeoutException;
import java.net.URL;
import java.nio.charset.Charset;
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.Future;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.google.appengine.api.urlfetch.FetchOptions;
import com.google.appengine.api.urlfetch.HTTPHeader;
import com.google.appengine.api.urlfetch.HTTPMethod;
import com.google.appengine.api.urlfetch.HTTPRequest;
import com.google.appengine.api.urlfetch.HTTPResponse;
import com.google.appengine.api.urlfetch.URLFetchService;
import com.google.appengine.api.urlfetch.URLFetchServiceFactory;
import com.google.common.base.Joiner;
import com.rafali.common.Base64UrlSafe;
public class HttpClientGAE {
public static final String POSTPROXY_PHP = "http://log.pictarine.com/postproxy.php";
private static final Logger logger = LoggerFactory.getLogger(HttpClientGAE.class.getPackage().getName());
private static final Charset UTF8 = Charset.forName("UTF-8");
private HttpClientGAE() {
}
public static String getResponseDELETE(String url, Map<String, String> params, Map<String, String> headers) {
int retry = 0;
while (retry < 3) {
long start = System.currentTimeMillis();
try {
URLFetchService fetcher = URLFetchServiceFactory.getURLFetchService();
String urlStr = ToolString.toUrl(url.trim(), params);
logger.debug("DELETE : " + urlStr);
HTTPRequest httpRequest = new HTTPRequest(new URL(urlStr), HTTPMethod.DELETE, FetchOptions.Builder.withDeadline(deadline));
HTTPResponse response = fetcher.fetch(httpRequest);
return processResponse(response);
} catch (Throwable e) {
retry++;
if (e instanceof RuntimeException) {
throw (RuntimeException) e;
} else if (retry < 3) {
logger.warn("retrying after " + (System.currentTimeMillis() - start) + " and " + retry + " retries\n" + e.getClass() + e.getMessage());
} else {
logger.error(e.getClass() + "\n" + ToolString.stack2string(e));
}
}
}
return null;
}
public static String getResponsePUT(String url, Map<String, String> params, String json, Map<String, String> headers) {
int retry = 0;
while (retry < 3) {
long start = System.currentTimeMillis();
try {
URLFetchService fetcher = URLFetchServiceFactory.getURLFetchService();
String urlStr = ToolString.toUrl(url.trim(), params);
logger.debug("PUT : " + urlStr);
HTTPRequest httpRequest = new HTTPRequest(new URL(urlStr), HTTPMethod.PUT, FetchOptions.Builder.withDeadline(deadline));
if (headers != null) {
for (String header : headers.keySet()) {
httpRequest.addHeader(new HTTPHeader(header, headers.get(header)));
}
}
httpRequest.setPayload(json.getBytes());
HTTPResponse response = fetcher.fetch(httpRequest);
return processResponse(response);
} catch (Throwable e) {
retry++;
if (e instanceof RuntimeException) {
throw (RuntimeException) e;
} else if (retry < 3) {
logger.warn("retrying after " + (System.currentTimeMillis() - start) + " and " + retry + " retries\n" + e.getClass() + e.getMessage());
} else {
logger.error(e.getClass() + "\n" + ToolString.stack2string(e));
}
}
}
return null;
}
public static String getResponseGET(String url) {
return getResponseGET(url, null, null);
}
public static String getResponseGET(String url, Map<String, String> params) {
return getResponseGET(url, params, null);
}
public static String getResponseGET(String url, Map<String, String> params, Map<String, String> headers) {
int retry = 0;
while (retry < 3) {
long start = System.currentTimeMillis();
try {
URLFetchService fetcher = URLFetchServiceFactory.getURLFetchService();
String urlStr = ToolString.toUrl(url.trim(), params);
HTTPRequest httpRequest = new HTTPRequest(new URL(urlStr), HTTPMethod.GET, FetchOptions.Builder.withDeadline(deadline));
if (headers != null) {
for (String name : headers.keySet()) {
httpRequest.addHeader(new HTTPHeader(name, headers.get(name)));
}
}
return processResponse(fetcher.fetch(httpRequest));
} catch (Throwable e) {
retry++;
if (e instanceof RuntimeException) {
throw (RuntimeException) e;
} else if (retry < 3) {
logger.warn("retrying after " + (System.currentTimeMillis() - start) + " and " + retry + " retries\n" + e.getClass() + e.getMessage());
} else {
logger.error(e.getClass() + "\n" + ToolString.stack2string(e));
}
}
}
return null;
}
public static String processResponse(HTTPResponse response) {
String content = new String(response.getContent(), UTF8);
if (response.getResponseCode() >= 400) {
throw new RuntimeException("HttpError:" + response.getResponseCode() + "\n" + content);
}
return content;
}
public static String getResponseProxyPOST(URL url) throws MalformedURLException, UnsupportedEncodingException, IOException {
URLFetchService fetcher = URLFetchServiceFactory.getURLFetchService();
String base64payload = "base64url=" + Base64UrlSafe.encodeServer(url.toString());
String urlStr = url.toString();
if (urlStr.contains("?")) {
base64payload = "base64url=" + Base64UrlSafe.encodeServer(urlStr.substring(0, urlStr.indexOf("?")));
base64payload += "&base64content=" + Base64UrlSafe.encodeServer(urlStr.substring(urlStr.indexOf("?") + 1));
} else {
base64payload = "base64url=" + Base64UrlSafe.encodeServer(urlStr);
}
HTTPRequest httpRequest = new HTTPRequest(new URL(HttpClientGAE.POSTPROXY_PHP), HTTPMethod.POST, FetchOptions.Builder.withDeadline(30d).doNotValidateCertificate());
httpRequest.setPayload(base64payload.getBytes(UTF8));
HTTPResponse response = fetcher.fetch(httpRequest);
String processResponse = HttpClientGAE.processResponse(response);
logger.info("proxying " + url + "\nprocessResponse:" + processResponse);
return processResponse;
}
public static String getResponsePOST(String url, Map<String, String> params) {
return getResponsePOST(url, null, params, null);
}
public static double deadline = 50d;
public static String getResponsePOST(String url, Map<String, String> headers, Map<String, String> params, String content) {
return getResponsePOST(url, headers, params, content, deadline);
}
public static String getResponsePOST(String url, Map<String, String> headers, Map<String, String> params, String content, double timeoutSeconds) {
int retry = 0;
Throwable previousException = null;
while (retry < 3) {
long start = System.currentTimeMillis();
try {
URLFetchService fetcher = URLFetchServiceFactory.getURLFetchService();
HTTPRequest httpRequest;
String urlStr;
if (content == null) {
urlStr = url;
} else {
urlStr = ToolString.toUrl(url.trim(), params);
}
String base64payload = null;
if (previousException instanceof SocketTimeoutException) {
base64payload = "base64url=" + Base64UrlSafe.encodeServer(urlStr);
urlStr = POSTPROXY_PHP;
if (content != null) {
base64payload += "&base64content=" + Base64UrlSafe.encodeServer(content);
}
logger.info("proxy call : " + urlStr + "\n" + base64payload);
}
httpRequest = new HTTPRequest(new URL(urlStr), HTTPMethod.POST, FetchOptions.Builder.withDeadline(timeoutSeconds).doNotValidateCertificate());
if (base64payload != null) {
httpRequest.setPayload(base64payload.getBytes(UTF8));
} else if (content == null) {
if (params != null) {
String paramStr = Joiner.on("&").withKeyValueSeparator("=").useForNull("null").join(params);
httpRequest.setPayload(paramStr.getBytes(UTF8));
logger.debug(paramStr);
}
} else {
httpRequest.setPayload(content.getBytes(UTF8));
}
if (headers != null) {
for (String header : headers.keySet()) {
httpRequest.addHeader(new HTTPHeader(header, headers.get(header)));
}
}
HTTPResponse response = fetcher.fetch(httpRequest);
return processResponse(response);
} catch (Throwable e) {
retry++;
previousException = e;
if (e instanceof RuntimeException) {
throw (RuntimeException) e;
} else if (retry < 3) {
logger.warn("retrying after " + (System.currentTimeMillis() - start) + " and " + retry + " retries\n" + e.getClass() + " : " + e.getMessage());
} else {
logger.error(e.getClass() + "\n" + ToolString.stack2string(e));
}
}
}
return null;
}
// public String getResponsePOST(String url, Map<String, String> params, String json, Map<String, String> headers) {
// int retry = 0;
// while (retry < 3) {
// long start = System.currentTimeMillis();
// try {
// URLFetchService fetcher = URLFetchServiceFactory.getURLFetchService();
// String urlStr = ToolString.toUrl(url.trim(), params);
// logger.debug("POST : " + urlStr);
// HTTPRequest httpRequest = new HTTPRequest(new URL(urlStr), HTTPMethod.POST, FetchOptions.Builder.withDeadline(50d));
// if (headers != null) {
// for (String header : headers.keySet()) {
// httpRequest.addHeader(new HTTPHeader(header, headers.get(header)));
// }
// }
// httpRequest.setPayload(json.getBytes());
// HTTPResponse response = fetcher.fetch(httpRequest);
// return processResponse(response);
// } catch (Throwable e) {
// retry++;
// if (e instanceof RuntimeException) {
// throw (RuntimeException) e;
// } else if (retry < 3) {
// logger.warn("retrying after " + (System.currentTimeMillis() - start) + " and " + retry + " retries\n" + e.getClass() + e.getMessage());
// } else {
// logger.error(e.getClass() + "\n" + ToolException.stack2string(e));
// }
// }
// }
// return null;
// }
public static Map<String, String> getResponses(Collection<String> urls) {
Map<String, String> responses = new HashMap<String, String>();
URLFetchService fetcher = URLFetchServiceFactory.getURLFetchService();
Map<String, Future<HTTPResponse>> futures = new HashMap<String, Future<HTTPResponse>>();
try {
for (String url : urls) {
HTTPRequest httpRequest = new HTTPRequest(new URL(url), HTTPMethod.GET, FetchOptions.Builder.withDeadline(deadline));
Future<HTTPResponse> future = fetcher.fetchAsync(httpRequest);
futures.put(url, future);
}
} catch (MalformedURLException e) {
logger.error(e.getClass() + "\n" + ToolString.stack2string(e));
}
for (String url : urls) {
Future<HTTPResponse> future = futures.get(url);
try {
HTTPResponse httpResponse = future.get();
responses.put(url, new String(httpResponse.getContent(), UTF8));
} catch (Exception e) {
logger.error(e.getClass() + "\n" + ToolString.stack2string(e));
}
}
return responses;
}
public static String getResponseProxyGET(URL url) {
String urlproxy;
String urlStr = url.toString();
if (urlStr.contains("?")) {
urlproxy = "http://log.pictarine.com/getproxy.php?base64url=" + Base64UrlSafe.encodeServer(urlStr.substring(0, urlStr.indexOf("?"))) + "&base64query="
+ Base64UrlSafe.encodeServer(urlStr.substring(urlStr.indexOf("?") + 1));
} else {
urlproxy = "http://log.pictarine.com/getproxy.php?base64url=" + Base64UrlSafe.encodeServer(urlStr);
}
String responseGET = getResponseGET(urlproxy);
logger.info("urlproxy : " + urlproxy + "\nresponseGET : " + responseGET);
return responseGET;
}
}