@srfnstack/spliffy 0.5.5 → 0.8.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,115 +0,0 @@
1
- const fs = require( 'fs' )
2
- const etag = require( 'etag' )
3
- const serverConfig = require( './serverConfig' )
4
- const log = require( "./log" );
5
-
6
- function toArrayBuffer( buffer ) {
7
- return buffer.buffer.slice( buffer.byteOffset, buffer.byteOffset + buffer.byteLength );
8
- }
9
-
10
- const readFile = async ( fullPath ) => await new Promise(
11
- ( resolve, reject ) =>
12
- fs.readFile( fullPath, ( err, data ) => {
13
- if( err ) reject( err )
14
- else resolve( data )
15
- }
16
- )
17
- )
18
-
19
- const writeHeaders = ( req, res, tag, stat, contentType ) => {
20
- if( req.headers['if-none-match'] === tag ) {
21
- res.writeHead( 304, 'Not Modified' )
22
- return
23
- }
24
- res.writeHead( 200, {
25
- 'Content-Type': contentType,
26
- 'Content-Length': stat.size,
27
- 'Cache-Control': serverConfig.current.staticCacheControl || 'max-age=600',
28
- 'ETag': tag
29
- } )
30
- }
31
-
32
- const readStat = async path => new Promise( ( resolve, reject ) =>
33
- fs.stat( path, ( err, stats ) =>
34
- err ? reject( err ) : resolve( stats )
35
- ) )
36
-
37
- function onAbortedOrFinishedResponse( res, readStream ) {
38
- if( res.id === -1 ) {
39
- log.error( "ERROR! onAbortedOrFinishedResponse called twice for the same res!" )
40
- } else {
41
- readStream.destroy();
42
- }
43
- res.id = -1;
44
- }
45
-
46
- //borrowed from https://github.com/uNetworking/uWebSockets.js/blob/8ba1edc0bbd05f97f6b1c8a03fd93be89bec458d/examples/VideoStreamer.js#L38
47
- async function streamFile( res, fullPath, stat ) {
48
- const totalSize = stat.size;
49
- return new Promise( ( resolve, reject ) => {
50
- const readStream = fs.createReadStream( fullPath )
51
- readStream.on( 'data', chunk => {
52
- const ab = toArrayBuffer( chunk );
53
- let lastOffset = res.getWriteOffset();
54
- let [ok, done] = res.tryEnd( ab, totalSize );
55
- if( done ) {
56
- onAbortedOrFinishedResponse( res, readStream );
57
- res.writableEnded = true
58
- resolve();
59
- } else if( !ok ) {
60
- readStream.pause();
61
- res.ab = ab;
62
- res.abOffset = lastOffset;
63
- res.onWritable( ( offset ) => {
64
- let [ok, done] = res.tryEnd( res.ab.slice( offset - res.abOffset ), totalSize );
65
- if( done ) {
66
- onAbortedOrFinishedResponse( res, readStream );
67
- res.writableEnded = true
68
- resolve()
69
- } else if( ok ) {
70
- readStream.resume();
71
- }
72
- return ok;
73
- } );
74
- }
75
- } )
76
- .on( 'error', () =>
77
- reject( 'Unhandled read error from Node.js, you need to handle this!' )
78
- )
79
- } )
80
- }
81
-
82
- module.exports = {
83
- create: async ( fullPath, contentType ) => {
84
- const cache = {}
85
-
86
- return {
87
- GET: async ( { req, res } ) => {
88
- if( !fs.existsSync( fullPath ) ) {
89
- return {
90
- statusCode: 404,
91
- statusMessage: 'Not Found'
92
- }
93
- } else {
94
- if( serverConfig.current.cacheStatic ) {
95
- if( !cache.stat ) {
96
- cache.stat = await readStat( fullPath )
97
- cache.content = await readFile( fullPath )
98
- cache.etag = etag( cache.content )
99
- }
100
- writeHeaders( req, res, cache.etag, cache.stat, contentType )
101
- return cache.content
102
- } else {
103
- let stat = await readStat( fullPath )
104
- writeHeaders( req, res, etag( stat ), stat, contentType )
105
- res.flushHeaders()
106
- if(stat.size === 0) {
107
- return ""
108
- }
109
- await streamFile( res, fullPath, stat )
110
- }
111
- }
112
- }
113
- }
114
- }
115
- }