This repository has been archived by the owner on May 21, 2020. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 11
/
nox.js
134 lines (109 loc) · 3.21 KB
/
nox.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
// nox - S3 Client for node.js
//
// Copyright(c) 2011-2012 Nephics AB
// MIT Licensed
//
// Some code parts derived from knox:
// https://github.com/LearnBoost/knox
// Copyright(c) 2010 LearnBoost <[email protected]>
// MIT Licensed
var http = require('http');
var url = require('url');
var path = require('path');
var fs = require('fs');
var auth = require('./auth')
function merge(a, b) {
Object.keys(b).forEach(function(key) {
a[key] = b[key]
});
return a;
}
// Create a S3 client
//
// Required options:
// key: aws key
// secret: aws secret
// bucket: aws bucket name (may include the endpoint)
exports.createClient = function(options) {
if (!options.key) throw new Error('aws "key" required');
if (!options.secret) throw new Error('aws "secret" required');
if (!options.bucket) throw new Error('aws "bucket" required');
var bucket;
var endpoint;
if (options.bucket.match(/\.amazonaws\.com$/)) {
// bucket includes the endpoint
endpoint = options.bucket;
bucket = options.bucket.match(/(.*)\.([\w\-]+)\.amazonaws\.com$/)[1];
}
else {
// assume default endpoint
bucket = options.bucket;
endpoint = bucket + '.s3.amazonaws.com';
}
function request(method, filename, headers) {
var date = new Date;
var headers = headers || {};
// Default headers
merge(headers, {
Date:date.toUTCString(),
Host:endpoint
});
// Authorization header
headers.Authorization = auth.authorization({
key:options.key,
secret:options.secret,
verb:method,
date:date,
resource:auth.canonicalizeResource(path.join('/', bucket, filename)),
contentType:headers['Content-Type'],
md5:headers['Content-MD5'],
amazonHeaders:auth.canonicalizeHeaders(headers)
});
// Issue request
var opts = {
host:endpoint,
port:80,
method:method,
path:path.join('/', filename),
headers:headers
};
return http.request(opts);
}
var client = new function() {};
client.put = function put(filename, headers) {
headers.Expect = '100-continue';
return request('PUT', filename, headers);
};
client.get = function get(filename, headers) {
return request('GET', filename, headers);
};
client.head = function head(filename, headers) {
return request('HEAD', filename, headers);
};
// Delete file
client.del = function del(filename, headers) {
return request('DELETE', filename, headers);
};
// Return an S3 presigned url to the given `filename`.
client.signedUrl = function signedUrl(filename, expiration) {
var epoch = Math.floor(expiration.getTime()/1000);
var signature = auth.signQuery({
secret:options.secret,
date:epoch,
resource:'/' + bucket + url.parse(filename).pathname
});
var _url = 'http://' + path.join(endpoint, filename) +
'?Expires=' + epoch +
'&AWSAccessKeyId=' + options.key +
'&Signature=' + encodeURIComponent(signature);
return _url;
};
client.url =
client.http = function(filename){
return 'http://' + path.join(this.endpoint, this.bucket, filename);
};
client.https = function(filename){
return 'https://' + path.join(this.endpoint, filename);
};
return client;
};