public string GetUriPath(string filename, string subFolderPath = null) { if (string.IsNullOrEmpty(Host)) { return(""); } if (HttpHomePathNoExtension) { filename = Path.GetFileNameWithoutExtension(filename); } filename = URLHelpers.URLEncode(filename); if (subFolderPath == null) { subFolderPath = GetSubFolderPath(); } UriBuilder httpHomeUri; string httpHomePath = GetHttpHomePath(); if (string.IsNullOrEmpty(httpHomePath)) { string host = Host; if (host.StartsWith("ftp.")) { host = host.Substring(4); } httpHomeUri = new UriBuilder(URLHelpers.CombineURL(host, subFolderPath, filename)); httpHomeUri.Port = -1; //Since httpHomePath is not set, it's safe to erase UriBuilder's assumed port number } else { //Parse HttpHomePath in to host, port, path and query components int firstSlash = httpHomePath.IndexOf('/'); string httpHome = firstSlash >= 0 ? httpHomePath.Substring(0, firstSlash) : httpHomePath; int portSpecifiedAt = httpHome.LastIndexOf(':'); string httpHomeHost = portSpecifiedAt >= 0 ? httpHome.Substring(0, portSpecifiedAt) : httpHome; int httpHomePort = -1; string httpHomePathAndQuery = firstSlash >= 0 ? httpHomePath.Substring(firstSlash + 1) : ""; int querySpecifiedAt = httpHomePathAndQuery.LastIndexOf('?'); string httpHomeDir = querySpecifiedAt >= 0 ? httpHomePathAndQuery.Substring(0, querySpecifiedAt) : httpHomePathAndQuery; string httpHomeQuery = querySpecifiedAt >= 0 ? httpHomePathAndQuery.Substring(querySpecifiedAt + 1) : ""; if (portSpecifiedAt >= 0) { int.TryParse(httpHome.Substring(portSpecifiedAt + 1), out httpHomePort); } //Build URI httpHomeUri = new UriBuilder { Host = httpHomeHost, Path = httpHomeDir, Query = httpHomeQuery }; if (portSpecifiedAt >= 0) { httpHomeUri.Port = httpHomePort; } if (httpHomeUri.Query.EndsWith("=")) { //Setting URIBuilder.Query automatically prepends a ? so we must trim it first. if (HttpHomePathAutoAddSubFolderPath) { httpHomeUri.Query = URLHelpers.CombineURL(httpHomeUri.Query.Substring(1), subFolderPath, filename); } else { httpHomeUri.Query = httpHomeUri.Query.Substring(1) + filename; } } else { if (HttpHomePathAutoAddSubFolderPath) { httpHomeUri.Path = URLHelpers.CombineURL(httpHomeUri.Path, subFolderPath); } httpHomeUri.Path = URLHelpers.CombineURL(httpHomeUri.Path, filename); } } httpHomeUri.Scheme = BrowserProtocol.GetDescription(); return(httpHomeUri.Uri.AbsoluteUri); }
private static string NormalizeParameters(Dictionary <string, string> parameters) { return(string.Join("&", parameters.OrderBy(x => x.Key).ThenBy(x => x.Value).Select(x => x.Key + "=" + URLHelpers.URLEncode(x.Value)).ToArray())); }
public static string GenerateQuery(string url, Dictionary <string, string> args, HttpMethod httpMethod, OAuthInfo oauth) { if (string.IsNullOrEmpty(oauth.ConsumerKey) || (string.IsNullOrEmpty(oauth.ConsumerSecret) && oauth.SignatureMethod == OAuthInfo.OAuthInfoSignatureMethod.HMAC_SHA1) || (oauth.ConsumerPrivateKey == null && oauth.SignatureMethod == OAuthInfo.OAuthInfoSignatureMethod.RSA_SHA1)) { throw new Exception("ConsumerKey or ConsumerSecret or ConsumerPrivateKey empty."); } Dictionary <string, string> parameters = new Dictionary <string, string>(); parameters.Add(ParameterVersion, oauth.OAuthVersion); parameters.Add(ParameterNonce, GenerateNonce()); parameters.Add(ParameterTimestamp, GenerateTimestamp()); parameters.Add(ParameterConsumerKey, oauth.ConsumerKey); switch (oauth.SignatureMethod) { case OAuthInfo.OAuthInfoSignatureMethod.HMAC_SHA1: parameters.Add(ParameterSignatureMethod, HMACSHA1SignatureType); break; case OAuthInfo.OAuthInfoSignatureMethod.RSA_SHA1: parameters.Add(ParameterSignatureMethod, RSASHA1SignatureType); break; default: throw new NotImplementedException("Unsupported signature method"); } string secret = null; if (!string.IsNullOrEmpty(oauth.UserToken) && !string.IsNullOrEmpty(oauth.UserSecret)) { secret = oauth.UserSecret; parameters.Add(ParameterToken, oauth.UserToken); } else if (!string.IsNullOrEmpty(oauth.AuthToken) && !string.IsNullOrEmpty(oauth.AuthSecret)) { secret = oauth.AuthSecret; parameters.Add(ParameterToken, oauth.AuthToken); if (!string.IsNullOrEmpty(oauth.AuthVerifier)) { parameters.Add(ParameterVerifier, oauth.AuthVerifier); } } if (args != null) { foreach (KeyValuePair <string, string> arg in args) { parameters[arg.Key] = arg.Value; } } string normalizedUrl = NormalizeUrl(url); string normalizedParameters = NormalizeParameters(parameters); string signatureBase = GenerateSignatureBase(httpMethod, normalizedUrl, normalizedParameters); byte[] signatureData; switch (oauth.SignatureMethod) { case OAuthInfo.OAuthInfoSignatureMethod.HMAC_SHA1: signatureData = GenerateSignature(signatureBase, oauth.ConsumerSecret, secret); break; case OAuthInfo.OAuthInfoSignatureMethod.RSA_SHA1: signatureData = GenerateSignatureRSASHA1(signatureBase, oauth.ConsumerPrivateKey); break; default: throw new NotImplementedException("Unsupported signature method"); } string signature = URLHelpers.URLEncode(Convert.ToBase64String(signatureData)); return(string.Format("{0}?{1}&{2}={3}", normalizedUrl, normalizedParameters, ParameterSignature, signature)); }
public override UploadResult Upload(Stream stream, string fileName) { string parsedUploadPath = NameParser.Parse(NameParserType.FilePath, UploadPath); string destinationPath = URLHelpers.CombineURL(parsedUploadPath, fileName); // docs: https://www.backblaze.com/b2/docs/ // STEP 1: authorize, get auth token, api url, download url DebugHelper.WriteLine($"B2 uploader: Attempting to authorize as '{ApplicationKeyId}'."); B2Authorization auth = B2ApiAuthorize(ApplicationKeyId, ApplicationKey, out string authError); if (authError != null) { DebugHelper.WriteLine("B2 uploader: Failed to authorize."); Errors.Add($"Could not authenticate with B2: {authError}"); return(null); } DebugHelper.WriteLine($"B2 uploader: Authorized, using API server {auth.apiUrl}, download URL {auth.downloadUrl}"); // STEP 1.25: if we have an application key, there will be a bucketId present here, but if // not, we have an account key and need to find our bucket id ourselves string bucketId = auth.allowed?.bucketId; if (bucketId == null) { DebugHelper.WriteLine("B2 uploader: Key doesn't have a bucket ID set, so I'm looking for a bucket ID."); string newBucketId = B2ApiGetBucketId(auth, BucketName, out string getBucketError); if (getBucketError != null) { DebugHelper.WriteLine($"B2 uploader: It's {newBucketId}."); bucketId = newBucketId; } } // STEP 1.5: verify whether we can write to the bucket user wants to write to, with the given prefix DebugHelper.WriteLine("B2 uploader: Checking clientside whether we have permission to upload."); bool authCheckOk = IsAuthorizedForUpload(auth, bucketId, destinationPath, out string authCheckError); if (!authCheckOk) { DebugHelper.WriteLine("B2 uploader: Key is not suitable for this upload."); Errors.Add($"B2 upload failed: {authCheckError}"); return(null); } // STEP 1.75: start upload attempt loop const int maxTries = 5; B2UploadUrl url = null; for (int tries = 1; tries <= maxTries; tries++) { string newOrSameUrl = url == null ? "New URL." : "Same URL."; DebugHelper.WriteLine($"B2 uploader: Upload attempt {tries} of {maxTries}. {newOrSameUrl}"); // sloppy, but we need exponential backoff somehow and we are not in async code // since B2Uploader should have the thread to itself, and this just occurs on rare failures, // this should be OK if (tries > 1) { int delay = (int)Math.Pow(2, tries - 1) * 1000; DebugHelper.WriteLine($"Waiting ${delay} ms for backoff."); Thread.Sleep(delay); } // STEP 2: get upload url that we need to POST to in step 3 if (url == null) { DebugHelper.WriteLine("B2 uploader: Getting new upload URL."); url = B2ApiGetUploadUrl(auth, bucketId, out string getUrlError); if (getUrlError != null) { // this is guaranteed to be unrecoverable, so bail out DebugHelper.WriteLine("B2 uploader: Got error trying to get upload URL."); Errors.Add("Could not get B2 upload URL: " + getUrlError); return(null); } } // STEP 3: upload file and see if anything went wrong DebugHelper.WriteLine($"B2 uploader: Uploading to URL {url.uploadUrl}"); B2UploadResult uploadResult = B2ApiUploadFile(url, destinationPath, stream); HashSet <string> expiredTokenCodes = new HashSet <string>(new List <string> { "expired_auth_token", "bad_auth_token" }); if (uploadResult.RC == -1) { // magic number for "connection failed", should also happen when upload // caps are exceeded DebugHelper.WriteLine("B2 uploader: Connection failed, trying with new URL."); url = null; continue; } else if (uploadResult.RC == 401 && expiredTokenCodes.Contains(uploadResult.Error.code)) { // Unauthorized, our token expired DebugHelper.WriteLine("B2 uploader: Upload auth token expired, trying with new URL."); url = null; continue; } else if (uploadResult.RC == 408) { DebugHelper.WriteLine("B2 uploader: Request Timeout, trying with same URL."); continue; } else if (uploadResult.RC == 429) { DebugHelper.WriteLine("B2 uploader: Too Many Requests, trying with same URL."); continue; } else if (uploadResult.RC == 503) { DebugHelper.WriteLine("B2 uploader: Service Unavailable, trying with new URL."); url = null; continue; } else if (uploadResult.RC != 200) { // something else happened that wasn't a success, so bail out DebugHelper.WriteLine("B2 uploader: Unknown error, upload failure."); Errors.Add("B2 uploader: Unknown error occurred while calling b2_upload_file()."); return(null); } // success! // STEP 4: compose: // the download url (e.g. "https://f567.backblazeb2.com") // /file/$bucket/$uploadPath // or // $customUrl/$uploadPath string encodedFileName = URLHelpers.URLEncode(uploadResult.Upload.fileName, true); string remoteLocation = URLHelpers.CombineURL(auth.downloadUrl, "file", URLHelpers.URLEncode(BucketName), encodedFileName); DebugHelper.WriteLine($"B2 uploader: Successful upload! File should be at: {remoteLocation}"); if (UseCustomUrl) { remoteLocation = URLHelpers.CombineURL(CustomUrl, encodedFileName); remoteLocation = URLHelpers.FixPrefix(remoteLocation, "https://"); DebugHelper.WriteLine($"B2 uploader: But user requested custom URL, which will be: {remoteLocation}"); } return(new UploadResult() { IsSuccess = true, URL = remoteLocation }); } DebugHelper.WriteLine("B2 uploader: Ran out of attempts, aborting."); Errors.Add($"B2 upload failed: Could not upload file after {maxTries} attempts."); return(null); }
private void B2UpdateCustomDomainPreview() { string uploadPath = NameParser.Parse(NameParserType.FolderPath, Config.B2UploadPath); string url; if (cbB2CustomUrl.Checked) { string customUrl = NameParser.Parse(NameParserType.FolderPath, Config.B2CustomUrl); url = URLHelpers.CombineURL(customUrl, uploadPath, "example.png"); url = URLHelpers.FixPrefix(url, "https://"); } else { string bucket = string.IsNullOrEmpty(Config.B2BucketName) ? "[bucket]" : URLHelpers.URLEncode(Config.B2BucketName); url = URLHelpers.CombineURL("https://f001.backblazeb2.com/file", bucket, uploadPath, "example.png"); } lblB2UrlPreview.Text = url; }
public override UploadResult Upload(Stream stream, string fileName) { bool isPathStyleRequest = Settings.UsePathStyle; if (!isPathStyleRequest && Settings.Bucket.Contains(".")) { isPathStyleRequest = true; } string endpoint = URLHelpers.RemovePrefixes(Settings.Endpoint); string host = isPathStyleRequest ? endpoint : $"{Settings.Bucket}.{endpoint}"; string algorithm = "AWS4-HMAC-SHA256"; string credentialDate = DateTime.UtcNow.ToString("yyyyMMdd", CultureInfo.InvariantCulture); string region = GetRegion(); string scope = URLHelpers.CombineURL(credentialDate, region, "s3", "aws4_request"); string credential = URLHelpers.CombineURL(Settings.AccessKeyID, scope); string timeStamp = DateTime.UtcNow.ToString("yyyyMMddTHHmmssZ", CultureInfo.InvariantCulture); string contentType = UploadHelpers.GetMimeType(fileName); string hashedPayload; if (Settings.SignedPayload) { hashedPayload = Helpers.BytesToHex(Helpers.ComputeSHA256(stream)); } else { hashedPayload = "UNSIGNED-PAYLOAD"; } if ((Settings.RemoveExtensionImage && Helpers.IsImageFile(fileName)) || (Settings.RemoveExtensionText && Helpers.IsTextFile(fileName)) || (Settings.RemoveExtensionVideo && Helpers.IsVideoFile(fileName))) { fileName = Path.GetFileNameWithoutExtension(fileName); } string uploadPath = GetUploadPath(fileName); NameValueCollection headers = new NameValueCollection { ["Host"] = host, ["Content-Length"] = stream.Length.ToString(), ["Content-Type"] = contentType, ["x-amz-date"] = timeStamp, ["x-amz-content-sha256"] = hashedPayload, ["x-amz-storage-class"] = Settings.StorageClass.ToString() }; if (Settings.SetPublicACL) { headers["x-amz-acl"] = "public-read"; } string canonicalURI = uploadPath; if (isPathStyleRequest) { canonicalURI = URLHelpers.CombineURL(Settings.Bucket, canonicalURI); } canonicalURI = URLHelpers.AddSlash(canonicalURI, SlashType.Prefix); canonicalURI = URLHelpers.URLEncode(canonicalURI, true); string canonicalQueryString = ""; string canonicalHeaders = CreateCanonicalHeaders(headers); string signedHeaders = GetSignedHeaders(headers); string canonicalRequest = "PUT" + "\n" + canonicalURI + "\n" + canonicalQueryString + "\n" + canonicalHeaders + "\n" + signedHeaders + "\n" + hashedPayload; string stringToSign = algorithm + "\n" + timeStamp + "\n" + scope + "\n" + Helpers.BytesToHex(Helpers.ComputeSHA256(canonicalRequest)); byte[] dateKey = Helpers.ComputeHMACSHA256(credentialDate, "AWS4" + Settings.SecretAccessKey); byte[] dateRegionKey = Helpers.ComputeHMACSHA256(region, dateKey); byte[] dateRegionServiceKey = Helpers.ComputeHMACSHA256("s3", dateRegionKey); byte[] signingKey = Helpers.ComputeHMACSHA256("aws4_request", dateRegionServiceKey); string signature = Helpers.BytesToHex(Helpers.ComputeHMACSHA256(stringToSign, signingKey)); headers["Authorization"] = algorithm + " " + "Credential=" + credential + "," + "SignedHeaders=" + signedHeaders + "," + "Signature=" + signature; headers.Remove("Host"); headers.Remove("Content-Type"); string url = URLHelpers.CombineURL(host, canonicalURI); url = URLHelpers.ForcePrefix(url, "https://"); using (HttpWebResponse response = GetResponse(HttpMethod.PUT, url, stream, contentType, null, headers)) { if (response != null) { NameValueCollection responseHeaders = response.Headers; if (responseHeaders != null && responseHeaders["ETag"] != null) { return(new UploadResult { IsSuccess = true, URL = GenerateURL(uploadPath) }); } } } Errors.Add("Upload to Amazon S3 failed."); return(null); }
public override UploadResult Upload(Stream stream, string fileName) { if (string.IsNullOrEmpty(Host)) { throw new Exception("ownCloud Host is empty."); } if (string.IsNullOrEmpty(Username) || string.IsNullOrEmpty(Password)) { throw new Exception("ownCloud Username or Password is empty."); } if (string.IsNullOrEmpty(Path)) { Path = "/"; } // Original, unencoded path. Necessary for shared files string path = URLHelpers.CombineURL(Path, fileName); // Encoded path, necessary when sent in the URL string encodedPath = URLHelpers.CombineURL(Path, URLHelpers.URLEncode(fileName)); string url = URLHelpers.CombineURL(Host, "remote.php/webdav", encodedPath); url = URLHelpers.FixPrefix(url); NameValueCollection headers = CreateAuthenticationHeader(Username, Password); SSLBypassHelper sslBypassHelper = null; try { if (IgnoreInvalidCert) { sslBypassHelper = new SSLBypassHelper(); } string response = SendRequestStream(url, stream, Helpers.GetMimeType(fileName), headers, method: HttpMethod.PUT); UploadResult result = new UploadResult(response); if (!IsError) { if (CreateShare) { AllowReportProgress = false; result.URL = ShareFile(path); } else { result.IsURLExpected = false; } } return(result); } finally { if (sslBypassHelper != null) { sslBypassHelper.Dispose(); } } }
public string GetUriPath(string filename, string subFolderPath = null) { if (string.IsNullOrEmpty(Host)) { return(string.Empty); } if (HttpHomePathNoExtension) { filename = Path.GetFileNameWithoutExtension(filename); } filename = URLHelpers.URLEncode(filename); if (subFolderPath == null) { subFolderPath = GetSubFolderPath(); } subFolderPath = URLHelpers.URLPathEncode(subFolderPath); UriBuilder httpHomeUri; var httpHomePath = GetHttpHomePath(); if (string.IsNullOrEmpty(httpHomePath)) { var host = Host; if (host.StartsWith("ftp.")) { host = host.Substring(4); } httpHomeUri = new UriBuilder(URLHelpers.CombineURL(host, subFolderPath, filename)); } else { //Parse HttpHomePath in to host, port and path components var firstSlash = httpHomePath.IndexOf('/'); var httpHome = firstSlash >= 0 ? httpHomePath.Substring(0, firstSlash) : httpHomePath; var portSpecifiedAt = httpHome.LastIndexOf(':'); var httpHomeHost = portSpecifiedAt >= 0 ? httpHome.Substring(0, portSpecifiedAt) : httpHome; var httpHomePort = -1; var httpHomeDir = httpHomePath.Substring(firstSlash + 1); if (portSpecifiedAt >= 0) { int.TryParse(httpHome.Substring(portSpecifiedAt + 1), out httpHomePort); } //Build URI httpHomeUri = new UriBuilder { Host = httpHomeHost, Path = httpHomeDir }; if (portSpecifiedAt >= 0) { httpHomeUri.Port = httpHomePort; } if (HttpHomePathAutoAddSubFolderPath) { httpHomeUri.Path = URLHelpers.CombineURL(httpHomeUri.Path, subFolderPath); } if (httpHomeUri.Query.EndsWith("=")) { httpHomeUri.Query += filename; } else { httpHomeUri.Path = URLHelpers.CombineURL(httpHomeUri.Path, filename); } } httpHomeUri.Scheme = BrowserProtocol.GetDescription(); return(httpHomeUri.Uri.ToString()); }
public void ShareURL(string url) { if (!string.IsNullOrEmpty(url)) { string encodedUrl = URLHelpers.URLEncode(url); switch (Info.TaskSettings.URLSharingServiceDestination) { case URLSharingServices.Email: if (Program.UploadersConfig.IsValid(URLSharingServices.Email)) { using (EmailForm emailForm = new EmailForm(Program.UploadersConfig.EmailRememberLastTo ? Program.UploadersConfig.EmailLastTo : string.Empty, Program.UploadersConfig.EmailDefaultSubject, url)) { if (emailForm.ShowDialog() == DialogResult.OK) { if (Program.UploadersConfig.EmailRememberLastTo) { Program.UploadersConfig.EmailLastTo = emailForm.ToEmail; } Email email = new Email { SmtpServer = Program.UploadersConfig.EmailSmtpServer, SmtpPort = Program.UploadersConfig.EmailSmtpPort, FromEmail = Program.UploadersConfig.EmailFrom, Password = Program.UploadersConfig.EmailPassword }; email.Send(emailForm.ToEmail, emailForm.Subject, emailForm.Body); } } } else { URLHelpers.OpenURL("mailto:?body=" + encodedUrl); } break; case URLSharingServices.Twitter: if (Program.UploadersConfig.IsValid(URLSharingServices.Twitter)) { OAuthInfo twitterOAuth = Program.UploadersConfig.TwitterOAuthInfoList[Program.UploadersConfig.TwitterSelectedAccount]; using (TwitterTweetForm twitter = new TwitterTweetForm(twitterOAuth, url)) { twitter.ShowDialog(); } } else { URLHelpers.OpenURL("https://twitter.com/intent/tweet?text=" + encodedUrl); } break; case URLSharingServices.Facebook: URLHelpers.OpenURL("https://www.facebook.com/sharer/sharer.php?u=" + encodedUrl); break; case URLSharingServices.GooglePlus: URLHelpers.OpenURL("https://plus.google.com/share?url=" + encodedUrl); break; case URLSharingServices.Reddit: URLHelpers.OpenURL("http://www.reddit.com/submit?url=" + encodedUrl); break; case URLSharingServices.Pinterest: URLHelpers.OpenURL(string.Format("http://pinterest.com/pin/create/button/?url={0}&media={0}", encodedUrl)); break; case URLSharingServices.Tumblr: URLHelpers.OpenURL("https://www.tumblr.com/share?v=3&u=" + encodedUrl); break; case URLSharingServices.LinkedIn: URLHelpers.OpenURL("https://www.linkedin.com/shareArticle?url=" + encodedUrl); break; case URLSharingServices.StumbleUpon: URLHelpers.OpenURL("http://www.stumbleupon.com/submit?url=" + encodedUrl); break; case URLSharingServices.Delicious: URLHelpers.OpenURL("https://delicious.com/save?v=5&url=" + encodedUrl); break; case URLSharingServices.VK: URLHelpers.OpenURL("http://vk.com/share.php?url=" + encodedUrl); break; } } }
public string GetAuthorizationURL() { return(string.Format("https://accounts.google.com/o/oauth2/auth?response_type={0}&client_id={1}&redirect_uri={2}&scope={3}", "code", AuthInfo.Client_ID, "urn:ietf:wg:oauth:2.0:oob", URLHelpers.URLEncode("https://picasaweb.google.com/data"))); }
public override UploadResult Upload(Stream stream, string fileName) { bool isPathStyleRequest = Settings.UsePathStyle; if (!isPathStyleRequest && Settings.Bucket.Contains(".")) { isPathStyleRequest = true; } string endpoint = URLHelpers.RemovePrefixes(Settings.Endpoint); string host = isPathStyleRequest ? endpoint : $"{Settings.Bucket}.{endpoint}"; string algorithm = "AWS4-HMAC-SHA256"; string credentialDate = DateTime.UtcNow.ToString("yyyyMMdd", CultureInfo.InvariantCulture); string region = GetRegion(); string scope = URLHelpers.CombineURL(credentialDate, region, "s3", "aws4_request"); string credential = URLHelpers.CombineURL(Settings.AccessKeyID, scope); string timeStamp = DateTime.UtcNow.ToString("yyyyMMddTHHmmssZ", CultureInfo.InvariantCulture); string contentType = RequestHelpers.GetMimeType(fileName); string hashedPayload; if (Settings.SignedPayload) { hashedPayload = Helpers.BytesToHex(Helpers.ComputeSHA256(stream)); } else { hashedPayload = "UNSIGNED-PAYLOAD"; } string uploadPath = GetUploadPath(fileName); string resultURL = GenerateURL(uploadPath); OnEarlyURLCopyRequested(resultURL); NameValueCollection headers = new NameValueCollection { ["Host"] = host, ["Content-Length"] = stream.Length.ToString(), ["Content-Type"] = contentType, ["x-amz-date"] = timeStamp, ["x-amz-content-sha256"] = hashedPayload, // If you don't specify, S3 Standard is the default storage class. Amazon S3 supports other storage classes. // Valid Values: STANDARD | REDUCED_REDUNDANCY | STANDARD_IA | ONEZONE_IA | INTELLIGENT_TIERING | GLACIER | DEEP_ARCHIVE // https://docs.aws.amazon.com/AmazonS3/latest/API/API_PutObject.html ["x-amz-storage-class"] = Settings.StorageClass.ToString() }; if (Settings.SetPublicACL) { // The canned ACL to apply to the object. For more information, see Canned ACL. // https://docs.aws.amazon.com/AmazonS3/latest/dev/acl-overview.html#canned-acl headers["x-amz-acl"] = "public-read"; } string canonicalURI = uploadPath; if (isPathStyleRequest) { canonicalURI = URLHelpers.CombineURL(Settings.Bucket, canonicalURI); } canonicalURI = URLHelpers.AddSlash(canonicalURI, SlashType.Prefix); canonicalURI = URLHelpers.URLEncode(canonicalURI, true); string canonicalQueryString = ""; string canonicalHeaders = CreateCanonicalHeaders(headers); string signedHeaders = GetSignedHeaders(headers); string canonicalRequest = "PUT" + "\n" + canonicalURI + "\n" + canonicalQueryString + "\n" + canonicalHeaders + "\n" + signedHeaders + "\n" + hashedPayload; string stringToSign = algorithm + "\n" + timeStamp + "\n" + scope + "\n" + Helpers.BytesToHex(Helpers.ComputeSHA256(canonicalRequest)); byte[] dateKey = Helpers.ComputeHMACSHA256(credentialDate, "AWS4" + Settings.SecretAccessKey); byte[] dateRegionKey = Helpers.ComputeHMACSHA256(region, dateKey); byte[] dateRegionServiceKey = Helpers.ComputeHMACSHA256("s3", dateRegionKey); byte[] signingKey = Helpers.ComputeHMACSHA256("aws4_request", dateRegionServiceKey); string signature = Helpers.BytesToHex(Helpers.ComputeHMACSHA256(stringToSign, signingKey)); headers["Authorization"] = algorithm + " " + "Credential=" + credential + "," + "SignedHeaders=" + signedHeaders + "," + "Signature=" + signature; headers.Remove("Host"); headers.Remove("Content-Type"); string url = URLHelpers.CombineURL(host, canonicalURI); url = URLHelpers.ForcePrefix(url, "https://"); SendRequest(HttpMethod.PUT, url, stream, contentType, null, headers); if (LastResponseInfo != null && LastResponseInfo.IsSuccess) { return(new UploadResult { IsSuccess = true, URL = resultURL }); } Errors.Add("Upload to Amazon S3 failed."); return(null); }
public override void ShareURL(string url, UploadersConfig config) { string encodedUrl = URLHelpers.URLEncode(url); URLHelpers.OpenURL(string.Format(UrlFormatString, encodedUrl)); }