@azure/storage-file-datalake 12.13.0 → 12.14.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +2187 -2176
- package/dist/index.js.map +1 -1
- package/dist-esm/storage-file-datalake/src/clients.js +3 -3
- package/dist-esm/storage-file-datalake/src/clients.js.map +1 -1
- package/dist-esm/storage-file-datalake/src/generated/src/models/parameters.js +1 -1
- package/dist-esm/storage-file-datalake/src/generated/src/models/parameters.js.map +1 -1
- package/dist-esm/storage-file-datalake/src/generated/src/storageClientContext.js +2 -2
- package/dist-esm/storage-file-datalake/src/generated/src/storageClientContext.js.map +1 -1
- package/dist-esm/storage-file-datalake/src/models.js.map +1 -1
- package/dist-esm/storage-file-datalake/src/utils/constants.js +2 -2
- package/dist-esm/storage-file-datalake/src/utils/constants.js.map +1 -1
- package/dist-esm/storage-file-datalake/src/utils/utils.common.js +21 -9
- package/dist-esm/storage-file-datalake/src/utils/utils.common.js.map +1 -1
- package/package.json +2 -2
- package/types/3.1/storage-file-datalake.d.ts +6 -0
- package/types/latest/storage-file-datalake.d.ts +6 -0
package/dist/index.js
CHANGED
|
@@ -123,8 +123,8 @@ class AnonymousCredential extends Credential {
|
|
|
123
123
|
|
|
124
124
|
// Copyright (c) Microsoft Corporation.
|
|
125
125
|
// Licensed under the MIT license.
|
|
126
|
-
const SDK_VERSION = "12.
|
|
127
|
-
const SERVICE_VERSION = "
|
|
126
|
+
const SDK_VERSION = "12.14.0";
|
|
127
|
+
const SERVICE_VERSION = "2023-01-03";
|
|
128
128
|
const KB = 1024;
|
|
129
129
|
const MB = KB * 1024;
|
|
130
130
|
const DEFAULT_HIGH_LEVEL_CONCURRENCY = 5;
|
|
@@ -353,1102 +353,1096 @@ const PathStylePorts = [
|
|
|
353
353
|
"11104",
|
|
354
354
|
];
|
|
355
355
|
|
|
356
|
+
// Copyright (c) Microsoft Corporation.
|
|
356
357
|
/**
|
|
357
|
-
*
|
|
358
|
-
*
|
|
359
|
-
* ## URL encode and escape strategy for JS SDKs
|
|
360
|
-
*
|
|
361
|
-
* When customers pass a URL string into XxxClient classes constructors, the URL string may already be URL encoded or not.
|
|
362
|
-
* But before sending to Azure Storage server, the URL must be encoded. However, it's hard for a SDK to guess whether the URL
|
|
363
|
-
* string has been encoded or not. We have 2 potential strategies, and chose strategy two for the XxxClient constructors.
|
|
364
|
-
*
|
|
365
|
-
* ### Strategy One: Assume the customer URL string is not encoded, and always encode URL string in SDK.
|
|
366
|
-
*
|
|
367
|
-
* This is what legacy V2 SDK does, simple and works for most of the cases.
|
|
368
|
-
* - When customer URL string is "http://account.blob.core.windows.net/con/b:",
|
|
369
|
-
* SDK will encode it to "http://account.blob.core.windows.net/con/b%3A" and send to server. A blob named "b:" will be created.
|
|
370
|
-
* - When customer URL string is "http://account.blob.core.windows.net/con/b%3A",
|
|
371
|
-
* SDK will encode it to "http://account.blob.core.windows.net/con/b%253A" and send to server. A blob named "b%3A" will be created.
|
|
372
|
-
*
|
|
373
|
-
* But this strategy will make it not possible to create a blob with "?" in it's name. Because when customer URL string is
|
|
374
|
-
* "http://account.blob.core.windows.net/con/blob?name", the "?name" will be treated as URL paramter instead of blob name.
|
|
375
|
-
* If customer URL string is "http://account.blob.core.windows.net/con/blob%3Fname", a blob named "blob%3Fname" will be created.
|
|
376
|
-
* V2 SDK doesn't have this issue because it doesn't allow customer pass in a full URL, it accepts a separate blob name and encodeURIComponent for it.
|
|
377
|
-
* We cannot accept a SDK cannot create a blob name with "?". So we implement strategy two:
|
|
378
|
-
*
|
|
379
|
-
* ### Strategy Two: SDK doesn't assume the URL has been encoded or not. It will just escape the special characters.
|
|
380
|
-
*
|
|
381
|
-
* This is what V10 Blob Go SDK does. It accepts a URL type in Go, and call url.EscapedPath() to escape the special chars unescaped.
|
|
382
|
-
* - When customer URL string is "http://account.blob.core.windows.net/con/b:",
|
|
383
|
-
* SDK will escape ":" like "http://account.blob.core.windows.net/con/b%3A" and send to server. A blob named "b:" will be created.
|
|
384
|
-
* - When customer URL string is "http://account.blob.core.windows.net/con/b%3A",
|
|
385
|
-
* There is no special characters, so send "http://account.blob.core.windows.net/con/b%3A" to server. A blob named "b:" will be created.
|
|
386
|
-
* - When customer URL string is "http://account.blob.core.windows.net/con/b%253A",
|
|
387
|
-
* There is no special characters, so send "http://account.blob.core.windows.net/con/b%253A" to server. A blob named "b%3A" will be created.
|
|
388
|
-
*
|
|
389
|
-
* This strategy gives us flexibility to create with any special characters. But "%" will be treated as a special characters, if the URL string
|
|
390
|
-
* is not encoded, there shouldn't a "%" in the URL string, otherwise the URL is not a valid URL.
|
|
391
|
-
* If customer needs to create a blob with "%" in it's blob name, use "%25" instead of "%". Just like above 3rd sample.
|
|
392
|
-
* And following URL strings are invalid:
|
|
393
|
-
* - "http://account.blob.core.windows.net/con/b%"
|
|
394
|
-
* - "http://account.blob.core.windows.net/con/b%2"
|
|
395
|
-
* - "http://account.blob.core.windows.net/con/b%G"
|
|
396
|
-
*
|
|
397
|
-
* Another special character is "?", use "%2F" to represent a blob name with "?" in a URL string.
|
|
398
|
-
*
|
|
399
|
-
* ### Strategy for containerName, blobName or other specific XXXName parameters in methods such as `containerClient.getBlobClient(blobName)`
|
|
400
|
-
*
|
|
401
|
-
* We will apply strategy one, and call encodeURIComponent for these parameters like blobName. Because what customers passes in is a plain name instead of a URL.
|
|
358
|
+
* Get a blob endpoint URL from incoming blob or dfs endpoint URLs.
|
|
359
|
+
* Only handle known host name pair patterns, add more patterns into ToBlobEndpointHostMappings in constants.ts.
|
|
402
360
|
*
|
|
403
|
-
*
|
|
404
|
-
*
|
|
361
|
+
* Expected input and outputs:
|
|
362
|
+
* http://account.blob.core.windows.net - http://account.blob.core.windows.net
|
|
363
|
+
* http://account.dfs.core.windows.net - http://account.blob.core.windows.net
|
|
364
|
+
* http://127.0.0.1:10000 - http://127.0.0.1:10000
|
|
365
|
+
* http://account.blob.core.windows.net/abc - http://account.blob.core.windows.net/abc
|
|
366
|
+
* http://account.dfs.core.windows.net/abc - http://account.blob.core.windows.net/abc
|
|
367
|
+
* http://127.0.0.1:10000/abc - http://127.0.0.1:10000/abc
|
|
405
368
|
*
|
|
406
369
|
* @param url -
|
|
407
370
|
*/
|
|
408
|
-
function
|
|
371
|
+
function toBlobEndpointUrl(url) {
|
|
409
372
|
const urlParsed = coreHttp.URLBuilder.parse(url);
|
|
410
|
-
let
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
urlParsed.setPath(path);
|
|
414
|
-
return urlParsed.toString();
|
|
415
|
-
}
|
|
416
|
-
function getProxyUriFromDevConnString(connectionString) {
|
|
417
|
-
// Development Connection String
|
|
418
|
-
// https://docs.microsoft.com/en-us/azure/storage/common/storage-configure-connection-string#connect-to-the-emulator-account-using-the-well-known-account-name-and-key
|
|
419
|
-
let proxyUri = "";
|
|
420
|
-
if (connectionString.search("DevelopmentStorageProxyUri=") !== -1) {
|
|
421
|
-
// CONNECTION_STRING=UseDevelopmentStorage=true;DevelopmentStorageProxyUri=http://myProxyUri
|
|
422
|
-
const matchCredentials = connectionString.split(";");
|
|
423
|
-
for (const element of matchCredentials) {
|
|
424
|
-
if (element.trim().startsWith("DevelopmentStorageProxyUri=")) {
|
|
425
|
-
proxyUri = element.trim().match("DevelopmentStorageProxyUri=(.*)")[1];
|
|
426
|
-
}
|
|
427
|
-
}
|
|
428
|
-
}
|
|
429
|
-
return proxyUri;
|
|
430
|
-
}
|
|
431
|
-
function getValueInConnString(connectionString, argument) {
|
|
432
|
-
const elements = connectionString.split(";");
|
|
433
|
-
for (const element of elements) {
|
|
434
|
-
if (element.trim().startsWith(argument)) {
|
|
435
|
-
return element.trim().match(argument + "=(.*)")[1];
|
|
436
|
-
}
|
|
437
|
-
}
|
|
438
|
-
return "";
|
|
439
|
-
}
|
|
440
|
-
/**
|
|
441
|
-
* Extracts the parts of an Azure Storage account connection string.
|
|
442
|
-
*
|
|
443
|
-
* @param connectionString - Connection string.
|
|
444
|
-
* @returns String key value pairs of the storage account's url and credentials.
|
|
445
|
-
*/
|
|
446
|
-
function extractConnectionStringParts(connectionString) {
|
|
447
|
-
let proxyUri = "";
|
|
448
|
-
if (connectionString.startsWith("UseDevelopmentStorage=true")) {
|
|
449
|
-
// Development connection string
|
|
450
|
-
proxyUri = getProxyUriFromDevConnString(connectionString);
|
|
451
|
-
connectionString = DevelopmentConnectionString;
|
|
452
|
-
}
|
|
453
|
-
// Matching BlobEndpoint in the Account connection string
|
|
454
|
-
let blobEndpoint = getValueInConnString(connectionString, "BlobEndpoint");
|
|
455
|
-
// Slicing off '/' at the end if exists
|
|
456
|
-
// (The methods that use `extractConnectionStringParts` expect the url to not have `/` at the end)
|
|
457
|
-
blobEndpoint = blobEndpoint.endsWith("/") ? blobEndpoint.slice(0, -1) : blobEndpoint;
|
|
458
|
-
if (connectionString.search("DefaultEndpointsProtocol=") !== -1 &&
|
|
459
|
-
connectionString.search("AccountKey=") !== -1) {
|
|
460
|
-
// Account connection string
|
|
461
|
-
let defaultEndpointsProtocol = "";
|
|
462
|
-
let accountName = "";
|
|
463
|
-
let accountKey = Buffer.from("accountKey", "base64");
|
|
464
|
-
let endpointSuffix = "";
|
|
465
|
-
// Get account name and key
|
|
466
|
-
accountName = getValueInConnString(connectionString, "AccountName");
|
|
467
|
-
accountKey = Buffer.from(getValueInConnString(connectionString, "AccountKey"), "base64");
|
|
468
|
-
if (!blobEndpoint) {
|
|
469
|
-
// BlobEndpoint is not present in the Account connection string
|
|
470
|
-
// Can be obtained from `${defaultEndpointsProtocol}://${accountName}.blob.${endpointSuffix}`
|
|
471
|
-
defaultEndpointsProtocol = getValueInConnString(connectionString, "DefaultEndpointsProtocol");
|
|
472
|
-
const protocol = defaultEndpointsProtocol.toLowerCase();
|
|
473
|
-
if (protocol !== "https" && protocol !== "http") {
|
|
474
|
-
throw new Error("Invalid DefaultEndpointsProtocol in the provided Connection String. Expecting 'https' or 'http'");
|
|
475
|
-
}
|
|
476
|
-
endpointSuffix = getValueInConnString(connectionString, "EndpointSuffix");
|
|
477
|
-
if (!endpointSuffix) {
|
|
478
|
-
throw new Error("Invalid EndpointSuffix in the provided Connection String");
|
|
479
|
-
}
|
|
480
|
-
blobEndpoint = `${defaultEndpointsProtocol}://${accountName}.blob.${endpointSuffix}`;
|
|
481
|
-
}
|
|
482
|
-
if (!accountName) {
|
|
483
|
-
throw new Error("Invalid AccountName in the provided Connection String");
|
|
484
|
-
}
|
|
485
|
-
else if (accountKey.length === 0) {
|
|
486
|
-
throw new Error("Invalid AccountKey in the provided Connection String");
|
|
487
|
-
}
|
|
488
|
-
return {
|
|
489
|
-
kind: "AccountConnString",
|
|
490
|
-
url: blobEndpoint,
|
|
491
|
-
accountName,
|
|
492
|
-
accountKey,
|
|
493
|
-
proxyUri,
|
|
494
|
-
};
|
|
373
|
+
let host = urlParsed.getHost();
|
|
374
|
+
if (host === undefined) {
|
|
375
|
+
throw RangeError(`toBlobEndpointUrl() parameter url ${url} doesn't include valid host.`);
|
|
495
376
|
}
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
if (!blobEndpoint) {
|
|
501
|
-
throw new Error("Invalid BlobEndpoint in the provided SAS Connection String");
|
|
502
|
-
}
|
|
503
|
-
else if (!accountSas) {
|
|
504
|
-
throw new Error("Invalid SharedAccessSignature in the provided SAS Connection String");
|
|
377
|
+
for (const mapping of ToBlobEndpointHostMappings) {
|
|
378
|
+
if (host.includes(mapping[0])) {
|
|
379
|
+
host = host.replace(mapping[0], mapping[1]);
|
|
380
|
+
break;
|
|
505
381
|
}
|
|
506
|
-
return { kind: "SASConnString", url: blobEndpoint, accountName, accountSas };
|
|
507
382
|
}
|
|
383
|
+
urlParsed.setHost(host);
|
|
384
|
+
return urlParsed.toString();
|
|
508
385
|
}
|
|
509
386
|
/**
|
|
510
|
-
*
|
|
511
|
-
*
|
|
512
|
-
* @param text -
|
|
513
|
-
*/
|
|
514
|
-
function escape(text) {
|
|
515
|
-
return encodeURIComponent(text)
|
|
516
|
-
.replace(/%2F/g, "/") // Don't escape for "/"
|
|
517
|
-
.replace(/'/g, "%27") // Escape for "'"
|
|
518
|
-
.replace(/\+/g, "%20")
|
|
519
|
-
.replace(/%25/g, "%"); // Revert encoded "%"
|
|
520
|
-
}
|
|
521
|
-
/**
|
|
522
|
-
* Append a string to URL path. Will remove duplicated "/" in front of the string
|
|
523
|
-
* when URL path ends with a "/".
|
|
387
|
+
* Get a dfs endpoint URL from incoming blob or dfs endpoint URLs.
|
|
388
|
+
* Only handle known host name pair patterns, add more patterns into ToDfsEndpointHostMappings in constants.ts.
|
|
524
389
|
*
|
|
525
|
-
*
|
|
526
|
-
*
|
|
527
|
-
*
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
path = path ? (path.endsWith("/") ? `${path}${name}` : `${path}/${name}`) : name;
|
|
533
|
-
urlParsed.setPath(path);
|
|
534
|
-
const normalizedUrl = new URL(urlParsed.toString());
|
|
535
|
-
return normalizedUrl.toString();
|
|
536
|
-
}
|
|
537
|
-
/**
|
|
538
|
-
* Append a string to URL query.
|
|
390
|
+
* Expected input and outputs:
|
|
391
|
+
* http://account.blob.core.windows.net - http://account.dfs.core.windows.net
|
|
392
|
+
* http://account.dfs.core.windows.net - http://account.dfs.core.windows.net
|
|
393
|
+
* http://127.0.0.1:10000 - http://127.0.0.1:10000
|
|
394
|
+
* http://account.blob.core.windows.net/abc - http://account.dfs.core.windows.net/abc
|
|
395
|
+
* http://account.dfs.core.windows.net/abc - http://account.dfs.core.windows.net/abc
|
|
396
|
+
* http://127.0.0.1:10000/abc - http://127.0.0.1:10000/abc
|
|
539
397
|
*
|
|
540
|
-
* @param url -
|
|
541
|
-
* @param queryParts - String to be appended to the URL query.
|
|
542
|
-
* @returns An updated URL string.
|
|
398
|
+
* @param url -
|
|
543
399
|
*/
|
|
544
|
-
function
|
|
400
|
+
function toDfsEndpointUrl(url) {
|
|
545
401
|
const urlParsed = coreHttp.URLBuilder.parse(url);
|
|
546
|
-
let
|
|
547
|
-
if (
|
|
548
|
-
|
|
402
|
+
let host = urlParsed.getHost();
|
|
403
|
+
if (host === undefined) {
|
|
404
|
+
throw RangeError(`toDfsEndpointUrl() parameter url ${url} doesn't include valid host.`);
|
|
549
405
|
}
|
|
550
|
-
|
|
551
|
-
|
|
406
|
+
for (const mapping of ToDfsEndpointHostMappings) {
|
|
407
|
+
if (host.includes(mapping[0])) {
|
|
408
|
+
host = host.replace(mapping[0], mapping[1]);
|
|
409
|
+
break;
|
|
410
|
+
}
|
|
552
411
|
}
|
|
553
|
-
urlParsed.setQuery(query);
|
|
554
|
-
return urlParsed.toString();
|
|
555
|
-
}
|
|
556
|
-
/**
|
|
557
|
-
* Set URL parameter name and value. If name exists in URL parameters, old value
|
|
558
|
-
* will be replaced by name key. If not provide value, the parameter will be deleted.
|
|
559
|
-
*
|
|
560
|
-
* @param url - Source URL string
|
|
561
|
-
* @param name - Parameter name
|
|
562
|
-
* @param value - Parameter value
|
|
563
|
-
* @returns An updated URL string
|
|
564
|
-
*/
|
|
565
|
-
function setURLParameter(url, name, value) {
|
|
566
|
-
const urlParsed = coreHttp.URLBuilder.parse(url);
|
|
567
|
-
urlParsed.setQueryParameter(name, value);
|
|
568
|
-
return urlParsed.toString();
|
|
569
|
-
}
|
|
570
|
-
/**
|
|
571
|
-
* Set URL host.
|
|
572
|
-
*
|
|
573
|
-
* @param url - Source URL string
|
|
574
|
-
* @param host - New host string
|
|
575
|
-
* @returns An updated URL string
|
|
576
|
-
*/
|
|
577
|
-
function setURLHost(url, host) {
|
|
578
|
-
const urlParsed = coreHttp.URLBuilder.parse(url);
|
|
579
412
|
urlParsed.setHost(host);
|
|
580
413
|
return urlParsed.toString();
|
|
581
414
|
}
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
}
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
function setURLPath(url, path) {
|
|
598
|
-
const urlParsed = coreHttp.URLBuilder.parse(url);
|
|
599
|
-
urlParsed.setPath(path);
|
|
600
|
-
return urlParsed.toString();
|
|
415
|
+
function toFileSystemAsyncIterableIterator(iter) {
|
|
416
|
+
return {
|
|
417
|
+
async next() {
|
|
418
|
+
const rawResult = await iter.next();
|
|
419
|
+
if (rawResult.value) {
|
|
420
|
+
rawResult.value.fileSystemItems = rawResult.value.containerItems.map((val) => {
|
|
421
|
+
return Object.assign(Object.assign({}, val), { versionId: val.version, properties: Object.assign(Object.assign({}, val.properties), { publicAccess: toPublicAccessType(val.properties.publicAccess) }) });
|
|
422
|
+
});
|
|
423
|
+
}
|
|
424
|
+
return rawResult;
|
|
425
|
+
},
|
|
426
|
+
[Symbol.asyncIterator]() {
|
|
427
|
+
return this;
|
|
428
|
+
},
|
|
429
|
+
};
|
|
601
430
|
}
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
431
|
+
function toFileSystemPagedAsyncIterableIterator(iter) {
|
|
432
|
+
return {
|
|
433
|
+
async next() {
|
|
434
|
+
const rawResult = await iter.next();
|
|
435
|
+
const result = rawResult;
|
|
436
|
+
if (!result.done && !rawResult.done) {
|
|
437
|
+
result.value.properties.publicAccess = toPublicAccessType(rawResult.value.properties.publicAccess);
|
|
438
|
+
result.value.versionId = rawResult.value.version;
|
|
439
|
+
}
|
|
440
|
+
return result;
|
|
441
|
+
},
|
|
442
|
+
[Symbol.asyncIterator]() {
|
|
443
|
+
return this;
|
|
444
|
+
},
|
|
445
|
+
byPage(settings = {}) {
|
|
446
|
+
return toFileSystemAsyncIterableIterator(iter.byPage(settings));
|
|
447
|
+
},
|
|
448
|
+
};
|
|
610
449
|
}
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
* @param url - Source URL string
|
|
615
|
-
*/
|
|
616
|
-
function getURLPathAndQuery(url) {
|
|
617
|
-
const urlParsed = coreHttp.URLBuilder.parse(url);
|
|
618
|
-
const pathString = urlParsed.getPath();
|
|
619
|
-
if (!pathString) {
|
|
620
|
-
throw new RangeError("Invalid url without valid path.");
|
|
450
|
+
function toContainerPublicAccessType(publicAccessType) {
|
|
451
|
+
if (!publicAccessType) {
|
|
452
|
+
return undefined;
|
|
621
453
|
}
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
|
|
454
|
+
switch (publicAccessType) {
|
|
455
|
+
case "filesystem":
|
|
456
|
+
return "container";
|
|
457
|
+
case "file":
|
|
458
|
+
return "blob";
|
|
459
|
+
default:
|
|
460
|
+
throw TypeError(`toContainerPublicAccessType() parameter ${publicAccessType} is not recognized.`);
|
|
626
461
|
}
|
|
627
|
-
return `${pathString}${queryString}`;
|
|
628
462
|
}
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
* @param url -
|
|
633
|
-
*/
|
|
634
|
-
function getURLQueries(url) {
|
|
635
|
-
let queryString = coreHttp.URLBuilder.parse(url).getQuery();
|
|
636
|
-
if (!queryString) {
|
|
637
|
-
return {};
|
|
463
|
+
function toPublicAccessType(containerPublicAccessType) {
|
|
464
|
+
if (!containerPublicAccessType) {
|
|
465
|
+
return undefined;
|
|
638
466
|
}
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
});
|
|
647
|
-
const queries = {};
|
|
648
|
-
for (const querySubString of querySubStrings) {
|
|
649
|
-
const splitResults = querySubString.split("=");
|
|
650
|
-
const key = splitResults[0];
|
|
651
|
-
const value = splitResults[1];
|
|
652
|
-
queries[key] = value;
|
|
467
|
+
switch (containerPublicAccessType) {
|
|
468
|
+
case "container":
|
|
469
|
+
return "filesystem";
|
|
470
|
+
case "blob":
|
|
471
|
+
return "file";
|
|
472
|
+
default:
|
|
473
|
+
throw TypeError(`toPublicAccessType() parameter ${containerPublicAccessType} is not recognized.`);
|
|
653
474
|
}
|
|
654
|
-
return queries;
|
|
655
|
-
}
|
|
656
|
-
/**
|
|
657
|
-
* Set URL query string.
|
|
658
|
-
*
|
|
659
|
-
* @param url -
|
|
660
|
-
* @param queryString -
|
|
661
|
-
*/
|
|
662
|
-
function setURLQueries(url, queryString) {
|
|
663
|
-
const urlParsed = coreHttp.URLBuilder.parse(url);
|
|
664
|
-
urlParsed.setQuery(queryString);
|
|
665
|
-
return urlParsed.toString();
|
|
666
|
-
}
|
|
667
|
-
/**
|
|
668
|
-
* Rounds a date off to seconds.
|
|
669
|
-
*
|
|
670
|
-
* @param date -
|
|
671
|
-
* @param withMilliseconds - If true, YYYY-MM-DDThh:mm:ss.fffffffZ will be returned;
|
|
672
|
-
* If false, YYYY-MM-DDThh:mm:ssZ will be returned.
|
|
673
|
-
* @returns Date string in ISO8061 format, with or without 7 milliseconds component
|
|
674
|
-
*/
|
|
675
|
-
function truncatedISO8061Date(date, withMilliseconds = true) {
|
|
676
|
-
// Date.toISOString() will return like "2018-10-29T06:34:36.139Z"
|
|
677
|
-
const dateString = date.toISOString();
|
|
678
|
-
return withMilliseconds
|
|
679
|
-
? dateString.substring(0, dateString.length - 1) + "0000" + "Z"
|
|
680
|
-
: dateString.substring(0, dateString.length - 5) + "Z";
|
|
681
|
-
}
|
|
682
|
-
/**
|
|
683
|
-
* Base64 encode.
|
|
684
|
-
*
|
|
685
|
-
* @param content -
|
|
686
|
-
*/
|
|
687
|
-
function base64encode(content) {
|
|
688
|
-
return !coreHttp.isNode ? btoa(content) : Buffer.from(content).toString("base64");
|
|
689
475
|
}
|
|
690
|
-
|
|
691
|
-
|
|
692
|
-
|
|
693
|
-
|
|
694
|
-
|
|
695
|
-
|
|
696
|
-
|
|
697
|
-
|
|
698
|
-
|
|
699
|
-
/* eslint-disable-next-line prefer-const*/
|
|
700
|
-
let timeout;
|
|
701
|
-
const abortHandler = () => {
|
|
702
|
-
if (timeout !== undefined) {
|
|
703
|
-
clearTimeout(timeout);
|
|
704
|
-
}
|
|
705
|
-
reject(abortError);
|
|
706
|
-
};
|
|
707
|
-
const resolveHandler = () => {
|
|
708
|
-
if (aborter !== undefined) {
|
|
709
|
-
aborter.removeEventListener("abort", abortHandler);
|
|
710
|
-
}
|
|
711
|
-
resolve();
|
|
712
|
-
};
|
|
713
|
-
timeout = setTimeout(resolveHandler, timeInMs);
|
|
714
|
-
if (aborter !== undefined) {
|
|
715
|
-
aborter.addEventListener("abort", abortHandler);
|
|
476
|
+
function toProperties(metadata) {
|
|
477
|
+
if (metadata === undefined) {
|
|
478
|
+
return undefined;
|
|
479
|
+
}
|
|
480
|
+
const properties = [];
|
|
481
|
+
for (const key in metadata) {
|
|
482
|
+
if (Object.prototype.hasOwnProperty.call(metadata, key)) {
|
|
483
|
+
const value = metadata[key];
|
|
484
|
+
properties.push(`${key}=${base64encode(value)}`);
|
|
716
485
|
}
|
|
717
|
-
}
|
|
486
|
+
}
|
|
487
|
+
return properties.join(",");
|
|
718
488
|
}
|
|
719
|
-
|
|
720
|
-
|
|
721
|
-
*
|
|
722
|
-
* @param str1 -
|
|
723
|
-
* @param str2 -
|
|
724
|
-
*/
|
|
725
|
-
function iEqual(str1, str2) {
|
|
726
|
-
return str1.toLocaleLowerCase() === str2.toLocaleLowerCase();
|
|
489
|
+
function toPathGetAccessControlResponse(response) {
|
|
490
|
+
return Object.assign(Object.assign({}, response), { _response: response._response, permissions: toPermissions(response.permissions), acl: toAcl(response.acl) });
|
|
727
491
|
}
|
|
728
|
-
|
|
729
|
-
|
|
730
|
-
|
|
731
|
-
|
|
732
|
-
*/
|
|
733
|
-
function getAccountNameFromUrl(blobEndpointUrl) {
|
|
734
|
-
const parsedUrl = coreHttp.URLBuilder.parse(blobEndpointUrl);
|
|
735
|
-
let accountName;
|
|
736
|
-
try {
|
|
737
|
-
if (parsedUrl.getHost().split(".")[1] === "blob") {
|
|
738
|
-
// `${defaultEndpointsProtocol}://${accountName}.blob.${endpointSuffix}`;
|
|
739
|
-
accountName = parsedUrl.getHost().split(".")[0];
|
|
740
|
-
}
|
|
741
|
-
else if (isIpEndpointStyle(parsedUrl)) {
|
|
742
|
-
// IPv4/IPv6 address hosts... Example - http://192.0.0.10:10001/devstoreaccount1/
|
|
743
|
-
// Single word domain without a [dot] in the endpoint... Example - http://localhost:10001/devstoreaccount1/
|
|
744
|
-
// .getPath() -> /devstoreaccount1/
|
|
745
|
-
accountName = parsedUrl.getPath().split("/")[1];
|
|
746
|
-
}
|
|
747
|
-
else {
|
|
748
|
-
// Custom domain case: "https://customdomain.com/containername/blob".
|
|
749
|
-
accountName = "";
|
|
750
|
-
}
|
|
751
|
-
return accountName;
|
|
492
|
+
function toRolePermissions(permissionsString) {
|
|
493
|
+
const error = new RangeError(`toRolePermissions() Invalid role permissions string ${permissionsString}`);
|
|
494
|
+
if (permissionsString.length !== 3) {
|
|
495
|
+
throw error;
|
|
752
496
|
}
|
|
753
|
-
|
|
754
|
-
|
|
497
|
+
permissionsString = permissionsString.toLowerCase();
|
|
498
|
+
let read = false;
|
|
499
|
+
if (permissionsString[0] === "r") {
|
|
500
|
+
read = true;
|
|
755
501
|
}
|
|
756
|
-
|
|
757
|
-
|
|
758
|
-
if (parsedUrl.getHost() === undefined) {
|
|
759
|
-
return false;
|
|
502
|
+
else if (permissionsString[0] !== "-") {
|
|
503
|
+
throw error;
|
|
760
504
|
}
|
|
761
|
-
|
|
762
|
-
|
|
763
|
-
|
|
764
|
-
|
|
765
|
-
|
|
766
|
-
|
|
767
|
-
|
|
505
|
+
let write = false;
|
|
506
|
+
if (permissionsString[1] === "w") {
|
|
507
|
+
write = true;
|
|
508
|
+
}
|
|
509
|
+
else if (permissionsString[1] !== "-") {
|
|
510
|
+
throw error;
|
|
511
|
+
}
|
|
512
|
+
let execute = false;
|
|
513
|
+
if (permissionsString[2] === "x") {
|
|
514
|
+
execute = true;
|
|
515
|
+
}
|
|
516
|
+
else if (permissionsString[2] !== "-") {
|
|
517
|
+
throw error;
|
|
518
|
+
}
|
|
519
|
+
return { read, write, execute };
|
|
768
520
|
}
|
|
769
|
-
|
|
770
|
-
|
|
771
|
-
* This is to convert a Windows File Time ticks to a Date object.
|
|
772
|
-
*/
|
|
773
|
-
function windowsFileTimeTicksToTime(timeNumber) {
|
|
774
|
-
if (!timeNumber)
|
|
775
|
-
return undefined;
|
|
776
|
-
const timeNumberInternal = parseInt(timeNumber);
|
|
777
|
-
if (timeNumberInternal === 0)
|
|
521
|
+
function toPermissions(permissionsString) {
|
|
522
|
+
if (permissionsString === undefined || permissionsString === "" || permissionsString === null) {
|
|
778
523
|
return undefined;
|
|
779
|
-
// A windows file time is a 64-bit value that represents the number of 100-nanosecond intervals that have elapsed
|
|
780
|
-
// since 12:00 A.M. January 1, 1601 Coordinated Universal Time (UTC).
|
|
781
|
-
// Date accepts a value that represents miliseconds from 12:00 A.M. January 1, 1970
|
|
782
|
-
// Here should correct the year number after converting.
|
|
783
|
-
const timeNumerInMs = timeNumberInternal / 10000;
|
|
784
|
-
const date = new Date(timeNumerInMs);
|
|
785
|
-
// When initializing date from a miliseconds number the day after 2023-03-01 is still 2023-03-01.
|
|
786
|
-
// For example, 13322188799999 is 2023-03-01T23:59:59.999Z, while 13322188800000 is 2023-03-01T00:00:00.000Z
|
|
787
|
-
// Here is to work around the bug.
|
|
788
|
-
if (timeNumerInMs >= BugTimeBeginningInMS) {
|
|
789
|
-
date.setUTCDate(date.getUTCDate() + 1);
|
|
790
524
|
}
|
|
791
|
-
|
|
792
|
-
|
|
525
|
+
if (permissionsString.length !== 9 && permissionsString.length !== 10) {
|
|
526
|
+
throw RangeError(`toPermissions() Invalid permissions string ${permissionsString}`);
|
|
527
|
+
}
|
|
528
|
+
let stickyBit = false;
|
|
529
|
+
if (permissionsString[8] === "t") {
|
|
530
|
+
stickyBit = true;
|
|
531
|
+
const firstPart = permissionsString.substr(0, 8);
|
|
532
|
+
const lastPart = permissionsString.substr(9);
|
|
533
|
+
permissionsString = firstPart + "x" + lastPart;
|
|
534
|
+
}
|
|
535
|
+
else if (permissionsString[8] === "T") {
|
|
536
|
+
stickyBit = true;
|
|
537
|
+
const firstPart = permissionsString.substr(0, 8);
|
|
538
|
+
const lastPart = permissionsString.substr(9);
|
|
539
|
+
permissionsString = firstPart + "-" + lastPart;
|
|
540
|
+
}
|
|
541
|
+
// Case insensitive
|
|
542
|
+
permissionsString = permissionsString.toLowerCase();
|
|
543
|
+
let extendedAcls = false;
|
|
544
|
+
if (permissionsString.length === 10) {
|
|
545
|
+
if (permissionsString[9] === "+") {
|
|
546
|
+
extendedAcls = true;
|
|
547
|
+
}
|
|
548
|
+
else {
|
|
549
|
+
throw RangeError(`toPermissions() Invalid extendedAcls bit ${permissionsString[9]} in permissions string ${permissionsString}`);
|
|
550
|
+
}
|
|
551
|
+
}
|
|
552
|
+
const owner = toRolePermissions(permissionsString.substr(0, 3));
|
|
553
|
+
const group = toRolePermissions(permissionsString.substr(3, 3));
|
|
554
|
+
const other = toRolePermissions(permissionsString.substr(6, 3));
|
|
555
|
+
return {
|
|
556
|
+
owner,
|
|
557
|
+
group,
|
|
558
|
+
other,
|
|
559
|
+
stickyBit,
|
|
560
|
+
extendedAcls,
|
|
561
|
+
};
|
|
793
562
|
}
|
|
794
|
-
function
|
|
795
|
-
|
|
796
|
-
|
|
563
|
+
function toAccessControlItem(aclItemString) {
|
|
564
|
+
const error = new RangeError(`toAccessControlItem() Parameter access control item string ${aclItemString} is not valid.`);
|
|
565
|
+
if (aclItemString === "") {
|
|
566
|
+
throw error;
|
|
797
567
|
}
|
|
798
|
-
|
|
799
|
-
|
|
568
|
+
aclItemString = aclItemString.toLowerCase();
|
|
569
|
+
const parts = aclItemString.split(":");
|
|
570
|
+
if (parts.length < 3 || parts.length > 4) {
|
|
571
|
+
throw error;
|
|
572
|
+
}
|
|
573
|
+
let defaultScope = false;
|
|
574
|
+
let index = 0;
|
|
575
|
+
if (parts.length === 4) {
|
|
576
|
+
if (parts[index] !== "default") {
|
|
577
|
+
throw error;
|
|
578
|
+
}
|
|
579
|
+
defaultScope = true;
|
|
580
|
+
index++;
|
|
581
|
+
}
|
|
582
|
+
const accessControlType = parts[index++];
|
|
583
|
+
if (accessControlType !== "user" &&
|
|
584
|
+
accessControlType !== "group" &&
|
|
585
|
+
accessControlType !== "mask" &&
|
|
586
|
+
accessControlType !== "other") {
|
|
587
|
+
throw error;
|
|
800
588
|
}
|
|
589
|
+
const entityId = parts[index++];
|
|
590
|
+
const permissions = toRolePermissions(parts[index++]);
|
|
591
|
+
return {
|
|
592
|
+
defaultScope,
|
|
593
|
+
accessControlType,
|
|
594
|
+
entityId,
|
|
595
|
+
permissions,
|
|
596
|
+
};
|
|
801
597
|
}
|
|
802
|
-
|
|
803
|
-
|
|
804
|
-
|
|
805
|
-
function EscapePath(pathName) {
|
|
806
|
-
const split = pathName.split("/");
|
|
807
|
-
for (let i = 0; i < split.length; i++) {
|
|
808
|
-
split[i] = encodeURIComponent(split[i]);
|
|
598
|
+
function toAcl(aclString) {
|
|
599
|
+
if (aclString === undefined || aclString === "" || aclString === null) {
|
|
600
|
+
return [];
|
|
809
601
|
}
|
|
810
|
-
|
|
602
|
+
const acls = [];
|
|
603
|
+
const aclParts = aclString.split(",");
|
|
604
|
+
for (const aclPart of aclParts) {
|
|
605
|
+
acls.push(toAccessControlItem(aclPart));
|
|
606
|
+
}
|
|
607
|
+
return acls;
|
|
608
|
+
}
|
|
609
|
+
function toAccessControlItemString(item) {
|
|
610
|
+
const entityIdString = item.entityId !== undefined ? `:${item.entityId}` : "";
|
|
611
|
+
const permissionsString = item.permissions !== undefined ? `:${toRolePermissionsString(item.permissions)}` : "";
|
|
612
|
+
return `${item.defaultScope ? "default:" : ""}${item.accessControlType}${entityIdString}${permissionsString}`;
|
|
613
|
+
}
|
|
614
|
+
function toAclString(acl) {
|
|
615
|
+
return acl.map(toAccessControlItemString).join(",");
|
|
616
|
+
}
|
|
617
|
+
function toRolePermissionsString(p, stickyBit = false) {
|
|
618
|
+
return `${p.read ? "r" : "-"}${p.write ? "w" : "-"}${stickyBit ? (p.execute ? "t" : "T") : p.execute ? "x" : "-"}`;
|
|
619
|
+
}
|
|
620
|
+
function toPermissionsString(permissions) {
|
|
621
|
+
return `${toRolePermissionsString(permissions.owner)}${toRolePermissionsString(permissions.group)}${toRolePermissionsString(permissions.other, permissions.stickyBit)}${permissions.extendedAcls ? "+" : ""}`;
|
|
622
|
+
}
|
|
623
|
+
function toAccessControlChangeFailureArray(aclFailedEntries = []) {
|
|
624
|
+
return aclFailedEntries.map((aclFailedEntry) => {
|
|
625
|
+
return {
|
|
626
|
+
name: aclFailedEntry.name || "",
|
|
627
|
+
isDirectory: (aclFailedEntry.type || "").toLowerCase() === "directory",
|
|
628
|
+
message: aclFailedEntry.errorMessage || "",
|
|
629
|
+
};
|
|
630
|
+
});
|
|
631
|
+
}
|
|
632
|
+
function toBlobCpkInfo(input) {
|
|
633
|
+
return input
|
|
634
|
+
? {
|
|
635
|
+
encryptionKey: input.encryptionKey,
|
|
636
|
+
encryptionKeySha256: input.encryptionKeySha256,
|
|
637
|
+
encryptionAlgorithm: "AES256",
|
|
638
|
+
}
|
|
639
|
+
: undefined;
|
|
811
640
|
}
|
|
641
|
+
|
|
812
642
|
/**
|
|
813
|
-
*
|
|
643
|
+
* Reserved URL characters must be properly escaped for Storage services like Blob or File.
|
|
644
|
+
*
|
|
645
|
+
* ## URL encode and escape strategy for JS SDKs
|
|
646
|
+
*
|
|
647
|
+
* When customers pass a URL string into XxxClient classes constructors, the URL string may already be URL encoded or not.
|
|
648
|
+
* But before sending to Azure Storage server, the URL must be encoded. However, it's hard for a SDK to guess whether the URL
|
|
649
|
+
* string has been encoded or not. We have 2 potential strategies, and chose strategy two for the XxxClient constructors.
|
|
650
|
+
*
|
|
651
|
+
* ### Strategy One: Assume the customer URL string is not encoded, and always encode URL string in SDK.
|
|
652
|
+
*
|
|
653
|
+
* This is what legacy V2 SDK does, simple and works for most of the cases.
|
|
654
|
+
* - When customer URL string is "http://account.blob.core.windows.net/con/b:",
|
|
655
|
+
* SDK will encode it to "http://account.blob.core.windows.net/con/b%3A" and send to server. A blob named "b:" will be created.
|
|
656
|
+
* - When customer URL string is "http://account.blob.core.windows.net/con/b%3A",
|
|
657
|
+
* SDK will encode it to "http://account.blob.core.windows.net/con/b%253A" and send to server. A blob named "b%3A" will be created.
|
|
658
|
+
*
|
|
659
|
+
* But this strategy will make it not possible to create a blob with "?" in it's name. Because when customer URL string is
|
|
660
|
+
* "http://account.blob.core.windows.net/con/blob?name", the "?name" will be treated as URL paramter instead of blob name.
|
|
661
|
+
* If customer URL string is "http://account.blob.core.windows.net/con/blob%3Fname", a blob named "blob%3Fname" will be created.
|
|
662
|
+
* V2 SDK doesn't have this issue because it doesn't allow customer pass in a full URL, it accepts a separate blob name and encodeURIComponent for it.
|
|
663
|
+
* We cannot accept a SDK cannot create a blob name with "?". So we implement strategy two:
|
|
664
|
+
*
|
|
665
|
+
* ### Strategy Two: SDK doesn't assume the URL has been encoded or not. It will just escape the special characters.
|
|
666
|
+
*
|
|
667
|
+
* This is what V10 Blob Go SDK does. It accepts a URL type in Go, and call url.EscapedPath() to escape the special chars unescaped.
|
|
668
|
+
* - When customer URL string is "http://account.blob.core.windows.net/con/b:",
|
|
669
|
+
* SDK will escape ":" like "http://account.blob.core.windows.net/con/b%3A" and send to server. A blob named "b:" will be created.
|
|
670
|
+
* - When customer URL string is "http://account.blob.core.windows.net/con/b%3A",
|
|
671
|
+
* There is no special characters, so send "http://account.blob.core.windows.net/con/b%3A" to server. A blob named "b:" will be created.
|
|
672
|
+
* - When customer URL string is "http://account.blob.core.windows.net/con/b%253A",
|
|
673
|
+
* There is no special characters, so send "http://account.blob.core.windows.net/con/b%253A" to server. A blob named "b%3A" will be created.
|
|
674
|
+
*
|
|
675
|
+
* This strategy gives us flexibility to create with any special characters. But "%" will be treated as a special characters, if the URL string
|
|
676
|
+
* is not encoded, there shouldn't a "%" in the URL string, otherwise the URL is not a valid URL.
|
|
677
|
+
* If customer needs to create a blob with "%" in it's blob name, use "%25" instead of "%". Just like above 3rd sample.
|
|
678
|
+
* And following URL strings are invalid:
|
|
679
|
+
* - "http://account.blob.core.windows.net/con/b%"
|
|
680
|
+
* - "http://account.blob.core.windows.net/con/b%2"
|
|
681
|
+
* - "http://account.blob.core.windows.net/con/b%G"
|
|
682
|
+
*
|
|
683
|
+
* Another special character is "?", use "%2F" to represent a blob name with "?" in a URL string.
|
|
684
|
+
*
|
|
685
|
+
* ### Strategy for containerName, blobName or other specific XXXName parameters in methods such as `containerClient.getBlobClient(blobName)`
|
|
686
|
+
*
|
|
687
|
+
* We will apply strategy one, and call encodeURIComponent for these parameters like blobName. Because what customers passes in is a plain name instead of a URL.
|
|
688
|
+
*
|
|
689
|
+
* @see https://docs.microsoft.com/en-us/rest/api/storageservices/naming-and-referencing-containers--blobs--and-metadata
|
|
690
|
+
* @see https://docs.microsoft.com/en-us/rest/api/storageservices/naming-and-referencing-shares--directories--files--and-metadata
|
|
691
|
+
*
|
|
692
|
+
* @param url -
|
|
814
693
|
*/
|
|
815
|
-
function
|
|
816
|
-
const
|
|
817
|
-
|
|
818
|
-
|
|
819
|
-
|
|
820
|
-
|
|
821
|
-
|
|
822
|
-
|
|
694
|
+
function escapeURLPath(url) {
|
|
695
|
+
const urlParsed = coreHttp.URLBuilder.parse(url);
|
|
696
|
+
let path = urlParsed.getPath();
|
|
697
|
+
path = path || "/";
|
|
698
|
+
path = escape(path);
|
|
699
|
+
urlParsed.setPath(path);
|
|
700
|
+
return urlParsed.toString();
|
|
701
|
+
}
|
|
702
|
+
function getProxyUriFromDevConnString(connectionString) {
|
|
703
|
+
// Development Connection String
|
|
704
|
+
// https://docs.microsoft.com/en-us/azure/storage/common/storage-configure-connection-string#connect-to-the-emulator-account-using-the-well-known-account-name-and-key
|
|
705
|
+
let proxyUri = "";
|
|
706
|
+
if (connectionString.search("DevelopmentStorageProxyUri=") !== -1) {
|
|
707
|
+
// CONNECTION_STRING=UseDevelopmentStorage=true;DevelopmentStorageProxyUri=http://myProxyUri
|
|
708
|
+
const matchCredentials = connectionString.split(";");
|
|
709
|
+
for (const element of matchCredentials) {
|
|
710
|
+
if (element.trim().startsWith("DevelopmentStorageProxyUri=")) {
|
|
711
|
+
proxyUri = element.trim().match("DevelopmentStorageProxyUri=(.*)")[1];
|
|
823
712
|
}
|
|
824
713
|
}
|
|
825
714
|
}
|
|
826
|
-
return
|
|
715
|
+
return proxyUri;
|
|
716
|
+
}
|
|
717
|
+
function getValueInConnString(connectionString, argument) {
|
|
718
|
+
const elements = connectionString.split(";");
|
|
719
|
+
for (const element of elements) {
|
|
720
|
+
if (element.trim().startsWith(argument)) {
|
|
721
|
+
return element.trim().match(argument + "=(.*)")[1];
|
|
722
|
+
}
|
|
723
|
+
}
|
|
724
|
+
return "";
|
|
827
725
|
}
|
|
828
|
-
|
|
829
726
|
/**
|
|
830
|
-
*
|
|
727
|
+
* Extracts the parts of an Azure Storage account connection string.
|
|
728
|
+
*
|
|
729
|
+
* @param connectionString - Connection string.
|
|
730
|
+
* @returns String key value pairs of the storage account's url and credentials.
|
|
831
731
|
*/
|
|
832
|
-
|
|
833
|
-
|
|
834
|
-
|
|
835
|
-
|
|
836
|
-
|
|
837
|
-
|
|
838
|
-
*/
|
|
839
|
-
constructor(nextPolicy, options, factory) {
|
|
840
|
-
super(nextPolicy, options);
|
|
841
|
-
this.factory = factory;
|
|
732
|
+
function extractConnectionStringParts(connectionString) {
|
|
733
|
+
let proxyUri = "";
|
|
734
|
+
if (connectionString.startsWith("UseDevelopmentStorage=true")) {
|
|
735
|
+
// Development connection string
|
|
736
|
+
proxyUri = getProxyUriFromDevConnString(connectionString);
|
|
737
|
+
connectionString = DevelopmentConnectionString;
|
|
842
738
|
}
|
|
843
|
-
|
|
844
|
-
|
|
845
|
-
|
|
846
|
-
|
|
847
|
-
|
|
848
|
-
|
|
849
|
-
|
|
850
|
-
|
|
851
|
-
|
|
852
|
-
|
|
853
|
-
|
|
854
|
-
|
|
855
|
-
|
|
856
|
-
|
|
857
|
-
|
|
858
|
-
|
|
859
|
-
|
|
860
|
-
|
|
861
|
-
|
|
862
|
-
|
|
863
|
-
|
|
864
|
-
|
|
865
|
-
|
|
866
|
-
|
|
867
|
-
|
|
868
|
-
|
|
869
|
-
|
|
870
|
-
|
|
871
|
-
this.getCanonicalizedResourceString(request);
|
|
872
|
-
const signature = this.factory.computeHMACSHA256(stringToSign);
|
|
873
|
-
request.headers.set(HeaderConstants.AUTHORIZATION, `SharedKey ${this.factory.accountName}:${signature}`);
|
|
874
|
-
// Workaround for node-fetch which will set content-type for dfs append data operations based on Patch
|
|
875
|
-
if (typeof request.body !== "function" && !request.headers.get(HeaderConstants.CONTENT_TYPE)) {
|
|
876
|
-
request.headers.set(HeaderConstants.CONTENT_TYPE, "");
|
|
739
|
+
// Matching BlobEndpoint in the Account connection string
|
|
740
|
+
let blobEndpoint = getValueInConnString(connectionString, "BlobEndpoint");
|
|
741
|
+
// Slicing off '/' at the end if exists
|
|
742
|
+
// (The methods that use `extractConnectionStringParts` expect the url to not have `/` at the end)
|
|
743
|
+
blobEndpoint = blobEndpoint.endsWith("/") ? blobEndpoint.slice(0, -1) : blobEndpoint;
|
|
744
|
+
if (connectionString.search("DefaultEndpointsProtocol=") !== -1 &&
|
|
745
|
+
connectionString.search("AccountKey=") !== -1) {
|
|
746
|
+
// Account connection string
|
|
747
|
+
let defaultEndpointsProtocol = "";
|
|
748
|
+
let accountName = "";
|
|
749
|
+
let accountKey = Buffer.from("accountKey", "base64");
|
|
750
|
+
let endpointSuffix = "";
|
|
751
|
+
// Get account name and key
|
|
752
|
+
accountName = getValueInConnString(connectionString, "AccountName");
|
|
753
|
+
accountKey = Buffer.from(getValueInConnString(connectionString, "AccountKey"), "base64");
|
|
754
|
+
if (!blobEndpoint) {
|
|
755
|
+
// BlobEndpoint is not present in the Account connection string
|
|
756
|
+
// Can be obtained from `${defaultEndpointsProtocol}://${accountName}.blob.${endpointSuffix}`
|
|
757
|
+
defaultEndpointsProtocol = getValueInConnString(connectionString, "DefaultEndpointsProtocol");
|
|
758
|
+
const protocol = defaultEndpointsProtocol.toLowerCase();
|
|
759
|
+
if (protocol !== "https" && protocol !== "http") {
|
|
760
|
+
throw new Error("Invalid DefaultEndpointsProtocol in the provided Connection String. Expecting 'https' or 'http'");
|
|
761
|
+
}
|
|
762
|
+
endpointSuffix = getValueInConnString(connectionString, "EndpointSuffix");
|
|
763
|
+
if (!endpointSuffix) {
|
|
764
|
+
throw new Error("Invalid EndpointSuffix in the provided Connection String");
|
|
765
|
+
}
|
|
766
|
+
blobEndpoint = `${defaultEndpointsProtocol}://${accountName}.blob.${endpointSuffix}`;
|
|
877
767
|
}
|
|
878
|
-
|
|
879
|
-
|
|
880
|
-
// console.log(`[STRING TO SIGN]:${JSON.stringify(stringToSign)}`);
|
|
881
|
-
// console.log(`[KEY]: ${request.headers.get(HeaderConstants.AUTHORIZATION)}`);
|
|
882
|
-
return request;
|
|
883
|
-
}
|
|
884
|
-
/**
|
|
885
|
-
* Retrieve header value according to shared key sign rules.
|
|
886
|
-
* @see https://docs.microsoft.com/en-us/rest/api/storageservices/authenticate-with-shared-key
|
|
887
|
-
*
|
|
888
|
-
* @param request -
|
|
889
|
-
* @param headerName -
|
|
890
|
-
*/
|
|
891
|
-
getHeaderValueToSign(request, headerName) {
|
|
892
|
-
const value = request.headers.get(headerName);
|
|
893
|
-
if (!value) {
|
|
894
|
-
return "";
|
|
768
|
+
if (!accountName) {
|
|
769
|
+
throw new Error("Invalid AccountName in the provided Connection String");
|
|
895
770
|
}
|
|
896
|
-
|
|
897
|
-
|
|
898
|
-
// https://docs.microsoft.com/en-us/rest/api/storageservices/authenticate-with-shared-key
|
|
899
|
-
if (headerName === HeaderConstants.CONTENT_LENGTH && value === "0") {
|
|
900
|
-
return "";
|
|
771
|
+
else if (accountKey.length === 0) {
|
|
772
|
+
throw new Error("Invalid AccountKey in the provided Connection String");
|
|
901
773
|
}
|
|
902
|
-
return
|
|
903
|
-
|
|
904
|
-
|
|
905
|
-
|
|
906
|
-
|
|
907
|
-
|
|
908
|
-
|
|
909
|
-
* Each header may appear only once in the string.
|
|
910
|
-
* 4. Replace any linear whitespace in the header value with a single space.
|
|
911
|
-
* 5. Trim any whitespace around the colon in the header.
|
|
912
|
-
* 6. Finally, append a new-line character to each canonicalized header in the resulting list.
|
|
913
|
-
* Construct the CanonicalizedHeaders string by concatenating all headers in this list into a single string.
|
|
914
|
-
*
|
|
915
|
-
* @param request -
|
|
916
|
-
*/
|
|
917
|
-
getCanonicalizedHeadersString(request) {
|
|
918
|
-
let headersArray = request.headers.headersArray().filter((value) => {
|
|
919
|
-
return value.name.toLowerCase().startsWith(HeaderConstants.PREFIX_FOR_STORAGE);
|
|
920
|
-
});
|
|
921
|
-
headersArray.sort((a, b) => {
|
|
922
|
-
return a.name.toLowerCase().localeCompare(b.name.toLowerCase());
|
|
923
|
-
});
|
|
924
|
-
// Remove duplicate headers
|
|
925
|
-
headersArray = headersArray.filter((value, index, array) => {
|
|
926
|
-
if (index > 0 && value.name.toLowerCase() === array[index - 1].name.toLowerCase()) {
|
|
927
|
-
return false;
|
|
928
|
-
}
|
|
929
|
-
return true;
|
|
930
|
-
});
|
|
931
|
-
let canonicalizedHeadersStringToSign = "";
|
|
932
|
-
headersArray.forEach((header) => {
|
|
933
|
-
canonicalizedHeadersStringToSign += `${header.name
|
|
934
|
-
.toLowerCase()
|
|
935
|
-
.trimRight()}:${header.value.trimLeft()}\n`;
|
|
936
|
-
});
|
|
937
|
-
return canonicalizedHeadersStringToSign;
|
|
774
|
+
return {
|
|
775
|
+
kind: "AccountConnString",
|
|
776
|
+
url: blobEndpoint,
|
|
777
|
+
accountName,
|
|
778
|
+
accountKey,
|
|
779
|
+
proxyUri,
|
|
780
|
+
};
|
|
938
781
|
}
|
|
939
|
-
|
|
940
|
-
|
|
941
|
-
|
|
942
|
-
|
|
943
|
-
|
|
944
|
-
|
|
945
|
-
const path = getURLPath(request.url) || "/";
|
|
946
|
-
let canonicalizedResourceString = "";
|
|
947
|
-
canonicalizedResourceString += `/${this.factory.accountName}${path}`;
|
|
948
|
-
const queries = getURLQueries(request.url);
|
|
949
|
-
const lowercaseQueries = {};
|
|
950
|
-
if (queries) {
|
|
951
|
-
const queryKeys = [];
|
|
952
|
-
for (const key in queries) {
|
|
953
|
-
if (Object.prototype.hasOwnProperty.call(queries, key)) {
|
|
954
|
-
const lowercaseKey = key.toLowerCase();
|
|
955
|
-
lowercaseQueries[lowercaseKey] = queries[key];
|
|
956
|
-
queryKeys.push(lowercaseKey);
|
|
957
|
-
}
|
|
958
|
-
}
|
|
959
|
-
queryKeys.sort();
|
|
960
|
-
for (const key of queryKeys) {
|
|
961
|
-
canonicalizedResourceString += `\n${key}:${decodeURIComponent(lowercaseQueries[key])}`;
|
|
962
|
-
}
|
|
782
|
+
else {
|
|
783
|
+
// SAS connection string
|
|
784
|
+
const accountSas = getValueInConnString(connectionString, "SharedAccessSignature");
|
|
785
|
+
const accountName = getAccountNameFromUrl(blobEndpoint);
|
|
786
|
+
if (!blobEndpoint) {
|
|
787
|
+
throw new Error("Invalid BlobEndpoint in the provided SAS Connection String");
|
|
963
788
|
}
|
|
964
|
-
|
|
789
|
+
else if (!accountSas) {
|
|
790
|
+
throw new Error("Invalid SharedAccessSignature in the provided SAS Connection String");
|
|
791
|
+
}
|
|
792
|
+
return { kind: "SASConnString", url: blobEndpoint, accountName, accountSas };
|
|
965
793
|
}
|
|
966
794
|
}
|
|
967
|
-
|
|
968
|
-
// Copyright (c) Microsoft Corporation.
|
|
969
795
|
/**
|
|
970
|
-
*
|
|
796
|
+
* Internal escape method implemented Strategy Two mentioned in escapeURL() description.
|
|
971
797
|
*
|
|
972
|
-
*
|
|
798
|
+
* @param text -
|
|
973
799
|
*/
|
|
974
|
-
|
|
975
|
-
|
|
976
|
-
|
|
977
|
-
|
|
978
|
-
|
|
979
|
-
|
|
980
|
-
constructor(accountName, accountKey) {
|
|
981
|
-
super();
|
|
982
|
-
this.accountName = accountName;
|
|
983
|
-
this.accountKey = Buffer.from(accountKey, "base64");
|
|
984
|
-
}
|
|
985
|
-
/**
|
|
986
|
-
* Creates a StorageSharedKeyCredentialPolicy object.
|
|
987
|
-
*
|
|
988
|
-
* @param nextPolicy -
|
|
989
|
-
* @param options -
|
|
990
|
-
*/
|
|
991
|
-
create(nextPolicy, options) {
|
|
992
|
-
return new StorageSharedKeyCredentialPolicy(nextPolicy, options, this);
|
|
993
|
-
}
|
|
994
|
-
/**
|
|
995
|
-
* Generates a hash signature for an HTTP request or for a SAS.
|
|
996
|
-
*
|
|
997
|
-
* @param stringToSign -
|
|
998
|
-
*/
|
|
999
|
-
computeHMACSHA256(stringToSign) {
|
|
1000
|
-
return crypto.createHmac("sha256", this.accountKey).update(stringToSign, "utf8").digest("base64");
|
|
1001
|
-
}
|
|
800
|
+
function escape(text) {
|
|
801
|
+
return encodeURIComponent(text)
|
|
802
|
+
.replace(/%2F/g, "/") // Don't escape for "/"
|
|
803
|
+
.replace(/'/g, "%27") // Escape for "'"
|
|
804
|
+
.replace(/\+/g, "%20")
|
|
805
|
+
.replace(/%25/g, "%"); // Revert encoded "%"
|
|
1002
806
|
}
|
|
1003
|
-
|
|
1004
|
-
// Copyright (c) Microsoft Corporation.
|
|
1005
807
|
/**
|
|
1006
|
-
*
|
|
1007
|
-
*
|
|
808
|
+
* Append a string to URL path. Will remove duplicated "/" in front of the string
|
|
809
|
+
* when URL path ends with a "/".
|
|
810
|
+
*
|
|
811
|
+
* @param url - Source URL string
|
|
812
|
+
* @param name - String to be appended to URL
|
|
813
|
+
* @returns An updated URL string
|
|
1008
814
|
*/
|
|
1009
|
-
|
|
1010
|
-
|
|
1011
|
-
|
|
1012
|
-
});
|
|
815
|
+
function appendToURLPath(url, name) {
|
|
816
|
+
const urlParsed = coreHttp.URLBuilder.parse(url);
|
|
817
|
+
let path = urlParsed.getPath();
|
|
818
|
+
path = path ? (path.endsWith("/") ? `${path}${name}` : `${path}/${name}`) : name;
|
|
819
|
+
urlParsed.setPath(path);
|
|
820
|
+
const normalizedUrl = new URL(urlParsed.toString());
|
|
821
|
+
return normalizedUrl.toString();
|
|
822
|
+
}
|
|
1013
823
|
/**
|
|
1014
|
-
*
|
|
824
|
+
* Append a string to URL query.
|
|
1015
825
|
*
|
|
1016
|
-
*
|
|
1017
|
-
*
|
|
1018
|
-
*
|
|
826
|
+
* @param url - Source URL string.
|
|
827
|
+
* @param queryParts - String to be appended to the URL query.
|
|
828
|
+
* @returns An updated URL string.
|
|
1019
829
|
*/
|
|
1020
|
-
function
|
|
1021
|
-
|
|
1022
|
-
|
|
1023
|
-
|
|
1024
|
-
|
|
1025
|
-
tracingContext: (_b = options === null || options === void 0 ? void 0 : options.tracingOptions) === null || _b === void 0 ? void 0 : _b.tracingContext,
|
|
1026
|
-
};
|
|
1027
|
-
}
|
|
1028
|
-
|
|
1029
|
-
class DataLakeLeaseClient {
|
|
1030
|
-
constructor(client) {
|
|
1031
|
-
this.client = client;
|
|
1032
|
-
}
|
|
1033
|
-
get leaseId() {
|
|
1034
|
-
return this.client.leaseId;
|
|
830
|
+
function appendToURLQuery(url, queryParts) {
|
|
831
|
+
const urlParsed = coreHttp.URLBuilder.parse(url);
|
|
832
|
+
let query = urlParsed.getQuery();
|
|
833
|
+
if (query) {
|
|
834
|
+
query += "&" + queryParts;
|
|
1035
835
|
}
|
|
1036
|
-
|
|
1037
|
-
|
|
836
|
+
else {
|
|
837
|
+
query = queryParts;
|
|
1038
838
|
}
|
|
1039
|
-
|
|
1040
|
-
|
|
1041
|
-
|
|
1042
|
-
|
|
1043
|
-
|
|
1044
|
-
|
|
1045
|
-
|
|
1046
|
-
|
|
1047
|
-
|
|
1048
|
-
|
|
1049
|
-
|
|
1050
|
-
|
|
1051
|
-
|
|
1052
|
-
|
|
1053
|
-
|
|
1054
|
-
|
|
1055
|
-
|
|
1056
|
-
|
|
1057
|
-
|
|
1058
|
-
|
|
1059
|
-
|
|
1060
|
-
|
|
1061
|
-
|
|
1062
|
-
|
|
1063
|
-
|
|
1064
|
-
|
|
1065
|
-
|
|
1066
|
-
|
|
1067
|
-
|
|
1068
|
-
|
|
1069
|
-
|
|
1070
|
-
|
|
1071
|
-
|
|
839
|
+
urlParsed.setQuery(query);
|
|
840
|
+
return urlParsed.toString();
|
|
841
|
+
}
|
|
842
|
+
/**
|
|
843
|
+
* Set URL parameter name and value. If name exists in URL parameters, old value
|
|
844
|
+
* will be replaced by name key. If not provide value, the parameter will be deleted.
|
|
845
|
+
*
|
|
846
|
+
* @param url - Source URL string
|
|
847
|
+
* @param name - Parameter name
|
|
848
|
+
* @param value - Parameter value
|
|
849
|
+
* @returns An updated URL string
|
|
850
|
+
*/
|
|
851
|
+
function setURLParameter(url, name, value) {
|
|
852
|
+
const urlParsed = coreHttp.URLBuilder.parse(url);
|
|
853
|
+
urlParsed.setQueryParameter(name, value);
|
|
854
|
+
return urlParsed.toString();
|
|
855
|
+
}
|
|
856
|
+
/**
|
|
857
|
+
* Set URL host.
|
|
858
|
+
*
|
|
859
|
+
* @param url - Source URL string
|
|
860
|
+
* @param host - New host string
|
|
861
|
+
* @returns An updated URL string
|
|
862
|
+
*/
|
|
863
|
+
function setURLHost(url, host) {
|
|
864
|
+
const urlParsed = coreHttp.URLBuilder.parse(url);
|
|
865
|
+
urlParsed.setHost(host);
|
|
866
|
+
return urlParsed.toString();
|
|
867
|
+
}
|
|
868
|
+
/**
|
|
869
|
+
* Get URL path from an URL string.
|
|
870
|
+
*
|
|
871
|
+
* @param url - Source URL string
|
|
872
|
+
*/
|
|
873
|
+
function getURLPath(url) {
|
|
874
|
+
const urlParsed = coreHttp.URLBuilder.parse(url);
|
|
875
|
+
return urlParsed.getPath();
|
|
876
|
+
}
|
|
877
|
+
/**
|
|
878
|
+
* Set URL path.
|
|
879
|
+
*
|
|
880
|
+
* @param url -
|
|
881
|
+
* @param path -
|
|
882
|
+
*/
|
|
883
|
+
function setURLPath(url, path) {
|
|
884
|
+
const urlParsed = coreHttp.URLBuilder.parse(url);
|
|
885
|
+
urlParsed.setPath(path);
|
|
886
|
+
return urlParsed.toString();
|
|
887
|
+
}
|
|
888
|
+
/**
|
|
889
|
+
* Get URL scheme from an URL string.
|
|
890
|
+
*
|
|
891
|
+
* @param url - Source URL string
|
|
892
|
+
*/
|
|
893
|
+
function getURLScheme(url) {
|
|
894
|
+
const urlParsed = coreHttp.URLBuilder.parse(url);
|
|
895
|
+
return urlParsed.getScheme();
|
|
896
|
+
}
|
|
897
|
+
/**
|
|
898
|
+
* Get URL path and query from an URL string.
|
|
899
|
+
*
|
|
900
|
+
* @param url - Source URL string
|
|
901
|
+
*/
|
|
902
|
+
function getURLPathAndQuery(url) {
|
|
903
|
+
const urlParsed = coreHttp.URLBuilder.parse(url);
|
|
904
|
+
const pathString = urlParsed.getPath();
|
|
905
|
+
if (!pathString) {
|
|
906
|
+
throw new RangeError("Invalid url without valid path.");
|
|
1072
907
|
}
|
|
1073
|
-
|
|
1074
|
-
|
|
1075
|
-
|
|
1076
|
-
|
|
1077
|
-
return await this.client.releaseLease(updatedOptions);
|
|
1078
|
-
}
|
|
1079
|
-
catch (e) {
|
|
1080
|
-
span.setStatus({
|
|
1081
|
-
code: coreTracing.SpanStatusCode.ERROR,
|
|
1082
|
-
message: e.message,
|
|
1083
|
-
});
|
|
1084
|
-
throw e;
|
|
1085
|
-
}
|
|
1086
|
-
finally {
|
|
1087
|
-
span.end();
|
|
1088
|
-
}
|
|
908
|
+
let queryString = urlParsed.getQuery() || "";
|
|
909
|
+
queryString = queryString.trim();
|
|
910
|
+
if (queryString !== "") {
|
|
911
|
+
queryString = queryString.startsWith("?") ? queryString : `?${queryString}`; // Ensure query string start with '?'
|
|
1089
912
|
}
|
|
1090
|
-
|
|
1091
|
-
|
|
1092
|
-
|
|
1093
|
-
|
|
1094
|
-
|
|
1095
|
-
|
|
1096
|
-
|
|
1097
|
-
|
|
1098
|
-
|
|
1099
|
-
|
|
1100
|
-
|
|
1101
|
-
throw e;
|
|
1102
|
-
}
|
|
1103
|
-
finally {
|
|
1104
|
-
span.end();
|
|
1105
|
-
}
|
|
913
|
+
return `${pathString}${queryString}`;
|
|
914
|
+
}
|
|
915
|
+
/**
|
|
916
|
+
* Get URL query key value pairs from an URL string.
|
|
917
|
+
*
|
|
918
|
+
* @param url -
|
|
919
|
+
*/
|
|
920
|
+
function getURLQueries(url) {
|
|
921
|
+
let queryString = coreHttp.URLBuilder.parse(url).getQuery();
|
|
922
|
+
if (!queryString) {
|
|
923
|
+
return {};
|
|
1106
924
|
}
|
|
1107
|
-
|
|
1108
|
-
|
|
1109
|
-
|
|
1110
|
-
|
|
1111
|
-
|
|
1112
|
-
|
|
1113
|
-
|
|
1114
|
-
|
|
1115
|
-
|
|
1116
|
-
|
|
1117
|
-
|
|
1118
|
-
|
|
1119
|
-
|
|
1120
|
-
|
|
1121
|
-
span.end();
|
|
1122
|
-
}
|
|
925
|
+
queryString = queryString.trim();
|
|
926
|
+
queryString = queryString.startsWith("?") ? queryString.substr(1) : queryString;
|
|
927
|
+
let querySubStrings = queryString.split("&");
|
|
928
|
+
querySubStrings = querySubStrings.filter((value) => {
|
|
929
|
+
const indexOfEqual = value.indexOf("=");
|
|
930
|
+
const lastIndexOfEqual = value.lastIndexOf("=");
|
|
931
|
+
return (indexOfEqual > 0 && indexOfEqual === lastIndexOfEqual && lastIndexOfEqual < value.length - 1);
|
|
932
|
+
});
|
|
933
|
+
const queries = {};
|
|
934
|
+
for (const querySubString of querySubStrings) {
|
|
935
|
+
const splitResults = querySubString.split("=");
|
|
936
|
+
const key = splitResults[0];
|
|
937
|
+
const value = splitResults[1];
|
|
938
|
+
queries[key] = value;
|
|
1123
939
|
}
|
|
940
|
+
return queries;
|
|
1124
941
|
}
|
|
1125
|
-
|
|
1126
|
-
|
|
1127
|
-
* Copyright (c) Microsoft Corporation.
|
|
1128
|
-
* Licensed under the MIT License.
|
|
942
|
+
/**
|
|
943
|
+
* Set URL query string.
|
|
1129
944
|
*
|
|
1130
|
-
*
|
|
1131
|
-
*
|
|
945
|
+
* @param url -
|
|
946
|
+
* @param queryString -
|
|
1132
947
|
*/
|
|
1133
|
-
|
|
1134
|
-
|
|
1135
|
-
|
|
1136
|
-
|
|
1137
|
-
|
|
1138
|
-
|
|
1139
|
-
|
|
1140
|
-
|
|
1141
|
-
|
|
1142
|
-
|
|
1143
|
-
|
|
1144
|
-
|
|
1145
|
-
|
|
1146
|
-
|
|
1147
|
-
|
|
1148
|
-
|
|
1149
|
-
|
|
1150
|
-
|
|
1151
|
-
|
|
948
|
+
function setURLQueries(url, queryString) {
|
|
949
|
+
const urlParsed = coreHttp.URLBuilder.parse(url);
|
|
950
|
+
urlParsed.setQuery(queryString);
|
|
951
|
+
return urlParsed.toString();
|
|
952
|
+
}
|
|
953
|
+
/**
|
|
954
|
+
* Rounds a date off to seconds.
|
|
955
|
+
*
|
|
956
|
+
* @param date -
|
|
957
|
+
* @param withMilliseconds - If true, YYYY-MM-DDThh:mm:ss.fffffffZ will be returned;
|
|
958
|
+
* If false, YYYY-MM-DDThh:mm:ssZ will be returned.
|
|
959
|
+
* @returns Date string in ISO8061 format, with or without 7 milliseconds component
|
|
960
|
+
*/
|
|
961
|
+
function truncatedISO8061Date(date, withMilliseconds = true) {
|
|
962
|
+
// Date.toISOString() will return like "2018-10-29T06:34:36.139Z"
|
|
963
|
+
const dateString = date.toISOString();
|
|
964
|
+
return withMilliseconds
|
|
965
|
+
? dateString.substring(0, dateString.length - 1) + "0000" + "Z"
|
|
966
|
+
: dateString.substring(0, dateString.length - 5) + "Z";
|
|
967
|
+
}
|
|
968
|
+
/**
|
|
969
|
+
* Base64 encode.
|
|
970
|
+
*
|
|
971
|
+
* @param content -
|
|
972
|
+
*/
|
|
973
|
+
function base64encode(content) {
|
|
974
|
+
return !coreHttp.isNode ? btoa(content) : Buffer.from(content).toString("base64");
|
|
975
|
+
}
|
|
976
|
+
/**
|
|
977
|
+
* Delay specified time interval.
|
|
978
|
+
*
|
|
979
|
+
* @param timeInMs -
|
|
980
|
+
* @param aborter -
|
|
981
|
+
* @param abortError -
|
|
982
|
+
*/
|
|
983
|
+
async function delay(timeInMs, aborter, abortError) {
|
|
984
|
+
return new Promise((resolve, reject) => {
|
|
985
|
+
/* eslint-disable-next-line prefer-const*/
|
|
986
|
+
let timeout;
|
|
987
|
+
const abortHandler = () => {
|
|
988
|
+
if (timeout !== undefined) {
|
|
989
|
+
clearTimeout(timeout);
|
|
1152
990
|
}
|
|
1153
|
-
|
|
1154
|
-
|
|
1155
|
-
|
|
1156
|
-
|
|
1157
|
-
|
|
1158
|
-
type: {
|
|
1159
|
-
name: "Composite",
|
|
1160
|
-
className: "FileSystem",
|
|
1161
|
-
modelProperties: {
|
|
1162
|
-
name: {
|
|
1163
|
-
serializedName: "name",
|
|
1164
|
-
xmlName: "name",
|
|
1165
|
-
type: {
|
|
1166
|
-
name: "String"
|
|
1167
|
-
}
|
|
1168
|
-
},
|
|
1169
|
-
lastModified: {
|
|
1170
|
-
serializedName: "lastModified",
|
|
1171
|
-
xmlName: "lastModified",
|
|
1172
|
-
type: {
|
|
1173
|
-
name: "DateTimeRfc1123"
|
|
1174
|
-
}
|
|
1175
|
-
},
|
|
1176
|
-
etag: {
|
|
1177
|
-
serializedName: "eTag",
|
|
1178
|
-
xmlName: "eTag",
|
|
1179
|
-
type: {
|
|
1180
|
-
name: "String"
|
|
1181
|
-
}
|
|
991
|
+
reject(abortError);
|
|
992
|
+
};
|
|
993
|
+
const resolveHandler = () => {
|
|
994
|
+
if (aborter !== undefined) {
|
|
995
|
+
aborter.removeEventListener("abort", abortHandler);
|
|
1182
996
|
}
|
|
997
|
+
resolve();
|
|
998
|
+
};
|
|
999
|
+
timeout = setTimeout(resolveHandler, timeInMs);
|
|
1000
|
+
if (aborter !== undefined) {
|
|
1001
|
+
aborter.addEventListener("abort", abortHandler);
|
|
1183
1002
|
}
|
|
1184
|
-
}
|
|
1185
|
-
}
|
|
1186
|
-
|
|
1187
|
-
|
|
1188
|
-
|
|
1189
|
-
|
|
1190
|
-
|
|
1191
|
-
|
|
1192
|
-
|
|
1193
|
-
|
|
1194
|
-
|
|
1195
|
-
|
|
1196
|
-
|
|
1197
|
-
|
|
1198
|
-
|
|
1199
|
-
|
|
1200
|
-
|
|
1201
|
-
|
|
1202
|
-
|
|
1203
|
-
|
|
1204
|
-
|
|
1205
|
-
|
|
1206
|
-
|
|
1003
|
+
});
|
|
1004
|
+
}
|
|
1005
|
+
/**
|
|
1006
|
+
* If two strings are equal when compared case insensitive.
|
|
1007
|
+
*
|
|
1008
|
+
* @param str1 -
|
|
1009
|
+
* @param str2 -
|
|
1010
|
+
*/
|
|
1011
|
+
function iEqual(str1, str2) {
|
|
1012
|
+
return str1.toLocaleLowerCase() === str2.toLocaleLowerCase();
|
|
1013
|
+
}
|
|
1014
|
+
/**
|
|
1015
|
+
* Extracts account name from the blobEndpointUrl
|
|
1016
|
+
* @param blobEndpointUrl - blobEndpointUrl to extract the account name from
|
|
1017
|
+
* @returns account name
|
|
1018
|
+
*/
|
|
1019
|
+
function getAccountNameFromUrl(blobEndpointUrl) {
|
|
1020
|
+
const parsedUrl = coreHttp.URLBuilder.parse(blobEndpointUrl);
|
|
1021
|
+
let accountName;
|
|
1022
|
+
try {
|
|
1023
|
+
if (parsedUrl.getHost().split(".")[1] === "blob") {
|
|
1024
|
+
// `${defaultEndpointsProtocol}://${accountName}.blob.${endpointSuffix}`;
|
|
1025
|
+
accountName = parsedUrl.getHost().split(".")[0];
|
|
1026
|
+
}
|
|
1027
|
+
else if (isIpEndpointStyle(parsedUrl)) {
|
|
1028
|
+
// IPv4/IPv6 address hosts... Example - http://192.0.0.10:10001/devstoreaccount1/
|
|
1029
|
+
// Single word domain without a [dot] in the endpoint... Example - http://localhost:10001/devstoreaccount1/
|
|
1030
|
+
// .getPath() -> /devstoreaccount1/
|
|
1031
|
+
accountName = parsedUrl.getPath().split("/")[1];
|
|
1032
|
+
}
|
|
1033
|
+
else {
|
|
1034
|
+
// Custom domain case: "https://customdomain.com/containername/blob".
|
|
1035
|
+
accountName = "";
|
|
1207
1036
|
}
|
|
1037
|
+
return accountName;
|
|
1208
1038
|
}
|
|
1209
|
-
|
|
1210
|
-
|
|
1211
|
-
|
|
1212
|
-
|
|
1213
|
-
|
|
1214
|
-
|
|
1215
|
-
|
|
1216
|
-
|
|
1217
|
-
|
|
1218
|
-
|
|
1219
|
-
|
|
1220
|
-
|
|
1221
|
-
|
|
1222
|
-
|
|
1223
|
-
|
|
1224
|
-
|
|
1225
|
-
|
|
1226
|
-
|
|
1227
|
-
|
|
1228
|
-
|
|
1229
|
-
|
|
1039
|
+
catch (error) {
|
|
1040
|
+
throw new Error("Unable to extract accountName with provided information.");
|
|
1041
|
+
}
|
|
1042
|
+
}
|
|
1043
|
+
function isIpEndpointStyle(parsedUrl) {
|
|
1044
|
+
if (parsedUrl.getHost() === undefined) {
|
|
1045
|
+
return false;
|
|
1046
|
+
}
|
|
1047
|
+
const host = parsedUrl.getHost() + (parsedUrl.getPort() === undefined ? "" : ":" + parsedUrl.getPort());
|
|
1048
|
+
// Case 1: Ipv6, use a broad regex to find out candidates whose host contains two ':'.
|
|
1049
|
+
// Case 2: localhost(:port), use broad regex to match port part.
|
|
1050
|
+
// Case 3: Ipv4, use broad regex which just check if host contains Ipv4.
|
|
1051
|
+
// For valid host please refer to https://man7.org/linux/man-pages/man7/hostname.7.html.
|
|
1052
|
+
return (/^.*:.*:.*$|^localhost(:[0-9]+)?$|^(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])(\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])){3}(:[0-9]+)?$/.test(host) ||
|
|
1053
|
+
(parsedUrl.getPort() !== undefined && PathStylePorts.includes(parsedUrl.getPort())));
|
|
1054
|
+
}
|
|
1055
|
+
const BugTimeBeginningInMS = 13322188800000;
|
|
1056
|
+
/**
|
|
1057
|
+
* This is to convert a Windows File Time ticks to a Date object.
|
|
1058
|
+
*/
|
|
1059
|
+
function windowsFileTimeTicksToTime(timeNumber) {
|
|
1060
|
+
if (!timeNumber)
|
|
1061
|
+
return undefined;
|
|
1062
|
+
const timeNumberInternal = parseInt(timeNumber);
|
|
1063
|
+
if (timeNumberInternal === 0)
|
|
1064
|
+
return undefined;
|
|
1065
|
+
// A windows file time is a 64-bit value that represents the number of 100-nanosecond intervals that have elapsed
|
|
1066
|
+
// since 12:00 A.M. January 1, 1601 Coordinated Universal Time (UTC).
|
|
1067
|
+
// Date accepts a value that represents miliseconds from 12:00 A.M. January 1, 1970
|
|
1068
|
+
// Here should correct the year number after converting.
|
|
1069
|
+
const timeNumerInMs = timeNumberInternal / 10000;
|
|
1070
|
+
const date = new Date(timeNumerInMs);
|
|
1071
|
+
// When initializing date from a miliseconds number the day after 2023-03-01 is still 2023-03-01.
|
|
1072
|
+
// For example, 13322188799999 is 2023-03-01T23:59:59.999Z, while 13322188800000 is 2023-03-01T00:00:00.000Z
|
|
1073
|
+
// Here is to work around the bug.
|
|
1074
|
+
if (timeNumerInMs >= BugTimeBeginningInMS) {
|
|
1075
|
+
date.setUTCDate(date.getUTCDate() + 1);
|
|
1076
|
+
}
|
|
1077
|
+
date.setUTCFullYear(date.getUTCFullYear() - 369);
|
|
1078
|
+
return date;
|
|
1079
|
+
}
|
|
1080
|
+
function ensureCpkIfSpecified(cpk, isHttps) {
|
|
1081
|
+
if (cpk && !isHttps) {
|
|
1082
|
+
throw new RangeError("Customer-provided encryption key must be used over HTTPS.");
|
|
1083
|
+
}
|
|
1084
|
+
if (cpk && !cpk.encryptionAlgorithm) {
|
|
1085
|
+
cpk.encryptionAlgorithm = EncryptionAlgorithmAES25;
|
|
1086
|
+
}
|
|
1087
|
+
}
|
|
1088
|
+
/**
|
|
1089
|
+
* Escape the file or directory name but keep path separator ('/').
|
|
1090
|
+
*/
|
|
1091
|
+
function EscapePath(pathName) {
|
|
1092
|
+
const split = pathName.split("/");
|
|
1093
|
+
for (let i = 0; i < split.length; i++) {
|
|
1094
|
+
split[i] = encodeURIComponent(split[i]);
|
|
1095
|
+
}
|
|
1096
|
+
return split.join("/");
|
|
1097
|
+
}
|
|
1098
|
+
function ParseHeaderValue(rawResponse, headerName) {
|
|
1099
|
+
if (rawResponse._response) {
|
|
1100
|
+
const headers = rawResponse._response.headers;
|
|
1101
|
+
if (headers) {
|
|
1102
|
+
return headers.get(headerName);
|
|
1230
1103
|
}
|
|
1231
1104
|
}
|
|
1232
|
-
|
|
1233
|
-
|
|
1234
|
-
|
|
1235
|
-
|
|
1236
|
-
|
|
1237
|
-
|
|
1238
|
-
|
|
1239
|
-
|
|
1240
|
-
|
|
1241
|
-
|
|
1242
|
-
|
|
1243
|
-
|
|
1244
|
-
|
|
1245
|
-
|
|
1246
|
-
|
|
1247
|
-
|
|
1248
|
-
|
|
1249
|
-
|
|
1250
|
-
|
|
1251
|
-
|
|
1252
|
-
|
|
1105
|
+
return undefined;
|
|
1106
|
+
}
|
|
1107
|
+
/**
|
|
1108
|
+
* Parse extra properties values from headers in raw response.
|
|
1109
|
+
*/
|
|
1110
|
+
function ParsePathGetPropertiesExtraHeaderValues(rawResponse) {
|
|
1111
|
+
var _a;
|
|
1112
|
+
const response = rawResponse;
|
|
1113
|
+
response.encryptionContext = ParseHeaderValue(rawResponse, "x-ms-encryption-context");
|
|
1114
|
+
response.owner = ParseHeaderValue(rawResponse, "x-ms-owner");
|
|
1115
|
+
response.group = ParseHeaderValue(rawResponse, "x-ms-group");
|
|
1116
|
+
response.permissions = toPermissions(ParseHeaderValue(rawResponse, "x-ms-permissions"));
|
|
1117
|
+
if ((_a = response._response) === null || _a === void 0 ? void 0 : _a.parsedHeaders) {
|
|
1118
|
+
response._response.parsedHeaders.encryptionContext = response.encryptionContext;
|
|
1119
|
+
response._response.parsedHeaders.owner = response.owner;
|
|
1120
|
+
response._response.parsedHeaders.group = response.group;
|
|
1121
|
+
response._response.parsedHeaders.permissions = response.permissions;
|
|
1122
|
+
}
|
|
1123
|
+
return response;
|
|
1124
|
+
}
|
|
1125
|
+
|
|
1126
|
+
/**
|
|
1127
|
+
* StorageSharedKeyCredentialPolicy is a policy used to sign HTTP request with a shared key.
|
|
1128
|
+
*/
|
|
1129
|
+
class StorageSharedKeyCredentialPolicy extends CredentialPolicy {
|
|
1130
|
+
/**
|
|
1131
|
+
* Creates an instance of StorageSharedKeyCredentialPolicy.
|
|
1132
|
+
* @param nextPolicy -
|
|
1133
|
+
* @param options -
|
|
1134
|
+
* @param factory -
|
|
1135
|
+
*/
|
|
1136
|
+
constructor(nextPolicy, options, factory) {
|
|
1137
|
+
super(nextPolicy, options);
|
|
1138
|
+
this.factory = factory;
|
|
1139
|
+
}
|
|
1140
|
+
/**
|
|
1141
|
+
* Signs request.
|
|
1142
|
+
*
|
|
1143
|
+
* @param request -
|
|
1144
|
+
*/
|
|
1145
|
+
signRequest(request) {
|
|
1146
|
+
request.headers.set(HeaderConstants.X_MS_DATE, new Date().toUTCString());
|
|
1147
|
+
if (request.body &&
|
|
1148
|
+
(typeof request.body === "string" || request.body !== undefined) &&
|
|
1149
|
+
request.body.length > 0) {
|
|
1150
|
+
request.headers.set(HeaderConstants.CONTENT_LENGTH, Buffer.byteLength(request.body));
|
|
1151
|
+
}
|
|
1152
|
+
const stringToSign = [
|
|
1153
|
+
request.method.toUpperCase(),
|
|
1154
|
+
this.getHeaderValueToSign(request, HeaderConstants.CONTENT_LANGUAGE),
|
|
1155
|
+
this.getHeaderValueToSign(request, HeaderConstants.CONTENT_ENCODING),
|
|
1156
|
+
this.getHeaderValueToSign(request, HeaderConstants.CONTENT_LENGTH),
|
|
1157
|
+
this.getHeaderValueToSign(request, HeaderConstants.CONTENT_MD5),
|
|
1158
|
+
this.getHeaderValueToSign(request, HeaderConstants.CONTENT_TYPE),
|
|
1159
|
+
this.getHeaderValueToSign(request, HeaderConstants.DATE),
|
|
1160
|
+
this.getHeaderValueToSign(request, HeaderConstants.IF_MODIFIED_SINCE),
|
|
1161
|
+
this.getHeaderValueToSign(request, HeaderConstants.IF_MATCH),
|
|
1162
|
+
this.getHeaderValueToSign(request, HeaderConstants.IF_NONE_MATCH),
|
|
1163
|
+
this.getHeaderValueToSign(request, HeaderConstants.IF_UNMODIFIED_SINCE),
|
|
1164
|
+
this.getHeaderValueToSign(request, HeaderConstants.RANGE),
|
|
1165
|
+
].join("\n") +
|
|
1166
|
+
"\n" +
|
|
1167
|
+
this.getCanonicalizedHeadersString(request) +
|
|
1168
|
+
this.getCanonicalizedResourceString(request);
|
|
1169
|
+
const signature = this.factory.computeHMACSHA256(stringToSign);
|
|
1170
|
+
request.headers.set(HeaderConstants.AUTHORIZATION, `SharedKey ${this.factory.accountName}:${signature}`);
|
|
1171
|
+
// Workaround for node-fetch which will set content-type for dfs append data operations based on Patch
|
|
1172
|
+
if (typeof request.body !== "function" && !request.headers.get(HeaderConstants.CONTENT_TYPE)) {
|
|
1173
|
+
request.headers.set(HeaderConstants.CONTENT_TYPE, "");
|
|
1253
1174
|
}
|
|
1175
|
+
// console.log(`[URL]:${request.url}`);
|
|
1176
|
+
// console.log(`[HEADERS]:${request.headers.toString()}`);
|
|
1177
|
+
// console.log(`[STRING TO SIGN]:${JSON.stringify(stringToSign)}`);
|
|
1178
|
+
// console.log(`[KEY]: ${request.headers.get(HeaderConstants.AUTHORIZATION)}`);
|
|
1179
|
+
return request;
|
|
1254
1180
|
}
|
|
1255
|
-
|
|
1256
|
-
|
|
1257
|
-
|
|
1258
|
-
|
|
1259
|
-
|
|
1260
|
-
|
|
1261
|
-
|
|
1262
|
-
|
|
1263
|
-
|
|
1264
|
-
|
|
1265
|
-
|
|
1266
|
-
|
|
1267
|
-
|
|
1268
|
-
|
|
1269
|
-
|
|
1270
|
-
|
|
1271
|
-
|
|
1272
|
-
type: {
|
|
1273
|
-
name: "Boolean"
|
|
1274
|
-
}
|
|
1275
|
-
},
|
|
1276
|
-
lastModified: {
|
|
1277
|
-
serializedName: "lastModified",
|
|
1278
|
-
xmlName: "lastModified",
|
|
1279
|
-
type: {
|
|
1280
|
-
name: "DateTimeRfc1123"
|
|
1281
|
-
}
|
|
1282
|
-
},
|
|
1283
|
-
etag: {
|
|
1284
|
-
serializedName: "eTag",
|
|
1285
|
-
xmlName: "eTag",
|
|
1286
|
-
type: {
|
|
1287
|
-
name: "String"
|
|
1288
|
-
}
|
|
1289
|
-
},
|
|
1290
|
-
contentLength: {
|
|
1291
|
-
serializedName: "contentLength",
|
|
1292
|
-
xmlName: "contentLength",
|
|
1293
|
-
type: {
|
|
1294
|
-
name: "Number"
|
|
1295
|
-
}
|
|
1296
|
-
},
|
|
1297
|
-
owner: {
|
|
1298
|
-
serializedName: "owner",
|
|
1299
|
-
xmlName: "owner",
|
|
1300
|
-
type: {
|
|
1301
|
-
name: "String"
|
|
1302
|
-
}
|
|
1303
|
-
},
|
|
1304
|
-
group: {
|
|
1305
|
-
serializedName: "group",
|
|
1306
|
-
xmlName: "group",
|
|
1307
|
-
type: {
|
|
1308
|
-
name: "String"
|
|
1309
|
-
}
|
|
1310
|
-
},
|
|
1311
|
-
permissions: {
|
|
1312
|
-
serializedName: "permissions",
|
|
1313
|
-
xmlName: "permissions",
|
|
1314
|
-
type: {
|
|
1315
|
-
name: "String"
|
|
1316
|
-
}
|
|
1317
|
-
},
|
|
1318
|
-
encryptionScope: {
|
|
1319
|
-
serializedName: "EncryptionScope",
|
|
1320
|
-
xmlName: "EncryptionScope",
|
|
1321
|
-
type: {
|
|
1322
|
-
name: "String"
|
|
1323
|
-
}
|
|
1324
|
-
},
|
|
1325
|
-
creationTime: {
|
|
1326
|
-
serializedName: "creationTime",
|
|
1327
|
-
xmlName: "creationTime",
|
|
1328
|
-
type: {
|
|
1329
|
-
name: "String"
|
|
1330
|
-
}
|
|
1331
|
-
},
|
|
1332
|
-
expiryTime: {
|
|
1333
|
-
serializedName: "expiryTime",
|
|
1334
|
-
xmlName: "expiryTime",
|
|
1335
|
-
type: {
|
|
1336
|
-
name: "String"
|
|
1337
|
-
}
|
|
1338
|
-
},
|
|
1339
|
-
encryptionContext: {
|
|
1340
|
-
serializedName: "EncryptionContext",
|
|
1341
|
-
xmlName: "EncryptionContext",
|
|
1342
|
-
type: {
|
|
1343
|
-
name: "String"
|
|
1344
|
-
}
|
|
1345
|
-
}
|
|
1181
|
+
/**
|
|
1182
|
+
* Retrieve header value according to shared key sign rules.
|
|
1183
|
+
* @see https://docs.microsoft.com/en-us/rest/api/storageservices/authenticate-with-shared-key
|
|
1184
|
+
*
|
|
1185
|
+
* @param request -
|
|
1186
|
+
* @param headerName -
|
|
1187
|
+
*/
|
|
1188
|
+
getHeaderValueToSign(request, headerName) {
|
|
1189
|
+
const value = request.headers.get(headerName);
|
|
1190
|
+
if (!value) {
|
|
1191
|
+
return "";
|
|
1192
|
+
}
|
|
1193
|
+
// When using version 2015-02-21 or later, if Content-Length is zero, then
|
|
1194
|
+
// set the Content-Length part of the StringToSign to an empty string.
|
|
1195
|
+
// https://docs.microsoft.com/en-us/rest/api/storageservices/authenticate-with-shared-key
|
|
1196
|
+
if (headerName === HeaderConstants.CONTENT_LENGTH && value === "0") {
|
|
1197
|
+
return "";
|
|
1346
1198
|
}
|
|
1199
|
+
return value;
|
|
1347
1200
|
}
|
|
1348
|
-
|
|
1349
|
-
|
|
1350
|
-
|
|
1351
|
-
|
|
1352
|
-
|
|
1353
|
-
|
|
1354
|
-
|
|
1355
|
-
|
|
1356
|
-
|
|
1357
|
-
|
|
1358
|
-
|
|
1359
|
-
|
|
1360
|
-
|
|
1361
|
-
|
|
1362
|
-
|
|
1363
|
-
|
|
1364
|
-
|
|
1365
|
-
|
|
1366
|
-
|
|
1367
|
-
|
|
1368
|
-
|
|
1369
|
-
|
|
1370
|
-
|
|
1371
|
-
|
|
1372
|
-
|
|
1373
|
-
|
|
1374
|
-
|
|
1375
|
-
|
|
1376
|
-
|
|
1377
|
-
|
|
1378
|
-
|
|
1379
|
-
}
|
|
1380
|
-
|
|
1381
|
-
|
|
1382
|
-
|
|
1383
|
-
|
|
1384
|
-
|
|
1385
|
-
|
|
1386
|
-
|
|
1387
|
-
|
|
1388
|
-
|
|
1389
|
-
|
|
1390
|
-
|
|
1391
|
-
|
|
1392
|
-
|
|
1393
|
-
|
|
1394
|
-
|
|
1395
|
-
|
|
1396
|
-
|
|
1397
|
-
|
|
1398
|
-
|
|
1399
|
-
|
|
1400
|
-
|
|
1401
|
-
},
|
|
1402
|
-
segment: {
|
|
1403
|
-
serializedName: "Segment",
|
|
1404
|
-
xmlName: "Blobs",
|
|
1405
|
-
type: {
|
|
1406
|
-
name: "Composite",
|
|
1407
|
-
className: "BlobHierarchyListSegment"
|
|
1408
|
-
}
|
|
1409
|
-
},
|
|
1410
|
-
nextMarker: {
|
|
1411
|
-
serializedName: "NextMarker",
|
|
1412
|
-
xmlName: "NextMarker",
|
|
1413
|
-
type: {
|
|
1414
|
-
name: "String"
|
|
1201
|
+
/**
|
|
1202
|
+
* To construct the CanonicalizedHeaders portion of the signature string, follow these steps:
|
|
1203
|
+
* 1. Retrieve all headers for the resource that begin with x-ms-, including the x-ms-date header.
|
|
1204
|
+
* 2. Convert each HTTP header name to lowercase.
|
|
1205
|
+
* 3. Sort the headers lexicographically by header name, in ascending order.
|
|
1206
|
+
* Each header may appear only once in the string.
|
|
1207
|
+
* 4. Replace any linear whitespace in the header value with a single space.
|
|
1208
|
+
* 5. Trim any whitespace around the colon in the header.
|
|
1209
|
+
* 6. Finally, append a new-line character to each canonicalized header in the resulting list.
|
|
1210
|
+
* Construct the CanonicalizedHeaders string by concatenating all headers in this list into a single string.
|
|
1211
|
+
*
|
|
1212
|
+
* @param request -
|
|
1213
|
+
*/
|
|
1214
|
+
getCanonicalizedHeadersString(request) {
|
|
1215
|
+
let headersArray = request.headers.headersArray().filter((value) => {
|
|
1216
|
+
return value.name.toLowerCase().startsWith(HeaderConstants.PREFIX_FOR_STORAGE);
|
|
1217
|
+
});
|
|
1218
|
+
headersArray.sort((a, b) => {
|
|
1219
|
+
return a.name.toLowerCase().localeCompare(b.name.toLowerCase());
|
|
1220
|
+
});
|
|
1221
|
+
// Remove duplicate headers
|
|
1222
|
+
headersArray = headersArray.filter((value, index, array) => {
|
|
1223
|
+
if (index > 0 && value.name.toLowerCase() === array[index - 1].name.toLowerCase()) {
|
|
1224
|
+
return false;
|
|
1225
|
+
}
|
|
1226
|
+
return true;
|
|
1227
|
+
});
|
|
1228
|
+
let canonicalizedHeadersStringToSign = "";
|
|
1229
|
+
headersArray.forEach((header) => {
|
|
1230
|
+
canonicalizedHeadersStringToSign += `${header.name
|
|
1231
|
+
.toLowerCase()
|
|
1232
|
+
.trimRight()}:${header.value.trimLeft()}\n`;
|
|
1233
|
+
});
|
|
1234
|
+
return canonicalizedHeadersStringToSign;
|
|
1235
|
+
}
|
|
1236
|
+
/**
|
|
1237
|
+
* Retrieves the webResource canonicalized resource string.
|
|
1238
|
+
*
|
|
1239
|
+
* @param request -
|
|
1240
|
+
*/
|
|
1241
|
+
getCanonicalizedResourceString(request) {
|
|
1242
|
+
const path = getURLPath(request.url) || "/";
|
|
1243
|
+
let canonicalizedResourceString = "";
|
|
1244
|
+
canonicalizedResourceString += `/${this.factory.accountName}${path}`;
|
|
1245
|
+
const queries = getURLQueries(request.url);
|
|
1246
|
+
const lowercaseQueries = {};
|
|
1247
|
+
if (queries) {
|
|
1248
|
+
const queryKeys = [];
|
|
1249
|
+
for (const key in queries) {
|
|
1250
|
+
if (Object.prototype.hasOwnProperty.call(queries, key)) {
|
|
1251
|
+
const lowercaseKey = key.toLowerCase();
|
|
1252
|
+
lowercaseQueries[lowercaseKey] = queries[key];
|
|
1253
|
+
queryKeys.push(lowercaseKey);
|
|
1415
1254
|
}
|
|
1416
1255
|
}
|
|
1256
|
+
queryKeys.sort();
|
|
1257
|
+
for (const key of queryKeys) {
|
|
1258
|
+
canonicalizedResourceString += `\n${key}:${decodeURIComponent(lowercaseQueries[key])}`;
|
|
1259
|
+
}
|
|
1417
1260
|
}
|
|
1261
|
+
return canonicalizedResourceString;
|
|
1418
1262
|
}
|
|
1419
|
-
}
|
|
1420
|
-
|
|
1421
|
-
|
|
1422
|
-
|
|
1423
|
-
|
|
1424
|
-
|
|
1425
|
-
|
|
1426
|
-
|
|
1427
|
-
|
|
1428
|
-
|
|
1429
|
-
|
|
1430
|
-
|
|
1431
|
-
|
|
1432
|
-
|
|
1433
|
-
|
|
1434
|
-
|
|
1435
|
-
|
|
1436
|
-
|
|
1437
|
-
|
|
1438
|
-
|
|
1439
|
-
|
|
1440
|
-
|
|
1441
|
-
|
|
1442
|
-
|
|
1443
|
-
|
|
1444
|
-
|
|
1445
|
-
|
|
1263
|
+
}
|
|
1264
|
+
|
|
1265
|
+
// Copyright (c) Microsoft Corporation.
|
|
1266
|
+
/**
|
|
1267
|
+
* ONLY AVAILABLE IN NODE.JS RUNTIME.
|
|
1268
|
+
*
|
|
1269
|
+
* StorageSharedKeyCredential for account key authorization of Azure Storage service.
|
|
1270
|
+
*/
|
|
1271
|
+
class StorageSharedKeyCredential extends Credential {
|
|
1272
|
+
/**
|
|
1273
|
+
* Creates an instance of StorageSharedKeyCredential.
|
|
1274
|
+
* @param accountName -
|
|
1275
|
+
* @param accountKey -
|
|
1276
|
+
*/
|
|
1277
|
+
constructor(accountName, accountKey) {
|
|
1278
|
+
super();
|
|
1279
|
+
this.accountName = accountName;
|
|
1280
|
+
this.accountKey = Buffer.from(accountKey, "base64");
|
|
1281
|
+
}
|
|
1282
|
+
/**
|
|
1283
|
+
* Creates a StorageSharedKeyCredentialPolicy object.
|
|
1284
|
+
*
|
|
1285
|
+
* @param nextPolicy -
|
|
1286
|
+
* @param options -
|
|
1287
|
+
*/
|
|
1288
|
+
create(nextPolicy, options) {
|
|
1289
|
+
return new StorageSharedKeyCredentialPolicy(nextPolicy, options, this);
|
|
1290
|
+
}
|
|
1291
|
+
/**
|
|
1292
|
+
* Generates a hash signature for an HTTP request or for a SAS.
|
|
1293
|
+
*
|
|
1294
|
+
* @param stringToSign -
|
|
1295
|
+
*/
|
|
1296
|
+
computeHMACSHA256(stringToSign) {
|
|
1297
|
+
return crypto.createHmac("sha256", this.accountKey).update(stringToSign, "utf8").digest("base64");
|
|
1298
|
+
}
|
|
1299
|
+
}
|
|
1300
|
+
|
|
1301
|
+
// Copyright (c) Microsoft Corporation.
|
|
1302
|
+
/**
|
|
1303
|
+
* Creates a span using the global tracer.
|
|
1304
|
+
* @internal
|
|
1305
|
+
*/
|
|
1306
|
+
const createSpan = coreTracing.createSpanFunction({
|
|
1307
|
+
packagePrefix: "Azure.Storage.DataLake",
|
|
1308
|
+
namespace: "Microsoft.Storage",
|
|
1309
|
+
});
|
|
1310
|
+
/**
|
|
1311
|
+
* @internal
|
|
1312
|
+
*
|
|
1313
|
+
* Adapt the tracing options from OperationOptions to what they need to be for
|
|
1314
|
+
* RequestOptionsBase (when we update to later OpenTelemetry versions this is now
|
|
1315
|
+
* two separate fields, not just one).
|
|
1316
|
+
*/
|
|
1317
|
+
function convertTracingToRequestOptionsBase(options) {
|
|
1318
|
+
var _a, _b;
|
|
1319
|
+
return {
|
|
1320
|
+
// By passing spanOptions if they exist at runtime, we're backwards compatible with @azure/core-tracing@preview.13 and earlier.
|
|
1321
|
+
spanOptions: (_a = options === null || options === void 0 ? void 0 : options.tracingOptions) === null || _a === void 0 ? void 0 : _a.spanOptions,
|
|
1322
|
+
tracingContext: (_b = options === null || options === void 0 ? void 0 : options.tracingOptions) === null || _b === void 0 ? void 0 : _b.tracingContext,
|
|
1323
|
+
};
|
|
1324
|
+
}
|
|
1325
|
+
|
|
1326
|
+
class DataLakeLeaseClient {
|
|
1327
|
+
constructor(client) {
|
|
1328
|
+
this.client = client;
|
|
1329
|
+
}
|
|
1330
|
+
get leaseId() {
|
|
1331
|
+
return this.client.leaseId;
|
|
1332
|
+
}
|
|
1333
|
+
get url() {
|
|
1334
|
+
return this.client.url;
|
|
1335
|
+
}
|
|
1336
|
+
async acquireLease(duration, options = {}) {
|
|
1337
|
+
options.conditions = options.conditions || {};
|
|
1338
|
+
const { span, updatedOptions } = createSpan("DataLakeLeaseClient-acquireLease", options);
|
|
1339
|
+
try {
|
|
1340
|
+
return await this.client.acquireLease(duration, updatedOptions);
|
|
1341
|
+
}
|
|
1342
|
+
catch (e) {
|
|
1343
|
+
span.setStatus({
|
|
1344
|
+
code: coreTracing.SpanStatusCode.ERROR,
|
|
1345
|
+
message: e.message,
|
|
1346
|
+
});
|
|
1347
|
+
throw e;
|
|
1348
|
+
}
|
|
1349
|
+
finally {
|
|
1350
|
+
span.end();
|
|
1351
|
+
}
|
|
1352
|
+
}
|
|
1353
|
+
async changeLease(proposedLeaseId, options = {}) {
|
|
1354
|
+
options.conditions = options.conditions || {};
|
|
1355
|
+
const { span, updatedOptions } = createSpan("DataLakeLeaseClient-changeLease", options);
|
|
1356
|
+
try {
|
|
1357
|
+
return await this.client.changeLease(proposedLeaseId, updatedOptions);
|
|
1358
|
+
}
|
|
1359
|
+
catch (e) {
|
|
1360
|
+
span.setStatus({
|
|
1361
|
+
code: coreTracing.SpanStatusCode.ERROR,
|
|
1362
|
+
message: e.message,
|
|
1363
|
+
});
|
|
1364
|
+
throw e;
|
|
1365
|
+
}
|
|
1366
|
+
finally {
|
|
1367
|
+
span.end();
|
|
1368
|
+
}
|
|
1369
|
+
}
|
|
1370
|
+
async releaseLease(options = {}) {
|
|
1371
|
+
options.conditions = options.conditions || {};
|
|
1372
|
+
const { span, updatedOptions } = createSpan("DataLakeLeaseClient-releaseLease", options);
|
|
1373
|
+
try {
|
|
1374
|
+
return await this.client.releaseLease(updatedOptions);
|
|
1375
|
+
}
|
|
1376
|
+
catch (e) {
|
|
1377
|
+
span.setStatus({
|
|
1378
|
+
code: coreTracing.SpanStatusCode.ERROR,
|
|
1379
|
+
message: e.message,
|
|
1380
|
+
});
|
|
1381
|
+
throw e;
|
|
1382
|
+
}
|
|
1383
|
+
finally {
|
|
1384
|
+
span.end();
|
|
1385
|
+
}
|
|
1386
|
+
}
|
|
1387
|
+
async renewLease(options = {}) {
|
|
1388
|
+
options.conditions = options.conditions || {};
|
|
1389
|
+
const { span, updatedOptions } = createSpan("DataLakeLeaseClient-renewLease", options);
|
|
1390
|
+
try {
|
|
1391
|
+
return await this.client.renewLease(updatedOptions);
|
|
1392
|
+
}
|
|
1393
|
+
catch (e) {
|
|
1394
|
+
span.setStatus({
|
|
1395
|
+
code: coreTracing.SpanStatusCode.ERROR,
|
|
1396
|
+
message: e.message,
|
|
1397
|
+
});
|
|
1398
|
+
throw e;
|
|
1399
|
+
}
|
|
1400
|
+
finally {
|
|
1401
|
+
span.end();
|
|
1402
|
+
}
|
|
1403
|
+
}
|
|
1404
|
+
async breakLease(breakPeriod, options = {}) {
|
|
1405
|
+
options.conditions = options.conditions || {};
|
|
1406
|
+
const { span, updatedOptions } = createSpan("DataLakeLeaseClient-renewLease", options);
|
|
1407
|
+
try {
|
|
1408
|
+
return await this.client.breakLease(breakPeriod, updatedOptions);
|
|
1409
|
+
}
|
|
1410
|
+
catch (e) {
|
|
1411
|
+
span.setStatus({
|
|
1412
|
+
code: coreTracing.SpanStatusCode.ERROR,
|
|
1413
|
+
message: e.message,
|
|
1414
|
+
});
|
|
1415
|
+
throw e;
|
|
1416
|
+
}
|
|
1417
|
+
finally {
|
|
1418
|
+
span.end();
|
|
1419
|
+
}
|
|
1420
|
+
}
|
|
1421
|
+
}
|
|
1422
|
+
|
|
1423
|
+
/*
|
|
1424
|
+
* Copyright (c) Microsoft Corporation.
|
|
1425
|
+
* Licensed under the MIT License.
|
|
1426
|
+
*
|
|
1427
|
+
* Code generated by Microsoft (R) AutoRest Code Generator.
|
|
1428
|
+
* Changes may cause incorrect behavior and will be lost if the code is regenerated.
|
|
1429
|
+
*/
|
|
1430
|
+
const FileSystemList = {
|
|
1431
|
+
serializedName: "FileSystemList",
|
|
1432
|
+
type: {
|
|
1433
|
+
name: "Composite",
|
|
1434
|
+
className: "FileSystemList",
|
|
1435
|
+
modelProperties: {
|
|
1436
|
+
filesystems: {
|
|
1437
|
+
serializedName: "filesystems",
|
|
1438
|
+
xmlName: "filesystems",
|
|
1439
|
+
xmlElementName: "FileSystem",
|
|
1446
1440
|
type: {
|
|
1447
1441
|
name: "Sequence",
|
|
1448
1442
|
element: {
|
|
1449
1443
|
type: {
|
|
1450
1444
|
name: "Composite",
|
|
1451
|
-
className: "
|
|
1445
|
+
className: "FileSystem"
|
|
1452
1446
|
}
|
|
1453
1447
|
}
|
|
1454
1448
|
}
|
|
@@ -1456,16 +1450,29 @@ const BlobHierarchyListSegment = {
|
|
|
1456
1450
|
}
|
|
1457
1451
|
}
|
|
1458
1452
|
};
|
|
1459
|
-
const
|
|
1460
|
-
serializedName: "
|
|
1453
|
+
const FileSystem$1 = {
|
|
1454
|
+
serializedName: "FileSystem",
|
|
1461
1455
|
type: {
|
|
1462
1456
|
name: "Composite",
|
|
1463
|
-
className: "
|
|
1457
|
+
className: "FileSystem",
|
|
1464
1458
|
modelProperties: {
|
|
1465
1459
|
name: {
|
|
1466
|
-
serializedName: "
|
|
1467
|
-
|
|
1468
|
-
|
|
1460
|
+
serializedName: "name",
|
|
1461
|
+
xmlName: "name",
|
|
1462
|
+
type: {
|
|
1463
|
+
name: "String"
|
|
1464
|
+
}
|
|
1465
|
+
},
|
|
1466
|
+
lastModified: {
|
|
1467
|
+
serializedName: "lastModified",
|
|
1468
|
+
xmlName: "lastModified",
|
|
1469
|
+
type: {
|
|
1470
|
+
name: "DateTimeRfc1123"
|
|
1471
|
+
}
|
|
1472
|
+
},
|
|
1473
|
+
etag: {
|
|
1474
|
+
serializedName: "eTag",
|
|
1475
|
+
xmlName: "eTag",
|
|
1469
1476
|
type: {
|
|
1470
1477
|
name: "String"
|
|
1471
1478
|
}
|
|
@@ -1473,321 +1480,272 @@ const BlobPrefix = {
|
|
|
1473
1480
|
}
|
|
1474
1481
|
}
|
|
1475
1482
|
};
|
|
1476
|
-
const
|
|
1477
|
-
serializedName: "
|
|
1478
|
-
xmlName: "Blob",
|
|
1483
|
+
const StorageError = {
|
|
1484
|
+
serializedName: "StorageError",
|
|
1479
1485
|
type: {
|
|
1480
1486
|
name: "Composite",
|
|
1481
|
-
className: "
|
|
1487
|
+
className: "StorageError",
|
|
1482
1488
|
modelProperties: {
|
|
1483
|
-
|
|
1484
|
-
serializedName: "
|
|
1485
|
-
|
|
1486
|
-
xmlName: "Name",
|
|
1489
|
+
error: {
|
|
1490
|
+
serializedName: "error",
|
|
1491
|
+
xmlName: "error",
|
|
1487
1492
|
type: {
|
|
1488
|
-
name: "
|
|
1493
|
+
name: "Composite",
|
|
1494
|
+
className: "StorageErrorError"
|
|
1489
1495
|
}
|
|
1490
1496
|
},
|
|
1491
|
-
|
|
1492
|
-
serializedName: "
|
|
1493
|
-
|
|
1494
|
-
xmlName: "Deleted",
|
|
1497
|
+
code: {
|
|
1498
|
+
serializedName: "Code",
|
|
1499
|
+
xmlName: "Code",
|
|
1495
1500
|
type: {
|
|
1496
|
-
name: "
|
|
1501
|
+
name: "String"
|
|
1497
1502
|
}
|
|
1498
|
-
}
|
|
1499
|
-
|
|
1500
|
-
|
|
1501
|
-
|
|
1502
|
-
|
|
1503
|
+
}
|
|
1504
|
+
}
|
|
1505
|
+
}
|
|
1506
|
+
};
|
|
1507
|
+
const StorageErrorError = {
|
|
1508
|
+
serializedName: "StorageErrorError",
|
|
1509
|
+
type: {
|
|
1510
|
+
name: "Composite",
|
|
1511
|
+
className: "StorageErrorError",
|
|
1512
|
+
modelProperties: {
|
|
1513
|
+
code: {
|
|
1514
|
+
serializedName: "Code",
|
|
1515
|
+
xmlName: "Code",
|
|
1503
1516
|
type: {
|
|
1504
1517
|
name: "String"
|
|
1505
1518
|
}
|
|
1506
1519
|
},
|
|
1507
|
-
|
|
1508
|
-
serializedName: "
|
|
1509
|
-
xmlName: "
|
|
1520
|
+
message: {
|
|
1521
|
+
serializedName: "Message",
|
|
1522
|
+
xmlName: "Message",
|
|
1510
1523
|
type: {
|
|
1511
1524
|
name: "String"
|
|
1512
1525
|
}
|
|
1513
|
-
}
|
|
1514
|
-
|
|
1515
|
-
|
|
1516
|
-
|
|
1517
|
-
|
|
1518
|
-
|
|
1519
|
-
|
|
1520
|
-
|
|
1521
|
-
|
|
1522
|
-
|
|
1523
|
-
|
|
1524
|
-
|
|
1525
|
-
|
|
1526
|
-
|
|
1527
|
-
}
|
|
1528
|
-
},
|
|
1529
|
-
deletionId: {
|
|
1530
|
-
serializedName: "DeletionId",
|
|
1531
|
-
xmlName: "DeletionId",
|
|
1526
|
+
}
|
|
1527
|
+
}
|
|
1528
|
+
}
|
|
1529
|
+
};
|
|
1530
|
+
const PathList = {
|
|
1531
|
+
serializedName: "PathList",
|
|
1532
|
+
type: {
|
|
1533
|
+
name: "Composite",
|
|
1534
|
+
className: "PathList",
|
|
1535
|
+
modelProperties: {
|
|
1536
|
+
paths: {
|
|
1537
|
+
serializedName: "paths",
|
|
1538
|
+
xmlName: "paths",
|
|
1539
|
+
xmlElementName: "Path",
|
|
1532
1540
|
type: {
|
|
1533
|
-
name: "
|
|
1541
|
+
name: "Sequence",
|
|
1542
|
+
element: {
|
|
1543
|
+
type: {
|
|
1544
|
+
name: "Composite",
|
|
1545
|
+
className: "Path"
|
|
1546
|
+
}
|
|
1547
|
+
}
|
|
1534
1548
|
}
|
|
1535
1549
|
}
|
|
1536
1550
|
}
|
|
1537
1551
|
}
|
|
1538
1552
|
};
|
|
1539
|
-
const
|
|
1540
|
-
serializedName: "
|
|
1541
|
-
xmlName: "Properties",
|
|
1553
|
+
const Path$1 = {
|
|
1554
|
+
serializedName: "Path",
|
|
1542
1555
|
type: {
|
|
1543
1556
|
name: "Composite",
|
|
1544
|
-
className: "
|
|
1557
|
+
className: "Path",
|
|
1545
1558
|
modelProperties: {
|
|
1546
|
-
|
|
1547
|
-
serializedName: "
|
|
1548
|
-
xmlName: "
|
|
1559
|
+
name: {
|
|
1560
|
+
serializedName: "name",
|
|
1561
|
+
xmlName: "name",
|
|
1549
1562
|
type: {
|
|
1550
|
-
name: "
|
|
1563
|
+
name: "String"
|
|
1564
|
+
}
|
|
1565
|
+
},
|
|
1566
|
+
isDirectory: {
|
|
1567
|
+
serializedName: "isDirectory",
|
|
1568
|
+
xmlName: "isDirectory",
|
|
1569
|
+
type: {
|
|
1570
|
+
name: "Boolean"
|
|
1551
1571
|
}
|
|
1552
1572
|
},
|
|
1553
1573
|
lastModified: {
|
|
1554
|
-
serializedName: "
|
|
1555
|
-
|
|
1556
|
-
xmlName: "Last-Modified",
|
|
1574
|
+
serializedName: "lastModified",
|
|
1575
|
+
xmlName: "lastModified",
|
|
1557
1576
|
type: {
|
|
1558
1577
|
name: "DateTimeRfc1123"
|
|
1559
1578
|
}
|
|
1560
1579
|
},
|
|
1561
1580
|
etag: {
|
|
1562
|
-
serializedName: "
|
|
1563
|
-
|
|
1564
|
-
xmlName: "Etag",
|
|
1581
|
+
serializedName: "eTag",
|
|
1582
|
+
xmlName: "eTag",
|
|
1565
1583
|
type: {
|
|
1566
1584
|
name: "String"
|
|
1567
1585
|
}
|
|
1568
1586
|
},
|
|
1569
1587
|
contentLength: {
|
|
1570
|
-
serializedName: "
|
|
1571
|
-
xmlName: "
|
|
1588
|
+
serializedName: "contentLength",
|
|
1589
|
+
xmlName: "contentLength",
|
|
1572
1590
|
type: {
|
|
1573
1591
|
name: "Number"
|
|
1574
1592
|
}
|
|
1575
1593
|
},
|
|
1576
|
-
|
|
1577
|
-
serializedName: "
|
|
1578
|
-
xmlName: "
|
|
1594
|
+
owner: {
|
|
1595
|
+
serializedName: "owner",
|
|
1596
|
+
xmlName: "owner",
|
|
1579
1597
|
type: {
|
|
1580
1598
|
name: "String"
|
|
1581
1599
|
}
|
|
1582
1600
|
},
|
|
1583
|
-
|
|
1584
|
-
serializedName: "
|
|
1585
|
-
xmlName: "
|
|
1601
|
+
group: {
|
|
1602
|
+
serializedName: "group",
|
|
1603
|
+
xmlName: "group",
|
|
1586
1604
|
type: {
|
|
1587
1605
|
name: "String"
|
|
1588
1606
|
}
|
|
1589
1607
|
},
|
|
1590
|
-
|
|
1591
|
-
serializedName: "
|
|
1592
|
-
xmlName: "
|
|
1608
|
+
permissions: {
|
|
1609
|
+
serializedName: "permissions",
|
|
1610
|
+
xmlName: "permissions",
|
|
1593
1611
|
type: {
|
|
1594
1612
|
name: "String"
|
|
1595
1613
|
}
|
|
1596
1614
|
},
|
|
1597
|
-
|
|
1598
|
-
serializedName: "
|
|
1599
|
-
xmlName: "
|
|
1600
|
-
type: {
|
|
1601
|
-
name: "ByteArray"
|
|
1602
|
-
}
|
|
1603
|
-
},
|
|
1604
|
-
contentDisposition: {
|
|
1605
|
-
serializedName: "Content-Disposition",
|
|
1606
|
-
xmlName: "Content-Disposition",
|
|
1615
|
+
encryptionScope: {
|
|
1616
|
+
serializedName: "EncryptionScope",
|
|
1617
|
+
xmlName: "EncryptionScope",
|
|
1607
1618
|
type: {
|
|
1608
1619
|
name: "String"
|
|
1609
1620
|
}
|
|
1610
1621
|
},
|
|
1611
|
-
|
|
1612
|
-
serializedName: "
|
|
1613
|
-
xmlName: "
|
|
1622
|
+
creationTime: {
|
|
1623
|
+
serializedName: "creationTime",
|
|
1624
|
+
xmlName: "creationTime",
|
|
1614
1625
|
type: {
|
|
1615
1626
|
name: "String"
|
|
1616
1627
|
}
|
|
1617
1628
|
},
|
|
1618
|
-
|
|
1619
|
-
serializedName: "
|
|
1620
|
-
xmlName: "
|
|
1621
|
-
type: {
|
|
1622
|
-
name: "Number"
|
|
1623
|
-
}
|
|
1624
|
-
},
|
|
1625
|
-
copyId: {
|
|
1626
|
-
serializedName: "CopyId",
|
|
1627
|
-
xmlName: "CopyId",
|
|
1629
|
+
expiryTime: {
|
|
1630
|
+
serializedName: "expiryTime",
|
|
1631
|
+
xmlName: "expiryTime",
|
|
1628
1632
|
type: {
|
|
1629
1633
|
name: "String"
|
|
1630
1634
|
}
|
|
1631
1635
|
},
|
|
1632
|
-
|
|
1633
|
-
serializedName: "
|
|
1634
|
-
xmlName: "
|
|
1636
|
+
encryptionContext: {
|
|
1637
|
+
serializedName: "EncryptionContext",
|
|
1638
|
+
xmlName: "EncryptionContext",
|
|
1635
1639
|
type: {
|
|
1636
1640
|
name: "String"
|
|
1637
1641
|
}
|
|
1638
|
-
}
|
|
1639
|
-
|
|
1640
|
-
|
|
1641
|
-
|
|
1642
|
+
}
|
|
1643
|
+
}
|
|
1644
|
+
}
|
|
1645
|
+
};
|
|
1646
|
+
const ListBlobsHierarchySegmentResponse = {
|
|
1647
|
+
serializedName: "ListBlobsHierarchySegmentResponse",
|
|
1648
|
+
xmlName: "EnumerationResults",
|
|
1649
|
+
type: {
|
|
1650
|
+
name: "Composite",
|
|
1651
|
+
className: "ListBlobsHierarchySegmentResponse",
|
|
1652
|
+
modelProperties: {
|
|
1653
|
+
serviceEndpoint: {
|
|
1654
|
+
serializedName: "ServiceEndpoint",
|
|
1655
|
+
required: true,
|
|
1656
|
+
xmlName: "ServiceEndpoint",
|
|
1657
|
+
xmlIsAttribute: true,
|
|
1642
1658
|
type: {
|
|
1643
1659
|
name: "String"
|
|
1644
1660
|
}
|
|
1645
1661
|
},
|
|
1646
|
-
|
|
1647
|
-
serializedName: "
|
|
1648
|
-
|
|
1649
|
-
|
|
1650
|
-
|
|
1651
|
-
}
|
|
1652
|
-
},
|
|
1653
|
-
copyStatusDescription: {
|
|
1654
|
-
serializedName: "CopyStatusDescription",
|
|
1655
|
-
xmlName: "CopyStatusDescription",
|
|
1662
|
+
containerName: {
|
|
1663
|
+
serializedName: "ContainerName",
|
|
1664
|
+
required: true,
|
|
1665
|
+
xmlName: "ContainerName",
|
|
1666
|
+
xmlIsAttribute: true,
|
|
1656
1667
|
type: {
|
|
1657
1668
|
name: "String"
|
|
1658
1669
|
}
|
|
1659
1670
|
},
|
|
1660
|
-
|
|
1661
|
-
serializedName: "
|
|
1662
|
-
xmlName: "
|
|
1663
|
-
type: {
|
|
1664
|
-
name: "Boolean"
|
|
1665
|
-
}
|
|
1666
|
-
},
|
|
1667
|
-
incrementalCopy: {
|
|
1668
|
-
serializedName: "IncrementalCopy",
|
|
1669
|
-
xmlName: "IncrementalCopy",
|
|
1670
|
-
type: {
|
|
1671
|
-
name: "Boolean"
|
|
1672
|
-
}
|
|
1673
|
-
},
|
|
1674
|
-
destinationSnapshot: {
|
|
1675
|
-
serializedName: "DestinationSnapshot",
|
|
1676
|
-
xmlName: "DestinationSnapshot",
|
|
1671
|
+
prefix: {
|
|
1672
|
+
serializedName: "Prefix",
|
|
1673
|
+
xmlName: "Prefix",
|
|
1677
1674
|
type: {
|
|
1678
1675
|
name: "String"
|
|
1679
1676
|
}
|
|
1680
1677
|
},
|
|
1681
|
-
|
|
1682
|
-
serializedName: "
|
|
1683
|
-
xmlName: "
|
|
1678
|
+
marker: {
|
|
1679
|
+
serializedName: "Marker",
|
|
1680
|
+
xmlName: "Marker",
|
|
1684
1681
|
type: {
|
|
1685
|
-
name: "
|
|
1682
|
+
name: "String"
|
|
1686
1683
|
}
|
|
1687
1684
|
},
|
|
1688
|
-
|
|
1689
|
-
serializedName: "
|
|
1690
|
-
xmlName: "
|
|
1685
|
+
maxResults: {
|
|
1686
|
+
serializedName: "MaxResults",
|
|
1687
|
+
xmlName: "MaxResults",
|
|
1691
1688
|
type: {
|
|
1692
1689
|
name: "Number"
|
|
1693
1690
|
}
|
|
1694
1691
|
},
|
|
1695
|
-
|
|
1696
|
-
serializedName: "
|
|
1697
|
-
xmlName: "
|
|
1692
|
+
delimiter: {
|
|
1693
|
+
serializedName: "Delimiter",
|
|
1694
|
+
xmlName: "Delimiter",
|
|
1698
1695
|
type: {
|
|
1699
|
-
name: "
|
|
1696
|
+
name: "String"
|
|
1700
1697
|
}
|
|
1701
1698
|
},
|
|
1702
|
-
|
|
1703
|
-
serializedName: "
|
|
1704
|
-
xmlName: "
|
|
1699
|
+
segment: {
|
|
1700
|
+
serializedName: "Segment",
|
|
1701
|
+
xmlName: "Blobs",
|
|
1705
1702
|
type: {
|
|
1706
|
-
name: "
|
|
1703
|
+
name: "Composite",
|
|
1704
|
+
className: "BlobHierarchyListSegment"
|
|
1707
1705
|
}
|
|
1708
1706
|
},
|
|
1709
|
-
|
|
1710
|
-
serializedName: "
|
|
1711
|
-
xmlName: "
|
|
1707
|
+
nextMarker: {
|
|
1708
|
+
serializedName: "NextMarker",
|
|
1709
|
+
xmlName: "NextMarker",
|
|
1712
1710
|
type: {
|
|
1713
1711
|
name: "String"
|
|
1714
1712
|
}
|
|
1715
|
-
}
|
|
1716
|
-
|
|
1717
|
-
|
|
1718
|
-
|
|
1713
|
+
}
|
|
1714
|
+
}
|
|
1715
|
+
}
|
|
1716
|
+
};
|
|
1717
|
+
const BlobHierarchyListSegment = {
|
|
1718
|
+
serializedName: "BlobHierarchyListSegment",
|
|
1719
|
+
xmlName: "Blobs",
|
|
1720
|
+
type: {
|
|
1721
|
+
name: "Composite",
|
|
1722
|
+
className: "BlobHierarchyListSegment",
|
|
1723
|
+
modelProperties: {
|
|
1724
|
+
blobPrefixes: {
|
|
1725
|
+
serializedName: "BlobPrefixes",
|
|
1726
|
+
xmlName: "BlobPrefixes",
|
|
1727
|
+
xmlElementName: "BlobPrefix",
|
|
1719
1728
|
type: {
|
|
1720
|
-
name: "
|
|
1729
|
+
name: "Sequence",
|
|
1730
|
+
element: {
|
|
1731
|
+
type: {
|
|
1732
|
+
name: "Composite",
|
|
1733
|
+
className: "BlobPrefix"
|
|
1734
|
+
}
|
|
1735
|
+
}
|
|
1721
1736
|
}
|
|
1722
1737
|
},
|
|
1723
|
-
|
|
1724
|
-
serializedName: "
|
|
1725
|
-
|
|
1726
|
-
|
|
1727
|
-
|
|
1728
|
-
}
|
|
1729
|
-
},
|
|
1730
|
-
expiresOn: {
|
|
1731
|
-
serializedName: "Expiry-Time",
|
|
1732
|
-
xmlName: "Expiry-Time",
|
|
1733
|
-
type: {
|
|
1734
|
-
name: "DateTimeRfc1123"
|
|
1735
|
-
}
|
|
1736
|
-
},
|
|
1737
|
-
sealed: {
|
|
1738
|
-
serializedName: "Sealed",
|
|
1739
|
-
xmlName: "Sealed",
|
|
1740
|
-
type: {
|
|
1741
|
-
name: "Boolean"
|
|
1742
|
-
}
|
|
1743
|
-
},
|
|
1744
|
-
lastAccessedOn: {
|
|
1745
|
-
serializedName: "LastAccessTime",
|
|
1746
|
-
xmlName: "LastAccessTime",
|
|
1747
|
-
type: {
|
|
1748
|
-
name: "DateTimeRfc1123"
|
|
1749
|
-
}
|
|
1750
|
-
}
|
|
1751
|
-
}
|
|
1752
|
-
}
|
|
1753
|
-
};
|
|
1754
|
-
const SetAccessControlRecursiveResponse = {
|
|
1755
|
-
serializedName: "SetAccessControlRecursiveResponse",
|
|
1756
|
-
type: {
|
|
1757
|
-
name: "Composite",
|
|
1758
|
-
className: "SetAccessControlRecursiveResponse",
|
|
1759
|
-
modelProperties: {
|
|
1760
|
-
directoriesSuccessful: {
|
|
1761
|
-
serializedName: "directoriesSuccessful",
|
|
1762
|
-
xmlName: "directoriesSuccessful",
|
|
1763
|
-
type: {
|
|
1764
|
-
name: "Number"
|
|
1765
|
-
}
|
|
1766
|
-
},
|
|
1767
|
-
filesSuccessful: {
|
|
1768
|
-
serializedName: "filesSuccessful",
|
|
1769
|
-
xmlName: "filesSuccessful",
|
|
1770
|
-
type: {
|
|
1771
|
-
name: "Number"
|
|
1772
|
-
}
|
|
1773
|
-
},
|
|
1774
|
-
failureCount: {
|
|
1775
|
-
serializedName: "failureCount",
|
|
1776
|
-
xmlName: "failureCount",
|
|
1777
|
-
type: {
|
|
1778
|
-
name: "Number"
|
|
1779
|
-
}
|
|
1780
|
-
},
|
|
1781
|
-
failedEntries: {
|
|
1782
|
-
serializedName: "failedEntries",
|
|
1783
|
-
xmlName: "failedEntries",
|
|
1784
|
-
xmlElementName: "AclFailedEntry",
|
|
1738
|
+
blobItems: {
|
|
1739
|
+
serializedName: "BlobItems",
|
|
1740
|
+
required: true,
|
|
1741
|
+
xmlName: "BlobItems",
|
|
1742
|
+
xmlElementName: "Blob",
|
|
1785
1743
|
type: {
|
|
1786
1744
|
name: "Sequence",
|
|
1787
1745
|
element: {
|
|
1788
1746
|
type: {
|
|
1789
1747
|
name: "Composite",
|
|
1790
|
-
className: "
|
|
1748
|
+
className: "BlobItemModel"
|
|
1791
1749
|
}
|
|
1792
1750
|
}
|
|
1793
1751
|
}
|
|
@@ -1795,29 +1753,16 @@ const SetAccessControlRecursiveResponse = {
|
|
|
1795
1753
|
}
|
|
1796
1754
|
}
|
|
1797
1755
|
};
|
|
1798
|
-
const
|
|
1799
|
-
serializedName: "
|
|
1756
|
+
const BlobPrefix = {
|
|
1757
|
+
serializedName: "BlobPrefix",
|
|
1800
1758
|
type: {
|
|
1801
1759
|
name: "Composite",
|
|
1802
|
-
className: "
|
|
1760
|
+
className: "BlobPrefix",
|
|
1803
1761
|
modelProperties: {
|
|
1804
1762
|
name: {
|
|
1805
|
-
serializedName: "
|
|
1806
|
-
|
|
1807
|
-
|
|
1808
|
-
name: "String"
|
|
1809
|
-
}
|
|
1810
|
-
},
|
|
1811
|
-
type: {
|
|
1812
|
-
serializedName: "type",
|
|
1813
|
-
xmlName: "type",
|
|
1814
|
-
type: {
|
|
1815
|
-
name: "String"
|
|
1816
|
-
}
|
|
1817
|
-
},
|
|
1818
|
-
errorMessage: {
|
|
1819
|
-
serializedName: "errorMessage",
|
|
1820
|
-
xmlName: "errorMessage",
|
|
1763
|
+
serializedName: "Name",
|
|
1764
|
+
required: true,
|
|
1765
|
+
xmlName: "Name",
|
|
1821
1766
|
type: {
|
|
1822
1767
|
name: "String"
|
|
1823
1768
|
}
|
|
@@ -1825,62 +1770,62 @@ const AclFailedEntry = {
|
|
|
1825
1770
|
}
|
|
1826
1771
|
}
|
|
1827
1772
|
};
|
|
1828
|
-
const
|
|
1829
|
-
serializedName: "
|
|
1773
|
+
const BlobItemModel = {
|
|
1774
|
+
serializedName: "BlobItemModel",
|
|
1775
|
+
xmlName: "Blob",
|
|
1830
1776
|
type: {
|
|
1831
1777
|
name: "Composite",
|
|
1832
|
-
className: "
|
|
1778
|
+
className: "BlobItemModel",
|
|
1833
1779
|
modelProperties: {
|
|
1834
|
-
|
|
1835
|
-
serializedName: "
|
|
1836
|
-
|
|
1780
|
+
name: {
|
|
1781
|
+
serializedName: "Name",
|
|
1782
|
+
required: true,
|
|
1783
|
+
xmlName: "Name",
|
|
1837
1784
|
type: {
|
|
1838
|
-
name: "
|
|
1785
|
+
name: "String"
|
|
1839
1786
|
}
|
|
1840
1787
|
},
|
|
1841
|
-
|
|
1842
|
-
|
|
1843
|
-
|
|
1844
|
-
|
|
1845
|
-
serializedName: "x-ms-request-id",
|
|
1846
|
-
xmlName: "x-ms-request-id",
|
|
1788
|
+
deleted: {
|
|
1789
|
+
serializedName: "Deleted",
|
|
1790
|
+
required: true,
|
|
1791
|
+
xmlName: "Deleted",
|
|
1847
1792
|
type: {
|
|
1848
|
-
name: "
|
|
1793
|
+
name: "Boolean"
|
|
1849
1794
|
}
|
|
1850
1795
|
},
|
|
1851
|
-
|
|
1852
|
-
serializedName: "
|
|
1853
|
-
|
|
1796
|
+
snapshot: {
|
|
1797
|
+
serializedName: "Snapshot",
|
|
1798
|
+
required: true,
|
|
1799
|
+
xmlName: "Snapshot",
|
|
1854
1800
|
type: {
|
|
1855
1801
|
name: "String"
|
|
1856
1802
|
}
|
|
1857
1803
|
},
|
|
1858
|
-
|
|
1859
|
-
serializedName: "
|
|
1860
|
-
xmlName: "
|
|
1804
|
+
versionId: {
|
|
1805
|
+
serializedName: "VersionId",
|
|
1806
|
+
xmlName: "VersionId",
|
|
1861
1807
|
type: {
|
|
1862
1808
|
name: "String"
|
|
1863
1809
|
}
|
|
1864
1810
|
},
|
|
1865
|
-
|
|
1866
|
-
serializedName: "
|
|
1867
|
-
xmlName: "
|
|
1811
|
+
isCurrentVersion: {
|
|
1812
|
+
serializedName: "IsCurrentVersion",
|
|
1813
|
+
xmlName: "IsCurrentVersion",
|
|
1868
1814
|
type: {
|
|
1869
|
-
name: "
|
|
1815
|
+
name: "Boolean"
|
|
1870
1816
|
}
|
|
1871
|
-
}
|
|
1872
|
-
|
|
1873
|
-
|
|
1874
|
-
|
|
1875
|
-
|
|
1876
|
-
|
|
1877
|
-
|
|
1878
|
-
|
|
1879
|
-
|
|
1880
|
-
|
|
1881
|
-
|
|
1882
|
-
|
|
1883
|
-
xmlName: "x-ms-error-code",
|
|
1817
|
+
},
|
|
1818
|
+
properties: {
|
|
1819
|
+
serializedName: "Properties",
|
|
1820
|
+
xmlName: "Properties",
|
|
1821
|
+
type: {
|
|
1822
|
+
name: "Composite",
|
|
1823
|
+
className: "BlobPropertiesModel"
|
|
1824
|
+
}
|
|
1825
|
+
},
|
|
1826
|
+
deletionId: {
|
|
1827
|
+
serializedName: "DeletionId",
|
|
1828
|
+
xmlName: "DeletionId",
|
|
1884
1829
|
type: {
|
|
1885
1830
|
name: "String"
|
|
1886
1831
|
}
|
|
@@ -1888,162 +1833,304 @@ const ServiceListFileSystemsExceptionHeaders = {
|
|
|
1888
1833
|
}
|
|
1889
1834
|
}
|
|
1890
1835
|
};
|
|
1891
|
-
const
|
|
1892
|
-
serializedName: "
|
|
1836
|
+
const BlobPropertiesModel = {
|
|
1837
|
+
serializedName: "BlobPropertiesModel",
|
|
1838
|
+
xmlName: "Properties",
|
|
1893
1839
|
type: {
|
|
1894
1840
|
name: "Composite",
|
|
1895
|
-
className: "
|
|
1841
|
+
className: "BlobPropertiesModel",
|
|
1896
1842
|
modelProperties: {
|
|
1897
|
-
|
|
1898
|
-
serializedName: "
|
|
1899
|
-
xmlName: "
|
|
1843
|
+
creationTime: {
|
|
1844
|
+
serializedName: "Creation-Time",
|
|
1845
|
+
xmlName: "Creation-Time",
|
|
1900
1846
|
type: {
|
|
1901
1847
|
name: "DateTimeRfc1123"
|
|
1902
1848
|
}
|
|
1903
1849
|
},
|
|
1904
|
-
etag: {
|
|
1905
|
-
serializedName: "etag",
|
|
1906
|
-
xmlName: "etag",
|
|
1907
|
-
type: {
|
|
1908
|
-
name: "String"
|
|
1909
|
-
}
|
|
1910
|
-
},
|
|
1911
1850
|
lastModified: {
|
|
1912
|
-
serializedName: "
|
|
1913
|
-
|
|
1851
|
+
serializedName: "Last-Modified",
|
|
1852
|
+
required: true,
|
|
1853
|
+
xmlName: "Last-Modified",
|
|
1914
1854
|
type: {
|
|
1915
1855
|
name: "DateTimeRfc1123"
|
|
1916
1856
|
}
|
|
1917
1857
|
},
|
|
1918
|
-
|
|
1919
|
-
|
|
1920
|
-
|
|
1921
|
-
|
|
1922
|
-
serializedName: "x-ms-request-id",
|
|
1923
|
-
xmlName: "x-ms-request-id",
|
|
1858
|
+
etag: {
|
|
1859
|
+
serializedName: "Etag",
|
|
1860
|
+
required: true,
|
|
1861
|
+
xmlName: "Etag",
|
|
1924
1862
|
type: {
|
|
1925
1863
|
name: "String"
|
|
1926
1864
|
}
|
|
1927
1865
|
},
|
|
1928
|
-
|
|
1929
|
-
serializedName: "
|
|
1930
|
-
xmlName: "
|
|
1866
|
+
contentLength: {
|
|
1867
|
+
serializedName: "Content-Length",
|
|
1868
|
+
xmlName: "Content-Length",
|
|
1931
1869
|
type: {
|
|
1932
|
-
name: "
|
|
1870
|
+
name: "Number"
|
|
1933
1871
|
}
|
|
1934
1872
|
},
|
|
1935
|
-
|
|
1936
|
-
serializedName: "
|
|
1937
|
-
xmlName: "
|
|
1873
|
+
contentType: {
|
|
1874
|
+
serializedName: "Content-Type",
|
|
1875
|
+
xmlName: "Content-Type",
|
|
1938
1876
|
type: {
|
|
1939
1877
|
name: "String"
|
|
1940
1878
|
}
|
|
1941
|
-
}
|
|
1942
|
-
|
|
1943
|
-
|
|
1944
|
-
|
|
1945
|
-
const FileSystemCreateExceptionHeaders = {
|
|
1946
|
-
serializedName: "FileSystem_createExceptionHeaders",
|
|
1947
|
-
type: {
|
|
1948
|
-
name: "Composite",
|
|
1949
|
-
className: "FileSystemCreateExceptionHeaders",
|
|
1950
|
-
modelProperties: {
|
|
1951
|
-
errorCode: {
|
|
1952
|
-
serializedName: "x-ms-error-code",
|
|
1953
|
-
xmlName: "x-ms-error-code",
|
|
1879
|
+
},
|
|
1880
|
+
contentEncoding: {
|
|
1881
|
+
serializedName: "Content-Encoding",
|
|
1882
|
+
xmlName: "Content-Encoding",
|
|
1954
1883
|
type: {
|
|
1955
1884
|
name: "String"
|
|
1956
1885
|
}
|
|
1957
|
-
}
|
|
1958
|
-
}
|
|
1959
|
-
}
|
|
1960
|
-
};
|
|
1961
|
-
const FileSystemSetPropertiesHeaders = {
|
|
1962
|
-
serializedName: "FileSystem_setPropertiesHeaders",
|
|
1963
|
-
type: {
|
|
1964
|
-
name: "Composite",
|
|
1965
|
-
className: "FileSystemSetPropertiesHeaders",
|
|
1966
|
-
modelProperties: {
|
|
1967
|
-
date: {
|
|
1968
|
-
serializedName: "date",
|
|
1969
|
-
xmlName: "date",
|
|
1970
|
-
type: {
|
|
1971
|
-
name: "DateTimeRfc1123"
|
|
1972
|
-
}
|
|
1973
1886
|
},
|
|
1974
|
-
|
|
1975
|
-
serializedName: "
|
|
1976
|
-
xmlName: "
|
|
1887
|
+
contentLanguage: {
|
|
1888
|
+
serializedName: "Content-Language",
|
|
1889
|
+
xmlName: "Content-Language",
|
|
1977
1890
|
type: {
|
|
1978
1891
|
name: "String"
|
|
1979
1892
|
}
|
|
1980
1893
|
},
|
|
1981
|
-
|
|
1982
|
-
serializedName: "
|
|
1983
|
-
xmlName: "
|
|
1984
|
-
type: {
|
|
1894
|
+
contentMD5: {
|
|
1895
|
+
serializedName: "Content-MD5",
|
|
1896
|
+
xmlName: "Content-MD5",
|
|
1897
|
+
type: {
|
|
1898
|
+
name: "ByteArray"
|
|
1899
|
+
}
|
|
1900
|
+
},
|
|
1901
|
+
contentDisposition: {
|
|
1902
|
+
serializedName: "Content-Disposition",
|
|
1903
|
+
xmlName: "Content-Disposition",
|
|
1904
|
+
type: {
|
|
1905
|
+
name: "String"
|
|
1906
|
+
}
|
|
1907
|
+
},
|
|
1908
|
+
cacheControl: {
|
|
1909
|
+
serializedName: "Cache-Control",
|
|
1910
|
+
xmlName: "Cache-Control",
|
|
1911
|
+
type: {
|
|
1912
|
+
name: "String"
|
|
1913
|
+
}
|
|
1914
|
+
},
|
|
1915
|
+
blobSequenceNumber: {
|
|
1916
|
+
serializedName: "x-ms-blob-sequence-number",
|
|
1917
|
+
xmlName: "x-ms-blob-sequence-number",
|
|
1918
|
+
type: {
|
|
1919
|
+
name: "Number"
|
|
1920
|
+
}
|
|
1921
|
+
},
|
|
1922
|
+
copyId: {
|
|
1923
|
+
serializedName: "CopyId",
|
|
1924
|
+
xmlName: "CopyId",
|
|
1925
|
+
type: {
|
|
1926
|
+
name: "String"
|
|
1927
|
+
}
|
|
1928
|
+
},
|
|
1929
|
+
copySource: {
|
|
1930
|
+
serializedName: "CopySource",
|
|
1931
|
+
xmlName: "CopySource",
|
|
1932
|
+
type: {
|
|
1933
|
+
name: "String"
|
|
1934
|
+
}
|
|
1935
|
+
},
|
|
1936
|
+
copyProgress: {
|
|
1937
|
+
serializedName: "CopyProgress",
|
|
1938
|
+
xmlName: "CopyProgress",
|
|
1939
|
+
type: {
|
|
1940
|
+
name: "String"
|
|
1941
|
+
}
|
|
1942
|
+
},
|
|
1943
|
+
copyCompletionTime: {
|
|
1944
|
+
serializedName: "CopyCompletionTime",
|
|
1945
|
+
xmlName: "CopyCompletionTime",
|
|
1946
|
+
type: {
|
|
1985
1947
|
name: "DateTimeRfc1123"
|
|
1986
1948
|
}
|
|
1987
1949
|
},
|
|
1988
|
-
|
|
1989
|
-
|
|
1990
|
-
|
|
1991
|
-
},
|
|
1992
|
-
serializedName: "x-ms-request-id",
|
|
1993
|
-
xmlName: "x-ms-request-id",
|
|
1950
|
+
copyStatusDescription: {
|
|
1951
|
+
serializedName: "CopyStatusDescription",
|
|
1952
|
+
xmlName: "CopyStatusDescription",
|
|
1994
1953
|
type: {
|
|
1995
1954
|
name: "String"
|
|
1996
1955
|
}
|
|
1997
1956
|
},
|
|
1998
|
-
|
|
1999
|
-
serializedName: "
|
|
2000
|
-
xmlName: "
|
|
1957
|
+
serverEncrypted: {
|
|
1958
|
+
serializedName: "ServerEncrypted",
|
|
1959
|
+
xmlName: "ServerEncrypted",
|
|
1960
|
+
type: {
|
|
1961
|
+
name: "Boolean"
|
|
1962
|
+
}
|
|
1963
|
+
},
|
|
1964
|
+
incrementalCopy: {
|
|
1965
|
+
serializedName: "IncrementalCopy",
|
|
1966
|
+
xmlName: "IncrementalCopy",
|
|
1967
|
+
type: {
|
|
1968
|
+
name: "Boolean"
|
|
1969
|
+
}
|
|
1970
|
+
},
|
|
1971
|
+
destinationSnapshot: {
|
|
1972
|
+
serializedName: "DestinationSnapshot",
|
|
1973
|
+
xmlName: "DestinationSnapshot",
|
|
1974
|
+
type: {
|
|
1975
|
+
name: "String"
|
|
1976
|
+
}
|
|
1977
|
+
},
|
|
1978
|
+
deletedTime: {
|
|
1979
|
+
serializedName: "DeletedTime",
|
|
1980
|
+
xmlName: "DeletedTime",
|
|
1981
|
+
type: {
|
|
1982
|
+
name: "DateTimeRfc1123"
|
|
1983
|
+
}
|
|
1984
|
+
},
|
|
1985
|
+
remainingRetentionDays: {
|
|
1986
|
+
serializedName: "RemainingRetentionDays",
|
|
1987
|
+
xmlName: "RemainingRetentionDays",
|
|
1988
|
+
type: {
|
|
1989
|
+
name: "Number"
|
|
1990
|
+
}
|
|
1991
|
+
},
|
|
1992
|
+
accessTierInferred: {
|
|
1993
|
+
serializedName: "AccessTierInferred",
|
|
1994
|
+
xmlName: "AccessTierInferred",
|
|
1995
|
+
type: {
|
|
1996
|
+
name: "Boolean"
|
|
1997
|
+
}
|
|
1998
|
+
},
|
|
1999
|
+
customerProvidedKeySha256: {
|
|
2000
|
+
serializedName: "CustomerProvidedKeySha256",
|
|
2001
|
+
xmlName: "CustomerProvidedKeySha256",
|
|
2002
|
+
type: {
|
|
2003
|
+
name: "String"
|
|
2004
|
+
}
|
|
2005
|
+
},
|
|
2006
|
+
encryptionScope: {
|
|
2007
|
+
serializedName: "EncryptionScope",
|
|
2008
|
+
xmlName: "EncryptionScope",
|
|
2001
2009
|
type: {
|
|
2002
2010
|
name: "String"
|
|
2003
2011
|
}
|
|
2012
|
+
},
|
|
2013
|
+
accessTierChangeTime: {
|
|
2014
|
+
serializedName: "AccessTierChangeTime",
|
|
2015
|
+
xmlName: "AccessTierChangeTime",
|
|
2016
|
+
type: {
|
|
2017
|
+
name: "DateTimeRfc1123"
|
|
2018
|
+
}
|
|
2019
|
+
},
|
|
2020
|
+
tagCount: {
|
|
2021
|
+
serializedName: "TagCount",
|
|
2022
|
+
xmlName: "TagCount",
|
|
2023
|
+
type: {
|
|
2024
|
+
name: "Number"
|
|
2025
|
+
}
|
|
2026
|
+
},
|
|
2027
|
+
expiresOn: {
|
|
2028
|
+
serializedName: "Expiry-Time",
|
|
2029
|
+
xmlName: "Expiry-Time",
|
|
2030
|
+
type: {
|
|
2031
|
+
name: "DateTimeRfc1123"
|
|
2032
|
+
}
|
|
2033
|
+
},
|
|
2034
|
+
sealed: {
|
|
2035
|
+
serializedName: "Sealed",
|
|
2036
|
+
xmlName: "Sealed",
|
|
2037
|
+
type: {
|
|
2038
|
+
name: "Boolean"
|
|
2039
|
+
}
|
|
2040
|
+
},
|
|
2041
|
+
lastAccessedOn: {
|
|
2042
|
+
serializedName: "LastAccessTime",
|
|
2043
|
+
xmlName: "LastAccessTime",
|
|
2044
|
+
type: {
|
|
2045
|
+
name: "DateTimeRfc1123"
|
|
2046
|
+
}
|
|
2004
2047
|
}
|
|
2005
2048
|
}
|
|
2006
2049
|
}
|
|
2007
2050
|
};
|
|
2008
|
-
const
|
|
2009
|
-
serializedName: "
|
|
2051
|
+
const SetAccessControlRecursiveResponse = {
|
|
2052
|
+
serializedName: "SetAccessControlRecursiveResponse",
|
|
2010
2053
|
type: {
|
|
2011
2054
|
name: "Composite",
|
|
2012
|
-
className: "
|
|
2055
|
+
className: "SetAccessControlRecursiveResponse",
|
|
2013
2056
|
modelProperties: {
|
|
2014
|
-
|
|
2015
|
-
serializedName: "
|
|
2016
|
-
xmlName: "
|
|
2057
|
+
directoriesSuccessful: {
|
|
2058
|
+
serializedName: "directoriesSuccessful",
|
|
2059
|
+
xmlName: "directoriesSuccessful",
|
|
2017
2060
|
type: {
|
|
2018
|
-
name: "
|
|
2061
|
+
name: "Number"
|
|
2062
|
+
}
|
|
2063
|
+
},
|
|
2064
|
+
filesSuccessful: {
|
|
2065
|
+
serializedName: "filesSuccessful",
|
|
2066
|
+
xmlName: "filesSuccessful",
|
|
2067
|
+
type: {
|
|
2068
|
+
name: "Number"
|
|
2069
|
+
}
|
|
2070
|
+
},
|
|
2071
|
+
failureCount: {
|
|
2072
|
+
serializedName: "failureCount",
|
|
2073
|
+
xmlName: "failureCount",
|
|
2074
|
+
type: {
|
|
2075
|
+
name: "Number"
|
|
2076
|
+
}
|
|
2077
|
+
},
|
|
2078
|
+
failedEntries: {
|
|
2079
|
+
serializedName: "failedEntries",
|
|
2080
|
+
xmlName: "failedEntries",
|
|
2081
|
+
xmlElementName: "AclFailedEntry",
|
|
2082
|
+
type: {
|
|
2083
|
+
name: "Sequence",
|
|
2084
|
+
element: {
|
|
2085
|
+
type: {
|
|
2086
|
+
name: "Composite",
|
|
2087
|
+
className: "AclFailedEntry"
|
|
2088
|
+
}
|
|
2089
|
+
}
|
|
2019
2090
|
}
|
|
2020
2091
|
}
|
|
2021
2092
|
}
|
|
2022
2093
|
}
|
|
2023
2094
|
};
|
|
2024
|
-
const
|
|
2025
|
-
serializedName: "
|
|
2095
|
+
const AclFailedEntry = {
|
|
2096
|
+
serializedName: "AclFailedEntry",
|
|
2026
2097
|
type: {
|
|
2027
2098
|
name: "Composite",
|
|
2028
|
-
className: "
|
|
2099
|
+
className: "AclFailedEntry",
|
|
2029
2100
|
modelProperties: {
|
|
2030
|
-
|
|
2031
|
-
serializedName: "
|
|
2032
|
-
xmlName: "
|
|
2101
|
+
name: {
|
|
2102
|
+
serializedName: "name",
|
|
2103
|
+
xmlName: "name",
|
|
2033
2104
|
type: {
|
|
2034
|
-
name: "
|
|
2105
|
+
name: "String"
|
|
2035
2106
|
}
|
|
2036
2107
|
},
|
|
2037
|
-
|
|
2038
|
-
serializedName: "
|
|
2039
|
-
xmlName: "
|
|
2108
|
+
type: {
|
|
2109
|
+
serializedName: "type",
|
|
2110
|
+
xmlName: "type",
|
|
2040
2111
|
type: {
|
|
2041
2112
|
name: "String"
|
|
2042
2113
|
}
|
|
2043
2114
|
},
|
|
2044
|
-
|
|
2045
|
-
serializedName: "
|
|
2046
|
-
xmlName: "
|
|
2115
|
+
errorMessage: {
|
|
2116
|
+
serializedName: "errorMessage",
|
|
2117
|
+
xmlName: "errorMessage",
|
|
2118
|
+
type: {
|
|
2119
|
+
name: "String"
|
|
2120
|
+
}
|
|
2121
|
+
}
|
|
2122
|
+
}
|
|
2123
|
+
}
|
|
2124
|
+
};
|
|
2125
|
+
const ServiceListFileSystemsHeaders = {
|
|
2126
|
+
serializedName: "Service_listFileSystemsHeaders",
|
|
2127
|
+
type: {
|
|
2128
|
+
name: "Composite",
|
|
2129
|
+
className: "ServiceListFileSystemsHeaders",
|
|
2130
|
+
modelProperties: {
|
|
2131
|
+
date: {
|
|
2132
|
+
serializedName: "date",
|
|
2133
|
+
xmlName: "date",
|
|
2047
2134
|
type: {
|
|
2048
2135
|
name: "DateTimeRfc1123"
|
|
2049
2136
|
}
|
|
@@ -2065,16 +2152,16 @@ const FileSystemGetPropertiesHeaders = {
|
|
|
2065
2152
|
name: "String"
|
|
2066
2153
|
}
|
|
2067
2154
|
},
|
|
2068
|
-
|
|
2069
|
-
serializedName: "x-ms-
|
|
2070
|
-
xmlName: "x-ms-
|
|
2155
|
+
continuation: {
|
|
2156
|
+
serializedName: "x-ms-continuation",
|
|
2157
|
+
xmlName: "x-ms-continuation",
|
|
2071
2158
|
type: {
|
|
2072
2159
|
name: "String"
|
|
2073
2160
|
}
|
|
2074
2161
|
},
|
|
2075
|
-
|
|
2076
|
-
serializedName: "
|
|
2077
|
-
xmlName: "
|
|
2162
|
+
contentType: {
|
|
2163
|
+
serializedName: "content-type",
|
|
2164
|
+
xmlName: "content-type",
|
|
2078
2165
|
type: {
|
|
2079
2166
|
name: "String"
|
|
2080
2167
|
}
|
|
@@ -2082,11 +2169,11 @@ const FileSystemGetPropertiesHeaders = {
|
|
|
2082
2169
|
}
|
|
2083
2170
|
}
|
|
2084
2171
|
};
|
|
2085
|
-
const
|
|
2086
|
-
serializedName: "
|
|
2172
|
+
const ServiceListFileSystemsExceptionHeaders = {
|
|
2173
|
+
serializedName: "Service_listFileSystemsExceptionHeaders",
|
|
2087
2174
|
type: {
|
|
2088
2175
|
name: "Composite",
|
|
2089
|
-
className: "
|
|
2176
|
+
className: "ServiceListFileSystemsExceptionHeaders",
|
|
2090
2177
|
modelProperties: {
|
|
2091
2178
|
errorCode: {
|
|
2092
2179
|
serializedName: "x-ms-error-code",
|
|
@@ -2098,8 +2185,218 @@ const FileSystemGetPropertiesExceptionHeaders = {
|
|
|
2098
2185
|
}
|
|
2099
2186
|
}
|
|
2100
2187
|
};
|
|
2101
|
-
const
|
|
2102
|
-
serializedName: "
|
|
2188
|
+
const FileSystemCreateHeaders = {
|
|
2189
|
+
serializedName: "FileSystem_createHeaders",
|
|
2190
|
+
type: {
|
|
2191
|
+
name: "Composite",
|
|
2192
|
+
className: "FileSystemCreateHeaders",
|
|
2193
|
+
modelProperties: {
|
|
2194
|
+
date: {
|
|
2195
|
+
serializedName: "date",
|
|
2196
|
+
xmlName: "date",
|
|
2197
|
+
type: {
|
|
2198
|
+
name: "DateTimeRfc1123"
|
|
2199
|
+
}
|
|
2200
|
+
},
|
|
2201
|
+
etag: {
|
|
2202
|
+
serializedName: "etag",
|
|
2203
|
+
xmlName: "etag",
|
|
2204
|
+
type: {
|
|
2205
|
+
name: "String"
|
|
2206
|
+
}
|
|
2207
|
+
},
|
|
2208
|
+
lastModified: {
|
|
2209
|
+
serializedName: "last-modified",
|
|
2210
|
+
xmlName: "last-modified",
|
|
2211
|
+
type: {
|
|
2212
|
+
name: "DateTimeRfc1123"
|
|
2213
|
+
}
|
|
2214
|
+
},
|
|
2215
|
+
clientRequestId: {
|
|
2216
|
+
constraints: {
|
|
2217
|
+
Pattern: new RegExp("^[{(]?[0-9a-f]{8}[-]?([0-9a-f]{4}[-]?){3}[0-9a-f]{12}[)}]?$")
|
|
2218
|
+
},
|
|
2219
|
+
serializedName: "x-ms-request-id",
|
|
2220
|
+
xmlName: "x-ms-request-id",
|
|
2221
|
+
type: {
|
|
2222
|
+
name: "String"
|
|
2223
|
+
}
|
|
2224
|
+
},
|
|
2225
|
+
version: {
|
|
2226
|
+
serializedName: "x-ms-version",
|
|
2227
|
+
xmlName: "x-ms-version",
|
|
2228
|
+
type: {
|
|
2229
|
+
name: "String"
|
|
2230
|
+
}
|
|
2231
|
+
},
|
|
2232
|
+
namespaceEnabled: {
|
|
2233
|
+
serializedName: "x-ms-namespace-enabled",
|
|
2234
|
+
xmlName: "x-ms-namespace-enabled",
|
|
2235
|
+
type: {
|
|
2236
|
+
name: "String"
|
|
2237
|
+
}
|
|
2238
|
+
}
|
|
2239
|
+
}
|
|
2240
|
+
}
|
|
2241
|
+
};
|
|
2242
|
+
const FileSystemCreateExceptionHeaders = {
|
|
2243
|
+
serializedName: "FileSystem_createExceptionHeaders",
|
|
2244
|
+
type: {
|
|
2245
|
+
name: "Composite",
|
|
2246
|
+
className: "FileSystemCreateExceptionHeaders",
|
|
2247
|
+
modelProperties: {
|
|
2248
|
+
errorCode: {
|
|
2249
|
+
serializedName: "x-ms-error-code",
|
|
2250
|
+
xmlName: "x-ms-error-code",
|
|
2251
|
+
type: {
|
|
2252
|
+
name: "String"
|
|
2253
|
+
}
|
|
2254
|
+
}
|
|
2255
|
+
}
|
|
2256
|
+
}
|
|
2257
|
+
};
|
|
2258
|
+
const FileSystemSetPropertiesHeaders = {
|
|
2259
|
+
serializedName: "FileSystem_setPropertiesHeaders",
|
|
2260
|
+
type: {
|
|
2261
|
+
name: "Composite",
|
|
2262
|
+
className: "FileSystemSetPropertiesHeaders",
|
|
2263
|
+
modelProperties: {
|
|
2264
|
+
date: {
|
|
2265
|
+
serializedName: "date",
|
|
2266
|
+
xmlName: "date",
|
|
2267
|
+
type: {
|
|
2268
|
+
name: "DateTimeRfc1123"
|
|
2269
|
+
}
|
|
2270
|
+
},
|
|
2271
|
+
etag: {
|
|
2272
|
+
serializedName: "etag",
|
|
2273
|
+
xmlName: "etag",
|
|
2274
|
+
type: {
|
|
2275
|
+
name: "String"
|
|
2276
|
+
}
|
|
2277
|
+
},
|
|
2278
|
+
lastModified: {
|
|
2279
|
+
serializedName: "last-modified",
|
|
2280
|
+
xmlName: "last-modified",
|
|
2281
|
+
type: {
|
|
2282
|
+
name: "DateTimeRfc1123"
|
|
2283
|
+
}
|
|
2284
|
+
},
|
|
2285
|
+
requestId: {
|
|
2286
|
+
constraints: {
|
|
2287
|
+
Pattern: new RegExp("^[{(]?[0-9a-f]{8}[-]?([0-9a-f]{4}[-]?){3}[0-9a-f]{12}[)}]?$")
|
|
2288
|
+
},
|
|
2289
|
+
serializedName: "x-ms-request-id",
|
|
2290
|
+
xmlName: "x-ms-request-id",
|
|
2291
|
+
type: {
|
|
2292
|
+
name: "String"
|
|
2293
|
+
}
|
|
2294
|
+
},
|
|
2295
|
+
version: {
|
|
2296
|
+
serializedName: "x-ms-version",
|
|
2297
|
+
xmlName: "x-ms-version",
|
|
2298
|
+
type: {
|
|
2299
|
+
name: "String"
|
|
2300
|
+
}
|
|
2301
|
+
}
|
|
2302
|
+
}
|
|
2303
|
+
}
|
|
2304
|
+
};
|
|
2305
|
+
const FileSystemSetPropertiesExceptionHeaders = {
|
|
2306
|
+
serializedName: "FileSystem_setPropertiesExceptionHeaders",
|
|
2307
|
+
type: {
|
|
2308
|
+
name: "Composite",
|
|
2309
|
+
className: "FileSystemSetPropertiesExceptionHeaders",
|
|
2310
|
+
modelProperties: {
|
|
2311
|
+
errorCode: {
|
|
2312
|
+
serializedName: "x-ms-error-code",
|
|
2313
|
+
xmlName: "x-ms-error-code",
|
|
2314
|
+
type: {
|
|
2315
|
+
name: "String"
|
|
2316
|
+
}
|
|
2317
|
+
}
|
|
2318
|
+
}
|
|
2319
|
+
}
|
|
2320
|
+
};
|
|
2321
|
+
const FileSystemGetPropertiesHeaders = {
|
|
2322
|
+
serializedName: "FileSystem_getPropertiesHeaders",
|
|
2323
|
+
type: {
|
|
2324
|
+
name: "Composite",
|
|
2325
|
+
className: "FileSystemGetPropertiesHeaders",
|
|
2326
|
+
modelProperties: {
|
|
2327
|
+
date: {
|
|
2328
|
+
serializedName: "date",
|
|
2329
|
+
xmlName: "date",
|
|
2330
|
+
type: {
|
|
2331
|
+
name: "DateTimeRfc1123"
|
|
2332
|
+
}
|
|
2333
|
+
},
|
|
2334
|
+
etag: {
|
|
2335
|
+
serializedName: "etag",
|
|
2336
|
+
xmlName: "etag",
|
|
2337
|
+
type: {
|
|
2338
|
+
name: "String"
|
|
2339
|
+
}
|
|
2340
|
+
},
|
|
2341
|
+
lastModified: {
|
|
2342
|
+
serializedName: "last-modified",
|
|
2343
|
+
xmlName: "last-modified",
|
|
2344
|
+
type: {
|
|
2345
|
+
name: "DateTimeRfc1123"
|
|
2346
|
+
}
|
|
2347
|
+
},
|
|
2348
|
+
requestId: {
|
|
2349
|
+
constraints: {
|
|
2350
|
+
Pattern: new RegExp("^[{(]?[0-9a-f]{8}[-]?([0-9a-f]{4}[-]?){3}[0-9a-f]{12}[)}]?$")
|
|
2351
|
+
},
|
|
2352
|
+
serializedName: "x-ms-request-id",
|
|
2353
|
+
xmlName: "x-ms-request-id",
|
|
2354
|
+
type: {
|
|
2355
|
+
name: "String"
|
|
2356
|
+
}
|
|
2357
|
+
},
|
|
2358
|
+
version: {
|
|
2359
|
+
serializedName: "x-ms-version",
|
|
2360
|
+
xmlName: "x-ms-version",
|
|
2361
|
+
type: {
|
|
2362
|
+
name: "String"
|
|
2363
|
+
}
|
|
2364
|
+
},
|
|
2365
|
+
properties: {
|
|
2366
|
+
serializedName: "x-ms-properties",
|
|
2367
|
+
xmlName: "x-ms-properties",
|
|
2368
|
+
type: {
|
|
2369
|
+
name: "String"
|
|
2370
|
+
}
|
|
2371
|
+
},
|
|
2372
|
+
namespaceEnabled: {
|
|
2373
|
+
serializedName: "x-ms-namespace-enabled",
|
|
2374
|
+
xmlName: "x-ms-namespace-enabled",
|
|
2375
|
+
type: {
|
|
2376
|
+
name: "String"
|
|
2377
|
+
}
|
|
2378
|
+
}
|
|
2379
|
+
}
|
|
2380
|
+
}
|
|
2381
|
+
};
|
|
2382
|
+
const FileSystemGetPropertiesExceptionHeaders = {
|
|
2383
|
+
serializedName: "FileSystem_getPropertiesExceptionHeaders",
|
|
2384
|
+
type: {
|
|
2385
|
+
name: "Composite",
|
|
2386
|
+
className: "FileSystemGetPropertiesExceptionHeaders",
|
|
2387
|
+
modelProperties: {
|
|
2388
|
+
errorCode: {
|
|
2389
|
+
serializedName: "x-ms-error-code",
|
|
2390
|
+
xmlName: "x-ms-error-code",
|
|
2391
|
+
type: {
|
|
2392
|
+
name: "String"
|
|
2393
|
+
}
|
|
2394
|
+
}
|
|
2395
|
+
}
|
|
2396
|
+
}
|
|
2397
|
+
};
|
|
2398
|
+
const FileSystemDeleteHeaders = {
|
|
2399
|
+
serializedName: "FileSystem_deleteHeaders",
|
|
2103
2400
|
type: {
|
|
2104
2401
|
name: "Composite",
|
|
2105
2402
|
className: "FileSystemDeleteHeaders",
|
|
@@ -3705,7 +4002,7 @@ const timeout = {
|
|
|
3705
4002
|
const version = {
|
|
3706
4003
|
parameterPath: "version",
|
|
3707
4004
|
mapper: {
|
|
3708
|
-
defaultValue: "
|
|
4005
|
+
defaultValue: "2023-01-03",
|
|
3709
4006
|
isConstant: true,
|
|
3710
4007
|
serializedName: "x-ms-version",
|
|
3711
4008
|
type: {
|
|
@@ -5361,841 +5658,555 @@ const appendDataOperationSpec = {
|
|
|
5361
5658
|
encryptionAlgorithm,
|
|
5362
5659
|
proposedLeaseId,
|
|
5363
5660
|
leaseDuration,
|
|
5364
|
-
accept2,
|
|
5365
|
-
contentLength,
|
|
5366
|
-
leaseAction,
|
|
5367
|
-
contentType2,
|
|
5368
|
-
transactionalContentHash,
|
|
5369
|
-
transactionalContentCrc64
|
|
5370
|
-
],
|
|
5371
|
-
mediaType: "binary",
|
|
5372
|
-
serializer
|
|
5373
|
-
};
|
|
5374
|
-
const setExpiryOperationSpec = {
|
|
5375
|
-
path: "/{filesystem}/{path}",
|
|
5376
|
-
httpMethod: "PUT",
|
|
5377
|
-
responses: {
|
|
5378
|
-
200: {
|
|
5379
|
-
headersMapper: PathSetExpiryHeaders
|
|
5380
|
-
},
|
|
5381
|
-
default: {
|
|
5382
|
-
bodyMapper: StorageError,
|
|
5383
|
-
headersMapper: PathSetExpiryExceptionHeaders
|
|
5384
|
-
}
|
|
5385
|
-
},
|
|
5386
|
-
queryParameters: [timeout, comp1],
|
|
5387
|
-
urlParameters: [url],
|
|
5388
|
-
headerParameters: [
|
|
5389
|
-
accept,
|
|
5390
|
-
requestId,
|
|
5391
|
-
version,
|
|
5392
|
-
expiresOn,
|
|
5393
|
-
expiryOptions1
|
|
5394
|
-
],
|
|
5395
|
-
serializer
|
|
5396
|
-
};
|
|
5397
|
-
const undeleteOperationSpec = {
|
|
5398
|
-
path: "/{filesystem}/{path}",
|
|
5399
|
-
httpMethod: "PUT",
|
|
5400
|
-
responses: {
|
|
5401
|
-
200: {
|
|
5402
|
-
headersMapper: PathUndeleteHeaders
|
|
5403
|
-
},
|
|
5404
|
-
default: {
|
|
5405
|
-
bodyMapper: StorageError,
|
|
5406
|
-
headersMapper: PathUndeleteExceptionHeaders
|
|
5407
|
-
}
|
|
5408
|
-
},
|
|
5409
|
-
queryParameters: [timeout, comp2],
|
|
5410
|
-
urlParameters: [url],
|
|
5411
|
-
headerParameters: [
|
|
5412
|
-
accept,
|
|
5413
|
-
requestId,
|
|
5414
|
-
version,
|
|
5415
|
-
undeleteSource
|
|
5416
|
-
],
|
|
5417
|
-
serializer
|
|
5418
|
-
};
|
|
5419
|
-
|
|
5420
|
-
// Copyright (c) Microsoft Corporation.
|
|
5421
|
-
/**
|
|
5422
|
-
* The `@azure/logger` configuration for this package.
|
|
5423
|
-
*/
|
|
5424
|
-
const logger = logger$1.createClientLogger("storage-file-datalake");
|
|
5425
|
-
|
|
5426
|
-
// Copyright (c) Microsoft Corporation.
|
|
5427
|
-
/**
|
|
5428
|
-
* StorageBrowserPolicy will handle differences between Node.js and browser runtime, including:
|
|
5429
|
-
*
|
|
5430
|
-
* 1. Browsers cache GET/HEAD requests by adding conditional headers such as 'IF_MODIFIED_SINCE'.
|
|
5431
|
-
* StorageBrowserPolicy is a policy used to add a timestamp query to GET/HEAD request URL
|
|
5432
|
-
* thus avoid the browser cache.
|
|
5433
|
-
*
|
|
5434
|
-
* 2. Remove cookie header for security
|
|
5435
|
-
*
|
|
5436
|
-
* 3. Remove content-length header to avoid browsers warning
|
|
5437
|
-
*/
|
|
5438
|
-
class StorageBrowserPolicy extends coreHttp.BaseRequestPolicy {
|
|
5439
|
-
/**
|
|
5440
|
-
* Creates an instance of StorageBrowserPolicy.
|
|
5441
|
-
* @param nextPolicy -
|
|
5442
|
-
* @param options -
|
|
5443
|
-
*/
|
|
5444
|
-
// The base class has a protected constructor. Adding a public one to enable constructing of this class.
|
|
5445
|
-
/* eslint-disable-next-line @typescript-eslint/no-useless-constructor*/
|
|
5446
|
-
constructor(nextPolicy, options) {
|
|
5447
|
-
super(nextPolicy, options);
|
|
5448
|
-
}
|
|
5449
|
-
/**
|
|
5450
|
-
* Sends out request.
|
|
5451
|
-
*
|
|
5452
|
-
* @param request -
|
|
5453
|
-
*/
|
|
5454
|
-
async sendRequest(request) {
|
|
5455
|
-
if (coreHttp.isNode) {
|
|
5456
|
-
return this._nextPolicy.sendRequest(request);
|
|
5457
|
-
}
|
|
5458
|
-
if (request.method.toUpperCase() === "GET" || request.method.toUpperCase() === "HEAD") {
|
|
5459
|
-
request.url = setURLParameter(request.url, UrlConstants.Parameters.FORCE_BROWSER_NO_CACHE, new Date().getTime().toString());
|
|
5460
|
-
}
|
|
5461
|
-
request.headers.remove(HeaderConstants.COOKIE);
|
|
5462
|
-
// According to XHR standards, content-length should be fully controlled by browsers
|
|
5463
|
-
request.headers.remove(HeaderConstants.CONTENT_LENGTH);
|
|
5464
|
-
// DFS flush file API requires content-length=0, workaround to force browsers add content-length header
|
|
5465
|
-
if (request.method === "PATCH" && request.body === undefined) {
|
|
5466
|
-
request.body = "";
|
|
5467
|
-
}
|
|
5468
|
-
return this._nextPolicy.sendRequest(request);
|
|
5469
|
-
}
|
|
5470
|
-
}
|
|
5471
|
-
|
|
5472
|
-
// Copyright (c) Microsoft Corporation.
|
|
5473
|
-
/**
|
|
5474
|
-
* StorageBrowserPolicyFactory is a factory class helping generating StorageBrowserPolicy objects.
|
|
5475
|
-
*/
|
|
5476
|
-
class StorageBrowserPolicyFactory {
|
|
5477
|
-
/**
|
|
5478
|
-
* Creates a StorageBrowserPolicyFactory object.
|
|
5479
|
-
*
|
|
5480
|
-
* @param nextPolicy -
|
|
5481
|
-
* @param options -
|
|
5482
|
-
*/
|
|
5483
|
-
create(nextPolicy, options) {
|
|
5484
|
-
return new StorageBrowserPolicy(nextPolicy, options);
|
|
5485
|
-
}
|
|
5486
|
-
}
|
|
5487
|
-
|
|
5488
|
-
// Copyright (c) Microsoft Corporation.
|
|
5489
|
-
/**
|
|
5490
|
-
* RetryPolicy types.
|
|
5491
|
-
*/
|
|
5492
|
-
exports.StorageRetryPolicyType = void 0;
|
|
5493
|
-
(function (StorageRetryPolicyType) {
|
|
5494
|
-
/**
|
|
5495
|
-
* Exponential retry. Retry time delay grows exponentially.
|
|
5496
|
-
*/
|
|
5497
|
-
StorageRetryPolicyType[StorageRetryPolicyType["EXPONENTIAL"] = 0] = "EXPONENTIAL";
|
|
5498
|
-
/**
|
|
5499
|
-
* Linear retry. Retry time delay grows linearly.
|
|
5500
|
-
*/
|
|
5501
|
-
StorageRetryPolicyType[StorageRetryPolicyType["FIXED"] = 1] = "FIXED";
|
|
5502
|
-
})(exports.StorageRetryPolicyType || (exports.StorageRetryPolicyType = {}));
|
|
5503
|
-
// Default values of StorageRetryOptions
|
|
5504
|
-
const DEFAULT_RETRY_OPTIONS = {
|
|
5505
|
-
maxRetryDelayInMs: 120 * 1000,
|
|
5506
|
-
maxTries: 4,
|
|
5507
|
-
retryDelayInMs: 4 * 1000,
|
|
5508
|
-
retryPolicyType: exports.StorageRetryPolicyType.EXPONENTIAL,
|
|
5509
|
-
secondaryHost: "",
|
|
5510
|
-
tryTimeoutInMs: undefined, // Use server side default timeout strategy
|
|
5511
|
-
};
|
|
5512
|
-
const RETRY_ABORT_ERROR = new abortController.AbortError("The operation was aborted.");
|
|
5513
|
-
/**
|
|
5514
|
-
* Retry policy with exponential retry and linear retry implemented.
|
|
5515
|
-
*/
|
|
5516
|
-
class StorageRetryPolicy extends coreHttp.BaseRequestPolicy {
|
|
5517
|
-
/**
|
|
5518
|
-
* Creates an instance of RetryPolicy.
|
|
5519
|
-
*
|
|
5520
|
-
* @param nextPolicy -
|
|
5521
|
-
* @param options -
|
|
5522
|
-
* @param retryOptions -
|
|
5523
|
-
*/
|
|
5524
|
-
constructor(nextPolicy, options, retryOptions = DEFAULT_RETRY_OPTIONS) {
|
|
5525
|
-
super(nextPolicy, options);
|
|
5526
|
-
// Initialize retry options
|
|
5527
|
-
this.retryOptions = {
|
|
5528
|
-
retryPolicyType: retryOptions.retryPolicyType
|
|
5529
|
-
? retryOptions.retryPolicyType
|
|
5530
|
-
: DEFAULT_RETRY_OPTIONS.retryPolicyType,
|
|
5531
|
-
maxTries: retryOptions.maxTries && retryOptions.maxTries >= 1
|
|
5532
|
-
? Math.floor(retryOptions.maxTries)
|
|
5533
|
-
: DEFAULT_RETRY_OPTIONS.maxTries,
|
|
5534
|
-
tryTimeoutInMs: retryOptions.tryTimeoutInMs && retryOptions.tryTimeoutInMs >= 0
|
|
5535
|
-
? retryOptions.tryTimeoutInMs
|
|
5536
|
-
: DEFAULT_RETRY_OPTIONS.tryTimeoutInMs,
|
|
5537
|
-
retryDelayInMs: retryOptions.retryDelayInMs && retryOptions.retryDelayInMs >= 0
|
|
5538
|
-
? Math.min(retryOptions.retryDelayInMs, retryOptions.maxRetryDelayInMs
|
|
5539
|
-
? retryOptions.maxRetryDelayInMs
|
|
5540
|
-
: DEFAULT_RETRY_OPTIONS.maxRetryDelayInMs)
|
|
5541
|
-
: DEFAULT_RETRY_OPTIONS.retryDelayInMs,
|
|
5542
|
-
maxRetryDelayInMs: retryOptions.maxRetryDelayInMs && retryOptions.maxRetryDelayInMs >= 0
|
|
5543
|
-
? retryOptions.maxRetryDelayInMs
|
|
5544
|
-
: DEFAULT_RETRY_OPTIONS.maxRetryDelayInMs,
|
|
5545
|
-
secondaryHost: retryOptions.secondaryHost
|
|
5546
|
-
? retryOptions.secondaryHost
|
|
5547
|
-
: DEFAULT_RETRY_OPTIONS.secondaryHost,
|
|
5548
|
-
};
|
|
5549
|
-
}
|
|
5550
|
-
/**
|
|
5551
|
-
* Sends request.
|
|
5552
|
-
*
|
|
5553
|
-
* @param request -
|
|
5554
|
-
*/
|
|
5555
|
-
async sendRequest(request) {
|
|
5556
|
-
return this.attemptSendRequest(request, false, 1);
|
|
5557
|
-
}
|
|
5558
|
-
/**
|
|
5559
|
-
* Decide and perform next retry. Won't mutate request parameter.
|
|
5560
|
-
*
|
|
5561
|
-
* @param request -
|
|
5562
|
-
* @param secondaryHas404 - If attempt was against the secondary & it returned a StatusNotFound (404), then
|
|
5563
|
-
* the resource was not found. This may be due to replication delay. So, in this
|
|
5564
|
-
* case, we'll never try the secondary again for this operation.
|
|
5565
|
-
* @param attempt - How many retries has been attempted to performed, starting from 1, which includes
|
|
5566
|
-
* the attempt will be performed by this method call.
|
|
5567
|
-
*/
|
|
5568
|
-
async attemptSendRequest(request, secondaryHas404, attempt) {
|
|
5569
|
-
const newRequest = request.clone();
|
|
5570
|
-
const isPrimaryRetry = secondaryHas404 ||
|
|
5571
|
-
!this.retryOptions.secondaryHost ||
|
|
5572
|
-
!(request.method === "GET" || request.method === "HEAD" || request.method === "OPTIONS") ||
|
|
5573
|
-
attempt % 2 === 1;
|
|
5574
|
-
if (!isPrimaryRetry) {
|
|
5575
|
-
newRequest.url = setURLHost(newRequest.url, this.retryOptions.secondaryHost);
|
|
5576
|
-
}
|
|
5577
|
-
// Set the server-side timeout query parameter "timeout=[seconds]"
|
|
5578
|
-
if (this.retryOptions.tryTimeoutInMs) {
|
|
5579
|
-
newRequest.url = setURLParameter(newRequest.url, UrlConstants.Parameters.TIMEOUT, Math.floor(this.retryOptions.tryTimeoutInMs / 1000).toString());
|
|
5580
|
-
}
|
|
5581
|
-
let response;
|
|
5582
|
-
try {
|
|
5583
|
-
logger.info(`RetryPolicy: =====> Try=${attempt} ${isPrimaryRetry ? "Primary" : "Secondary"}`);
|
|
5584
|
-
response = await this._nextPolicy.sendRequest(newRequest);
|
|
5585
|
-
if (!this.shouldRetry(isPrimaryRetry, attempt, response)) {
|
|
5586
|
-
return response;
|
|
5587
|
-
}
|
|
5588
|
-
secondaryHas404 = secondaryHas404 || (!isPrimaryRetry && response.status === 404);
|
|
5589
|
-
}
|
|
5590
|
-
catch (err) {
|
|
5591
|
-
logger.error(`RetryPolicy: Caught error, message: ${err.message}, code: ${err.code}`);
|
|
5592
|
-
if (!this.shouldRetry(isPrimaryRetry, attempt, response, err)) {
|
|
5593
|
-
throw err;
|
|
5594
|
-
}
|
|
5595
|
-
}
|
|
5596
|
-
await this.delay(isPrimaryRetry, attempt, request.abortSignal);
|
|
5597
|
-
return this.attemptSendRequest(request, secondaryHas404, ++attempt);
|
|
5598
|
-
}
|
|
5599
|
-
/**
|
|
5600
|
-
* Decide whether to retry according to last HTTP response and retry counters.
|
|
5601
|
-
*
|
|
5602
|
-
* @param isPrimaryRetry -
|
|
5603
|
-
* @param attempt -
|
|
5604
|
-
* @param response -
|
|
5605
|
-
* @param err -
|
|
5606
|
-
*/
|
|
5607
|
-
shouldRetry(isPrimaryRetry, attempt, response, err) {
|
|
5608
|
-
if (attempt >= this.retryOptions.maxTries) {
|
|
5609
|
-
logger.info(`RetryPolicy: Attempt(s) ${attempt} >= maxTries ${this.retryOptions
|
|
5610
|
-
.maxTries}, no further try.`);
|
|
5611
|
-
return false;
|
|
5612
|
-
}
|
|
5613
|
-
// Handle network failures, you may need to customize the list when you implement
|
|
5614
|
-
// your own http client
|
|
5615
|
-
const retriableErrors = [
|
|
5616
|
-
"ETIMEDOUT",
|
|
5617
|
-
"ESOCKETTIMEDOUT",
|
|
5618
|
-
"ECONNREFUSED",
|
|
5619
|
-
"ECONNRESET",
|
|
5620
|
-
"ENOENT",
|
|
5621
|
-
"ENOTFOUND",
|
|
5622
|
-
"TIMEOUT",
|
|
5623
|
-
"EPIPE",
|
|
5624
|
-
"REQUEST_SEND_ERROR", // For default xhr based http client provided in ms-rest-js
|
|
5625
|
-
];
|
|
5626
|
-
if (err) {
|
|
5627
|
-
for (const retriableError of retriableErrors) {
|
|
5628
|
-
if (err.name.toUpperCase().includes(retriableError) ||
|
|
5629
|
-
err.message.toUpperCase().includes(retriableError) ||
|
|
5630
|
-
(err.code && err.code.toString().toUpperCase() === retriableError)) {
|
|
5631
|
-
logger.info(`RetryPolicy: Network error ${retriableError} found, will retry.`);
|
|
5632
|
-
return true;
|
|
5633
|
-
}
|
|
5634
|
-
}
|
|
5635
|
-
}
|
|
5636
|
-
// If attempt was against the secondary & it returned a StatusNotFound (404), then
|
|
5637
|
-
// the resource was not found. This may be due to replication delay. So, in this
|
|
5638
|
-
// case, we'll never try the secondary again for this operation.
|
|
5639
|
-
if (response || err) {
|
|
5640
|
-
const statusCode = response ? response.status : err ? err.statusCode : 0;
|
|
5641
|
-
if (!isPrimaryRetry && statusCode === 404) {
|
|
5642
|
-
logger.info(`RetryPolicy: Secondary access with 404, will retry.`);
|
|
5643
|
-
return true;
|
|
5644
|
-
}
|
|
5645
|
-
// Server internal error or server timeout
|
|
5646
|
-
if (statusCode === 503 || statusCode === 500) {
|
|
5647
|
-
logger.info(`RetryPolicy: Will retry for status code ${statusCode}.`);
|
|
5648
|
-
return true;
|
|
5649
|
-
}
|
|
5650
|
-
}
|
|
5651
|
-
if ((err === null || err === void 0 ? void 0 : err.code) === "PARSE_ERROR" && (err === null || err === void 0 ? void 0 : err.message.startsWith(`Error "Error: Unclosed root tag`))) {
|
|
5652
|
-
logger.info("RetryPolicy: Incomplete XML response likely due to service timeout, will retry.");
|
|
5653
|
-
return true;
|
|
5654
|
-
}
|
|
5655
|
-
return false;
|
|
5656
|
-
}
|
|
5657
|
-
/**
|
|
5658
|
-
* Delay a calculated time between retries.
|
|
5659
|
-
*
|
|
5660
|
-
* @param isPrimaryRetry -
|
|
5661
|
-
* @param attempt -
|
|
5662
|
-
* @param abortSignal -
|
|
5663
|
-
*/
|
|
5664
|
-
async delay(isPrimaryRetry, attempt, abortSignal) {
|
|
5665
|
-
let delayTimeInMs = 0;
|
|
5666
|
-
if (isPrimaryRetry) {
|
|
5667
|
-
switch (this.retryOptions.retryPolicyType) {
|
|
5668
|
-
case exports.StorageRetryPolicyType.EXPONENTIAL:
|
|
5669
|
-
delayTimeInMs = Math.min((Math.pow(2, attempt - 1) - 1) * this.retryOptions.retryDelayInMs, this.retryOptions.maxRetryDelayInMs);
|
|
5670
|
-
break;
|
|
5671
|
-
case exports.StorageRetryPolicyType.FIXED:
|
|
5672
|
-
delayTimeInMs = this.retryOptions.retryDelayInMs;
|
|
5673
|
-
break;
|
|
5674
|
-
}
|
|
5675
|
-
}
|
|
5676
|
-
else {
|
|
5677
|
-
delayTimeInMs = Math.random() * 1000;
|
|
5678
|
-
}
|
|
5679
|
-
logger.info(`RetryPolicy: Delay for ${delayTimeInMs}ms`);
|
|
5680
|
-
return delay(delayTimeInMs, abortSignal, RETRY_ABORT_ERROR);
|
|
5681
|
-
}
|
|
5682
|
-
}
|
|
5683
|
-
|
|
5684
|
-
// Copyright (c) Microsoft Corporation.
|
|
5685
|
-
/**
|
|
5686
|
-
* StorageRetryPolicyFactory is a factory class helping generating {@link StorageRetryPolicy} objects.
|
|
5687
|
-
*/
|
|
5688
|
-
class StorageRetryPolicyFactory {
|
|
5689
|
-
/**
|
|
5690
|
-
* Creates an instance of StorageRetryPolicyFactory.
|
|
5691
|
-
* @param retryOptions -
|
|
5692
|
-
*/
|
|
5693
|
-
constructor(retryOptions) {
|
|
5694
|
-
this.retryOptions = retryOptions;
|
|
5695
|
-
}
|
|
5696
|
-
/**
|
|
5697
|
-
* Creates a StorageRetryPolicy object.
|
|
5698
|
-
*
|
|
5699
|
-
* @param nextPolicy -
|
|
5700
|
-
* @param options -
|
|
5701
|
-
*/
|
|
5702
|
-
create(nextPolicy, options) {
|
|
5703
|
-
return new StorageRetryPolicy(nextPolicy, options, this.retryOptions);
|
|
5704
|
-
}
|
|
5705
|
-
}
|
|
5706
|
-
|
|
5707
|
-
// Copyright (c) Microsoft Corporation.
|
|
5708
|
-
/**
|
|
5709
|
-
* TelemetryPolicy is a policy used to tag user-agent header for every requests.
|
|
5710
|
-
*/
|
|
5711
|
-
class TelemetryPolicy extends coreHttp.BaseRequestPolicy {
|
|
5712
|
-
/**
|
|
5713
|
-
* Creates an instance of TelemetryPolicy.
|
|
5714
|
-
* @param nextPolicy -
|
|
5715
|
-
* @param options -
|
|
5716
|
-
* @param telemetry -
|
|
5717
|
-
*/
|
|
5718
|
-
constructor(nextPolicy, options, telemetry) {
|
|
5719
|
-
super(nextPolicy, options);
|
|
5720
|
-
this.telemetry = telemetry;
|
|
5721
|
-
}
|
|
5722
|
-
/**
|
|
5723
|
-
* Sends out request.
|
|
5724
|
-
*
|
|
5725
|
-
* @param request -
|
|
5726
|
-
*/
|
|
5727
|
-
async sendRequest(request) {
|
|
5728
|
-
if (coreHttp.isNode) {
|
|
5729
|
-
if (!request.headers) {
|
|
5730
|
-
request.headers = new coreHttp.HttpHeaders();
|
|
5731
|
-
}
|
|
5732
|
-
if (!request.headers.get(HeaderConstants.USER_AGENT)) {
|
|
5733
|
-
request.headers.set(HeaderConstants.USER_AGENT, this.telemetry);
|
|
5734
|
-
}
|
|
5735
|
-
}
|
|
5736
|
-
return this._nextPolicy.sendRequest(request);
|
|
5737
|
-
}
|
|
5738
|
-
}
|
|
5739
|
-
|
|
5740
|
-
// Copyright (c) Microsoft Corporation.
|
|
5741
|
-
/**
|
|
5742
|
-
* TelemetryPolicyFactory is a factory class helping generating {@link TelemetryPolicy} objects.
|
|
5743
|
-
*/
|
|
5744
|
-
class TelemetryPolicyFactory {
|
|
5745
|
-
/**
|
|
5746
|
-
* Creates an instance of TelemetryPolicyFactory.
|
|
5747
|
-
* @param telemetry -
|
|
5748
|
-
*/
|
|
5749
|
-
constructor(telemetry) {
|
|
5750
|
-
const userAgentInfo = [];
|
|
5751
|
-
if (coreHttp.isNode) {
|
|
5752
|
-
if (telemetry) {
|
|
5753
|
-
const telemetryString = telemetry.userAgentPrefix || "";
|
|
5754
|
-
if (telemetryString.length > 0 && userAgentInfo.indexOf(telemetryString) === -1) {
|
|
5755
|
-
userAgentInfo.push(telemetryString);
|
|
5756
|
-
}
|
|
5757
|
-
}
|
|
5758
|
-
// e.g. azsdk-js-storagedatalake/10.0.0
|
|
5759
|
-
const libInfo = `azsdk-js-storagedatalake/${SDK_VERSION}`;
|
|
5760
|
-
if (userAgentInfo.indexOf(libInfo) === -1) {
|
|
5761
|
-
userAgentInfo.push(libInfo);
|
|
5762
|
-
}
|
|
5763
|
-
// e.g. (NODE-VERSION 4.9.1; Windows_NT 10.0.16299)
|
|
5764
|
-
let runtimeInfo = `(NODE-VERSION ${process.version})`;
|
|
5765
|
-
if (os__namespace) {
|
|
5766
|
-
runtimeInfo = `(NODE-VERSION ${process.version}; ${os__namespace.type()} ${os__namespace.release()})`;
|
|
5767
|
-
}
|
|
5768
|
-
if (userAgentInfo.indexOf(runtimeInfo) === -1) {
|
|
5769
|
-
userAgentInfo.push(runtimeInfo);
|
|
5770
|
-
}
|
|
5771
|
-
}
|
|
5772
|
-
this.telemetryString = userAgentInfo.join(" ");
|
|
5773
|
-
}
|
|
5774
|
-
/**
|
|
5775
|
-
* Creates a TelemetryPolicy object.
|
|
5776
|
-
*
|
|
5777
|
-
* @param nextPolicy -
|
|
5778
|
-
* @param options -
|
|
5779
|
-
*/
|
|
5780
|
-
create(nextPolicy, options) {
|
|
5781
|
-
return new TelemetryPolicy(nextPolicy, options, this.telemetryString);
|
|
5782
|
-
}
|
|
5783
|
-
}
|
|
5784
|
-
|
|
5785
|
-
// Copyright (c) Microsoft Corporation.
|
|
5786
|
-
const _defaultHttpClient = new coreHttp.DefaultHttpClient();
|
|
5787
|
-
function getCachedDefaultHttpClient() {
|
|
5788
|
-
return _defaultHttpClient;
|
|
5789
|
-
}
|
|
5790
|
-
|
|
5791
|
-
// Copyright (c) Microsoft Corporation.
|
|
5792
|
-
/**
|
|
5793
|
-
* A Pipeline class containing HTTP request policies.
|
|
5794
|
-
* You can create a default Pipeline by calling {@link newPipeline}.
|
|
5795
|
-
* Or you can create a Pipeline with your own policies by the constructor of Pipeline.
|
|
5796
|
-
*
|
|
5797
|
-
* Refer to {@link newPipeline} and provided policies before implementing your
|
|
5798
|
-
* customized Pipeline.
|
|
5799
|
-
*/
|
|
5800
|
-
class Pipeline {
|
|
5801
|
-
/**
|
|
5802
|
-
* Creates an instance of Pipeline. Customize HTTPClient by implementing IHttpClient interface.
|
|
5803
|
-
*
|
|
5804
|
-
* @param factories -
|
|
5805
|
-
* @param options -
|
|
5806
|
-
*/
|
|
5807
|
-
constructor(factories, options = {}) {
|
|
5808
|
-
this.factories = factories;
|
|
5809
|
-
// when options.httpClient is not specified, passing in a DefaultHttpClient instance to
|
|
5810
|
-
// avoid each client creating its own http client.
|
|
5811
|
-
this.options = Object.assign(Object.assign({}, options), { httpClient: options.httpClient || getCachedDefaultHttpClient() });
|
|
5812
|
-
}
|
|
5813
|
-
/**
|
|
5814
|
-
* Transfer Pipeline object to ServiceClientOptions object which is required by
|
|
5815
|
-
* ServiceClient constructor.
|
|
5816
|
-
*
|
|
5817
|
-
* @returns The ServiceClientOptions object from this Pipeline.
|
|
5818
|
-
*/
|
|
5819
|
-
toServiceClientOptions() {
|
|
5820
|
-
return {
|
|
5821
|
-
httpClient: this.options.httpClient,
|
|
5822
|
-
requestPolicyFactories: this.factories,
|
|
5823
|
-
};
|
|
5824
|
-
}
|
|
5825
|
-
}
|
|
5826
|
-
/**
|
|
5827
|
-
* Creates a new Pipeline object with Credential provided.
|
|
5828
|
-
*
|
|
5829
|
-
* @param credential - Such as AnonymousCredential, StorageSharedKeyCredential or any credential from the `@azure/identity` package to authenticate requests to the service. You can also provide an object that implements the TokenCredential interface. If not specified, AnonymousCredential is used.
|
|
5830
|
-
* @param pipelineOptions - Optional. Options.
|
|
5831
|
-
* @returns A new Pipeline object.
|
|
5832
|
-
*/
|
|
5833
|
-
function newPipeline(credential, pipelineOptions = {}) {
|
|
5834
|
-
if (credential === undefined) {
|
|
5835
|
-
credential = new AnonymousCredential();
|
|
5836
|
-
}
|
|
5837
|
-
// Order is important. Closer to the API at the top & closer to the network at the bottom.
|
|
5838
|
-
// The credential's policy factory must appear close to the wire so it can sign any
|
|
5839
|
-
// changes made by other factories (like UniqueRequestIDPolicyFactory)
|
|
5840
|
-
const telemetryPolicy = new TelemetryPolicyFactory(pipelineOptions.userAgentOptions);
|
|
5841
|
-
const factories = [
|
|
5842
|
-
coreHttp.tracingPolicy({ userAgent: telemetryPolicy.telemetryString }),
|
|
5843
|
-
coreHttp.keepAlivePolicy(pipelineOptions.keepAliveOptions),
|
|
5844
|
-
telemetryPolicy,
|
|
5845
|
-
coreHttp.generateClientRequestIdPolicy(),
|
|
5846
|
-
new StorageBrowserPolicyFactory(),
|
|
5847
|
-
new StorageRetryPolicyFactory(pipelineOptions.retryOptions),
|
|
5848
|
-
coreHttp.deserializationPolicy(),
|
|
5849
|
-
coreHttp.logPolicy({
|
|
5850
|
-
logger: logger.info,
|
|
5851
|
-
allowedHeaderNames: StorageDataLakeLoggingAllowedHeaderNames,
|
|
5852
|
-
allowedQueryParameters: StorageDataLakeLoggingAllowedQueryParameters,
|
|
5853
|
-
}),
|
|
5854
|
-
];
|
|
5855
|
-
if (coreHttp.isNode) {
|
|
5856
|
-
// policies only available in Node.js runtime, not in browsers
|
|
5857
|
-
factories.push(coreHttp.proxyPolicy(pipelineOptions.proxyOptions));
|
|
5858
|
-
factories.push(coreHttp.disableResponseDecompressionPolicy());
|
|
5859
|
-
}
|
|
5860
|
-
factories.push(coreHttp.isTokenCredential(credential)
|
|
5861
|
-
? attachCredential(coreHttp.bearerTokenAuthenticationPolicy(credential, StorageOAuthScopes), credential)
|
|
5862
|
-
: credential);
|
|
5863
|
-
return new Pipeline(factories, pipelineOptions);
|
|
5864
|
-
}
|
|
5865
|
-
/**
|
|
5866
|
-
* Attach a TokenCredential to an object.
|
|
5867
|
-
*
|
|
5868
|
-
* @param thing -
|
|
5869
|
-
* @param credential -
|
|
5870
|
-
*/
|
|
5871
|
-
function attachCredential(thing, credential) {
|
|
5872
|
-
thing.credential = credential;
|
|
5873
|
-
return thing;
|
|
5874
|
-
}
|
|
5875
|
-
|
|
5876
|
-
/*
|
|
5877
|
-
* Copyright (c) Microsoft Corporation.
|
|
5878
|
-
* Licensed under the MIT License.
|
|
5879
|
-
*
|
|
5880
|
-
* Code generated by Microsoft (R) AutoRest Code Generator.
|
|
5881
|
-
* Changes may cause incorrect behavior and will be lost if the code is regenerated.
|
|
5882
|
-
*/
|
|
5883
|
-
const packageName = "azure-storage-datalake";
|
|
5884
|
-
const packageVersion = "12.13.0";
|
|
5885
|
-
class StorageClientContext extends coreHttp__namespace.ServiceClient {
|
|
5886
|
-
/**
|
|
5887
|
-
* Initializes a new instance of the StorageClientContext class.
|
|
5888
|
-
* @param url The URL of the service account, container, or blob that is the target of the desired
|
|
5889
|
-
* operation.
|
|
5890
|
-
* @param options The parameter options
|
|
5891
|
-
*/
|
|
5892
|
-
constructor(url, options) {
|
|
5893
|
-
if (url === undefined) {
|
|
5894
|
-
throw new Error("'url' cannot be null");
|
|
5895
|
-
}
|
|
5896
|
-
// Initializing default values for options
|
|
5897
|
-
if (!options) {
|
|
5898
|
-
options = {};
|
|
5661
|
+
accept2,
|
|
5662
|
+
contentLength,
|
|
5663
|
+
leaseAction,
|
|
5664
|
+
contentType2,
|
|
5665
|
+
transactionalContentHash,
|
|
5666
|
+
transactionalContentCrc64
|
|
5667
|
+
],
|
|
5668
|
+
mediaType: "binary",
|
|
5669
|
+
serializer
|
|
5670
|
+
};
|
|
5671
|
+
const setExpiryOperationSpec = {
|
|
5672
|
+
path: "/{filesystem}/{path}",
|
|
5673
|
+
httpMethod: "PUT",
|
|
5674
|
+
responses: {
|
|
5675
|
+
200: {
|
|
5676
|
+
headersMapper: PathSetExpiryHeaders
|
|
5677
|
+
},
|
|
5678
|
+
default: {
|
|
5679
|
+
bodyMapper: StorageError,
|
|
5680
|
+
headersMapper: PathSetExpiryExceptionHeaders
|
|
5899
5681
|
}
|
|
5900
|
-
|
|
5901
|
-
|
|
5902
|
-
|
|
5682
|
+
},
|
|
5683
|
+
queryParameters: [timeout, comp1],
|
|
5684
|
+
urlParameters: [url],
|
|
5685
|
+
headerParameters: [
|
|
5686
|
+
accept,
|
|
5687
|
+
requestId,
|
|
5688
|
+
version,
|
|
5689
|
+
expiresOn,
|
|
5690
|
+
expiryOptions1
|
|
5691
|
+
],
|
|
5692
|
+
serializer
|
|
5693
|
+
};
|
|
5694
|
+
const undeleteOperationSpec = {
|
|
5695
|
+
path: "/{filesystem}/{path}",
|
|
5696
|
+
httpMethod: "PUT",
|
|
5697
|
+
responses: {
|
|
5698
|
+
200: {
|
|
5699
|
+
headersMapper: PathUndeleteHeaders
|
|
5700
|
+
},
|
|
5701
|
+
default: {
|
|
5702
|
+
bodyMapper: StorageError,
|
|
5703
|
+
headersMapper: PathUndeleteExceptionHeaders
|
|
5903
5704
|
}
|
|
5904
|
-
|
|
5905
|
-
|
|
5906
|
-
|
|
5907
|
-
|
|
5908
|
-
|
|
5909
|
-
|
|
5910
|
-
|
|
5911
|
-
|
|
5912
|
-
|
|
5913
|
-
|
|
5705
|
+
},
|
|
5706
|
+
queryParameters: [timeout, comp2],
|
|
5707
|
+
urlParameters: [url],
|
|
5708
|
+
headerParameters: [
|
|
5709
|
+
accept,
|
|
5710
|
+
requestId,
|
|
5711
|
+
version,
|
|
5712
|
+
undeleteSource
|
|
5713
|
+
],
|
|
5714
|
+
serializer
|
|
5715
|
+
};
|
|
5914
5716
|
|
|
5915
5717
|
// Copyright (c) Microsoft Corporation.
|
|
5916
5718
|
/**
|
|
5917
|
-
*
|
|
5918
|
-
* Only handle known host name pair patterns, add more patterns into ToBlobEndpointHostMappings in constants.ts.
|
|
5919
|
-
*
|
|
5920
|
-
* Expected input and outputs:
|
|
5921
|
-
* http://account.blob.core.windows.net - http://account.blob.core.windows.net
|
|
5922
|
-
* http://account.dfs.core.windows.net - http://account.blob.core.windows.net
|
|
5923
|
-
* http://127.0.0.1:10000 - http://127.0.0.1:10000
|
|
5924
|
-
* http://account.blob.core.windows.net/abc - http://account.blob.core.windows.net/abc
|
|
5925
|
-
* http://account.dfs.core.windows.net/abc - http://account.blob.core.windows.net/abc
|
|
5926
|
-
* http://127.0.0.1:10000/abc - http://127.0.0.1:10000/abc
|
|
5927
|
-
*
|
|
5928
|
-
* @param url -
|
|
5719
|
+
* The `@azure/logger` configuration for this package.
|
|
5929
5720
|
*/
|
|
5930
|
-
|
|
5931
|
-
|
|
5932
|
-
|
|
5933
|
-
if (host === undefined) {
|
|
5934
|
-
throw RangeError(`toBlobEndpointUrl() parameter url ${url} doesn't include valid host.`);
|
|
5935
|
-
}
|
|
5936
|
-
for (const mapping of ToBlobEndpointHostMappings) {
|
|
5937
|
-
if (host.includes(mapping[0])) {
|
|
5938
|
-
host = host.replace(mapping[0], mapping[1]);
|
|
5939
|
-
break;
|
|
5940
|
-
}
|
|
5941
|
-
}
|
|
5942
|
-
urlParsed.setHost(host);
|
|
5943
|
-
return urlParsed.toString();
|
|
5944
|
-
}
|
|
5721
|
+
const logger = logger$1.createClientLogger("storage-file-datalake");
|
|
5722
|
+
|
|
5723
|
+
// Copyright (c) Microsoft Corporation.
|
|
5945
5724
|
/**
|
|
5946
|
-
*
|
|
5947
|
-
* Only handle known host name pair patterns, add more patterns into ToDfsEndpointHostMappings in constants.ts.
|
|
5725
|
+
* StorageBrowserPolicy will handle differences between Node.js and browser runtime, including:
|
|
5948
5726
|
*
|
|
5949
|
-
*
|
|
5950
|
-
*
|
|
5951
|
-
*
|
|
5952
|
-
* http://127.0.0.1:10000 - http://127.0.0.1:10000
|
|
5953
|
-
* http://account.blob.core.windows.net/abc - http://account.dfs.core.windows.net/abc
|
|
5954
|
-
* http://account.dfs.core.windows.net/abc - http://account.dfs.core.windows.net/abc
|
|
5955
|
-
* http://127.0.0.1:10000/abc - http://127.0.0.1:10000/abc
|
|
5727
|
+
* 1. Browsers cache GET/HEAD requests by adding conditional headers such as 'IF_MODIFIED_SINCE'.
|
|
5728
|
+
* StorageBrowserPolicy is a policy used to add a timestamp query to GET/HEAD request URL
|
|
5729
|
+
* thus avoid the browser cache.
|
|
5956
5730
|
*
|
|
5957
|
-
*
|
|
5731
|
+
* 2. Remove cookie header for security
|
|
5732
|
+
*
|
|
5733
|
+
* 3. Remove content-length header to avoid browsers warning
|
|
5958
5734
|
*/
|
|
5959
|
-
|
|
5960
|
-
|
|
5961
|
-
|
|
5962
|
-
|
|
5963
|
-
|
|
5735
|
+
class StorageBrowserPolicy extends coreHttp.BaseRequestPolicy {
|
|
5736
|
+
/**
|
|
5737
|
+
* Creates an instance of StorageBrowserPolicy.
|
|
5738
|
+
* @param nextPolicy -
|
|
5739
|
+
* @param options -
|
|
5740
|
+
*/
|
|
5741
|
+
// The base class has a protected constructor. Adding a public one to enable constructing of this class.
|
|
5742
|
+
/* eslint-disable-next-line @typescript-eslint/no-useless-constructor*/
|
|
5743
|
+
constructor(nextPolicy, options) {
|
|
5744
|
+
super(nextPolicy, options);
|
|
5964
5745
|
}
|
|
5965
|
-
|
|
5966
|
-
|
|
5967
|
-
|
|
5968
|
-
|
|
5746
|
+
/**
|
|
5747
|
+
* Sends out request.
|
|
5748
|
+
*
|
|
5749
|
+
* @param request -
|
|
5750
|
+
*/
|
|
5751
|
+
async sendRequest(request) {
|
|
5752
|
+
if (coreHttp.isNode) {
|
|
5753
|
+
return this._nextPolicy.sendRequest(request);
|
|
5969
5754
|
}
|
|
5970
|
-
|
|
5971
|
-
|
|
5972
|
-
return urlParsed.toString();
|
|
5973
|
-
}
|
|
5974
|
-
function toFileSystemAsyncIterableIterator(iter) {
|
|
5975
|
-
return {
|
|
5976
|
-
async next() {
|
|
5977
|
-
const rawResult = await iter.next();
|
|
5978
|
-
if (rawResult.value) {
|
|
5979
|
-
rawResult.value.fileSystemItems = rawResult.value.containerItems.map((val) => {
|
|
5980
|
-
return Object.assign(Object.assign({}, val), { versionId: val.version, properties: Object.assign(Object.assign({}, val.properties), { publicAccess: toPublicAccessType(val.properties.publicAccess) }) });
|
|
5981
|
-
});
|
|
5982
|
-
}
|
|
5983
|
-
return rawResult;
|
|
5984
|
-
},
|
|
5985
|
-
[Symbol.asyncIterator]() {
|
|
5986
|
-
return this;
|
|
5987
|
-
},
|
|
5988
|
-
};
|
|
5989
|
-
}
|
|
5990
|
-
function toFileSystemPagedAsyncIterableIterator(iter) {
|
|
5991
|
-
return {
|
|
5992
|
-
async next() {
|
|
5993
|
-
const rawResult = await iter.next();
|
|
5994
|
-
const result = rawResult;
|
|
5995
|
-
if (!result.done && !rawResult.done) {
|
|
5996
|
-
result.value.properties.publicAccess = toPublicAccessType(rawResult.value.properties.publicAccess);
|
|
5997
|
-
result.value.versionId = rawResult.value.version;
|
|
5998
|
-
}
|
|
5999
|
-
return result;
|
|
6000
|
-
},
|
|
6001
|
-
[Symbol.asyncIterator]() {
|
|
6002
|
-
return this;
|
|
6003
|
-
},
|
|
6004
|
-
byPage(settings = {}) {
|
|
6005
|
-
return toFileSystemAsyncIterableIterator(iter.byPage(settings));
|
|
6006
|
-
},
|
|
6007
|
-
};
|
|
6008
|
-
}
|
|
6009
|
-
function toContainerPublicAccessType(publicAccessType) {
|
|
6010
|
-
if (!publicAccessType) {
|
|
6011
|
-
return undefined;
|
|
6012
|
-
}
|
|
6013
|
-
switch (publicAccessType) {
|
|
6014
|
-
case "filesystem":
|
|
6015
|
-
return "container";
|
|
6016
|
-
case "file":
|
|
6017
|
-
return "blob";
|
|
6018
|
-
default:
|
|
6019
|
-
throw TypeError(`toContainerPublicAccessType() parameter ${publicAccessType} is not recognized.`);
|
|
6020
|
-
}
|
|
6021
|
-
}
|
|
6022
|
-
function toPublicAccessType(containerPublicAccessType) {
|
|
6023
|
-
if (!containerPublicAccessType) {
|
|
6024
|
-
return undefined;
|
|
6025
|
-
}
|
|
6026
|
-
switch (containerPublicAccessType) {
|
|
6027
|
-
case "container":
|
|
6028
|
-
return "filesystem";
|
|
6029
|
-
case "blob":
|
|
6030
|
-
return "file";
|
|
6031
|
-
default:
|
|
6032
|
-
throw TypeError(`toPublicAccessType() parameter ${containerPublicAccessType} is not recognized.`);
|
|
6033
|
-
}
|
|
6034
|
-
}
|
|
6035
|
-
function toProperties(metadata) {
|
|
6036
|
-
if (metadata === undefined) {
|
|
6037
|
-
return undefined;
|
|
6038
|
-
}
|
|
6039
|
-
const properties = [];
|
|
6040
|
-
for (const key in metadata) {
|
|
6041
|
-
if (Object.prototype.hasOwnProperty.call(metadata, key)) {
|
|
6042
|
-
const value = metadata[key];
|
|
6043
|
-
properties.push(`${key}=${base64encode(value)}`);
|
|
5755
|
+
if (request.method.toUpperCase() === "GET" || request.method.toUpperCase() === "HEAD") {
|
|
5756
|
+
request.url = setURLParameter(request.url, UrlConstants.Parameters.FORCE_BROWSER_NO_CACHE, new Date().getTime().toString());
|
|
6044
5757
|
}
|
|
5758
|
+
request.headers.remove(HeaderConstants.COOKIE);
|
|
5759
|
+
// According to XHR standards, content-length should be fully controlled by browsers
|
|
5760
|
+
request.headers.remove(HeaderConstants.CONTENT_LENGTH);
|
|
5761
|
+
// DFS flush file API requires content-length=0, workaround to force browsers add content-length header
|
|
5762
|
+
if (request.method === "PATCH" && request.body === undefined) {
|
|
5763
|
+
request.body = "";
|
|
5764
|
+
}
|
|
5765
|
+
return this._nextPolicy.sendRequest(request);
|
|
6045
5766
|
}
|
|
6046
|
-
return properties.join(",");
|
|
6047
|
-
}
|
|
6048
|
-
function toPathGetAccessControlResponse(response) {
|
|
6049
|
-
return Object.assign(Object.assign({}, response), { _response: response._response, permissions: toPermissions(response.permissions), acl: toAcl(response.acl) });
|
|
6050
5767
|
}
|
|
6051
|
-
|
|
6052
|
-
|
|
6053
|
-
|
|
6054
|
-
|
|
6055
|
-
|
|
6056
|
-
|
|
6057
|
-
|
|
6058
|
-
|
|
6059
|
-
|
|
6060
|
-
|
|
6061
|
-
|
|
6062
|
-
|
|
6063
|
-
|
|
6064
|
-
|
|
6065
|
-
if (permissionsString[1] === "w") {
|
|
6066
|
-
write = true;
|
|
6067
|
-
}
|
|
6068
|
-
else if (permissionsString[1] !== "-") {
|
|
6069
|
-
throw error;
|
|
6070
|
-
}
|
|
6071
|
-
let execute = false;
|
|
6072
|
-
if (permissionsString[2] === "x") {
|
|
6073
|
-
execute = true;
|
|
6074
|
-
}
|
|
6075
|
-
else if (permissionsString[2] !== "-") {
|
|
6076
|
-
throw error;
|
|
5768
|
+
|
|
5769
|
+
// Copyright (c) Microsoft Corporation.
|
|
5770
|
+
/**
|
|
5771
|
+
* StorageBrowserPolicyFactory is a factory class helping generating StorageBrowserPolicy objects.
|
|
5772
|
+
*/
|
|
5773
|
+
class StorageBrowserPolicyFactory {
|
|
5774
|
+
/**
|
|
5775
|
+
* Creates a StorageBrowserPolicyFactory object.
|
|
5776
|
+
*
|
|
5777
|
+
* @param nextPolicy -
|
|
5778
|
+
* @param options -
|
|
5779
|
+
*/
|
|
5780
|
+
create(nextPolicy, options) {
|
|
5781
|
+
return new StorageBrowserPolicy(nextPolicy, options);
|
|
6077
5782
|
}
|
|
6078
|
-
return { read, write, execute };
|
|
6079
5783
|
}
|
|
6080
|
-
|
|
6081
|
-
|
|
6082
|
-
|
|
5784
|
+
|
|
5785
|
+
// Copyright (c) Microsoft Corporation.
|
|
5786
|
+
/**
|
|
5787
|
+
* RetryPolicy types.
|
|
5788
|
+
*/
|
|
5789
|
+
exports.StorageRetryPolicyType = void 0;
|
|
5790
|
+
(function (StorageRetryPolicyType) {
|
|
5791
|
+
/**
|
|
5792
|
+
* Exponential retry. Retry time delay grows exponentially.
|
|
5793
|
+
*/
|
|
5794
|
+
StorageRetryPolicyType[StorageRetryPolicyType["EXPONENTIAL"] = 0] = "EXPONENTIAL";
|
|
5795
|
+
/**
|
|
5796
|
+
* Linear retry. Retry time delay grows linearly.
|
|
5797
|
+
*/
|
|
5798
|
+
StorageRetryPolicyType[StorageRetryPolicyType["FIXED"] = 1] = "FIXED";
|
|
5799
|
+
})(exports.StorageRetryPolicyType || (exports.StorageRetryPolicyType = {}));
|
|
5800
|
+
// Default values of StorageRetryOptions
|
|
5801
|
+
const DEFAULT_RETRY_OPTIONS = {
|
|
5802
|
+
maxRetryDelayInMs: 120 * 1000,
|
|
5803
|
+
maxTries: 4,
|
|
5804
|
+
retryDelayInMs: 4 * 1000,
|
|
5805
|
+
retryPolicyType: exports.StorageRetryPolicyType.EXPONENTIAL,
|
|
5806
|
+
secondaryHost: "",
|
|
5807
|
+
tryTimeoutInMs: undefined, // Use server side default timeout strategy
|
|
5808
|
+
};
|
|
5809
|
+
const RETRY_ABORT_ERROR = new abortController.AbortError("The operation was aborted.");
|
|
5810
|
+
/**
|
|
5811
|
+
* Retry policy with exponential retry and linear retry implemented.
|
|
5812
|
+
*/
|
|
5813
|
+
class StorageRetryPolicy extends coreHttp.BaseRequestPolicy {
|
|
5814
|
+
/**
|
|
5815
|
+
* Creates an instance of RetryPolicy.
|
|
5816
|
+
*
|
|
5817
|
+
* @param nextPolicy -
|
|
5818
|
+
* @param options -
|
|
5819
|
+
* @param retryOptions -
|
|
5820
|
+
*/
|
|
5821
|
+
constructor(nextPolicy, options, retryOptions = DEFAULT_RETRY_OPTIONS) {
|
|
5822
|
+
super(nextPolicy, options);
|
|
5823
|
+
// Initialize retry options
|
|
5824
|
+
this.retryOptions = {
|
|
5825
|
+
retryPolicyType: retryOptions.retryPolicyType
|
|
5826
|
+
? retryOptions.retryPolicyType
|
|
5827
|
+
: DEFAULT_RETRY_OPTIONS.retryPolicyType,
|
|
5828
|
+
maxTries: retryOptions.maxTries && retryOptions.maxTries >= 1
|
|
5829
|
+
? Math.floor(retryOptions.maxTries)
|
|
5830
|
+
: DEFAULT_RETRY_OPTIONS.maxTries,
|
|
5831
|
+
tryTimeoutInMs: retryOptions.tryTimeoutInMs && retryOptions.tryTimeoutInMs >= 0
|
|
5832
|
+
? retryOptions.tryTimeoutInMs
|
|
5833
|
+
: DEFAULT_RETRY_OPTIONS.tryTimeoutInMs,
|
|
5834
|
+
retryDelayInMs: retryOptions.retryDelayInMs && retryOptions.retryDelayInMs >= 0
|
|
5835
|
+
? Math.min(retryOptions.retryDelayInMs, retryOptions.maxRetryDelayInMs
|
|
5836
|
+
? retryOptions.maxRetryDelayInMs
|
|
5837
|
+
: DEFAULT_RETRY_OPTIONS.maxRetryDelayInMs)
|
|
5838
|
+
: DEFAULT_RETRY_OPTIONS.retryDelayInMs,
|
|
5839
|
+
maxRetryDelayInMs: retryOptions.maxRetryDelayInMs && retryOptions.maxRetryDelayInMs >= 0
|
|
5840
|
+
? retryOptions.maxRetryDelayInMs
|
|
5841
|
+
: DEFAULT_RETRY_OPTIONS.maxRetryDelayInMs,
|
|
5842
|
+
secondaryHost: retryOptions.secondaryHost
|
|
5843
|
+
? retryOptions.secondaryHost
|
|
5844
|
+
: DEFAULT_RETRY_OPTIONS.secondaryHost,
|
|
5845
|
+
};
|
|
6083
5846
|
}
|
|
6084
|
-
|
|
6085
|
-
|
|
5847
|
+
/**
|
|
5848
|
+
* Sends request.
|
|
5849
|
+
*
|
|
5850
|
+
* @param request -
|
|
5851
|
+
*/
|
|
5852
|
+
async sendRequest(request) {
|
|
5853
|
+
return this.attemptSendRequest(request, false, 1);
|
|
6086
5854
|
}
|
|
6087
|
-
|
|
6088
|
-
|
|
6089
|
-
|
|
6090
|
-
|
|
6091
|
-
|
|
6092
|
-
|
|
5855
|
+
/**
|
|
5856
|
+
* Decide and perform next retry. Won't mutate request parameter.
|
|
5857
|
+
*
|
|
5858
|
+
* @param request -
|
|
5859
|
+
* @param secondaryHas404 - If attempt was against the secondary & it returned a StatusNotFound (404), then
|
|
5860
|
+
* the resource was not found. This may be due to replication delay. So, in this
|
|
5861
|
+
* case, we'll never try the secondary again for this operation.
|
|
5862
|
+
* @param attempt - How many retries has been attempted to performed, starting from 1, which includes
|
|
5863
|
+
* the attempt will be performed by this method call.
|
|
5864
|
+
*/
|
|
5865
|
+
async attemptSendRequest(request, secondaryHas404, attempt) {
|
|
5866
|
+
const newRequest = request.clone();
|
|
5867
|
+
const isPrimaryRetry = secondaryHas404 ||
|
|
5868
|
+
!this.retryOptions.secondaryHost ||
|
|
5869
|
+
!(request.method === "GET" || request.method === "HEAD" || request.method === "OPTIONS") ||
|
|
5870
|
+
attempt % 2 === 1;
|
|
5871
|
+
if (!isPrimaryRetry) {
|
|
5872
|
+
newRequest.url = setURLHost(newRequest.url, this.retryOptions.secondaryHost);
|
|
5873
|
+
}
|
|
5874
|
+
// Set the server-side timeout query parameter "timeout=[seconds]"
|
|
5875
|
+
if (this.retryOptions.tryTimeoutInMs) {
|
|
5876
|
+
newRequest.url = setURLParameter(newRequest.url, UrlConstants.Parameters.TIMEOUT, Math.floor(this.retryOptions.tryTimeoutInMs / 1000).toString());
|
|
5877
|
+
}
|
|
5878
|
+
let response;
|
|
5879
|
+
try {
|
|
5880
|
+
logger.info(`RetryPolicy: =====> Try=${attempt} ${isPrimaryRetry ? "Primary" : "Secondary"}`);
|
|
5881
|
+
response = await this._nextPolicy.sendRequest(newRequest);
|
|
5882
|
+
if (!this.shouldRetry(isPrimaryRetry, attempt, response)) {
|
|
5883
|
+
return response;
|
|
5884
|
+
}
|
|
5885
|
+
secondaryHas404 = secondaryHas404 || (!isPrimaryRetry && response.status === 404);
|
|
5886
|
+
}
|
|
5887
|
+
catch (err) {
|
|
5888
|
+
logger.error(`RetryPolicy: Caught error, message: ${err.message}, code: ${err.code}`);
|
|
5889
|
+
if (!this.shouldRetry(isPrimaryRetry, attempt, response, err)) {
|
|
5890
|
+
throw err;
|
|
5891
|
+
}
|
|
5892
|
+
}
|
|
5893
|
+
await this.delay(isPrimaryRetry, attempt, request.abortSignal);
|
|
5894
|
+
return this.attemptSendRequest(request, secondaryHas404, ++attempt);
|
|
6093
5895
|
}
|
|
6094
|
-
|
|
6095
|
-
|
|
6096
|
-
|
|
6097
|
-
|
|
6098
|
-
|
|
5896
|
+
/**
|
|
5897
|
+
* Decide whether to retry according to last HTTP response and retry counters.
|
|
5898
|
+
*
|
|
5899
|
+
* @param isPrimaryRetry -
|
|
5900
|
+
* @param attempt -
|
|
5901
|
+
* @param response -
|
|
5902
|
+
* @param err -
|
|
5903
|
+
*/
|
|
5904
|
+
shouldRetry(isPrimaryRetry, attempt, response, err) {
|
|
5905
|
+
if (attempt >= this.retryOptions.maxTries) {
|
|
5906
|
+
logger.info(`RetryPolicy: Attempt(s) ${attempt} >= maxTries ${this.retryOptions
|
|
5907
|
+
.maxTries}, no further try.`);
|
|
5908
|
+
return false;
|
|
5909
|
+
}
|
|
5910
|
+
// Handle network failures, you may need to customize the list when you implement
|
|
5911
|
+
// your own http client
|
|
5912
|
+
const retriableErrors = [
|
|
5913
|
+
"ETIMEDOUT",
|
|
5914
|
+
"ESOCKETTIMEDOUT",
|
|
5915
|
+
"ECONNREFUSED",
|
|
5916
|
+
"ECONNRESET",
|
|
5917
|
+
"ENOENT",
|
|
5918
|
+
"ENOTFOUND",
|
|
5919
|
+
"TIMEOUT",
|
|
5920
|
+
"EPIPE",
|
|
5921
|
+
"REQUEST_SEND_ERROR", // For default xhr based http client provided in ms-rest-js
|
|
5922
|
+
];
|
|
5923
|
+
if (err) {
|
|
5924
|
+
for (const retriableError of retriableErrors) {
|
|
5925
|
+
if (err.name.toUpperCase().includes(retriableError) ||
|
|
5926
|
+
err.message.toUpperCase().includes(retriableError) ||
|
|
5927
|
+
(err.code && err.code.toString().toUpperCase() === retriableError)) {
|
|
5928
|
+
logger.info(`RetryPolicy: Network error ${retriableError} found, will retry.`);
|
|
5929
|
+
return true;
|
|
5930
|
+
}
|
|
5931
|
+
}
|
|
5932
|
+
}
|
|
5933
|
+
// If attempt was against the secondary & it returned a StatusNotFound (404), then
|
|
5934
|
+
// the resource was not found. This may be due to replication delay. So, in this
|
|
5935
|
+
// case, we'll never try the secondary again for this operation.
|
|
5936
|
+
if (response || err) {
|
|
5937
|
+
const statusCode = response ? response.status : err ? err.statusCode : 0;
|
|
5938
|
+
if (!isPrimaryRetry && statusCode === 404) {
|
|
5939
|
+
logger.info(`RetryPolicy: Secondary access with 404, will retry.`);
|
|
5940
|
+
return true;
|
|
5941
|
+
}
|
|
5942
|
+
// Server internal error or server timeout
|
|
5943
|
+
if (statusCode === 503 || statusCode === 500) {
|
|
5944
|
+
logger.info(`RetryPolicy: Will retry for status code ${statusCode}.`);
|
|
5945
|
+
return true;
|
|
5946
|
+
}
|
|
5947
|
+
}
|
|
5948
|
+
if ((err === null || err === void 0 ? void 0 : err.code) === "PARSE_ERROR" && (err === null || err === void 0 ? void 0 : err.message.startsWith(`Error "Error: Unclosed root tag`))) {
|
|
5949
|
+
logger.info("RetryPolicy: Incomplete XML response likely due to service timeout, will retry.");
|
|
5950
|
+
return true;
|
|
5951
|
+
}
|
|
5952
|
+
return false;
|
|
6099
5953
|
}
|
|
6100
|
-
|
|
6101
|
-
|
|
6102
|
-
|
|
6103
|
-
|
|
6104
|
-
|
|
6105
|
-
|
|
5954
|
+
/**
|
|
5955
|
+
* Delay a calculated time between retries.
|
|
5956
|
+
*
|
|
5957
|
+
* @param isPrimaryRetry -
|
|
5958
|
+
* @param attempt -
|
|
5959
|
+
* @param abortSignal -
|
|
5960
|
+
*/
|
|
5961
|
+
async delay(isPrimaryRetry, attempt, abortSignal) {
|
|
5962
|
+
let delayTimeInMs = 0;
|
|
5963
|
+
if (isPrimaryRetry) {
|
|
5964
|
+
switch (this.retryOptions.retryPolicyType) {
|
|
5965
|
+
case exports.StorageRetryPolicyType.EXPONENTIAL:
|
|
5966
|
+
delayTimeInMs = Math.min((Math.pow(2, attempt - 1) - 1) * this.retryOptions.retryDelayInMs, this.retryOptions.maxRetryDelayInMs);
|
|
5967
|
+
break;
|
|
5968
|
+
case exports.StorageRetryPolicyType.FIXED:
|
|
5969
|
+
delayTimeInMs = this.retryOptions.retryDelayInMs;
|
|
5970
|
+
break;
|
|
5971
|
+
}
|
|
6106
5972
|
}
|
|
6107
5973
|
else {
|
|
6108
|
-
|
|
5974
|
+
delayTimeInMs = Math.random() * 1000;
|
|
6109
5975
|
}
|
|
5976
|
+
logger.info(`RetryPolicy: Delay for ${delayTimeInMs}ms`);
|
|
5977
|
+
return delay(delayTimeInMs, abortSignal, RETRY_ABORT_ERROR);
|
|
6110
5978
|
}
|
|
6111
|
-
const owner = toRolePermissions(permissionsString.substr(0, 3));
|
|
6112
|
-
const group = toRolePermissions(permissionsString.substr(3, 3));
|
|
6113
|
-
const other = toRolePermissions(permissionsString.substr(6, 3));
|
|
6114
|
-
return {
|
|
6115
|
-
owner,
|
|
6116
|
-
group,
|
|
6117
|
-
other,
|
|
6118
|
-
stickyBit,
|
|
6119
|
-
extendedAcls,
|
|
6120
|
-
};
|
|
6121
5979
|
}
|
|
6122
|
-
|
|
6123
|
-
|
|
6124
|
-
|
|
6125
|
-
|
|
5980
|
+
|
|
5981
|
+
// Copyright (c) Microsoft Corporation.
|
|
5982
|
+
/**
|
|
5983
|
+
* StorageRetryPolicyFactory is a factory class helping generating {@link StorageRetryPolicy} objects.
|
|
5984
|
+
*/
|
|
5985
|
+
class StorageRetryPolicyFactory {
|
|
5986
|
+
/**
|
|
5987
|
+
* Creates an instance of StorageRetryPolicyFactory.
|
|
5988
|
+
* @param retryOptions -
|
|
5989
|
+
*/
|
|
5990
|
+
constructor(retryOptions) {
|
|
5991
|
+
this.retryOptions = retryOptions;
|
|
5992
|
+
}
|
|
5993
|
+
/**
|
|
5994
|
+
* Creates a StorageRetryPolicy object.
|
|
5995
|
+
*
|
|
5996
|
+
* @param nextPolicy -
|
|
5997
|
+
* @param options -
|
|
5998
|
+
*/
|
|
5999
|
+
create(nextPolicy, options) {
|
|
6000
|
+
return new StorageRetryPolicy(nextPolicy, options, this.retryOptions);
|
|
6126
6001
|
}
|
|
6127
|
-
|
|
6128
|
-
|
|
6129
|
-
|
|
6130
|
-
|
|
6002
|
+
}
|
|
6003
|
+
|
|
6004
|
+
// Copyright (c) Microsoft Corporation.
|
|
6005
|
+
/**
|
|
6006
|
+
* TelemetryPolicy is a policy used to tag user-agent header for every requests.
|
|
6007
|
+
*/
|
|
6008
|
+
class TelemetryPolicy extends coreHttp.BaseRequestPolicy {
|
|
6009
|
+
/**
|
|
6010
|
+
* Creates an instance of TelemetryPolicy.
|
|
6011
|
+
* @param nextPolicy -
|
|
6012
|
+
* @param options -
|
|
6013
|
+
* @param telemetry -
|
|
6014
|
+
*/
|
|
6015
|
+
constructor(nextPolicy, options, telemetry) {
|
|
6016
|
+
super(nextPolicy, options);
|
|
6017
|
+
this.telemetry = telemetry;
|
|
6131
6018
|
}
|
|
6132
|
-
|
|
6133
|
-
|
|
6134
|
-
|
|
6135
|
-
|
|
6136
|
-
|
|
6019
|
+
/**
|
|
6020
|
+
* Sends out request.
|
|
6021
|
+
*
|
|
6022
|
+
* @param request -
|
|
6023
|
+
*/
|
|
6024
|
+
async sendRequest(request) {
|
|
6025
|
+
if (coreHttp.isNode) {
|
|
6026
|
+
if (!request.headers) {
|
|
6027
|
+
request.headers = new coreHttp.HttpHeaders();
|
|
6028
|
+
}
|
|
6029
|
+
if (!request.headers.get(HeaderConstants.USER_AGENT)) {
|
|
6030
|
+
request.headers.set(HeaderConstants.USER_AGENT, this.telemetry);
|
|
6031
|
+
}
|
|
6137
6032
|
}
|
|
6138
|
-
|
|
6139
|
-
index++;
|
|
6140
|
-
}
|
|
6141
|
-
const accessControlType = parts[index++];
|
|
6142
|
-
if (accessControlType !== "user" &&
|
|
6143
|
-
accessControlType !== "group" &&
|
|
6144
|
-
accessControlType !== "mask" &&
|
|
6145
|
-
accessControlType !== "other") {
|
|
6146
|
-
throw error;
|
|
6033
|
+
return this._nextPolicy.sendRequest(request);
|
|
6147
6034
|
}
|
|
6148
|
-
const entityId = parts[index++];
|
|
6149
|
-
const permissions = toRolePermissions(parts[index++]);
|
|
6150
|
-
return {
|
|
6151
|
-
defaultScope,
|
|
6152
|
-
accessControlType,
|
|
6153
|
-
entityId,
|
|
6154
|
-
permissions,
|
|
6155
|
-
};
|
|
6156
6035
|
}
|
|
6157
|
-
|
|
6158
|
-
|
|
6159
|
-
|
|
6036
|
+
|
|
6037
|
+
// Copyright (c) Microsoft Corporation.
|
|
6038
|
+
/**
|
|
6039
|
+
* TelemetryPolicyFactory is a factory class helping generating {@link TelemetryPolicy} objects.
|
|
6040
|
+
*/
|
|
6041
|
+
class TelemetryPolicyFactory {
|
|
6042
|
+
/**
|
|
6043
|
+
* Creates an instance of TelemetryPolicyFactory.
|
|
6044
|
+
* @param telemetry -
|
|
6045
|
+
*/
|
|
6046
|
+
constructor(telemetry) {
|
|
6047
|
+
const userAgentInfo = [];
|
|
6048
|
+
if (coreHttp.isNode) {
|
|
6049
|
+
if (telemetry) {
|
|
6050
|
+
const telemetryString = telemetry.userAgentPrefix || "";
|
|
6051
|
+
if (telemetryString.length > 0 && userAgentInfo.indexOf(telemetryString) === -1) {
|
|
6052
|
+
userAgentInfo.push(telemetryString);
|
|
6053
|
+
}
|
|
6054
|
+
}
|
|
6055
|
+
// e.g. azsdk-js-storagedatalake/10.0.0
|
|
6056
|
+
const libInfo = `azsdk-js-storagedatalake/${SDK_VERSION}`;
|
|
6057
|
+
if (userAgentInfo.indexOf(libInfo) === -1) {
|
|
6058
|
+
userAgentInfo.push(libInfo);
|
|
6059
|
+
}
|
|
6060
|
+
// e.g. (NODE-VERSION 4.9.1; Windows_NT 10.0.16299)
|
|
6061
|
+
let runtimeInfo = `(NODE-VERSION ${process.version})`;
|
|
6062
|
+
if (os__namespace) {
|
|
6063
|
+
runtimeInfo = `(NODE-VERSION ${process.version}; ${os__namespace.type()} ${os__namespace.release()})`;
|
|
6064
|
+
}
|
|
6065
|
+
if (userAgentInfo.indexOf(runtimeInfo) === -1) {
|
|
6066
|
+
userAgentInfo.push(runtimeInfo);
|
|
6067
|
+
}
|
|
6068
|
+
}
|
|
6069
|
+
this.telemetryString = userAgentInfo.join(" ");
|
|
6160
6070
|
}
|
|
6161
|
-
|
|
6162
|
-
|
|
6163
|
-
|
|
6164
|
-
|
|
6071
|
+
/**
|
|
6072
|
+
* Creates a TelemetryPolicy object.
|
|
6073
|
+
*
|
|
6074
|
+
* @param nextPolicy -
|
|
6075
|
+
* @param options -
|
|
6076
|
+
*/
|
|
6077
|
+
create(nextPolicy, options) {
|
|
6078
|
+
return new TelemetryPolicy(nextPolicy, options, this.telemetryString);
|
|
6165
6079
|
}
|
|
6166
|
-
return acls;
|
|
6167
|
-
}
|
|
6168
|
-
function toAccessControlItemString(item) {
|
|
6169
|
-
const entityIdString = item.entityId !== undefined ? `:${item.entityId}` : "";
|
|
6170
|
-
const permissionsString = item.permissions !== undefined ? `:${toRolePermissionsString(item.permissions)}` : "";
|
|
6171
|
-
return `${item.defaultScope ? "default:" : ""}${item.accessControlType}${entityIdString}${permissionsString}`;
|
|
6172
|
-
}
|
|
6173
|
-
function toAclString(acl) {
|
|
6174
|
-
return acl.map(toAccessControlItemString).join(",");
|
|
6175
6080
|
}
|
|
6176
|
-
|
|
6177
|
-
|
|
6178
|
-
|
|
6179
|
-
function
|
|
6180
|
-
return
|
|
6081
|
+
|
|
6082
|
+
// Copyright (c) Microsoft Corporation.
|
|
6083
|
+
const _defaultHttpClient = new coreHttp.DefaultHttpClient();
|
|
6084
|
+
function getCachedDefaultHttpClient() {
|
|
6085
|
+
return _defaultHttpClient;
|
|
6181
6086
|
}
|
|
6182
|
-
|
|
6183
|
-
|
|
6087
|
+
|
|
6088
|
+
// Copyright (c) Microsoft Corporation.
|
|
6089
|
+
/**
|
|
6090
|
+
* A Pipeline class containing HTTP request policies.
|
|
6091
|
+
* You can create a default Pipeline by calling {@link newPipeline}.
|
|
6092
|
+
* Or you can create a Pipeline with your own policies by the constructor of Pipeline.
|
|
6093
|
+
*
|
|
6094
|
+
* Refer to {@link newPipeline} and provided policies before implementing your
|
|
6095
|
+
* customized Pipeline.
|
|
6096
|
+
*/
|
|
6097
|
+
class Pipeline {
|
|
6098
|
+
/**
|
|
6099
|
+
* Creates an instance of Pipeline. Customize HTTPClient by implementing IHttpClient interface.
|
|
6100
|
+
*
|
|
6101
|
+
* @param factories -
|
|
6102
|
+
* @param options -
|
|
6103
|
+
*/
|
|
6104
|
+
constructor(factories, options = {}) {
|
|
6105
|
+
this.factories = factories;
|
|
6106
|
+
// when options.httpClient is not specified, passing in a DefaultHttpClient instance to
|
|
6107
|
+
// avoid each client creating its own http client.
|
|
6108
|
+
this.options = Object.assign(Object.assign({}, options), { httpClient: options.httpClient || getCachedDefaultHttpClient() });
|
|
6109
|
+
}
|
|
6110
|
+
/**
|
|
6111
|
+
* Transfer Pipeline object to ServiceClientOptions object which is required by
|
|
6112
|
+
* ServiceClient constructor.
|
|
6113
|
+
*
|
|
6114
|
+
* @returns The ServiceClientOptions object from this Pipeline.
|
|
6115
|
+
*/
|
|
6116
|
+
toServiceClientOptions() {
|
|
6184
6117
|
return {
|
|
6185
|
-
|
|
6186
|
-
|
|
6187
|
-
message: aclFailedEntry.errorMessage || "",
|
|
6118
|
+
httpClient: this.options.httpClient,
|
|
6119
|
+
requestPolicyFactories: this.factories,
|
|
6188
6120
|
};
|
|
6189
|
-
}
|
|
6121
|
+
}
|
|
6190
6122
|
}
|
|
6191
|
-
|
|
6192
|
-
|
|
6193
|
-
|
|
6194
|
-
|
|
6195
|
-
|
|
6196
|
-
|
|
6123
|
+
/**
|
|
6124
|
+
* Creates a new Pipeline object with Credential provided.
|
|
6125
|
+
*
|
|
6126
|
+
* @param credential - Such as AnonymousCredential, StorageSharedKeyCredential or any credential from the `@azure/identity` package to authenticate requests to the service. You can also provide an object that implements the TokenCredential interface. If not specified, AnonymousCredential is used.
|
|
6127
|
+
* @param pipelineOptions - Optional. Options.
|
|
6128
|
+
* @returns A new Pipeline object.
|
|
6129
|
+
*/
|
|
6130
|
+
function newPipeline(credential, pipelineOptions = {}) {
|
|
6131
|
+
if (credential === undefined) {
|
|
6132
|
+
credential = new AnonymousCredential();
|
|
6133
|
+
}
|
|
6134
|
+
// Order is important. Closer to the API at the top & closer to the network at the bottom.
|
|
6135
|
+
// The credential's policy factory must appear close to the wire so it can sign any
|
|
6136
|
+
// changes made by other factories (like UniqueRequestIDPolicyFactory)
|
|
6137
|
+
const telemetryPolicy = new TelemetryPolicyFactory(pipelineOptions.userAgentOptions);
|
|
6138
|
+
const factories = [
|
|
6139
|
+
coreHttp.tracingPolicy({ userAgent: telemetryPolicy.telemetryString }),
|
|
6140
|
+
coreHttp.keepAlivePolicy(pipelineOptions.keepAliveOptions),
|
|
6141
|
+
telemetryPolicy,
|
|
6142
|
+
coreHttp.generateClientRequestIdPolicy(),
|
|
6143
|
+
new StorageBrowserPolicyFactory(),
|
|
6144
|
+
new StorageRetryPolicyFactory(pipelineOptions.retryOptions),
|
|
6145
|
+
coreHttp.deserializationPolicy(),
|
|
6146
|
+
coreHttp.logPolicy({
|
|
6147
|
+
logger: logger.info,
|
|
6148
|
+
allowedHeaderNames: StorageDataLakeLoggingAllowedHeaderNames,
|
|
6149
|
+
allowedQueryParameters: StorageDataLakeLoggingAllowedQueryParameters,
|
|
6150
|
+
}),
|
|
6151
|
+
];
|
|
6152
|
+
if (coreHttp.isNode) {
|
|
6153
|
+
// policies only available in Node.js runtime, not in browsers
|
|
6154
|
+
factories.push(coreHttp.proxyPolicy(pipelineOptions.proxyOptions));
|
|
6155
|
+
factories.push(coreHttp.disableResponseDecompressionPolicy());
|
|
6156
|
+
}
|
|
6157
|
+
factories.push(coreHttp.isTokenCredential(credential)
|
|
6158
|
+
? attachCredential(coreHttp.bearerTokenAuthenticationPolicy(credential, StorageOAuthScopes), credential)
|
|
6159
|
+
: credential);
|
|
6160
|
+
return new Pipeline(factories, pipelineOptions);
|
|
6161
|
+
}
|
|
6162
|
+
/**
|
|
6163
|
+
* Attach a TokenCredential to an object.
|
|
6164
|
+
*
|
|
6165
|
+
* @param thing -
|
|
6166
|
+
* @param credential -
|
|
6167
|
+
*/
|
|
6168
|
+
function attachCredential(thing, credential) {
|
|
6169
|
+
thing.credential = credential;
|
|
6170
|
+
return thing;
|
|
6171
|
+
}
|
|
6172
|
+
|
|
6173
|
+
/*
|
|
6174
|
+
* Copyright (c) Microsoft Corporation.
|
|
6175
|
+
* Licensed under the MIT License.
|
|
6176
|
+
*
|
|
6177
|
+
* Code generated by Microsoft (R) AutoRest Code Generator.
|
|
6178
|
+
* Changes may cause incorrect behavior and will be lost if the code is regenerated.
|
|
6179
|
+
*/
|
|
6180
|
+
const packageName = "azure-storage-datalake";
|
|
6181
|
+
const packageVersion = "12.14.0";
|
|
6182
|
+
class StorageClientContext extends coreHttp__namespace.ServiceClient {
|
|
6183
|
+
/**
|
|
6184
|
+
* Initializes a new instance of the StorageClientContext class.
|
|
6185
|
+
* @param url The URL of the service account, container, or blob that is the target of the desired
|
|
6186
|
+
* operation.
|
|
6187
|
+
* @param options The parameter options
|
|
6188
|
+
*/
|
|
6189
|
+
constructor(url, options) {
|
|
6190
|
+
if (url === undefined) {
|
|
6191
|
+
throw new Error("'url' cannot be null");
|
|
6197
6192
|
}
|
|
6198
|
-
|
|
6193
|
+
// Initializing default values for options
|
|
6194
|
+
if (!options) {
|
|
6195
|
+
options = {};
|
|
6196
|
+
}
|
|
6197
|
+
if (!options.userAgent) {
|
|
6198
|
+
const defaultUserAgent = coreHttp__namespace.getDefaultUserAgentValue();
|
|
6199
|
+
options.userAgent = `${packageName}/${packageVersion} ${defaultUserAgent}`;
|
|
6200
|
+
}
|
|
6201
|
+
super(undefined, options);
|
|
6202
|
+
this.requestContentType = "application/json; charset=utf-8";
|
|
6203
|
+
this.baseUri = options.endpoint || "{url}";
|
|
6204
|
+
// Parameter assignments
|
|
6205
|
+
this.url = url;
|
|
6206
|
+
// Assigning values to Constant parameters
|
|
6207
|
+
this.version = options.version || "2023-01-03";
|
|
6208
|
+
this.resource = options.resource || "filesystem";
|
|
6209
|
+
}
|
|
6199
6210
|
}
|
|
6200
6211
|
|
|
6201
6212
|
// Copyright (c) Microsoft Corporation.
|
|
@@ -8570,7 +8581,7 @@ class DataLakePathClient extends StorageClient {
|
|
|
8570
8581
|
const { span, updatedOptions } = createSpan("DataLakePathClient-getProperties", options);
|
|
8571
8582
|
try {
|
|
8572
8583
|
const response = (await this.blobClient.getProperties(Object.assign(Object.assign({}, options), { customerProvidedKey: toBlobCpkInfo(options.customerProvidedKey), tracingOptions: updatedOptions.tracingOptions })));
|
|
8573
|
-
return
|
|
8584
|
+
return ParsePathGetPropertiesExtraHeaderValues(response);
|
|
8574
8585
|
}
|
|
8575
8586
|
catch (e) {
|
|
8576
8587
|
span.setStatus({
|
|
@@ -8914,7 +8925,7 @@ class DataLakeFileClient extends DataLakePathClient {
|
|
|
8914
8925
|
const { span, updatedOptions } = createSpan("DataLakeFileClient-read", options);
|
|
8915
8926
|
try {
|
|
8916
8927
|
const rawResponse = await this.blockBlobClientInternal.download(offset, count, Object.assign(Object.assign({}, updatedOptions), { customerProvidedKey: toBlobCpkInfo(updatedOptions.customerProvidedKey) }));
|
|
8917
|
-
const response =
|
|
8928
|
+
const response = ParsePathGetPropertiesExtraHeaderValues(rawResponse);
|
|
8918
8929
|
if (!coreHttp.isNode && !response.contentAsBlob) {
|
|
8919
8930
|
response.contentAsBlob = rawResponse.blobBody;
|
|
8920
8931
|
}
|