Error uploading artifact using REST API

Simon Taylor's Avatar

Simon Taylor

02 Dec, 2015 12:17 PM

Hi there,

I'm trying to use the REST API (as described here: http://www.appveyor.com/docs/build-worker-api#push-artifact) to push a build artefact, but I'm getting a 400 error uploading the file (second step). I'm using some old code that used to work, but I recently resurrected it and now it fails, so I guess something must have changed in the API that I need to adapt my code to work with.

Here's what I do:
1. PUT to %APPVEYOR_API_URL%/api/artifacts with json content with filename, etc.
2. This returns back URL to upload to.
3. Upload file to that URL using WebClient.UploadFileTaskAsync().
4. This returns a 400.

The contents of the 400 response are as follows:

<?xml version='1.0' encoding='UTF-8'?>
<Error>
  <Code>InvalidAuthentication</Code>
  <Message>The provided authentication header is invalid.</Message>
  <Details>Cannot use Query String params with form POST.</Details>
</Error>

You can see a build with this error, with various logging with stuff like what it's uploading to which URL here: https://ci.appveyor.com/project/simontaylor81/syrup/build/1.0.126#L150

If you want to look at the code that does all this, it's here: https://github.com/simontaylor81/Syrup/blob/mipmaps/SRPTests/Util/A...

Cheers,
Simon.

  1. Support Staff 1 Posted by Feodor Fitsner on 02 Dec, 2015 07:35 PM

    Feodor Fitsner's Avatar

    Right, it's been changed for OSS environment.

    If there is storage.googleapis.com in the upload URL then you should PUT file contents in the request stream, for example:

                        HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create(uploadUrl);
                        request.Method = "PUT";
    
                        using (var fileStream = File.OpenRead(path))
                        {
                            using (Stream reqStream = request.GetRequestStream())
                            {
                                fileStream.CopyTo(reqStream);
                            }
                        }
                        request.GetResponse();
    

    once the file uploaded to Google Storage you should call "finalizing" method from the API:

    PUT /api/artifacts
    
    {
      "fileName": "<file_name>"
      "size": <file_size_in_bytes>
    }
    
  2. 2 Posted by Simon Taylor on 02 Dec, 2015 09:54 PM

    Simon Taylor's Avatar

    Great, that worked a treat!

    I've submitted a PR for updating the docs. Wasn't sure how much detail to go into, hope it's ok. I didn't put in any example code for the PUT to the google URL since all the other examples in that page are in powershell, and I don't know enough powershell to be confident I was doing it right!

    If you want to look at my code that does this, it's here: https://github.com/simontaylor81/Syrup/blob/939470368e100604845d2a3...

  3. Support Staff 3 Posted by Feodor Fitsner on 02 Dec, 2015 10:16 PM

    Feodor Fitsner's Avatar

    Looks great, thank you!

  4. Ilya Finkelshteyn closed this discussion on 25 Aug, 2018 02:02 AM.

Comments are currently closed for this discussion. You can start a new one.

Keyboard shortcuts

Generic

? Show this help
ESC Blurs the current field

Comment Form

r Focus the comment reply box
^ + ↩ Submit the comment

You can use Command ⌘ instead of Control ^ on Mac