blob: ef3d88158f4d850159334e2b1930a8da3f1960c1 [file] [log] [blame]
package com.intellij.tasks.impl;
import com.intellij.openapi.components.ServiceManager;
import com.intellij.tasks.TaskRepositoryType;
import com.intellij.tasks.config.TaskSettings;
import com.intellij.util.net.HttpConfigurable;
import com.intellij.util.net.ssl.CertificateManager;
import org.apache.commons.httpclient.*;
import org.apache.commons.httpclient.auth.AuthScope;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
/**
* Base class for HTTP-based repositories.
*
* @author Dmitry Avdeev
*/
public abstract class BaseRepositoryImpl extends BaseRepository {
private final HttpClient myClient;
protected BaseRepositoryImpl() {
myClient = createClient();
}
protected BaseRepositoryImpl(TaskRepositoryType type) {
super(type);
myClient = createClient();
}
protected BaseRepositoryImpl(BaseRepositoryImpl other) {
super(other);
myClient = other.myClient;
}
protected static String encodeUrl(@NotNull String s) {
try {
return URLEncoder.encode(s, "UTF-8");
}
catch (UnsupportedEncodingException e) {
throw new RuntimeException(e);
}
}
protected HttpClient getHttpClient() {
return myClient;
}
private HttpClient createClient() {
HttpClient client = new HttpClient(new MultiThreadedHttpConnectionManager());
configureHttpClient(client);
// After CertificateManager became application service it no longer "automagically" preliminarily
// initializes default SSL context as required for trackers written in httpclient 3.x.
// Clients that use httpclient 4.x (see NewBaseRepositoryImpl.getHttpClient) install SSL context explicitly though.
// This workaround allows to install context properly as soon as HTTP client is needed.
ServiceManager.getService(CertificateManager.class);
return client;
}
protected final void reconfigureClient() {
synchronized (myClient) {
configureHttpClient(myClient);
}
}
protected void configureHttpClient(HttpClient client) {
client.getParams().setConnectionManagerTimeout(3000);
client.getParams().setSoTimeout(TaskSettings.getInstance().CONNECTION_TIMEOUT);
if (isUseProxy()) {
HttpConfigurable proxy = HttpConfigurable.getInstance();
client.getHostConfiguration().setProxy(proxy.PROXY_HOST, proxy.PROXY_PORT);
if (proxy.PROXY_AUTHENTICATION) {
AuthScope authScope = new AuthScope(proxy.PROXY_HOST, proxy.PROXY_PORT);
Credentials credentials = getCredentials(proxy.PROXY_LOGIN, proxy.getPlainProxyPassword(), proxy.PROXY_HOST);
client.getState().setProxyCredentials(authScope, credentials);
}
}
if (isUseHttpAuthentication()) {
client.getParams().setCredentialCharset("UTF-8");
client.getParams().setAuthenticationPreemptive(true);
client.getState().setCredentials(AuthScope.ANY, new UsernamePasswordCredentials(getUsername(), getPassword()));
}
else {
client.getState().clearCredentials();
client.getParams().setAuthenticationPreemptive(false);
}
}
@Nullable
private static Credentials getCredentials(String login, String password, String host) {
int domainIndex = login.indexOf("\\");
if (domainIndex > 0) {
// if the username is in the form "user\domain"
// then use NTCredentials instead of UsernamePasswordCredentials
String domain = login.substring(0, domainIndex);
if (login.length() > domainIndex + 1) {
String user = login.substring(domainIndex + 1);
return new NTCredentials(user, password, host, domain);
}
else {
return null;
}
}
else {
return new UsernamePasswordCredentials(login, password);
}
}
protected void configureHttpMethod(HttpMethod method) {
}
public abstract static class HttpTestConnection<T extends HttpMethod> extends CancellableConnection {
protected T myMethod;
public HttpTestConnection(T method) {
myMethod = method;
}
@Override
protected void doTest() throws Exception {
doTest(myMethod);
}
@Override
public void cancel() {
myMethod.abort();
}
protected abstract void doTest(T method) throws Exception;
}
@Override
public void setUseProxy(boolean useProxy) {
if (useProxy != isUseProxy()) {
super.setUseProxy(useProxy);
reconfigureClient();
}
}
@Override
public void setUseHttpAuthentication(boolean useHttpAuthentication) {
if (useHttpAuthentication != isUseHttpAuthentication()) {
super.setUseHttpAuthentication(useHttpAuthentication);
reconfigureClient();
}
}
@Override
public void setPassword(String password) {
if (!password.equals(getPassword())) {
super.setPassword(password);
reconfigureClient();
}
}
@Override
public void setUsername(String username) {
if (!username.equals(getUsername())) {
super.setUsername(username);
reconfigureClient();
}
}
}