node-http-server – Blame information for rev 35

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