Http Downloader : Http Connection « Network « Android






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;
  }
}

   
    
    
    
  








Related examples in the same category

1.Http Connection
2.Using HttpGet to get the web response
3.Create Http connection
4.Http connection with
5.HttpGet and DefaultHttpClient
6.Http Post
7.Simple HTTP Request
8.Http Request Class
9.Http Get and Http Post
10.Get Text from HttpResponse
11.Http Request
12.Is Http Url Available
13.Http Retriever
14.Receive Response from HttpURLConnection
15.Print http headers. Useful for debugging.
16.Return the base URL from the given URL. Example: http://foo.org/abc.html -> http://foo.org/
17.Send message with HttpPost
18.Get Http Stream
19.Generic Object Http Loader
20.Http Get and DefaultHttpClient
21.Gets http output from URL
22.Util for Http Get
23.do Http Get Request and return the status code
24.Http Get
25.implements HttpClient
26.Get File From HTTP
27.Make all redirects to go to http in stead of https
28.New Http Client Manager
29.Http Client Manager
30.Multipart Post
31.Get Server Data
32.Yahoo News Crawler
33.Send Packet
34.Read a web page
35.parse Request Header
36.Data Send Utils
37.This class is in charge of synchronizing the events (with due dates) with Google Calendar
38.Update Favicon
39.Converts key-value pair to appropriate signature for Facebook.