Skip to content
Snippets Groups Projects
Commit ec4eddea authored by Benedikt Heinrichs's avatar Benedikt Heinrichs
Browse files

Merge branch 'Topic/81-s3ZipUpload' into 'Poduct/75-s3ZipMetadata'

Topic/81 s3 zip upload

See merge request coscine/cs-s3zip!1
parents 04b6770f 196e356a
No related branches found
No related tags found
2 merge requests!2Product/75 s3 zip metadata,!1Topic/81 s3 zip upload
......@@ -4,8 +4,8 @@ The allows to zip a folder and/or upload a whole stream in chunks to a S3 object
For example:
```
var s3 = new S3Zip(s3MultipartStreamConfiguration);
s3.ZipAndUploadFolder(@"c:\temp\test", "Test.zip");
var zipUtilities = new ZipUtilities(_s3MultipartStreamConfiguration);
zipUtilities.ZipAndUploadFolder(@"c:\temp\test", "test.zip");
```
A zip file of the folder will be in S3 under the key Test.zip.
\ No newline at end of file
A zip file of the folder will be in S3 under the key test.zip.
\ No newline at end of file
......@@ -4,8 +4,8 @@ The allows to zip a folder and/or upload a whole stream in chunks to a S3 object
For example:
```
var s3 = new S3Zip(s3MultipartStreamConfiguration);
s3.ZipAndUploadFolder(@"c:\temp\test", "Test.zip");
var zipUtilities = new ZipUtilities(_s3MultipartStreamConfiguration);
zipUtilities.ZipAndUploadFolder(@"c:\temp\test", "test.zip");
```
A zip file of the folder will be in S3 under the key Test.zip.
\ No newline at end of file
A zip file of the folder will be in S3 under the key test.zip.
\ No newline at end of file
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
// General Information about an assembly is controlled through the following
// set of attributes. Change these attribute values to modify the information
// associated with an assembly.
[assembly: AssemblyTitle("cs-S3Zip.Tests")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("cs-S3Zip.Tests")]
[assembly: AssemblyCopyright("Copyright © 2019")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
// Setting ComVisible to false makes the types in this assembly not visible
// to COM components. If you need to access a type in this assembly from
// COM, set the ComVisible attribute to true on that type.
[assembly: ComVisible(false)]
// The following GUID is for the ID of the typelib if this project is exposed to COM
[assembly: Guid("6b58eb5e-d857-464b-8174-c17375bae1cf")]
// Version information for an assembly consists of the following four values:
//
// Major Version
// Minor Version
// Build Number
// Revision
//
// You can specify all the values or you can default the Build and Revision Numbers
// by using the '*' as shown below:
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("1.0.0.0")]
[assembly: AssemblyFileVersion("1.0.0.0")]

using Amazon.S3;
using Amazon.S3.Model;
using NUnit.Framework;
using System;
using System.IO;
using System.Linq;
using System.Security.Cryptography;
namespace coscine.cs_S3Zip.Tests
{
[TestFixture]
public class S3ZipTests
{
private readonly S3MultipartStreamConfiguration _s3MultipartStreamConfiguration;
private readonly int ONE_MB;
public S3ZipTests()
{
var accessKey = Environment.GetEnvironmentVariable("S3_ACCESS_KEY", EnvironmentVariableTarget.Process);
var secretKey = Environment.GetEnvironmentVariable("S3_SECRET_KEY", EnvironmentVariableTarget.Process);
ONE_MB = (int)Math.Pow(2, 20);
_s3MultipartStreamConfiguration = new S3MultipartStreamConfiguration
{
AccessKey = accessKey,
SecretKey = secretKey,
BucketName = "PITLABTTEST",
AmazonS3Config = new AmazonS3Config
{
ServiceURL = "https://s3.rwth-aachen.de/",
ForcePathStyle = true
}
};
}
[TestCase(110, 50)]
[TestCase(110, 5)]
[TestCase(30, 50)]
[TestCase(30, 5)]
public void S3StreamTest(int length, int chunkSize)
{
var key = "S3StreamTest.txt";
var chars = "$%#@!*abcdefghijklmnopqrstuvwxyz1234567890?;:ABCDEFGHIJKLMNOPQRSTUVWXYZ^&".ToCharArray();
var seed = DateTime.Now.Millisecond;
var random = new Random(seed);
var randomBuffer = new byte[ONE_MB];
var oldChunkSize = _s3MultipartStreamConfiguration.ChunckSize;
_s3MultipartStreamConfiguration.ChunckSize = chunkSize * ONE_MB;
using (var s3Stream = new S3MultipartStream(key, _s3MultipartStreamConfiguration))
{
for (int i = 0; i < length; i++)
{
FillArrayWithRandomChars(randomBuffer, randomBuffer.Length, chars, random);
s3Stream.Write(randomBuffer, 0, ONE_MB);
}
}
var request = new GetObjectRequest
{
BucketName = _s3MultipartStreamConfiguration.BucketName,
Key = key
};
// reset the random number generator
random = new Random(seed);
using (var client = new AmazonS3Client(_s3MultipartStreamConfiguration.AccessKey, _s3MultipartStreamConfiguration.SecretKey, _s3MultipartStreamConfiguration.AmazonS3Config))
{
var buffer = new byte[ONE_MB];
using (var response = client.GetObject(request))
{
// Was request successfull?
Assert.IsTrue(response.HttpStatusCode == System.Net.HttpStatusCode.OK);
// Has the correct length?
Assert.IsTrue(response.ContentLength == length * ONE_MB);
using (var responseStream = response.ResponseStream)
{
int alreadyRead = 0;
for (int i = 0; i < length; i++)
{
int read = responseStream.Read(buffer, 0, buffer.Length);
FillArrayWithRandomChars(randomBuffer, read, chars, random);
// check if the data is equal to the previously generated one.
Assert.IsTrue(Enumerable.SequenceEqual(randomBuffer.Take(read), buffer.Take(read)));
alreadyRead += read;
}
}
}
}
_s3MultipartStreamConfiguration.ChunckSize = oldChunkSize;
}
private void FillArrayWithRandomChars(byte[] randomBuffer, int length, char[] chars, Random random)
{
for (int i = 0; i < length; i++)
{
randomBuffer[i] = (byte)chars[random.Next(chars.Length)];
}
}
}
}
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="..\packages\NUnit3TestAdapter.3.13.0\build\net35\NUnit3TestAdapter.props" Condition="Exists('..\packages\NUnit3TestAdapter.3.13.0\build\net35\NUnit3TestAdapter.props')" />
<Import Project="..\packages\NUnit.3.11.0\build\NUnit.props" Condition="Exists('..\packages\NUnit.3.11.0\build\NUnit.props')" />
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProjectGuid>{6B58EB5E-D857-464B-8174-C17375BAE1CF}</ProjectGuid>
<OutputType>Library</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>coscine.cs_S3Zip.Tests</RootNamespace>
<AssemblyName>cs-S3Zip.Tests</AssemblyName>
<TargetFrameworkVersion>v4.7.2</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
<Deterministic>true</Deterministic>
<NuGetPackageImportStamp>
</NuGetPackageImportStamp>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<ItemGroup>
<Reference Include="AWSSDK.Core, Version=3.3.0.0, Culture=neutral, PublicKeyToken=885c28607f98e604" />
<Reference Include="AWSSDK.S3, Version=3.3.0.0, Culture=neutral, PublicKeyToken=885c28607f98e604" />
<Reference Include="nunit.framework, Version=3.11.0.0, Culture=neutral, PublicKeyToken=2638cd05610744eb, processorArchitecture=MSIL">
<HintPath>..\packages\NUnit.3.11.0\lib\net45\nunit.framework.dll</HintPath>
</Reference>
<Reference Include="System" />
<Reference Include="System.Core" />
<Reference Include="System.Xml.Linq" />
<Reference Include="System.Data.DataSetExtensions" />
<Reference Include="Microsoft.CSharp" />
<Reference Include="System.Data" />
<Reference Include="System.Net.Http" />
<Reference Include="System.Xml" />
</ItemGroup>
<ItemGroup>
<Compile Include="S3ZipTests.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
</ItemGroup>
<ItemGroup>
<None Include="packages.config" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\cs-S3Zip\cs-S3Zip.csproj">
<Project>{7AC0CBDF-046B-496E-931B-776678098C7E}</Project>
<Name>cs-S3Zip</Name>
</ProjectReference>
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
<PropertyGroup>
<ErrorText>This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.</ErrorText>
</PropertyGroup>
<Error Condition="!Exists('..\packages\NUnit.3.11.0\build\NUnit.props')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\NUnit.3.11.0\build\NUnit.props'))" />
<Error Condition="!Exists('..\packages\NUnit3TestAdapter.3.13.0\build\net35\NUnit3TestAdapter.props')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\NUnit3TestAdapter.3.13.0\build\net35\NUnit3TestAdapter.props'))" />
</Target>
</Project>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="NUnit" version="3.11.0" targetFramework="net472" />
<package id="NUnit3TestAdapter" version="3.13.0" targetFramework="net472" />
</packages>
\ No newline at end of file

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 16
VisualStudioVersion = 16.0.28803.156
MinimumVisualStudioVersion = 10.0.40219.1
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "cs-S3Zip", "cs-S3Zip\cs-S3Zip.csproj", "{7AC0CBDF-046B-496E-931B-776678098C7E}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "cs-S3Zip.Tests", "cs-S3Zip.Tests\cs-S3Zip.Tests.csproj", "{6B58EB5E-D857-464B-8174-C17375BAE1CF}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Release|Any CPU = Release|Any CPU
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{7AC0CBDF-046B-496E-931B-776678098C7E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{7AC0CBDF-046B-496E-931B-776678098C7E}.Debug|Any CPU.Build.0 = Debug|Any CPU
{7AC0CBDF-046B-496E-931B-776678098C7E}.Release|Any CPU.ActiveCfg = Release|Any CPU
{7AC0CBDF-046B-496E-931B-776678098C7E}.Release|Any CPU.Build.0 = Release|Any CPU
{6B58EB5E-D857-464B-8174-C17375BAE1CF}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{6B58EB5E-D857-464B-8174-C17375BAE1CF}.Debug|Any CPU.Build.0 = Debug|Any CPU
{6B58EB5E-D857-464B-8174-C17375BAE1CF}.Release|Any CPU.ActiveCfg = Release|Any CPU
{6B58EB5E-D857-464B-8174-C17375BAE1CF}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {CB4D8BFF-53DB-45F3-9A1B-8572F8A2D443}
EndGlobalSection
EndGlobal
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
// General Information about an assembly is controlled through the following
// set of attributes. Change these attribute values to modify the information
// associated with an assembly.
[assembly: AssemblyTitle("cs-S3Zip")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("cs-S3Zip")]
[assembly: AssemblyCopyright("Copyright © 2019")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
// Setting ComVisible to false makes the types in this assembly not visible
// to COM components. If you need to access a type in this assembly from
// COM, set the ComVisible attribute to true on that type.
[assembly: ComVisible(false)]
// The following GUID is for the ID of the typelib if this project is exposed to COM
[assembly: Guid("7ac0cbdf-046b-496e-931b-776678098c7e")]
// Version information for an assembly consists of the following four values:
//
// Major Version
// Minor Version
// Build Number
// Revision
//
// You can specify all the values or you can default the Build and Revision Numbers
// by using the '*' as shown below:
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("1.0.0.0")]
[assembly: AssemblyFileVersion("1.0.0.0")]
using Amazon.S3;
using Amazon.S3.Model;
using System;
using System.Collections.Generic;
using System.IO;
namespace coscine.cs_S3Zip
{
public class S3MultipartStream : Stream
{
private readonly Stream _internalStream;
private readonly InitiateMultipartUploadResponse _initiateMultipartUploadResponse;
private readonly List<UploadPartResponse> _uploadPartResponses;
private int _part;
private int _length;
private int _position;
public S3MultipartStream(string key, S3MultipartStreamConfiguration s3MultipartStreamConfiguration, Stream internalStream)
{
S3MultipartStreamConfiguration = s3MultipartStreamConfiguration;
_internalStream = internalStream;
_uploadPartResponses = new List<UploadPartResponse>();
_part = 0;
_length = 0;
_position = 0;
Key = key;
var initiateRequest = new InitiateMultipartUploadRequest
{
BucketName = S3MultipartStreamConfiguration.BucketName,
Key = key
};
using (var client = new AmazonS3Client(S3MultipartStreamConfiguration.AccessKey, S3MultipartStreamConfiguration.SecretKey, S3MultipartStreamConfiguration.AmazonS3Config))
{
_initiateMultipartUploadResponse = client.InitiateMultipartUpload(initiateRequest);
}
}
public S3MultipartStream(string key, S3MultipartStreamConfiguration s3MultipartStreamConfiguration) : this(key, s3MultipartStreamConfiguration, new MemoryStream(s3MultipartStreamConfiguration.ChunckSize))
{
}
public string Key { get; }
public S3MultipartStreamConfiguration S3MultipartStreamConfiguration { get; set; }
public override bool CanRead => false;
public override bool CanSeek => false;
public override bool CanWrite => true;
public override long Length => _length;
public override long Position { get => _position; set => throw new NotImplementedException(); }
public override void Flush()
{
_internalStream.Flush();
}
public override int Read(byte[] buffer, int offset, int count)
{
throw new NotImplementedException();
}
public override long Seek(long offset, SeekOrigin origin)
{
throw new NotImplementedException();
}
public override void SetLength(long value)
{
throw new NotImplementedException();
}
public override void Write(byte[] buffer, int offset, int count)
{
int written = 0;
while (written < count)
{
if (count - written + _internalStream.Length <= S3MultipartStreamConfiguration.ChunckSize)
{
_internalStream.Write(buffer, offset + written, count - written);
break;
}
else
{
int toBeWritten = S3MultipartStreamConfiguration.ChunckSize - (int)_internalStream.Length;
_internalStream.Write(buffer, offset + written, toBeWritten);
written += toBeWritten;
UploadPart();
// resets stream
_internalStream.SetLength(0);
}
}
_length += count;
_position += count;
}
private void UploadPart()
{
using (var client = new AmazonS3Client(S3MultipartStreamConfiguration.AccessKey, S3MultipartStreamConfiguration.SecretKey, S3MultipartStreamConfiguration.AmazonS3Config))
{
_internalStream.Position = 0;
var uploadPartRequest = new UploadPartRequest
{
BucketName = S3MultipartStreamConfiguration.BucketName,
Key = Key,
UploadId = _initiateMultipartUploadResponse.UploadId,
PartNumber = _part + 1,
PartSize = _internalStream.Length,
InputStream = _internalStream
};
_uploadPartResponses.Add(client.UploadPart(uploadPartRequest));
_part++;
}
}
private void FinalizeS3MultipartUpload()
{
var completeRequest = new CompleteMultipartUploadRequest
{
BucketName = S3MultipartStreamConfiguration.BucketName,
Key = Key,
UploadId = _initiateMultipartUploadResponse.UploadId
};
completeRequest.AddPartETags(_uploadPartResponses);
using (var client = new AmazonS3Client(S3MultipartStreamConfiguration.AccessKey, S3MultipartStreamConfiguration.SecretKey, S3MultipartStreamConfiguration.AmazonS3Config))
{
client.CompleteMultipartUpload(completeRequest);
}
}
// Finalize on stream close clall.
public override void Close()
{
if(_internalStream.Length > 0)
{
UploadPart();
}
FinalizeS3MultipartUpload();
_internalStream.Close();
}
}
}
using Amazon.S3;
using System;
namespace coscine.cs_S3Zip
{
public class S3MultipartStreamConfiguration
{
public string AccessKey { get; set; }
public string SecretKey { get; set; }
public string BucketName { get; set; }
public AmazonS3Config AmazonS3Config { get; set; }
public int ChunckSize { get; set; } = 50 * (int)Math.Pow(2, 20);
}
}
using System.Collections.Generic;
using System.IO;
using System.IO.Compression;
namespace coscine.cs_S3Zip
{
public class ZipUtilities
{
public S3MultipartStreamConfiguration S3ZipConfiguration { get; set; }
public ZipUtilities(S3MultipartStreamConfiguration s3ZipConfiguration)
{
S3ZipConfiguration = s3ZipConfiguration;
}
public void ZipFolder(string path, ZipArchive zipArchive)
{
ZipFolder(new DirectoryInfo(path), zipArchive);
}
public void ZipFolder(DirectoryInfo directoryInfo, ZipArchive zipArchive)
{
var prefixLength = directoryInfo.FullName.EndsWith(@"\") ? directoryInfo.FullName.Length : directoryInfo.FullName.Length + 1;
ZipFiles(directoryInfo.GetFiles("*", SearchOption.AllDirectories), prefixLength, zipArchive);
}
public void ZipFiles(IEnumerable<FileInfo> files, int prefixLength, ZipArchive zipArchive)
{
foreach (var file in files)
{
// cut off parent directory path
var fileEntry = zipArchive.CreateEntry(file.FullName.Substring(prefixLength));
using (var fileStream = file.OpenRead())
{
ZipStream(fileStream, fileEntry);
}
}
}
public void ZipStream(Stream stream, ZipArchiveEntry fileEntry)
{
using (var entryStream = fileEntry.Open())
{
stream.CopyTo(entryStream);
}
}
public void ZipAndUploadFolder(string path)
{
ZipAndUploadFolder(new DirectoryInfo(path));
}
public void ZipAndUploadFolder(DirectoryInfo directoryInfo)
{
ZipAndUploadFolder(directoryInfo, directoryInfo.Name);
}
public void ZipAndUploadFolder(string path, string key)
{
ZipAndUploadFolder(new DirectoryInfo(path), key);
}
public void ZipAndUploadFolder(DirectoryInfo directoryInfo, string key)
{
using (var s3Stream = new S3MultipartStream(key, S3ZipConfiguration))
{
using (var archive = new ZipArchive(s3Stream, ZipArchiveMode.Create, true))
{
ZipFolder(directoryInfo, archive);
}
}
}
}
}
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProjectGuid>{7AC0CBDF-046B-496E-931B-776678098C7E}</ProjectGuid>
<OutputType>Library</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>coscine.cs_S3Zip</RootNamespace>
<AssemblyName>cs-S3Zip</AssemblyName>
<TargetFrameworkVersion>v4.7.2</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
<Deterministic>true</Deterministic>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<ItemGroup>
<Reference Include="AWSSDK.Core, Version=3.3.0.0, Culture=neutral, PublicKeyToken=885c28607f98e604, processorArchitecture=MSIL">
<HintPath>..\packages\AWSSDK.Core.3.3.101.1\lib\net45\AWSSDK.Core.dll</HintPath>
</Reference>
<Reference Include="AWSSDK.S3, Version=3.3.0.0, Culture=neutral, PublicKeyToken=885c28607f98e604, processorArchitecture=MSIL">
<HintPath>..\packages\AWSSDK.S3.3.3.101.8\lib\net45\AWSSDK.S3.dll</HintPath>
</Reference>
<Reference Include="System" />
<Reference Include="System.Core" />
<Reference Include="System.IO.Compression" />
<Reference Include="System.Xml.Linq" />
<Reference Include="System.Data.DataSetExtensions" />
<Reference Include="Microsoft.CSharp" />
<Reference Include="System.Data" />
<Reference Include="System.Net.Http" />
<Reference Include="System.Xml" />
</ItemGroup>
<ItemGroup>
<Compile Include="S3MultipartStream.cs" />
<Compile Include="ZipUtilities.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="S3MultipartStreamConfiguration.cs" />
</ItemGroup>
<ItemGroup>
<None Include="packages.config" />
</ItemGroup>
<ItemGroup>
<Analyzer Include="..\packages\AWSSDK.S3.3.3.101.8\analyzers\dotnet\cs\AWSSDK.S3.CodeAnalysis.dll" />
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
</Project>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="AWSSDK.Core" version="3.3.101.1" targetFramework="net472" />
<package id="AWSSDK.S3" version="3.3.101.8" targetFramework="net472" />
</packages>
\ No newline at end of file
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment