public void ForceHTTPS() { URL = URLHelpers.ForcePrefix(URL); ThumbnailURL = URLHelpers.ForcePrefix(ThumbnailURL); DeletionURL = URLHelpers.ForcePrefix(DeletionURL); ShortenedURL = URLHelpers.ForcePrefix(ShortenedURL); }
public override UploadResult Upload(Stream stream, string fileName) { if (string.IsNullOrEmpty(AzureStorageAccountName)) { Errors.Add("'Account Name' must not be empty"); } if (string.IsNullOrEmpty(AzureStorageAccountAccessKey)) { Errors.Add("'Access key' must not be empty"); } if (string.IsNullOrEmpty(AzureStorageContainer)) { Errors.Add("'Container' must not be empty"); } if (IsError) { return(null); } CreateContainerIfNotExists(); string date = DateTime.UtcNow.ToString("R", CultureInfo.InvariantCulture); string url = $"https://{AzureStorageAccountName}.{AzureStorageEnvironment}/{AzureStorageContainer}/{fileName}"; string urlForCopy = url; if (!string.IsNullOrEmpty(AzureStorageCustomDomain)) { // Azure Blob Storage does not support https with custom domains at this time urlForCopy = URLHelpers.ForcePrefix(URLHelpers.CombineURL(AzureStorageCustomDomain, AzureStorageContainer, fileName), "http://"); } string contentType = Helpers.GetMimeType(fileName); NameValueCollection requestHeaders = new NameValueCollection(); requestHeaders["x-ms-date"] = date; requestHeaders["x-ms-version"] = APIVersion; 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 stringToSign = GenerateStringToSign(canonicalizedHeaders, canonicalizedResource, stream.Length.ToString(), contentType); requestHeaders["Authorization"] = $"SharedKey {AzureStorageAccountName}:{stringToSign}"; NameValueCollection responseHeaders = SendRequestGetHeaders(HttpMethod.PUT, url, stream, contentType, null, requestHeaders, null); if (responseHeaders != null) { return(new UploadResult { IsSuccess = true, URL = urlForCopy }); } else { Errors.Add("Upload failed."); return(null); } }
private void TranscodeFile(UploadResult result) { StreamableTranscodeResponse transcodeResponse = JsonConvert.DeserializeObject <StreamableTranscodeResponse>(result.Response); if (!string.IsNullOrEmpty(transcodeResponse.Shortcode)) { ProgressManager progress = new ProgressManager(100); OnProgressChanged(progress); while (!StopUploadRequested) { string statusJson = SendRequest(HttpMethod.GET, URLHelpers.CombineURL(Host, "videos", transcodeResponse.Shortcode)); StreamableStatusResponse response = JsonConvert.DeserializeObject <StreamableStatusResponse>(statusJson); if (response.status > 2) { Errors.Add(response.message); result.IsSuccess = false; break; } else if (response.status == 2) { progress.UpdateProgress(100 - progress.Position); OnProgressChanged(progress); result.IsSuccess = true; if (UseDirectURL && response.files != null && response.files.mp4 != null && !string.IsNullOrEmpty(response.files.mp4.url)) { result.URL = URLHelpers.ForcePrefix(response.files.mp4.url); } else { result.URL = URLHelpers.ForcePrefix(response.url); } break; } progress.UpdateProgress(response.percent - progress.Position); OnProgressChanged(progress); Thread.Sleep(1000); } } else { Errors.Add("Could not create video"); result.IsSuccess = false; } }
public override UploadResult ShortenURL(string url) { UploadResult result = new UploadResult { URL = url }; string RequestUrl = "https://firebasedynamiclinks.googleapis.com/v1/shortLinks"; string longDynamicLink = URLHelpers.ForcePrefix(DynamicLinkDomain + ".app.goo.gl/?link=" + HttpUtility.UrlEncode(url)); string option; Dictionary <string, string> args = new Dictionary <string, string> { { "key", WebAPIKey } }; if (IsShort) { option = "SHORT"; } else { option = "UNGUESSABLE"; } FirebaseRequest request = new FirebaseRequest { longDynamicLink = longDynamicLink, suffix = new FirebaseRequestSuffix { option = option } }; string json = JsonConvert.SerializeObject(request); result.Response = SendRequest(HttpMethod.POST, RequestUrl, json, ContentTypeJSON, args); result.ShortenedURL = JsonConvert.DeserializeObject <FirebaseResponse>(result.Response).shortLink; return(result); }
public override UploadResult Upload(Stream stream, string fileName) { bool forcePathStyle = Settings.UsePathStyle; if (!forcePathStyle && Settings.Bucket.Contains(".")) { forcePathStyle = true; } string endpoint = URLHelpers.RemovePrefixes(Settings.Endpoint); string host = forcePathStyle ? 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 longDate = DateTime.UtcNow.ToString("yyyyMMddTHHmmssZ", CultureInfo.InvariantCulture); string expiresTotalSeconds = ((long)TimeSpan.FromHours(1).TotalSeconds).ToString(); string contentType = Helpers.GetMimeType(fileName); NameValueCollection headers = new NameValueCollection(); headers["content-type"] = contentType; headers["host"] = host; if (Settings.SetPublicACL) { headers["x-amz-acl"] = "public-read"; } headers["x-amz-storage-class"] = Settings.StorageClass.ToString(); string signedHeaders = GetSignedHeaders(headers); Dictionary <string, string> args = new Dictionary <string, string>(); args.Add("X-Amz-Algorithm", algorithm); args.Add("X-Amz-Credential", credential); args.Add("X-Amz-Date", longDate); args.Add("X-Amz-Expires", expiresTotalSeconds); args.Add("X-Amz-SignedHeaders", signedHeaders); string uploadPath = GetUploadPath(fileName); string canonicalURI = uploadPath; if (forcePathStyle) { canonicalURI = URLHelpers.CombineURL(Settings.Bucket, canonicalURI); } canonicalURI = URLHelpers.AddSlash(canonicalURI, SlashType.Prefix); canonicalURI = URLHelpers.URLPathEncode(canonicalURI); string canonicalQueryString = URLHelpers.CreateQuery(args, true); string canonicalHeaders = CreateCanonicalHeaders(headers); string canonicalRequest = "PUT" + "\n" + canonicalURI + "\n" + canonicalQueryString + "\n" + canonicalHeaders + "\n" + signedHeaders + "\n" + "UNSIGNED-PAYLOAD"; string stringToSign = algorithm + "\n" + longDate + "\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)); args.Add("X-Amz-Signature", signature); headers.Remove("content-type"); headers.Remove("host"); string url = URLHelpers.CombineURL(host, canonicalURI); url = URLHelpers.CreateQuery(url, args, true); url = URLHelpers.ForcePrefix(url, "https://"); NameValueCollection responseHeaders = SendRequestGetHeaders(HttpMethod.PUT, url, stream, contentType, null, headers); if (responseHeaders == null || responseHeaders.Count == 0) { Errors.Add("Upload to Amazon S3 failed. Check your access credentials."); return(null); } if (responseHeaders["ETag"] == null) { Errors.Add("Upload to Amazon S3 failed."); return(null); } return(new UploadResult { IsSuccess = true, URL = GenerateURL(uploadPath) }); }
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 = Helpers.GetMimeType(fileName); string uploadPath = GetUploadPath(fileName); string hashedPayload = "UNSIGNED-PAYLOAD"; NameValueCollection headers = new NameValueCollection(); headers["host"] = host; headers["content-type"] = contentType; headers["x-amz-date"] = timeStamp; headers["x-amz-content-sha256"] = hashedPayload; headers["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.URLPathEncode(canonicalURI); 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://"); NameValueCollection responseHeaders = SendRequestGetHeaders(HttpMethod.PUT, url, stream, contentType, null, headers); if (responseHeaders == null || responseHeaders.Count == 0 || responseHeaders["ETag"] == null) { Errors.Add("Upload to Amazon S3 failed."); return(null); } return(new UploadResult { IsSuccess = true, URL = GenerateURL(uploadPath) }); }
public override UploadResult Upload(Stream stream, string fileName) { if (string.IsNullOrEmpty(s3Settings.AccessKeyID)) { Errors.Add("'Access Key' must not be empty."); } if (string.IsNullOrEmpty(s3Settings.SecretAccessKey)) { Errors.Add("'Secret Access Key' must not be empty."); } if (string.IsNullOrEmpty(s3Settings.Bucket)) { Errors.Add("'Bucket' must not be empty."); } if (GetCurrentRegion(s3Settings) == UnknownEndpoint) { Errors.Add("Please select an endpoint."); } if (IsError) { return(null); } AmazonS3Region region = GetCurrentRegion(s3Settings); AmazonS3Config s3ClientConfig = new AmazonS3Config(); if (region.AmazonRegion == null) { s3ClientConfig.ServiceURL = URLHelpers.ForcePrefix(region.Hostname); } else { s3ClientConfig.RegionEndpoint = region.AmazonRegion; } using (AmazonS3Client client = new AmazonS3Client(GetCurrentCredentials(), s3ClientConfig)) { GetPreSignedUrlRequest putRequest = new GetPreSignedUrlRequest { BucketName = s3Settings.Bucket, Key = GetObjectKey(fileName), Verb = HttpVerb.PUT, Expires = DateTime.UtcNow.AddMinutes(5), ContentType = Helpers.GetMimeType(fileName) }; NameValueCollection requestHeaders = new NameValueCollection(); requestHeaders["x-amz-acl"] = "public-read"; requestHeaders["x-amz-storage-class"] = GetObjectStorageClass(); putRequest.Headers["x-amz-acl"] = "public-read"; putRequest.Headers["x-amz-storage-class"] = GetObjectStorageClass(); NameValueCollection responseHeaders = SendRequestStreamGetHeaders(client.GetPreSignedURL(putRequest), stream, Helpers.GetMimeType(fileName), requestHeaders, method: HttpMethod.PUT); if (responseHeaders.Count == 0) { Errors.Add("Upload to Amazon S3 failed. Check your access credentials."); return(null); } string eTag = responseHeaders.Get("ETag"); if (eTag == null) { Errors.Add("Upload to Amazon S3 failed."); return(null); } if (GetMd5Hash(stream) == eTag.Replace("\"", "")) { return(new UploadResult { IsSuccess = true, URL = GetObjectURL(putRequest.Key) }); } Errors.Add("Upload to Amazon S3 failed, uploaded data did not match."); return(null); } }
private string GetEndpoint() { return(URLHelpers.ForcePrefix(URLHelpers.CombineURL(GetCurrentRegion(s3Settings).Hostname, s3Settings.Bucket))); }
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); }
private void DoAfterUploadJobs() { try { if (Info.TaskSettings.AdvancedSettings.ResultForceHTTPS) { Info.Result.URL = URLHelpers.ForcePrefix(Info.Result.URL); Info.Result.ThumbnailURL = URLHelpers.ForcePrefix(Info.Result.ThumbnailURL); Info.Result.DeletionURL = URLHelpers.ForcePrefix(Info.Result.DeletionURL); } if (Info.Job != TaskJob.ShareURL && (Info.TaskSettings.AfterUploadJob.HasFlag(AfterUploadTasks.UseURLShortener) || Info.Job == TaskJob.ShortenURL || (Info.TaskSettings.AdvancedSettings.AutoShortenURLLength > 0 && Info.Result.URL.Length > Info.TaskSettings.AdvancedSettings.AutoShortenURLLength))) { UploadResult result = ShortenURL(Info.Result.URL); if (result != null) { Info.Result.ShortenedURL = result.ShortenedURL; Info.Result.Errors.AddRange(result.Errors); } } if (Info.Job != TaskJob.ShortenURL && (Info.TaskSettings.AfterUploadJob.HasFlag(AfterUploadTasks.ShareURL) || Info.Job == TaskJob.ShareURL)) { UploadResult result = ShareURL(Info.Result.ToString()); if (result != null) { Info.Result.Errors.AddRange(result.Errors); } if (Info.Job == TaskJob.ShareURL) { Info.Result.IsURLExpected = false; } } if (Info.TaskSettings.AfterUploadJob.HasFlag(AfterUploadTasks.CopyURLToClipboard)) { string txt; if (!string.IsNullOrEmpty(Info.TaskSettings.AdvancedSettings.ClipboardContentFormat)) { txt = new UploadInfoParser().Parse(Info, Info.TaskSettings.AdvancedSettings.ClipboardContentFormat); } else { txt = Info.Result.ToString(); } if (!string.IsNullOrEmpty(txt)) { ClipboardHelpers.CopyText(txt); } } if (Info.TaskSettings.AfterUploadJob.HasFlag(AfterUploadTasks.OpenURL)) { string result; if (!string.IsNullOrEmpty(Info.TaskSettings.AdvancedSettings.OpenURLFormat)) { result = new UploadInfoParser().Parse(Info, Info.TaskSettings.AdvancedSettings.OpenURLFormat); } else { result = Info.Result.ToString(); } URLHelpers.OpenURL(result); } if (Info.TaskSettings.AfterUploadJob.HasFlag(AfterUploadTasks.ShowQRCode)) { threadWorker.InvokeAsync(() => new QRCodeForm(Info.Result.ToString()).Show()); } } catch (Exception e) { DebugHelper.WriteException(e); AddErrorMessage(e.ToString()); } }
public override UploadResult Upload(Stream stream, string fileName) { 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.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(); string contentType = Helpers.GetMimeType(fileName); NameValueCollection headers = new NameValueCollection(); headers["content-type"] = contentType; headers["host"] = host; headers["x-amz-acl"] = "public-read"; headers["x-amz-storage-class"] = Settings.UseReducedRedundancyStorage ? "REDUCED_REDUNDANCY" : "STANDARD"; string signedHeaders = GetSignedHeaders(headers); Dictionary <string, string> args = new Dictionary <string, string>(); args.Add("X-Amz-Algorithm", algorithm); args.Add("X-Amz-Credential", credential); args.Add("X-Amz-Date", longDate); args.Add("X-Amz-Expires", expiresTotalSeconds); args.Add("X-Amz-SignedHeaders", signedHeaders); string uploadPath = GetUploadPath(fileName); string canonicalURI = URLHelpers.AddSlash(uploadPath, SlashType.Prefix); canonicalURI = URLHelpers.URLPathEncode(canonicalURI); string canonicalQueryString = CreateQueryString(args); string canonicalHeaders = CreateCanonicalHeaders(headers); string canonicalRequest = "PUT" + "\n" + canonicalURI + "\n" + canonicalQueryString + "\n" + canonicalHeaders + "\n" + signedHeaders + "\n" + "UNSIGNED-PAYLOAD"; string stringToSign = algorithm + "\n" + longDate + "\n" + scope + "\n" + BytesToHex(ComputeHash(canonicalRequest)); byte[] secretKey = Encoding.UTF8.GetBytes("AWS4" + Settings.SecretAccessKey); byte[] dateKey = ComputeHMAC(Encoding.UTF8.GetBytes(credentialDate), secretKey); 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)); args.Add("X-Amz-Signature", signature); headers.Remove("content-type"); headers.Remove("host"); string url = URLHelpers.CombineURL(host, canonicalURI) + "?" + CreateQueryString(args); url = URLHelpers.ForcePrefix(url, "https://"); NameValueCollection responseHeaders = SendRequestGetHeaders(HttpMethod.PUT, url, stream, contentType, null, headers); if (responseHeaders == null || responseHeaders.Count == 0) { Errors.Add("Upload to Amazon S3 failed. Check your access credentials."); return(null); } if (responseHeaders["ETag"] == null) { Errors.Add("Upload to Amazon S3 failed."); return(null); } return(new UploadResult { IsSuccess = true, URL = GenerateURL(fileName) }); }