Added Amazon S3 regions list, added custom region support

This commit is contained in:
Jaex 2017-03-17 03:15:19 +03:00
parent e20506ed8d
commit 058872b87a
7 changed files with 8236 additions and 2157 deletions

View file

@ -48,7 +48,7 @@ public override bool CheckConfig(UploadersConfig config)
{
return config.AmazonS3Settings != null && !string.IsNullOrEmpty(config.AmazonS3Settings.AccessKeyID) &&
!string.IsNullOrEmpty(config.AmazonS3Settings.SecretAccessKey) && !string.IsNullOrEmpty(config.AmazonS3Settings.Bucket) &&
!string.IsNullOrEmpty(config.AmazonS3Settings.Endpoint);
!string.IsNullOrEmpty(config.AmazonS3Settings.RegionHostname) && !string.IsNullOrEmpty(config.AmazonS3Settings.RegionIdentifier);
}
public override GenericUploader CreateUploader(UploadersConfig config, TaskReferenceHelper taskInfo)
@ -61,6 +61,26 @@ public override GenericUploader CreateUploader(UploadersConfig config, TaskRefer
public sealed class AmazonS3 : FileUploader
{
public static List<AmazonS3Region> Regions { get; } = new List<AmazonS3Region>()
{
new AmazonS3Region("Asia Pacific (Tokyo)", "s3-ap-northeast-1.amazonaws.com", "ap-northeast-1"),
new AmazonS3Region("Asia Pacific (Seoul)", "s3.ap-northeast-2.amazonaws.com", "ap-northeast-2"),
new AmazonS3Region("Asia Pacific (Mumbai)", "s3.ap-south-1.amazonaws.com", "ap-south-1"),
new AmazonS3Region("Asia Pacific (Singapore)", "s3-ap-southeast-1.amazonaws.com", "ap-southeast-1"),
new AmazonS3Region("Asia Pacific (Sydney)", "s3-ap-southeast-2.amazonaws.com", "ap-southeast-2"),
new AmazonS3Region("Canada (Central)", "s3.ca-central-1.amazonaws.com", "ca-central-1"),
new AmazonS3Region("EU Central (Frankfurt)", "s3.eu-central-1.amazonaws.com", "eu-central-1"),
new AmazonS3Region("EU West (Ireland)", "s3-eu-west-1.amazonaws.com", "eu-west-1"),
new AmazonS3Region("EU West (London)", "s3.eu-west-2.amazonaws.com", "eu-west-2"),
new AmazonS3Region("South America (Sao Paulo)", "s3-sa-east-1.amazonaws.com", "sa-east-1"),
new AmazonS3Region("US East (Virginia)", "s3.amazonaws.com", "us-east-1"),
new AmazonS3Region("US East (Ohio)", "s3.us-east-2.amazonaws.com", "us-east-2"),
new AmazonS3Region("US West (N. California)", "s3-us-west-1.amazonaws.com", "us-west-1"),
new AmazonS3Region("US West (Oregon)", "s3-us-west-2.amazonaws.com", "us-west-2"),
new AmazonS3Region("China (Beijing)", "s3.cn-north-1.amazonaws.com.cn", "cn-north-1"),
new AmazonS3Region("US GovCloud West (Oregon)", "s3-us-gov-west-1.amazonaws.com", "us-gov-west-1")
};
private AmazonS3Settings Settings { get; set; }
public AmazonS3(AmazonS3Settings settings)
@ -70,10 +90,11 @@ public AmazonS3(AmazonS3Settings settings)
public override UploadResult Upload(Stream stream, string fileName)
{
string host = $"{Settings.Bucket}.s3.{Settings.Endpoint}.amazonaws.com";
string hostname = URLHelpers.RemovePrefixes(Settings.RegionHostname);
string host = $"{Settings.Bucket}.{hostname}";
string algorithm = "AWS4-HMAC-SHA256";
string credentialDate = DateTime.UtcNow.ToString("yyyyMMdd", CultureInfo.InvariantCulture);
string scope = $"{credentialDate}/{Settings.Endpoint}/s3/aws4_request";
string scope = $"{credentialDate}/{Settings.RegionIdentifier}/s3/aws4_request";
string credential = $"{Settings.AccessKeyID}/{scope}";
string longDate = DateTime.UtcNow.ToString("yyyyMMddTHHmmssZ", CultureInfo.InvariantCulture);
string expiresTotalSeconds = ((long)TimeSpan.FromHours(1).TotalSeconds).ToString();
@ -115,7 +136,7 @@ public override UploadResult Upload(Stream stream, string fileName)
byte[] secretKey = Encoding.UTF8.GetBytes("AWS4" + Settings.SecretAccessKey);
byte[] dateKey = ComputeHMAC(Encoding.UTF8.GetBytes(credentialDate), secretKey);
byte[] dateRegionKey = ComputeHMAC(Encoding.UTF8.GetBytes(Settings.Endpoint), dateKey);
byte[] dateRegionKey = ComputeHMAC(Encoding.UTF8.GetBytes(Settings.RegionIdentifier), dateKey);
byte[] dateRegionServiceKey = ComputeHMAC(Encoding.UTF8.GetBytes("s3"), dateRegionKey);
byte[] signingKey = ComputeHMAC(Encoding.UTF8.GetBytes("aws4_request"), dateRegionServiceKey);
string signature = BytesToHex(ComputeHMAC(Encoding.UTF8.GetBytes(stringToSign), signingKey));
@ -158,7 +179,8 @@ private string GetUploadPath(string fileName)
public string GenerateURL(string fileName)
{
string uploadPath = GetUploadPath(fileName);
return URLHelpers.CombineURL($"https://s3.{Settings.Endpoint}.amazonaws.com", Settings.Bucket, uploadPath);
string url = URLHelpers.CombineURL(Settings.RegionHostname, Settings.Bucket, uploadPath);
return URLHelpers.ForcePrefix(url, "https://");
}
private string CreateCanonicalHeaders(NameValueCollection headers)

View file

@ -0,0 +1,46 @@
#region License Information (GPL v3)
/*
ShareX - A program that allows you to take screenshots and share any file type
Copyright (c) 2007-2017 ShareX Team
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
Optionally you can also view the license at <http://www.gnu.org/licenses/>.
*/
#endregion License Information (GPL v3)
namespace ShareX.UploadersLib.FileUploaders
{
public class AmazonS3Region
{
public string Name { get; set; }
public string Hostname { get; set; }
public string Identifier { get; set; }
public AmazonS3Region(string name, string hostname, string identifier)
{
Name = name;
Hostname = hostname;
Identifier = identifier;
}
public override string ToString()
{
return $"{Name} [{Identifier}]";
}
}
}

View file

@ -29,7 +29,8 @@ public class AmazonS3Settings
{
public string AccessKeyID { get; set; }
public string SecretAccessKey { get; set; }
public string Endpoint { get; set; }
public string RegionHostname { get; set; }
public string RegionIdentifier { get; set; }
public string Bucket { get; set; }
public string ObjectPrefix { get; set; }
public bool UseCustomCNAME { get; set; }

View file

@ -230,7 +230,7 @@ private void InitializeComponent()
this.cbAmazonS3Endpoint = new System.Windows.Forms.ComboBox();
this.lblAmazonS3BucketName = new System.Windows.Forms.Label();
this.txtAmazonS3BucketName = new System.Windows.Forms.TextBox();
this.lblAmazonS3Endpoint = new System.Windows.Forms.Label();
this.lblAmazonS3Regions = new System.Windows.Forms.Label();
this.txtAmazonS3ObjectPrefix = new System.Windows.Forms.TextBox();
this.lblAmazonS3ObjectPrefix = new System.Windows.Forms.Label();
this.txtAmazonS3SecretKey = new System.Windows.Forms.TextBox();
@ -593,6 +593,11 @@ private void InitializeComponent()
this.lblWidthHint = new System.Windows.Forms.Label();
this.ttlvMain = new ShareX.HelpersLib.TabToListView();
this.actRapidShareAccountType = new ShareX.UploadersLib.AccountTypeControl();
this.txtAmazonS3Identifier = new System.Windows.Forms.TextBox();
this.lblAmazonS3Identifier = new System.Windows.Forms.Label();
this.toolTip1 = new System.Windows.Forms.ToolTip(this.components);
this.txtAmazonS3Hostname = new System.Windows.Forms.TextBox();
this.lblAmazonS3Hostname = new System.Windows.Forms.Label();
this.tpOtherUploaders.SuspendLayout();
this.tcOtherUploaders.SuspendLayout();
this.tpTwitter.SuspendLayout();
@ -2131,6 +2136,10 @@ private void InitializeComponent()
//
// tpAmazonS3
//
this.tpAmazonS3.Controls.Add(this.lblAmazonS3Hostname);
this.tpAmazonS3.Controls.Add(this.txtAmazonS3Hostname);
this.tpAmazonS3.Controls.Add(this.lblAmazonS3Identifier);
this.tpAmazonS3.Controls.Add(this.txtAmazonS3Identifier);
this.tpAmazonS3.Controls.Add(this.txtAmazonS3CustomDomain);
this.tpAmazonS3.Controls.Add(this.lblAmazonS3PathPreviewLabel);
this.tpAmazonS3.Controls.Add(this.lblAmazonS3PathPreview);
@ -2140,7 +2149,7 @@ private void InitializeComponent()
this.tpAmazonS3.Controls.Add(this.cbAmazonS3Endpoint);
this.tpAmazonS3.Controls.Add(this.lblAmazonS3BucketName);
this.tpAmazonS3.Controls.Add(this.txtAmazonS3BucketName);
this.tpAmazonS3.Controls.Add(this.lblAmazonS3Endpoint);
this.tpAmazonS3.Controls.Add(this.lblAmazonS3Regions);
this.tpAmazonS3.Controls.Add(this.txtAmazonS3ObjectPrefix);
this.tpAmazonS3.Controls.Add(this.lblAmazonS3ObjectPrefix);
this.tpAmazonS3.Controls.Add(this.cbAmazonS3UseRRS);
@ -2184,10 +2193,11 @@ private void InitializeComponent()
//
// cbAmazonS3Endpoint
//
this.cbAmazonS3Endpoint.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
this.cbAmazonS3Endpoint.FormattingEnabled = true;
resources.ApplyResources(this.cbAmazonS3Endpoint, "cbAmazonS3Endpoint");
this.cbAmazonS3Endpoint.Name = "cbAmazonS3Endpoint";
this.cbAmazonS3Endpoint.TextChanged += new System.EventHandler(this.cbAmazonS3Endpoint_TextChanged);
this.cbAmazonS3Endpoint.SelectedIndexChanged += new System.EventHandler(this.cbAmazonS3Endpoint_SelectedIndexChanged);
//
// lblAmazonS3BucketName
//
@ -2200,10 +2210,10 @@ private void InitializeComponent()
this.txtAmazonS3BucketName.Name = "txtAmazonS3BucketName";
this.txtAmazonS3BucketName.TextChanged += new System.EventHandler(this.txtAmazonS3BucketName_TextChanged);
//
// lblAmazonS3Endpoint
// lblAmazonS3Regions
//
resources.ApplyResources(this.lblAmazonS3Endpoint, "lblAmazonS3Endpoint");
this.lblAmazonS3Endpoint.Name = "lblAmazonS3Endpoint";
resources.ApplyResources(this.lblAmazonS3Regions, "lblAmazonS3Regions");
this.lblAmazonS3Regions.Name = "lblAmazonS3Regions";
//
// txtAmazonS3ObjectPrefix
//
@ -4788,6 +4798,28 @@ private void InitializeComponent()
this.actRapidShareAccountType.Name = "actRapidShareAccountType";
this.actRapidShareAccountType.SelectedAccountType = ShareX.UploadersLib.AccountType.Anonymous;
//
// txtAmazonS3Identifier
//
resources.ApplyResources(this.txtAmazonS3Identifier, "txtAmazonS3Identifier");
this.txtAmazonS3Identifier.Name = "txtAmazonS3Identifier";
this.txtAmazonS3Identifier.TextChanged += new System.EventHandler(this.txtAmazonS3Identifier_TextChanged);
//
// lblAmazonS3Identifier
//
resources.ApplyResources(this.lblAmazonS3Identifier, "lblAmazonS3Identifier");
this.lblAmazonS3Identifier.Name = "lblAmazonS3Identifier";
//
// txtAmazonS3Hostname
//
resources.ApplyResources(this.txtAmazonS3Hostname, "txtAmazonS3Hostname");
this.txtAmazonS3Hostname.Name = "txtAmazonS3Hostname";
this.txtAmazonS3Hostname.TextChanged += new System.EventHandler(this.txtAmazonS3Hostname_TextChanged);
//
// lblAmazonS3Hostname
//
resources.ApplyResources(this.lblAmazonS3Hostname, "lblAmazonS3Hostname");
this.lblAmazonS3Hostname.Name = "lblAmazonS3Hostname";
//
// UploadersConfigForm
//
resources.ApplyResources(this, "$this");
@ -5067,7 +5099,7 @@ private void InitializeComponent()
private System.Windows.Forms.ComboBox cbAmazonS3Endpoint;
private System.Windows.Forms.Label lblAmazonS3BucketName;
private System.Windows.Forms.TextBox txtAmazonS3BucketName;
private System.Windows.Forms.Label lblAmazonS3Endpoint;
private System.Windows.Forms.Label lblAmazonS3Regions;
private System.Windows.Forms.TextBox txtAmazonS3ObjectPrefix;
private System.Windows.Forms.Label lblAmazonS3ObjectPrefix;
private System.Windows.Forms.CheckBox cbAmazonS3UseRRS;
@ -5522,5 +5554,10 @@ private void InitializeComponent()
private System.Windows.Forms.Label lblGistCustomURL;
private System.Windows.Forms.Label lblGistOAuthInfo;
private System.Windows.Forms.Label lblGistCustomURLExample;
private System.Windows.Forms.TextBox txtAmazonS3Identifier;
private System.Windows.Forms.TextBox txtAmazonS3Hostname;
private System.Windows.Forms.Label lblAmazonS3Identifier;
private System.Windows.Forms.ToolTip toolTip1;
private System.Windows.Forms.Label lblAmazonS3Hostname;
}
}

View file

@ -515,13 +515,15 @@ public void LoadSettings()
txtAmazonS3AccessKey.Text = Config.AmazonS3Settings.AccessKeyID;
txtAmazonS3SecretKey.Text = Config.AmazonS3Settings.SecretAccessKey;
cbAmazonS3Endpoint.Items.AddRange(AmazonS3.Regions.ToArray());
txtAmazonS3Hostname.Text = Config.AmazonS3Settings.RegionHostname;
txtAmazonS3Identifier.Text = Config.AmazonS3Settings.RegionIdentifier;
txtAmazonS3BucketName.Text = Config.AmazonS3Settings.Bucket;
txtAmazonS3ObjectPrefix.Text = Config.AmazonS3Settings.ObjectPrefix;
cbAmazonS3CustomCNAME.Checked = Config.AmazonS3Settings.UseCustomCNAME;
txtAmazonS3CustomDomain.Enabled = Config.AmazonS3Settings.UseCustomCNAME;
txtAmazonS3CustomDomain.Text = Config.AmazonS3Settings.CustomDomain;
cbAmazonS3UseRRS.Checked = Config.AmazonS3Settings.UseReducedRedundancyStorage;
cbAmazonS3Endpoint.Text = Config.AmazonS3Settings.Endpoint;
UpdateAmazonS3Status();
// ownCloud
@ -582,17 +584,20 @@ public void LoadSettings()
cbStreamableUseDirectURL.Checked = Config.StreamableUseDirectURL;
// Uplea
txtUpleaApiKey.Text = Config.UpleaApiKey;
txtUpleaEmailAddress.Text = Config.UpleaEmailAddress;
cbUpleaInstantDownloadEnabled.Checked = Config.UpleaInstantDownloadEnabled;
cbUpleaIsPremium.Checked = Config.UpleaIsPremiumMember;
// Azure Storage
txtAzureStorageAccountName.Text = Config.AzureStorageAccountName;
txtAzureStorageAccessKey.Text = Config.AzureStorageAccountAccessKey;
txtAzureStorageContainer.Text = Config.AzureStorageContainer;
// Plik
txtPlikAPIKey.Text = Config.PlikSettings.APIKey;
txtPlikURL.Text = Config.PlikSettings.URL;
txtPlikPassword.Text = Config.PlikSettings.Password;
@ -1970,9 +1975,27 @@ private void txtAmazonS3SecretKey_TextChanged(object sender, EventArgs e)
Config.AmazonS3Settings.SecretAccessKey = txtAmazonS3SecretKey.Text;
}
private void cbAmazonS3Endpoint_TextChanged(object sender, EventArgs e)
private void cbAmazonS3Endpoint_SelectedIndexChanged(object sender, EventArgs e)
{
Config.AmazonS3Settings.Endpoint = cbAmazonS3Endpoint.Text;
AmazonS3Region region = cbAmazonS3Endpoint.SelectedItem as AmazonS3Region;
if (region != null)
{
txtAmazonS3Identifier.Text = region.Identifier;
txtAmazonS3Hostname.Text = region.Hostname;
}
}
private void txtAmazonS3Hostname_TextChanged(object sender, EventArgs e)
{
Config.AmazonS3Settings.RegionHostname = txtAmazonS3Hostname.Text;
UpdateAmazonS3Status();
}
private void txtAmazonS3Identifier_TextChanged(object sender, EventArgs e)
{
Config.AmazonS3Settings.RegionIdentifier = txtAmazonS3Identifier.Text;
UpdateAmazonS3Status();
}
private void txtAmazonS3BucketName_TextChanged(object sender, EventArgs e)

File diff suppressed because it is too large Load diff

View file

@ -115,6 +115,7 @@
<Compile Include="BaseServices\IUploaderService.cs" />
<Compile Include="BaseUploaders\GenericUploader.cs" />
<Compile Include="FileUploaders\AmazonS3.cs" />
<Compile Include="FileUploaders\AmazonS3Region.cs" />
<Compile Include="FileUploaders\AmazonS3Settings.cs" />
<Compile Include="FileUploaders\AzureStorage.cs" />
<Compile Include="FileUploaders\AzureStorageSettings.cs" />