title: Downloading an asset from GitHub using Java
body: <p>I wrote a small program to download assets from GitHub releases:</p>
  <pre><code>import java.io.IOException;
  import java.io.InputStream;
  import java.net.HttpURLConnection;
  import java.net.URL;
  import java.nio.file.Files;
  import java.nio.file.Paths;
  import java.nio.file.StandardCopyOption;
  
  public class GitTest
  {
      public static void main(String[] args) throws IOException
      {
          String assetUrlString = &quot;https://api.github.com/repos/YuryMalyshev/SnakeGameWithProcessing/releases/assets/24010211&quot;;
          String token = &quot;Bearer My_Secret_GitHub_Personal_Access_Token&quot;;
          String filename = &quot;test.txt&quot;;
      
          URL assetURL = new URL(assetUrlString);
          HttpURLConnection downloadconnection = (HttpURLConnection) assetURL.openConnection();
          downloadconnection.setConnectTimeout(0);
          downloadconnection.addRequestProperty(&quot;Accept&quot;, &quot;application/octet-stream&quot;);
          downloadconnection.addRequestProperty(&quot;Authorization&quot;, token);
          downloadconnection.connect();
          
          // to partially mitigate the problem, we can put the problematic code
          // into try-catch to get redirect URL
          try
          {
              // throws IOException with message 
              //&quot;Server returned HTTP response code: 400 for URL: ... if ran on Linux&quot;
              InputStream inStream = downloadconnection.getInputStream(); 
              Files.copy(inStream, Paths.get(filename), StandardCopyOption.REPLACE_EXISTING);
          }
          catch(IOException e)
          {
              String responseMsg = e.getMessage();
              if(responseMsg.contains(&quot;Server returned HTTP response code: 400 for URL&quot;))
              {
                  URL redirectURL = new URL(responseMsg.substring(responseMsg.indexOf(&quot;https://&quot;)));
                  HttpURLConnection redirectconnection = (HttpURLConnection)redirectURL.openConnection();
                  redirectconnection.connect();
                  InputStream inStream = redirectconnection.getInputStream(); 
                  Files.copy(inStream, Paths.get(filename), StandardCopyOption.REPLACE_EXISTING);
                  redirectconnection.disconnect();
              }
          }
          downloadconnection.disconnect();
      }
  }
  </code></pre>
  <p>StackTrace:</p>
  <pre><code>Exception in thread &quot;main&quot; java.io.IOException: Server returned HTTP response code: 400 for URL: https://github-production-release-asset-2e65be.s3.amazonaws.com/251348046/ca3bbd00-e0b0-11ea-8d30-49e495660664?X-Amz-Algorithm=AWS4-HMAC-SHA256&amp;X-Amz-Credential=AKIAIWNJYAX4CSVEH53A%2F20200817%2Fus-east-1%2Fs3%2Faws4_request&amp;X-Amz-Date=20200817T145454Z&amp;X-Amz-Expires=300&amp;X-Amz-Signature=16f08a48455394dccdb94b91da32e4814885ae66c17d6f942ec814448b51975a&amp;X-Amz-SignedHeaders=host&amp;actor_id=49309415&amp;repo_id=251348046&amp;response-content-disposition=attachment%3B%20filename%3DTest.txt&amp;response-content-type=application%2Foctet-stream
      at sun.net.www.protocol.http.HttpURLConnection.getInputStream0(HttpURLConnection.java:1840)
      at sun.net.www.protocol.http.HttpURLConnection.getInputStream(HttpURLConnection.java:1441)
      at sun.net.www.protocol.https.HttpsURLConnectionImpl.getInputStream(HttpsURLConnectionImpl.java:254)
      at GitTest.main(GitTest.java:24)
  </code></pre>
  <p>Error Stream when getting Code 400</p>
  <pre><code>&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;
  &lt;Error&gt;
      &lt;Code&gt;InvalidArgument&lt;/Code&gt;
      &lt;Message&gt;Only one auth mechanism allowed; only the X-Amz-Algorithm query parameter, Signature query string parameter or the Authorization header should be specified&lt;/Message&gt;
      &lt;ArgumentName&gt;Authorization&lt;/ArgumentName&gt;
      &lt;ArgumentValue&gt;Bearer My_Secret_GitHub_Personal_Access_Token&lt;/ArgumentValue&gt;
      &lt;RequestId&gt;5C8A004BD481B671&lt;/RequestId&gt;
      &lt;HostId&gt;geSe0mXTd5ZFCskr7WK+9iI/RDx+mTTO/tgt25uGTK9v+fmUeM8qx6bkTSjPI3rgxPO4aNRrHEM=&lt;/HostId&gt;
  &lt;/Error&gt;
  </code></pre>
  <p>It works fine on my Windows 10 machine, but when I try to execute it on Linux (RPi OS) the exception is thrown.</p>
  <p>If I take the URL from the exception message and paste it into the browser (on Linux), then the file downloads just fine as well.</p>
  <p>I tried to execute the program with <em>sudo</em> but the result is the same.</p>
  <hr />
  <p><s>I guess one way would be to retrieve URL from the exception since I don't really know how it is generated, and use Runtime to execute cURL command. But I'd like to avoid it</s> Just use redirect URL and continue with it.</p>
  <hr />
  <p>Edit 1: cURL request would have the next form: <code>curl -L -H &quot;Accept: application/octet-stream&quot; -H &quot;Authorization: Bearer &lt;token&gt;&quot; &lt;url_to_the_asset&gt; --output &lt;name_of_the_file&gt;</code></p>
  <hr />
  <p>Edit 2: Added content of ErrorStream and partial solution</p>