From 89e60a45e9d483a244a1123ac31bbef3adb19923 Mon Sep 17 00:00:00 2001 From: Ajay Gaur Date: Tue, 19 Jun 2018 14:59:14 +0530 Subject: [PATCH 1/8] Resolves the issue of user agent is being set even if the process is started from browser --- lib/common/services/storageserviceclient.js | 90 +++++++++++---------- 1 file changed, 46 insertions(+), 44 deletions(-) diff --git a/lib/common/services/storageserviceclient.js b/lib/common/services/storageserviceclient.js index a4dfdbca..66d31b07 100644 --- a/lib/common/services/storageserviceclient.js +++ b/lib/common/services/storageserviceclient.js @@ -1,18 +1,18 @@ -// +// // Copyright (c) Microsoft and contributors. All rights reserved. -// +// // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // http://www.apache.org/licenses/LICENSE-2.0 -// +// // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// +// // See the License for the specific language governing permissions and // limitations under the License. -// +// // Module dependencies. var request = require('../request-wrapper'); @@ -254,12 +254,14 @@ StorageServiceClient.prototype._performRequest = function (webResource, body, op if(!options.clientRequestId) { options.clientRequestId = guid.v1(); } - + webResource.withHeader(HeaderConstants.CLIENT_REQUEST_ID, options.clientRequestId); - // Sets the user-agent string - var userAgentComment = util.format('(NODE-VERSION %s; %s %s)', process.version, os.type(), os.release()); - webResource.withHeader(HeaderConstants.USER_AGENT, Constants.USER_AGENT_PRODUCT_NAME + '/' + Constants.USER_AGENT_PRODUCT_VERSION + ' ' + userAgentComment); + // Sets the user-agent string if the process is not started by the browser + if(!process.browser) { + var userAgentComment = util.format('(NODE-VERSION %s; %s %s)', process.version, os.type(), os.release()); + webResource.withHeader(HeaderConstants.USER_AGENT, Constants.USER_AGENT_PRODUCT_NAME + '/' + Constants.USER_AGENT_PRODUCT_VERSION + ' ' + userAgentComment); + } // Initialize the location that the request is going to be sent to. if(azureutil.objectIsNull(options.locationMode)) { @@ -277,18 +279,18 @@ StorageServiceClient.prototype._performRequest = function (webResource, body, op } this._initializeLocation(options); - + // Initialize the operationExpiryTime this._setOperationExpiryTime(options); - // If the output stream already got sent to server and got error back, + // If the output stream already got sent to server and got error back, // we should NOT retry within the SDK as the stream data is not valid anymore if we retry directly. // And it's very hard for SDK to re-wind the stream. // - // If users want to retry on this kind of error, they can implement their own logic to parse the response and + // If users want to retry on this kind of error, they can implement their own logic to parse the response and // determine if they need to re-prepare a stream and call our SDK API to retry. // - // Currently for blobs/files with size greater than 32MB (DEFAULT_SINGLE_BLOB_PUT_THRESHOLD_IN_BYTES), + // Currently for blobs/files with size greater than 32MB (DEFAULT_SINGLE_BLOB_PUT_THRESHOLD_IN_BYTES), // we'll send the steam by chunk buffers which doesn't have this issue. var outputStreamSent = false; @@ -333,7 +335,7 @@ StorageServiceClient.prototype._performRequest = function (webResource, body, op var requestStream; var requestWithDefaults; - + if(self.proxy) { if(requestWithDefaults === undefined) { requestWithDefaults = request.defaults({'proxy':self.proxy}); @@ -356,7 +358,7 @@ StorageServiceClient.prototype._performRequest = function (webResource, body, op if (contentLength !== undefined) { errorMessageBuffer = new Buffer(contentLength); } - + requestStream.on('data', function (data) { if (contentLength !== undefined) { data.copy(errorMessageBuffer, index); @@ -402,7 +404,7 @@ StorageServiceClient.prototype._performRequest = function (webResource, body, op if(azureutil.objectIsNull(options.disableContentMD5Validation) || options.disableContentMD5Validation === false) { response.contentMD5 = internalHash.digest('base64'); } - + response.length = responseLength; endResponse = response; }); @@ -443,7 +445,7 @@ StorageServiceClient.prototype._performRequest = function (webResource, body, op if (!azureutil.isBrowser() && Buffer.isBuffer(body.outputData)) { // Request module will take 200MB additional memory when we pass a 100MB buffer as body // Transfer buffer to stream will highly reduce the memory used by request module - finalRequestOptions.body = new BufferStream(body.outputData); + finalRequestOptions.body = new BufferStream(body.outputData); } else { finalRequestOptions.body = body.outputData; } @@ -578,10 +580,10 @@ StorageServiceClient.prototype._buildRequestOptions = function (webResource, bod } webResource.withHeader(HeaderConstants.ACCEPT_CHARSET, 'UTF-8'); - // Browsers cache GET/HEAD requests by adding conditional headers such as 'IF_MODIFIED_SINCE' after Azure Storage 'Authorization header' calculation, - // which may result in a 403 authorization error. So add timestamp to GET/HEAD request URLs thus avoid the browser cache. + // Browsers cache GET/HEAD requests by adding conditional headers such as 'IF_MODIFIED_SINCE' after Azure Storage 'Authorization header' calculation, + // which may result in a 403 authorization error. So add timestamp to GET/HEAD request URLs thus avoid the browser cache. if (azureutil.isBrowser() && ( - webResource.method === Constants.HttpConstants.HttpVerbs.GET || + webResource.method === Constants.HttpConstants.HttpVerbs.GET || webResource.method === Constants.HttpConstants.HttpVerbs.HEAD)) { webResource.withQueryOption(HeaderConstants.FORCE_NO_CACHE_IN_BROWSER, new Date().getTime()); } @@ -597,7 +599,7 @@ StorageServiceClient.prototype._buildRequestOptions = function (webResource, bod if(!azureutil.objectIsNull(options.timeoutIntervalInMs) && options.timeoutIntervalInMs > 0) { webResource.withQueryOption(QueryStringConstants.TIMEOUT, Math.ceil(options.timeoutIntervalInMs / 1000)); } - + if(options.accessConditions) { webResource.withHeader(HeaderConstants.IF_MATCH, options.accessConditions.EtagMatch); webResource.withHeader(HeaderConstants.IF_MODIFIED_SINCE, options.accessConditions.DateModifedSince); @@ -616,7 +618,7 @@ StorageServiceClient.prototype._buildRequestOptions = function (webResource, bod webResource.withHeader(HeaderConstants.SOURCE_IF_NONE_MATCH, options.sourceAccessConditions.EtagNonMatch); webResource.withHeader(HeaderConstants.SOURCE_IF_UNMODIFIED_SINCE, options.sourceAccessConditions.DateUnModifiedSince); } - + if (!webResource.headers || webResource.headers[HeaderConstants.CONTENT_TYPE] === undefined) { // work around to add an empty content type header to prevent the request module from magically adding a content type. webResource.headers[HeaderConstants.CONTENT_TYPE] = ''; @@ -657,7 +659,7 @@ StorageServiceClient.prototype._buildRequestOptions = function (webResource, bod //set encoding of response data. If set to null, the body is returned as a Buffer requestOptions.encoding = options.responseEncoding; } - + if (options && options.clientRequestTimeoutInMs) { requestOptions.timeout = options.clientRequestTimeoutInMs; } else { @@ -946,7 +948,7 @@ StorageServiceClient.prototype._setRequestUrl = function (webResource, options) if(host && host.lastIndexOf('/') !== (host.length - 1)){ host = host + '/'; } - + var fullPath = url.format({pathname: webResource.path, query: webResource.queryString}); webResource.uri = url.resolve(host, fullPath); webResource.path = url.parse(webResource.uri).pathname; @@ -1033,7 +1035,7 @@ StorageServiceClient.prototype.parseMetadataHeaders = function (headers) { metadata[key] = headers[header]; } } - + return metadata; }; @@ -1043,7 +1045,7 @@ StorageServiceClient.prototype.parseMetadataHeaders = function (headers) { * * @this {StorageServiceClient} * @param {object} [options] The request options. -* @param {LocationMode} [options.locationMode] Specifies the location mode used to decide which location the request should be sent to. +* @param {LocationMode} [options.locationMode] Specifies the location mode used to decide which location the request should be sent to. * Please see StorageUtilities.LocationMode for the possible values. * @param {int} [options.timeoutIntervalInMs] The server timeout interval, in milliseconds, to use for the request. * @param {int} [options.clientRequestTimeoutInMs] The timeout of client requests, in milliseconds, to use for the request. @@ -1052,40 +1054,40 @@ StorageServiceClient.prototype.parseMetadataHeaders = function (headers) { * execution time is checked intermittently while performing requests, and before executing retries. * @param {bool} [options.useNagleAlgorithm] Determines whether the Nagle algorithm is used; true to use the Nagle algorithm; otherwise, false. * The default value is false. -* @param {errorOrResult} callback `error` will contain information if an error occurs; otherwise, `result` will contain the properties +* @param {errorOrResult} callback `error` will contain information if an error occurs; otherwise, `result` will contain the properties * and `response` will contain information related to this operation. */ StorageServiceClient.prototype.getAccountServiceProperties = function (optionsOrCallback, callback) { var userOptions; azureutil.normalizeArgs(optionsOrCallback, callback, function (o, c) { userOptions = o; callback = c; }); - + validate.validateArgs('getServiceProperties', function (v) { v.callback(callback); }); - + var options = extend(true, {}, userOptions); - + var webResource = WebResource.get() .withQueryOption(QueryStringConstants.COMP, 'properties') .withQueryOption(QueryStringConstants.RESTYPE, 'service'); - + options.requestLocationMode = RequestLocationMode.PRIMARY_OR_SECONDARY; - + var processResponseCallback = function (responseObject, next) { responseObject.servicePropertiesResult = null; if (!responseObject.error) { responseObject.servicePropertiesResult = ServicePropertiesResult.parse(responseObject.response.body.StorageServiceProperties); } - + // function to be called after all filters var finalCallback = function (returnObject) { callback(returnObject.error, returnObject.servicePropertiesResult, returnObject.response); }; - + // call the first filter next(responseObject, finalCallback); }; - + this.performRequest(webResource, null, options, processResponseCallback); }; @@ -1096,7 +1098,7 @@ StorageServiceClient.prototype.getAccountServiceProperties = function (optionsOr * @this {StorageServiceClient} * @param {object} serviceProperties The service properties. * @param {object} [options] The request options. -* @param {LocationMode} [options.locationMode] Specifies the location mode used to decide which location the request should be sent to. +* @param {LocationMode} [options.locationMode] Specifies the location mode used to decide which location the request should be sent to. * Please see StorageUtilities.LocationMode for the possible values. * @param {int} [options.timeoutIntervalInMs] The server timeout interval, in milliseconds, to use for the request. * @param {int} [options.clientRequestTimeoutInMs] The timeout of client requests, in milliseconds, to use for the request. @@ -1112,30 +1114,30 @@ StorageServiceClient.prototype.getAccountServiceProperties = function (optionsOr StorageServiceClient.prototype.setAccountServiceProperties = function (serviceProperties, optionsOrCallback, callback) { var userOptions; azureutil.normalizeArgs(optionsOrCallback, callback, function (o, c) { userOptions = o; callback = c; }); - + validate.validateArgs('setServiceProperties', function (v) { v.object(serviceProperties, 'serviceProperties'); v.callback(callback); }); - + var options = extend(true, {}, userOptions); var servicePropertiesXml = ServicePropertiesResult.serialize(serviceProperties); - + var webResource = WebResource.put() .withQueryOption(QueryStringConstants.COMP, 'properties') .withQueryOption(QueryStringConstants.RESTYPE, 'service') .withHeader(HeaderConstants.CONTENT_TYPE, 'application/xml;charset="utf-8"') .withHeader(HeaderConstants.CONTENT_LENGTH, Buffer.byteLength(servicePropertiesXml)) .withBody(servicePropertiesXml); - + var processResponseCallback = function (responseObject, next) { var finalCallback = function (returnObject) { callback(returnObject.error, returnObject.response); }; - + next(responseObject, finalCallback); }; - + this.performRequest(webResource, webResource.body, options, processResponseCallback); }; @@ -1164,14 +1166,14 @@ StorageServiceClient._normalizeError = function (error, response) { // blob/queue errors should have error.Error, table errors should have error['odata.error'] var errorProperties = error.Error || error.error || error['odata.error'] || error['m:error'] || error; normalizedError.code = errorProperties.message; // The message exists when there is error.Error. - + for (var property in errorProperties) { if (errorProperties.hasOwnProperty(property)) { var key = property.toLowerCase(); if(key.indexOf('m:') === 0) { key = key.substring(2); } - + normalizedError[key] = errorProperties[property]; // if this is a table error, message is an object - flatten it to normalize with blob/queue errors From 60ff33839b7cfb5fe8df1ba8438b12e8f1c1a1a8 Mon Sep 17 00:00:00 2001 From: Xiaoning Liu Date: Wed, 18 Jul 2018 10:47:26 +0800 Subject: [PATCH 2/8] GitHub issue template --- ISSUE_TEMPLATE.md | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) create mode 100644 ISSUE_TEMPLATE.md diff --git a/ISSUE_TEMPLATE.md b/ISSUE_TEMPLATE.md new file mode 100644 index 00000000..09597b9f --- /dev/null +++ b/ISSUE_TEMPLATE.md @@ -0,0 +1,16 @@ +### Which service(blob, file, queue, table) does this issue concern? + + +### Which version of the SDK was used? + + +### What's the Node.js/Browser version? + + +### What problem was encountered? + + +### Steps to reproduce the issue? + + +### Have you found a mitigation/solution? From 32e237e4949dfdb012b4d55d2e49d0adec5b6180 Mon Sep 17 00:00:00 2001 From: jiacfan Date: Fri, 27 Jul 2018 15:12:02 +0800 Subject: [PATCH 3/8] Add enable global HTTP(s) agent support. --- ChangeLog.md | 5 +++++ lib/common/services/storageserviceclient.js | 7 ++++++- lib/services/blob/blobservice.core.js | 2 ++ lib/services/file/fileservice.core.js | 2 ++ lib/services/queue/queueservice.js | 2 ++ lib/services/table/tableservice.js | 2 ++ typings/azure-storage/azure-storage.d.ts | 18 ++++++++++++++++-- 7 files changed, 35 insertions(+), 3 deletions(-) diff --git a/ChangeLog.md b/ChangeLog.md index b69c4813..8fa13432 100644 --- a/ChangeLog.md +++ b/ChangeLog.md @@ -1,6 +1,11 @@ Note: This is an Azure Storage only package. The all up Azure node sdk still has the old storage bits in there. In a future release, those storage bits will be removed and an npm dependency to this storage node sdk will be taken. This is a GA release and the changes described below indicate the changes from the Azure node SDK 0.9.8 available here - https://github.com/Azure/azure-sdk-for-node. +2018.07 Version 2.10.1 + +ALL +* Added a parameter `enableGlobalHttpAgent` to all services. To enable global HTTP(s) agent, please set `{blob|queue|table|file}Service.enableGlobalHttpAgent` to true. + 2018.06 Version 2.10.0 ALL diff --git a/lib/common/services/storageserviceclient.js b/lib/common/services/storageserviceclient.js index 66d31b07..1dc6c1a3 100644 --- a/lib/common/services/storageserviceclient.js +++ b/lib/common/services/storageserviceclient.js @@ -636,6 +636,8 @@ StorageServiceClient.prototype._buildRequestOptions = function (webResource, bod delete webResource.headers[HeaderConstants.CONTENT_LENGTH]; } + var enableGlobalHttpAgent = this.enableGlobalHttpAgent; + // Sets the request url in the web resource. this._setRequestUrl(webResource, options); @@ -666,7 +668,10 @@ StorageServiceClient.prototype._buildRequestOptions = function (webResource, bod requestOptions.timeout = Constants.DEFAULT_CLIENT_REQUEST_TIMEOUT_IN_MS; // 2 minutes } - requestOptions.forever = true; + // If global HTTP agent is not enabled, use forever agent. + if (enableGlobalHttpAgent !== true) { + requestOptions.forever = true; + } } callback(error, requestOptions); diff --git a/lib/services/blob/blobservice.core.js b/lib/services/blob/blobservice.core.js index a8af688a..37dc0be8 100644 --- a/lib/services/blob/blobservice.core.js +++ b/lib/services/blob/blobservice.core.js @@ -86,6 +86,8 @@ var StorageError = errors.StorageError; * the value specified by the singleBlobPutThresholdInBytes property in size. * useNagleAlgorithm Determines whether the Nagle algorithm is used for requests made via the Blob service; true to use the * Nagle algorithm; otherwise, false. The default value is false. +* enableGlobalHttpAgent Determines whether global HTTP(s) agent is enabled; true to use Global HTTP(s) agent; otherwise, false to use +* http(s).Agent({keepAlive:true}). * @constructor * @extends {StorageServiceClient} * diff --git a/lib/services/file/fileservice.core.js b/lib/services/file/fileservice.core.js index 27eef1da..13140927 100644 --- a/lib/services/file/fileservice.core.js +++ b/lib/services/file/fileservice.core.js @@ -77,6 +77,8 @@ var ArgumentError = errors.ArgumentError; * parallelOperationThreadCount The number of parallel operations that may be performed when uploading a file. * useNagleAlgorithm Determines whether the Nagle algorithm is used for requests made via the file service; true to use the * Nagle algorithm; otherwise, false. The default value is false. +* enableGlobalHttpAgent Determines whether global HTTP(s) agent is enabled; true to use Global HTTP(s) agent; otherwise, false to use +* http(s).Agent({keepAlive:true}). * @constructor * @extends {StorageServiceClient} * diff --git a/lib/services/queue/queueservice.js b/lib/services/queue/queueservice.js index 6d3a79cf..f183e23e 100644 --- a/lib/services/queue/queueservice.js +++ b/lib/services/queue/queueservice.js @@ -55,6 +55,8 @@ var ServiceStatsParser = azureCommon.ServiceStatsParser; * defaultLocationMode The default location mode for requests made via the Queue service. * useNagleAlgorithm Determines whether the Nagle algorithm is used for requests made via the Queue service; true to use the * Nagle algorithm; otherwise, false. The default value is false. +* enableGlobalHttpAgent Determines whether global HTTP(s) agent is enabled; true to use Global HTTP(s) agent; otherwise, false to use +* http(s).Agent({keepAlive:true}). * @constructor * @augments {StorageServiceClient} * diff --git a/lib/services/table/tableservice.js b/lib/services/table/tableservice.js index 6ddf5505..4b58d481 100644 --- a/lib/services/table/tableservice.js +++ b/lib/services/table/tableservice.js @@ -61,6 +61,8 @@ var TableUtilities = require('./tableutilities'); * defaultPayloadFormat The default payload format for requests made via the Table service. * useNagleAlgorithm Determines whether the Nagle algorithm is used for requests made via the Table service.; true to use the * Nagle algorithm; otherwise, false. The default value is false. +* enableGlobalHttpAgent Determines whether global HTTP(s) agent is enabled; true to use Global HTTP(s) agent; otherwise, false to use +* http(s).Agent({keepAlive:true}). * @constructor * @extends {StorageServiceClient} * diff --git a/typings/azure-storage/azure-storage.d.ts b/typings/azure-storage/azure-storage.d.ts index f220b3ed..6b9a5ca1 100644 --- a/typings/azure-storage/azure-storage.d.ts +++ b/typings/azure-storage/azure-storage.d.ts @@ -86,6 +86,8 @@ declare module azurestorage { * the value specified by the singleBlobPutThresholdInBytes property in size. * useNagleAlgorithm Determines whether the Nagle algorithm is used for requests made via the Blob service; true to use the * Nagle algorithm; otherwise, false. The default value is false. + * enableGlobalHttpAgent Determines whether global HTTP(s) agent is enabled; true to use Global HTTP(s) agent; otherwise, false to use + * http(s).Agent({keepAlive:true}). * @constructor * @extends {StorageServiceClient} * @@ -3240,6 +3242,8 @@ declare module azurestorage { * defaultLocationMode The default location mode for requests made via the Queue service. * useNagleAlgorithm Determines whether the Nagle algorithm is used for requests made via the Queue service; true to use the * Nagle algorithm; otherwise, false. The default value is false. + * enableGlobalHttpAgent Determines whether global HTTP(s) agent is enabled; true to use Global HTTP(s) agent; otherwise, false to use + * http(s).Agent({keepAlive:true}). * If no connection string or storageaccount and storageaccesskey are provided, * the AZURE_STORAGE_CONNECTION_STRING or AZURE_STORAGE_ACCOUNT and AZURE_STORAGE_ACCESS_KEY environment variables will be used. * @augments {StorageServiceClient} @@ -5513,6 +5517,8 @@ declare module azurestorage { * defaultPayloadFormat The default payload format for requests made via the Table service. * useNagleAlgorithm Determines whether the Nagle algorithm is used for requests made via the Table service.; true to use the * Nagle algorithm; otherwise, false. The default value is false. + * enableGlobalHttpAgent Determines whether global HTTP(s) agent is enabled; true to use Global HTTP(s) agent; otherwise, false to use + * http(s).Agent({keepAlive:true}). * @constructor * @extends {StorageServiceClient} * @@ -7654,6 +7660,8 @@ declare module azurestorage { * parallelOperationThreadCount The number of parallel operations that may be performed when uploading a file. * useNagleAlgorithm Determines whether the Nagle algorithm is used for requests made via the file service; true to use the * Nagle algorithm; otherwise, false. The default value is false. + * enableGlobalHttpAgent Determines whether global HTTP(s) agent is enabled; true to use Global HTTP(s) agent; otherwise, false to use + * http(s).Agent({keepAlive:true}). * @constructor * @extends {StorageServiceClient} * @@ -9217,15 +9225,21 @@ declare module azurestorage { defaultClientRequestTimeoutInMs: number; /** * Determines whether the Nagle algorithm is used for requests made via the Queue service; true to use the - * Nagle algorithm; otherwise, false. The default value is false. + * Nagle algorithm; otherwise, false. The default value is false. * @member {bool} StorageServiceClient#useNagleAlgorithm */ useNagleAlgorithm: boolean; + /** + * Determines whether global HTTP(s) agent is enabled; true to use Global HTTP(s) agent; otherwise, false to use + * http(s).Agent({keepAlive:true}). + * @member {bool} StorageServiceClient#enableGlobalHttpAgent + */ + enableGlobalHttpAgent: boolean; /** The proxy object specified by caller. * @member {Proxy} StorageServiceClient#proxy */ proxy: Proxy; - /** The logging settings object. + /** The logging settings object. * @member {diagnostics.logger.Logger} StorageServiceClient#logger */ logger: diagnostics.logger.Logger; From 3c2f64d390e52e5ebbcee0a883a21242b58fcca8 Mon Sep 17 00:00:00 2001 From: jiacfan Date: Fri, 27 Jul 2018 15:12:51 +0800 Subject: [PATCH 4/8] Fix content type for json. --- ChangeLog.md | 1 + lib/common/util/constants.js | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/ChangeLog.md b/ChangeLog.md index 8fa13432..e7006d14 100644 --- a/ChangeLog.md +++ b/ChangeLog.md @@ -5,6 +5,7 @@ be taken. This is a GA release and the changes described below indicate the chan ALL * Added a parameter `enableGlobalHttpAgent` to all services. To enable global HTTP(s) agent, please set `{blob|queue|table|file}Service.enableGlobalHttpAgent` to true. +* Fixed content type for json. 2018.06 Version 2.10.0 diff --git a/lib/common/util/constants.js b/lib/common/util/constants.js index 761d3b55..b387b421 100644 --- a/lib/common/util/constants.js +++ b/lib/common/util/constants.js @@ -1448,7 +1448,7 @@ var Constants = { * @const * @type {string} */ - JSON_CONTENT_TYPE_VALUE: 'application/json;', + JSON_CONTENT_TYPE_VALUE: 'application/json', /** * The header that specifies storage SKU, also known as account type. From c08c66282f1a74f5ee5c4c7a004fc44e7bc9da27 Mon Sep 17 00:00:00 2001 From: jiacfan Date: Fri, 27 Jul 2018 15:15:42 +0800 Subject: [PATCH 5/8] Update version to 2.10.1. --- lib/common/util/constants.js | 2 +- package.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/common/util/constants.js b/lib/common/util/constants.js index b387b421..ddef9183 100644 --- a/lib/common/util/constants.js +++ b/lib/common/util/constants.js @@ -37,7 +37,7 @@ var Constants = { * @const * @type {string} */ - USER_AGENT_PRODUCT_VERSION: '2.10.0', + USER_AGENT_PRODUCT_VERSION: '2.10.1', /** * The number of default concurrent requests for parallel operation. diff --git a/package.json b/package.json index 4622af4b..089e4415 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "azure-storage", "author": "Microsoft Corporation", - "version": "2.10.0", + "version": "2.10.1", "description": "Microsoft Azure Storage Client Library for Node.js", "typings": "typings/azure-storage/azure-storage.d.ts", "tags": [ From 5ab6c75adf3586a4f031247e82e4d10474a8e260 Mon Sep 17 00:00:00 2001 From: jiacfan Date: Wed, 1 Aug 2018 17:17:48 +0800 Subject: [PATCH 6/8] Update change log. --- ChangeLog.md | 4 ++-- browser/ChangeLog.md | 6 ++++++ 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/ChangeLog.md b/ChangeLog.md index e7006d14..c36b4666 100644 --- a/ChangeLog.md +++ b/ChangeLog.md @@ -1,11 +1,11 @@ Note: This is an Azure Storage only package. The all up Azure node sdk still has the old storage bits in there. In a future release, those storage bits will be removed and an npm dependency to this storage node sdk will be taken. This is a GA release and the changes described below indicate the changes from the Azure node SDK 0.9.8 available here - https://github.com/Azure/azure-sdk-for-node. -2018.07 Version 2.10.1 +2018.08 Version 2.10.1 ALL * Added a parameter `enableGlobalHttpAgent` to all services. To enable global HTTP(s) agent, please set `{blob|queue|table|file}Service.enableGlobalHttpAgent` to true. -* Fixed content type for json. +* Fixed a bug that content type value is incorrect for json. 2018.06 Version 2.10.0 diff --git a/browser/ChangeLog.md b/browser/ChangeLog.md index 35496f05..e8c2433b 100644 --- a/browser/ChangeLog.md +++ b/browser/ChangeLog.md @@ -1,5 +1,11 @@ Note: This is the change log file for Azure Storage JavaScript Client Library. +2018.08 Version 2.10.101 + +ALL +* Fixed a bug that content type value is incorrect for json. +* Fixed an issue that user agent is set in browser environment. + 2018.06 Version 2.10.100 ALL From 48cb6acefebd0c057f115de447a9e4657c6308b1 Mon Sep 17 00:00:00 2001 From: jiacfan Date: Thu, 2 Aug 2018 11:45:04 +0800 Subject: [PATCH 7/8] Fix content type concatenating in table service. --- lib/services/table/models/batchresult.js | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/lib/services/table/models/batchresult.js b/lib/services/table/models/batchresult.js index 4e39ad95..49497ffd 100644 --- a/lib/services/table/models/batchresult.js +++ b/lib/services/table/models/batchresult.js @@ -16,6 +16,7 @@ // Module dependencies. var azureCommon = require('./../../../common/common.core'); +var azureutil = azureCommon.util; var Md5Wrapper = require('./../../../common/md5-wrapper'); var StorageServiceClient = azureCommon.StorageServiceClient; var WebResource = azureCommon.WebResource; @@ -115,7 +116,11 @@ BatchResult.prototype._serializeOperation = function (operation, count) { webResource.headers[HeaderConstants.CONTENT_ID] = count; } - if (webResource.headers[HeaderConstants.CONTENT_TYPE]) { + var contentType = webResource.headers[HeaderConstants.CONTENT_TYPE]; + if (contentType) { + if (!azureutil.stringEndsWith(contentType, ';')) { + webResource.headers[HeaderConstants.CONTENT_TYPE] += ';'; + } webResource.headers[HeaderConstants.CONTENT_TYPE] += 'type=entry'; } From 631af97ddec9b0932bf3eb54dcd24fc755f232bc Mon Sep 17 00:00:00 2001 From: jiacfan Date: Thu, 2 Aug 2018 14:33:04 +0800 Subject: [PATCH 8/8] Update change log for generated browser compatible JavaScript files. --- browser/ChangeLog.md | 1 + 1 file changed, 1 insertion(+) diff --git a/browser/ChangeLog.md b/browser/ChangeLog.md index e8c2433b..3d04a41a 100644 --- a/browser/ChangeLog.md +++ b/browser/ChangeLog.md @@ -3,6 +3,7 @@ Note: This is the change log file for Azure Storage JavaScript Client Library. 2018.08 Version 2.10.101 ALL +* Generated browser compatible JavaScript files based on Microsoft Azure Storage SDK for Node.js 2.10.1. * Fixed a bug that content type value is incorrect for json. * Fixed an issue that user agent is set in browser environment.