💾 Archived View for gmi.noulin.net › gitRepositories › git-off › file › src › node_modules › aws-sdk… captured on 2023-01-29 at 11:58:07. Gemini links have been rewritten to link to archived content
-=-=-=-=-=-=-
request.js (26488B)
1 var AWS = require('./core'); 2 var AcceptorStateMachine = require('./state_machine'); 3 var inherit = AWS.util.inherit; 4 var domain = AWS.util.domain; 5 var jmespath = require('jmespath'); 6 7 /** 8 * @api private 9 */ 10 var hardErrorStates = {success: 1, error: 1, complete: 1}; 11 12 function isTerminalState(machine) { 13 return Object.prototype.hasOwnProperty.call(hardErrorStates, machine._asm.currentState); 14 } 15 16 var fsm = new AcceptorStateMachine(); 17 fsm.setupStates = function() { 18 var transition = function(_, done) { 19 var self = this; 20 self._haltHandlersOnError = false; 21 22 self.emit(self._asm.currentState, function(err) { 23 if (err) { 24 if (isTerminalState(self)) { 25 if (domain && self.domain instanceof domain.Domain) { 26 err.domainEmitter = self; 27 err.domain = self.domain; 28 err.domainThrown = false; 29 self.domain.emit('error', err); 30 } else { 31 throw err; 32 } 33 } else { 34 self.response.error = err; 35 done(err); 36 } 37 } else { 38 done(self.response.error); 39 } 40 }); 41 42 }; 43 44 this.addState('validate', 'build', 'error', transition); 45 this.addState('build', 'afterBuild', 'restart', transition); 46 this.addState('afterBuild', 'sign', 'restart', transition); 47 this.addState('sign', 'send', 'retry', transition); 48 this.addState('retry', 'afterRetry', 'afterRetry', transition); 49 this.addState('afterRetry', 'sign', 'error', transition); 50 this.addState('send', 'validateResponse', 'retry', transition); 51 this.addState('validateResponse', 'extractData', 'extractError', transition); 52 this.addState('extractError', 'extractData', 'retry', transition); 53 this.addState('extractData', 'success', 'retry', transition); 54 this.addState('restart', 'build', 'error', transition); 55 this.addState('success', 'complete', 'complete', transition); 56 this.addState('error', 'complete', 'complete', transition); 57 this.addState('complete', null, null, transition); 58 }; 59 fsm.setupStates(); 60 61 /** 62 * ## Asynchronous Requests 63 * 64 * All requests made through the SDK are asynchronous and use a 65 * callback interface. Each service method that kicks off a request 66 * returns an `AWS.Request` object that you can use to register 67 * callbacks. 68 * 69 * For example, the following service method returns the request 70 * object as "request", which can be used to register callbacks: 71 * 72 * ```javascript 73 * // request is an AWS.Request object 74 * var request = ec2.describeInstances(); 75 * 76 * // register callbacks on request to retrieve response data 77 * request.on('success', function(response) { 78 * console.log(response.data); 79 * }); 80 * ``` 81 * 82 * When a request is ready to be sent, the {send} method should 83 * be called: 84 * 85 * ```javascript 86 * request.send(); 87 * ``` 88 * 89 * ## Removing Default Listeners for Events 90 * 91 * Request objects are built with default listeners for the various events, 92 * depending on the service type. In some cases, you may want to remove 93 * some built-in listeners to customize behaviour. Doing this requires 94 * access to the built-in listener functions, which are exposed through 95 * the {AWS.EventListeners.Core} namespace. For instance, you may 96 * want to customize the HTTP handler used when sending a request. In this 97 * case, you can remove the built-in listener associated with the 'send' 98 * event, the {AWS.EventListeners.Core.SEND} listener and add your own. 99 * 100 * ## Multiple Callbacks and Chaining 101 * 102 * You can register multiple callbacks on any request object. The 103 * callbacks can be registered for different events, or all for the 104 * same event. In addition, you can chain callback registration, for 105 * example: 106 * 107 * ```javascript 108 * request. 109 * on('success', function(response) { 110 * console.log("Success!"); 111 * }). 112 * on('error', function(response) { 113 * console.log("Error!"); 114 * }). 115 * on('complete', function(response) { 116 * console.log("Always!"); 117 * }). 118 * send(); 119 * ``` 120 * 121 * The above example will print either "Success! Always!", or "Error! Always!", 122 * depending on whether the request succeeded or not. 123 * 124 * @!attribute httpRequest 125 * @readonly 126 * @!group HTTP Properties 127 * @return [AWS.HttpRequest] the raw HTTP request object 128 * containing request headers and body information 129 * sent by the service. 130 * 131 * @!attribute startTime 132 * @readonly 133 * @!group Operation Properties 134 * @return [Date] the time that the request started 135 * 136 * @!group Request Building Events 137 * 138 * @!event validate(request) 139 * Triggered when a request is being validated. Listeners 140 * should throw an error if the request should not be sent. 141 * @param request [Request] the request object being sent 142 * @see AWS.EventListeners.Core.VALIDATE_CREDENTIALS 143 * @see AWS.EventListeners.Core.VALIDATE_REGION 144 * @example Ensuring that a certain parameter is set before sending a request 145 * var req = s3.putObject(params); 146 * req.on('validate', function() { 147 * if (!req.params.Body.match(/^Hello\s/)) { 148 * throw new Error('Body must start with "Hello "'); 149 * } 150 * }); 151 * req.send(function(err, data) { ... }); 152 * 153 * @!event build(request) 154 * Triggered when the request payload is being built. Listeners 155 * should fill the necessary information to send the request 156 * over HTTP. 157 * @param (see AWS.Request~validate) 158 * @example Add a custom HTTP header to a request 159 * var req = s3.putObject(params); 160 * req.on('build', function() { 161 * req.httpRequest.headers['Custom-Header'] = 'value'; 162 * }); 163 * req.send(function(err, data) { ... }); 164 * 165 * @!event sign(request) 166 * Triggered when the request is being signed. Listeners should 167 * add the correct authentication headers and/or adjust the body, 168 * depending on the authentication mechanism being used. 169 * @param (see AWS.Request~validate) 170 * 171 * @!group Request Sending Events 172 * 173 * @!event send(response) 174 * Triggered when the request is ready to be sent. Listeners 175 * should call the underlying transport layer to initiate 176 * the sending of the request. 177 * @param response [Response] the response object 178 * @context [Request] the request object that was sent 179 * @see AWS.EventListeners.Core.SEND 180 * 181 * @!event retry(response) 182 * Triggered when a request failed and might need to be retried or redirected. 183 * If the response is retryable, the listener should set the 184 * `response.error.retryable` property to `true`, and optionally set 185 * `response.error.retryCount` to the millisecond delay for the next attempt. 186 * In the case of a redirect, `response.error.redirect` should be set to 187 * `true` with `retryCount` set to an optional delay on the next request. 188 * 189 * If a listener decides that a request should not be retried, 190 * it should set both `retryable` and `redirect` to false. 191 * 192 * Note that a retryable error will be retried at most 193 * {AWS.Config.maxRetries} times (based on the service object's config). 194 * Similarly, a request that is redirected will only redirect at most 195 * {AWS.Config.maxRedirects} times. 196 * 197 * @param (see AWS.Request~send) 198 * @context (see AWS.Request~send) 199 * @example Adding a custom retry for a 404 response 200 * request.on('retry', function(response) { 201 * // this resource is not yet available, wait 10 seconds to get it again 202 * if (response.httpResponse.statusCode === 404 && response.error) { 203 * response.error.retryable = true; // retry this error 204 * response.error.retryCount = 10000; // wait 10 seconds 205 * } 206 * }); 207 * 208 * @!group Data Parsing Events 209 * 210 * @!event extractError(response) 211 * Triggered on all non-2xx requests so that listeners can extract 212 * error details from the response body. Listeners to this event 213 * should set the `response.error` property. 214 * @param (see AWS.Request~send) 215 * @context (see AWS.Request~send) 216 * 217 * @!event extractData(response) 218 * Triggered in successful requests to allow listeners to 219 * de-serialize the response body into `response.data`. 220 * @param (see AWS.Request~send) 221 * @context (see AWS.Request~send) 222 * 223 * @!group Completion Events 224 * 225 * @!event success(response) 226 * Triggered when the request completed successfully. 227 * `response.data` will contain the response data and 228 * `response.error` will be null. 229 * @param (see AWS.Request~send) 230 * @context (see AWS.Request~send) 231 * 232 * @!event error(error, response) 233 * Triggered when an error occurs at any point during the 234 * request. `response.error` will contain details about the error 235 * that occurred. `response.data` will be null. 236 * @param error [Error] the error object containing details about 237 * the error that occurred. 238 * @param (see AWS.Request~send) 239 * @context (see AWS.Request~send) 240 * 241 * @!event complete(response) 242 * Triggered whenever a request cycle completes. `response.error` 243 * should be checked, since the request may have failed. 244 * @param (see AWS.Request~send) 245 * @context (see AWS.Request~send) 246 * 247 * @!group HTTP Events 248 * 249 * @!event httpHeaders(statusCode, headers, response) 250 * Triggered when headers are sent by the remote server 251 * @param statusCode [Integer] the HTTP response code 252 * @param headers [map<String,String>] the response headers 253 * @param (see AWS.Request~send) 254 * @context (see AWS.Request~send) 255 * 256 * @!event httpData(chunk, response) 257 * Triggered when data is sent by the remote server 258 * @param chunk [Buffer] the buffer data containing the next data chunk 259 * from the server 260 * @param (see AWS.Request~send) 261 * @context (see AWS.Request~send) 262 * @see AWS.EventListeners.Core.HTTP_DATA 263 * 264 * @!event httpUploadProgress(progress, response) 265 * Triggered when the HTTP request has uploaded more data 266 * @param progress [map] An object containing the `loaded` and `total` bytes 267 * of the request. 268 * @param (see AWS.Request~send) 269 * @context (see AWS.Request~send) 270 * @note This event will not be emitted in Node.js 0.8.x. 271 * 272 * @!event httpDownloadProgress(progress, response) 273 * Triggered when the HTTP request has downloaded more data 274 * @param progress [map] An object containing the `loaded` and `total` bytes 275 * of the request. 276 * @param (see AWS.Request~send) 277 * @context (see AWS.Request~send) 278 * @note This event will not be emitted in Node.js 0.8.x. 279 * 280 * @!event httpError(error, response) 281 * Triggered when the HTTP request failed 282 * @param error [Error] the error object that was thrown 283 * @param (see AWS.Request~send) 284 * @context (see AWS.Request~send) 285 * 286 * @!event httpDone(response) 287 * Triggered when the server is finished sending data 288 * @param (see AWS.Request~send) 289 * @context (see AWS.Request~send) 290 * 291 * @see AWS.Response 292 */ 293 AWS.Request = inherit({ 294 295 /** 296 * Creates a request for an operation on a given service with 297 * a set of input parameters. 298 * 299 * @param service [AWS.Service] the service to perform the operation on 300 * @param operation [String] the operation to perform on the service 301 * @param params [Object] parameters to send to the operation. 302 * See the operation's documentation for the format of the 303 * parameters. 304 */ 305 constructor: function Request(service, operation, params) { 306 var endpoint = service.endpoint; 307 var region = service.config.region; 308 var customUserAgent = service.config.customUserAgent; 309 310 // global endpoints sign as us-east-1 311 if (service.isGlobalEndpoint) region = 'us-east-1'; 312 313 this.domain = domain && domain.active; 314 this.service = service; 315 this.operation = operation; 316 this.params = params || {}; 317 this.httpRequest = new AWS.HttpRequest(endpoint, region, customUserAgent); 318 this.startTime = AWS.util.date.getDate(); 319 320 this.response = new AWS.Response(this); 321 this._asm = new AcceptorStateMachine(fsm.states, 'validate'); 322 this._haltHandlersOnError = false; 323 324 AWS.SequentialExecutor.call(this); 325 this.emit = this.emitEvent; 326 }, 327 328 /** 329 * @!group Sending a Request 330 */ 331 332 /** 333 * @overload send(callback = null) 334 * Sends the request object. 335 * 336 * @callback callback function(err, data) 337 * If a callback is supplied, it is called when a response is returned 338 * from the service. 339 * @context [AWS.Request] the request object being sent. 340 * @param err [Error] the error object returned from the request. 341 * Set to `null` if the request is successful. 342 * @param data [Object] the de-serialized data returned from 343 * the request. Set to `null` if a request error occurs. 344 * @example Sending a request with a callback 345 * request = s3.putObject({Bucket: 'bucket', Key: 'key'}); 346 * request.send(function(err, data) { console.log(err, data); }); 347 * @example Sending a request with no callback (using event handlers) 348 * request = s3.putObject({Bucket: 'bucket', Key: 'key'}); 349 * request.on('complete', function(response) { ... }); // register a callback 350 * request.send(); 351 */ 352 send: function send(callback) { 353 if (callback) { 354 this.on('complete', function (resp) { 355 callback.call(resp, resp.error, resp.data); 356 }); 357 } 358 this.runTo(); 359 360 return this.response; 361 }, 362 363 /** 364 * @!method promise() 365 * Returns a 'thenable' promise. 366 * 367 * Two callbacks can be provided to the `then` method on the returned promise. 368 * The first callback will be called if the promise is fulfilled, and the second 369 * callback will be called if the promise is rejected. 370 * @callback fulfilledCallback function(data) 371 * Called if the promise is fulfilled. 372 * @param data [Object] the de-serialized data returned from the request. 373 * @callback rejectedCallback function(error) 374 * Called if the promise is rejected. 375 * @param error [Error] the error object returned from the request. 376 * @return [Promise] A promise that represents the state of the request. 377 * @example Sending a request using promises. 378 * var request = s3.putObject({Bucket: 'bucket', Key: 'key'}); 379 * var result = request.promise(); 380 * result.then(function(data) { ... }, function(error) { ... }); 381 */ 382 383 /** 384 * @api private 385 */ 386 build: function build(callback) { 387 return this.runTo('send', callback); 388 }, 389 390 /** 391 * @api private 392 */ 393 runTo: function runTo(state, done) { 394 this._asm.runTo(state, done, this); 395 return this; 396 }, 397 398 /** 399 * Aborts a request, emitting the error and complete events. 400 * 401 * @!macro nobrowser 402 * @example Aborting a request after sending 403 * var params = { 404 * Bucket: 'bucket', Key: 'key', 405 * Body: new Buffer(1024 * 1024 * 5) // 5MB payload 406 * }; 407 * var request = s3.putObject(params); 408 * request.send(function (err, data) { 409 * if (err) console.log("Error:", err.code, err.message); 410 * else console.log(data); 411 * }); 412 * 413 * // abort request in 1 second 414 * setTimeout(request.abort.bind(request), 1000); 415 * 416 * // prints "Error: RequestAbortedError Request aborted by user" 417 * @return [AWS.Request] the same request object, for chaining. 418 * @since v1.4.0 419 */ 420 abort: function abort() { 421 this.removeAllListeners('validateResponse'); 422 this.removeAllListeners('extractError'); 423 this.on('validateResponse', function addAbortedError(resp) { 424 resp.error = AWS.util.error(new Error('Request aborted by user'), { 425 code: 'RequestAbortedError', retryable: false 426 }); 427 }); 428 429 if (this.httpRequest.stream) { // abort HTTP stream 430 this.httpRequest.stream.abort(); 431 if (this.httpRequest._abortCallback) { 432 this.httpRequest._abortCallback(); 433 } else { 434 this.removeAllListeners('send'); // haven't sent yet, so let's not 435 } 436 } 437 438 return this; 439 }, 440 441 /** 442 * Iterates over each page of results given a pageable request, calling 443 * the provided callback with each page of data. After all pages have been 444 * retrieved, the callback is called with `null` data. 445 * 446 * @note This operation can generate multiple requests to a service. 447 * @example Iterating over multiple pages of objects in an S3 bucket 448 * var pages = 1; 449 * s3.listObjects().eachPage(function(err, data) { 450 * if (err) return; 451 * console.log("Page", pages++); 452 * console.log(data); 453 * }); 454 * @example Iterating over multiple pages with an asynchronous callback 455 * s3.listObjects(params).eachPage(function(err, data, done) { 456 * doSomethingAsyncAndOrExpensive(function() { 457 * // The next page of results isn't fetched until done is called 458 * done(); 459 * }); 460 * }); 461 * @callback callback function(err, data, [doneCallback]) 462 * Called with each page of resulting data from the request. If the 463 * optional `doneCallback` is provided in the function, it must be called 464 * when the callback is complete. 465 * 466 * @param err [Error] an error object, if an error occurred. 467 * @param data [Object] a single page of response data. If there is no 468 * more data, this object will be `null`. 469 * @param doneCallback [Function] an optional done callback. If this 470 * argument is defined in the function declaration, it should be called 471 * when the next page is ready to be retrieved. This is useful for 472 * controlling serial pagination across asynchronous operations. 473 * @return [Boolean] if the callback returns `false`, pagination will 474 * stop. 475 * 476 * @see AWS.Request.eachItem 477 * @see AWS.Response.nextPage 478 * @since v1.4.0 479 */ 480 eachPage: function eachPage(callback) { 481 // Make all callbacks async-ish 482 callback = AWS.util.fn.makeAsync(callback, 3); 483 484 function wrappedCallback(response) { 485 callback.call(response, response.error, response.data, function (result) { 486 if (result === false) return; 487 488 if (response.hasNextPage()) { 489 response.nextPage().on('complete', wrappedCallback).send(); 490 } else { 491 callback.call(response, null, null, AWS.util.fn.noop); 492 } 493 }); 494 } 495 496 this.on('complete', wrappedCallback).send(); 497 }, 498 499 /** 500 * Enumerates over individual items of a request, paging the responses if 501 * necessary. 502 * 503 * @api experimental 504 * @since v1.4.0 505 */ 506 eachItem: function eachItem(callback) { 507 var self = this; 508 function wrappedCallback(err, data) { 509 if (err) return callback(err, null); 510 if (data === null) return callback(null, null); 511 512 var config = self.service.paginationConfig(self.operation); 513 var resultKey = config.resultKey; 514 if (Array.isArray(resultKey)) resultKey = resultKey[0]; 515 var items = jmespath.search(data, resultKey); 516 var continueIteration = true; 517 AWS.util.arrayEach(items, function(item) { 518 continueIteration = callback(null, item); 519 if (continueIteration === false) { 520 return AWS.util.abort; 521 } 522 }); 523 return continueIteration; 524 } 525 526 this.eachPage(wrappedCallback); 527 }, 528 529 /** 530 * @return [Boolean] whether the operation can return multiple pages of 531 * response data. 532 * @see AWS.Response.eachPage 533 * @since v1.4.0 534 */ 535 isPageable: function isPageable() { 536 return this.service.paginationConfig(this.operation) ? true : false; 537 }, 538 539 /** 540 * Converts the request object into a readable stream that 541 * can be read from or piped into a writable stream. 542 * 543 * @note The data read from a readable stream contains only 544 * the raw HTTP body contents. 545 * @example Manually reading from a stream 546 * request.createReadStream().on('data', function(data) { 547 * console.log("Got data:", data.toString()); 548 * }); 549 * @example Piping a request body into a file 550 * var out = fs.createWriteStream('/path/to/outfile.jpg'); 551 * s3.service.getObject(params).createReadStream().pipe(out); 552 * @return [Stream] the readable stream object that can be piped 553 * or read from (by registering 'data' event listeners). 554 * @!macro nobrowser 555 */ 556 createReadStream: function createReadStream() { 557 var streams = AWS.util.stream; 558 var req = this; 559 var stream = null; 560 561 if (AWS.HttpClient.streamsApiVersion === 2) { 562 stream = new streams.PassThrough(); 563 req.send(); 564 } else { 565 stream = new streams.Stream(); 566 stream.readable = true; 567 568 stream.sent = false; 569 stream.on('newListener', function(event) { 570 if (!stream.sent && event === 'data') { 571 stream.sent = true; 572 process.nextTick(function() { req.send(); }); 573 } 574 }); 575 } 576 577 this.on('httpHeaders', function streamHeaders(statusCode, headers, resp) { 578 if (statusCode < 300) { 579 req.removeListener('httpData', AWS.EventListeners.Core.HTTP_DATA); 580 req.removeListener('httpError', AWS.EventListeners.Core.HTTP_ERROR); 581 req.on('httpError', function streamHttpError(error) { 582 resp.error = error; 583 resp.error.retryable = false; 584 }); 585 586 var shouldCheckContentLength = false; 587 var expectedLen; 588 if (req.httpRequest.method !== 'HEAD') { 589 expectedLen = parseInt(headers['content-length'], 10); 590 } 591 if (expectedLen !== undefined && !isNaN(expectedLen) && expectedLen >= 0) { 592 shouldCheckContentLength = true; 593 var receivedLen = 0; 594 } 595 596 var checkContentLengthAndEmit = function checkContentLengthAndEmit() { 597 if (shouldCheckContentLength && receivedLen !== expectedLen) { 598 stream.emit('error', AWS.util.error( 599 new Error('Stream content length mismatch. Received ' + 600 receivedLen + ' of ' + expectedLen + ' bytes.'), 601 { code: 'StreamContentLengthMismatch' } 602 )); 603 } else if (AWS.HttpClient.streamsApiVersion === 2) { 604 stream.end(); 605 } else { 606 stream.emit('end') 607 } 608 } 609 610 var httpStream = resp.httpResponse.createUnbufferedStream(); 611 612 if (AWS.HttpClient.streamsApiVersion === 2) { 613 if (shouldCheckContentLength) { 614 var lengthAccumulator = new streams.PassThrough(); 615 lengthAccumulator._write = function(chunk) { 616 if (chunk && chunk.length) { 617 receivedLen += chunk.length; 618 } 619 return streams.PassThrough.prototype._write.apply(this, arguments); 620 }; 621 622 lengthAccumulator.on('end', checkContentLengthAndEmit); 623 httpStream.pipe(lengthAccumulator).pipe(stream, { end: false }); 624 } else { 625 httpStream.pipe(stream); 626 } 627 } else { 628 629 if (shouldCheckContentLength) { 630 httpStream.on('data', function(arg) { 631 if (arg && arg.length) { 632 receivedLen += arg.length; 633 } 634 }); 635 } 636 637 httpStream.on('data', function(arg) { 638 stream.emit('data', arg); 639 }); 640 httpStream.on('end', checkContentLengthAndEmit); 641 } 642 643 httpStream.on('error', function(err) { 644 shouldCheckContentLength = false; 645 stream.emit('error', err); 646 }); 647 } 648 }); 649 650 this.on('error', function(err) { 651 stream.emit('error', err); 652 }); 653 654 return stream; 655 }, 656 657 /** 658 * @param [Array,Response] args This should be the response object, 659 * or an array of args to send to the event. 660 * @api private 661 */ 662 emitEvent: function emit(eventName, args, done) { 663 if (typeof args === 'function') { done = args; args = null; } 664 if (!done) done = function() { }; 665 if (!args) args = this.eventParameters(eventName, this.response); 666 667 var origEmit = AWS.SequentialExecutor.prototype.emit; 668 origEmit.call(this, eventName, args, function (err) { 669 if (err) this.response.error = err; 670 done.call(this, err); 671 }); 672 }, 673 674 /** 675 * @api private 676 */ 677 eventParameters: function eventParameters(eventName) { 678 switch (eventName) { 679 case 'restart': 680 case 'validate': 681 case 'sign': 682 case 'build': 683 case 'afterValidate': 684 case 'afterBuild': 685 return [this]; 686 case 'error': 687 return [this.response.error, this.response]; 688 default: 689 return [this.response]; 690 } 691 }, 692 693 /** 694 * @api private 695 */ 696 presign: function presign(expires, callback) { 697 if (!callback && typeof expires === 'function') { 698 callback = expires; 699 expires = null; 700 } 701 return new AWS.Signers.Presign().sign(this.toGet(), expires, callback); 702 }, 703 704 /** 705 * @api private 706 */ 707 isPresigned: function isPresigned() { 708 return Object.prototype.hasOwnProperty.call(this.httpRequest.headers, 'presigned-expires'); 709 }, 710 711 /** 712 * @api private 713 */ 714 toUnauthenticated: function toUnauthenticated() { 715 this.removeListener('validate', AWS.EventListeners.Core.VALIDATE_CREDENTIALS); 716 this.removeListener('sign', AWS.EventListeners.Core.SIGN); 717 return this; 718 }, 719 720 /** 721 * @api private 722 */ 723 toGet: function toGet() { 724 if (this.service.api.protocol === 'query' || 725 this.service.api.protocol === 'ec2') { 726 this.removeListener('build', this.buildAsGet); 727 this.addListener('build', this.buildAsGet); 728 } 729 return this; 730 }, 731 732 /** 733 * @api private 734 */ 735 buildAsGet: function buildAsGet(request) { 736 request.httpRequest.method = 'GET'; 737 request.httpRequest.path = request.service.endpoint.path + 738 '?' + request.httpRequest.body; 739 request.httpRequest.body = ''; 740 741 // don't need these headers on a GET request 742 delete request.httpRequest.headers['Content-Length']; 743 delete request.httpRequest.headers['Content-Type']; 744 }, 745 746 /** 747 * @api private 748 */ 749 haltHandlersOnError: function haltHandlersOnError() { 750 this._haltHandlersOnError = true; 751 } 752 }); 753 754 /** 755 * @api private 756 */ 757 AWS.Request.addPromisesToClass = function addPromisesToClass(PromiseDependency) { 758 this.prototype.promise = function promise() { 759 var self = this; 760 return new PromiseDependency(function(resolve, reject) { 761 self.on('complete', function(resp) { 762 if (resp.error) { 763 reject(resp.error); 764 } else { 765 resolve(resp.data); 766 } 767 }); 768 self.runTo(); 769 }); 770 }; 771 }; 772 773 /** 774 * @api private 775 */ 776 AWS.Request.deletePromisesFromClass = function deletePromisesFromClass() { 777 delete this.prototype.promise; 778 }; 779 780 AWS.util.addPromises(AWS.Request); 781 782 AWS.util.mixin(AWS.Request, AWS.SequentialExecutor);