Skip to content

Commit 3344709

Browse files
authored
fix: update S3 status 200 error behavior (#4654)
* fix: update S3 status 200 error behavior * fix: exit is200Error early if response too short/long
1 parent e4e0c12 commit 3344709

File tree

3 files changed

+63
-13
lines changed

3 files changed

+63
-13
lines changed

Diff for: .changes/next-release/bugfix-s3-09efbe2a.json

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
{
2+
"type": "bugfix",
3+
"category": "s3",
4+
"description": "update s3 status 200 error classification"
5+
}

Diff for: lib/services/s3.js

+51-6
Original file line numberDiff line numberDiff line change
@@ -531,17 +531,21 @@ AWS.util.update(AWS.S3.prototype, {
531531
* @api private
532532
*/
533533
extractErrorFrom200Response: function extractErrorFrom200Response(resp) {
534-
if (!operationsWith200StatusCodeError[resp.request.operation]) return;
534+
var service = this.service ? this.service : this;
535+
if (!service.is200Error(resp) && !operationsWith200StatusCodeError[resp.request.operation]) {
536+
return;
537+
}
535538
var httpResponse = resp.httpResponse;
536-
if (httpResponse.body && httpResponse.body.toString().match('<Error>')) {
539+
var bodyString = httpResponse.body && httpResponse.body.toString() || '';
540+
if (bodyString && bodyString.indexOf('</Error>') === bodyString.length - 8) {
537541
// Response body with '<Error>...</Error>' indicates an exception.
538542
// Get S3 client object. In ManagedUpload, this.service refers to
539543
// S3 client object.
540544
resp.data = null;
541-
var service = this.service ? this.service : this;
542545
service.extractError(resp);
546+
resp.error.is200Error = true;
543547
throw resp.error;
544-
} else if (!httpResponse.body || !httpResponse.body.toString().match(/<[\w_]/)) {
548+
} else if (!httpResponse.body || !bodyString.match(/<[\w_]/)) {
545549
// When body is empty or incomplete, S3 might stop the request on detecting client
546550
// side aborting the request.
547551
resp.data = null;
@@ -552,13 +556,54 @@ AWS.util.update(AWS.S3.prototype, {
552556
}
553557
},
554558

559+
/**
560+
* @api private
561+
* @param resp - to evaluate.
562+
* @return true if the response has status code 200 but is an error.
563+
*/
564+
is200Error: function is200Error(resp) {
565+
var code = resp && resp.httpResponse && resp.httpResponse.statusCode;
566+
if (code !== 200) {
567+
return false;
568+
}
569+
try {
570+
var req = resp.request;
571+
var outputMembers = req.service.api.operations[req.operation].output.members;
572+
var keys = Object.keys(outputMembers);
573+
for (var i = 0; i < keys.length; ++i) {
574+
var member = outputMembers[keys[i]];
575+
if (member.type === 'binary' && member.isStreaming) {
576+
return false;
577+
}
578+
}
579+
580+
var body = resp.httpResponse.body;
581+
if (body && body.byteLength !== undefined) {
582+
if (body.byteLength < 15 || body.byteLength > 3000) {
583+
// body is too short or long to be an error message.
584+
return false;
585+
}
586+
}
587+
if (!body) {
588+
return false;
589+
}
590+
var bodyString = body.toString();
591+
if (bodyString.indexOf('</Error>') === bodyString.length - 8) {
592+
return true;
593+
}
594+
} catch (e) {
595+
return false;
596+
}
597+
return false;
598+
},
599+
555600
/**
556601
* @return [Boolean] whether the error can be retried
557602
* @api private
558603
*/
559604
retryableError: function retryableError(error, request) {
560-
if (operationsWith200StatusCodeError[request.operation] &&
561-
error.statusCode === 200) {
605+
if (error.is200Error ||
606+
(operationsWith200StatusCodeError[request.operation] && error.statusCode === 200)) {
562607
return true;
563608
} else if (request._requestRegionForBucket &&
564609
request.service.bucketRegionCache[request._requestRegionForBucket]) {

Diff for: scripts/region-checker/allowlist.js

+7-7
Original file line numberDiff line numberDiff line change
@@ -44,13 +44,13 @@ var allowlist = {
4444
263,
4545
276,
4646
282,
47-
642,
48-
644,
49-
763,
50-
774,
51-
775,
52-
776,
53-
781
47+
687,
48+
689,
49+
808,
50+
819,
51+
820,
52+
821,
53+
826
5454
],
5555
'/token/sso_token_provider.js': [
5656
60

0 commit comments

Comments
 (0)