private static URLConnection openConnection(RequestBuilderImpl builder, RequestImpl request) throws IOException {
    if (builder.myForceHttps && request.myUrl.startsWith("http:")) {
      request.myUrl = "https:" + request.myUrl.substring(5);
    }

    for (int i = 0; i < builder.myRedirectLimit; i++) {
      final String url = request.myUrl;

      final URLConnection connection;
      if (!builder.myUseProxy) {
        connection = new URL(url).openConnection(Proxy.NO_PROXY);
      }
      else {
        Application app = ApplicationManager.getApplication();
        IdeUiService uiService = app != null ? app.getServiceIfCreated(IdeUiService.class) : null;
        if (uiService != null) {
          connection = uiService.openHttpConnection(url);
        }
        else {
          connection = new URL(url).openConnection();
        }
      }

      if (connection instanceof HttpsURLConnection) {
        configureSslConnection(url, (HttpsURLConnection)connection);
      }

      connection.setConnectTimeout(builder.myConnectTimeout);
      connection.setReadTimeout(builder.myTimeout);

      if (builder.myUserAgent != null) {
        connection.setRequestProperty("User-Agent", builder.myUserAgent);
      }

      if (builder.myHostnameVerifier != null && connection instanceof HttpsURLConnection) {
        ((HttpsURLConnection)connection).setHostnameVerifier(builder.myHostnameVerifier);
      }

      if (builder.myGzip) {
        connection.setRequestProperty("Accept-Encoding", "gzip");
      }

      if (builder.myAccept != null) {
        connection.setRequestProperty("Accept", builder.myAccept);
      }

      connection.setUseCaches(false);

      if (builder.myInternalTuner != null) {
        builder.myInternalTuner.tune(connection);
      }

      if (builder.myTuner != null) {
        builder.myTuner.tune(connection);
      }

      checkRequestHeadersForNulBytes(connection);

      if (!(connection instanceof HttpURLConnection httpURLConnection)) {
        return connection;
      }

      httpURLConnection.setInstanceFollowRedirects(false);

      if (connection.getDoOutput()) {
        return connection;
      }

      String method = httpURLConnection.getRequestMethod();

      LOG.assertTrue(method.equals("GET") || method.equals("HEAD") || method.equals("DELETE"),
                     "'" + method + "' not supported; please use GET, HEAD, DELETE, PUT or POST");

      if (LOG.isDebugEnabled()) {
        LOG.debug("connecting to " + url);
      }

      int responseCode;
      try {
        responseCode = httpURLConnection.getResponseCode();
      }
      catch (SSLHandshakeException e) {
        throw !NetUtils.isSniEnabled() ? new SSLException("SSL error probably caused by disabled SNI", e) : e;
      }

      if (LOG.isDebugEnabled()) {
        LOG.debug("response from " + url + ": " + responseCode);
      }

      if (responseCode < 200 || responseCode >= 300 && responseCode != HttpURLConnection.HTTP_NOT_MODIFIED) {
        if (ArrayUtil.indexOf(REDIRECTS, responseCode) >= 0) {
          httpURLConnection.disconnect();
          String loc = connection.getHeaderField("Location");
          if (LOG.isDebugEnabled()) LOG.debug("redirect from " + url + ": " + loc);
          if (loc != null) {
            if (!loc.contains("://")) {
              // Location is a relative URI
              URL locUrl = new URL(new URL(url), loc);
              loc = locUrl.toExternalForm();
            }
            request.myUrl = loc;
            continue;
          }
        }

        if (builder.myThrowStatusCodeException) {
          throwHttpStatusError(httpURLConnection, request, builder, responseCode);
        }
      }

      return connection;
    }

    throw new IOException(IdeCoreBundle.message("error.connection.failed.redirects"));
  }
private static URLConnection openConnection(RequestBuilderImpl builder, RequestImpl request)