Skip to content

Commit e5a72fe

Browse files
storage: support resumable uploads
1 parent 1cc2031 commit e5a72fe

3 files changed

Lines changed: 256 additions & 82 deletions

File tree

lib/common/util.js

Lines changed: 69 additions & 66 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
* you may not use this file except in compliance with the License.
66
* You may obtain a copy of the License at
77
*
8-
* http://www.apache.org/licenses/LICENSE-2.0
8+
* http://www.apache.org/licenses/LICENSE-2.0
99
*
1010
* Unless required by applicable law or agreed to in writing, software
1111
* distributed under the License is distributed on an "AS IS" BASIS,
@@ -52,26 +52,26 @@ var USER_AGENT = 'gcloud-node/' + PKG.version;
5252
*
5353
* @example
5454
* // globalConfig = {
55-
* // credentials: {...}
55+
* // credentials: {...}
5656
* // }
5757
* Datastore.prototype.dataset = function(options) {
58-
* // options = {
59-
* // keyFilename: 'keyfile.json'
60-
* // }
61-
* return extendGlobalConfig(this.config, options);
62-
* // returns:
63-
* // {
64-
* // keyFilename: 'keyfile.json'
65-
* // }
58+
* // options = {
59+
* // keyFilename: 'keyfile.json'
60+
* // }
61+
* return extendGlobalConfig(this.config, options);
62+
* // returns:
63+
* // {
64+
* // keyFilename: 'keyfile.json'
65+
* // }
6666
* };
6767
*/
6868
function extendGlobalConfig(globalConfig, overrides) {
6969
var options = extend({}, globalConfig);
7070
var hasGlobalConnection = options.credentials || options.keyFilename;
7171
var isOverridingConnection = overrides.credentials || overrides.keyFilename;
7272
if (hasGlobalConnection && isOverridingConnection) {
73-
delete options.credentials;
74-
delete options.keyFilename;
73+
delete options.credentials;
74+
delete options.keyFilename;
7575
}
7676
return extend(true, {}, options, overrides);
7777
}
@@ -93,7 +93,7 @@ module.exports.extendGlobalConfig = extendGlobalConfig;
9393
*/
9494
function arrayize(input) {
9595
if (!Array.isArray(input)) {
96-
return [input];
96+
return [input];
9797
}
9898
return input;
9999
}
@@ -109,14 +109,14 @@ module.exports.arrayize = arrayize;
109109
*
110110
* @example
111111
* format('This is a {language} ({abbr}) codebase.', {
112-
* language: 'JavaScript',
113-
* abbr: 'JS'
112+
* language: 'JavaScript',
113+
* abbr: 'JS'
114114
* });
115115
* // 'This is a JavaScript (JS) codebase.'
116116
*/
117117
function format(template, args) {
118118
return template.replace(/{([^}]*)}/g, function(match, key) {
119-
return args[key] || match;
119+
return args[key] || match;
120120
});
121121
}
122122

@@ -127,7 +127,7 @@ module.exports.format = format;
127127
*
128128
* @example
129129
* function doSomething(callback) {
130-
* callback = callback || noop;
130+
* callback = callback || noop;
131131
* }
132132
*/
133133
function noop() {}
@@ -147,6 +147,7 @@ function ApiError(errorBody) {
147147
this.errors = errorBody.errors;
148148
this.code = errorBody.code;
149149
this.message = errorBody.message;
150+
this.response = errorBody.response;
150151
}
151152

152153
util.inherits(ApiError, Error);
@@ -162,27 +163,28 @@ util.inherits(ApiError, Error);
162163
function handleResp(err, resp, body, callback) {
163164
callback = callback || noop;
164165
if (err) {
165-
callback(err);
166-
return;
166+
callback(err);
167+
return;
167168
}
168169
if (typeof body === 'string') {
169-
try {
170-
body = JSON.parse(body);
171-
} catch(err) {}
170+
try {
171+
body = JSON.parse(body);
172+
} catch(err) {}
172173
}
173174
if (body && body.error) {
174-
// Error from JSON api.
175-
callback(new ApiError(body.error));
176-
return;
175+
// Error from JSON api.
176+
callback(new ApiError(body.error));
177+
return;
177178
}
178179
if (resp && (resp.statusCode < 200 || resp.statusCode > 299)) {
179-
// Unknown error. Format according to ApiError standard.
180-
callback(new ApiError({
181-
errors: [],
182-
code: resp.statusCode,
183-
message: body || 'Error during request.'
184-
}));
185-
return;
180+
// Unknown error. Format according to ApiError standard.
181+
callback(new ApiError({
182+
errors: [],
183+
code: resp.statusCode,
184+
message: body || 'Error during request.',
185+
response: resp
186+
}));
187+
return;
186188
}
187189
callback(null, body, resp);
188190
}
@@ -196,7 +198,7 @@ module.exports.handleResp = handleResp;
196198
*/
197199
function getType(value) {
198200
if (value instanceof Buffer) {
199-
return 'buffer';
201+
return 'buffer';
200202
}
201203
return Object.prototype.toString.call(value).match(/\s(\w+)\]/)[1];
202204
}
@@ -226,7 +228,7 @@ module.exports.is = is;
226228
*
227229
* @example
228230
* function aFunction() {
229-
* return toArray(arguments);
231+
* return toArray(arguments);
230232
* }
231233
*
232234
* aFunction(1, 2, 3);
@@ -245,17 +247,17 @@ module.exports.toArray = toArray;
245247
* @param {Duplexify} dup - Duplexify stream.
246248
* @param {object} options - Configuration object.
247249
* @param {module:common/connection} options.connection - A connection instance,
248-
* used to get a token with and send the request through.
250+
* used to get a token with and send the request through.
249251
* @param {object} options.metadata - Metadata to send at the head of the
250-
* request.
252+
* request.
251253
* @param {object} options.request - Request object, in the format of a standard
252-
* Node.js http.request() object.
254+
* Node.js http.request() object.
253255
* @param {string=} options.request.method - Default: "POST".
254256
* @param {string=} options.request.qs.uploadType - Default: "multipart".
255257
* @param {string=} options.streamContentType - Default:
256-
* "application/octet-stream".
258+
* "application/octet-stream".
257259
* @param {function} onComplete - Callback, executed after the writable Request
258-
* stream has completed.
260+
* stream has completed.
259261
*/
260262
function makeWritableStream(dup, options, onComplete) {
261263
onComplete = onComplete || noop;
@@ -269,7 +271,7 @@ function makeWritableStream(dup, options, onComplete) {
269271
var defaults = {
270272
method: 'POST',
271273
qs: {
272-
uploadType: 'multipart'
274+
uploadType: 'multipart'
273275
}
274276
};
275277

@@ -339,42 +341,43 @@ function makeWritableStream(dup, options, onComplete) {
339341
});
340342
}
341343

344+
342345
module.exports.makeWritableStream = makeWritableStream;
343346

344347
function makeAuthorizedRequest(config) {
345348
var authorize = gsa(config);
346349

347350
function makeRequest(reqOpts, callback) {
348-
var tokenRefreshAttempts = 0;
349-
reqOpts.headers = reqOpts.headers || {};
350-
351-
if (reqOpts.headers['User-Agent']) {
352-
reqOpts.headers['User-Agent'] += '; ' + USER_AGENT;
353-
} else {
354-
reqOpts.headers['User-Agent'] = USER_AGENT;
355-
}
356-
357-
function onAuthorizedRequest(err, authorizedReqOpts) {
358-
if (err) {
359-
if (err.code === 401 &&
360-
++tokenRefreshAttempts <= MAX_TOKEN_REFRESH_ATTEMPTS) {
361-
authorize(reqOpts, onAuthorizedRequest);
362-
} else {
363-
(callback.onAuthorized || callback)(err);
364-
}
365-
return;
366-
}
367-
368-
if (callback.onAuthorized) {
369-
callback.onAuthorized(null, authorizedReqOpts);
351+
var tokenRefreshAttempts = 0;
352+
reqOpts.headers = reqOpts.headers || {};
353+
354+
if (reqOpts.headers['User-Agent']) {
355+
reqOpts.headers['User-Agent'] += '; ' + USER_AGENT;
356+
} else {
357+
reqOpts.headers['User-Agent'] = USER_AGENT;
358+
}
359+
360+
function onAuthorizedRequest(err, authorizedReqOpts) {
361+
if (err) {
362+
if (err.code === 401 &&
363+
++tokenRefreshAttempts <= MAX_TOKEN_REFRESH_ATTEMPTS) {
364+
authorize(reqOpts, onAuthorizedRequest);
370365
} else {
371-
request(authorizedReqOpts, function(err, res, body) {
372-
handleResp(err, res, body, callback);
373-
});
366+
(callback.onAuthorized || callback)(err);
374367
}
368+
return;
369+
}
370+
371+
if (callback.onAuthorized) {
372+
callback.onAuthorized(null, authorizedReqOpts);
373+
} else {
374+
request(authorizedReqOpts, function(err, res, body) {
375+
handleResp(err, res, body, callback);
376+
});
375377
}
378+
}
376379

377-
authorize(reqOpts, onAuthorizedRequest);
380+
authorize(reqOpts, onAuthorizedRequest);
378381
}
379382

380383
makeRequest.getCredentials = authorize.getCredentials;

0 commit comments

Comments
 (0)