3.3 Octopus Deploy - 400 Bad Request

Hi. I’ve downloaded Octopus Deploy 3.3 beta for .NET Core 1.0 support. I am trying to upload a .zip file, and I am unable to get past 400 Bad Request. There are 0 packages uploaded to this server.

Powershell:

$webclient = New-Object System.Net.WebClient

$file = “D:\artifact\Core.zip”
$url = “http://deploy/api/packages/raw?apiKey=[redacted]&replace=true

try {
Write-Output $file
$webclient.UploadFile($url, $file)
}
catch [Net.WebException] {
Write-Host $_.Exception.ToString()
}

Error:

System.Net.WebException: The remote server returned an error: (400) Bad Request.
at System.Net.WebClient.UploadFile(Uri address, String method, String fileName)
at UploadFile(Object , Object[] )
at System.Management.Automation.DotNetAdapter.AuxiliaryMethodInvoke(Object target, Object[] arguments, MethodInformat
ion methodInformation, Object[] originalArguments)

Hi,
Its great to hear you have already downloaded the 3.3 beta and have begun to put it through its paces. We have indeed just added support for pushing zip packages however it looks as though there a few things that you will need to change to get this script working.

First, I notice that the package you are pushing is called Core.zip. As outlined the documentation on supported packages, non-NuGet packages require a specific naming format so that we can extract both the package name and version. For example, the package should be named something like MyPackage.1.2.0.zip.

Secondly since this upload endpoint is an extension of the endpoint that supports the NuGet push api, it needs to be formatted with the content type multipart/form-data, along with the file-name in the content body.
Check out LINQPad script for an example on how this might work in a C# script.

A naive PowerShell converted version of this script might look something like

$octopusUrl = "http://localhost:8065";
$apiKey = "API-0XZFML5YENX7HGC98LOBQ11GPZU"
$packageFilePath = "C:\Temp\CareForUAPITest.0.0.672.nupkg";
$replaceExisting = $true;

$packageUrl = $octopusUrl + "/api/packages/raw?replace=" + $replaceExisting;

Write-Host Uploading $packageFilePath to $packageUrl;


$webRequest = [System.Net.HttpWebRequest]::Create($packageUrl);
$webRequest.Accept = "application/json";
$webRequest.ContentType = "application/json";
$webRequest.Method = "POST";
$webRequest.Headers["X-Octopus-ApiKey"] = $apiKey;


$packageFileStream = new-object IO.FileStream $packageFilePath,'Open','Read','Read'

	$boundary = "----------------------------" + [System.DateTime]::Now.Ticks.ToString("x");
	$boundarybytes = [System.Text.Encoding]::ASCII.GetBytes("`r`n--" + $boundary + "`r`n")
	$webRequest.ContentType = "multipart/form-data; boundary=" + $boundary;
	$webRequest.GetRequestStream().Write($boundarybytes, 0, $boundarybytes.Length);

    $header = "Content-Disposition: form-data; filename="""+ [System.IO.Path]::GetFileName($packageFilePath) +"""`r`nContent-Type: application/octet-stream`r`n`r`n";
	$headerbytes = [System.Text.Encoding]::ASCII.GetBytes($header);
	$webRequest.GetRequestStream().Write($headerbytes, 0, $headerbytes.Length);
	$packageFileStream.CopyTo($webRequest.GetRequestStream());
	$webRequest.GetRequestStream().Write($boundarybytes, 0, $boundarybytes.Length);
	$webRequest.GetRequestStream().Flush();
	$webRequest.GetRequestStream().Close();

    $packageFileStream.Close();
    $packageFileStream.Dispose();


$webResponse = $webRequest.GetResponse();
Write-Host $webResponse.StatusCode $webResponse.StatusDescription;
$webResponse.Dispose();

We have flagged this area as something that requires a little more documentation which we will add to in the future by providing a few more language examples. On a side-note we do also have plans to extend octo.exe to support push commands so keep an eye out for that too!

I hope this response helps you to solve your problem. Please let me know if you run into any further problems pushing this package.
Cheers,
Robert

Hi Robert,
That was indeed my problem. I was looking at the wrong documentation