1- //
1+ //
22// Copyright (c) Microsoft and contributors. All rights reserved.
3- //
3+ //
44// Licensed under the Apache License, Version 2.0 (the "License");
55// you may not use this file except in compliance with the License.
66// You may obtain a copy of the License at
77// http://www.apache.org/licenses/LICENSE-2.0
8- //
8+ //
99// Unless required by applicable law or agreed to in writing, software
1010// distributed under the License is distributed on an "AS IS" BASIS,
1111// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12- //
12+ //
1313// See the License for the specific language governing permissions and
1414// limitations under the License.
15- //
15+ //
1616
1717// Module dependencies.
1818var request = require ( '../request-wrapper' ) ;
@@ -254,12 +254,14 @@ StorageServiceClient.prototype._performRequest = function (webResource, body, op
254254 if ( ! options . clientRequestId ) {
255255 options . clientRequestId = guid . v1 ( ) ;
256256 }
257-
257+
258258 webResource . withHeader ( HeaderConstants . CLIENT_REQUEST_ID , options . clientRequestId ) ;
259259
260- // Sets the user-agent string
261- var userAgentComment = util . format ( '(NODE-VERSION %s; %s %s)' , process . version , os . type ( ) , os . release ( ) ) ;
262- webResource . withHeader ( HeaderConstants . USER_AGENT , Constants . USER_AGENT_PRODUCT_NAME + '/' + Constants . USER_AGENT_PRODUCT_VERSION + ' ' + userAgentComment ) ;
260+ // Sets the user-agent string if the process is not started by the browser
261+ if ( ! process . browser ) {
262+ var userAgentComment = util . format ( '(NODE-VERSION %s; %s %s)' , process . version , os . type ( ) , os . release ( ) ) ;
263+ webResource . withHeader ( HeaderConstants . USER_AGENT , Constants . USER_AGENT_PRODUCT_NAME + '/' + Constants . USER_AGENT_PRODUCT_VERSION + ' ' + userAgentComment ) ;
264+ }
263265
264266 // Initialize the location that the request is going to be sent to.
265267 if ( azureutil . objectIsNull ( options . locationMode ) ) {
@@ -277,18 +279,18 @@ StorageServiceClient.prototype._performRequest = function (webResource, body, op
277279 }
278280
279281 this . _initializeLocation ( options ) ;
280-
282+
281283 // Initialize the operationExpiryTime
282284 this . _setOperationExpiryTime ( options ) ;
283285
284- // If the output stream already got sent to server and got error back,
286+ // If the output stream already got sent to server and got error back,
285287 // we should NOT retry within the SDK as the stream data is not valid anymore if we retry directly.
286288 // And it's very hard for SDK to re-wind the stream.
287289 //
288- // If users want to retry on this kind of error, they can implement their own logic to parse the response and
290+ // If users want to retry on this kind of error, they can implement their own logic to parse the response and
289291 // determine if they need to re-prepare a stream and call our SDK API to retry.
290292 //
291- // Currently for blobs/files with size greater than 32MB (DEFAULT_SINGLE_BLOB_PUT_THRESHOLD_IN_BYTES),
293+ // Currently for blobs/files with size greater than 32MB (DEFAULT_SINGLE_BLOB_PUT_THRESHOLD_IN_BYTES),
292294 // we'll send the steam by chunk buffers which doesn't have this issue.
293295 var outputStreamSent = false ;
294296
@@ -333,7 +335,7 @@ StorageServiceClient.prototype._performRequest = function (webResource, body, op
333335 var requestStream ;
334336
335337 var requestWithDefaults ;
336-
338+
337339 if ( self . proxy ) {
338340 if ( requestWithDefaults === undefined ) {
339341 requestWithDefaults = request . defaults ( { 'proxy' :self . proxy } ) ;
@@ -356,7 +358,7 @@ StorageServiceClient.prototype._performRequest = function (webResource, body, op
356358 if ( contentLength !== undefined ) {
357359 errorMessageBuffer = new Buffer ( contentLength ) ;
358360 }
359-
361+
360362 requestStream . on ( 'data' , function ( data ) {
361363 if ( contentLength !== undefined ) {
362364 data . copy ( errorMessageBuffer , index ) ;
@@ -402,7 +404,7 @@ StorageServiceClient.prototype._performRequest = function (webResource, body, op
402404 if ( azureutil . objectIsNull ( options . disableContentMD5Validation ) || options . disableContentMD5Validation === false ) {
403405 response . contentMD5 = internalHash . digest ( 'base64' ) ;
404406 }
405-
407+
406408 response . length = responseLength ;
407409 endResponse = response ;
408410 } ) ;
@@ -443,7 +445,7 @@ StorageServiceClient.prototype._performRequest = function (webResource, body, op
443445 if ( ! azureutil . isBrowser ( ) && Buffer . isBuffer ( body . outputData ) ) {
444446 // Request module will take 200MB additional memory when we pass a 100MB buffer as body
445447 // Transfer buffer to stream will highly reduce the memory used by request module
446- finalRequestOptions . body = new BufferStream ( body . outputData ) ;
448+ finalRequestOptions . body = new BufferStream ( body . outputData ) ;
447449 } else {
448450 finalRequestOptions . body = body . outputData ;
449451 }
@@ -578,10 +580,10 @@ StorageServiceClient.prototype._buildRequestOptions = function (webResource, bod
578580 }
579581 webResource . withHeader ( HeaderConstants . ACCEPT_CHARSET , 'UTF-8' ) ;
580582
581- // Browsers cache GET/HEAD requests by adding conditional headers such as 'IF_MODIFIED_SINCE' after Azure Storage 'Authorization header' calculation,
582- // which may result in a 403 authorization error. So add timestamp to GET/HEAD request URLs thus avoid the browser cache.
583+ // Browsers cache GET/HEAD requests by adding conditional headers such as 'IF_MODIFIED_SINCE' after Azure Storage 'Authorization header' calculation,
584+ // which may result in a 403 authorization error. So add timestamp to GET/HEAD request URLs thus avoid the browser cache.
583585 if ( azureutil . isBrowser ( ) && (
584- webResource . method === Constants . HttpConstants . HttpVerbs . GET ||
586+ webResource . method === Constants . HttpConstants . HttpVerbs . GET ||
585587 webResource . method === Constants . HttpConstants . HttpVerbs . HEAD ) ) {
586588 webResource . withQueryOption ( HeaderConstants . FORCE_NO_CACHE_IN_BROWSER , new Date ( ) . getTime ( ) ) ;
587589 }
@@ -597,7 +599,7 @@ StorageServiceClient.prototype._buildRequestOptions = function (webResource, bod
597599 if ( ! azureutil . objectIsNull ( options . timeoutIntervalInMs ) && options . timeoutIntervalInMs > 0 ) {
598600 webResource . withQueryOption ( QueryStringConstants . TIMEOUT , Math . ceil ( options . timeoutIntervalInMs / 1000 ) ) ;
599601 }
600-
602+
601603 if ( options . accessConditions ) {
602604 webResource . withHeader ( HeaderConstants . IF_MATCH , options . accessConditions . EtagMatch ) ;
603605 webResource . withHeader ( HeaderConstants . IF_MODIFIED_SINCE , options . accessConditions . DateModifedSince ) ;
@@ -616,7 +618,7 @@ StorageServiceClient.prototype._buildRequestOptions = function (webResource, bod
616618 webResource . withHeader ( HeaderConstants . SOURCE_IF_NONE_MATCH , options . sourceAccessConditions . EtagNonMatch ) ;
617619 webResource . withHeader ( HeaderConstants . SOURCE_IF_UNMODIFIED_SINCE , options . sourceAccessConditions . DateUnModifiedSince ) ;
618620 }
619-
621+
620622 if ( ! webResource . headers || webResource . headers [ HeaderConstants . CONTENT_TYPE ] === undefined ) {
621623 // work around to add an empty content type header to prevent the request module from magically adding a content type.
622624 webResource . headers [ HeaderConstants . CONTENT_TYPE ] = '' ;
@@ -634,6 +636,8 @@ StorageServiceClient.prototype._buildRequestOptions = function (webResource, bod
634636 delete webResource . headers [ HeaderConstants . CONTENT_LENGTH ] ;
635637 }
636638
639+ var enableGlobalHttpAgent = this . enableGlobalHttpAgent ;
640+
637641 // Sets the request url in the web resource.
638642 this . _setRequestUrl ( webResource , options ) ;
639643
@@ -657,14 +661,17 @@ StorageServiceClient.prototype._buildRequestOptions = function (webResource, bod
657661 //set encoding of response data. If set to null, the body is returned as a Buffer
658662 requestOptions . encoding = options . responseEncoding ;
659663 }
660-
664+
661665 if ( options && options . clientRequestTimeoutInMs ) {
662666 requestOptions . timeout = options . clientRequestTimeoutInMs ;
663667 } else {
664668 requestOptions . timeout = Constants . DEFAULT_CLIENT_REQUEST_TIMEOUT_IN_MS ; // 2 minutes
665669 }
666670
667- requestOptions . forever = true ;
671+ // If global HTTP agent is not enabled, use forever agent.
672+ if ( enableGlobalHttpAgent !== true ) {
673+ requestOptions . forever = true ;
674+ }
668675 }
669676
670677 callback ( error , requestOptions ) ;
@@ -946,7 +953,7 @@ StorageServiceClient.prototype._setRequestUrl = function (webResource, options)
946953 if ( host && host . lastIndexOf ( '/' ) !== ( host . length - 1 ) ) {
947954 host = host + '/' ;
948955 }
949-
956+
950957 var fullPath = url . format ( { pathname : webResource . path , query : webResource . queryString } ) ;
951958 webResource . uri = url . resolve ( host , fullPath ) ;
952959 webResource . path = url . parse ( webResource . uri ) . pathname ;
@@ -1033,7 +1040,7 @@ StorageServiceClient.prototype.parseMetadataHeaders = function (headers) {
10331040 metadata [ key ] = headers [ header ] ;
10341041 }
10351042 }
1036-
1043+
10371044 return metadata ;
10381045} ;
10391046
@@ -1043,7 +1050,7 @@ StorageServiceClient.prototype.parseMetadataHeaders = function (headers) {
10431050*
10441051* @this {StorageServiceClient}
10451052* @param {object } [options] The request options.
1046- * @param {LocationMode } [options.locationMode] Specifies the location mode used to decide which location the request should be sent to.
1053+ * @param {LocationMode } [options.locationMode] Specifies the location mode used to decide which location the request should be sent to.
10471054* Please see StorageUtilities.LocationMode for the possible values.
10481055* @param {int } [options.timeoutIntervalInMs] The server timeout interval, in milliseconds, to use for the request.
10491056* @param {int } [options.clientRequestTimeoutInMs] The timeout of client requests, in milliseconds, to use for the request.
@@ -1052,40 +1059,40 @@ StorageServiceClient.prototype.parseMetadataHeaders = function (headers) {
10521059* execution time is checked intermittently while performing requests, and before executing retries.
10531060* @param {bool } [options.useNagleAlgorithm] Determines whether the Nagle algorithm is used; true to use the Nagle algorithm; otherwise, false.
10541061* The default value is false.
1055- * @param {errorOrResult } callback `error` will contain information if an error occurs; otherwise, `result` will contain the properties
1062+ * @param {errorOrResult } callback `error` will contain information if an error occurs; otherwise, `result` will contain the properties
10561063* and `response` will contain information related to this operation.
10571064*/
10581065StorageServiceClient . prototype . getAccountServiceProperties = function ( optionsOrCallback , callback ) {
10591066 var userOptions ;
10601067 azureutil . normalizeArgs ( optionsOrCallback , callback , function ( o , c ) { userOptions = o ; callback = c ; } ) ;
1061-
1068+
10621069 validate . validateArgs ( 'getServiceProperties' , function ( v ) {
10631070 v . callback ( callback ) ;
10641071 } ) ;
1065-
1072+
10661073 var options = extend ( true , { } , userOptions ) ;
1067-
1074+
10681075 var webResource = WebResource . get ( )
10691076 . withQueryOption ( QueryStringConstants . COMP , 'properties' )
10701077 . withQueryOption ( QueryStringConstants . RESTYPE , 'service' ) ;
1071-
1078+
10721079 options . requestLocationMode = RequestLocationMode . PRIMARY_OR_SECONDARY ;
1073-
1080+
10741081 var processResponseCallback = function ( responseObject , next ) {
10751082 responseObject . servicePropertiesResult = null ;
10761083 if ( ! responseObject . error ) {
10771084 responseObject . servicePropertiesResult = ServicePropertiesResult . parse ( responseObject . response . body . StorageServiceProperties ) ;
10781085 }
1079-
1086+
10801087 // function to be called after all filters
10811088 var finalCallback = function ( returnObject ) {
10821089 callback ( returnObject . error , returnObject . servicePropertiesResult , returnObject . response ) ;
10831090 } ;
1084-
1091+
10851092 // call the first filter
10861093 next ( responseObject , finalCallback ) ;
10871094 } ;
1088-
1095+
10891096 this . performRequest ( webResource , null , options , processResponseCallback ) ;
10901097} ;
10911098
@@ -1096,7 +1103,7 @@ StorageServiceClient.prototype.getAccountServiceProperties = function (optionsOr
10961103* @this {StorageServiceClient}
10971104* @param {object } serviceProperties The service properties.
10981105* @param {object } [options] The request options.
1099- * @param {LocationMode } [options.locationMode] Specifies the location mode used to decide which location the request should be sent to.
1106+ * @param {LocationMode } [options.locationMode] Specifies the location mode used to decide which location the request should be sent to.
11001107* Please see StorageUtilities.LocationMode for the possible values.
11011108* @param {int } [options.timeoutIntervalInMs] The server timeout interval, in milliseconds, to use for the request.
11021109* @param {int } [options.clientRequestTimeoutInMs] The timeout of client requests, in milliseconds, to use for the request.
@@ -1112,30 +1119,30 @@ StorageServiceClient.prototype.getAccountServiceProperties = function (optionsOr
11121119StorageServiceClient . prototype . setAccountServiceProperties = function ( serviceProperties , optionsOrCallback , callback ) {
11131120 var userOptions ;
11141121 azureutil . normalizeArgs ( optionsOrCallback , callback , function ( o , c ) { userOptions = o ; callback = c ; } ) ;
1115-
1122+
11161123 validate . validateArgs ( 'setServiceProperties' , function ( v ) {
11171124 v . object ( serviceProperties , 'serviceProperties' ) ;
11181125 v . callback ( callback ) ;
11191126 } ) ;
1120-
1127+
11211128 var options = extend ( true , { } , userOptions ) ;
11221129 var servicePropertiesXml = ServicePropertiesResult . serialize ( serviceProperties ) ;
1123-
1130+
11241131 var webResource = WebResource . put ( )
11251132 . withQueryOption ( QueryStringConstants . COMP , 'properties' )
11261133 . withQueryOption ( QueryStringConstants . RESTYPE , 'service' )
11271134 . withHeader ( HeaderConstants . CONTENT_TYPE , 'application/xml;charset="utf-8"' )
11281135 . withHeader ( HeaderConstants . CONTENT_LENGTH , Buffer . byteLength ( servicePropertiesXml ) )
11291136 . withBody ( servicePropertiesXml ) ;
1130-
1137+
11311138 var processResponseCallback = function ( responseObject , next ) {
11321139 var finalCallback = function ( returnObject ) {
11331140 callback ( returnObject . error , returnObject . response ) ;
11341141 } ;
1135-
1142+
11361143 next ( responseObject , finalCallback ) ;
11371144 } ;
1138-
1145+
11391146 this . performRequest ( webResource , webResource . body , options , processResponseCallback ) ;
11401147} ;
11411148
@@ -1164,14 +1171,14 @@ StorageServiceClient._normalizeError = function (error, response) {
11641171 // blob/queue errors should have error.Error, table errors should have error['odata.error']
11651172 var errorProperties = error . Error || error . error || error [ 'odata.error' ] || error [ 'm:error' ] || error ;
11661173 normalizedError . code = errorProperties . message ; // The message exists when there is error.Error.
1167-
1174+
11681175 for ( var property in errorProperties ) {
11691176 if ( errorProperties . hasOwnProperty ( property ) ) {
11701177 var key = property . toLowerCase ( ) ;
11711178 if ( key . indexOf ( 'm:' ) === 0 ) {
11721179 key = key . substring ( 2 ) ;
11731180 }
1174-
1181+
11751182 normalizedError [ key ] = errorProperties [ property ] ;
11761183
11771184 // if this is a table error, message is an object - flatten it to normalize with blob/queue errors
0 commit comments