public HttpURLConnection processURL(String spec, String requestMethod, byte[] body, Map<String, List<String>> headers)
          throws IOException {
    if (LOG.isDebugEnabled()) {
      LOG.debug("readFrom spec:{}", URLCredentialsHider.hideCredentials(spec));
    }

    URL url = new URL(spec);
    HttpURLConnection connection = (spec.startsWith("https") && setupTruststoreForHttps) ?
            getSSLConnection(url) : getConnection(url);

    AppCookieManager appCookieManager = getAppCookieManager();

    String appCookie = appCookieManager.getCachedAppCookie(spec);
    if (appCookie != null) {
      LOG.debug("Using cached app cookie for URL:{}", URLCredentialsHider.hideCredentials(spec));

      // allow for additional passed in cookies
      if (headers == null || headers.isEmpty()) {
        headers = Collections.singletonMap(COOKIE, Collections.singletonList(appCookie));
      } else {
        headers = new HashMap<>(headers);

        List<String> cookieList = headers.get(COOKIE);
        String       cookies    = cookieList == null || cookieList.isEmpty() ? null : cookieList.get(0);

        headers.put(COOKIE, Collections.singletonList(appendCookie(cookies, appCookie)));
      }
    }
    connection.setConnectTimeout(connTimeout);
    connection.setReadTimeout(readTimeout);
    connection.setDoOutput(true);
    connection.setRequestMethod(requestMethod);

    if (headers != null) {
      for (Map.Entry<String, List<String>> entry: headers.entrySet()) {
        String paramValue = entry.getValue().toString();
        connection.setRequestProperty(entry.getKey(), paramValue.substring(1, paramValue.length() - 1));
      }
    }

    if (body != null) {
      connection.getOutputStream().write(body);
    }

    if (url.getUserInfo() != null) {
      String basicAuth = String.format(BASIC_AUTH, new String(new Base64().encode(url.getUserInfo().getBytes())));
      connection.setRequestProperty(AUTHORIZATION, basicAuth);
    }

    int statusCode = connection.getResponseCode();
    if (statusCode == HttpStatus.SC_UNAUTHORIZED ) {
      String wwwAuthHeader = connection.getHeaderField(WWW_AUTHENTICATE);
      if (LOG.isInfoEnabled()) {
        LOG.info("Received WWW-Authentication header:" + wwwAuthHeader + ", for URL:" +
                URLCredentialsHider.hideCredentials(spec));
      }
      if (wwwAuthHeader != null &&
        wwwAuthHeader.trim().startsWith(NEGOTIATE)) {
        connection = spec.startsWith("https") ? getSSLConnection(url) : getConnection(url);
        appCookie = appCookieManager.getAppCookie(spec, true);
        connection.setRequestProperty(COOKIE, appCookie);
        connection.setConnectTimeout(connTimeout);
        connection.setReadTimeout(readTimeout);
        connection.setDoOutput(true);

        return connection;
      } else {
        // no supported authentication type found
        // we would let the original response propagate
        LOG.error("Unsupported WWW-Authentication header:" + wwwAuthHeader+ ", for URL:" +
                URLCredentialsHider.hideCredentials(spec));
        return connection;
      }
    } else {
        // not a 401 Unauthorized status code
        // we would let the original response propagate
        if (statusCode == HttpStatus.SC_NOT_FOUND || statusCode == HttpStatus.SC_FORBIDDEN){
          LOG.error(String.format("Received HTTP %s response from URL: %s", statusCode,
                  URLCredentialsHider.hideCredentials(spec)));
        }
        return connection;
    }
  }
Get a URL connection from the given spec.

@param spec           the String to parse as a URL
@param requestMethod  the HTTP method (GET,POST,PUT,etc.).
@param body           the body of the request; may be null
@param headers        the headers of the request; may be null

@return a URL connection

@throws IOException if the URL connection can not be established
ambari-server/src/main/java/org/apache/ambari/server/controller/internal/URLStreamProvider.java