Skip to content

Commit

Permalink
Merge pull request #437 from aws/feature-expect-100-s3
Browse files Browse the repository at this point in the history
Add Expect: 100-continue for large payloads in S3 by default.
  • Loading branch information
lsegal committed Dec 10, 2014
2 parents 772df68 + e072af4 commit 543ee65
Show file tree
Hide file tree
Showing 3 changed files with 39 additions and 1 deletion.
11 changes: 10 additions & 1 deletion lib/http/node.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ require('../http');
*/
AWS.NodeHttpClient = AWS.util.inherit({
handleRequest: function handleRequest(httpRequest, httpOptions, callback, errCallback) {
var self = this;
var cbAlreadyCalled = false;
var endpoint = httpRequest.endpoint;
var pathPrefix = '';
Expand Down Expand Up @@ -61,7 +62,15 @@ AWS.NodeHttpClient = AWS.util.inherit({
errCallback.apply(this, arguments);
});

this.writeBody(stream, httpRequest);
var expect = httpRequest.headers.Expect || httpRequest.headers.expect;
if (expect === '100-continue') {
stream.on('continue', function() {
self.writeBody(stream, httpRequest);
});
} else {
this.writeBody(stream, httpRequest);
}

return stream;
},

Expand Down
12 changes: 12 additions & 0 deletions lib/services/s3.js
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ AWS.util.update(AWS.S3.prototype, {
request.addListener('build', this.computeContentMd5);
request.onAsync('build', this.computeSha256);
request.addListener('build', this.computeSseCustomerKeyMd5);
request.addListener('afterBuild', this.addExpect100Continue);
request.removeListener('validate',
AWS.EventListeners.Core.VALIDATE_REGION);
request.addListener('extractError', this.extractError);
Expand Down Expand Up @@ -101,6 +102,17 @@ AWS.util.update(AWS.S3.prototype, {
}
},

/**
* Adds Expect: 100-continue header if payload is greater-or-equal 1MB
* @api private
*/
addExpect100Continue: function addExpect100Continue(req) {
var len = req.httpRequest.headers['Content-Length'];
if (AWS.util.isNode() && len >= 1024 * 1024) {
req.httpRequest.headers['Expect'] = '100-continue';
}
},

/**
* Adds a default content type if none is supplied.
*
Expand Down
17 changes: 17 additions & 0 deletions test/services/s3.spec.coffee
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,23 @@ describe 'AWS.S3', ->
req = build('listObjects', { Bucket: 'bucket', MaxKeys:123 })
expect(req.path).to.equal('/?max-keys=123')

describe 'adding Expect: 100-continue', ->
if AWS.util.isNode()
it 'does not add expect header to payloads less than 1MB', ->
req = build('putObject', Bucket: 'bucket', Key: 'key', Body: new Buffer(1024 * 1024 - 1))
expect(req.headers['Expect']).not.to.exist

it 'adds expect header to payloads greater than 1MB', ->
req = build('putObject', Bucket: 'bucket', Key: 'key', Body: new Buffer(1024 * 1024 + 1))
expect(req.headers['Expect']).to.equal('100-continue')

if AWS.util.isBrowser()
beforeEach -> helpers.spyOn(AWS.util, 'isBrowser').andReturn(true)

it 'does not add expect header in the browser', ->
req = build('putObject', Bucket: 'bucket', Key: 'key', Body: new Buffer(1024 * 1024 + 1))
expect(req.headers['Expect']).not.to.exist

describe 'adding Content-Type', ->
beforeEach -> helpers.spyOn(AWS.util, 'isBrowser').andReturn(true)

Expand Down

0 comments on commit 543ee65

Please sign in to comment.