content: /*
   * Copyright (c) 2013. wyouflf (wyouflf@gmail.com)
   *
   * 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.lidroid.xutils.http;
  
  import com.lidroid.xutils.HttpUtils;
  import com.lidroid.xutils.exception.HttpException;
  import com.lidroid.xutils.http.callback.DefaultHttpRedirectHandler;
  import com.lidroid.xutils.http.callback.HttpRedirectHandler;
  import org.apache.http.HttpResponse;
  import org.apache.http.StatusLine;
  import org.apache.http.client.HttpRequestRetryHandler;
  import org.apache.http.client.methods.HttpRequestBase;
  import org.apache.http.impl.client.AbstractHttpClient;
  import org.apache.http.protocol.HttpContext;
  
  import java.io.IOException;
  import java.net.UnknownHostException;
  
  public class SyncHttpHandler {
  
      private final AbstractHttpClient client;
      private final HttpContext context;
  
      private HttpRedirectHandler httpRedirectHandler;
  
      public void setHttpRedirectHandler(HttpRedirectHandler httpRedirectHandler) {
          this.httpRedirectHandler = httpRedirectHandler;
      }
  
      private String requestUrl;
      private String requestMethod;
      private String charset; // The default charset of response header info.
  
      private int retriedTimes = 0;
  
      public SyncHttpHandler(AbstractHttpClient client, HttpContext context, String charset) {
          this.client = client;
          this.context = context;
          this.charset = charset;
      }
  
  
      private long expiry = HttpCache.getDefaultExpiryTime();
  
      public void setExpiry(long expiry) {
          this.expiry = expiry;
      }
  
      public ResponseStream sendRequest(HttpRequestBase request) throws HttpException {
  
          HttpRequestRetryHandler retryHandler = client.getHttpRequestRetryHandler();
          while (true) {
              boolean retry = true;
              IOException exception = null;
              try {
                  requestUrl = request.getURI().toString();
                  requestMethod = request.getMethod();
                  if (HttpUtils.sHttpCache.isEnabled(requestMethod)) {
                      String result = HttpUtils.sHttpCache.get(requestUrl);
                      if (result != null) {
                          return new ResponseStream(result);
                      }
                  }
  
                  HttpResponse response = client.execute(request, context);
                  return handleResponse(response);
              } catch (UnknownHostException e) {
                  exception = e;
                  retry = retryHandler.retryRequest(exception, ++retriedTimes, context);
              } catch (IOException e) {
                  exception = e;
                  retry = retryHandler.retryRequest(exception, ++retriedTimes, context);
              } catch (NullPointerException e) {
                  exception = new IOException(e.getMessage());
                  exception.initCause(e);
                  retry = retryHandler.retryRequest(exception, ++retriedTimes, context);
              } catch (HttpException e) {
                  throw e;
              } catch (Throwable e) {
                  exception = new IOException(e.getMessage());
                  exception.initCause(e);
                  retry = retryHandler.retryRequest(exception, ++retriedTimes, context);
              }
              if (!retry) {
                  throw new HttpException(exception);
              }
          }
      }
  
      private ResponseStream handleResponse(HttpResponse response) throws HttpException, IOException {
          if (response == null) {
              throw new HttpException("response is null");
          }
          StatusLine status = response.getStatusLine();
          int statusCode = status.getStatusCode();
          if (statusCode < 300) {
              ResponseStream responseStream = new ResponseStream(response, charset, requestUrl, expiry);
              responseStream.setRequestMethod(requestMethod);
              return responseStream;
          } else if (statusCode == 301 || statusCode == 302) {
              if (httpRedirectHandler == null) {
                  httpRedirectHandler = new DefaultHttpRedirectHandler();
              }
              HttpRequestBase request = httpRedirectHandler.getDirectRequest(response);
              if (request != null) {
                  return this.sendRequest(request);
              }
          } else if (statusCode == 416) {
              throw new HttpException(statusCode, "maybe the file has downloaded completely");
          } else {
              throw new HttpException(statusCode, status.getReasonPhrase());
          }
          return null;
      }
  }
  