/** 连接网络读取数据 */ @Override protected <T> void connectWithRetries(AbstractRequest<T> request, InternalResponse response) throws HttpClientException, HttpNetException, HttpServerException { // if(true) { // throw new HttpNetException(NetException.NetworkDisabled); // } // 1. create apache request final HttpUriRequest apacheRequest = createApacheRequest(request); // 2. update http header if (request.getHeaders() != null) { Set<Entry<String, String>> set = request.getHeaders().entrySet(); for (Entry<String, String> en : set) { apacheRequest.setHeader(new BasicHeader(en.getKey(), en.getValue())); } } // 3. try to connect HttpListener<T> listener = request.getHttpListener(); StatisticsListener statistic = response.getStatistics(); int times = 0, maxRetryTimes = request.getMaxRetryTimes(), maxRedirectTimes = request.getMaxRedirectTimes(); boolean retry = true; IOException cause = null; while (retry) { try { cause = null; retry = false; if (request.isCancelledOrInterrupted()) { return; } if (statistic != null) { statistic.onPreConnect(request); } HttpResponse ares = mHttpClient.execute(apacheRequest); if (statistic != null) { statistic.onAfterConnect(request); } // status StatusLine status = ares.getStatusLine(); HttpStatus httpStatus = new HttpStatus(status.getStatusCode(), status.getReasonPhrase()); response.setHttpStatus(httpStatus); // header Header[] headers = ares.getAllHeaders(); if (headers != null) { com.litesuits.http.data.NameValuePair hs[] = new com.litesuits.http.data.NameValuePair[headers.length]; for (int i = 0; i < headers.length; i++) { String name = headers[i].getName(); String value = headers[i].getValue(); if ("Content-Length".equalsIgnoreCase(name)) { response.setContentLength(Long.parseLong(value)); } hs[i] = new com.litesuits.http.data.NameValuePair(name, value); } response.setHeaders(hs); } // data body if (status.getStatusCode() <= 299 || status.getStatusCode() == 600) { // 成功 HttpEntity entity = ares.getEntity(); if (entity != null) { // charset String charSet = getCharsetFromEntity(entity, request.getCharSet()); response.setCharSet(charSet); // is cancelled ? if (request.isCancelledOrInterrupted()) { return; } // length long len = response.getContentLength(); DataParser<T> parser = request.getDataParser(); if (statistic != null) { statistic.onPreRead(request); } parser.readFromNetStream(entity.getContent(), len, charSet); if (statistic != null) { statistic.onAfterRead(request); } response.setReadedLength(parser.getReadedLength()); endEntityViaReflection(entity); } return; } else if (status.getStatusCode() <= 399) { // redirect if (response.getRedirectTimes() < maxRedirectTimes) { // get the location header to find out where to redirect to Header locationHeader = ares.getFirstHeader(Consts.REDIRECT_LOCATION); if (locationHeader != null) { String location = locationHeader.getValue(); if (location != null && location.length() > 0) { if (!location.toLowerCase().startsWith("http")) { URI uri = new URI(request.getFullUri()); URI redirect = new URI(uri.getScheme(), uri.getHost(), location, null); location = redirect.toString(); } response.setRedirectTimes(response.getRedirectTimes() + 1); request.setUri(location); if (HttpLog.isPrint) { HttpLog.i(TAG, "Redirect to : " + location); } if (listener != null) { listener.notifyCallRedirect( request, maxRedirectTimes, response.getRedirectTimes()); } connectWithRetries(request, response); return; } } throw new HttpServerException(httpStatus); } else { throw new HttpServerException(ServerException.RedirectTooMuch); } } else if (status.getStatusCode() <= 499) { // 客户端被拒 throw new HttpServerException(httpStatus); } else if (status.getStatusCode() < 599) { // 服务器有误 throw new HttpServerException(httpStatus); } } catch (IOException e) { cause = e; } catch (NullPointerException e) { // bug in HttpClient 4.0.x, see http://code.google.com/p/android/issues/detail?id=5255 if (Build.VERSION.SDK_INT < Build.VERSION_CODES.GINGERBREAD) { cause = new IOException(e.getMessage()); } else { cause = new IOException(e); } } catch (URISyntaxException e) { throw new HttpClientException(e); } catch (IllegalStateException e) { // for apache http client. if url is illegal, it usually raises an exception as // "IllegalStateException: // Scheme 'xxx' not registered." throw new HttpClientException(e); } catch (SecurityException e) { throw new HttpClientException(e, ClientException.PermissionDenied); } catch (RuntimeException e) { throw new HttpClientException(e); } if (cause != null) { try { if (request.isCancelledOrInterrupted()) { return; } times++; retry = retryHandler.retryRequest( cause, times, maxRetryTimes, mHttpContext, config.getContext()); } catch (InterruptedException e) { e.printStackTrace(); return; } if (retry) { response.setRetryTimes(times); if (HttpLog.isPrint) { HttpLog.i(TAG, "LiteHttp retry request: " + request.getUri()); } if (listener != null) { listener.notifyCallRetry(request, maxRetryTimes, times); } } } } if (cause != null) { throw new HttpNetException(cause); } }
@Override @SuppressWarnings("unchecked") protected ResultType doBackground() throws Throwable { if (this.isCancelled()) { throw new Callback.CancelledException("cancelled before request"); } // 初始化请求参数 ResultType result = null; boolean retry = true; int retryCount = 0; Throwable exception = null; HttpRetryHandler retryHandler = new HttpRetryHandler(this.params.getMaxRetryCount()); request = initRequest(); if (this.isCancelled()) { throw new Callback.CancelledException("cancelled before request"); } // 检查缓存 Object cacheResult = null; if (cacheCallback != null && HttpMethod.permitsCache(params.getMethod())) { // 尝试从缓存获取结果, 并为请求头加入缓存控制参数. while (retry) { try { clearRawResult(); rawResult = this.request.loadResultFromCache(); break; } catch (Throwable ex) { LogUtil.w("load disk cache error", ex); exception = ex; retry = retryHandler.retryRequest(ex, ++retryCount, this.request); } } if (this.isCancelled()) { clearRawResult(); throw new Callback.CancelledException("cancelled before request"); } if (rawResult != null) { if (prepareCallback != null) { try { cacheResult = prepareCallback.prepare(rawResult); } catch (Throwable ex) { cacheResult = null; LogUtil.w("prepare disk cache error", ex); } finally { clearRawResult(); } } else { cacheResult = rawResult; } if (this.isCancelled()) { throw new Callback.CancelledException("cancelled before request"); } if (cacheResult != null) { // 同步等待是否信任缓存 this.update(FLAG_CACHE, cacheResult); while (trustCache == null) { synchronized (cacheLock) { try { cacheLock.wait(); } catch (Throwable ignored) { } } } // 处理完成 if (trustCache) { return null; } } } } if (trustCache == null) { trustCache = false; } if (cacheResult == null) { this.request.clearCacheHeader(); } // 发起请求 retry = true; while (retry) { try { if (this.isCancelled()) { throw new Callback.CancelledException("cancelled before request"); } // 由loader发起请求, 拿到结果. this.request.close(); // retry 前关闭上次请求 try { clearRawResult(); requestWorker = new RequestWorker(this.request, this.loadType); if (params.isCancelFast()) { requestWorker.start(); requestWorker.join(); } else { requestWorker.run(); } if (requestWorker.ex != null) { throw requestWorker.ex; } rawResult = requestWorker.result; } catch (Throwable ex) { clearRawResult(); if (this.isCancelled()) { throw new Callback.CancelledException("cancelled during request"); } else { throw ex; } } if (prepareCallback != null) { try { result = (ResultType) prepareCallback.prepare(rawResult); } finally { clearRawResult(); } } else { result = (ResultType) rawResult; } // 保存缓存 if (cacheCallback != null && HttpMethod.permitsCache(params.getMethod())) { this.request.save2Cache(); } retry = false; if (this.isCancelled()) { throw new Callback.CancelledException("cancelled after request"); } } catch (Throwable ex) { if (this.request.getResponseCode() == 304) { // disk cache is valid. return null; } else { exception = ex; retry = retryHandler.retryRequest(ex, ++retryCount, this.request); } } } if (exception != null && result == null && !trustCache) { throw exception; } return result; }