JDKHttpConnection.java

  1. /*
  2.  * Copyright (C) 2013, 2020 Christian Halstrick <christian.halstrick@sap.com> and others
  3.  *
  4.  * This program and the accompanying materials are made available under the
  5.  * terms of the Eclipse Distribution License v. 1.0 which is available at
  6.  * https://www.eclipse.org/org/documents/edl-v10.php.
  7.  *
  8.  * SPDX-License-Identifier: BSD-3-Clause
  9.  */
  10. package org.eclipse.jgit.transport.http;

  11. import java.io.IOException;
  12. import java.io.InputStream;
  13. import java.io.OutputStream;
  14. import java.net.HttpURLConnection;
  15. import java.net.MalformedURLException;
  16. import java.net.ProtocolException;
  17. import java.net.Proxy;
  18. import java.net.URL;
  19. import java.security.KeyManagementException;
  20. import java.security.NoSuchAlgorithmException;
  21. import java.security.SecureRandom;
  22. import java.util.LinkedList;
  23. import java.util.List;
  24. import java.util.Map;

  25. import javax.net.ssl.HostnameVerifier;
  26. import javax.net.ssl.HttpsURLConnection;
  27. import javax.net.ssl.KeyManager;
  28. import javax.net.ssl.SSLContext;
  29. import javax.net.ssl.SSLSocket;
  30. import javax.net.ssl.TrustManager;

  31. import org.eclipse.jgit.annotations.NonNull;
  32. import org.eclipse.jgit.internal.transport.http.DelegatingSSLSocketFactory;
  33. import org.eclipse.jgit.util.HttpSupport;
  34. /**
  35.  * A {@link org.eclipse.jgit.transport.http.HttpConnection} which simply
  36.  * delegates every call to a {@link java.net.HttpURLConnection}. This is the
  37.  * default implementation used by JGit
  38.  *
  39.  * @since 3.3
  40.  */
  41. public class JDKHttpConnection implements HttpConnection {
  42.     HttpURLConnection wrappedUrlConnection;

  43.     // used for mock testing
  44.     JDKHttpConnection(HttpURLConnection urlConnection) {
  45.         this.wrappedUrlConnection = urlConnection;
  46.     }

  47.     /**
  48.      * Constructor for JDKHttpConnection.
  49.      *
  50.      * @param url
  51.      *            a {@link java.net.URL} object.
  52.      * @throws java.net.MalformedURLException
  53.      * @throws java.io.IOException
  54.      */
  55.     protected JDKHttpConnection(URL url)
  56.             throws MalformedURLException,
  57.             IOException {
  58.         this.wrappedUrlConnection = (HttpURLConnection) url.openConnection();
  59.     }

  60.     /**
  61.      * Constructor for JDKHttpConnection.
  62.      *
  63.      * @param url
  64.      *            a {@link java.net.URL} object.
  65.      * @param proxy
  66.      *            a {@link java.net.Proxy} object.
  67.      * @throws java.net.MalformedURLException
  68.      * @throws java.io.IOException
  69.      */
  70.     protected JDKHttpConnection(URL url, Proxy proxy)
  71.             throws MalformedURLException, IOException {
  72.         this.wrappedUrlConnection = (HttpURLConnection) url
  73.                 .openConnection(proxy);
  74.     }

  75.     /** {@inheritDoc} */
  76.     @Override
  77.     public int getResponseCode() throws IOException {
  78.         return wrappedUrlConnection.getResponseCode();
  79.     }

  80.     /** {@inheritDoc} */
  81.     @Override
  82.     public URL getURL() {
  83.         return wrappedUrlConnection.getURL();
  84.     }

  85.     /** {@inheritDoc} */
  86.     @Override
  87.     public String getResponseMessage() throws IOException {
  88.         return wrappedUrlConnection.getResponseMessage();
  89.     }

  90.     /** {@inheritDoc} */
  91.     @Override
  92.     public Map<String, List<String>> getHeaderFields() {
  93.         return wrappedUrlConnection.getHeaderFields();
  94.     }

  95.     /** {@inheritDoc} */
  96.     @Override
  97.     public void setRequestProperty(String key, String value) {
  98.         wrappedUrlConnection.setRequestProperty(key, value);
  99.     }

  100.     /** {@inheritDoc} */
  101.     @Override
  102.     public void setRequestMethod(String method) throws ProtocolException {
  103.         wrappedUrlConnection.setRequestMethod(method);
  104.     }

  105.     /** {@inheritDoc} */
  106.     @Override
  107.     public void setUseCaches(boolean usecaches) {
  108.         wrappedUrlConnection.setUseCaches(usecaches);
  109.     }

  110.     /** {@inheritDoc} */
  111.     @Override
  112.     public void setConnectTimeout(int timeout) {
  113.         wrappedUrlConnection.setConnectTimeout(timeout);
  114.     }

  115.     /** {@inheritDoc} */
  116.     @Override
  117.     public void setReadTimeout(int timeout) {
  118.         wrappedUrlConnection.setReadTimeout(timeout);
  119.     }

  120.     /** {@inheritDoc} */
  121.     @Override
  122.     public String getContentType() {
  123.         return wrappedUrlConnection.getContentType();
  124.     }

  125.     /** {@inheritDoc} */
  126.     @Override
  127.     public InputStream getInputStream() throws IOException {
  128.         return wrappedUrlConnection.getInputStream();
  129.     }

  130.     /** {@inheritDoc} */
  131.     @Override
  132.     public String getHeaderField(@NonNull String name) {
  133.         return wrappedUrlConnection.getHeaderField(name);
  134.     }

  135.     @Override
  136.     public List<String> getHeaderFields(@NonNull String name) {
  137.         Map<String, List<String>> m = wrappedUrlConnection.getHeaderFields();
  138.         List<String> fields = mapValuesToListIgnoreCase(name, m);
  139.         return fields;
  140.     }

  141.     private static List<String> mapValuesToListIgnoreCase(String keyName,
  142.             Map<String, List<String>> m) {
  143.         List<String> fields = new LinkedList<>();
  144.         m.entrySet().stream().filter(e -> keyName.equalsIgnoreCase(e.getKey()))
  145.                 .filter(e -> e.getValue() != null)
  146.                 .forEach(e -> fields.addAll(e.getValue()));
  147.         return fields;
  148.     }

  149.     /** {@inheritDoc} */
  150.     @Override
  151.     public int getContentLength() {
  152.         return wrappedUrlConnection.getContentLength();
  153.     }

  154.     /** {@inheritDoc} */
  155.     @Override
  156.     public void setInstanceFollowRedirects(boolean followRedirects) {
  157.         wrappedUrlConnection.setInstanceFollowRedirects(followRedirects);
  158.     }

  159.     /** {@inheritDoc} */
  160.     @Override
  161.     public void setDoOutput(boolean dooutput) {
  162.         wrappedUrlConnection.setDoOutput(dooutput);
  163.     }

  164.     /** {@inheritDoc} */
  165.     @Override
  166.     public void setFixedLengthStreamingMode(int contentLength) {
  167.         wrappedUrlConnection.setFixedLengthStreamingMode(contentLength);
  168.     }

  169.     /** {@inheritDoc} */
  170.     @Override
  171.     public OutputStream getOutputStream() throws IOException {
  172.         return wrappedUrlConnection.getOutputStream();
  173.     }

  174.     /** {@inheritDoc} */
  175.     @Override
  176.     public void setChunkedStreamingMode(int chunklen) {
  177.         wrappedUrlConnection.setChunkedStreamingMode(chunklen);
  178.     }

  179.     /** {@inheritDoc} */
  180.     @Override
  181.     public String getRequestMethod() {
  182.         return wrappedUrlConnection.getRequestMethod();
  183.     }

  184.     /** {@inheritDoc} */
  185.     @Override
  186.     public boolean usingProxy() {
  187.         return wrappedUrlConnection.usingProxy();
  188.     }

  189.     /** {@inheritDoc} */
  190.     @Override
  191.     public void connect() throws IOException {
  192.         wrappedUrlConnection.connect();
  193.     }

  194.     /** {@inheritDoc} */
  195.     @Override
  196.     public void setHostnameVerifier(HostnameVerifier hostnameverifier) {
  197.         ((HttpsURLConnection) wrappedUrlConnection)
  198.                 .setHostnameVerifier(hostnameverifier);
  199.     }

  200.     /** {@inheritDoc} */
  201.     @Override
  202.     public void configure(KeyManager[] km, TrustManager[] tm,
  203.             SecureRandom random) throws NoSuchAlgorithmException,
  204.             KeyManagementException {
  205.         SSLContext ctx = SSLContext.getInstance("TLS"); //$NON-NLS-1$
  206.         ctx.init(km, tm, random);
  207.         ((HttpsURLConnection) wrappedUrlConnection).setSSLSocketFactory(
  208.                 new DelegatingSSLSocketFactory(ctx.getSocketFactory()) {

  209.                     @Override
  210.                     protected void configure(SSLSocket socket)
  211.                             throws IOException {
  212.                         HttpSupport.configureTLS(socket);
  213.                     }
  214.                 });
  215.     }

  216. }