Skip to content

Commit e9b3df1

Browse files
committed
Extract Client class to separate module
PR-URL: #120
1 parent 94db5a0 commit e9b3df1

File tree

2 files changed

+95
-89
lines changed

2 files changed

+95
-89
lines changed

lib/client.js

Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
'use strict';
2+
3+
const { http, path } = require('./dependencies.js');
4+
5+
const MIME_TYPES = {
6+
html: 'text/html; charset=UTF-8',
7+
json: 'application/json; charset=UTF-8',
8+
js: 'application/javascript; charset=UTF-8',
9+
css: 'text/css',
10+
png: 'image/png',
11+
ico: 'image/x-icon',
12+
svg: 'image/svg+xml',
13+
};
14+
15+
class Client {
16+
constructor(req, res, application, connection) {
17+
this.req = req;
18+
this.res = res;
19+
this.application = application;
20+
this.connection = connection;
21+
}
22+
23+
static() {
24+
const { req: { url }, res, application } = this;
25+
const filePath = url === '/' ? '/index.html' : url;
26+
const fileExt = path.extname(filePath).substring(1);
27+
const mimeType = MIME_TYPES[fileExt] || MIME_TYPES.html;
28+
res.writeHead(200, { 'Content-Type': mimeType });
29+
const data = application.cache.get(filePath);
30+
if (data) res.end(data);
31+
else this.error(404);
32+
}
33+
34+
redirect(location) {
35+
const { res } = this;
36+
if (res.headersSent) return;
37+
res.writeHead(302, { 'Location': location });
38+
res.end();
39+
}
40+
41+
error(status, err) {
42+
const { application, req: { url }, res, connection } = this;
43+
const reason = http.STATUS_CODES[status];
44+
const error = err ? err.stack : reason;
45+
const msg = status === 403 ? err.message : `${url} - ${error} - ${status}`;
46+
application.logger.error(msg);
47+
const result = JSON.stringify({ result: 'error', reason });
48+
if (connection) {
49+
connection.send(result);
50+
return;
51+
}
52+
if (res.finished) return;
53+
res.writeHead(status, { 'Content-Type': MIME_TYPES.json });
54+
res.end(result);
55+
}
56+
57+
async rpc(method, args) {
58+
const { application, res, connection } = this;
59+
const { semaphore } = application.server;
60+
try {
61+
await semaphore.enter();
62+
} catch {
63+
this.error(504);
64+
return;
65+
}
66+
try {
67+
const session = await application.auth.restore(this);
68+
const proc = application.runScript(method, session);
69+
if (!proc) {
70+
this.error(404);
71+
return;
72+
}
73+
if (!session && proc.access !== 'public') {
74+
this.error(403, new Error(`Forbidden: /api/${method}`));
75+
return;
76+
}
77+
const result = await proc.method(args);
78+
if (!session && proc.access === 'public') {
79+
const session = application.auth.start(this, result.userId);
80+
result.token = session.token;
81+
}
82+
const data = JSON.stringify(result);
83+
if (connection) connection.send(data);
84+
else res.end(data);
85+
} catch (err) {
86+
this.error(500, err);
87+
} finally {
88+
semaphore.leave();
89+
}
90+
}
91+
}
92+
93+
module.exports = Client;

lib/server.js

Lines changed: 2 additions & 89 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,10 @@
11
'use strict';
22

3-
const { http, https, path, worker, common } = require('./dependencies.js');
3+
const { http, https, worker, common } = require('./dependencies.js');
44

55
const WebSocket = require('ws');
66
const Semaphore = require('./semaphore.js');
7-
8-
const MIME_TYPES = {
9-
html: 'text/html; charset=UTF-8',
10-
json: 'application/json; charset=UTF-8',
11-
js: 'application/javascript; charset=UTF-8',
12-
css: 'text/css',
13-
png: 'image/png',
14-
ico: 'image/x-icon',
15-
svg: 'image/svg+xml',
16-
};
7+
const Client = require('./client.js');
178

189
const SHUTDOWN_TIMEOUT = 5000;
1910
const LONG_RESPONSE = 30000;
@@ -40,84 +31,6 @@ const closeClients = () => {
4031
}
4132
};
4233

43-
class Client {
44-
constructor(req, res, application, connection) {
45-
this.req = req;
46-
this.res = res;
47-
this.application = application;
48-
this.connection = connection;
49-
}
50-
51-
static() {
52-
const { req: { url }, res, application } = this;
53-
const filePath = url === '/' ? '/index.html' : url;
54-
const fileExt = path.extname(filePath).substring(1);
55-
const mimeType = MIME_TYPES[fileExt] || MIME_TYPES.html;
56-
res.writeHead(200, { 'Content-Type': mimeType });
57-
const data = application.cache.get(filePath);
58-
if (data) res.end(data);
59-
else this.error(404);
60-
}
61-
62-
redirect(location) {
63-
const { res } = this;
64-
if (res.headersSent) return;
65-
res.writeHead(302, { 'Location': location });
66-
res.end();
67-
}
68-
69-
error(status, err) {
70-
const { application, req: { url }, res, connection } = this;
71-
const reason = http.STATUS_CODES[status];
72-
const error = err ? err.stack : reason;
73-
const msg = status === 403 ? err.message : `${url} - ${error} - ${status}`;
74-
application.logger.error(msg);
75-
const result = JSON.stringify({ result: 'error', reason });
76-
if (connection) {
77-
connection.send(result);
78-
return;
79-
}
80-
if (res.finished) return;
81-
res.writeHead(status, { 'Content-Type': MIME_TYPES.json });
82-
res.end(result);
83-
}
84-
85-
async rpc(method, args) {
86-
const { application, res, connection } = this;
87-
const { semaphore } = application.server;
88-
try {
89-
await semaphore.enter();
90-
} catch {
91-
this.error(504);
92-
return;
93-
}
94-
try {
95-
const session = await application.auth.restore(this);
96-
const proc = application.runScript(method, session);
97-
if (!proc) {
98-
this.error(404);
99-
return;
100-
}
101-
if (!session && proc.access !== 'public') {
102-
this.error(403, new Error(`Forbidden: /api/${method}`));
103-
return;
104-
}
105-
const result = await proc.method(args);
106-
if (!session && proc.access === 'public') {
107-
const session = application.auth.start(this, result.userId);
108-
result.token = session.token;
109-
}
110-
const data = JSON.stringify(result);
111-
if (connection) connection.send(data);
112-
else res.end(data);
113-
} catch (err) {
114-
this.error(500, err);
115-
} finally {
116-
semaphore.leave();
117-
}
118-
}
119-
}
120-
12134
const listener = application => (req, res) => {
12235
let finished = false;
12336
const { method, url, connection } = req;

0 commit comments

Comments
 (0)