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