node-http-server – Diff between revs 14 and 15

Subversion Repositories:
Rev:
Show entire fileRegard whitespace
Rev 14 Rev 15
Line 9... Line 9...
9 const fs = require('fs'); 9 const fs = require('fs');
10 const mime = require('mime'); 10 const mime = require('mime');
11 const auth = require("http-auth"); 11 const auth = require("http-auth");
Line 12... Line 12...
12   12  
13 // Checks whether userPath is a child of rootPath. 13 // Checks whether userPath is a child of rootPath.
-   14 function isRooted(userPath, rootPath, separator, callback) {
14 function isRooted(userPath, rootPath, separator) { 15 process.nextTick(() => {
15 userPath = userPath.split(separator).filter(Boolean); 16 userPath = userPath.split(separator).filter(Boolean);
16 rootPath = rootPath.split(separator).filter(Boolean); 17 rootPath = rootPath.split(separator).filter(Boolean);
17 return userPath.length >= rootPath.length && 18 callback(userPath.length >= rootPath.length &&
-   19 rootPath.every((e, i) => e === userPath[i]));
18 rootPath.every((e, i) => e === userPath[i]); 20 });
Line 19... Line 21...
19 } 21 }
20   22  
21 // Serves files. 23 // Serves files.
22 function files(config, request, response, resource, callback) { -  
23 // Check if the file is accessible. 24 function files(config, request, response, resource, callback) {
24 process.nextTick(() => { 25 // Check if the file is accessible.
25 fs.access(resource, fs.constants.R_OK, (error) => { 26 fs.access(resource, fs.constants.R_OK, (error) => {
26 if (error) { 27 if (error) {
27 response.statusCode = 403; 28 response.statusCode = 403;
Line 43... Line 44...
43 response.statusCode = 500; 44 response.statusCode = 500;
44 response.end(); 45 response.end();
45 }); 46 });
Line 46... Line 47...
46   47  
47 }); -  
48 }); 48 });
Line 49... Line 49...
49 } 49 }
50   50  
51 // Serves a directory index. -  
52 function index(config, request, response, resource, callback) { -  
53 process.nextTick(() => { 51 // Serves a directory listing or the document index in case it exists.
54 const root = path.resolve(resource, config.site.index); 52 function index(config, request, response, resource, root, callback) {
55 fs.stat(root, (error, stats) => { 53 fs.stat(root, (error, stats) => {
56 if (error) { 54 if (error) {
57 fs.readdir(resource, (error, paths) => { 55 fs.readdir(resource, (error, paths) => {
Line 78... Line 76...
78 }); 76 });
Line 79... Line 77...
79   77  
80 return; 78 return;
Line -... Line 79...
-   79 }
81 } 80  
82   81 // Serve the document index.
83 fs.access(resource, fs.constants.R_OK, (error) => { 82 fs.access(resource, fs.constants.R_OK, (error) => {
84 if (error) { 83 if (error) {
85 process.nextTick(() => { 84 process.nextTick(() => {
Line 108... Line 107...
108 response.statusCode = 500; 107 response.statusCode = 500;
109 response.end(); 108 response.end();
110 }); 109 });
Line 111... Line 110...
111   110  
112 }); -  
113   -  
114 }); 111 });
115 }); 112 });
Line 116... Line 113...
116 } 113 }
117   114  
118 // Determines whether the requested resource is a directory or a file. -  
119 function serve(config, request, response, resource, callback) { 115 // Determines whether the requested resource is a directory or a file.
120 process.nextTick(() => { 116 function serve(config, request, response, resource, callback) {
121 fs.stat(resource, (error, stats) => { 117 fs.stat(resource, (error, stats) => {
122 // Document does not exist. 118 // Document does not exist.
123 if (error) { 119 if (error) {
124 response.statusCode = 404; 120 response.statusCode = 404;
125 response.end(); 121 response.end();
Line 126... Line 122...
126 return; 122 return;
127 } 123 }
128   124  
129 switch (stats.isDirectory()) { 125 switch (stats.isDirectory()) {
130 case true: // Directory is requested so provide directory indexes. 126 case true: // Directory is requested so provide directory indexes.
131 index(config, request, response, resource, callback) 127 index(config, request, response, resource, path.resolve(resource, config.site.index), callback)
132 break; 128 break;
133 default: // Browser requesting file. 129 default: // Browser requesting file.
134 files(config, request, response, resource, callback); 130 files(config, request, response, resource, callback);
135 break; -  
136 } 131 break;
Line 137... Line 132...
137 }); 132 }
138 }); 133 });
139 } 134 }
Line 169... Line 164...
169 .join('/'); 164 .join('/');
170 const resource = trimmedPath === '/' ? 165 const resource = trimmedPath === '/' ?
171 path.join(root, trimmedPath) : 166 path.join(root, trimmedPath) :
172 path.resolve(root, trimmedPath); 167 path.resolve(root, trimmedPath);
Line 173... Line 168...
173   168  
-   169 isRooted(resource, root, path.sep, (rooted) => {
174 if (!isRooted(resource, root, path.sep)) { 170 if (!rooted) {
175 process.nextTick(() => { 171 process.nextTick(() => {
176 callback('Attempted path traversal: ' + 172 callback('Attempted path traversal: ' +
177 requestAddress.address + ':' + 173 requestAddress.address + ':' +
178 requestAddress.port + 174 requestAddress.port +
Line 184... Line 180...
184 response.statusCode = 404; 180 response.statusCode = 404;
185 response.end(); 181 response.end();
186 return; 182 return;
187 } 183 }
Line -... Line 184...
-   184  
188   185 // Check if the requested path requires authentication.
189 switch (config.auth.locations.some( 186 switch (config.auth.locations.some(
190 (authPath) => authPath.toUpperCase() === requestedURL.pathname.toUpperCase())) { 187 (authPath) => authPath.toUpperCase() === requestedURL.pathname.toUpperCase())) {
191 case true: 188 case true:
192 // Requested location requires authentication. 189 // Requested location requires authentication.
Line 215... Line 212...
215 }); 212 });
216 serve(config, request, response, resource, callback); 213 serve(config, request, response, resource, callback);
217 break; 214 break;
218 } 215 }
219 }); 216 });
-   217 });
220 } 218 }
221 }; 219 };