node-http-server – Blame information for rev 38

Subversion Repositories:
Rev:
Rev Author Line No. Line
35 office 1 #!/usr/bin/env node
2  
3 /*************************************************************************/
4 /* Copyright (C) 2017 Wizardry and Steamworks - License: GNU GPLv3 */
5 /*************************************************************************/
6  
38 office 7 const fs = require('fs')
8 const stream = require('stream')
9 const util = require('util')
10 const tz = require('moment-timezone')
11 const forge = require('node-forge')
12 const EventEmitter = require('events').EventEmitter
35 office 13  
14 // Cache constructor.
15 function Cache(config, client, request, response) {
16 // Create events emitters for logging and data.
38 office 17 EventEmitter.call(this)
35 office 18  
19 // Pass through objects needed for caching.
38 office 20 this.config = config
21 this.client = client
22 this.request = request
23 this.response = response
24 }
35 office 25  
26 // Cache handling.
27 Cache.prototype.process = function(resource, input, type) {
38 office 28 EventEmitter.call(this)
29 const self = this
35 office 30  
37 office 31 // Read the resource and cache or not depending on configuration settings.
35 office 32 fs.stat(resource, (error, stats) => {
38 office 33 var expires = 0
35 office 34 Object.keys(self.config.site.cache).forEach((key) => {
35 self.config.site.cache[key].forEach((expire) => {
36 if (expire.test(resource)) {
38 office 37 expires = key
35 office 38 }
38 office 39 })
40 })
35 office 41  
42 switch (self.request.httpVersion) {
43 case '1.1': // HTTP 1.1
44 self.response.setHeader('Cache-Control',
45 "max-age=" + expires + ", public"
38 office 46 )
47 const sha1 = forge.md.sha1.create()
35 office 48 const data = new stream.Readable({
49 objectMode: true,
50 read(size) {}
38 office 51 })
35 office 52 input
53 .on('data', (chunk) => {
38 office 54 sha1.update(chunk)
55 data.push(chunk)
35 office 56 })
57 .on('end', () => {
38 office 58 const etag = sha1.digest().toHex()
35 office 59  
60 // Set the ETag for the resource.
38 office 61 self.response.setHeader('ETag', etag)
35 office 62  
63 const ifNoneMatch = Object
64 .getOwnPropertyNames(self.request.headers)
65 .filter((header) => header.toUpperCase() ===
38 office 66 'If-None-Match'.toUpperCase())
35 office 67  
68 const ifModifiedSince = Object
69 .getOwnPropertyNames(self.request.headers)
70 .filter((header) => header.toUpperCase() ===
38 office 71 'If-Modified-Since'.toUpperCase())
35 office 72  
73 if ((ifNoneMatch.length !== 0 &&
74 self.request.headers[ifNoneMatch].toUpperCase() === etag.toUpperCase()) ||
75 (ifModifiedSince.length !== 0 &&
76 tz(self.request.headers[ifModifiedSince]).tz('UTC') < tz(stat.mtime).tz('UTC'))) {
77 < tz(stat.mtime).tz('UTC'))) { // Send a cache hit response.
78 < tz(stat.mtime).tz('UTC'))) { self.emit('log', {
79 < tz(stat.mtime).tz('UTC'))) { message: 'Client: ' +
80 < tz(stat.mtime).tz('UTC'))) { self.client.address + ':' +
81 < tz(stat.mtime).tz('UTC'))) { self.client.port +
82 < tz(stat.mtime).tz('UTC'))) { ' cached resource: ' +
83 < tz(stat.mtime).tz('UTC'))) { resource,
84 < tz(stat.mtime).tz('UTC'))) { severity: 'info'
38 office 85 < tz(stat.mtime).tz('UTC'))) { })
35 office 86 < tz(stat.mtime).tz('UTC'))) { self.emit('data', {
87 < tz(stat.mtime).tz('UTC'))) { status: 304,
88 < tz(stat.mtime).tz('UTC'))) { data: new stream.Readable({
89 < tz(stat.mtime).tz('UTC'))) { read(size) {
38 office 90 < tz(stat.mtime).tz('UTC'))) { this.push(null)
35 office 91 < tz(stat.mtime).tz('UTC'))) { }
92 < tz(stat.mtime).tz('UTC'))) { }),
93 < tz(stat.mtime).tz('UTC'))) { type: type
38 office 94 < tz(stat.mtime).tz('UTC'))) { })
95 < tz(stat.mtime).tz('UTC'))) { return
35 office 96 < tz(stat.mtime).tz('UTC'))) { }
97  
98 < tz(stat.mtime).tz('UTC'))) { // Send the resource.
99 < tz(stat.mtime).tz('UTC'))) { self.emit('log', {
100 < tz(stat.mtime).tz('UTC'))) { message: 'Client: ' +
101 < tz(stat.mtime).tz('UTC'))) { self.client.address + ':' +
102 < tz(stat.mtime).tz('UTC'))) { self.client.port +
103 < tz(stat.mtime).tz('UTC'))) { ' sent resource: ' +
104 < tz(stat.mtime).tz('UTC'))) { resource,
105 < tz(stat.mtime).tz('UTC'))) { severity: 'info'
38 office 106 < tz(stat.mtime).tz('UTC'))) { })
107 < tz(stat.mtime).tz('UTC'))) { data.push(null)
35 office 108 < tz(stat.mtime).tz('UTC'))) { self.emit('data', {
109 < tz(stat.mtime).tz('UTC'))) { status: 200,
110 < tz(stat.mtime).tz('UTC'))) { data: data,
111 < tz(stat.mtime).tz('UTC'))) { type: type
38 office 112 < tz(stat.mtime).tz('UTC'))) { })
113 < tz(stat.mtime).tz('UTC'))) { })
35 office 114  
38 office 115 < tz(stat.mtime).tz('UTC'))) { return
35 office 116 < tz(stat.mtime).tz('UTC'))) { default:
117 < tz(stat.mtime).tz('UTC'))) { self.response.setHeader('Last-Modified',
118 < tz(stat.mtime).tz('UTC'))) { tz(stats.mtime)
119 < tz(stat.mtime).tz('UTC'))) { .tz('UTC')
120 < tz(stat.mtime).tz('UTC'))) { .format("ddd, DD MMM YYYY HH:mm:ss z")
38 office 121 < tz(stat.mtime).tz('UTC'))) { )
35 office 122 < tz(stat.mtime).tz('UTC'))) { self.response.setHeader('Expires',
123 < tz(stat.mtime).tz('UTC'))) { tz()
124 < tz(stat.mtime).tz('UTC'))) { .tz('UTC')
125 < tz(stat.mtime).tz('UTC'))) { .add(expires, 'seconds')
126 < tz(stat.mtime).tz('UTC'))) { .format("ddd, DD MMM YYYY HH:mm:ss z")
38 office 127 < tz(stat.mtime).tz('UTC'))) { )
35 office 128 < tz(stat.mtime).tz('UTC'))) { // Send the resource.
129 < tz(stat.mtime).tz('UTC'))) { self.emit('log', {
130 < tz(stat.mtime).tz('UTC'))) { message: 'Client: ' +
131 < tz(stat.mtime).tz('UTC'))) { self.client.address + ':' +
132 < tz(stat.mtime).tz('UTC'))) { self.client.port +
133 < tz(stat.mtime).tz('UTC'))) { ' sent resource: ' +
134 < tz(stat.mtime).tz('UTC'))) { resource,
135 < tz(stat.mtime).tz('UTC'))) { severity: 'info'
38 office 136 < tz(stat.mtime).tz('UTC'))) { })
35 office 137 < tz(stat.mtime).tz('UTC'))) { self.emit('data', {
138 < tz(stat.mtime).tz('UTC'))) { status: 200,
139 < tz(stat.mtime).tz('UTC'))) { data: input,
140 < tz(stat.mtime).tz('UTC'))) { type: type
38 office 141 < tz(stat.mtime).tz('UTC'))) { })
142 < tz(stat.mtime).tz('UTC'))) { break
35 office 143 < tz(stat.mtime).tz('UTC'))) { }
38 office 144 < tz(stat.mtime).tz('UTC'))) { })
35 office 145  
38 office 146 < tz(stat.mtime).tz('UTC'))) { return this
147 < tz(stat.mtime).tz('UTC'))) {}
35 office 148  
38 office 149 < tz(stat.mtime).tz('UTC'))) {util.inherits(Cache, EventEmitter)
150 < tz(stat.mtime).tz('UTC'))) {module.exports = Cache