Skip to content

Commit c3c4aad

Browse files
Merge pull request #102 from Marketcircle/add-urlencode-option
Add an option to disable URL encoding source
2 parents 063a9c1 + 468671e commit c3c4aad

File tree

5 files changed

+54
-10
lines changed

5 files changed

+54
-10
lines changed

README.md

+10
Original file line numberDiff line numberDiff line change
@@ -160,6 +160,16 @@ The Server-side encryption algorithm used when storing this object in S3 (e.g.,
160160
- "AES256"
161161
- "aws:kms"
162162

163+
### urlEncodeSourceObject
164+
165+
Controls if the `x-amz-copy-source` header is going to be be URL encoded.
166+
There is a known issue with DigitalOcean Spaces and older versions of CEPH
167+
that don't accept URL encoded copy sources.
168+
169+
If you are using DigitalOcean spaces you need to set this setting to `false`.
170+
171+
*Default:* `true`
172+
163173
### How do I activate a revision?
164174

165175
A user can activate a revision by either:

index.js

+4-1
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ module.exports = {
1717
prefix: '',
1818
acl: 'public-read',
1919
cacheControl: 'max-age=0, no-cache',
20+
urlEncodeSourceObject: true,
2021
distDir: function(context) {
2122
return context.distDir;
2223
},
@@ -50,6 +51,7 @@ module.exports = {
5051
var brotliCompressedFiles = this.readConfig('brotliCompressedFiles');
5152
var allowOverwrite = this.readConfig('allowOverwrite');
5253
var serverSideEncryption = this.readConfig('serverSideEncryption');
54+
var urlEncodeSourceObject = this.readConfig('urlEncodeSourceObject');
5355
var filePath = joinUriSegments(distDir, filePattern);
5456

5557
var options = {
@@ -62,7 +64,8 @@ module.exports = {
6264
revisionKey: revisionKey,
6365
gzippedFilePaths: gzippedFiles,
6466
brotliCompressedFilePaths: brotliCompressedFiles,
65-
allowOverwrite: allowOverwrite
67+
allowOverwrite: allowOverwrite,
68+
urlEncodeSourceObject: urlEncodeSourceObject
6669
};
6770

6871
if (serverSideEncryption) {

lib/s3.js

+8-3
Original file line numberDiff line numberDiff line change
@@ -108,20 +108,25 @@ module.exports = CoreObject.extend({
108108
var prefix = options.prefix;
109109
var filePattern = options.filePattern;
110110
var key = filePattern + ":" + options.revisionKey;
111-
var serverSideEncryption = options.serverSideEncryption;
111+
var serverSideEncryption = options.serverSideEncryption;
112+
var urlEncodeSourceObject = options.urlEncodeSourceObject;
112113

113114
var revisionKey = joinUriSegments(prefix, key);
114115
var indexKey = joinUriSegments(prefix, filePattern);
115-
var copySource = encodeURIComponent([bucket, revisionKey].join('/'));
116116
var copyObject = RSVP.denodeify(client.copyObject.bind(client));
117117

118118
var params = {
119119
Bucket: bucket,
120-
CopySource: copySource,
121120
Key: indexKey,
122121
ACL: acl,
123122
};
124123

124+
if (urlEncodeSourceObject) {
125+
params.CopySource = encodeURIComponent([bucket, revisionKey].join('/'));
126+
} else {
127+
params.CopySource = `${bucket}/${revisionKey}`
128+
}
129+
125130
if (serverSideEncryption) {
126131
params.ServerSideEncryption = serverSideEncryption;
127132
}

tests/unit/index-test.js

+8-4
Original file line numberDiff line numberDiff line change
@@ -119,7 +119,8 @@ describe('s3-index plugin', function() {
119119
gzippedFilePaths: [],
120120
brotliCompressedFilePaths: [],
121121
revisionKey: REVISION_KEY,
122-
allowOverwrite: false
122+
allowOverwrite: false,
123+
urlEncodeSourceObject: true
123124
};
124125

125126
assert.deepEqual(s3Options, expected);
@@ -163,7 +164,8 @@ describe('s3-index plugin', function() {
163164
gzippedFilePaths: [],
164165
brotliCompressedFilePaths: [],
165166
revisionKey: REVISION_KEY,
166-
allowOverwrite: false
167+
allowOverwrite: false,
168+
urlEncodeSourceObject: true
167169
};
168170

169171
assert.deepEqual(s3Options, expected);
@@ -187,7 +189,8 @@ describe('s3-index plugin', function() {
187189
gzippedFilePaths: ['index.html'],
188190
brotliCompressedFilePaths: [],
189191
revisionKey: REVISION_KEY,
190-
allowOverwrite: false
192+
allowOverwrite: false,
193+
urlEncodeSourceObject: true
191194
};
192195

193196
assert.deepEqual(s3Options, expected);
@@ -211,7 +214,8 @@ describe('s3-index plugin', function() {
211214
gzippedFilePaths: [],
212215
brotliCompressedFilePaths: ['index.html'],
213216
revisionKey: REVISION_KEY,
214-
allowOverwrite: false
217+
allowOverwrite: false,
218+
urlEncodeSourceObject: true
215219
};
216220

217221
assert.deepEqual(s3Options, expected);

tests/unit/lib/s3-test.js

+24-2
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,8 @@ describe('s3', function() {
7777
filePattern: filePattern,
7878
revisionKey: revisionKey,
7979
filePath: 'tests/unit/fixtures/test.html',
80-
allowOverwrite: false
80+
allowOverwrite: false,
81+
urlEncodeSourceObject: true
8182
};
8283

8384
s3Client.putObject = function(params, cb) {
@@ -372,7 +373,8 @@ describe('s3', function() {
372373
bucket: bucket,
373374
prefix: prefix,
374375
acl: acl,
375-
filePattern: filePattern
376+
filePattern: filePattern,
377+
urlEncodeSourceObject: true,
376378
};
377379
});
378380

@@ -429,6 +431,26 @@ describe('s3', function() {
429431
});
430432
});
431433

434+
it ('does not url encode the CopySource when urlEncodeSourceObject is disabled', function() {
435+
options.urlEncodeSourceObject = false;
436+
var prefix = 'my-app';
437+
revisionsData = {
438+
Contents: [
439+
{ Key: prefix+'/test.html:123', LastModified: new Date('September 27, 2015 01:00:00'), ETag: '123' },
440+
{ Key: prefix+'/test.html:456', LastModified: new Date('September 27, 2015 02:00:00') , ETag: '456' }
441+
]
442+
};
443+
444+
options.prefix = prefix;
445+
var promise = subject.activate(options);
446+
447+
return assert.isFulfilled(promise)
448+
.then(function() {
449+
assert.equal(copyParams.Key, prefix+'/'+filePattern);
450+
assert.equal(copyParams.CopySource, bucket+'/'+prefix+'/'+filePattern+':456');
451+
});
452+
});
453+
432454
it('allows `acl` option to be passed to customize the used ACL', function() {
433455
var acl = 'authenticated-read';
434456

0 commit comments

Comments
 (0)