sprucehttp_sjs 1.0.12 → 2.1.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.
- package/README.md +49 -34
- package/index.js +54 -37
- package/package.json +6 -6
package/README.md
CHANGED
|
@@ -10,19 +10,19 @@ A module for responding to requests within SpruceHTTP in an SJS file.
|
|
|
10
10
|
- [writeData(data)](#writedatadata)
|
|
11
11
|
- [writeDataAsync(data)](#writedataasyncdata)
|
|
12
12
|
- [clearResponse()](#clearresponse)
|
|
13
|
-
- [siteConfig
|
|
14
|
-
- [requestIP
|
|
15
|
-
- [method
|
|
16
|
-
- [path
|
|
17
|
-
- [pathInfo
|
|
18
|
-
- [query
|
|
13
|
+
- [siteConfig](#siteconfig)
|
|
14
|
+
- [requestIP](#requestip)
|
|
15
|
+
- [method](#method)
|
|
16
|
+
- [path](#path)
|
|
17
|
+
- [pathInfo](#pathinfo)
|
|
18
|
+
- [query](#query)
|
|
19
19
|
- [queryValue(key)](#queryvaluekey)
|
|
20
|
-
- [httpVersion
|
|
21
|
-
- [headers
|
|
20
|
+
- [httpVersion](#httpversion)
|
|
21
|
+
- [headers](#headers)
|
|
22
22
|
- [headerValue(name)](#headervaluename)
|
|
23
|
-
- [body
|
|
24
|
-
- [bodyStream()](#
|
|
25
|
-
- [
|
|
23
|
+
- [body](#body)
|
|
24
|
+
- [bodyStream([options])](#bodystreamoptions)
|
|
25
|
+
- [mTlsPeerCertificate](#mtlspeercertificate)
|
|
26
26
|
|
|
27
27
|
## Documentation:
|
|
28
28
|
Importing the module:
|
|
@@ -35,16 +35,20 @@ Sets the response into stream mode. This cannot be undone for the duration of th
|
|
|
35
35
|
|
|
36
36
|
Stream mode means that responses are not buffered by the webserver, and thus are sent immediately as they're received from the SJS script. This means that the status line and headers _**must**_ be sent first before the data, and the ``\r\n`` after the headers must be sent by the script as well.
|
|
37
37
|
|
|
38
|
+
Returns a Promise that resolves when the server acknowledges the switch to stream mode.
|
|
39
|
+
|
|
38
40
|
```js
|
|
39
41
|
sjs.streamMode(); // Set the response to stream mode.
|
|
40
42
|
```
|
|
41
43
|
|
|
42
44
|
### ``writeStatusLine(statusCode[, reasonPhrase])``:
|
|
43
45
|
- ``statusLine:`` number: The HTTP status code to send.
|
|
44
|
-
- ``reasonPhrase:`` string: The reason phrase to send.
|
|
46
|
+
- ``reasonPhrase:`` string: Optional. The reason phrase to send.
|
|
45
47
|
|
|
46
48
|
Writes the status line to the response.
|
|
47
49
|
|
|
50
|
+
Returns a Promise that resolves when the server acknowledges the status line.
|
|
51
|
+
|
|
48
52
|
To send a 200 "OK" response, without needing to specify the reason phrase.
|
|
49
53
|
```js
|
|
50
54
|
sjs.writeStatusLine(200);
|
|
@@ -61,6 +65,8 @@ sjs.writeStatusLine(418, "I'm a teapot");
|
|
|
61
65
|
|
|
62
66
|
Writes a header to the response.
|
|
63
67
|
|
|
68
|
+
Returns a Promise that resolves when the server acknowledges the header.
|
|
69
|
+
|
|
64
70
|
To write the "Content-Type: text/html" header.
|
|
65
71
|
```js
|
|
66
72
|
sjs.writeHeader("Content-Type", "text/html");
|
|
@@ -71,6 +77,8 @@ sjs.writeHeader("Content-Type", "text/html");
|
|
|
71
77
|
|
|
72
78
|
Writes data (the body) to the response. When not in stream mode, the Content-Length header is automatically updated.
|
|
73
79
|
|
|
80
|
+
This function is deprecated. Use ``writeDataAsync`` instead, as data cannot be reliably sent synchronously.
|
|
81
|
+
|
|
74
82
|
Writes text data to the body.
|
|
75
83
|
```js
|
|
76
84
|
sjs.writeData("Hello, world!");
|
|
@@ -87,6 +95,8 @@ sjs.writeData(fs.readFileSync("image.png", 'binary'));
|
|
|
87
95
|
|
|
88
96
|
Writes data (the body) to the response asynchronously. When not in stream mode, the Content-Length header is automatically updated.
|
|
89
97
|
|
|
98
|
+
Returns a Promise that resolves when the data has been written.
|
|
99
|
+
|
|
90
100
|
Writes text data to the body.
|
|
91
101
|
```js
|
|
92
102
|
await sjs.writeDataAsync("Hello, world!");
|
|
@@ -102,6 +112,8 @@ await sjs.writeDataAsync(fs.readFileSync("image.png", 'binary'));
|
|
|
102
112
|
Clears the currently written response and resets the status line, headers, and body.
|
|
103
113
|
This is useful when you want to send a different response than the one you have already written.
|
|
104
114
|
|
|
115
|
+
Returns a Promise that resolves when the response has been cleared.
|
|
116
|
+
|
|
105
117
|
This function does not work in stream mode.
|
|
106
118
|
|
|
107
119
|
```js
|
|
@@ -116,11 +128,13 @@ sjs.writeHeader("Content-Type", "text/html");
|
|
|
116
128
|
sjs.writeData("<h1>I'm <i>not</i> a teapot</h1>");
|
|
117
129
|
```
|
|
118
130
|
|
|
119
|
-
### ``siteConfig
|
|
131
|
+
### ``siteConfig``:
|
|
120
132
|
Returns the site-specific configuration set in your config file.
|
|
121
133
|
|
|
134
|
+
Returns an object representing the site configuration.
|
|
135
|
+
|
|
122
136
|
```js
|
|
123
|
-
console.log(sjs.siteConfig
|
|
137
|
+
console.log(sjs.siteConfig);
|
|
124
138
|
/*
|
|
125
139
|
{
|
|
126
140
|
"type": "local",
|
|
@@ -141,46 +155,46 @@ console.log(sjs.siteConfig());
|
|
|
141
155
|
*/
|
|
142
156
|
```
|
|
143
157
|
|
|
144
|
-
### ``requestIP
|
|
158
|
+
### ``requestIP``:
|
|
145
159
|
Returns the requestor's IP address.
|
|
146
160
|
|
|
147
161
|
```js
|
|
148
|
-
console.log(sjs.requestIP
|
|
162
|
+
console.log(sjs.requestIP);
|
|
149
163
|
// ::ffff:127.0.0.1
|
|
150
164
|
```
|
|
151
165
|
|
|
152
|
-
### ``method
|
|
166
|
+
### ``method``:
|
|
153
167
|
Returns the request method.
|
|
154
168
|
|
|
155
169
|
```js
|
|
156
|
-
console.log(sjs.method
|
|
170
|
+
console.log(sjs.method);
|
|
157
171
|
// get
|
|
158
172
|
```
|
|
159
173
|
|
|
160
|
-
### ``path
|
|
174
|
+
### ``path``:
|
|
161
175
|
Returns the request path.
|
|
162
176
|
|
|
163
177
|
```js
|
|
164
|
-
console.log(sjs.path
|
|
178
|
+
console.log(sjs.path);
|
|
165
179
|
// /index.sjs
|
|
166
180
|
```
|
|
167
181
|
|
|
168
|
-
### ``pathInfo
|
|
182
|
+
### ``pathInfo``:
|
|
169
183
|
Returns the request's info path.
|
|
170
184
|
|
|
171
185
|
```js
|
|
172
186
|
// Using path /index.sjs/info
|
|
173
|
-
console.log(sjs.path
|
|
174
|
-
console.log(sjs.pathInfo
|
|
187
|
+
console.log(sjs.path);
|
|
188
|
+
console.log(sjs.pathInfo);
|
|
175
189
|
// /index.sjs
|
|
176
190
|
// /info
|
|
177
191
|
```
|
|
178
192
|
|
|
179
|
-
### ``query
|
|
193
|
+
### ``query``:
|
|
180
194
|
Returns the request query.
|
|
181
195
|
|
|
182
196
|
```js
|
|
183
|
-
console.log(sjs.query
|
|
197
|
+
console.log(sjs.query);
|
|
184
198
|
/*
|
|
185
199
|
{
|
|
186
200
|
"name": "John",
|
|
@@ -199,19 +213,19 @@ console.log(sjs.queryValue("name"));
|
|
|
199
213
|
// John
|
|
200
214
|
```
|
|
201
215
|
|
|
202
|
-
### ``httpVersion
|
|
216
|
+
### ``httpVersion``:
|
|
203
217
|
Returns the HTTP version of the request.
|
|
204
218
|
|
|
205
219
|
```js
|
|
206
|
-
console.log(sjs.httpVersion
|
|
220
|
+
console.log(sjs.httpVersion);
|
|
207
221
|
// http/1.1
|
|
208
222
|
```
|
|
209
223
|
|
|
210
|
-
### ``headers
|
|
224
|
+
### ``headers``:
|
|
211
225
|
Returns the request headers.
|
|
212
226
|
|
|
213
227
|
```js
|
|
214
|
-
console.log(sjs.headers
|
|
228
|
+
console.log(sjs.headers);
|
|
215
229
|
/*
|
|
216
230
|
{
|
|
217
231
|
"connection": "keep-alive",
|
|
@@ -232,15 +246,16 @@ console.log(sjs.headerValue("user-agent"));
|
|
|
232
246
|
// Bruh/1.0 (Macintosh; PPC Mac OS X 7_0_1) AppleBruhKit 1.3 (XHTML, like IE) Netscape/69.420 Moment/360 NoScope/1.0
|
|
233
247
|
```
|
|
234
248
|
|
|
235
|
-
### ``body
|
|
249
|
+
### ``body``:
|
|
236
250
|
Returns the request body as a buffer.
|
|
237
251
|
|
|
238
252
|
```js
|
|
239
|
-
console.log(sjs.body
|
|
253
|
+
console.log(sjs.body.toString("utf8"));
|
|
240
254
|
// Hello, world!
|
|
241
255
|
```
|
|
242
256
|
|
|
243
|
-
### ``bodyStream()``:
|
|
257
|
+
### ``bodyStream([options])``:
|
|
258
|
+
- ``options:`` BufferEncoding | ReadStreamOptions: Optional. The options to pass to fs.createReadStream.
|
|
244
259
|
Returns the request body as a ReadStream.
|
|
245
260
|
|
|
246
261
|
```js
|
|
@@ -248,10 +263,10 @@ console.log(sjs.bodyStream().read(13).toString("utf8"));
|
|
|
248
263
|
// Hello, world!
|
|
249
264
|
```
|
|
250
265
|
|
|
251
|
-
### ``
|
|
266
|
+
### ``mTlsPeerCertificate``:
|
|
252
267
|
Returns details about the mTLS peer's certificate, if present.
|
|
253
268
|
|
|
254
269
|
```js
|
|
255
|
-
console.log(sjs.
|
|
270
|
+
console.log(sjs.mTlsPeerCertificate.subject.CN);
|
|
256
271
|
// sprucehttp.com
|
|
257
272
|
```
|
package/index.js
CHANGED
|
@@ -1,16 +1,19 @@
|
|
|
1
1
|
// This is still CommonJS to support both the old and new versions of the module system.
|
|
2
2
|
// eslint-disable-next-line @typescript-eslint/no-require-imports
|
|
3
|
-
const fs = require("fs");
|
|
3
|
+
const fs = require("node:fs");
|
|
4
4
|
|
|
5
5
|
module.exports = {
|
|
6
6
|
/**
|
|
7
7
|
* Sets the response into stream mode.
|
|
8
8
|
*
|
|
9
9
|
* Stream mode means that responses are not buffered by the webserver.
|
|
10
|
+
* @returns {Promise<void>} A Promise that resolves when the server acknowledges the switch to stream mode.
|
|
10
11
|
*/
|
|
11
|
-
streamMode
|
|
12
|
-
|
|
13
|
-
|
|
12
|
+
streamMode() {
|
|
13
|
+
return new Promise(function (resolve) {
|
|
14
|
+
process.send({
|
|
15
|
+
type: "streamMode"
|
|
16
|
+
}, resolve);
|
|
14
17
|
});
|
|
15
18
|
},
|
|
16
19
|
|
|
@@ -18,12 +21,15 @@ module.exports = {
|
|
|
18
21
|
* Writes the status line to the response.
|
|
19
22
|
* @param {number} statusCode The HTTP status code to send.
|
|
20
23
|
* @param {string} [reasonPhrase] The reason phrase to send.
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
24
|
+
* @return {Promise<void>} A Promise that resolves when the server acknowledges the status line.
|
|
25
|
+
*/
|
|
26
|
+
writeStatusLine(statusCode, reasonPhrase) {
|
|
27
|
+
return new Promise(function (resolve) {
|
|
28
|
+
process.send({
|
|
29
|
+
type: "status",
|
|
30
|
+
statusCode,
|
|
31
|
+
reasonPhrase
|
|
32
|
+
}, resolve);
|
|
27
33
|
});
|
|
28
34
|
},
|
|
29
35
|
|
|
@@ -31,12 +37,15 @@ module.exports = {
|
|
|
31
37
|
* Writes a header to the response.
|
|
32
38
|
* @param {string} name The name of the header to send.
|
|
33
39
|
* @param {string} value The value of the header to send.
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
+
* @return {Promise<void>} A Promise that resolves when the server acknowledges the header.
|
|
41
|
+
*/
|
|
42
|
+
writeHeader(name, value) {
|
|
43
|
+
return new Promise(function (resolve) {
|
|
44
|
+
process.send({
|
|
45
|
+
type: "header",
|
|
46
|
+
name,
|
|
47
|
+
value
|
|
48
|
+
}, resolve);
|
|
40
49
|
});
|
|
41
50
|
},
|
|
42
51
|
|
|
@@ -45,18 +54,23 @@ module.exports = {
|
|
|
45
54
|
*
|
|
46
55
|
* When not in stream mode, the Content-Length header is automatically updated.
|
|
47
56
|
* @param {string | Buffer} data The data to send.
|
|
57
|
+
* @returns {void}
|
|
58
|
+
* @deprecated Use writeDataAsync instead. Data cannot be reliably sent synchronously. Will be removed in a future major version.
|
|
48
59
|
*/
|
|
49
|
-
writeData
|
|
60
|
+
writeData(data) {
|
|
50
61
|
(async () => { await this.writeDataAsync(data); })();
|
|
51
62
|
},
|
|
52
63
|
|
|
53
64
|
/**
|
|
54
65
|
* Writes data (the body) to the response asynchronously.
|
|
55
66
|
*
|
|
67
|
+
* Will be renamed to writeData in a future major version.
|
|
68
|
+
*
|
|
56
69
|
* When not in stream mode, the Content-Length header is automatically updated.
|
|
57
70
|
* @param {string | Buffer} data The data to send.
|
|
71
|
+
* @returns {Promise<void>} A Promise that resolves when the data has been written.
|
|
58
72
|
*/
|
|
59
|
-
writeDataAsync
|
|
73
|
+
writeDataAsync(data) {
|
|
60
74
|
// eslint-disable-next-line no-async-promise-executor
|
|
61
75
|
return new Promise(async function (resolve) {
|
|
62
76
|
// Send the data in 1 MiB chunks
|
|
@@ -85,10 +99,13 @@ module.exports = {
|
|
|
85
99
|
* This is useful when you want to send a different response than the one you have already written.
|
|
86
100
|
*
|
|
87
101
|
* This function does not work in stream mode.
|
|
102
|
+
* @returns {Promise<void>} A Promise that resolves when the response has been cleared.
|
|
88
103
|
*/
|
|
89
|
-
clearResponse
|
|
90
|
-
|
|
91
|
-
|
|
104
|
+
clearResponse() {
|
|
105
|
+
return new Promise(function (resolve) {
|
|
106
|
+
process.send({
|
|
107
|
+
type: "clear"
|
|
108
|
+
}, resolve);
|
|
92
109
|
});
|
|
93
110
|
},
|
|
94
111
|
|
|
@@ -97,7 +114,7 @@ module.exports = {
|
|
|
97
114
|
*
|
|
98
115
|
* @returns {{[key: string]: string}} The site-specific configuration.
|
|
99
116
|
*/
|
|
100
|
-
siteConfig
|
|
117
|
+
get siteConfig() {
|
|
101
118
|
return JSON.parse(process.env.siteConfig);
|
|
102
119
|
},
|
|
103
120
|
|
|
@@ -106,7 +123,7 @@ module.exports = {
|
|
|
106
123
|
*
|
|
107
124
|
* @returns {string} The requestor's IP address.
|
|
108
125
|
*/
|
|
109
|
-
requestIP
|
|
126
|
+
get requestIP() {
|
|
110
127
|
return process.env.reqIP;
|
|
111
128
|
},
|
|
112
129
|
|
|
@@ -115,7 +132,7 @@ module.exports = {
|
|
|
115
132
|
*
|
|
116
133
|
* @returns {string} The request method.
|
|
117
134
|
*/
|
|
118
|
-
method
|
|
135
|
+
get method() {
|
|
119
136
|
return process.env.reqMethod.toLowerCase();
|
|
120
137
|
},
|
|
121
138
|
|
|
@@ -124,7 +141,7 @@ module.exports = {
|
|
|
124
141
|
*
|
|
125
142
|
* @returns {string} The full request path.
|
|
126
143
|
*/
|
|
127
|
-
path
|
|
144
|
+
get path() {
|
|
128
145
|
return process.env.reqPath;
|
|
129
146
|
},
|
|
130
147
|
|
|
@@ -133,7 +150,7 @@ module.exports = {
|
|
|
133
150
|
*
|
|
134
151
|
* @returns {string} The request's info path.
|
|
135
152
|
*/
|
|
136
|
-
pathInfo
|
|
153
|
+
get pathInfo() {
|
|
137
154
|
return process.env.reqPathInfo;
|
|
138
155
|
},
|
|
139
156
|
|
|
@@ -142,7 +159,7 @@ module.exports = {
|
|
|
142
159
|
*
|
|
143
160
|
* @returns {{[key: string]: string}} The parsed query string of the request.
|
|
144
161
|
*/
|
|
145
|
-
query
|
|
162
|
+
get query() {
|
|
146
163
|
return JSON.parse(process.env.reqQuery || "{}");
|
|
147
164
|
},
|
|
148
165
|
|
|
@@ -152,8 +169,8 @@ module.exports = {
|
|
|
152
169
|
* @param {string} key The key of the query to get.
|
|
153
170
|
* @returns {string} The value of the query parameter.
|
|
154
171
|
*/
|
|
155
|
-
queryValue
|
|
156
|
-
return this.query
|
|
172
|
+
queryValue(key) {
|
|
173
|
+
return this.query[key];
|
|
157
174
|
},
|
|
158
175
|
|
|
159
176
|
/**
|
|
@@ -161,7 +178,7 @@ module.exports = {
|
|
|
161
178
|
*
|
|
162
179
|
* @returns {string} The HTTP version of the request.
|
|
163
180
|
*/
|
|
164
|
-
httpVersion
|
|
181
|
+
get httpVersion() {
|
|
165
182
|
return process.env.reqHttpVersion;
|
|
166
183
|
},
|
|
167
184
|
|
|
@@ -170,7 +187,7 @@ module.exports = {
|
|
|
170
187
|
*
|
|
171
188
|
* @returns {{[key: string]: string}} The headers of the request.
|
|
172
189
|
*/
|
|
173
|
-
headers
|
|
190
|
+
get headers() {
|
|
174
191
|
return JSON.parse(process.env.reqHeaders || "{}");
|
|
175
192
|
},
|
|
176
193
|
|
|
@@ -180,8 +197,8 @@ module.exports = {
|
|
|
180
197
|
* @param {string} name The name of the header to get.
|
|
181
198
|
* @returns {string} The value of the header.
|
|
182
199
|
*/
|
|
183
|
-
headerValue
|
|
184
|
-
return this.headers
|
|
200
|
+
headerValue(name) {
|
|
201
|
+
return this.headers[name];
|
|
185
202
|
},
|
|
186
203
|
|
|
187
204
|
/**
|
|
@@ -189,7 +206,7 @@ module.exports = {
|
|
|
189
206
|
*
|
|
190
207
|
* @returns {Buffer} The body of the request.
|
|
191
208
|
*/
|
|
192
|
-
body
|
|
209
|
+
get body() {
|
|
193
210
|
let retVal = undefined;
|
|
194
211
|
if (process.env.reqBody) {
|
|
195
212
|
retVal = fs.readFileSync(process.env.reqBody);
|
|
@@ -203,7 +220,7 @@ module.exports = {
|
|
|
203
220
|
* @param {BufferEncoding | ReadStreamOptions} [options] The options to pass to fs.createReadStream.
|
|
204
221
|
* @returns {fs.ReadStream} A ReadStream of the body of the request.
|
|
205
222
|
*/
|
|
206
|
-
bodyStream
|
|
223
|
+
bodyStream(options) {
|
|
207
224
|
let retVal = undefined;
|
|
208
225
|
if (process.env.reqBody) {
|
|
209
226
|
retVal = fs.createReadStream(process.env.reqBody, options);
|
|
@@ -214,9 +231,9 @@ module.exports = {
|
|
|
214
231
|
/**
|
|
215
232
|
* Returns details about the mTLS peer's certificate, if present.
|
|
216
233
|
*
|
|
217
|
-
* @returns {PeerCertificate}
|
|
234
|
+
* @returns {import("node:tls").PeerCertificate}
|
|
218
235
|
*/
|
|
219
|
-
|
|
236
|
+
get mTlsPeerCertificate() {
|
|
220
237
|
let retVal = undefined;
|
|
221
238
|
if (process.env.mTlsPeerCertificate) {
|
|
222
239
|
retVal = JSON.parse(process.env.mTlsPeerCertificate);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "sprucehttp_sjs",
|
|
3
|
-
"version": "1.0
|
|
3
|
+
"version": "2.1.0",
|
|
4
4
|
"description": "A module for responding to requests within SpruceHTTP in an SJS file",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"scripts": {
|
|
@@ -13,15 +13,15 @@
|
|
|
13
13
|
"spruce",
|
|
14
14
|
"sprucehttp"
|
|
15
15
|
],
|
|
16
|
-
"homepage": "https://
|
|
16
|
+
"homepage": "https://sprucehttp.com/",
|
|
17
17
|
"bugs": {
|
|
18
|
-
"url": "https://
|
|
19
|
-
"email": "herronjo@
|
|
18
|
+
"url": "https://sprucehttp.com/reportbug/",
|
|
19
|
+
"email": "herronjo@sprucehttp.com"
|
|
20
20
|
},
|
|
21
21
|
"author": {
|
|
22
22
|
"name": "Joshua Herron",
|
|
23
|
-
"email": "herronjo@
|
|
24
|
-
"url": "https://
|
|
23
|
+
"email": "herronjo@sprucehttp.com",
|
|
24
|
+
"url": "https://sprucehttp.com"
|
|
25
25
|
},
|
|
26
26
|
"license": "Copyright (c) STiBaRC LLC. All rights reserved."
|
|
27
27
|
}
|