/**
   * Returns the contents of an attachment
   *
   * @param assetId The ID of the asset owning the attachment
   * @param attachmentId The ID of the attachment
   * @return The input stream for the attachment
   * @throws IOException
   * @throws RequestFailureException
   */
  public InputStream getAttachment(String assetId, String attachmentId)
      throws IOException, BadVersionException, RequestFailureException {
    // Get the URL for the attachment
    Attachment attachment = getAttachmentMetaData(assetId, attachmentId);

    // accept license for type CONTENT
    HttpURLConnection connection;
    if (attachment.getType() == Attachment.Type.CONTENT) {
      connection = createHttpURLConnection(attachment.getUrl() + "?license=agree");
    } else {
      connection = createHttpURLConnection(attachment.getUrl());
    }

    // If the attachment was a link and we have a basic auth userid + password specified
    // we are attempting to access the files staged from a protected site so authorise for it
    if (attachment.getLinkType() == LinkType.DIRECT) {
      if ((loginInfo.getAttachmentBasicAuthUserId() != null)
          && (loginInfo.getAttachmentBasicAuthPassword() != null)) {
        String userpass =
            loginInfo.getAttachmentBasicAuthUserId()
                + ":"
                + loginInfo.getAttachmentBasicAuthPassword();
        String basicAuth =
            "Basic "
                + javax.xml.bind.DatatypeConverter.printBase64Binary(
                    userpass.getBytes(Charset.forName("UTF-8")));
        connection.setRequestProperty("Authorization", basicAuth);
      }
    }

    connection.setRequestMethod("GET");
    testResponseCode(connection);
    return connection.getInputStream();
  }
  /**
   * @param urlString This string should include the ApiKey but not any auth data.
   * @return
   * @throws IOException
   */
  private HttpURLConnection createRealHttpURLConnection(final String urlString) throws IOException {
    URL url;
    try {
      url =
          AccessController.doPrivileged(
              new PrivilegedExceptionAction<URL>() {

                @Override
                public URL run() throws MalformedURLException {
                  return new URL(urlString);
                }
              });
    } catch (PrivilegedActionException e) {
      throw (MalformedURLException) e.getCause();
    }

    // If an HTTP proxy is defined, open the connection with a java.net.Proxy
    HttpURLConnection connection = null;
    if (loginInfo.getProxy() != null && loginInfo.getProxy().isHTTP()) {

      LoginInfoClientProxy loginProxy = loginInfo.getProxy();

      Proxy javaNetProxy =
          new Proxy(
              Proxy.Type.HTTP,
              new InetSocketAddress(
                  loginProxy.getProxyURL().getHost(), loginProxy.getProxyURL().getPort()));
      connection = (HttpURLConnection) url.openConnection(javaNetProxy);
    } else {
      connection = (HttpURLConnection) url.openConnection();
    }

    addAuthToConnection(connection);

    String userAgent = loginInfo.getUserAgent();
    if (userAgent != null && !userAgent.isEmpty()) {
      connection.setRequestProperty("User-Agent", userAgent);
    }

    return connection;
  }
  /**
   * Adds authentication credentials to the connection.
   *
   * <p>For basic auth credentials, both username *and* password must be set in order for this to
   * happen and it is an error for only one to be set.
   *
   * @throws AssertionError if precisely one of {username, password} is set.
   */
  private void addAuthToConnection(HttpURLConnection connection) {

    if (loginInfo.getUserId() != null && loginInfo.getPassword() == null) {
      throw new AssertionError(
          "userId is set but password is null. Either both or neither must be set.");
    }
    if (loginInfo.getUserId() == null && loginInfo.getPassword() != null) {
      throw new AssertionError(
          "password is set but userId is null. Either both or neither must be set.");
    }

    // The username and password are added to the connection as a basic auth
    // Authorization header
    if (loginInfo.getUserId() != null && loginInfo.getPassword() != null) {
      String userpass = loginInfo.getUserId() + ":" + loginInfo.getPassword();
      String basicAuth =
          "Basic "
              + javax.xml.bind.DatatypeConverter.printBase64Binary(
                  userpass.getBytes(Charset.forName("UTF-8")));
      connection.setRequestProperty("Authorization", basicAuth);
    }

    // If a proxy is defined and a userid and password are defined add the proxy
    // authorisation to the connection.
    if ((loginInfo.getProxy() != null)
        && (loginInfo.getProxy().getProxyUserid() != null)
        && (loginInfo.getProxy().getProxyPassword() != null)) {
      String proxyUser = loginInfo.getProxy().getProxyUserid();
      String proxyPwd = loginInfo.getProxy().getProxyPassword();
      String proxyUidAndPwd = proxyUser + ":" + proxyPwd;
      String proxyBasicAuth =
          "Basic "
              + javax.xml.bind.DatatypeConverter.printBase64Binary(
                  proxyUidAndPwd.getBytes(Charset.forName("UTF-8")));
      connection.setRequestProperty("Proxy-Authorization", proxyBasicAuth);
    }
  }
 /**
  * Create an {@link HttpURLConnection} that is set up with the security information to connect to
  * massive
  *
  * @param url The complete URL to use (does not include the apiKey)
  * @return the {@link HttpURLConnection} with the api key and security information added
  * @throws IOException
  */
 private HttpURLConnection createHttpURLConnection(final String urlString) throws IOException {
   // Add the api key, might already have query parameters so check
   final String connectingString = urlString.contains("?") ? "&" : "?";
   return createRealHttpURLConnection(
       urlString + connectingString + "apiKey=" + loginInfo.getApiKey());
 }
 /**
  * Create an {@link HttpURLConnection} that is set up with the security information to connect to
  * massive using the versioned URL as the base URL
  *
  * @param path The path within massive to connect to (note this does not need the API key or base
  *     path of "/ma/v1")
  * @return The {@link HttpURLConnection}
  * @throws IOException
  */
 private HttpURLConnection createHttpURLConnectionToMassive(String path) throws IOException {
   return createHttpURLConnection(loginInfo.getRepositoryUrl() + path);
 }