-
Notifications
You must be signed in to change notification settings - Fork 0
/
index.js
136 lines (109 loc) · 3.09 KB
/
index.js
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
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
/*
* Primary file for the API
*
*/
// Core dependencies
const http = require('http')
const https = require('https')
const url = require('url')
const StringDecoder = require('string_decoder').StringDecoder
const fs = require('fs')
// Dependencies
const config = require('./config')
const {
ping,
users,
tokens,
checks
} = require('./handlers')
// Define a request router
const router = {
ping,
users,
tokens,
checks
}
const sender = (res, statusCode = 200, payload = {}) => {
// Convert the payload to a json string
const payloadString = JSON.stringify(payload)
// If there was no payload provided
if (payloadString !== '{}') {
res.setHeader('Content-Type', 'application/json')
res.writeHead(statusCode)
res.end(payloadString)
} else {
// If no payload is given, send back the standard string for the given http code
res.setHeader('Content-Type', 'text/plain')
res.writeHead(statusCode)
res.end(http.STATUS_CODES[statusCode])
}
}
// All the server logic for both http and https server
const unifiedServer = (req, res) => {
// Get the URL and parse it
const parsedUrl = url.parse(req.url, true)
// Get the path
const path = parsedUrl.pathname
const trimmedPath = path.replace(/^\/+|\/+$/g, '')
// Get the query string as an object
const queryStringObject = parsedUrl.query
// Get the HTTP Method
const method = req.method.toLowerCase()
// Get the headers as an object
const headers = req.headers
// Get the payload, if any
const decoder = new StringDecoder('utf-8')
let buffer = ''
req.on('data', (data) => {
buffer += decoder.write(data);
})
req.on('end', () => {
buffer += decoder.end()
let payload
const boundSender = sender.bind(null, res)
try {
if (typeof buffer === 'string' && buffer.length) {
payload = JSON.parse(buffer)
} else {
payload = null
}
} catch (error) {
return boundSender(400)
}
// construct the data object to send to the handler
const data = {
path: trimmedPath,
query: queryStringObject,
payload,
method,
headers
}
// if path is not defined send 404
if (!router[trimmedPath]) {
return boundSender(404)
}
// if method is not supported on path send 405
if (!router[trimmedPath][method]) {
return boundSender(405)
}
const handler = router[trimmedPath][method]
// Route the request to the found handler
handler(data, boundSender)
})
}
// Instantiate the HTTP server
const httpServer = http.createServer(unifiedServer)
// Instantiate the HTTPS server
const httpsServerOptions = {
key: fs.readFileSync('./https/key.pem'),
cert: fs.readFileSync('./https/cert.pem')
}
const httpsServer = https.createServer(httpsServerOptions, unifiedServer)
// Start the HTTP server
httpServer.listen(config.httpPort, () => {
console.log(`The server is listening for http traffic on port ${config.httpPort}`)
})
// Start the HTTPS server
httpsServer.listen(config.httpsPort, () => {
console.log(`The server is listening for https traffic on port ${config.httpsPort}`)
})