file.js
1.91 KB
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
/**
* Module dependencies.
*/
var fs = require('fs');
var uri2path = require('file-uri-to-path');
var NotFoundError = require('./notfound');
var NotModifiedError = require('./notmodified');
var debug = require('debug')('get-uri:file');
/**
* Module exports.
*/
module.exports = get;
/**
* Returns a `fs.ReadStream` instance from a "file:" URI.
*
* @api protected
*/
function get (parsed, opts, fn) {
var fd;
var cache = opts.cache;
// same as in fs.ReadStream's constructor
var flags = opts.hasOwnProperty('flags') ? options.flags : 'r';
var mode = opts.hasOwnProperty('mode') ? options.mode : 438; /*=0666*/
// convert URI → Path
var uri = parsed.href;
var filepath = uri2path(uri);
debug('normalized pathname: %o', filepath);
// open() first to get a fd and ensure that the file exists
fs.open(filepath, flags, mode, onopen);
function onerror (err) {
if ('number' == typeof fd) {
fs.close(fd, onclose);
}
fn(err);
}
function onclose () {
debug('closed fd %o', fd);
}
function onopen (err, _fd) {
if (err) {
if ('ENOENT' == err.code) {
err = new NotFoundError();
}
return onerror(err);
}
fd = _fd;
// now fstat() to check the `mtime` and store the stat object for the cache
fs.fstat(fd, onstat);
}
function onstat (err, stat) {
if (err) return onerror(err);
// if a `cache` was provided, check if the file has not been modified
if (cache && cache.stat && stat && isNotModified(cache.stat, stat)) {
return onerror(new NotModifiedError());
}
// `fs.ReadStream` takes care of calling `fs.close()` on the
// fd after it's done reading
opts.fd = fd;
var rs = fs.createReadStream(null, opts);
rs.stat = stat;
fn(null, rs);
}
// returns `true` if the `mtime` of the 2 stat objects are equal
function isNotModified (prev, curr) {
return +prev.mtime == +curr.mtime;
}
}