@opra/http 1.21.0 → 1.22.1

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.
Files changed (70) hide show
  1. package/{esm/express-adapter.js → express-adapter.js} +2 -1
  2. package/{esm/http-adapter.js → http-adapter.js} +5 -1
  3. package/{esm/http-context.js → http-context.js} +10 -1
  4. package/{esm/http-handler.js → http-handler.js} +3 -0
  5. package/{esm/impl → impl}/http-incoming.host.js +1 -0
  6. package/{esm/impl → impl}/multipart-reader.js +10 -5
  7. package/{esm/impl → impl}/node-incoming-message.host.js +15 -4
  8. package/{esm/impl → impl}/node-outgoing-message.host.js +7 -2
  9. package/package.json +14 -31
  10. package/{esm/utils → utils}/body-reader.js +10 -2
  11. package/cjs/express-adapter.js +0 -134
  12. package/cjs/http-adapter.js +0 -25
  13. package/cjs/http-context.js +0 -114
  14. package/cjs/http-handler.js +0 -668
  15. package/cjs/impl/http-incoming.host.js +0 -112
  16. package/cjs/impl/http-outgoing.host.js +0 -207
  17. package/cjs/impl/multipart-reader.js +0 -209
  18. package/cjs/impl/node-incoming-message.host.js +0 -115
  19. package/cjs/impl/node-outgoing-message.host.js +0 -201
  20. package/cjs/index.js +0 -27
  21. package/cjs/interfaces/http-incoming.interface.js +0 -25
  22. package/cjs/interfaces/http-outgoing.interface.js +0 -22
  23. package/cjs/interfaces/node-incoming-message.interface.js +0 -65
  24. package/cjs/interfaces/node-outgoing-message.interface.js +0 -15
  25. package/cjs/package.json +0 -3
  26. package/cjs/type-guards.js +0 -27
  27. package/cjs/utils/body-reader.js +0 -227
  28. package/cjs/utils/common.js +0 -67
  29. package/cjs/utils/concat-readable.js +0 -19
  30. package/cjs/utils/convert-to-headers.js +0 -64
  31. package/cjs/utils/convert-to-raw-headers.js +0 -25
  32. package/cjs/utils/match-known-fields.js +0 -49
  33. package/cjs/utils/wrap-exception.js +0 -33
  34. package/esm/package.json +0 -3
  35. package/types/index.d.cts +0 -22
  36. /package/{types/express-adapter.d.ts → express-adapter.d.ts} +0 -0
  37. /package/{types/http-adapter.d.ts → http-adapter.d.ts} +0 -0
  38. /package/{types/http-context.d.ts → http-context.d.ts} +0 -0
  39. /package/{types/http-handler.d.ts → http-handler.d.ts} +0 -0
  40. /package/{types/impl → impl}/http-incoming.host.d.ts +0 -0
  41. /package/{types/impl → impl}/http-outgoing.host.d.ts +0 -0
  42. /package/{esm/impl → impl}/http-outgoing.host.js +0 -0
  43. /package/{types/impl → impl}/multipart-reader.d.ts +0 -0
  44. /package/{types/impl → impl}/node-incoming-message.host.d.ts +0 -0
  45. /package/{types/impl → impl}/node-outgoing-message.host.d.ts +0 -0
  46. /package/{types/index.d.ts → index.d.ts} +0 -0
  47. /package/{esm/index.js → index.js} +0 -0
  48. /package/{types/interfaces → interfaces}/http-incoming.interface.d.ts +0 -0
  49. /package/{esm/interfaces → interfaces}/http-incoming.interface.js +0 -0
  50. /package/{types/interfaces → interfaces}/http-outgoing.interface.d.ts +0 -0
  51. /package/{esm/interfaces → interfaces}/http-outgoing.interface.js +0 -0
  52. /package/{types/interfaces → interfaces}/node-incoming-message.interface.d.ts +0 -0
  53. /package/{esm/interfaces → interfaces}/node-incoming-message.interface.js +0 -0
  54. /package/{types/interfaces → interfaces}/node-outgoing-message.interface.d.ts +0 -0
  55. /package/{esm/interfaces → interfaces}/node-outgoing-message.interface.js +0 -0
  56. /package/{types/type-guards.d.ts → type-guards.d.ts} +0 -0
  57. /package/{esm/type-guards.js → type-guards.js} +0 -0
  58. /package/{types/utils → utils}/body-reader.d.ts +0 -0
  59. /package/{types/utils → utils}/common.d.ts +0 -0
  60. /package/{esm/utils → utils}/common.js +0 -0
  61. /package/{types/utils → utils}/concat-readable.d.ts +0 -0
  62. /package/{esm/utils → utils}/concat-readable.js +0 -0
  63. /package/{types/utils → utils}/convert-to-headers.d.ts +0 -0
  64. /package/{esm/utils → utils}/convert-to-headers.js +0 -0
  65. /package/{types/utils → utils}/convert-to-raw-headers.d.ts +0 -0
  66. /package/{esm/utils → utils}/convert-to-raw-headers.js +0 -0
  67. /package/{types/utils → utils}/match-known-fields.d.ts +0 -0
  68. /package/{esm/utils → utils}/match-known-fields.js +0 -0
  69. /package/{types/utils → utils}/wrap-exception.d.ts +0 -0
  70. /package/{esm/utils → utils}/wrap-exception.js +0 -0
@@ -1,112 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.HttpIncomingHost = void 0;
4
- const tslib_1 = require("tslib");
5
- /*
6
- Some parts of this file contains codes from open source express library
7
- https://github.com/expressjs
8
- */
9
- const type_is_1 = tslib_1.__importDefault(require("@browsery/type-is"));
10
- const accepts_1 = tslib_1.__importDefault(require("accepts"));
11
- const fresh_1 = tslib_1.__importDefault(require("fresh"));
12
- const range_parser_1 = tslib_1.__importDefault(require("range-parser"));
13
- const body_reader_js_1 = require("../utils/body-reader.js");
14
- class HttpIncomingHost {
15
- get protocol() {
16
- const proto = this.header('X-Forwarded-Proto') || 'http';
17
- const index = proto.indexOf(',');
18
- return index !== -1 ? proto.substring(0, index).trim() : proto.trim();
19
- }
20
- get secure() {
21
- return this.protocol === 'https';
22
- }
23
- get hostname() {
24
- let host = this.get('X-Forwarded-Host');
25
- if (!host) {
26
- host = this.get('Host');
27
- }
28
- else if (host.indexOf(',') !== -1) {
29
- // Note: X-Forwarded-Host is normally only ever a
30
- // single value, but this is to be safe.
31
- host = host.substring(0, host.indexOf(',')).trim();
32
- }
33
- if (host) {
34
- // IPv6 literal support
35
- const offset = host[0] === '[' ? host.indexOf(']') + 1 : 0;
36
- const index = host.indexOf(':', offset);
37
- return index !== -1 ? host.substring(0, index) : host;
38
- }
39
- return '';
40
- }
41
- get fresh() {
42
- const method = this.method;
43
- // GET or HEAD for weak freshness validation only
44
- if (method !== 'GET' && method !== 'HEAD')
45
- return false;
46
- const status = this.res?.statusCode;
47
- // 2xx or 304 as per rfc2616 14.26
48
- if ((status >= 200 && status < 300) || status === 304) {
49
- return (0, fresh_1.default)(this.headers, {
50
- etag: this.res.getHeader('ETag'),
51
- 'last-modified': this.res.getHeader('Last-Modified'),
52
- });
53
- }
54
- return false;
55
- }
56
- get xhr() {
57
- const val = this.get('X-Requested-With') || '';
58
- return val.toLowerCase() === 'xmlhttprequest';
59
- }
60
- header(name) {
61
- name = name.toLowerCase();
62
- const headers = this.headers;
63
- switch (name) {
64
- case 'referer':
65
- return headers.referer || headers.referrer;
66
- case 'referrer':
67
- return headers.referrer || headers.referer;
68
- default:
69
- return headers[name];
70
- }
71
- }
72
- get(name) {
73
- return this.header(name);
74
- }
75
- accepts(...types) {
76
- const accept = (0, accepts_1.default)(this);
77
- return accept.types.call(accept, ...types);
78
- }
79
- acceptsCharsets(...charsets) {
80
- const accept = (0, accepts_1.default)(this);
81
- return accept.charsets.call(accept, ...charsets);
82
- }
83
- acceptsEncodings(...encoding) {
84
- const accept = (0, accepts_1.default)(this);
85
- // eslint-disable-next-line prefer-spread
86
- return accept.encodings.apply(accept, encoding);
87
- }
88
- acceptsLanguages(...lang) {
89
- const accept = (0, accepts_1.default)(this);
90
- // eslint-disable-next-line prefer-spread
91
- return accept.languages.apply(accept, lang);
92
- }
93
- is(type, ...otherTypes) {
94
- const types = Array.isArray(type) ? type : [type];
95
- if (otherTypes.length)
96
- types.push(...otherTypes);
97
- const contentType = this.header('content-type');
98
- return contentType ? type_is_1.default.is(contentType, types) : null;
99
- }
100
- range(size, options) {
101
- const range = this.header('range');
102
- if (!range)
103
- return;
104
- return (0, range_parser_1.default)(size, range, options);
105
- }
106
- async readBody(options) {
107
- if (!this.complete)
108
- this.body = await body_reader_js_1.BodyReader.read(this, options);
109
- return this.body;
110
- }
111
- }
112
- exports.HttpIncomingHost = HttpIncomingHost;
@@ -1,207 +0,0 @@
1
- "use strict";
2
- /*
3
- Some parts of this file contains codes from open source express library
4
- https://github.com/expressjs
5
- */
6
- Object.defineProperty(exports, "__esModule", { value: true });
7
- exports.HttpOutgoingHost = void 0;
8
- const tslib_1 = require("tslib");
9
- const node_path_1 = tslib_1.__importDefault(require("node:path"));
10
- const common_1 = require("@opra/common");
11
- const content_disposition_1 = tslib_1.__importDefault(require("content-disposition"));
12
- const content_type_1 = tslib_1.__importDefault(require("content-type"));
13
- const cookie = tslib_1.__importStar(require("cookie"));
14
- const cookie_signature_1 = tslib_1.__importDefault(require("cookie-signature"));
15
- const encodeurl_1 = tslib_1.__importDefault(require("encodeurl"));
16
- const mime_types_1 = tslib_1.__importDefault(require("mime-types"));
17
- const putil_varhelpers_1 = require("putil-varhelpers");
18
- const vary_1 = tslib_1.__importDefault(require("vary"));
19
- const charsetRegExp = /;\s*charset\s*=/;
20
- class HttpOutgoingHost {
21
- attachment(filename) {
22
- if (filename)
23
- this.contentType(node_path_1.default.extname(filename));
24
- this.setHeader('Content-Disposition', (0, content_disposition_1.default)(filename));
25
- return this;
26
- }
27
- contentType(type) {
28
- const ct = type.indexOf('/') === -1 ? mime_types_1.default.lookup(type) : type;
29
- this.setHeader('Content-Type', ct);
30
- return this;
31
- }
32
- setHeader(field, val) {
33
- const setHeader = Object.getPrototypeOf(this).setHeader;
34
- if (typeof field === 'object') {
35
- for (const [k, v] of Object.entries(field)) {
36
- this.setHeader(k, v);
37
- }
38
- return this;
39
- }
40
- const fieldLower = field.toLowerCase();
41
- let value = Array.isArray(val) ? val.map(String) : val ? String(val) : '';
42
- // add charset to content-type
43
- if (fieldLower === 'content-type') {
44
- if (Array.isArray(value)) {
45
- throw new TypeError('Content-Type cannot be set to an Array');
46
- }
47
- if (!charsetRegExp.test(value)) {
48
- const charset = mime_types_1.default.charsets.lookup(value.split(';')[0]);
49
- if (charset)
50
- value += '; charset=' + charset.toLowerCase();
51
- }
52
- }
53
- setHeader.call(this, field, value);
54
- return this;
55
- }
56
- clearCookie(name, options) {
57
- const opts = {
58
- expires: new Date(1),
59
- path: '/',
60
- ...options,
61
- };
62
- return this.cookie(name, '', opts);
63
- }
64
- cookie(name, value, options) {
65
- const opts = { ...options };
66
- let val = typeof value === 'object' ? 'j:' + JSON.stringify(value) : String(value);
67
- if (opts.signed) {
68
- const secret = opts.secret || this.req?.secret;
69
- if (!secret)
70
- throw new Error('"secret" required for signed cookies');
71
- val = 's:' + cookie_signature_1.default.sign(val, secret);
72
- }
73
- if (opts.maxAge != null) {
74
- const maxAge = opts.maxAge - 0;
75
- if (!isNaN(maxAge)) {
76
- opts.expires = new Date(Date.now() + maxAge);
77
- opts.maxAge = Math.floor(maxAge / 1000);
78
- }
79
- }
80
- if (opts.path == null)
81
- opts.path = '/';
82
- this.appendHeader('Set-Cookie', cookie.serialize(name, String(val), opts));
83
- return this;
84
- }
85
- status(code) {
86
- this.statusCode = code;
87
- return this;
88
- }
89
- sendStatus(statusCode) {
90
- const body = common_1.HttpStatusCode[statusCode] || String(statusCode);
91
- this.statusCode = statusCode;
92
- this.contentType('txt');
93
- return this.send(body);
94
- }
95
- links(links) {
96
- let link = this.getHeader('Link') || '';
97
- if (link)
98
- link += ', ';
99
- this.setHeader('Link', link +
100
- Object.keys(links)
101
- .map(rel => '<' + links[rel] + '>; rel="' + rel + '"')
102
- .join(', '));
103
- return this;
104
- }
105
- location(url) {
106
- let loc = url;
107
- // "back" is an alias for the referrer
108
- if (url === 'back')
109
- loc = this.req?.get('Referrer') || '/';
110
- // set location
111
- return this.setHeader('Location', (0, encodeurl_1.default)(loc));
112
- }
113
- redirect(arg0, arg1) {
114
- const address = String(arg1 || arg0);
115
- const status = typeof arg0 === 'number' ? arg0 : 302;
116
- // Set location header
117
- this.location(address);
118
- // Respond
119
- this.statusCode = status;
120
- this.end();
121
- }
122
- send(body) {
123
- let chunk = body;
124
- let encoding;
125
- const req = this.req;
126
- let ctype = (0, putil_varhelpers_1.toString)(this.getHeader('Content-Type'));
127
- if (typeof chunk !== 'string') {
128
- if (chunk === null)
129
- chunk = '';
130
- else if (Buffer.isBuffer(chunk)) {
131
- if (!ctype)
132
- this.contentType('bin');
133
- }
134
- else {
135
- ctype = 'json';
136
- chunk = JSON.stringify(chunk);
137
- }
138
- }
139
- // write strings in utf-8
140
- if (typeof chunk === 'string') {
141
- encoding = 'utf-8';
142
- this.setHeader('Content-Type', setCharset(ctype || 'txt', encoding));
143
- }
144
- // populate Content-Length
145
- let len = 0;
146
- if (chunk !== undefined) {
147
- if (Buffer.isBuffer(chunk)) {
148
- // get length of Buffer
149
- len = chunk.length;
150
- }
151
- else if (chunk.length < 1000) {
152
- // just calculate length when small chunk
153
- len = Buffer.byteLength(chunk, encoding);
154
- }
155
- else {
156
- // convert chunk to Buffer and calculate
157
- chunk = Buffer.from(chunk, encoding);
158
- encoding = undefined;
159
- len = chunk.length;
160
- }
161
- this.setHeader('Content-Length', len);
162
- }
163
- // freshness
164
- if (req?.fresh)
165
- this.statusCode = 304;
166
- // strip irrelevant headers
167
- if (this.statusCode === 204 || this.statusCode === 304) {
168
- this.removeHeader('Content-Type');
169
- this.removeHeader('Content-Length');
170
- this.removeHeader('Transfer-Encoding');
171
- chunk = '';
172
- }
173
- // alter headers for 205
174
- if (this.statusCode === 205) {
175
- this.setHeader('Content-Length', '0');
176
- this.removeHeader('Transfer-Encoding');
177
- chunk = '';
178
- }
179
- if (req?.method === 'HEAD') {
180
- // skip body for HEAD
181
- this.end();
182
- }
183
- else {
184
- // respond
185
- if (encoding)
186
- this.end(chunk, encoding);
187
- else
188
- this.end(chunk);
189
- }
190
- return this;
191
- }
192
- vary(field) {
193
- (0, vary_1.default)(this, field);
194
- return this;
195
- }
196
- }
197
- exports.HttpOutgoingHost = HttpOutgoingHost;
198
- function setCharset(type, charset) {
199
- if (!(type && charset))
200
- return type;
201
- // parse type
202
- const parsed = content_type_1.default.parse(type);
203
- // set charset
204
- parsed.parameters.charset = charset;
205
- // format type
206
- return content_type_1.default.format(parsed);
207
- }
@@ -1,209 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.MultipartReader = void 0;
4
- const tslib_1 = require("tslib");
5
- const node_crypto_1 = require("node:crypto");
6
- const node_fs_1 = tslib_1.__importDefault(require("node:fs"));
7
- const node_os_1 = tslib_1.__importDefault(require("node:os"));
8
- const node_path_1 = tslib_1.__importDefault(require("node:path"));
9
- const type_is_1 = tslib_1.__importDefault(require("@browsery/type-is"));
10
- const common_1 = require("@opra/common");
11
- const busboy_1 = tslib_1.__importDefault(require("busboy"));
12
- const events_1 = require("events");
13
- const promises_1 = tslib_1.__importDefault(require("fs/promises"));
14
- const valgen_1 = require("valgen");
15
- class MultipartReader extends events_1.EventEmitter {
16
- constructor(context, options, mediaType) {
17
- super();
18
- this.context = context;
19
- this.mediaType = mediaType;
20
- this._started = false;
21
- this._finished = false;
22
- this._cancelled = false;
23
- this._items = [];
24
- this._stack = [];
25
- this.setMaxListeners(1000);
26
- this.tempDirectory = options?.tempDirectory || node_os_1.default.tmpdir();
27
- this.scope = options?.scope;
28
- const { request } = context;
29
- const form = (0, busboy_1.default)({ headers: request.headers });
30
- this._form = form;
31
- form.once('error', (e) => {
32
- this._cancelled = true;
33
- this._finished = true;
34
- if (this.listenerCount('error') > 0)
35
- this.emit('error', e);
36
- });
37
- form.on('close', () => {
38
- this._finished = true;
39
- });
40
- form.on('field', (field, value, info) => {
41
- const item = {
42
- kind: 'field',
43
- field,
44
- value,
45
- mimeType: info.mimeType,
46
- encoding: info.encoding,
47
- };
48
- this._items.push(item);
49
- this._stack.push(item);
50
- this.emit('field', item);
51
- this.emit('item', item);
52
- });
53
- form.on('file', (field, file, info) => {
54
- const saveTo = node_path_1.default.posix.join(this.tempDirectory, `opra-${generateFileName()}`);
55
- file.pipe(node_fs_1.default.createWriteStream(saveTo));
56
- file.once('end', () => {
57
- const item = {
58
- kind: 'file',
59
- field,
60
- storedPath: saveTo,
61
- filename: info.filename,
62
- mimeType: info.mimeType,
63
- encoding: info.encoding,
64
- };
65
- this._items.push(item);
66
- this._stack.push(item);
67
- this.emit('file', item);
68
- this.emit('item', item);
69
- });
70
- });
71
- }
72
- get items() {
73
- return this._items;
74
- }
75
- async getNext() {
76
- let item = this._stack.shift();
77
- if (!item && !this._finished) {
78
- this.resume();
79
- item = await new Promise((resolve, reject) => {
80
- let resolved = false;
81
- if (this._stack.length)
82
- return resolve(this._stack.shift());
83
- if (this._form.ended)
84
- return resolve(undefined);
85
- this._form.once('close', () => {
86
- if (resolved)
87
- return;
88
- resolved = true;
89
- resolve(this._stack.shift());
90
- });
91
- this.once('item', () => {
92
- this.pause();
93
- if (resolved)
94
- return;
95
- resolved = true;
96
- resolve(this._stack.shift());
97
- });
98
- this.once('error', e => reject(e));
99
- });
100
- }
101
- if (item && this.mediaType) {
102
- const field = this.mediaType.findMultipartField(item.field);
103
- if (!field)
104
- throw new common_1.BadRequestError(`Unknown multipart field (${item.field})`);
105
- if (item.kind === 'field') {
106
- const decode = field.generateCodec('decode', {
107
- scope: this.scope,
108
- ignoreReadonlyFields: true,
109
- projection: '*',
110
- });
111
- item.value = decode(item.value, {
112
- onFail: issue => `Multipart field (${item.field}) validation failed: ` +
113
- issue.message,
114
- });
115
- }
116
- else if (item.kind === 'file') {
117
- if (field.contentType) {
118
- const arr = Array.isArray(field.contentType)
119
- ? field.contentType
120
- : [field.contentType];
121
- if (!(item.mimeType && arr.find(ct => type_is_1.default.is(item.mimeType, [ct])))) {
122
- throw new common_1.BadRequestError(`Multipart field (${item.field}) do not accept this content type`);
123
- }
124
- }
125
- }
126
- }
127
- /** if all items received we check for required items */
128
- if (this._finished &&
129
- this.mediaType &&
130
- this.mediaType.multipartFields?.length > 0) {
131
- const fieldsLeft = new Set(this.mediaType.multipartFields);
132
- for (const x of this._items) {
133
- const field = this.mediaType.findMultipartField(x.field);
134
- if (field)
135
- fieldsLeft.delete(field);
136
- }
137
- let issues;
138
- for (const field of fieldsLeft) {
139
- if (!field.required)
140
- continue;
141
- try {
142
- (0, valgen_1.isNotNullish)(null, {
143
- onFail: () => `Multi part field "${String(field.fieldName)}" is required`,
144
- });
145
- }
146
- catch (e) {
147
- if (!issues) {
148
- issues = e.issues;
149
- this.context.errors.push(e);
150
- }
151
- else
152
- issues.push(...e.issues);
153
- }
154
- }
155
- if (this.context.errors.length)
156
- throw this.context.errors[0];
157
- }
158
- return item;
159
- }
160
- async getAll() {
161
- const items = [...this._items];
162
- let item;
163
- while (!this._cancelled && (item = await this.getNext())) {
164
- items.push(item);
165
- }
166
- return items;
167
- }
168
- getAll_() {
169
- if (this._form.ended)
170
- return Promise.resolve([...this._items]);
171
- this.resume();
172
- return new Promise((resolve, reject) => {
173
- this._form.once('error', reject);
174
- this._form.once('end', () => {
175
- resolve([...this._items]);
176
- });
177
- });
178
- }
179
- cancel() {
180
- this._cancelled = true;
181
- if (this._form.req)
182
- this.resume();
183
- }
184
- resume() {
185
- if (!this._started) {
186
- this._started = true;
187
- this.context.request.pipe(this._form);
188
- }
189
- this.context.request.resume();
190
- }
191
- pause() {
192
- this.context.request.pause();
193
- }
194
- async purge() {
195
- const promises = [];
196
- this._items.forEach(item => {
197
- if (item.kind !== 'file')
198
- return;
199
- promises.push(promises_1.default.unlink(item.storedPath));
200
- });
201
- return Promise.allSettled(promises);
202
- }
203
- }
204
- exports.MultipartReader = MultipartReader;
205
- function generateFileName() {
206
- const buf = Buffer.alloc(10);
207
- return (new Date().toISOString().substring(0, 10).replace(/-/g, '') +
208
- (0, node_crypto_1.randomFillSync)(buf).toString('hex'));
209
- }
@@ -1,115 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.NodeIncomingMessageHost = exports.kHttpParser = exports.kTrailersDistinct = exports.kTrailers = exports.kHeadersDistinct = exports.kHeaders = exports.CRLF = void 0;
4
- const objects_1 = require("@jsopen/objects");
5
- const stream_1 = require("stream");
6
- const convert_to_headers_js_1 = require("../utils/convert-to-headers.js");
7
- const convert_to_raw_headers_js_1 = require("../utils/convert-to-raw-headers.js");
8
- exports.CRLF = Buffer.from('\r\n');
9
- exports.kHeaders = Symbol.for('kHeaders');
10
- exports.kHeadersDistinct = Symbol.for('kHeadersDistinct');
11
- exports.kTrailers = Symbol.for('kTrailers');
12
- exports.kTrailersDistinct = Symbol.for('kTrailersDistinct');
13
- exports.kHttpParser = Symbol.for('kHttpParser');
14
- /**
15
- *
16
- * @class NodeIncomingMessageHost
17
- */
18
- class NodeIncomingMessageHost extends stream_1.Duplex {
19
- constructor(init) {
20
- super();
21
- this.rawHeaders = [];
22
- this.rawTrailers = [];
23
- this.complete = false;
24
- this.joinDuplicateHeaders = false;
25
- if (init) {
26
- this.complete = true;
27
- this.httpVersionMajor = init.httpVersionMajor || 1;
28
- this.httpVersionMinor = init.httpVersionMinor || 0;
29
- this.method = (init.method || 'GET').toUpperCase();
30
- this.url = init.url || '';
31
- if (init.body != null) {
32
- if (Buffer.isBuffer(init.body))
33
- this.body = init.body;
34
- else if (typeof init.body === 'string')
35
- this.body = Buffer.from(init.body, 'utf-8');
36
- else
37
- this.body = Buffer.from(JSON.stringify(init.body), 'utf-8');
38
- }
39
- if (init.headers) {
40
- this.rawHeaders = Array.isArray(init.headers)
41
- ? init.headers
42
- : (0, convert_to_raw_headers_js_1.convertToRawHeaders)(init.headers);
43
- }
44
- if (init.trailers) {
45
- this.rawTrailers = Array.isArray(init.trailers)
46
- ? init.trailers
47
- : (0, convert_to_raw_headers_js_1.convertToRawHeaders)(init.trailers);
48
- }
49
- this.ip = init.ip || '';
50
- this.ips = init.ips || (this.ip ? [this.ip] : []);
51
- if (this.body && !this.headers['content-length'])
52
- this.headers['content-length'] = String(this.body.length);
53
- if (init.params)
54
- this.params = init.params;
55
- if (init.cookies)
56
- this.cookies = init.cookies;
57
- }
58
- }
59
- get httpVersion() {
60
- return this.httpVersionMajor
61
- ? this.httpVersionMajor + '.' + this.httpVersionMinor
62
- : '';
63
- }
64
- get headers() {
65
- if (!this[exports.kHeaders])
66
- this[exports.kHeaders] = (0, convert_to_headers_js_1.convertToHeaders)(this.rawHeaders, {}, this.joinDuplicateHeaders);
67
- return this[exports.kHeaders];
68
- }
69
- set headers(headers) {
70
- this[exports.kHeaders] = headers;
71
- }
72
- get headersDistinct() {
73
- if (!this[exports.kHeadersDistinct])
74
- this[exports.kHeadersDistinct] = (0, convert_to_headers_js_1.convertToHeadersDistinct)(this.rawHeaders, {});
75
- return this[exports.kHeadersDistinct];
76
- }
77
- get trailers() {
78
- if (!this[exports.kTrailers])
79
- this[exports.kTrailers] = (0, convert_to_headers_js_1.convertToHeaders)(this.rawTrailers, {}, this.joinDuplicateHeaders);
80
- return this[exports.kTrailers];
81
- }
82
- set trailers(trailers) {
83
- this[exports.kTrailers] = trailers;
84
- }
85
- get trailersDistinct() {
86
- if (!this[exports.kTrailersDistinct])
87
- this[exports.kTrailersDistinct] = (0, convert_to_headers_js_1.convertToHeadersDistinct)(this.rawTrailers, {});
88
- return this[exports.kTrailersDistinct];
89
- }
90
- _read(size) {
91
- if (!this.body) {
92
- this.push(null);
93
- return;
94
- }
95
- if (!this._readStream) {
96
- if ((0, objects_1.isIterable)(this.body) || (0, objects_1.isAsyncIterable)(this.body))
97
- this._readStream = stream_1.Readable.from(this.body);
98
- else if (typeof this.body === 'string') {
99
- this._readStream = stream_1.Readable.from(Buffer.from(this.body, 'utf-8'));
100
- }
101
- else
102
- this._readStream = stream_1.Readable.from(Buffer.from(JSON.stringify(this.body), 'utf-8'));
103
- }
104
- const chunk = this._readStream.read(size);
105
- this.push(chunk);
106
- }
107
- _write(chunk, encoding, callback) {
108
- const error = this[exports.kHttpParser]?.execute(chunk);
109
- if (error && typeof error === 'object')
110
- callback(error);
111
- else
112
- callback();
113
- }
114
- }
115
- exports.NodeIncomingMessageHost = NodeIncomingMessageHost;