Skip to content

Commit 4f97cd1

Browse files
committed
Buffer all upload streams as Akamai requires a Content-Length header in
uploads, and some streams (e.g. multipart) don't provide one
1 parent aec217f commit 4f97cd1

2 files changed

Lines changed: 60 additions & 38 deletions

File tree

lib/akamai.js

Lines changed: 59 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -129,7 +129,7 @@ akamai.setLogger = function(l) {
129129
* @param {Function} cb
130130
* @returns {request}
131131
*/
132-
akamai.getRequestObject = function (path, params, cb) {
132+
akamai.getRequestObject = function (path, params, cb, httpHeaders) {
133133
var self = this,
134134
callback = function () {},
135135
options = _.merge(
@@ -141,6 +141,9 @@ akamai.getRequestObject = function (path, params, cb) {
141141
if (reqOptions) {
142142
_.assign(options,reqOptions) ;
143143
}
144+
if (httpHeaders) {
145+
_.assign(options.headers,httpHeaders) ;
146+
}
144147

145148
if (typeof(cb) === 'function') {
146149
callback = function (err, resp, body) {
@@ -191,12 +194,15 @@ akamai.fileExists = function (path, cb) {
191194

192195
/** Api functions **/
193196

194-
akamai.upload = function (stream, path, cb) {
197+
akamai.upload = function (stream, path, cb, contentLength) {
195198
var options = {
196199
request: {method: 'put'},
197200
headers: {action: 'upload', 'upload-type': 'binary'}
198201
};
199-
stream.pipe(this.getRequestObject(path, options, cb));
202+
var httpHeaders = {} ;
203+
if (contentLength)
204+
httpHeaders["Content-Length"] = contentLength ;
205+
stream.pipe(this.getRequestObject(path, options, cb, httpHeaders));
200206
return this;
201207
};
202208

@@ -276,57 +282,73 @@ akamai.mtime = function (path, date, cb) {
276282

277283
/* Added by MattW for MOL */
278284
/* Like upload, but creates the path beforehand */
279-
akamai.create = function(source /*stream*/, cpcode, target, callback) {
285+
akamai.create = function(stream, cpcode, target, callback) {
280286
var self = this ;
281287

282288
try {
283-
if (!source)
289+
if (!stream)
284290
return callback && callback(new Error("akamai.create: source is not a stream")) ;
285-
if (!("pipe" in source)) {
291+
if (!("pipe" in stream)) {
286292
// Probabaly not a stream
287-
var original = source ;
288-
source = new Stream();
293+
var source = new Stream();
289294
source.pipe = function(dest) {
290-
dest.write(original);
295+
dest.write(stream);
291296
return dest;
292-
};
297+
};
298+
doUpload(source,stream.length) ;
299+
} else {
300+
// Akamai requires uploads must have a Content-Length, so we'll have to buffer
301+
var buffers = [] ;
302+
stream.on('data',function(b){ buffers.push(b) }) ;
303+
stream.on('end',function(){
304+
var source = new Stream() ;
305+
var all = Buffer.concat(buffers) ;
306+
source.pipe = function(dest) {
307+
dest.write(all);
308+
return dest;
309+
};
310+
doUpload(source,all.length) ;
311+
}) ;
293312
}
313+
return ;
294314
} catch(ex) {
295315
return callback && callback(ex) ;
296316
}
297317

298-
function mkdir(path,idx,done) {
299-
if (idx>path.length)
300-
return done(null) ;
301-
idx += 1 ;
302-
var l = path.slice(0,idx).join("/") ;
303-
self.mkdir(l,function(err){
304-
if (err && err.status!=409 && err.status!=403) {
305-
err.message = "mkdir("+l+") "+err.message ;
306-
return done(err) ;
307-
}
308-
mkdir(path,idx,done) ;
309-
});
310-
}
311-
312-
// Create path
313-
target = path.join("/", "" + cpcode, "/", target) ;
314-
var dirPath = target.split("/") ;
315-
dirPath = dirPath.slice(0,dirPath.length-1).join("/") ;
316-
317-
mkdir(dirPath.split("/"),2,function(err){
318-
if (err) {
319-
err.message = err.message+"\n"+JSON.stringify(self.getConfig()) ;
320-
return callback && callback(err);
318+
function doUpload(source,contentLength) {
319+
function mkdir(path,idx,done) {
320+
if (idx>path.length)
321+
return done(null) ;
322+
idx += 1 ;
323+
var l = path.slice(0,idx).join("/") ;
324+
self.mkdir(l,function(err){
325+
if (err && err.status!=409 && err.status!=403) {
326+
err.message = "mkdir("+l+") "+err.message ;
327+
return done(err) ;
328+
}
329+
mkdir(path,idx,done) ;
330+
});
321331
}
322-
self.upload(source, target, function(err){
332+
333+
// Create path
334+
target = path.join("/", "" + cpcode, "/", target) ;
335+
var dirPath = target.split("/") ;
336+
dirPath = dirPath.slice(0,dirPath.length-1).join("/") ;
337+
338+
mkdir(dirPath.split("/"),2,function(err){
323339
if (err) {
324-
err.message = err.message+"\t"+JSON.stringify(self.getConfig()) ;
340+
err.message = err.message+"\n"+JSON.stringify(self.getConfig()) ;
325341
return callback && callback(err);
326342
}
327-
callback && callback();
343+
self.upload(source, target, function(err){
344+
if (err) {
345+
err.message = err.message+"\t"+JSON.stringify(self.getConfig()) ;
346+
return callback && callback(err);
347+
}
348+
callback && callback();
349+
},contentLength) ;
328350
}) ;
329-
}) ;
351+
}
330352
}
331353

332354

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "akamai-http-api",
3-
"version": "0.3.4",
3+
"version": "0.3.5",
44
"main": "./lib/akamai.js",
55
"author": "Kanstantsin Kamkou <kkamkou@gmail.com>",
66
"description": "Akamai NetStorage HTTP API for the Node.js",

0 commit comments

Comments
 (0)