package com.xiaomi.xms.sales.xmsf.account.utils;
import com.xiaomi.xms.sales.util.LogUtil;
import com.xiaomi.xms.sales.xmsf.account.exception.AccessDeniedException;
import org.apache.http.NameValuePair;
import org.apache.http.client.utils.URLEncodedUtils;
import org.json.JSONException;
import org.json.JSONObject;
import java.io.BufferedOutputStream;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.CookieManager;
import java.net.HttpCookie;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.ProtocolException;
import java.net.URI;
import java.net.URL;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
public final class SimpleRequest {
private static final String TAG = "SimpleRequest";
private static final String ENC = "utf-8";
private static final int TIMEOUT = 30000;
protected static String appendUrl(String origin,
List<NameValuePair> nameValuePairs) {
if (origin == null) {
throw new NullPointerException("origin is not allowed null");
}
StringBuilder urlBuilder = new StringBuilder(origin);
if (nameValuePairs != null) {
final String paramPart = URLEncodedUtils
.format(nameValuePairs, ENC);
if (paramPart != null && paramPart.length() > 0) {
if (origin.contains("?")) {
urlBuilder.append("&");
} else {
urlBuilder.append("?");
}
urlBuilder.append(paramPart);
}
}
return urlBuilder.toString();
}
public static StringContent getAsString(String url,
Map<String, String> params, Map<String, String> cookies,
boolean readBody) throws IOException, AccessDeniedException {
List<NameValuePair> nameValuePairs = ObjectUtils.mapToPairs(params);
final String fullUrl = appendUrl(url, nameValuePairs);
LogUtil.d(TAG, "requesting " + fullUrl);
HttpURLConnection conn = makeConn(fullUrl, cookies);
if (conn == null) {
LogUtil.e(TAG, "failed to create URLConnection");
return null;
}
try {
conn.setDoInput(true);
conn.setRequestMethod("GET");
conn.connect();
int code = conn.getResponseCode();
if (code == HttpURLConnection.HTTP_OK
|| code == HttpURLConnection.HTTP_MOVED_TEMP) {
final Map<String, List<String>> headerFields = conn
.getHeaderFields();
final CookieManager cm = new CookieManager();
final URI reqUri = URI.create(fullUrl);
cm.put(reqUri, headerFields);
List<HttpCookie> httpCookies = cm.getCookieStore().get(reqUri);
Map<String, String> cookieMap = parseCookies(httpCookies);
cookieMap.putAll(ObjectUtils.listToMap(headerFields));
StringBuilder sb = new StringBuilder();
if (readBody) {
BufferedReader br = new BufferedReader(
new InputStreamReader(conn.getInputStream()), 1024);
try {
String line;
while ((line = br.readLine()) != null) {
sb.append(line);
}
} catch (IOException e) {
e.printStackTrace();
} finally {
br.close();
}
}
final StringContent stringContent = new StringContent(
sb.toString());
stringContent.putHeaders(cookieMap);
return stringContent;
} else if (code == HttpURLConnection.HTTP_FORBIDDEN) {
throw new AccessDeniedException(
"access denied, encrypt error or user is forbidden to access the resource");
} else {
LogUtil.e(TAG, "http status error when GET: " + code);
}
} catch (ProtocolException e) {
throw new IOException("protocol error");
} finally {
conn.disconnect();
}
return null;
}
public static MapContent getAsMap(String url,
Map<String, String> params, Map<String, String> cookies,
boolean readBody) throws IOException, AccessDeniedException {
StringContent stringContent = getAsString(url, params, cookies,
readBody);
return convertStringToMap(stringContent);
}
public static StringContent postAsString(String url,
Map<String, String> params, Map<String, String> cookies,
boolean readBody) throws IOException, AccessDeniedException {
LogUtil.d(TAG, "requesting " + url);
HttpURLConnection conn = makeConn(url, cookies);
if (conn == null) {
LogUtil.e(TAG, "failed to create URLConnection");
return null;
}
try {
conn.setDoInput(true);
conn.setDoOutput(true);
conn.setRequestMethod("POST");
conn.connect();
List<NameValuePair> nameValuePairs = ObjectUtils.mapToPairs(params);
if (nameValuePairs != null) {
String content = URLEncodedUtils.format(nameValuePairs, ENC);
OutputStream os = conn.getOutputStream();
BufferedOutputStream bos = new BufferedOutputStream(os);
try {
bos.write(content.getBytes(ENC));
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
bos.flush();
bos.close();
} catch (IOException e) {
// ignore
}
}
}
int code = conn.getResponseCode();
if (code == HttpURLConnection.HTTP_OK
|| code == HttpURLConnection.HTTP_MOVED_TEMP) {
final Map<String, List<String>> headerFields = conn
.getHeaderFields();
final CookieManager cm = new CookieManager();
final URI reqUri = URI.create(url);
cm.put(reqUri, headerFields);
Map<String, String> cookieMap = parseCookies(
cm.getCookieStore().get(reqUri));
cookieMap.putAll(ObjectUtils.listToMap(headerFields));
StringBuilder sb = new StringBuilder();
if (readBody) {
BufferedReader br = new BufferedReader(
new InputStreamReader(conn.getInputStream()),
1024);
try {
String line;
while ((line = br.readLine()) != null) {
sb.append(line);
}
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
br.close();
} catch (IOException e) {
// ignore
}
}
}
final StringContent stringContent = new StringContent(
sb.toString());
stringContent.putHeaders(cookieMap);
return stringContent;
} else if (code == HttpURLConnection.HTTP_FORBIDDEN) {
throw new AccessDeniedException(
"access denied, encrypt error or user is forbidden to access the resource");
} else {
LogUtil.e(TAG, "http status error when POST: " + code);
}
} catch (ProtocolException e) {
throw new IOException("protocol error");
} finally {
conn.disconnect();
}
return null;
}
public static MapContent postAsMap(String url,
Map<String, String> params, Map<String, String> cookies,
boolean readBody) throws IOException, AccessDeniedException {
StringContent stringContent = postAsString(url, params, cookies,
readBody);
return convertStringToMap(stringContent);
}
protected static MapContent convertStringToMap(StringContent stringContent) {
if (stringContent == null) {
return null;
}
String bodyString = stringContent.getBody();
JSONObject jsonObject = null;
try {
jsonObject = new JSONObject(bodyString);
} catch (JSONException e) {
e.printStackTrace();
}
Map<String, Object> contentMap = ObjectUtils
.jsonToMap(jsonObject);
MapContent mapContent = new MapContent(contentMap);
mapContent.putHeaders(stringContent.getHeaders());
return mapContent;
}
protected static HttpURLConnection makeConn(String url,
Map<String, String> cookies) {
URL req = null;
try {
req = new URL(url);
} catch (MalformedURLException e) {
e.printStackTrace();
}
if (req == null) {
LogUtil.e(TAG, "failed to init url");
return null;
}
try {
HttpURLConnection conn = (HttpURLConnection) req.openConnection();
conn.setInstanceFollowRedirects(false);
conn.setConnectTimeout(TIMEOUT);
conn.setUseCaches(false);
conn.setRequestProperty("Content-Type",
"application/x-www-form-urlencoded");
if (cookies != null) {
conn.setRequestProperty("Cookie", joinMap(cookies, "; "));
}
return conn;
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
protected static String joinMap(Map<String, String> map, String sp) {
if (map == null) {
return null;
}
StringBuilder sb = new StringBuilder();
Set<Map.Entry<String, String>> entries = map.entrySet();
int i = 0;
for (Map.Entry<String, String> entry : entries) {
if (i > 0) {
sb.append(sp);
}
final String key = entry.getKey();
final String value = entry.getValue();
sb.append(key);
sb.append("=");
sb.append(value);
i++;
}
return sb.toString();
}
protected static Map<String, String> parseCookies(
List<HttpCookie> cookies) {
Map<String, String> cookieMap = new HashMap<String, String>();
for (HttpCookie cookie : cookies) {
if (!cookie.hasExpired()) {
final String name = cookie.getName();
final String value = cookie.getValue();
if (name != null) {
cookieMap.put(name, value);
}
} else {
LogUtil.d(TAG, "cookie has expired, key:" + cookie.getName());
}
}
return cookieMap;
}
public static class HeaderContent {
private final Map<String, String> headers
= new HashMap<String, String>();
public void putHeader(String key, String value) {
headers.put(key, value);
}
public String getHeader(String key) {
return headers.get(key);
}
public Map<String, String> getHeaders() {
return headers;
}
public void putHeaders(Map<String, String> headers) {
this.headers.putAll(headers);
}
@Override
public String toString() {
return "HeaderContent{" +
"headers=" + headers +
'}';
}
}
public static class StringContent extends HeaderContent {
private String body;
public StringContent(String body) {
this.body = body;
}
public String getBody() {
return body;
}
@Override
public String toString() {
return "StringContent{" +
"body='" + body + '\'' +
'}';
}
}
public static class MapContent extends HeaderContent {
private Map<String, Object> bodies;
public MapContent(Map<String, Object> bodies) {
this.bodies = bodies;
}
public Object getFromBody(String key) {
return bodies.get(key);
}
@Override
public String toString() {
return "MapContent{" +
"bodies=" + bodies +
'}';
}
}
public static class StreamContent extends HeaderContent {
private InputStream stream;
public StreamContent(InputStream stream) {
this.stream = stream;
}
public InputStream getStream() {
return stream;
}
}
}