Use OkHttpClient
This commit is contained in:
1 parent
08d0794fe8
commit
b7f8cda304
18 files changed
+551
-1121
No files matched your search
+7
-3
@@ -74,6 +74,7 @@
|
||||
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/exploded-aar/com.facebook.fresco/drawee/0.5.0/jars" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/exploded-aar/com.facebook.fresco/fbcore/0.5.0/jars" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/exploded-aar/com.facebook.fresco/fresco/0.5.0/jars" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/exploded-aar/com.facebook.fresco/imagepipeline-okhttp/0.5.0/jars" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/exploded-aar/com.facebook.fresco/imagepipeline/0.5.0/jars" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/incremental" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/jacoco" />
|
||||
@@ -92,15 +93,18 @@
|
||||
</content>
|
||||
<orderEntry type="jdk" jdkName="Android API 22 Platform" jdkType="Android SDK" />
|
||||
<orderEntry type="sourceFolder" forTests="false" />
|
||||
<orderEntry type="library" exported="" name="appcompat-v7-22.1.1" level="project" />
|
||||
<orderEntry type="library" exported="" name="svg-android-2.0.6" level="project" />
|
||||
<orderEntry type="library" exported="" name="imagepipeline-0.5.0" level="project" />
|
||||
<orderEntry type="library" exported="" name="support-annotations-22.1.1" level="project" />
|
||||
<orderEntry type="library" exported="" name="appcompat-v7-22.1.1" level="project" />
|
||||
<orderEntry type="library" exported="" name="fresco-0.5.0" level="project" />
|
||||
<orderEntry type="library" exported="" name="fbcore-0.5.0" level="project" />
|
||||
<orderEntry type="library" exported="" name="drawee-0.5.0" level="project" />
|
||||
<orderEntry type="library" exported="" name="bolts-android-1.1.4" level="project" />
|
||||
<orderEntry type="library" exported="" name="imagepipeline-0.5.0" level="project" />
|
||||
<orderEntry type="library" exported="" name="imagepipeline-okhttp-0.5.0" level="project" />
|
||||
<orderEntry type="library" exported="" name="library-2.4.0" level="project" />
|
||||
<orderEntry type="library" exported="" name="support-v4-22.1.1" level="project" />
|
||||
<orderEntry type="library" exported="" name="support-annotations-22.1.1" level="project" />
|
||||
<orderEntry type="library" exported="" name="okhttp-2.4.0-RC1" level="project" />
|
||||
<orderEntry type="library" exported="" name="okio-1.4.0" level="project" />
|
||||
</component>
|
||||
</module>
|
||||
@@ -28,5 +28,7 @@ dependencies {
|
||||
compile 'com.android.support:appcompat-v7:22.1.1'
|
||||
compile 'com.github.japgolly.android:svg-android:2.0.6'
|
||||
compile 'com.facebook.fresco:fresco:0.5.0'
|
||||
compile 'com.facebook.fresco:imagepipeline-okhttp:0.5.0'
|
||||
compile 'com.squareup.okhttp:okhttp:2.4.0-RC1'
|
||||
compile fileTree(dir: 'libs', include: ['*.jar'])
|
||||
}
|
||||
@@ -18,7 +18,10 @@ package com.hippo.ehviewer;
|
||||
import android.content.Context;
|
||||
|
||||
import com.facebook.drawee.backends.pipeline.Fresco;
|
||||
import com.facebook.imagepipeline.backends.okhttp.OkHttpImagePipelineConfigFactory;
|
||||
import com.facebook.imagepipeline.core.ImagePipelineConfig;
|
||||
import com.hippo.content.VectorContext;
|
||||
import com.hippo.ehviewer.network.EhOkHttpClient;
|
||||
import com.hippo.ehviewer.util.Config;
|
||||
import com.hippo.scene.SceneApplication;
|
||||
import com.hippo.util.Log;
|
||||
@@ -29,7 +32,10 @@ public class EhApplication extends SceneApplication {
|
||||
public void onCreate() {
|
||||
super.onCreate();
|
||||
|
||||
Fresco.initialize(this);
|
||||
ImagePipelineConfig config = OkHttpImagePipelineConfigFactory
|
||||
.newBuilder(this, EhOkHttpClient.getInstance())
|
||||
.build();
|
||||
Fresco.initialize(this, config);
|
||||
Config.initialize(this);
|
||||
}
|
||||
|
||||
|
||||
@@ -19,9 +19,14 @@ import android.os.AsyncTask;
|
||||
import android.os.Process;
|
||||
|
||||
import com.hippo.ehviewer.data.GalleryInfo;
|
||||
import com.hippo.ehviewer.network.EhHttpHelper;
|
||||
import com.hippo.ehviewer.network.EhOkHttpClient;
|
||||
import com.hippo.network.ResponseCodeException;
|
||||
import com.hippo.util.PriorityThreadFactory;
|
||||
import com.squareup.okhttp.FormEncodingBuilder;
|
||||
import com.squareup.okhttp.MediaType;
|
||||
import com.squareup.okhttp.Request;
|
||||
import com.squareup.okhttp.RequestBody;
|
||||
import com.squareup.okhttp.Response;
|
||||
|
||||
import org.json.JSONObject;
|
||||
|
||||
@@ -35,9 +40,10 @@ import java.util.concurrent.TimeUnit;
|
||||
@SuppressWarnings("unchecked")
|
||||
public final class EhClient {
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
private static final String TAG = EhClient.class.getSimpleName();
|
||||
|
||||
public static final MediaType JSON = MediaType.parse("application/json; charset=utf-8");
|
||||
|
||||
public static final int SOURCE_G = 0x0;
|
||||
public static final int SOURCE_EX = 0x1;
|
||||
public static final int SOURCE_LOFI = 0x2;
|
||||
@@ -47,7 +53,7 @@ public final class EhClient {
|
||||
public static final long APIUID = 1363542;
|
||||
public static final String APIKEY = "f4b5407ab1727b9d08d7";
|
||||
|
||||
private static final String LOGIN_URL =
|
||||
private static final String SIGN_IN_URL =
|
||||
"http://forums.e-hentai.org/index.php?act=Login&CODE=01";
|
||||
private static final String FORUMS_URL = "http://forums.e-hentai.org/index.php";
|
||||
|
||||
@@ -61,8 +67,14 @@ public final class EhClient {
|
||||
|
||||
public static final String API_EHVIEWER = "http://www.ehviewer.com/API";
|
||||
|
||||
private static final String SAD_PANDA_DISPOSITION = "inline; filename=\"sadpanda.jpg\"";
|
||||
private static final String SAD_PANDA_TYPE = "image/gif";
|
||||
private static final String SAD_PANDA_LENGTH = "9615";
|
||||
|
||||
private final ThreadPoolExecutor mRequestThreadPool;
|
||||
|
||||
private final EhOkHttpClient mHttpClient;
|
||||
|
||||
private static final EhClient sInstance;
|
||||
|
||||
static {
|
||||
@@ -80,6 +92,8 @@ public final class EhClient {
|
||||
Process.THREAD_PRIORITY_BACKGROUND);
|
||||
mRequestThreadPool = new ThreadPoolExecutor(poolSize, poolSize,
|
||||
1L, TimeUnit.SECONDS, requestWorkQueue, threadFactory);
|
||||
|
||||
mHttpClient = EhOkHttpClient.getInstance();
|
||||
}
|
||||
|
||||
public static String getReadableHost(int source) {
|
||||
@@ -106,7 +120,7 @@ public final class EhClient {
|
||||
}
|
||||
}
|
||||
|
||||
public interface EhClientListener {
|
||||
public interface SimpleListener {
|
||||
void onFailure(Exception e);
|
||||
}
|
||||
|
||||
@@ -134,10 +148,10 @@ public final class EhClient {
|
||||
|
||||
private abstract class SimpleBgJobHelper implements BgJobHelper {
|
||||
|
||||
private EhClientListener mListener;
|
||||
private SimpleListener mListener;
|
||||
private Exception mException;
|
||||
|
||||
public SimpleBgJobHelper(EhClientListener listener) {
|
||||
public SimpleBgJobHelper(SimpleListener listener) {
|
||||
mListener = listener;
|
||||
}
|
||||
|
||||
@@ -166,26 +180,37 @@ public final class EhClient {
|
||||
public abstract void doSuccessCallback();
|
||||
}
|
||||
|
||||
private void checkRequest(EhHttpHelper ehh) throws ResponseCodeException {
|
||||
final int responseCode = ehh.getResponseCode();
|
||||
private void checkResponse(Response response) throws Exception {
|
||||
final int responseCode = response.code();
|
||||
if (responseCode >= 400) {
|
||||
throw new ResponseCodeException(responseCode);
|
||||
}
|
||||
|
||||
String disposition = response.header("Content-Disposition", null);
|
||||
String type = response.header("Content-Type", null);
|
||||
String length = response.header("Content-Length", null);
|
||||
|
||||
if (SAD_PANDA_DISPOSITION.equals(disposition) && SAD_PANDA_TYPE.equals(type) &&
|
||||
SAD_PANDA_LENGTH.equals(length)) {
|
||||
throw new EhException("Sad Panda");
|
||||
}
|
||||
}
|
||||
|
||||
private Object[] doGetGalleryList(int source, String url) throws Exception {
|
||||
EhHttpHelper ehh = EhHttpHelper.obtain();
|
||||
String body = ehh.get(url);
|
||||
|
||||
checkRequest(ehh);
|
||||
EhHttpHelper.recycle(ehh);
|
||||
private Object[] doGetGalleryList(int source, String url) throws Exception {
|
||||
Request request = new Request.Builder()
|
||||
.url(url)
|
||||
.build();
|
||||
Response response = mHttpClient.newCall(request).execute();
|
||||
|
||||
checkResponse(response);
|
||||
|
||||
GalleryListParser parser = new GalleryListParser();
|
||||
parser.parse(body, source);
|
||||
parser.parse(response.body().string(), source);
|
||||
return new Object[]{parser.giList, parser.pageNum};
|
||||
}
|
||||
|
||||
public abstract static class OnGetGalleryListListener implements EhClientListener {
|
||||
public abstract static class OnGetGalleryListListener implements SimpleListener {
|
||||
public abstract void onSuccess(List<GalleryInfo> glList, int pageNum);
|
||||
}
|
||||
|
||||
@@ -230,26 +255,29 @@ public final class EhClient {
|
||||
doBgJob(new GetGalleryListHelper(source, url, listener));
|
||||
}
|
||||
|
||||
|
||||
private Object[] doGetPopular() throws Exception {
|
||||
final JSONObject json = new JSONObject();
|
||||
json.put("method", "popular");
|
||||
RequestBody body = RequestBody.create(JSON, json.toString());
|
||||
|
||||
EhHttpHelper ehh = EhHttpHelper.obtain();
|
||||
String body = ehh.postJson(API_EHVIEWER, json);
|
||||
Request request = new Request.Builder()
|
||||
.url(API_EHVIEWER)
|
||||
.post(body)
|
||||
.build();
|
||||
Response response = mHttpClient.newCall(request).execute();
|
||||
|
||||
checkRequest(ehh);
|
||||
EhHttpHelper.recycle(ehh);
|
||||
checkResponse(response);
|
||||
|
||||
PopularParser parser = new PopularParser();
|
||||
parser.parse(body);
|
||||
parser.parse(response.body().string());
|
||||
return new Object[]{parser.galleryInfoList, parser.timeStamp};
|
||||
}
|
||||
|
||||
public abstract static class OnGetPopularListener implements EhClientListener {
|
||||
public abstract static class OnGetPopularListener implements SimpleListener {
|
||||
public abstract void onSuccess(List<GalleryInfo> 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));
|
||||
}
|
||||
}
|
||||
@@ -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("<p>You are now logged in as: (.+?)<br />");
|
||||
m = p.matcher(body);
|
||||
if (m.find()) {
|
||||
displayname = m.group(1);
|
||||
return true;
|
||||
} else {
|
||||
p = Pattern.compile("(?:<h4>The error returned was:</h4>\\s*<p>(.+?)</p>)"
|
||||
+ "|(?:<span class=\"postcolor\">(.+?)</span>)");
|
||||
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
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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<EhHttpHelper> 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);
|
||||
}
|
||||
}
|
||||
@@ -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<String, List<String>> get(URI uri, Map<String, List<String>> 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<String> cookieList = new ArrayList<>();
|
||||
cookieList.add(cookie.toString());
|
||||
// Map to return
|
||||
Map<String, List<String>> cookieMap = new HashMap<>(requestHeaders);
|
||||
cookieMap.put("Cookie" , cookieList);
|
||||
|
||||
return Collections.unmodifiableMap(cookieMap);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void put(URI uri, Map<String, List<String>> responseHeaders) throws IOException {
|
||||
Cookie cookie = new Cookie();
|
||||
|
||||
List<String> 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));
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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 ******/
|
||||
|
||||
@@ -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() {
|
||||
|
||||
@@ -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<String, String> 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();
|
||||
}
|
||||
}
|
||||
@@ -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 <code>haha=hehe; fere=bfdgds</code>
|
||||
*
|
||||
* @param raw the raw string
|
||||
* @return the key is toLowerCase
|
||||
*/
|
||||
public static @NonNull Map<String, String> parseMap(@Nullable String raw) {
|
||||
Map<String, String> 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<String> 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<String, String> 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<FormData> mDataList;
|
||||
|
||||
|
||||
public PostFormDataHelper(String url, List<FormData> 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<FormData> 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));
|
||||
}
|
||||
}
|
||||
@@ -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");
|
||||
}
|
||||
}
|
||||
@@ -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");
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user