diff --git a/ShareX.UploadersLib/FileUploaders/AzureStorage.cs b/ShareX.UploadersLib/FileUploaders/AzureStorage.cs
index 60f717469..2a9724bf7 100644
--- a/ShareX.UploadersLib/FileUploaders/AzureStorage.cs
+++ b/ShareX.UploadersLib/FileUploaders/AzureStorage.cs
@@ -51,7 +51,7 @@ public override bool CheckConfig(UploadersConfig config)
public override GenericUploader CreateUploader(UploadersConfig config, TaskReferenceHelper taskInfo)
{
- return new AzureStorage(config.AzureStorageAccountName, config.AzureStorageAccountAccessKey, config.AzureStorageContainer, config.AzureStorageEnvironment, config.AzureStorageCustomDomain);
+ return new AzureStorage(config.AzureStorageAccountName, config.AzureStorageAccountAccessKey, config.AzureStorageContainer, config.AzureStorageEnvironment, config.AzureStorageCustomDomain, config.AzureStorageUploadPath, config.AzureStorageExcludeContainer);
}
public override TabPage GetUploadersConfigTabPage(UploadersConfigForm form) => form.tpAzureStorage;
@@ -66,14 +66,18 @@ public sealed class AzureStorage : FileUploader
public string AzureStorageContainer { get; private set; }
public string AzureStorageEnvironment { get; private set; }
public string AzureStorageCustomDomain { get; private set; }
+ public string AzureStorageUploadPath { get; private set; }
+ public bool AzureStorageExcludeContainer { get; private set; }
- public AzureStorage(string azureStorageAccountName, string azureStorageAccessKey, string azureStorageContainer, string azureStorageEnvironment, string customDomain)
+ public AzureStorage(string azureStorageAccountName, string azureStorageAccessKey, string azureStorageContainer, string azureStorageEnvironment, string customDomain, string uploadPath, bool excludeContainer)
{
AzureStorageAccountName = azureStorageAccountName;
AzureStorageAccountAccessKey = azureStorageAccessKey;
AzureStorageContainer = azureStorageContainer;
AzureStorageEnvironment = (!string.IsNullOrEmpty(azureStorageEnvironment)) ? azureStorageEnvironment : "blob.core.windows.net";
AzureStorageCustomDomain = customDomain;
+ AzureStorageUploadPath = uploadPath;
+ AzureStorageExcludeContainer = excludeContainer;
}
public override UploadResult Upload(Stream stream, string fileName)
@@ -90,7 +94,16 @@ public override UploadResult Upload(Stream stream, string fileName)
CreateContainerIfNotExists();
string date = DateTime.UtcNow.ToString("R", CultureInfo.InvariantCulture);
- string url = $"https://{AzureStorageAccountName}.{AzureStorageEnvironment}/{AzureStorageContainer}/{fileName}";
+ string targetPath = GetUploadPath(fileName);
+ string url;
+ if (AzureStorageContainer == "$root")
+ {
+ url = $"https://{AzureStorageAccountName}.{AzureStorageEnvironment}/{targetPath}";
+ }
+ else
+ {
+ url = $"https://{AzureStorageAccountName}.{AzureStorageEnvironment}/{AzureStorageContainer}/{targetPath}";
+ }
string contentType = Helpers.GetMimeType(fileName);
NameValueCollection requestHeaders = new NameValueCollection();
@@ -99,7 +112,15 @@ public override UploadResult Upload(Stream stream, string fileName)
requestHeaders["x-ms-blob-type"] = "BlockBlob";
string canonicalizedHeaders = $"x-ms-blob-type:BlockBlob\nx-ms-date:{date}\nx-ms-version:{APIVersion}\n";
- string canonicalizedResource = $"/{AzureStorageAccountName}/{AzureStorageContainer}/{fileName}";
+ string canonicalizedResource;
+ if (AzureStorageContainer == "$root")
+ {
+ canonicalizedResource = $"/{AzureStorageAccountName}/{targetPath}";
+ }
+ else
+ {
+ canonicalizedResource = $"/{AzureStorageAccountName}/{AzureStorageContainer}/{targetPath}";
+ }
string stringToSign = GenerateStringToSign(canonicalizedHeaders, canonicalizedResource, stream.Length.ToString(), contentType);
requestHeaders["Authorization"] = $"SharedKey {AzureStorageAccountName}:{stringToSign}";
@@ -112,7 +133,14 @@ public override UploadResult Upload(Stream stream, string fileName)
if (!string.IsNullOrEmpty(AzureStorageCustomDomain))
{
- result = URLHelpers.CombineURL(AzureStorageCustomDomain, AzureStorageContainer, fileName);
+ if (AzureStorageExcludeContainer)
+ {
+ result = URLHelpers.CombineURL(AzureStorageCustomDomain, targetPath);
+ }
+ else
+ {
+ result = URLHelpers.CombineURL(AzureStorageCustomDomain, AzureStorageContainer, targetPath);
+ }
result = URLHelpers.FixPrefix(result);
}
else
@@ -224,5 +252,18 @@ private string HashRequest(string stringToSign)
return hashedString;
}
+
+ private string GetUploadPath(string fileName)
+ {
+ if (!String.IsNullOrEmpty(AzureStorageUploadPath))
+ {
+ string path = NameParser.Parse(NameParserType.FolderPath, AzureStorageUploadPath.Trim('/'));
+ return URLHelpers.CombineURL(path, fileName);
+ }
+ else
+ {
+ return fileName;
+ }
+ }
}
}
\ No newline at end of file
diff --git a/ShareX.UploadersLib/Forms/UploadersConfigForm.Designer.cs b/ShareX.UploadersLib/Forms/UploadersConfigForm.Designer.cs
index c4409e0b5..ef84a07fb 100644
--- a/ShareX.UploadersLib/Forms/UploadersConfigForm.Designer.cs
+++ b/ShareX.UploadersLib/Forms/UploadersConfigForm.Designer.cs
@@ -309,6 +309,9 @@ private void InitializeComponent()
this.txtGoogleCloudStorageBucket = new System.Windows.Forms.TextBox();
this.oauth2GoogleCloudStorage = new ShareX.UploadersLib.OAuthControl();
this.tpAzureStorage = new System.Windows.Forms.TabPage();
+ this.cbAzureStorageExcludeContainer = new System.Windows.Forms.CheckBox();
+ this.txtAzureStorageUploadPath = new System.Windows.Forms.TextBox();
+ this.lblAzureStorageUploadPath = new System.Windows.Forms.Label();
this.cbAzureStorageEnvironment = new System.Windows.Forms.ComboBox();
this.lblAzureStorageEnvironment = new System.Windows.Forms.Label();
this.btnAzureStoragePortal = new System.Windows.Forms.Button();
@@ -2830,6 +2833,9 @@ private void InitializeComponent()
// tpAzureStorage
//
this.tpAzureStorage.BackColor = System.Drawing.SystemColors.Window;
+ this.tpAzureStorage.Controls.Add(this.cbAzureStorageExcludeContainer);
+ this.tpAzureStorage.Controls.Add(this.txtAzureStorageUploadPath);
+ this.tpAzureStorage.Controls.Add(this.lblAzureStorageUploadPath);
this.tpAzureStorage.Controls.Add(this.cbAzureStorageEnvironment);
this.tpAzureStorage.Controls.Add(this.lblAzureStorageEnvironment);
this.tpAzureStorage.Controls.Add(this.btnAzureStoragePortal);
@@ -2844,6 +2850,24 @@ private void InitializeComponent()
resources.ApplyResources(this.tpAzureStorage, "tpAzureStorage");
this.tpAzureStorage.Name = "tpAzureStorage";
//
+ // cbAzureStorageExcludeContainer
+ //
+ resources.ApplyResources(this.cbAzureStorageExcludeContainer, "cbAzureStorageExcludeContainer");
+ this.cbAzureStorageExcludeContainer.Name = "cbAzureStorageExcludeContainer";
+ this.cbAzureStorageExcludeContainer.UseVisualStyleBackColor = true;
+ this.cbAzureStorageExcludeContainer.CheckedChanged += new System.EventHandler(this.cbAzureStorageExcludeContainer_CheckedChanged);
+ //
+ // txtAzureStorageUploadPath
+ //
+ resources.ApplyResources(this.txtAzureStorageUploadPath, "txtAzureStorageUploadPath");
+ this.txtAzureStorageUploadPath.Name = "txtAzureStorageUploadPath";
+ this.txtAzureStorageUploadPath.TextChanged += new System.EventHandler(this.txtAzureStorageUploadPath_TextChanged);
+ //
+ // lblAzureStorageUploadPath
+ //
+ resources.ApplyResources(this.lblAzureStorageUploadPath, "lblAzureStorageUploadPath");
+ this.lblAzureStorageUploadPath.Name = "lblAzureStorageUploadPath";
+ //
// cbAzureStorageEnvironment
//
this.cbAzureStorageEnvironment.FormattingEnabled = true;
@@ -6082,6 +6106,9 @@ private void InitializeComponent()
private System.Windows.Forms.ListBox lbSharedFolderAccounts;
private System.Windows.Forms.Label lblGoogleCloudStoragePathPreviewLabel;
private System.Windows.Forms.Label lblGoogleCloudStoragePathPreview;
+ private System.Windows.Forms.TextBox txtAzureStorageUploadPath;
+ private System.Windows.Forms.Label lblAzureStorageUploadPath;
+ private System.Windows.Forms.CheckBox cbAzureStorageExcludeContainer;
private System.Windows.Forms.Label lblFirebaseDomain;
}
}
diff --git a/ShareX.UploadersLib/Forms/UploadersConfigForm.cs b/ShareX.UploadersLib/Forms/UploadersConfigForm.cs
index ee9aa3a08..7bed1acb7 100644
--- a/ShareX.UploadersLib/Forms/UploadersConfigForm.cs
+++ b/ShareX.UploadersLib/Forms/UploadersConfigForm.cs
@@ -667,6 +667,8 @@ public void LoadSettings()
txtAzureStorageContainer.Text = Config.AzureStorageContainer;
cbAzureStorageEnvironment.Text = Config.AzureStorageEnvironment;
txtAzureStorageCustomDomain.Text = Config.AzureStorageCustomDomain;
+ txtAzureStorageUploadPath.Text = Config.AzureStorageUploadPath;
+ cbAzureStorageExcludeContainer.Checked = Config.AzureStorageExcludeContainer;
#endregion Azure Storage
@@ -2870,6 +2872,16 @@ private void txtAzureStorageCustomDomain_TextChanged(object sender, EventArgs e)
Config.AzureStorageCustomDomain = txtAzureStorageCustomDomain.Text;
}
+ private void txtAzureStorageUploadPath_TextChanged(object sender, EventArgs e)
+ {
+ Config.AzureStorageUploadPath = txtAzureStorageUploadPath.Text;
+ }
+
+ private void cbAzureStorageExcludeContainer_CheckedChanged(object sender, EventArgs e)
+ {
+ Config.AzureStorageExcludeContainer = cbAzureStorageExcludeContainer.Checked;
+ }
+
private void btnAzureStoragePortal_Click(object sender, EventArgs e)
{
URLHelpers.OpenURL("https://portal.azure.com/?feature.customportal=false#blade/HubsExtension/Resources/resourceType/Microsoft.Storage%2FStorageAccounts");
diff --git a/ShareX.UploadersLib/Forms/UploadersConfigForm.resx b/ShareX.UploadersLib/Forms/UploadersConfigForm.resx
index d87827d03..592516ac3 100644
--- a/ShareX.UploadersLib/Forms/UploadersConfigForm.resx
+++ b/ShareX.UploadersLib/Forms/UploadersConfigForm.resx
@@ -3537,7 +3537,7 @@ store.book[0].title
3, 3, 3, 3
- 972, 537
+ 178, 42
7
@@ -7279,6 +7279,84 @@ store.book[0].title
7
+
+ True
+
+
+ NoControl
+
+
+ 16, 299
+
+
+ 230, 17
+
+
+ 13
+
+
+ Exclude container name from returned URL
+
+
+ cbAzureStorageExcludeContainer
+
+
+ System.Windows.Forms.CheckBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ tpAzureStorage
+
+
+ 0
+
+
+ 16, 223
+
+
+ 526, 20
+
+
+ 10
+
+
+ txtAzureStorageUploadPath
+
+
+ System.Windows.Forms.TextBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ tpAzureStorage
+
+
+ 1
+
+
+ NoControl
+
+
+ 13, 207
+
+
+ 100, 13
+
+
+ 9
+
+
+ Upload Path:
+
+
+ lblAzureStorageUploadPath
+
+
+ System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ tpAzureStorage
+
+
+ 2
+
blob.core.windows.net
@@ -7310,7 +7388,7 @@ store.book[0].title
tpAzureStorage
- 0
+ 3
True
@@ -7340,7 +7418,7 @@ store.book[0].title
tpAzureStorage
- 1
+ 4
NoControl
@@ -7352,7 +7430,7 @@ store.book[0].title
24, 24
- 6
+ 2
...
@@ -7367,7 +7445,7 @@ store.book[0].title
tpAzureStorage
- 2
+ 5
16, 128
@@ -7376,7 +7454,7 @@ store.book[0].title
526, 20
- 5
+ 6
txtAzureStorageContainer
@@ -7388,7 +7466,7 @@ store.book[0].title
tpAzureStorage
- 3
+ 6
True
@@ -7403,7 +7481,7 @@ store.book[0].title
55, 13
- 4
+ 5
Container:
@@ -7418,7 +7496,7 @@ store.book[0].title
tpAzureStorage
- 4
+ 7
16, 80
@@ -7427,7 +7505,7 @@ store.book[0].title
526, 20
- 3
+ 4
txtAzureStorageAccessKey
@@ -7439,7 +7517,7 @@ store.book[0].title
tpAzureStorage
- 5
+ 8
True
@@ -7457,7 +7535,7 @@ store.book[0].title
65, 13
- 2
+ 3
Access key:
@@ -7472,7 +7550,7 @@ store.book[0].title
tpAzureStorage
- 6
+ 9
16, 32
@@ -7493,7 +7571,7 @@ store.book[0].title
tpAzureStorage
- 7
+ 10
True
@@ -7526,16 +7604,16 @@ store.book[0].title
tpAzureStorage
- 8
+ 11
- 16, 222
+ 16, 273
526, 20
- 9
+ 12
txtAzureStorageCustomDomain
@@ -7547,19 +7625,19 @@ store.book[0].title
tpAzureStorage
- 9
+ 12
NoControl
- 13, 206
+ 13, 257
100, 13
- 10
+ 11
Custom Domain:
@@ -7574,10 +7652,10 @@ store.book[0].title
tpAzureStorage
- 10
+ 13
- 4, 202
+ 4, 40
3, 3, 3, 3
diff --git a/ShareX.UploadersLib/UploadersConfig.cs b/ShareX.UploadersLib/UploadersConfig.cs
index fc9404a42..ff36bbb22 100644
--- a/ShareX.UploadersLib/UploadersConfig.cs
+++ b/ShareX.UploadersLib/UploadersConfig.cs
@@ -372,6 +372,8 @@ public class UploadersConfig : SettingsBase
public string AzureStorageContainer = "";
public string AzureStorageEnvironment = "blob.core.windows.net";
public string AzureStorageCustomDomain = "";
+ public string AzureStorageUploadPath = "";
+ public bool AzureStorageExcludeContainer = false;
#endregion Azure Storage