UNPKG

4.07 kBJavaScriptView Raw
1// Generated by CoffeeScript 2.3.1
2(function() {
3 // Web server
4 // ----------
5 var Cors, DOWNLOAD, REV, TOKEN, UNTIL, UPLOAD, URL, agent, assert, attachments_proxy, crypto, request, strictEqual;
6
7 DOWNLOAD = 'get';
8
9 UPLOAD = 'put';
10
11 TOKEN = 'token';
12
13 REV = 'rev';
14
15 UNTIL = 'until';
16
17 attachments_proxy = function(our_proxy) {
18 var cors, download_uri, handler, hash, secret, signature, timeout, upload_uri, uri_maker;
19 ({secret, hash, timeout} = our_proxy);
20 cors = Cors();
21 if (hash == null) {
22 hash = 'sha256';
23 }
24 if (timeout == null) {
25 timeout = 3600 * 1000; // one hour
26 }
27 signature = function(method, pathname, rev, limit) {
28 strictEqual('string', typeof method, 'method');
29 strictEqual('string', typeof pathname, 'pathname');
30 strictEqual('string', typeof rev, 'rev');
31 strictEqual('string', typeof limit, 'limit');
32 return crypto.createHmac(hash, secret).update(method).update(pathname).update(rev).update(limit).digest('hex');
33 };
34 handler = function(req, res, next) {
35 var limit, pathname, proxy, rev, searchParams, token;
36 if (next == null) {
37 next = function(msg) {
38 res.writeHead(404);
39 res.end(msg);
40 };
41 }
42 proxy = function() {
43 var method, options, the_proxy;
44 ({method} = req);
45 options = our_proxy.target(pathname);
46 if ((options != null ? options.url : void 0) == null) {
47 return next();
48 }
49 options.url.searchParams.set('rev', rev);
50 options.url = options.url.toString();
51 the_proxy = agent(Object.assign({
52 method,
53 followRedirects: false,
54 maxRedirects: 0,
55 headers: {
56 Connection: 'close'
57 }
58 }, options));
59 the_proxy.on('error', function(error) {
60 return console.error('Proxy', method, options.url, error);
61 });
62 // req.socket.setKeepAlive true
63 res.setHeader('Connection', 'close');
64 req.on('end', function() {
65 return the_proxy.end();
66 });
67 res.on('close', function() {
68 return the_proxy.abort(); // this is the main one
69 });
70 req.pipe(the_proxy).pipe(res);
71 };
72 ({pathname, searchParams} = new URL(req.url, our_proxy.url));
73 token = searchParams.get(TOKEN);
74 if (token == null) {
75 return next('Invalid token');
76 }
77 rev = searchParams.get(REV);
78 if (rev == null) {
79 return next('Invalid rev');
80 }
81 limit = searchParams.get(UNTIL);
82 if (!((limit != null ? limit.match(/^\d+$/) : void 0) && parseInt(limit) > Date.now())) {
83 return next(`Invalid limit ${JSON.stringify(limit)}`);
84 }
85 switch (req.method) {
86 case 'OPTIONS':
87 return cors(req, res, next);
88 case 'PUT':
89 if (token === signature(UPLOAD, pathname, rev, limit)) {
90 return proxy();
91 } else {
92 return next("Invalid token");
93 }
94 break;
95 case 'GET':
96 case 'HEAD':
97 if (token === signature(DOWNLOAD, pathname, rev, limit)) {
98 return proxy();
99 } else {
100 return next("Invalid token");
101 }
102 }
103 next();
104 };
105 uri_maker = function(direction) {
106 return function(path, rev) {
107 var limit, url;
108 url = new URL(path, our_proxy.url);
109 url.searchParams.set(REV, rev);
110 limit = Date.now() + timeout;
111 url.searchParams.set(UNTIL, limit);
112 url.searchParams.set(TOKEN, signature(direction, path, rev, limit.toString()));
113 return url.toString();
114 };
115 };
116 download_uri = uri_maker(DOWNLOAD);
117 upload_uri = uri_maker(UPLOAD);
118 return {handler, download_uri, upload_uri};
119 };
120
121 module.exports = attachments_proxy;
122
123 ({URL} = require('url'));
124
125 crypto = require('crypto');
126
127 request = require('request');
128
129 agent = request.defaults({
130 pool: false
131 });
132
133 Cors = require('cors');
134
135 ({strictEqual} = assert = require('assert'));
136
137}).call(this);