giList, long timeStamp);
}
-
private final class GetPopularHelper extends SimpleBgJobHelper {
private OnGetPopularListener mListener;
@@ -283,4 +311,64 @@ public final class EhClient {
public void getPopular(OnGetPopularListener listener) {
doBgJob(new GetPopularHelper(listener));
}
+
+
+ private String doSignIn(String username, String password) throws Exception {
+ RequestBody formBody = new FormEncodingBuilder()
+ .add("UserName", username)
+ .add("PassWord", password)
+ .add("submit", "Log me in")
+ .add("CookieDate", "1")
+ .add("temporary_https", "off")
+ .build();
+
+ Request request = new Request.Builder()
+ .url(SIGN_IN_URL)
+ .post(formBody)
+ .build();
+ Response response = mHttpClient.newCall(request).execute();
+
+ checkResponse(response);
+
+ SignInParser parser = new SignInParser();
+ parser.parse(response.body().string());
+ return parser.displayname;
+ }
+
+ public abstract static class OnSignInListener implements SimpleListener {
+ public abstract void onSuccess(String displayname);
+ }
+
+ private final class SignInHelper extends SimpleBgJobHelper {
+
+ private String mUsername;
+ private String mPassword;
+ private OnSignInListener mListener;
+
+ private String mDisplayname;
+
+ public SignInHelper(String username, String password, OnSignInListener listener) {
+ super(listener);
+ mUsername = username;
+ mPassword = password;
+ mListener = listener;
+ }
+
+ @Override
+ public void doBgJob() throws Exception {
+ mDisplayname = doSignIn(mUsername, mPassword);
+ }
+
+ @Override
+ public void doSuccessCallback() {
+ mListener.onSuccess(mDisplayname);
+ }
+ }
+
+ /**
+ * Sign in
+ */
+ public void signIn(String username, String password, OnSignInListener listener) {
+ doBgJob(new SignInHelper(username, password, listener));
+ }
}
diff --git a/app/src/main/java/com/hippo/ehviewer/client/SignInParser.java b/app/src/main/java/com/hippo/ehviewer/client/SignInParser.java
new file mode 100644
index 000000000..68979b411
--- /dev/null
+++ b/app/src/main/java/com/hippo/ehviewer/client/SignInParser.java
@@ -0,0 +1,45 @@
+/*
+ * Copyright (C) 2015 Hippo Seven
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.hippo.ehviewer.client;
+
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+public class SignInParser {
+ public String displayname;
+
+ public boolean parse(String body) throws Exception {
+ Pattern p;
+ Matcher m;
+
+ p = Pattern.compile("You are now logged in as: (.+?)
");
+ m = p.matcher(body);
+ if (m.find()) {
+ displayname = m.group(1);
+ return true;
+ } else {
+ p = Pattern.compile("(?:
The error returned was:
\\s*(.+?)
)"
+ + "|(?:(.+?))");
+ m = p.matcher(body);
+
+ if (m.find()) {
+ throw new EhException(m.group(1) == null ? m.group(2) : m.group(1));
+ } else {
+ throw new EhException("Unknown error"); // TODO
+ }
+ }
+ }
+}
diff --git a/app/src/main/java/com/hippo/ehviewer/network/EhHttpHelper.java b/app/src/main/java/com/hippo/ehviewer/network/EhHttpHelper.java
deleted file mode 100644
index 35a2cd19f..000000000
--- a/app/src/main/java/com/hippo/ehviewer/network/EhHttpHelper.java
+++ /dev/null
@@ -1,62 +0,0 @@
-/*
- * Copyright (C) 2015 Hippo Seven
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.hippo.ehviewer.network;
-
-import android.support.annotation.NonNull;
-
-import com.hippo.network.HttpHelper;
-import com.hippo.util.Pool;
-
-import java.net.HttpURLConnection;
-import java.net.URL;
-
-public class EhHttpHelper extends HttpHelper {
-
- private static final Pool sPool = new Pool<>(10);
-
- private static String[] EHENTAI_DOMAIN = {
- "exhentai.org",
- "e-hentai.org"
- };
-
- public static @NonNull EhHttpHelper obtain() {
- EhHttpHelper ehh = sPool.obtain();
- if (ehh == null) {
- ehh = new EhHttpHelper();
- }
- return ehh;
- }
-
- public static void recycle(@NonNull EhHttpHelper ehh) {
- ehh.reset();
- sPool.recycle(ehh);
- }
-
- @Override
- protected String getCookie(URL url) {
- return super.getCookie(url);
- }
-
- @Override
- protected void storeCookie(URL url, String value) {
- super.storeCookie(url, value);
- }
-
- @Override
- protected void onBeforeConnect(HttpURLConnection conn) {
- super.onBeforeConnect(conn);
- }
-}
diff --git a/app/src/main/java/com/hippo/ehviewer/network/EhOkHttpClient.java b/app/src/main/java/com/hippo/ehviewer/network/EhOkHttpClient.java
new file mode 100644
index 000000000..c1ec61118
--- /dev/null
+++ b/app/src/main/java/com/hippo/ehviewer/network/EhOkHttpClient.java
@@ -0,0 +1,192 @@
+/*
+ * Copyright (C) 2015 Hippo Seven
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.hippo.ehviewer.network;
+
+import android.webkit.CookieManager;
+
+import com.hippo.ehviewer.util.Config;
+import com.hippo.network.Cookie;
+import com.hippo.util.MathUtils;
+import com.hippo.util.Utils;
+import com.squareup.okhttp.Interceptor;
+import com.squareup.okhttp.OkHttpClient;
+import com.squareup.okhttp.Request;
+import com.squareup.okhttp.Response;
+
+import java.io.IOException;
+import java.net.CookieHandler;
+import java.net.URI;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.TimeUnit;
+
+public class EhOkHttpClient extends OkHttpClient {
+
+ public static final String DEFAULT_USER_AGENT =
+ "Mozilla/5.0 (Windows NT 6.1; WOW64) " +
+ "AppleWebKit/537.36 (KHTML, like Gecko) " +
+ "Chrome/39.0.2171.95 Safari/537.36";
+ public static final String USER_AGENT =
+ System.getProperty("http.agent", DEFAULT_USER_AGENT);
+
+ private static String[] EHENTAI_DOMAIN = {
+ "exhentai.org",
+ "e-hentai.org"
+ };
+
+ private static final String HOST_EX = "exhentai.org";
+ private static final String HOST_LOFI = "lofi.e-hentai.org";
+
+ private static final String KEY_IPD_MEMBER_ID = "ipb_member_id";
+ private static final String KEY_IPD_PASS_HASH = "ipb_pass_hash";
+ private static final String KEY_IGNEOUS = "igneous";
+ private static final String KEY_UCONFIG = "uconfig";
+ private static final String KEY_XRES = "xres";
+ private static final String KEY_YAY = "yay";
+
+ private static CookieHandler mCookieHandler = new CookieHandler() {
+
+ private final CookieManager mCookieManager = CookieManager.getInstance();
+
+ public String getDomain(URI uri) {
+ String host = uri.getHost();
+ int length = host.length();
+ int dotCount = 0;
+ int i = length;
+ while(i-- != 0) {
+ char ch = host.charAt(i);
+ if (ch == '.') {
+ dotCount++;
+ }
+ if (dotCount == 2) {
+ // Get it
+ break;
+ }
+ }
+ return host.substring(MathUtils.clamp(i + 1, 0, length));
+ }
+
+ @Override
+ public Map> get(URI uri, Map> requestHeaders) throws IOException {
+ boolean isSignIn = Config.getSignIn();
+ String host = uri.getHost();
+ Cookie cookie = new Cookie();
+
+ if (!isSignIn && HOST_EX.equals(host)) {
+ cookie.put("yay", "louder");
+ } else {
+ cookie.putRaw(mCookieManager.getCookie(uri.toString()));
+
+ if (isSignIn && Utils.contain(EHENTAI_DOMAIN, getDomain(uri))) {
+ String ipdMemberId = Config.getIpdNumberId();
+ String ipdPassHash = Config.getIpdPassHash();
+ String igneous = Config.getIgneous();
+ if (ipdMemberId != null) {
+ cookie.put(KEY_IPD_MEMBER_ID, ipdMemberId);
+ }
+ if (ipdPassHash != null) {
+ cookie.put(KEY_IPD_PASS_HASH, ipdPassHash);
+ }
+ if (igneous != null) {
+ cookie.put(KEY_IGNEOUS, igneous);
+ }
+ // TODO cookie.put(KEY_UCONFIG, Config.getUconfig());
+ }
+
+ if (HOST_LOFI.equals(host)) {
+ // TODO cookie.put(KEY_XRES, Config.getXres());
+ }
+ }
+
+ List cookieList = new ArrayList<>();
+ cookieList.add(cookie.toString());
+ // Map to return
+ Map> cookieMap = new HashMap<>(requestHeaders);
+ cookieMap.put("Cookie" , cookieList);
+
+ return Collections.unmodifiableMap(cookieMap);
+ }
+
+ @Override
+ public void put(URI uri, Map> responseHeaders) throws IOException {
+ Cookie cookie = new Cookie();
+
+ List cookieList = responseHeaders.get("Set-Cookie");
+ if (cookieList != null) {
+ for (String cookieString : cookieList) {
+ cookie.putRaw(cookieString);
+ }
+ }
+
+ String ipdMemberId = cookie.get(KEY_IPD_MEMBER_ID);
+ String ipdPassHash = cookie.get(KEY_IPD_PASS_HASH);
+ String igneous = cookie.get(KEY_IGNEOUS);
+ if (ipdMemberId != null) {
+ Config.putIpdMemberId(ipdMemberId);
+ }
+ if (ipdPassHash != null) {
+ Config.putIpdPassHash(ipdPassHash);
+ }
+ if (igneous != null) {
+ Config.putIgneous(igneous);
+ }
+
+ cookie.remove(KEY_IPD_MEMBER_ID);
+ cookie.remove(KEY_IPD_MEMBER_ID);
+ cookie.remove(KEY_UCONFIG);
+ cookie.remove(KEY_XRES);
+ cookie.remove(KEY_YAY);
+
+ mCookieManager.setCookie(uri.toString(), cookie.toString());
+ }
+ };
+
+ public static class UserAgentInterceptor implements Interceptor {
+
+ private String mUserAgent;
+
+ public UserAgentInterceptor(String userAgent) {
+ mUserAgent = userAgent;
+ }
+
+ @Override
+ public Response intercept(Chain chain) throws IOException {
+ Request originalRequest = chain.request();
+ Request requestWithUserAgent = originalRequest.newBuilder()
+ .removeHeader("User-Agent")
+ .addHeader("User-Agent", mUserAgent)
+ .build();
+ return chain.proceed(requestWithUserAgent);
+ }
+ }
+
+ private static final EhOkHttpClient sInstance = new EhOkHttpClient();
+
+ public static EhOkHttpClient getInstance() {
+ return sInstance;
+ }
+
+ private EhOkHttpClient() {
+ setCookieHandler(mCookieHandler);
+ setConnectTimeout(5, TimeUnit.SECONDS);
+ setReadTimeout(5, TimeUnit.SECONDS);
+ setFollowRedirects(true);
+ networkInterceptors().add(new UserAgentInterceptor(USER_AGENT));
+ }
+}
diff --git a/app/src/main/java/com/hippo/ehviewer/ui/ContentActivity.java b/app/src/main/java/com/hippo/ehviewer/ui/ContentActivity.java
index 18e5ef58d..fe16d21b6 100644
--- a/app/src/main/java/com/hippo/ehviewer/ui/ContentActivity.java
+++ b/app/src/main/java/com/hippo/ehviewer/ui/ContentActivity.java
@@ -27,6 +27,7 @@ import android.view.View;
import android.widget.AdapterView;
import com.hippo.content.VectorContext;
+import com.hippo.ehviewer.Constants;
import com.hippo.ehviewer.R;
import com.hippo.ehviewer.ui.scene.GalleryListScene;
import com.hippo.ehviewer.ui.scene.SignInScene;
@@ -37,6 +38,7 @@ import com.hippo.scene.Announcer;
import com.hippo.scene.SimpleCurtain;
import com.hippo.scene.StageActivity;
import com.hippo.scene.StageLayout;
+import com.hippo.util.Messenger;
import com.hippo.widget.DrawerListView;
public final class ContentActivity extends StageActivity
@@ -188,6 +190,7 @@ public final class ContentActivity extends StageActivity
@Override
public void onClickSignOut() {
-
+ Config.putSignIn(false);
+ Messenger.getInstance().notify(Constants.MESSENGER_ID_SIGN_IN_OR_OUT, null);
}
}
diff --git a/app/src/main/java/com/hippo/ehviewer/ui/scene/SignInScene.java b/app/src/main/java/com/hippo/ehviewer/ui/scene/SignInScene.java
index 9984aed64..cd4e4f1ad 100644
--- a/app/src/main/java/com/hippo/ehviewer/ui/scene/SignInScene.java
+++ b/app/src/main/java/com/hippo/ehviewer/ui/scene/SignInScene.java
@@ -18,18 +18,39 @@ package com.hippo.ehviewer.ui.scene;
import android.annotation.Nullable;
import android.os.Bundle;
import android.view.View;
+import android.widget.EditText;
import android.widget.TextView;
import com.hippo.effect.ripple.RippleSalon;
+import com.hippo.ehviewer.Constants;
import com.hippo.ehviewer.R;
+import com.hippo.ehviewer.client.EhClient;
+import com.hippo.ehviewer.util.Config;
import com.hippo.scene.Scene;
+import com.hippo.util.Messenger;
-public class SignInScene extends Scene {
+public final class SignInScene extends Scene implements View.OnClickListener {
private View mMainView;
+ private EditText mUsername;
+ private EditText mPassword;
private TextView mSignUp;
private TextView mSignIn;
+ private EhClient.OnSignInListener mSignInListener = new EhClient.OnSignInListener() {
+ @Override
+ public void onSuccess(String displayname) {
+ Config.putSignIn(true);
+ Config.putDisplayName(displayname);
+ Messenger.getInstance().notify(Constants.MESSENGER_ID_SIGN_IN_OR_OUT, displayname);
+ }
+
+ @Override
+ public void onFailure(Exception e) {
+ e.printStackTrace();
+ }
+ };
+
@Override
public int getLaunchMode() {
return LAUNCH_MODE_SINGLE_TOP;
@@ -41,11 +62,15 @@ public class SignInScene extends Scene {
setContentView(R.layout.scene_sign_in);
mMainView = findViewById(R.id.sigin_in_main);
+ mUsername = (EditText) mMainView.findViewById(R.id.username);
+ mPassword = (EditText) mMainView.findViewById(R.id.password);
mSignUp = (TextView) mMainView.findViewById(R.id.sign_up);
mSignIn = (TextView) mMainView.findViewById(R.id.sign_in);
RippleSalon.addRipple(mSignUp, false);
RippleSalon.addRipple(mSignIn, false);
+ mSignUp.setOnClickListener(this);
+ mSignIn.setOnClickListener(this);
}
@Override
@@ -54,4 +79,13 @@ public class SignInScene extends Scene {
mMainView.getPaddingTop(),
mMainView.getPaddingRight(), b);
}
+
+ @Override
+ public void onClick(View v) {
+ if (v == mSignIn) {
+ String username = mUsername.getText().toString();
+ String password = mPassword.getText().toString();
+ EhClient.getInstance().signIn(username, password, mSignInListener);
+ }
+ }
}
diff --git a/app/src/main/java/com/hippo/ehviewer/util/Config.java b/app/src/main/java/com/hippo/ehviewer/util/Config.java
index 174a1d773..c3baaf8b8 100644
--- a/app/src/main/java/com/hippo/ehviewer/util/Config.java
+++ b/app/src/main/java/com/hippo/ehviewer/util/Config.java
@@ -79,11 +79,17 @@ public final class Config {
private static final String KEY_EH_SOURCE = "eh_source";
private static final int DEFAULT_EH_SOURCE = BuildConfig.DEBUG ?
- EhClient.SOURCE_LOFI : EhClient.SOURCE_G;
+ EhClient.SOURCE_EX : EhClient.SOURCE_G;
+ private static final String KEY_SIGN_IN = "sign_in";
+ private static final boolean DEFAULT_SIGN_IN = false;
+ private static final String KEY_DISPLAY_NAME = "display_name";
+ private static final String DEFAULT_DISPLAY_NAME = null;
private static final String KEY_IPD_MEMBER_ID = "ipb_member_id";
private static final String DEFAULT_IPD_MEMBER_ID = null;
private static final String KEY_IPD_PASS_HASH = "ipb_pass_hash";
private static final String DEFAULT_IPD_PASS_HASH = null;
+ private static final String KEY_IGNEOUS = "igneous";
+ private static final String DEFAULT_IGNEOUS = null;
public static int getEhSource() {
int value = getInt(KEY_EH_SOURCE, DEFAULT_EH_SOURCE);
@@ -101,6 +107,22 @@ public final class Config {
Messenger.getInstance().notify(Constants.MESSENGER_ID_EH_SOURCE, value);
}
+ public static boolean getSignIn() {
+ return getBoolean(KEY_SIGN_IN, DEFAULT_SIGN_IN);
+ }
+
+ public static void putSignIn(boolean value) {
+ putBoolean(KEY_SIGN_IN, value);
+ }
+
+ public static String getDisplayName() {
+ return getString(KEY_DISPLAY_NAME, DEFAULT_DISPLAY_NAME);
+ }
+
+ public static void putDisplayName(String value) {
+ putString(KEY_DISPLAY_NAME, value);
+ }
+
public static String getIpdNumberId() {
return getString(KEY_IPD_MEMBER_ID, DEFAULT_IPD_MEMBER_ID);
}
@@ -117,6 +139,20 @@ public final class Config {
putString(KEY_IPD_PASS_HASH, value);
}
+ public static String getIgneous() {
+ String igneous = getString(KEY_IGNEOUS, DEFAULT_IGNEOUS);
+ if ("mystery".equals(igneous)) {
+ return null;
+ } else {
+ return igneous;
+ }
+ }
+
+ public static void putIgneous(String value) {
+ if (!"mystery".equals(value)) {
+ putString(KEY_IGNEOUS, value);
+ }
+ }
/****** Advance ******/
diff --git a/app/src/main/java/com/hippo/ehviewer/widget/DrawerLeftPanel.java b/app/src/main/java/com/hippo/ehviewer/widget/DrawerLeftPanel.java
index a7e9a8734..e91e864ae 100644
--- a/app/src/main/java/com/hippo/ehviewer/widget/DrawerLeftPanel.java
+++ b/app/src/main/java/com/hippo/ehviewer/widget/DrawerLeftPanel.java
@@ -33,6 +33,7 @@ import com.facebook.drawee.view.SimpleDraweeView;
import com.hippo.effect.ripple.RippleSalon;
import com.hippo.ehviewer.Constants;
import com.hippo.ehviewer.R;
+import com.hippo.ehviewer.util.Config;
import com.hippo.util.FrescoUtils;
import com.hippo.util.Messenger;
import com.hippo.widget.DrawerListView;
@@ -136,10 +137,17 @@ public class DrawerLeftPanel extends LinearLayout {
mUserPanelOriginalPaddingTop = mUserPanel.getPaddingTop();
mDrawerListViewOriginalPaddingBottom = mDrawerListView.getPaddingBottom();
- // TODO
- mAvatar.setImageURI(DEFAULT_AVATAR_URI);
- mUsename.setText("");
- mAction.setText(mContext.getString(R.string.signin));
+ mSignIn = Config.getSignIn();
+ if (mSignIn) {
+ // TODO
+ mAvatar.setImageURI(DEFAULT_AVATAR_URI);
+ mUsename.setText(Config.getDisplayName());
+ mAction.setText(mContext.getString(R.string.signout));
+ } else {
+ mAvatar.setImageURI(DEFAULT_AVATAR_URI);
+ mUsename.setText("");
+ mAction.setText(mContext.getString(R.string.signin));
+ }
}
public DrawerListView getDrawerListView() {
diff --git a/app/src/main/java/com/hippo/network/Cookie.java b/app/src/main/java/com/hippo/network/Cookie.java
new file mode 100644
index 000000000..52f61636d
--- /dev/null
+++ b/app/src/main/java/com/hippo/network/Cookie.java
@@ -0,0 +1,85 @@
+/*
+ * Copyright (C) 2015 Hippo Seven
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.hippo.network;
+
+import com.hippo.util.Utils;
+
+import java.util.HashMap;
+import java.util.Map;
+
+public class Cookie {
+
+ private static final String KEY_DOMAIN = "domain";
+ private static final String KEY_PATH = "path";
+ private static final String KEY_EXPIRES = "expires";
+
+ private static final String[] UNSUPPORT_KEY = {
+ KEY_DOMAIN,
+ KEY_PATH,
+ KEY_EXPIRES
+ };
+
+ private Map mItems = new HashMap<>();
+
+ public void putRaw(String cookieString) {
+ if (cookieString != null) {
+ String[] pieces = cookieString.split(";");
+ for (String p : pieces) {
+ int index = p.indexOf('=');
+ if (index != -1) {
+ String key = p.substring(0, index).trim();
+ String value = p.substring(index + 1).trim();
+ if (!Utils.contain(UNSUPPORT_KEY, key)) {
+ mItems.put(key, value);
+ }
+ }
+ }
+ }
+ }
+
+ public void put(String key, String value) {
+ if (!Utils.contain(UNSUPPORT_KEY, key)) {
+ mItems.put(key, value);
+ }
+ }
+
+ public void remove(String key) {
+ mItems.remove(key);
+ }
+
+ public String get(String key) {
+ return mItems.get(key);
+ }
+
+ public String toString() {
+ StringBuilder sb = new StringBuilder();
+ String separator1 = "; ";
+ String separator2 = "=";
+ boolean first = true;
+
+ for (String key : mItems.keySet()) {
+ String value = mItems.get(key);
+ if (first) {
+ first = false;
+ } else {
+ sb.append(separator1);
+ }
+ sb.append(key).append(separator2).append(value);
+ }
+
+ return sb.toString();
+ }
+}
diff --git a/app/src/main/java/com/hippo/network/HttpHelper.java b/app/src/main/java/com/hippo/network/HttpHelper.java
deleted file mode 100644
index 0e6427892..000000000
--- a/app/src/main/java/com/hippo/network/HttpHelper.java
+++ /dev/null
@@ -1,951 +0,0 @@
-/*
- * Copyright (C) 2014-2015 Hippo Seven
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.hippo.network;
-
-import android.graphics.Bitmap;
-import android.graphics.BitmapFactory;
-import android.support.annotation.NonNull;
-import android.support.annotation.Nullable;
-import android.webkit.CookieManager;
-import android.webkit.MimeTypeMap;
-
-import com.hippo.util.FastByteArrayOutputStream;
-import com.hippo.util.Log;
-import com.hippo.util.Utils;
-
-import org.json.JSONObject;
-
-import java.io.ByteArrayOutputStream;
-import java.io.DataOutputStream;
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileNotFoundException;
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
-import java.net.HttpURLConnection;
-import java.net.MalformedURLException;
-import java.net.URL;
-import java.net.URLConnection;
-import java.net.URLEncoder;
-import java.util.HashMap;
-import java.util.LinkedHashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.zip.GZIPInputStream;
-
-/**
- * It is not thread safe
- */
-public class HttpHelper {
- private static final String TAG = HttpHelper.class.getSimpleName();
-
- private static final int MAX_RETRY = 3;
- private static final int MAX_REDIRECTS = 3;
- private static final int CONNECT_TIMEOUT = 5000;
- private static final int READ_TIMEOUT = 5000;
-
- public static final String DEFAULT_USER_AGENT =
- "Mozilla/5.0 (Windows NT 6.1; WOW64) " +
- "AppleWebKit/537.36 (KHTML, like Gecko) " +
- "Chrome/39.0.2171.95 Safari/537.36";
- public static final String USER_AGENT =
- System.getProperty("http.agent", DEFAULT_USER_AGENT);
-
- private static final int HTTP_TEMP_REDIRECT = 307;
-
- private static final String DEFAULT_CHARSET = "utf-8";
- private static final String CHARSET_KEY = "charset=";
-
- private static final CookieManager sCookieManager = CookieManager.getInstance();
-
- private int mResponseCode = -1;
-
- public void reset() {
- mResponseCode = -1;
- }
-
- public int getResponseCode() {
- return mResponseCode;
- }
-
- /**
- * Get cookie for the url
- * @param url the URL
- * @return the cookie for the URL
- */
- protected String getCookie(URL url) {
- return sCookieManager.getCookie(url.toString());
- }
-
- /**
- * Store cookie for the url
- * @param url the URL
- * @param value the cookie for the URL
- */
- protected void storeCookie(URL url, String value) {
- sCookieManager.setCookie(url.toString(), value);
- }
-
- /**
- * Prepare before connecting
- * @param conn the connection
- */
- protected void onBeforeConnect(HttpURLConnection conn) {
- conn.setInstanceFollowRedirects(true);
- conn.setRequestProperty("User-Agent", USER_AGENT);
- conn.setConnectTimeout(CONNECT_TIMEOUT);
- conn.setReadTimeout(READ_TIMEOUT);
- }
-
- /**
- * Is URL.toString is same
- */
- public static boolean isURLEquals(URL url1, URL url2) {
- if (url1 != null && url2 != null) {
- String urlStr1 = url1.toString();
- String urlStr2 = url2.toString();
- if (urlStr1 != null && urlStr2 != null) {
- return urlStr1.equals(urlStr2);
- }
- }
- return false;
- }
-
- /**
- * parse string like haha=hehe; fere=bfdgds
- *
- * @param raw the raw string
- * @return the key is toLowerCase
- */
- public static @NonNull Map parseMap(@Nullable String raw) {
- Map map = new HashMap<>();
- if (raw != null) {
- String[] pieces = raw.split(";");
- for (String p : pieces) {
- int index = p.indexOf('=');
- if (index != -1) {
- String key = p.substring(0, index).trim();
- String value = p.substring(index + 1).trim();
-
- // value might be "blabla", remove "
- int valueLength = value.length();
- if (value.length() > 1 && value.charAt(0) == '"' &&
- value.charAt(valueLength - 1) == '"') {
- value = value.substring(1, valueLength - 1);
- }
- map.put(key.toLowerCase(), value);
- }
- }
- }
-
- return map;
- }
-
- private Object doRequst(RequestHelper rh) throws Exception {
- URL url;
- HttpURLConnection conn = null;
- int redirectionCount = 0;
- try {
- url = rh.getUrl();
- while (redirectionCount++ < MAX_REDIRECTS) {
- Log.d(TAG, "Request: " + url.toString());
- conn = (HttpURLConnection) url.openConnection();
- // Prepare before connecting
- onBeforeConnect(conn);
- // Set cookie
- String cookie = getCookie(url);
- if (cookie != null) {
- conn.setRequestProperty("Cookie", cookie);
- }
- // Do custom staff
- rh.onBeforeConnect(conn);
-
- conn.connect();
- // Store cookie
- List cookieList = conn.getHeaderFields().get("Set-Cookie");
- if (cookieList != null) {
- for (String cookieTemp : cookieList) {
- if (cookieTemp != null) {
- storeCookie(url, cookieTemp);
- }
- }
- }
- final int responseCode = conn.getResponseCode();
- mResponseCode = responseCode;
- Log.d(TAG, "Response code: " + responseCode);
- switch (responseCode) {
- case HttpURLConnection.HTTP_MOVED_PERM:
- case HttpURLConnection.HTTP_MOVED_TEMP:
- case HttpURLConnection.HTTP_SEE_OTHER:
- case HTTP_TEMP_REDIRECT:
- // Should not come here,
- // because conn.setInstanceFollowRedirects(true)
- final String location = conn.getHeaderField("Location");
- Log.d(TAG, "New location: " + location);
- conn.disconnect();
- url = new URL(url, location);
- break;
- default:
- // Check redirect
- URL finalURL = conn.getURL();
- if (!isURLEquals(url, finalURL)) {
- rh.onRedirect(finalURL);
- }
- return rh.onAfterConnect(conn);
- }
- }
- } finally {
- if (conn != null)
- conn.disconnect();
- }
-
- throw new RedirectionException();
- }
-
- protected Object requst(@NonNull RequestHelper rh) throws Exception {
- Exception exception = null;
- for (
- int times = 0;
- times < MAX_RETRY && (times == 0 || rh.onRetry(exception));
- times++) {
- try {
- return doRequst(rh);
- } catch (Exception e) {
- exception = e;
- }
- }
-
- rh.onRequestFailed(exception);
-
- throw exception;
- }
-
- public interface RequestHelper {
-
- /**
- * Get the URL to connect
- * @return the URL to connect
- */
- URL getUrl() throws MalformedURLException;
-
- /**
- * Add header or do something else for HttpURLConnection before connect
- *
- * @param conn the connection
- * @throws Exception
- */
- void onBeforeConnect(HttpURLConnection conn) throws Exception;
-
- /**
- * If get redirect
- *
- * @param newURL the new URL
- */
- void onRedirect(URL newURL);
-
- /**
- * Get what do you need from HttpURLConnection after connect
- * Return null means get error
- *
- * @param conn the connection
- * @return what you want to return
- * @throws Exception
- */
- Object onAfterConnect(HttpURLConnection conn) throws Exception;
-
- /**
- * Retry http connecting, or stop
- *
- * @param previousException previous thrown
- * @return true for retry, false for stop
- */
- boolean onRetry(Exception previousException);
-
- /**
- * Called when request failed by exception
- *
- * @param exception the final exception
- */
- void onRequestFailed(Exception exception);
- }
-
- public static abstract class GetStringHelper implements RequestHelper {
- private final String mUrl;
-
- public GetStringHelper(String url) {
- mUrl = url;
- }
-
- @Override
- public URL getUrl() throws MalformedURLException {
- return new URL(mUrl);
- }
-
- @Override
- public void onBeforeConnect(HttpURLConnection conn)
- throws Exception {
- conn.addRequestProperty("Accept-Encoding", "gzip");
- }
-
- private String getCharset(HttpURLConnection conn) {
- String charset = parseMap(conn.getContentType()).get("charset");
- if (charset != null) {
- return charset;
- } else {
- return DEFAULT_CHARSET;
- }
- }
-
- private String getBody(HttpURLConnection conn)
- throws Exception {
- String body = null;
- InputStream is = null;
- ByteArrayOutputStream baos = null;
- try {
- try {
- // First try to get input stream
- is = conn.getInputStream();
- } catch (Exception t){
- // If we get error, get error stream
- is = conn.getErrorStream();
- }
- String encoding = conn.getContentEncoding();
- if (encoding != null && encoding.equalsIgnoreCase("gzip"))
- is = new GZIPInputStream(is);
-
- int length = conn.getContentLength();
- if (length >= 0) {
- baos = new ByteArrayOutputStream(length);
- } else {
- baos = new ByteArrayOutputStream();
- }
-
- Utils.copy(is, baos);
-
- body = baos.toString(getCharset(conn));
-
- } finally {
- Utils.closeQuietly(is);
- Utils.closeQuietly(baos);
- }
-
- return body;
- }
-
- @Override
- public void onRedirect(@NonNull URL newURL) {
- // Empty
- }
-
- @Override
- public Object onAfterConnect(@NonNull HttpURLConnection conn)
- throws Exception {
- return getBody(conn);
- }
-
- @Override
- public boolean onRetry(@NonNull Exception previousException) {
- // Do not care about exception, just retry
- return true;
- }
-
- @Override
- public void onRequestFailed(@NonNull Exception exception) {
- // Empty
- }
- }
-
- /**
- * RequstHelper for GET method
- */
- public static class GetHelper extends GetStringHelper {
-
- public GetHelper(String url) {
- super(url);
- }
-
- @Override
- public void onBeforeConnect(@NonNull HttpURLConnection conn)
- throws Exception {
- super.onBeforeConnect(conn);
- conn.setRequestMethod("GET");
- }
- }
-
- /**
- * RequstHelper for post form data, use POST method
- */
- public static class PostFormHelper extends GetStringHelper {
- private final String[][] mArgs;
-
- public PostFormHelper(String url, String[][] args) {
- super(url);
- mArgs = args;
- }
-
- @Override
- public void onBeforeConnect(HttpURLConnection conn)
- throws Exception {
- super.onBeforeConnect(conn);
- conn.setDoOutput(true);
- conn.setDoInput(true);
- conn.setUseCaches(false);
- conn.setRequestMethod("POST");
- conn.setRequestProperty("Content-Type",
- "application/x-www-form-urlencoded");
-
- DataOutputStream out = new DataOutputStream(conn.getOutputStream());
- StringBuilder sb = new StringBuilder();
- int i = 0;
- for (String[] arg : mArgs) {
- if (i != 0)
- sb.append("&");
- sb.append(URLEncoder.encode(arg[0], "UTF-8"));
- sb.append("=");
- sb.append(URLEncoder.encode(arg[1], "UTF-8"));
- i++;
- }
- out.writeBytes(sb.toString());
- out.flush();
- out.close();
- }
- }
-
- /**
- * RequstHelper for post json, use POST method
- */
- public static class PostJsonHelper extends GetStringHelper {
- private final JSONObject mJo;
-
- public PostJsonHelper(String url, JSONObject jo) {
- super(url);
- mJo = jo;
- }
-
- @Override
- public void onBeforeConnect(HttpURLConnection conn) throws Exception {
- super.onBeforeConnect(conn);
- conn.setDoOutput(true);
- conn.setDoInput(true);
- conn.setUseCaches(false);
- conn.setRequestMethod("POST");
- conn.setRequestProperty("Content-Type", "application/json");
-
- DataOutputStream out = new DataOutputStream(conn.getOutputStream());
- String body = mJo.toString();
- Log.d(TAG, "Post json: " + body);
- out.write(body.getBytes("utf-8"));
- out.flush();
- out.close();
- }
- }
-
- public abstract static class FormData {
- private final Map mProperties;
-
- public FormData() {
- mProperties = new LinkedHashMap<>();
- }
-
- public void setProperty(String key, String value) {
- mProperties.put(key, value);
- }
-
- public void clearProperty(String key) {
- mProperties.remove(key);
- }
-
- public void clearAllProperties() {
- mProperties.clear();
- }
-
- /**
- * Put information to target OutputStream.
- *
- * @param os target outputStream
- * @throws java.io.IOException
- */
- public abstract void output(OutputStream os) throws IOException;
-
- public void doOutPut(OutputStream os) throws IOException {
- StringBuilder sb = new StringBuilder();
- for (String key : mProperties.keySet())
- sb.append(key).append(": ").append(mProperties.get(key)).append("\r\n");
- sb.append("\r\n");
- os.write(sb.toString().getBytes());
- output(os);
- }
- }
-
- public static class StringData extends FormData {
- private final String mStr;
-
- public StringData(String str) {
- mStr = str;
- }
-
- @Override
- public void output(OutputStream os) throws IOException {
- os.write(mStr.getBytes());
- os.write("\r\n".getBytes());
- }
- }
-
- public static class BitmapData extends FormData {
- private final Bitmap mBitmap;
-
- public BitmapData(Bitmap bmp) {
- mBitmap = bmp;
- setProperty("Content-Type", "image/jpeg");
- }
-
- @Override
- public void output(OutputStream os) throws IOException {
- mBitmap.compress(Bitmap.CompressFormat.JPEG, 98, os);
- os.write("\r\n".getBytes());
- }
- }
-
- public static class FileData extends FormData {
- private final File mFile;
-
- public FileData(File file) {
- mFile = file;
- setProperty("Content-Type",
- URLConnection.guessContentTypeFromName(file.getName()));
- }
-
- @Override
- public void output(OutputStream os) throws IOException {
- InputStream is = new FileInputStream(mFile);
- byte[] buffer = new byte[1024];
- int bytesRead;
- while((bytesRead = is.read(buffer)) !=-1)
- os.write(buffer, 0, bytesRead);
- is.close();
-
- os.write("\r\n".getBytes());
- }
- }
-
- public static class PostFormDataHelper extends GetStringHelper {
- private static final String BOUNDARY = "----WebKitFormBoundary7eDB0hDQ91s22Tkf";
-
- private final List mDataList;
-
-
- public PostFormDataHelper(String url, List dataList) {
- super(url);
- mDataList = dataList;
- }
-
- @Override
- public void onBeforeConnect(HttpURLConnection conn) throws Exception {
- super.onBeforeConnect(conn);
- conn.setDoOutput(true);
- conn.setDoInput(true);
- conn.setUseCaches(false);
- conn.setRequestMethod("POST");
- conn.setRequestProperty("Content-Type",
- "multipart/form-data; boundary=" + BOUNDARY);
-
- DataOutputStream out = new DataOutputStream(conn.getOutputStream());
-
- for (FormData data : mDataList) {
- out.write("--".getBytes());
- out.write(BOUNDARY.getBytes());
- out.write("\r\n".getBytes());
- data.doOutPut(out);
- }
- out.write("--".getBytes());
- out.write(BOUNDARY.getBytes());
- out.write("--".getBytes());
-
- out.flush();
- out.close();
- }
- }
-
- public static class GetImageHelper implements RequestHelper {
- private final String mUrl;
-
- public GetImageHelper(String url) {
- mUrl = url;
- }
-
- @Override
- public URL getUrl() throws MalformedURLException {
- return new URL(mUrl);
- }
-
- @Override
- public void onBeforeConnect(HttpURLConnection conn)
- throws Exception {
- conn.setRequestMethod("GET");
- }
-
- @Override
- public void onRedirect(@NonNull URL newURL) {
- // Empty
- }
-
- @Override
- public Object onAfterConnect(HttpURLConnection conn)
- throws Exception {
- // If just
- // Bitmap bmp = BitmapFactory.decodeStream(conn.getInputStream(), null, Ui.getBitmapOpt());
- // bitmap might be incomplete.
- int size = conn.getContentLength();
- FastByteArrayOutputStream fbaos = new FastByteArrayOutputStream(size == -1 ? 24 * 1024 : (size + 100));
- Utils.copy(conn.getInputStream(), fbaos);
- Bitmap bmp = BitmapFactory.decodeByteArray(fbaos.getBuffer(), 0, fbaos.size(), null);
-
- if (bmp == null) {
- throw new IllegalStateException("Can not decode to bitmap.");
- }
- return bmp;
- }
-
- @Override
- public boolean onRetry(Exception previousException) {
- // Do not care about exception, just retry
- return true;
- }
-
- @Override
- public void onRequestFailed(Exception exception) {
- // Empty
- }
- }
-
- public interface OnDownloadListener {
-
- /**
- * Called before connecting
- */
- void onStartConnecting();
-
- /**
- * Called after connecting and before downloading
- *
- * @param totalSize content length, -1 for unknown
- */
- void onStartDownloading(int totalSize);
-
- /**
- * File name is fixed
- *
- * @param newName new file name
- */
- void onNameFix(String newName);
-
- /**
- * Called repeatedly during downloading
- *
- * @param downloadSize downloaded size
- * @param totalSize content length, -1 for unknown
- */
- void onDownload(int downloadSize, int totalSize);
-
- /**
- * Called when download ok
- */
- void onSuccess();
-
- /**
- * Called when download stop
- */
- void onStop();
-
- /**
- * Called when download failed
- *
- * @param e the exception why fail
- */
- void onFailure(Exception e);
- }
-
- public static class DownloadControlor {
- private boolean mStop = false;
-
- public void stop() {
- mStop = true;
- }
-
- public void reset() {
- mStop = false;
- }
-
- public boolean isStop() {
- return mStop;
- }
- }
-
- public static class DownloadHelper implements RequestHelper {
-
- private static final String DOWNLOAD_EXTENSION = ".download";
-
- private final String mUrl;
- private final File mDir;
- private String mFileName;
- private File mFile;
- private File mTempFile;
- private final DownloadControlor mControlor;
- private final OnDownloadListener mListener;
- private int mContentLength;
- private int mReceivedSize;
-
- public DownloadHelper(String url, File dir, String fileName,
- DownloadControlor controlor, OnDownloadListener listener) {
- mUrl = url;
- mDir = dir;
- mFileName = fileName;
- mControlor = controlor;
- mListener = listener;
- }
-
- @Override
- public URL getUrl() throws MalformedURLException {
- return new URL(mUrl);
- }
-
- private void checkStop() throws StopRequestException {
- if (mControlor != null && mControlor.isStop()) {
- throw new StopRequestException();
- }
- }
-
- @Override
- public void onBeforeConnect(HttpURLConnection conn) throws Exception {
- checkStop();
-
- conn.setRequestMethod("GET");
- // Sometimes for application/octet-stream, we need to add this line
- // to get content length
- conn.setRequestProperty("Range", "bytes=0-");
-
- if (mListener != null) {
- mListener.onStartConnecting();
- }
- }
-
- private int getContentLength(HttpURLConnection conn) {
- int contentLength = conn.getContentLength();
- String range;
- if (contentLength == -1 &&
- (range = conn.getHeaderField("Content-Range")) != null) {
- // Content-Range looks like bytes 500-999/1234
- int index = range.indexOf('/');
- if (index != -1) {
- contentLength = Utils.parseIntSafely(range.substring(index + 1), -1);
- }
- }
- return contentLength;
- }
-
- @Override
- public void onRedirect(@NonNull URL newURL) {
- // TODO
- }
-
- /**
- * Get new extension
- *
- * @param ext new extension
- * @return null for not changed
- */
- protected String fixNewExtension(String ext) {
- return null;
- }
-
- @Override
- public Object onAfterConnect(HttpURLConnection conn) throws Exception {
- // Check stop
- if (mControlor != null && mControlor.isStop())
- throw new StopRequestException();
-
- String contentType = conn.getContentType();
- int index = contentType.indexOf(';');
- if (index != -1)
- contentType = contentType.substring(0, index);
-
- mContentLength = getContentLength(conn);
- if (mListener != null) {
- mListener.onStartDownloading(mContentLength);
- }
-
- // Fix extension
- MimeTypeMap mime = MimeTypeMap.getSingleton();
- String newExtension = mime.getExtensionFromMimeType(contentType);
- if (newExtension == null) {
- index = contentType.lastIndexOf('/');
- if (index != -1) {
- newExtension = contentType.substring(index + 1);
- }
- }
- newExtension = fixNewExtension(newExtension);
- if (newExtension != null) {
- index = mFileName.lastIndexOf('.');
- if (index == -1) {
- mFileName = mFileName + '.' + newExtension;
- } else {
- mFileName = mFileName.substring(0, index) + '.' + newExtension;
- }
- }
-
- // Make sure parent exist
- if (!mDir.mkdirs() && !mDir.isDirectory()) {
- throw new FileNotFoundException("Can not create dir " +
- mDir.getPath());
- }
-
- mFile = new File(mDir, mFileName);
- mTempFile = new File(mDir, mFileName + DOWNLOAD_EXTENSION);
-
- // Transfer
- transferData(conn.getInputStream(), new FileOutputStream(mTempFile));
-
- // Get ok, rename
- Utils.deleteFile(mFile);
- if (!mTempFile.renameTo(mFile)) {
- throw new FileNotFoundException("Rename " + mTempFile.getPath() +
- " to " + mFile.getPath() + " error");
- }
-
- // Callback
- if (mListener != null) {
- mListener.onSuccess();
- }
-
- // We do not need result
- return null;
- }
-
- private void transferData(InputStream in, OutputStream out)
- throws Exception {
- final byte data[] = new byte[512 * 1024];
- mReceivedSize = 0;
-
- while (true) {
- // Check stop first
- checkStop();
-
- int bytesRead = in.read(data);
- if (bytesRead == -1)
- break;
- out.write(data, 0, bytesRead);
- mReceivedSize += bytesRead;
-
- if (mListener != null) {
- mListener.onDownload(mReceivedSize, mContentLength);
- }
- }
-
- if (mContentLength != -1 && mReceivedSize != mContentLength) {
- throw new UncompletedException("Received size is " + mReceivedSize
- + ", but ContentLength is " + mContentLength);
- }
- }
-
- @Override
- public boolean onRetry(Exception previousException) {
- // Delete unfinished file
- Utils.deleteFile(mTempFile);
- Utils.deleteFile(mFile);
-
- if (previousException instanceof StopRequestException) {
- return false;
- } else {
- return true;
- }
- }
-
- @Override
- public void onRequestFailed(Exception exception) {
- if (mListener != null) {
- if (exception instanceof StopRequestException) {
- mListener.onStop();
- } else {
- mListener.onFailure(exception);
- }
- }
- }
- }
-
- /**
- * Http GET method
- * @param url the url to get
- * @return body
- */
- public String get(String url) throws Exception {
- return (String) requst(new GetHelper(url));
- }
-
- /**
- * Post form data
- * @param url the url to post
- * @param args the form to post
- * @return body
- */
- public String postForm(String url, String[][] args) throws Exception {
- return (String) requst(new PostFormHelper(url, args));
- }
-
- /**
- * Post json data
- * @param url the url to post
- * @param json the json to post
- * @return body
- */
- public String postJson(String url, JSONObject json) throws Exception {
- return (String) requst(new PostJsonHelper(url, json));
- }
-
- /**
- * Post data, multipart/form-data
- * @param url the url to post
- * @param dataList the data list to post
- * @return body
- */
- public String postFormData(String url, List dataList) throws Exception {
- return (String)requst(new PostFormDataHelper(url, dataList));
- }
-
- /**
- * Get image
- * @param url the url to get image
- * @return bitmap
- */
- public Bitmap getImage(String url) throws Exception {
- return (Bitmap) requst(new GetImageHelper(url));
- }
-
- /**
- * Init DownloadHelper
- *
- * @param url the url to download
- * @param dir the dir to download file
- * @param file the file name
- * @param controlor download control
- * @param listener download listener
- */
- public void download(String url, File dir, String file,
- DownloadControlor controlor, OnDownloadListener listener) throws Exception {
- requst(new DownloadHelper(url, dir, file, controlor, listener));
- }
-}
diff --git a/app/src/main/java/com/hippo/network/RedirectionException.java b/app/src/main/java/com/hippo/network/RedirectionException.java
deleted file mode 100644
index 125028fb6..000000000
--- a/app/src/main/java/com/hippo/network/RedirectionException.java
+++ /dev/null
@@ -1,23 +0,0 @@
-/*
- * Copyright (C) 2014-2015 Hippo Seven
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.hippo.network;
-
-public class RedirectionException extends Exception {
-
- public RedirectionException() {
- super("To many redirection");
- }
-}
diff --git a/app/src/main/java/com/hippo/network/StopRequestException.java b/app/src/main/java/com/hippo/network/StopRequestException.java
deleted file mode 100644
index 8077f8332..000000000
--- a/app/src/main/java/com/hippo/network/StopRequestException.java
+++ /dev/null
@@ -1,23 +0,0 @@
-/*
- * Copyright (C) 2014-2015 Hippo Seven
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.hippo.network;
-
-public class StopRequestException extends Exception {
-
- public StopRequestException() {
- super("Stoped by request");
- }
-}
diff --git a/app/src/main/java/com/hippo/network/UncompletedException.java b/app/src/main/java/com/hippo/network/UncompletedException.java
deleted file mode 100644
index 334ef19d9..000000000
--- a/app/src/main/java/com/hippo/network/UncompletedException.java
+++ /dev/null
@@ -1,27 +0,0 @@
-/*
- * Copyright (C) 2014-2015 Hippo Seven
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.hippo.network;
-
-public class UncompletedException extends Exception {
-
- public UncompletedException() {
- super("Uncompleted error");
- }
-
- public UncompletedException(String detailMessage) {
- super(detailMessage);
- }
-}
diff --git a/app/src/main/java/com/hippo/util/ExceptionUtils.java b/app/src/main/java/com/hippo/util/ExceptionUtils.java
index c3595112e..51d5ace2b 100644
--- a/app/src/main/java/com/hippo/util/ExceptionUtils.java
+++ b/app/src/main/java/com/hippo/util/ExceptionUtils.java
@@ -21,11 +21,12 @@ import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import com.hippo.ehviewer.R;
-import com.hippo.network.RedirectionException;
+import com.hippo.ehviewer.client.EhException;
import com.hippo.network.ResponseCodeException;
import org.apache.http.conn.ConnectTimeoutException;
+import java.net.ProtocolException;
import java.net.SocketException;
import java.net.SocketTimeoutException;
import java.net.UnknownHostException;
@@ -46,10 +47,12 @@ public final class ExceptionUtils {
error += '\n' + responseCodeException.getMessage();
}
return error;
- } else if (e instanceof RedirectionException) {
+ } else if (e instanceof ProtocolException && e.getMessage().startsWith("Too many follow-up requests:")) {
return context.getString(R.string.em_redirection);
} else if (e instanceof SocketException) {
return context.getString(R.string.em_socket);
+ } else if (e instanceof EhException) {
+ return e.getMessage();
} else {
Log.d("Can't recognize this Exception", e);
return context.getString(R.string.em_unknown);
diff --git a/app/src/main/java/com/hippo/util/Utils.java b/app/src/main/java/com/hippo/util/Utils.java
index 9965b6356..112618c2d 100644
--- a/app/src/main/java/com/hippo/util/Utils.java
+++ b/app/src/main/java/com/hippo/util/Utils.java
@@ -15,6 +15,7 @@
package com.hippo.util;
+import android.annotation.NonNull;
import android.annotation.SuppressLint;
import android.content.Context;
import android.os.AsyncTask;
@@ -804,4 +805,13 @@ public final class Utils {
return EMPTY_STRING;
}
}
+
+ public static boolean contain(@NonNull Object[] array, Object obj) {
+ for (Object o : array) {
+ if (o.equals(obj)) {
+ return true;
+ }
+ }
+ return false;
+ }
}