Mega Code Archive

 
Categories / Android / Network
 

Http Downloader

//package org.terukusu.android.util; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.UnsupportedEncodingException; import java.net.SocketTimeoutException; import java.net.URLDecoder; import java.net.URLEncoder; import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.Date; import java.util.HashMap; import java.util.List; import java.util.Locale; import java.util.Map; import java.util.regex.Matcher; import java.util.regex.Pattern; import org.apache.http.Header; import org.apache.http.NameValuePair; import org.apache.http.client.ClientProtocolException; import org.apache.http.client.HttpClient; import org.apache.http.client.entity.UrlEncodedFormEntity; import org.apache.http.client.methods.HttpGet; import org.apache.http.client.methods.HttpPost; import org.apache.http.client.methods.HttpUriRequest; import org.apache.http.impl.client.DefaultHttpClient; import org.apache.http.message.BasicNameValuePair; import org.apache.http.params.CoreConnectionPNames; import android.util.Log; /**  * Web???????????????????????  *   * @author Teruhiko Kusunoki&lt;<a  *         href="teru.kusu@gmail.com">teru.kusu@gmail.com</a>&gt;  *   */ public class HttpDownloader {   /**    * TAG for {@link android.util.Log}    */   private static final String TAG = HttpDownloader.class.getSimpleName();   public static enum Method {     POST, GET   }   private static final int DEFAULT_BUFFER_SIZE = 4096;   private static final int DEFAULT_CONNECTION_TIMEOUT = 10000;   private static final int DEFAULT_SO_TIMEOUT = 10000;   /** URL?????????????????? */   private String encoding = StringUtils.getDefaultEncoding();   private Method method = Method.GET;   private String url;   private Map<String, String> queries;   private Map<String, String> cookies;   private Map<String, String> headers;   private int bufferSize = DEFAULT_BUFFER_SIZE;   private int connectionTimeout = DEFAULT_CONNECTION_TIMEOUT;   private int soTimeout = DEFAULT_SO_TIMEOUT;   /** ??????????Content-Length????? */   private long contentLength;   /** ??????????????? */   private long elapsed;   /** ??????????? */   private long downloaded;   /** ??????(bps) */   private long avarageSpeed;   /** ??????????????? */   private boolean isCanceled = false;   /**    * ????????????????    *     */   public HttpDownloader() {   }   /**    * ????????????????    *     * @param url    *            URL???    */   public HttpDownloader(String url) {     setUrl(url);   }   /**    * ????????????????    *     * @param url    *            URL    * @param queries    *            ???    */   public HttpDownloader(String url, Map<String, String> queries) {     this.url = url;     this.queries = queries;   }   public HttpDownloader(String url, Map<String, String> queries,       Map<String, String> cookies) {     this.url = url;     this.queries = queries;     this.cookies = cookies;   }   /**    * ????????????    *     * @throws SocketTimeoutException    *             ????????????????????????    * @throws ClientProtocolException    *             ?????????????????    * @throws IOException    *             ?????????????    */   public HttpResponse execute() throws SocketTimeoutException,       ClientProtocolException, IOException {     long start = System.currentTimeMillis();     HttpUriRequest request = null;     List<NameValuePair> postParams = new ArrayList<NameValuePair>();     if (Method.POST == getMethod()) {       HttpPost post = new HttpPost(getUrl());       if (getQueries() != null) {         for (Map.Entry<String, String> entry : getQueries().entrySet()) {           postParams.add(new BasicNameValuePair(entry.getKey(), entry               .getValue()));         }       }       post.setEntity(new UrlEncodedFormEntity(postParams, getEncoding()));       request = post;     } else {       StringBuilder sb = new StringBuilder(getUrl());       if (getQueries() != null) {         if (sb.indexOf("?") >= 0) {           sb.append('&');         } else {           sb.append('?');         }         sb.append(makeQueryString(getQueries()));       }       String fullUrl = sb.toString();       HttpGet get = new HttpGet(fullUrl);       request = get;     }     // ????     if (getCookies() != null) {       String cookieStr = makeCookieString(getCookies());       request.addHeader("Cookie", cookieStr);     }     if (getHeaders() != null) {       for (Map.Entry<String, String> entry : getHeaders().entrySet()) {         request.addHeader(entry.getKey(),             URLEncoder.encode(entry.getValue(), getEncoding()));       }     }     HttpClient client = new DefaultHttpClient();     client.getParams()         .setIntParameter(CoreConnectionPNames.CONNECTION_TIMEOUT,             getConnectionTimeout());     client.getParams().setIntParameter(CoreConnectionPNames.SO_TIMEOUT,         getSoTimeout());     org.apache.http.HttpResponse hr = null;     HttpResponse res = new HttpResponse();     hr = client.execute(request);     // ??     res.setStatusCode(hr.getStatusLine().getStatusCode());     // header     for (Header header : hr.getAllHeaders()) {       res.setHeader(header.getName(), header.getValue());     }     // cookie     for (Header header : hr.getHeaders("Set-Cookie")) {       String cookieEntry = header.getValue();       Cookie cookie = Cookie.parseCookie(cookieEntry, null);       res.setCookie(cookie.getKey(), cookie);     }     // body     if (hr.getEntity() == null) {       return res;     }     // ?????     Header contentTypeHeader = hr.getEntity().getContentType();     if (contentTypeHeader != null) {       String contentType = contentTypeHeader.getValue();       if (contentType != null) {         Pattern p = Pattern.compile(             "text/[^;]+(\\s*;\\s*charset\\s*=\\s*(.+))?",             Pattern.CASE_INSENSITIVE);         Matcher m = p.matcher(contentType);         if (m.find() && !StringUtils.isBlank(m.group(2))) {           res.setCharacterEncoding(m.group(2));         }       }     }     setContentLength(hr.getEntity().getContentLength());     res.setContentLength(hr.getEntity().getContentLength());     ByteArrayOutputStream baos = null;     InputStream is = null;     try {       baos = new ByteArrayOutputStream();       is = hr.getEntity().getContent();       byte[] buff = new byte[getBufferSize()];       int readSize = 0;       while (!isCanceled()) {         if (Thread.interrupted()) {           // ??????????           Thread.currentThread().interrupt();           synchronized (this) {             isCanceled = true;           }           break;         }         if ((readSize = is.read(buff)) < 0) {           // ??????           break;         }         synchronized (this) {           setDownloaded(getDownloaded() + readSize);           setElapsed(System.currentTimeMillis() - start);           long elapsedSec = getElapsed() / 1000;           if (elapsedSec == 0) {             setAvarageSpeed(getDownloaded());           } else {             setAvarageSpeed(getDownloaded() / elapsedSec);           }         }         baos.write(buff, 0, readSize);       }       Log.v(TAG, "downloaded: avarage speed = " + getAvarageSpeed()           + " bps, downloaded = " + getDownloaded() + " bytes");       if (isCanceled()) {         // ?DL??DL???         request.abort();       }     } finally {       try {         baos.close();       } catch (Exception ignore) {       }       try {         is.close();       } catch (Exception ignore) {       }     }     res.setBody(baos.toByteArray());     return res;   }   /**    * ?????URL??????????????    *     * @param params    *            ???    * @return ??????    */   private String makeQueryString(Map<String, String> params) {     StringBuilder sb = new StringBuilder();     for (Map.Entry<String, String> entry : params.entrySet()) {       if (sb.length() > 0) {         sb.append("&");       }       try {         sb.append(entry.getKey())             .append("=")             .append(URLEncoder.encode(entry.getValue(),                 getEncoding()));       } catch (UnsupportedEncodingException e) {         throw new RuntimeException(e.getMessage(), e);       }     }     return sb.toString();   }   /**    * Cookie??????????????????????    *     * @param cookies    *            ???????????????    * @return Cookie??????????    */   private String makeCookieString(Map<String, String> cookies) {     StringBuilder sb = new StringBuilder();     for (Map.Entry<String, String> entry : cookies.entrySet()) {       if (sb.length() > 0) {         sb.append("; ");       }       sb.append(entry.getKey()).append("=").append(entry.getValue());     }     return sb.toString();   }   /**    * ????????????    */   public synchronized void cancel() {     isCanceled = true;   }   /**    * ???????(bps)???    *     * @return ???????    */   public synchronized long getSpeed() {     // TODO implement     return 0;   }   /**    * encoding ???????    *     * @return encoding    */   public synchronized String getEncoding() {     return encoding;   }   /**    * encoding ???????    *     * @param encoding    *            ????? encoding    */   public synchronized void setEncoding(String encoding) {     this.encoding = encoding;   }   /**    * method ???????    *     * @return method    */   public synchronized Method getMethod() {     return method;   }   /**    * method ???????    *     * @param method    *            ????? method    */   public synchronized void setMethod(Method method) {     this.method = method;   }   /**    * url ???????    *     * @return url    */   public synchronized String getUrl() {     return url;   }   /**    * url ???????    *     * @param url    *            ????? url    */   public synchronized void setUrl(String url) {     this.url = url;   }   /**    * queries ???????    *     * @return queries    */   public synchronized Map<String, String> getQueries() {     return queries;   }   /**    * queries ???????    *     * @param queries    *            ????? queries    */   public synchronized void setQueries(Map<String, String> queries) {     this.queries = queries;   }   /**    * elapsed ???????    *     * @return elapsed    */   public synchronized long getElapsed() {     return elapsed;   }   /**    * elapsed ???????    *     * @param elapsed    *            ????? elapsed    */   public synchronized void setElapsed(long elapsed) {     this.elapsed = elapsed;   }   /**    * bufferSize ???????    *     * @return bufferSize    */   public synchronized int getBufferSize() {     return bufferSize;   }   /**    * bufferSize ???????    *     * @param bufferSize    *            ????? bufferSize    */   public synchronized void setBufferSize(int bufferSize) {     this.bufferSize = bufferSize;   }   /**    * cookies ???????    *     * @return cookies    */   public synchronized Map<String, String> getCookies() {     return cookies;   }   /**    * cookies ???????    *     * @param cookies    *            ????? cookies    */   public synchronized void setCookies(Map<String, String> cookies) {     this.cookies = cookies;   }   /**    * contentLength ???????    *     * @return contentLength    */   public synchronized long getContentLength() {     return contentLength;   }   /**    * contentLength ???????    *     * @param contentLength    *            ????? contentLength    */   protected synchronized void setContentLength(long contentLength) {     this.contentLength = contentLength;   }   /**    * downloaded ???????    *     * @return downloaded    */   public synchronized long getDownloaded() {     return downloaded;   }   /**    * downloaded ???????    *     * @param downloaded    *            ????? downloaded    */   protected synchronized void setDownloaded(long downloaded) {     this.downloaded = downloaded;   }   /**    * isCanceled ???????    *     * @return isCanceled    */   public synchronized boolean isCanceled() {     return isCanceled;   }   /**    * isCanceled ???????    *     * @param isCanceled    *            ????? isCanceled    */   protected synchronized void setCanceled(boolean isCanceled) {     this.isCanceled = isCanceled;   }   /**    * avarageSpeed ???????    *     * @return avarageSpeed    */   public synchronized long getAvarageSpeed() {     return avarageSpeed;   }   /**    * avarageSpeed ???????    *     * @param avarageSpeed    *            ????? avarageSpeed    */   protected synchronized void setAvarageSpeed(long avarageSpeed) {     this.avarageSpeed = avarageSpeed;   }   /**    * connectionTimeout ???????    *     * @return connectionTimeout    */   public synchronized int getConnectionTimeout() {     return connectionTimeout;   }   /**    * connectionTimeout ???????    *     * @param connectionTimeout    *            ????? connectionTimeout    */   public synchronized void setConnectionTimeout(int connectionTimeout) {     this.connectionTimeout = connectionTimeout;   }   /**    * soTimeout ???????    *     * @return soTimeout    */   public synchronized int getSoTimeout() {     return soTimeout;   }   /**    * soTimeout ???????    *     * @param soTimeout    *            ????? soTimeout    */   public synchronized void setSoTimeout(int soTimeout) {     this.soTimeout = soTimeout;   }   /**    * headers ???????    *     * @return headers    */   public synchronized Map<String, String> getHeaders() {     return headers;   }   /**    * headers ???????    *     * @param headers    *            ????? headers    */   public synchronized void setHeaders(Map<String, String> headers) {     this.headers = headers;   } } /**  * @author Teruhiko Kusunoki&lt;<a  *         href="teru.kusu@gmail.com">teru.kusu@gmail.com</a>&gt;  *   */ class HttpResponse {   private int statusCode;   private long contentLength;   private String characterEncoding;   private final Map<String, String> headers = new HashMap<String, String>();   private final Map<String, Cookie> cookies = new HashMap<String, Cookie>();   private byte[] body;   /**    *    */   public HttpResponse() {   }   public void setHeader(String name, String value) {     this.headers.put(name, value);   }   /**    * header ???????    *     * @return headers    */   public String getHeader(String name) {     return this.headers.get(name);   }   /**    * headers ???????    *     * @return headers    */   public Map<String, String> getHeaders() {     return headers;   }   /**    * ???????????    *     * @param name    *            ??    * @return ????    */   public Cookie getCookie(String name) {     return this.cookies.get(name);   }   /**    * ???????????    *     * @param name    *            ??    * @param cookie    *            ????    */   public void setCookie(String name, Cookie cookie) {     this.cookies.put(name, cookie);   }   /**    * cookies ???????    *     * @return cookies    */   public Map<String, Cookie> getCookies() {     return cookies;   }   /**    * body ???????    *     * @return body    */   public byte[] getBody() {     return body;   }   /**    * body ???????    *     * @param body    *            ????? body    */   public void setBody(byte[] body) {     this.body = body;   }   /**    * statusCode ???????    *     * @return statusCode    */   public int getStatusCode() {     return statusCode;   }   /**    * statusCode ???????    *     * @param statusCode    *            ????? statusCode    */   public void setStatusCode(int statusCode) {     this.statusCode = statusCode;   }   /**    * contentLength ???????    *     * @return contentLength    */   public long getContentLength() {     return contentLength;   }   /**    * contentLength ???????    *     * @param contentLength    *            ????? contentLength    */   public void setContentLength(long contentLength) {     this.contentLength = contentLength;   }   /**    * characterEncoding ??????? ????????? text/* ? charset ??????????????????    *     * @return characterEncoding    */   public String getCharacterEncoding() {     return characterEncoding;   }   /**    * characterEncoding ???????    *     * @param characterEncoding    *            ????? characterEncoding    */   public void setCharacterEncoding(String characterEncoding) {     this.characterEncoding = characterEncoding;   } } /**  * ?????????????????????????????  *   * @author Teruhiko Kusunoki&lt;<a  *         href="teru.kusu@gmail.com">teru.kusu@gmail.com</a>&gt;  *   */ class StringUtils {   /**    * ??????????????????????????????    */   private static final Pattern BLANK_PATTERN = Pattern.compile("^\\s*$");   /**    * ????????????????    *     * @param str    *            ????????    * @return ?????null???true??????false    */   public static boolean isEmpty(String str) {     return (str == null || str.length() == 0);   }   /**    * null????????????????????????????????????    *     * @param str    *            ????????    * @return null???????????????????????????? true??????false?    */   public static boolean isBlank(String str) {     return (str == null || BLANK_PATTERN.matcher(str).matches());   }   /**    * ????????????????????????????????    *     * @return ?????????????????????????    */   public static String getDefaultEncoding() {     return System.getProperty("file.encoding");   }   /**    * Base64??????????????????????????????????? ?: Mzg1OTQyMjczMA== =>    * 3859422730 => 0xE60A1E0A => 10.30.10.230    *     * @param str    *            Base64????????????????    * @return ???????????    */   public static String base64toInetAddress(String str) {     // TODO ??     throw new UnsupportedOperationException();     // String numStr = new String(Base64.decode(str, Base64.DEFAULT));     // int num = Integer.parseInt(numStr);     //     // String ipAddr = (num & 0xFF) + "." + (num >> 8 & 0xFF) + "."     // + (num >> 16 & 0xFF) + "." + (num >> 24 & 0xFF);     //     // return ipAddr;   } } /**  * @author Teruhiko Kusunoki&lt;<a  *         href="teru.kusu@gmail.com">teru.kusu@gmail.com</a>&gt;  *   */ class Cookie {   private String key;   private String value;   private String path;   private Date expire;   private String domain;   private boolean secure = false;   /**    * Set-Cookie ??????????????????????????? ?????????????    *     * @param cookieHeader    *            Set-Cookie?????    * @return ??????????    * @throws ParseException    *             ?????????    */   public static Cookie parseCookie(String cookieHeader) {     return parseCookie(cookieHeader, null);   }   /**    * Set-Cookie ???????????????????????????    *     * @param cookieHeader    *            Set-Cookie?????    * @param encode    *            cookie???????. null?????????????????    * @return ??????????    * @throws ParseException    *             ?????????    */   public static Cookie parseCookie(String cookieHeader, String encode) {     Cookie c = new Cookie();     for (String str : cookieHeader.split("\\s*;\\s*")) {       int index = str.indexOf('=');       if (index < 0) {         if ("secure".equals(str.toLowerCase())) {           c.setSecure(true);         }         continue;       }       String key = str.substring(0, index).toLowerCase();       String value = str.substring(index + 1);       if ("expires".equals(key.toLowerCase())) {         SimpleDateFormat sdf = new SimpleDateFormat(             "EEE, d-MMM-yyyy HH:mm:ss ZZZ", Locale.US);         Date date = null;         try {           date = sdf.parse(value);         } catch (ParseException e) {           throw new RuntimeException(e.getMessage(), e);         }         c.setExpire(date);       } else if ("domain".equals(key.toLowerCase())) {         c.setDomain(value);       } else if ("path".equals(key.toLowerCase())) {         c.setPath(value);       } else {         c.setKey(key);         if (StringUtils.isBlank(encode)) {           c.setValue(value);         } else {           try {             c.setValue(URLDecoder.decode(value, encode));           } catch (UnsupportedEncodingException e) {             throw new RuntimeException(e.getMessage(), e);           }         }       }     }     return c;   }   /**    * key ???????    *     * @return key    */   public String getKey() {     return key;   }   /**    * key ???????    *     * @param key    *            ????? key    */   public void setKey(String key) {     this.key = key;   }   /**    * value ???????    *     * @return value    */   public String getValue() {     return value;   }   /**    * value ???????    *     * @param value    *            ????? value    */   public void setValue(String value) {     this.value = value;   }   /**    * path ???????    *     * @return path    */   public String getPath() {     return path;   }   /**    * path ???????    *     * @param path    *            ????? path    */   public void setPath(String path) {     this.path = path;   }   /**    * expire ???????    *     * @return expire    */   public Date getExpire() {     return expire;   }   /**    * expire ???????    *     * @param expire    *            ????? expire    */   public void setExpire(Date expire) {     this.expire = expire;   }   /**    * domain ???????    *     * @return domain    */   public String getDomain() {     return domain;   }   /**    * domain ???????    *     * @param domain    *            ????? domain    */   public void setDomain(String domain) {     this.domain = domain;   }   /**    * secure ???????    *     * @return secure    */   public boolean isSecure() {     return secure;   }   /**    * secure ???????    *     * @param secure    *            ????? secure    */   public void setSecure(boolean secure) {     this.secure = secure;   } }