1 |
|
2 | "use strict";
|
3 |
|
4 | const debugHash = require('debug')('upnpserver:contentProvider:hash');
|
5 | const crypto = require('crypto');
|
6 | const Path = require('path');
|
7 |
|
8 | const URL = require('../util/url');
|
9 |
|
10 | const HASH_SIZE = 1024 * 1024;
|
11 |
|
12 | const CHANGE_PATH_SEPARATOR = (Path.sep !== '/');
|
13 |
|
14 | class ContentProvider {
|
15 | |
16 |
|
17 |
|
18 | constructor(configuration) {
|
19 | this._configuration = configuration || {};
|
20 | }
|
21 |
|
22 | |
23 |
|
24 |
|
25 | initialize(service, callback) {
|
26 | this._service=service;
|
27 | callback(null);
|
28 | }
|
29 |
|
30 | |
31 |
|
32 |
|
33 | normalizeParameter(value) {
|
34 | var replaced = value.replace(/\$\{([^\}]+)\}/g, function(_,name) {
|
35 | return process.env[name] || "";
|
36 | });
|
37 |
|
38 | return replaced;
|
39 | }
|
40 |
|
41 | |
42 |
|
43 |
|
44 | get service() {
|
45 | return this._service;
|
46 | }
|
47 |
|
48 |
|
49 | |
50 |
|
51 |
|
52 | get isLocalFilesystem() {
|
53 | return false;
|
54 | }
|
55 |
|
56 | |
57 |
|
58 |
|
59 |
|
60 | readdir(url, callback) {
|
61 | callback(new Error("not supported (url=" + url + ")"));
|
62 | }
|
63 |
|
64 | |
65 |
|
66 |
|
67 |
|
68 | stat(url, callback) {
|
69 | callback(new Error("not supported (url=" + url + ")"));
|
70 | }
|
71 |
|
72 | |
73 |
|
74 |
|
75 | createReadStream(session, url, options, callback) {
|
76 | callback(new Error("not supported (url=" + url + ")"));
|
77 | }
|
78 |
|
79 | |
80 |
|
81 |
|
82 | createWriteStream(url, options, callback) {
|
83 | callback(new Error("not supported (url=" + url + ")"));
|
84 | }
|
85 |
|
86 | |
87 |
|
88 |
|
89 | end(session, callback) {
|
90 | callback();
|
91 | }
|
92 |
|
93 | |
94 |
|
95 |
|
96 |
|
97 |
|
98 | join(path, newPath) {
|
99 | var p = Path.posix.join.apply(Path, arguments);
|
100 |
|
101 | return p;
|
102 | }
|
103 |
|
104 | |
105 |
|
106 |
|
107 | readContent(uri, encoding, callback) {
|
108 | if (arguments.length==2) {
|
109 | callback=encoding;
|
110 | encoding=undefined;
|
111 | }
|
112 |
|
113 | var ps={
|
114 | flags : 'r',
|
115 | autoClose : true
|
116 | };
|
117 |
|
118 | var done=false;
|
119 | var list=[];
|
120 | this.createReadStream(null, uri, ps, (error, stream) => {
|
121 | if (error) {
|
122 | return callback(error);
|
123 | }
|
124 |
|
125 | stream.on('data', (buffer) => list.push(buffer));
|
126 |
|
127 | stream.on('end', () => {
|
128 | if (done) {
|
129 | return;
|
130 | }
|
131 | done=true;
|
132 | var body=Buffer.concat(list);
|
133 | if (encoding) {
|
134 | return callback(null, body.toString(encoding));
|
135 | }
|
136 | callback(null, body);
|
137 | });
|
138 |
|
139 | stream.on('error', (error) => {
|
140 | if (done) {
|
141 | return;
|
142 | }
|
143 | done=true;
|
144 |
|
145 | callback(error);
|
146 | });
|
147 | });
|
148 | }
|
149 |
|
150 | writeContent(uri, content, encoding, callback) {
|
151 | if (arguments.length==3) {
|
152 | callback=encoding;
|
153 | encoding=undefined;
|
154 | }
|
155 |
|
156 | var ps={
|
157 | flags : 'w',
|
158 | autoClose : true
|
159 | };
|
160 |
|
161 | this.createWriteStream(uri, ps, (error, stream) => {
|
162 | if (error) {
|
163 | return callback(error);
|
164 | }
|
165 |
|
166 | stream.end(content, encoding, (error) => {
|
167 | callback(error);
|
168 | });
|
169 | });
|
170 | }
|
171 |
|
172 | |
173 |
|
174 |
|
175 | computeHash(uri, stats, callback) {
|
176 |
|
177 | this.createReadStream(null, uri, {
|
178 | flags : 'r',
|
179 | encoding : null,
|
180 | autoClose : true,
|
181 | start : 0,
|
182 | end : Math.min(stats.size, HASH_SIZE)
|
183 |
|
184 | }, (error, stream) => {
|
185 | var hash = crypto.createHash('sha256');
|
186 |
|
187 | hash.update(JSON.stringify({
|
188 | size : stats.size
|
189 | }));
|
190 |
|
191 | stream.on('data', (buffer) => hash.update(buffer));
|
192 |
|
193 | stream.on('end', () => {
|
194 | var digest = hash.digest("base64").replace(/=/g, '').replace(/\//g, '_');
|
195 |
|
196 | console.log("Hash of", uri, "=", digest);
|
197 |
|
198 | callback(null, digest);
|
199 | });
|
200 | });
|
201 | }
|
202 |
|
203 | |
204 |
|
205 |
|
206 | newURL(url) {
|
207 | return new URL(this, url);
|
208 | }
|
209 |
|
210 | |
211 |
|
212 |
|
213 | toString() {
|
214 | return "[ContentProvider name='"+this.name+"']";
|
215 | }
|
216 | }
|
217 |
|
218 |
|
219 | module.exports = ContentProvider;
|