/*******************************************************************************
* Copyright (c) 2012-2017 Codenvy, S.A.
* 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:
* Codenvy, S.A. - initial API and implementation
*******************************************************************************/
package org.eclipse.che.plugin.docker.client.connection;
import com.google.common.base.Strings;
import org.eclipse.che.commons.lang.Pair;
import org.eclipse.che.plugin.docker.client.DockerCertificates;
import javax.net.ssl.HttpsURLConnection;
import java.io.IOException;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.URI;
import java.net.URL;
import java.util.List;
/**
* @author andrew00x
* @author Alexander Garagatyi
*/
public class TcpConnection extends DockerConnection {
private final URI baseUri;
private final DockerCertificates certificates;
private final int connectionTimeout;
private final int readTimeout;
private HttpURLConnection connection;
public TcpConnection(URI baseUri, DockerCertificates certificates, int connectionTimeoutMs, int readTimeoutMs) {
if ("https".equals(baseUri.getScheme())) {
if (certificates == null) {
throw new IllegalArgumentException("Certificates are required for https connection.");
}
} else if (!("http".equals(baseUri.getScheme()))) {
throw new IllegalArgumentException(String.format("Invalid URL '%s', only http and https protocols are supported.", baseUri));
}
this.baseUri = baseUri;
this.certificates = certificates;
this.connectionTimeout = connectionTimeoutMs;
this.readTimeout = readTimeoutMs;
}
@Override
protected DockerResponse request(String method, String path, String query, List<Pair<String, ?>> headers, Entity<?> entity)
throws IOException {
final String requestUri = path + (Strings.isNullOrEmpty(query) ? "" : "?" + query);
final URL url = baseUri.resolve(requestUri).toURL();
final String protocol = url.getProtocol();
connection = (HttpURLConnection)url.openConnection();
connection.setConnectTimeout(connectionTimeout);
connection.setReadTimeout(readTimeout);
if ("https".equals(protocol)) {
((HttpsURLConnection)connection).setSSLSocketFactory(certificates.getSslContext().getSocketFactory());
}
connection.setRequestMethod(method);
// needed to fix bug https://github.com/docker/docker/issues/12845
connection.setRequestProperty("Connection", "close");
for (Pair<String, ?> header : headers) {
connection.setRequestProperty(header.first, String.valueOf(header.second));
}
String host = url.getHost();
if (url.getPort() != -1) {
host += ":" + Integer.toString(url.getPort());
}
// Host header is mandatory in HTTP 1.1
connection.setRequestProperty("Host", host);
if (entity != null) {
connection.setDoOutput(true);
try (OutputStream output = connection.getOutputStream()) {
entity.writeTo(output);
}
}
return new TcpDockerResponse(connection);
}
@Override
public void close() {
if (connection != null) {
connection.disconnect();
}
}
}