diff --git a/res/values-zh-rCN/strings.xml b/res/values-zh-rCN/strings.xml
index cebe5c14e..04ecea792 100644
--- a/res/values-zh-rCN/strings.xml
+++ b/res/values-zh-rCN/strings.xml
@@ -144,6 +144,7 @@
非预期的响应码:%d
太多重定向
主机错误
+ 获取正文失败
无效的请求
未挂载 SD卡
diff --git a/res/values/strings.xml b/res/values/strings.xml
index 1ea76b8ef..64eef3048 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -145,6 +145,7 @@
Unexpected response code : %d
Too many redirects
Host error
+ Get body error
Invalid request
SD card is Unmounted
diff --git a/src/com/hippo/ehviewer/GallerysDownloader.java b/src/com/hippo/ehviewer/GallerysDownloader.java
index 1934d86b8..f90259091 100644
--- a/src/com/hippo/ehviewer/GallerysDownloader.java
+++ b/src/com/hippo/ehviewer/GallerysDownloader.java
@@ -131,9 +131,4 @@ public class GallerysDownloader {
void onGalleryDownloadFailed(DownloadInfo downloadInfo, String eMsg);
void onGalleryDownloadCompleted(DownloadInfo downloadInfo);
}
-
-
-
-
-
}
diff --git a/src/com/hippo/ehviewer/ehclient/EhClient.java b/src/com/hippo/ehviewer/ehclient/EhClient.java
index a2a0aaa46..2e4ccdc71 100644
--- a/src/com/hippo/ehviewer/ehclient/EhClient.java
+++ b/src/com/hippo/ehviewer/ehclient/EhClient.java
@@ -272,7 +272,8 @@ public class EhClient {
final HttpHelper hp = new HttpHelper(mAppContext);
hp.setOnRespondListener(new HttpHelper.OnRespondListener() {
@Override
- public void onSuccess(String body) {
+ public void onSuccess(Object obj) {
+ String body = (String)obj;
LoginParser parser = new LoginParser();
if (parser.parser(body)) {
mInfo.login(username, parser.displayname);
@@ -360,7 +361,8 @@ public class EhClient {
HttpHelper hp = new HttpHelper(mAppContext);
hp.setOnRespondListener(new HttpHelper.OnRespondListener() {
@Override
- public void onSuccess(String body) {
+ public void onSuccess(Object obj) {
+ String body = (String)obj;
ListParser parser = new ListParser();
switch (parser.parser(body)) {
case ListParser.ALL:
@@ -398,7 +400,8 @@ public class EhClient {
HttpHelper hp = new HttpHelper(mAppContext);
hp.setOnRespondListener(new HttpHelper.OnRespondListener() {
@Override
- public void onSuccess(String body) {
+ public void onSuccess(Object obj) {
+ String body = (String)obj;
DetailParser parser = new DetailParser();
int mode = DetailParser.DETAIL | DetailParser.TAG
| DetailParser.PREVIEW_INFO | DetailParser.PREVIEW
@@ -463,7 +466,8 @@ public class EhClient {
HttpHelper hp = new HttpHelper(mAppContext);
hp.setOnRespondListener(new HttpHelper.OnRespondListener() {
@Override
- public void onSuccess(String body) {
+ public void onSuccess(Object obj) {
+ String body = (String)obj;
DetailParser parser = new DetailParser();
parser.setMode(DetailParser.PREVIEW);
if (parser.parser(body) == DetailParser.PREVIEW) {
@@ -905,10 +909,11 @@ public class EhClient {
HttpHelper hp = new HttpHelper(mAppContext);
hp.setOnRespondListener(new HttpHelper.OnRespondListener() {
@Override
- public void onSuccess(String pageContent) {
+ public void onSuccess(Object obj) {
+ String body = (String)obj;
DetailParser parser = new DetailParser();
parser.setMode(DetailParser.COMMENT);
- if (parser.parser(pageContent) == DetailParser.COMMENT) {
+ if (parser.parser(body) == DetailParser.COMMENT) {
listener.onSuccess(parser.comments);
} else {
listener.onFailure("parser error"); // TODO
@@ -958,9 +963,10 @@ public class EhClient {
HttpHelper hp = new HttpHelper(mAppContext);
hp.setOnRespondListener(new HttpHelper.OnRespondListener() {
@Override
- public void onSuccess(String pageContext) {
+ public void onSuccess(Object obj) {
+ String body = (String)obj;
RateParser parser = new RateParser();
- if (parser.parser(pageContext)) {
+ if (parser.parser(body)) {
listener.onSuccess(parser.mRatingAvg, parser.mRatingCnt);
} else {
listener.onFailure("parser error"); // TODO
@@ -1008,9 +1014,10 @@ public class EhClient {
HttpHelper hp = new HttpHelper(mAppContext);
hp.setOnRespondListener(new HttpHelper.OnRespondListener() {
@Override
- public void onSuccess(String pageContext) {
+ public void onSuccess(Object obj) {
+ String body = (String)obj;
VoteParser parser = new VoteParser();
- if (parser.parser(pageContext)) {
+ if (parser.parser(body)) {
listener.onSuccess(parser.mTagPane);
} else {
listener.onFailure("parser error"); // TODO
@@ -1065,10 +1072,10 @@ public class EhClient {
HttpHelper hp = new HttpHelper(mAppContext);
hp.setOnRespondListener(new HttpHelper.OnRespondListener() {
@Override
- public void onSuccess(String pageContext) {
-
+ public void onSuccess(Object obj) {
+ String body = (String)obj;
AddToFavoriteParser parser = new AddToFavoriteParser();
- if (parser.parser(pageContext)) {
+ if (parser.parser(body)) {
listener.onSuccess();
// Analytics
Analytics.addToFavoriteGallery(mAppContext, gid, token);
@@ -1185,9 +1192,10 @@ public class EhClient {
HttpHelper hp = new HttpHelper(mAppContext);
hp.setOnRespondListener(new HttpHelper.OnRespondListener() {
@Override
- public void onSuccess(String pageContext) {
+ public void onSuccess(Object obj) {
+ String body = (String)obj;
ListParser parser = new ListParser();
- int re = parser.parser(pageContext);
+ int re = parser.parser(body);
if (re == ListParser.ALL) {
listener.onSuccess(parser.giList, parser.indexPerPage, parser.maxPage);
} else if (re == ListParser.NOT_FOUND) {
@@ -1240,10 +1248,11 @@ public class EhClient {
HttpHelper hp = new HttpHelper(mAppContext);
hp.setOnRespondListener(new HttpHelper.OnRespondListener() {
@Override
- public void onSuccess(String pageContext) {
+ public void onSuccess(Object obj) {
+ String body = (String)obj;
try {
List gis = new ArrayList();
- JSONObject js = new JSONObject(pageContext);
+ JSONObject js = new JSONObject(body);
js = js.getJSONObject("popular");
if (!js.has("galleries")) {
diff --git a/src/com/hippo/ehviewer/ehclient/EhInfo.java b/src/com/hippo/ehviewer/ehclient/EhInfo.java
index a9b577831..47e004265 100644
--- a/src/com/hippo/ehviewer/ehclient/EhInfo.java
+++ b/src/com/hippo/ehviewer/ehclient/EhInfo.java
@@ -48,6 +48,7 @@ public class EhInfo {
private static final Bitmap.CompressFormat AVATAR_FORMAT = Bitmap.CompressFormat.PNG;
private static Bitmap DEFAULT_AVATAR;
+ public static final String EX_HOST = "exhentai.org";
public static final String[] COOKIABLE_HOSTS = {"exhentai.org",
"g.e-hentai.org", "forums.e-hentai.org"};
diff --git a/src/com/hippo/ehviewer/exception/RedirectionException.java b/src/com/hippo/ehviewer/exception/RedirectionException.java
deleted file mode 100644
index e437a4e68..000000000
--- a/src/com/hippo/ehviewer/exception/RedirectionException.java
+++ /dev/null
@@ -1,21 +0,0 @@
-/*
- * Copyright (C) 2014 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
- * distributed under the License is distributed on an "AS IS" BASIS,
- * 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.exception;
-
-public class RedirectionException extends Exception {
- private static final long serialVersionUID = 1L;
-}
diff --git a/src/com/hippo/ehviewer/exception/ResponseCodeException.java b/src/com/hippo/ehviewer/exception/ResponseCodeException.java
deleted file mode 100644
index 867700fd7..000000000
--- a/src/com/hippo/ehviewer/exception/ResponseCodeException.java
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- * Copyright (C) 2014 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
- * distributed under the License is distributed on an "AS IS" BASIS,
- * 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.exception;
-
-public class ResponseCodeException extends Exception {
-
- private static final long serialVersionUID = 1L;
- private static final String eMsg = "Error response code";
- private int mResponseCode;
-
- public ResponseCodeException(int responseCode) {
- this(responseCode, eMsg);
- }
-
- public ResponseCodeException(int responseCode, String message) {
- super(message);
- mResponseCode = responseCode;
- }
-
- public int getResponseCode() {
- return mResponseCode;
- }
-}
diff --git a/src/com/hippo/ehviewer/exception/SadPandaException.java b/src/com/hippo/ehviewer/exception/SadPandaException.java
deleted file mode 100644
index e62383969..000000000
--- a/src/com/hippo/ehviewer/exception/SadPandaException.java
+++ /dev/null
@@ -1,21 +0,0 @@
-/*
- * Copyright (C) 2014 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
- * distributed under the License is distributed on an "AS IS" BASIS,
- * 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.exception;
-
-public class SadPandaException extends Exception {
- private static final long serialVersionUID = 1L;
-}
diff --git a/src/com/hippo/ehviewer/network/Downloader.java b/src/com/hippo/ehviewer/network/Downloader.java
index 1ae1c7794..f243301b7 100644
--- a/src/com/hippo/ehviewer/network/Downloader.java
+++ b/src/com/hippo/ehviewer/network/Downloader.java
@@ -36,8 +36,6 @@ import com.hippo.ehviewer.util.Log;
import com.hippo.ehviewer.R;
import com.hippo.ehviewer.exception.FileException;
import com.hippo.ehviewer.exception.NoSdCardException;
-import com.hippo.ehviewer.exception.RedirectionException;
-import com.hippo.ehviewer.exception.ResponseCodeException;
import com.hippo.ehviewer.exception.StopRequestException;
import com.hippo.ehviewer.util.Util;
@@ -146,13 +144,6 @@ public class Downloader implements Runnable {
else if (mException instanceof UnknownHostException)
return mContext.getString(R.string.em_unknown_host);
- else if (mException instanceof ResponseCodeException)
- return String.format(mContext.getString(R.string.em_unexpected_response_code),
- ((ResponseCodeException)mException).getResponseCode());
-
- else if (mException instanceof RedirectionException)
- return mContext.getString(R.string.em_redirection_error);
-
else if (mException instanceof SocketException)
return "SocketException : " + mException.getMessage();
@@ -267,7 +258,7 @@ public class Downloader implements Runnable {
continue;
default:
- throw new ResponseCodeException(responseCode);
+ //throw new ResponseCodeException(responseCode);
}
} catch (Exception e) {
throw e;
@@ -276,7 +267,7 @@ public class Downloader implements Runnable {
conn.disconnect();
}
}
- throw new RedirectionException();
+ //throw new RedirectionException();
}
/**
@@ -287,7 +278,7 @@ public class Downloader implements Runnable {
private void processResponseHeaders(HttpURLConnection conn) {
mTotalSize = conn.getContentLength();
- // bytes 500-999/1234
+ //
String range;
if ((range = conn.getHeaderField("Content-Range")) != null) { // Support Content-Range
boolean newNum = true;
diff --git a/src/com/hippo/ehviewer/network/HttpHelper.java b/src/com/hippo/ehviewer/network/HttpHelper.java
index dd8647346..ee143bb0d 100644
--- a/src/com/hippo/ehviewer/network/HttpHelper.java
+++ b/src/com/hippo/ehviewer/network/HttpHelper.java
@@ -16,24 +16,20 @@
package com.hippo.ehviewer.network;
-import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.DataOutputStream;
+import java.io.File;
+import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
-import java.net.CookieHandler;
-import java.net.CookieManager;
-import java.net.CookiePolicy;
+import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
-import java.net.ProtocolException;
import java.net.SocketException;
import java.net.SocketTimeoutException;
import java.net.URL;
import java.net.URLEncoder;
import java.net.UnknownHostException;
-import java.util.List;
-import java.util.Map;
import java.util.zip.GZIPInputStream;
import org.apache.http.conn.ConnectTimeoutException;
@@ -42,9 +38,7 @@ import org.json.JSONObject;
import com.hippo.ehviewer.R;
import com.hippo.ehviewer.ehclient.EhClient;
import com.hippo.ehviewer.ehclient.EhInfo;
-import com.hippo.ehviewer.exception.RedirectionException;
-import com.hippo.ehviewer.exception.ResponseCodeException;
-import com.hippo.ehviewer.exception.SadPandaException;
+import com.hippo.ehviewer.exception.StopRequestException;
import com.hippo.ehviewer.util.Constants;
import com.hippo.ehviewer.util.Ui;
import com.hippo.ehviewer.util.Util;
@@ -67,13 +61,18 @@ public class HttpHelper {
private static final String TAG = "HttpHelper";
public static final String SAD_PANDA_ERROR = "Sad Panda";
public static final String HAPPY_PANDA_BODY = "Happy Panda";
-
+ public static final String DOWNLOAD_STOP = "Stop";
+ public static final String DOWNLOAD_OK = "Download";
private static String DEFAULT_CHARSET = "utf-8";
private static String CHARSET_KEY = "charset=";
class Package {
+ Object obj;
OnRespondListener listener;
- String str;
+ public Package(Object obj, OnRespondListener listener) {
+ this.obj = obj;
+ this.listener = listener;
+ }
}
private static Handler mHandler;
@@ -90,13 +89,13 @@ public class HttpHelper {
public void handleMessage(Message msg) {
Package p = (Package)msg.obj;
OnRespondListener listener = p.listener;
- String str = p.str;
+ Object obj = p.obj;
switch (msg.what) {
case Constants.TRUE:
- listener.onSuccess(str);
+ listener.onSuccess(obj);
break;
case Constants.FALSE:
- listener.onFailure(str);
+ listener.onFailure((String)obj);
break;
}
}
@@ -104,7 +103,7 @@ public class HttpHelper {
}
public interface OnRespondListener {
- void onSuccess(String body);
+ void onSuccess(Object body);
void onFailure(String eMsg);
}
@@ -114,7 +113,6 @@ public class HttpHelper {
public HttpHelper(Context context) {
mContext = context;
-
mContext.getApplicationContext();
}
@@ -153,49 +151,13 @@ public class HttpHelper {
else if (e instanceof SadPandaException)
return SAD_PANDA_ERROR;
+ else if (e instanceof GetBodyException)
+ return "获取失败"; // TODO
+
else
return e.getMessage();
}
- private String getBody(HttpURLConnection conn)
- throws IOException {
- String pageContext = null;
- InputStream is = null;
- ByteArrayOutputStream baos = null;
- try {
- is = conn.getInputStream();
- String encoding = conn.getContentEncoding();
- if (encoding != null && encoding.equals("gzip"))
- is = new GZIPInputStream(is);
-
- int length = conn.getContentLength();
- if (length >= 0)
- baos = new ByteArrayOutputStream(length);
- else
- baos = new ByteArrayOutputStream();
-
- Util.copy(is, baos, Constant.BUFFER_SIZE);
-
- // Get charset
- String charset = null;
- String contentType = conn.getContentType();
- int index = -1;
- if (contentType != null
- && (index = contentType.indexOf(CHARSET_KEY)) != -1) {
- charset = contentType.substring(index + CHARSET_KEY.length());
- } else
- charset = DEFAULT_CHARSET;
-
- pageContext = baos.toString(charset);
- } catch (IOException e) {
- throw e;
- } finally {
- Util.closeStreamQuietly(is);
- Util.closeStreamQuietly(baos);
- }
- return pageContext;
- }
-
private boolean isUrlCookiable(URL url) {
String host = url.getHost();
for (String h : EhInfo.COOKIABLE_HOSTS) {
@@ -205,7 +167,7 @@ public class HttpHelper {
return false;
}
- private String requst(RequestHelper rh, String urlStr) {
+ private Object requst(RequestHelper rh, String urlStr) {
mException = null;
int redirectionCount = 0;
URL url = null;
@@ -221,7 +183,6 @@ public class HttpHelper {
while (redirectionCount++ < Constant.MAX_REDIRECTS) {
conn = (HttpURLConnection) url.openConnection();
conn.setInstanceFollowRedirects(true);
- conn.addRequestProperty("Accept-Encoding", "gzip");
conn.setRequestProperty("User-Agent", Constant.userAgent);
conn.setConnectTimeout(Constant.DEFAULT_TIMEOUT);
conn.setReadTimeout(Constant.DEFAULT_TIMEOUT);
@@ -237,32 +198,30 @@ public class HttpHelper {
case HttpURLConnection.HTTP_OK:
case HttpURLConnection.HTTP_PARTIAL:
// Test sad panda
- String contentType = conn.getHeaderField("Content-Type");
- if (contentType != null && contentType.equals("image/gif"))
- throw new SadPandaException();
+ if (url.getHost().equals(EhInfo.EX_HOST)) {
+ String contentType = conn.getHeaderField("Content-Type");
+ if (contentType != null && contentType.equals("image/gif"))
+ throw new SadPandaException();
+ }
// Store cookie if necessary
if (isCookiable)
EhInfo.getInstance(mContext).storeCookie(conn);
- // Get body if necessary
- String body = rh.isNeedBody();
- if (body == null)
- body = getBody(conn);
+ // Get object connection
+ Object obj = rh.onAfterConnect(conn);
// Send to UI thread if necessary
if (msg != null) {
- Package p = new Package();
- p.listener = mListener;
- p.str = body;
- msg.obj = p;
+ msg.obj = new Package(obj, mListener);
msg.what = Constants.TRUE;
mHandler.sendMessage(msg);
}
- return body;
+ return obj;
// redirect
case HttpURLConnection.HTTP_MOVED_PERM:
case HttpURLConnection.HTTP_MOVED_TEMP:
case HttpURLConnection.HTTP_SEE_OTHER:
case Constant.HTTP_TEMP_REDIRECT:
final String location = conn.getHeaderField("Location");
+ conn.disconnect();
url = new URL(url, location);
continue;
@@ -270,15 +229,13 @@ public class HttpHelper {
throw new ResponseCodeException(responseCode);
}
}
+ throw new RedirectionException();
} catch (Exception e) {
mException = e;
e.printStackTrace();
if (msg != null) {
- Package p = new Package();
- p.listener = mListener;
- p.str = getEMsg();
- msg.obj = p;
+ msg.obj = new Package(getEMsg(), mListener);
msg.what = Constants.FALSE;
mHandler.sendMessage(msg);
}
@@ -287,17 +244,23 @@ public class HttpHelper {
if (conn != null)
conn.disconnect();
}
- mException = new RedirectionException();
- return null;
}
- interface RequestHelper {
+ private interface RequestHelper {
+ /**
+ * Add header or do something else for HttpURLConnection before connect
+ * @param conn
+ * @throws Exception
+ */
public void onBeforeConnect(HttpURLConnection conn) throws Exception;
/**
- * If need body, return null, otherwise return a string used as body
+ * Get what do you need from HttpURLConnection after connect
+ * Return null means get error
+ * @param conn
* @return
+ * @throws Exception
*/
- public String isNeedBody();
+ public Object onAfterConnect(HttpURLConnection conn) throws Exception;
}
/**
@@ -306,35 +269,88 @@ public class HttpHelper {
private class CheckSpHelper implements RequestHelper {
@Override
public void onBeforeConnect(HttpURLConnection conn)
- throws ProtocolException {
+ throws Exception {
conn.setRequestMethod("HEAD");
}
@Override
- public String isNeedBody() {
+ public Object onAfterConnect(HttpURLConnection conn)
+ throws Exception {
return HAPPY_PANDA_BODY;
}
}
+ private abstract class GetStringHelper implements RequestHelper {
+ @Override
+ public void onBeforeConnect(HttpURLConnection conn)
+ throws Exception {
+ conn.addRequestProperty("Accept-Encoding", "gzip");
+ }
+
+ private String getBody(HttpURLConnection conn)
+ throws Exception {
+ String body = null;
+ InputStream is = null;
+ ByteArrayOutputStream baos = null;
+ try {
+ is = conn.getInputStream();
+ String encoding = conn.getContentEncoding();
+ if (encoding != null && encoding.equals("gzip"))
+ is = new GZIPInputStream(is);
+
+ int length = conn.getContentLength();
+ if (length >= 0)
+ baos = new ByteArrayOutputStream(length);
+ else
+ baos = new ByteArrayOutputStream();
+
+ Util.copy(is, baos, Constant.BUFFER_SIZE);
+
+ // Get charset
+ String charset = null;
+ String contentType = conn.getContentType();
+ int index = -1;
+ if (contentType != null
+ && (index = contentType.indexOf(CHARSET_KEY)) != -1) {
+ charset = contentType.substring(index + CHARSET_KEY.length());
+ } else
+ charset = DEFAULT_CHARSET;
+
+ body = baos.toString(charset);
+ if (body == null)
+ throw new GetBodyException();
+ } catch (Exception e) {
+ throw e;
+ } finally {
+ Util.closeStreamQuietly(is);
+ Util.closeStreamQuietly(baos);
+ }
+ return body;
+ }
+
+ @Override
+ public Object onAfterConnect(HttpURLConnection conn)
+ throws Exception {
+ return getBody(conn);
+ }
+ }
+
/**
* RequstHelper for GET method
*/
- private class GetHelper implements RequestHelper {
+ private class GetHelper extends GetStringHelper {
@Override
public void onBeforeConnect(HttpURLConnection conn)
- throws ProtocolException {
+ throws Exception {
+ super.onBeforeConnect(conn);
conn.setRequestMethod("GET");
}
- @Override
- public String isNeedBody() {
- return null;
- }
}
/**
* RequstHelper for post form data, use POST method
*/
- private class PostFormHelper implements RequestHelper {
+ private class PostFormHelper extends GetStringHelper {
private String[][] mArgs;
public PostFormHelper(String[][] args) {
@@ -344,6 +360,7 @@ public class HttpHelper {
@Override
public void onBeforeConnect(HttpURLConnection conn)
throws Exception {
+ super.onBeforeConnect(conn);
conn.setDoOutput(true);
conn.setDoInput(true);
conn.setUseCaches(false);
@@ -367,16 +384,12 @@ public class HttpHelper {
out.flush();
out.close();
}
- @Override
- public String isNeedBody() {
- return null;
- }
}
/**
* RequstHelper for post json, use POST method
*/
- private class PostJsonHelper implements RequestHelper {
+ private class PostJsonHelper extends GetStringHelper {
private JSONObject mJo;
public PostJsonHelper(JSONObject jo) {
@@ -385,6 +398,7 @@ public class HttpHelper {
@Override
public void onBeforeConnect(HttpURLConnection conn) throws Exception {
+ super.onBeforeConnect(conn);
conn.setDoOutput(true);
conn.setDoInput(true);
conn.setUseCaches(false);
@@ -396,18 +410,155 @@ public class HttpHelper {
out.flush();
out.close();
}
+ }
+
+ private class GetImageHelper implements RequestHelper {
@Override
- public String isNeedBody() {
- return null;
+ public void onBeforeConnect(HttpURLConnection conn)
+ throws Exception {
+ conn.setRequestMethod("GET");
+ }
+
+ @Override
+ public Object onAfterConnect(HttpURLConnection conn)
+ throws Exception {
+ Bitmap bmp = BitmapFactory.decodeStream(conn.getInputStream(), null, Ui.getBitmapOpt());
+ if (bmp == null)
+ throw new GetBodyException();
+ return bmp;
}
}
+ public interface OnDownloadListener {
+ public void onDownloadStartConnect();
+ /**
+ * If totalSize -1 for can't get length info
+ * @param totalSize
+ */
+ public void onDownloadStartDownload(int totalSize);
+ public void onDownloadStatusUpdate(int downloadSize, int totalSize);
+ /**
+ * FAILED or COMPLETED or STOPED
+ * @param status
+ */
+ public void onDownloadOver(int status, String eMsg);
+ }
+
+ public class DownloadControlor {
+ private boolean mStop = false;
+
+ public void stop() {
+ mStop = true;
+ }
+
+ public void reset() {
+ mStop = false;
+ }
+
+ public boolean isStop() {
+ return mStop;
+ }
+ }
+
+ private class DownloadHelper implements RequestHelper {
+ private File mDir;
+ private String mFileName;
+ private DownloadControlor mControlor;
+ private OnDownloadListener mListener;
+ private int mContentLength;
+ private int mReceivedSize;
+
+ public DownloadHelper(File dir, String fileName, DownloadControlor controlor, OnDownloadListener listener) {
+ mDir = dir;
+ mFileName = fileName;
+ mControlor = controlor;
+ mListener = listener;
+ }
+
+ @Override
+ public void onBeforeConnect(HttpURLConnection conn) throws Exception {
+ conn.setRequestMethod("GET");
+ conn.addRequestProperty("Range", "bytes=0-");
+ mListener.onDownloadStartConnect();
+ }
+
+ 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
+ contentLength = 0;
+ int step = 0;
+ boolean isNum = false;
+ char ch;
+ for (int i = 0; i < range.length(); i++) {
+ ch = range.charAt(i);
+ if (ch >= '0' && ch <= '9') {
+ if (!isNum) {
+ isNum = true;
+ step++;
+ }
+ } else {
+ isNum = false;
+ }
+ if (isNum && step == 3)
+ contentLength = contentLength * 10 + ch - '0';
+ }
+ }
+ return contentLength;
+ }
+
+ @Override
+ public Object onAfterConnect(HttpURLConnection conn) throws Exception {
+ mContentLength = getContentLength(conn);
+ mListener.onDownloadStartDownload(mContentLength);
+
+ // Make sure parent exist
+ mDir.mkdirs();
+ File file = new File(mDir, mFileName);
+ try {
+ transferData(conn.getInputStream(), new FileOutputStream(file));
+ return DOWNLOAD_OK;
+ } catch (StopRequestException e) {
+ return DOWNLOAD_STOP;
+ } catch (Exception e) {
+ throw e;
+ }
+ }
+
+ private void transferData(InputStream in, OutputStream out)
+ throws Exception {
+ final byte data[] = new byte[Constant.BUFFER_SIZE];
+ mReceivedSize = 0;
+
+ while (true) {
+ if (mControlor.isStop())
+ throw new StopRequestException();
+
+ int bytesRead = in.read(data);
+ if (bytesRead == -1)
+ break;
+ out.write(data, 0, bytesRead);
+ mReceivedSize += bytesRead;
+
+ mListener.onDownloadStatusUpdate(mReceivedSize, mContentLength);
+ }
+
+ if (mContentLength != -1 && mReceivedSize != mContentLength)
+ throw new UncompletedException();
+ }
+
+ }
+
/**
- * Check Sad Panda
+ * Check Sad Panda.
+ * If get Sad Panda, return null,
+ * else return HttpHelper.HAPPY_PANDA_BODY
* @return
*/
public String checkSadPanda() {
- return requst(new CheckSpHelper(), EhClient.EX_HEADER);
+ return (String)requst(new CheckSpHelper(), EhClient.EX_HEADER);
}
/**
@@ -416,7 +567,7 @@ public class HttpHelper {
* @return
*/
public String get(String url) {
- return requst(new GetHelper(), url);
+ return (String)requst(new GetHelper(), url);
}
/**
@@ -426,7 +577,7 @@ public class HttpHelper {
* @return
*/
public String postForm(String url, String[][] args) {
- return requst(new PostFormHelper(args), url);
+ return (String)requst(new PostFormHelper(args), url);
}
/**
@@ -436,55 +587,59 @@ public class HttpHelper {
* @return
*/
public String postJson(String url, JSONObject json) {
- return requst(new PostJsonHelper(json), url);
+ return (String)requst(new PostJsonHelper(json), url);
}
- public Bitmap getImage(String urlStr) {
- mException = null;
+ /**
+ * Get image
+ * @param url
+ * @return
+ */
+ public Bitmap getImage(String url) {
+ return (Bitmap)requst(new GetImageHelper(), url);
+ }
+
+ public String download(String url, File dir, String file,
+ DownloadControlor controlor, OnDownloadListener listener) {
+ return (String)requst(new DownloadHelper(dir, file,
+ controlor, listener), url);
+ }
+
+ /** Exceptions **/
+
+ public class SadPandaException extends Exception {
+ private static final long serialVersionUID = 1L;
+ }
+
+ public class GetBodyException extends Exception {
+ private static final long serialVersionUID = 1L;
+ }
+
+ public class RedirectionException extends Exception {
+ private static final long serialVersionUID = 1L;
+ }
+
+ public class UncompletedException extends Exception {
+ private static final long serialVersionUID = 1L;
+ }
+
+ public class ResponseCodeException extends Exception {
- int redirectionCount = 0;
- URL url = null;
- HttpURLConnection conn = null;
+ private static final long serialVersionUID = 1L;
+ private static final String eMsg = "Error response code";
+ private int mResponseCode;
- try {
- Log.d(TAG, "Http get image " + urlStr);
- url = new URL(urlStr);
- while (redirectionCount++ < Constant.MAX_REDIRECTS) {
- conn = (HttpURLConnection)url.openConnection();
- conn.setRequestProperty("User-Agent", Constant.userAgent);
- conn.setConnectTimeout(Constant.DEFAULT_TIMEOUT);
- conn.setReadTimeout(Constant.DEFAULT_TIMEOUT);
- conn.setRequestMethod("GET");
- conn.connect();
-
- final int responseCode = conn.getResponseCode();
- switch (responseCode) {
- case HttpURLConnection.HTTP_OK:
- case HttpURLConnection.HTTP_PARTIAL:
- Bitmap bitmap = BitmapFactory.decodeStream(conn.getInputStream(), null, Ui.getBitmapOpt());
- return bitmap;
-
- case HttpURLConnection.HTTP_MOVED_PERM:
- case HttpURLConnection.HTTP_MOVED_TEMP:
- case HttpURLConnection.HTTP_SEE_OTHER:
- case Constant.HTTP_TEMP_REDIRECT:
- final String location = conn.getHeaderField("Location");
- url = new URL(url, location);
- continue;
-
- default:
- throw new ResponseCodeException(responseCode);
- }
- }
- } catch (Exception e) {
- mException = e;
- e.printStackTrace();
- return null;
- } finally {
- if (conn != null)
- conn.disconnect();
+ public ResponseCodeException(int responseCode) {
+ this(responseCode, eMsg);
+ }
+
+ public ResponseCodeException(int responseCode, String message) {
+ super(message);
+ mResponseCode = responseCode;
+ }
+
+ public int getResponseCode() {
+ return mResponseCode;
}
- mException = new RedirectionException();
- return null;
}
}