/*******************************************************************************
* Copyright (c) 2010 The Eclipse Foundation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* The Eclipse Foundation - initial API and implementation
*******************************************************************************/
package org.eclipse.epp.internal.mpc.core.transport.httpclient;
import java.io.ByteArrayInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.net.URI;
import java.util.concurrent.TimeUnit;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.StatusLine;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.HttpClient;
import org.apache.http.client.HttpResponseException;
import org.apache.http.client.fluent.Executor;
import org.apache.http.client.fluent.Request;
import org.apache.http.client.fluent.Response;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
import org.eclipse.epp.internal.mpc.core.MarketplaceClientCore;
import org.eclipse.epp.internal.mpc.core.util.UserAgentUtil;
import org.eclipse.epp.mpc.core.service.ITransport;
import org.eclipse.epp.mpc.core.service.ServiceUnavailableException;
@SuppressWarnings({ "restriction" })
public class HttpClientTransport implements ITransport {
public static final String USER_AGENT;
public static final String USER_AGENT_PROPERTY = HttpClientTransport.class.getPackage().getName() + ".userAgent"; //$NON-NLS-1$
/**
* Maximum time between response packets before the socket closes
*/
public static final int DEFAULT_READ_TIMEOUT = (int) TimeUnit.SECONDS.toMillis(30);
/**
* Maximum time to establish connection with server
*/
public static final int DEFAULT_CONNECT_TIMEOUT = (int) TimeUnit.SECONDS.toMillis(10);
/**
* Maximum time to wait for an available connection from the connection manager
*/
public static final int DEFAULT_CONNECTION_REQUEST_TIMEOUT = (int) TimeUnit.SECONDS.toMillis(30);
public static final String READ_TIMEOUT_PROPERTY = HttpClientTransport.class.getPackage().getName()
+ ".readTimeout"; //$NON-NLS-1$
public static final String CONNECT_TIMEOUT_PROPERTY = HttpClientTransport.class.getPackage().getName()
+ ".connectTimeout"; //$NON-NLS-1$
public static final String CONNECTION_REQUEST_TIMEOUT_PROPERTY = HttpClientTransport.class.getPackage().getName()
+ ".connectionRequestTimeout"; //$NON-NLS-1$
static {
USER_AGENT = UserAgentUtil.computeUserAgent();
}
private final HttpClient client;
private final Executor executor;
public HttpClientTransport() {
HttpClientFactory httpClientFactory = new HttpClientFactory();
client = httpClientFactory.build();
executor = httpClientFactory.getExecutor();
}
public HttpClient getClient() {
return client;
}
public Executor getExecutor() {
return executor;
}
protected Response execute(Request request, URI uri) throws ClientProtocolException, IOException {
return HttpClientProxyUtil.proxyAuthentication(executor, uri).execute(request);
}
protected Request configureRequest(Request request, URI uri) {
return request.viaProxy(HttpClientProxyUtil.getProxyHost(uri));
}
public InputStream stream(URI location, IProgressMonitor monitor)
throws FileNotFoundException, ServiceUnavailableException, CoreException {
try {
return createStreamingRequest().execute(location);
} catch (HttpResponseException e) {
int statusCode = e.getStatusCode();
switch (statusCode) {
case 404:
FileNotFoundException fnfe = new FileNotFoundException(e.getMessage());
fnfe.initCause(e);
throw fnfe;
case 503:
throw new ServiceUnavailableException(
new Status(IStatus.ERROR, MarketplaceClientCore.BUNDLE_ID, e.getMessage(), e));
default:
throw new CoreException(MarketplaceClientCore.computeStatus(e, null));
}
} catch (IOException e) {
throw new CoreException(MarketplaceClientCore.computeStatus(e, null));
}
}
protected RequestTemplate<InputStream> createStreamingRequest() {
return new RequestTemplate<InputStream>(this) {
@Override
protected Request createRequest(URI uri) {
return Request.Get(uri);
}
@Override
protected InputStream handleResponse(Response response) throws ClientProtocolException, IOException {
HttpResponse returnResponse = response.returnResponse();
HttpEntity entity = returnResponse.getEntity();
StatusLine statusLine = returnResponse.getStatusLine();
handleResponseStatus(statusLine.getStatusCode(), statusLine.getReasonPhrase(), entity);
return handleResponseEntity(entity);
}
@Override
protected InputStream handleResponseStream(InputStream content) throws IOException {
return content;
}
@Override
protected InputStream handleEmptyResponse() {
return new ByteArrayInputStream(new byte[0]);
}
};
}
}