@opra/core 0.33.13 → 1.0.0-alpha.10
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/cjs/augmentation/18n.augmentation.js +18 -5
- package/cjs/augmentation/http-controller.augmentation.js +25 -0
- package/cjs/constants.js +5 -0
- package/cjs/execution-context.js +24 -12
- package/cjs/{services → helpers}/logger.js +1 -2
- package/cjs/{services/api-service.js → helpers/service-base.js} +8 -8
- package/cjs/http/express-adapter.js +153 -0
- package/cjs/http/http-adapter.js +27 -0
- package/cjs/http/http-context.js +119 -0
- package/cjs/http/impl/asset-cache.js +21 -0
- package/cjs/http/impl/http-handler.js +584 -0
- package/cjs/http/{http-server-request.js → impl/http-incoming.host.js} +24 -49
- package/cjs/http/{http-server-response.js → impl/http-outgoing.host.js} +9 -28
- package/cjs/http/{helpers/multipart-helper.js → impl/multipart-reader.js} +23 -27
- package/cjs/http/impl/{http-incoming-message.host.js → node-incoming-message.host.js} +18 -57
- package/cjs/http/impl/{http-outgoing-message.host.js → node-outgoing-message.host.js} +11 -14
- package/cjs/http/interfaces/http-incoming.interface.js +25 -0
- package/cjs/http/interfaces/http-outgoing.interface.js +22 -0
- package/cjs/http/interfaces/node-incoming-message.interface.js +64 -0
- package/cjs/http/interfaces/node-outgoing-message.interface.js +15 -0
- package/cjs/http/utils/body-reader.js +217 -0
- package/cjs/http/{helpers → utils}/common.js +2 -1
- package/cjs/http/{helpers → utils}/convert-to-raw-headers.js +1 -2
- package/cjs/http/{helpers → utils}/match-known-fields.js +11 -9
- package/cjs/http/utils/wrap-exception.js +34 -0
- package/cjs/index.js +26 -26
- package/cjs/platform-adapter.js +21 -0
- package/cjs/type-guards.js +23 -0
- package/esm/augmentation/18n.augmentation.js +20 -7
- package/esm/augmentation/http-controller.augmentation.js +23 -0
- package/esm/constants.js +2 -0
- package/esm/execution-context.js +24 -13
- package/esm/{services → helpers}/logger.js +1 -2
- package/esm/{services/api-service.js → helpers/service-base.js} +6 -6
- package/esm/http/express-adapter.js +148 -0
- package/esm/http/http-adapter.js +23 -0
- package/esm/http/http-context.js +114 -0
- package/esm/http/impl/asset-cache.js +17 -0
- package/esm/http/impl/http-handler.js +579 -0
- package/esm/http/{http-server-request.js → impl/http-incoming.host.js} +20 -46
- package/esm/http/{http-server-response.js → impl/http-outgoing.host.js} +7 -27
- package/esm/http/{helpers/multipart-helper.js → impl/multipart-reader.js} +21 -25
- package/esm/http/impl/{http-incoming-message.host.js → node-incoming-message.host.js} +16 -55
- package/esm/http/impl/{http-outgoing-message.host.js → node-outgoing-message.host.js} +9 -12
- package/esm/http/interfaces/http-incoming.interface.js +22 -0
- package/esm/http/interfaces/http-outgoing.interface.js +19 -0
- package/esm/http/interfaces/node-incoming-message.interface.js +61 -0
- package/esm/http/interfaces/node-outgoing-message.interface.js +12 -0
- package/esm/http/utils/body-reader.js +212 -0
- package/esm/http/{helpers → utils}/common.js +2 -1
- package/esm/http/{helpers → utils}/convert-to-headers.js +1 -1
- package/esm/http/{helpers → utils}/convert-to-raw-headers.js +2 -3
- package/esm/http/{helpers → utils}/match-known-fields.js +11 -9
- package/esm/http/utils/wrap-exception.js +30 -0
- package/esm/index.js +26 -27
- package/esm/platform-adapter.js +19 -1
- package/esm/type-guards.js +16 -0
- package/package.json +31 -13
- package/types/augmentation/18n.augmentation.d.ts +31 -1
- package/types/augmentation/http-controller.augmentation.d.ts +21 -0
- package/types/constants.d.ts +2 -0
- package/types/execution-context.d.ts +22 -26
- package/types/helpers/service-base.d.ts +10 -0
- package/types/http/express-adapter.d.ts +13 -0
- package/types/http/http-adapter.d.ts +27 -0
- package/types/http/http-context.d.ts +44 -0
- package/types/http/impl/asset-cache.d.ts +5 -0
- package/types/http/impl/http-handler.d.ts +73 -0
- package/types/http/impl/http-incoming.host.d.ts +23 -0
- package/types/http/impl/http-outgoing.host.d.ts +17 -0
- package/types/http/{helpers/multipart-helper.d.ts → impl/multipart-reader.d.ts} +8 -6
- package/types/http/impl/{http-incoming-message.host.d.ts → node-incoming-message.host.d.ts} +10 -23
- package/types/http/impl/{http-outgoing-message.host.d.ts → node-outgoing-message.host.d.ts} +11 -27
- package/types/http/{http-server-request.d.ts → interfaces/http-incoming.interface.d.ts} +28 -17
- package/types/http/{http-server-response.d.ts → interfaces/http-outgoing.interface.d.ts} +17 -10
- package/types/http/interfaces/node-incoming-message.interface.d.ts +38 -0
- package/types/http/interfaces/node-outgoing-message.interface.d.ts +29 -0
- package/types/http/utils/body-reader.d.ts +41 -0
- package/types/http/utils/wrap-exception.d.ts +2 -0
- package/types/index.d.ts +25 -27
- package/types/platform-adapter.d.ts +20 -48
- package/types/type-guards.d.ts +8 -0
- package/cjs/augmentation/collection.augmentation.js +0 -2
- package/cjs/augmentation/container.augmentation.js +0 -2
- package/cjs/augmentation/resource.augmentation.js +0 -26
- package/cjs/augmentation/singleton.augmentation.js +0 -2
- package/cjs/augmentation/storage.augmentation.js +0 -2
- package/cjs/execution-context.host.js +0 -46
- package/cjs/http/adapters/express-adapter.host.js +0 -34
- package/cjs/http/adapters/express-adapter.js +0 -14
- package/cjs/http/adapters/node-http-adapter.host.js +0 -70
- package/cjs/http/adapters/node-http-adapter.js +0 -14
- package/cjs/http/helpers/json-body-loader.js +0 -29
- package/cjs/http/helpers/query-parsers.js +0 -16
- package/cjs/http/http-adapter-host.js +0 -715
- package/cjs/interfaces/interceptor.interface.js +0 -2
- package/cjs/interfaces/request-handler.interface.js +0 -2
- package/cjs/platform-adapter.host.js +0 -154
- package/cjs/request-context.js +0 -25
- package/cjs/request.host.js +0 -24
- package/cjs/request.js +0 -2
- package/cjs/response.host.js +0 -22
- package/cjs/response.js +0 -2
- package/esm/augmentation/collection.augmentation.js +0 -1
- package/esm/augmentation/container.augmentation.js +0 -1
- package/esm/augmentation/resource.augmentation.js +0 -24
- package/esm/augmentation/singleton.augmentation.js +0 -1
- package/esm/augmentation/storage.augmentation.js +0 -1
- package/esm/execution-context.host.js +0 -42
- package/esm/http/adapters/express-adapter.host.js +0 -30
- package/esm/http/adapters/express-adapter.js +0 -11
- package/esm/http/adapters/node-http-adapter.host.js +0 -65
- package/esm/http/adapters/node-http-adapter.js +0 -11
- package/esm/http/helpers/json-body-loader.js +0 -24
- package/esm/http/helpers/query-parsers.js +0 -12
- package/esm/http/http-adapter-host.js +0 -710
- package/esm/interfaces/interceptor.interface.js +0 -1
- package/esm/interfaces/request-handler.interface.js +0 -1
- package/esm/platform-adapter.host.js +0 -149
- package/esm/request-context.js +0 -22
- package/esm/request.host.js +0 -20
- package/esm/request.js +0 -1
- package/esm/response.host.js +0 -18
- package/esm/response.js +0 -1
- package/types/augmentation/collection.augmentation.d.ts +0 -146
- package/types/augmentation/container.augmentation.d.ts +0 -14
- package/types/augmentation/resource.augmentation.d.ts +0 -38
- package/types/augmentation/singleton.augmentation.d.ts +0 -83
- package/types/augmentation/storage.augmentation.d.ts +0 -50
- package/types/execution-context.host.d.ts +0 -25
- package/types/http/adapters/express-adapter.d.ts +0 -15
- package/types/http/adapters/express-adapter.host.d.ts +0 -12
- package/types/http/adapters/node-http-adapter.d.ts +0 -17
- package/types/http/adapters/node-http-adapter.host.d.ts +0 -19
- package/types/http/helpers/json-body-loader.d.ts +0 -5
- package/types/http/helpers/query-parsers.d.ts +0 -1
- package/types/http/http-adapter-host.d.ts +0 -34
- package/types/interfaces/interceptor.interface.d.ts +0 -2
- package/types/interfaces/request-handler.interface.d.ts +0 -4
- package/types/platform-adapter.host.d.ts +0 -43
- package/types/request-context.d.ts +0 -13
- package/types/request.d.ts +0 -14
- package/types/request.host.d.ts +0 -27
- package/types/response.d.ts +0 -22
- package/types/response.host.d.ts +0 -22
- package/types/services/api-service.d.ts +0 -10
- /package/cjs/http/{helpers → utils}/concat-readable.js +0 -0
- /package/cjs/http/{helpers → utils}/convert-to-headers.js +0 -0
- /package/esm/http/{helpers → utils}/concat-readable.js +0 -0
- /package/types/{services → helpers}/logger.d.ts +0 -0
- /package/types/http/{helpers → utils}/common.d.ts +0 -0
- /package/types/http/{helpers → utils}/concat-readable.d.ts +0 -0
- /package/types/http/{helpers → utils}/convert-to-headers.d.ts +0 -0
- /package/types/http/{helpers → utils}/convert-to-raw-headers.d.ts +0 -0
- /package/types/http/{helpers → utils}/match-known-fields.d.ts +0 -0
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
Some parts of this file contains codes from open source express library
|
|
3
3
|
https://github.com/expressjs
|
|
4
4
|
*/
|
|
5
|
+
import { HttpStatusCode } from '@opra/common';
|
|
5
6
|
import contentDisposition from 'content-disposition';
|
|
6
7
|
import contentType from 'content-type';
|
|
7
8
|
import cookie from 'cookie';
|
|
@@ -11,23 +12,8 @@ import mime from 'mime-types';
|
|
|
11
12
|
import path from 'path';
|
|
12
13
|
import { toString } from 'putil-varhelpers';
|
|
13
14
|
import vary from 'vary';
|
|
14
|
-
import { HttpStatusCode, isStream, mergePrototype } from '@opra/common';
|
|
15
|
-
import { HttpOutgoingMessageHost } from './impl/http-outgoing-message.host.js';
|
|
16
15
|
const charsetRegExp = /;\s*charset\s*=/;
|
|
17
|
-
|
|
18
|
-
return v && typeof v.getHeaders === 'function' && isStream(v);
|
|
19
|
-
}
|
|
20
|
-
export var HttpServerResponse;
|
|
21
|
-
(function (HttpServerResponse) {
|
|
22
|
-
function from(instance) {
|
|
23
|
-
if (!isHttpIncomingMessage(instance))
|
|
24
|
-
instance = new HttpOutgoingMessageHost(instance);
|
|
25
|
-
mergePrototype(instance, HttpServerResponseHost.prototype);
|
|
26
|
-
return instance;
|
|
27
|
-
}
|
|
28
|
-
HttpServerResponse.from = from;
|
|
29
|
-
})(HttpServerResponse || (HttpServerResponse = {}));
|
|
30
|
-
class HttpServerResponseHost {
|
|
16
|
+
export class HttpOutgoingHost {
|
|
31
17
|
attachment(filename) {
|
|
32
18
|
if (filename)
|
|
33
19
|
this.contentType(path.extname(filename));
|
|
@@ -35,9 +21,7 @@ class HttpServerResponseHost {
|
|
|
35
21
|
return this;
|
|
36
22
|
}
|
|
37
23
|
contentType(type) {
|
|
38
|
-
const ct = type.indexOf('/') === -1
|
|
39
|
-
? mime.lookup(type)
|
|
40
|
-
: type;
|
|
24
|
+
const ct = type.indexOf('/') === -1 ? mime.lookup(type) : type;
|
|
41
25
|
this.setHeader('Content-Type', ct);
|
|
42
26
|
return this;
|
|
43
27
|
}
|
|
@@ -50,9 +34,7 @@ class HttpServerResponseHost {
|
|
|
50
34
|
return this;
|
|
51
35
|
}
|
|
52
36
|
const fieldLower = field.toLowerCase();
|
|
53
|
-
let value = Array.isArray(val)
|
|
54
|
-
? val.map(String)
|
|
55
|
-
: (val ? String(val) : '');
|
|
37
|
+
let value = Array.isArray(val) ? val.map(String) : val ? String(val) : '';
|
|
56
38
|
// add charset to content-type
|
|
57
39
|
if (fieldLower === 'content-type') {
|
|
58
40
|
if (Array.isArray(value)) {
|
|
@@ -71,15 +53,13 @@ class HttpServerResponseHost {
|
|
|
71
53
|
const opts = {
|
|
72
54
|
expires: new Date(1),
|
|
73
55
|
path: '/',
|
|
74
|
-
...options
|
|
56
|
+
...options,
|
|
75
57
|
};
|
|
76
58
|
return this.cookie(name, '', opts);
|
|
77
59
|
}
|
|
78
60
|
cookie(name, value, options) {
|
|
79
61
|
const opts = { ...options };
|
|
80
|
-
let val = typeof value === 'object'
|
|
81
|
-
? 'j:' + JSON.stringify(value)
|
|
82
|
-
: String(value);
|
|
62
|
+
let val = typeof value === 'object' ? 'j:' + JSON.stringify(value) : String(value);
|
|
83
63
|
if (opts.signed) {
|
|
84
64
|
const secret = opts.secret || this.req?.secret;
|
|
85
65
|
if (!secret)
|
|
@@ -180,7 +160,7 @@ class HttpServerResponseHost {
|
|
|
180
160
|
if (req?.fresh)
|
|
181
161
|
this.statusCode = 304;
|
|
182
162
|
// strip irrelevant headers
|
|
183
|
-
if (
|
|
163
|
+
if (this.statusCode === 204 || this.statusCode === 304) {
|
|
184
164
|
this.removeHeader('Content-Type');
|
|
185
165
|
this.removeHeader('Content-Length');
|
|
186
166
|
this.removeHeader('Transfer-Encoding');
|
|
@@ -1,34 +1,36 @@
|
|
|
1
1
|
import { EventEmitter } from 'events';
|
|
2
2
|
import formidable from 'formidable';
|
|
3
3
|
import fs from 'fs/promises';
|
|
4
|
-
export class
|
|
5
|
-
constructor(options) {
|
|
4
|
+
export class MultipartReader extends EventEmitter {
|
|
5
|
+
constructor(incoming, options) {
|
|
6
6
|
super();
|
|
7
|
+
this._started = false;
|
|
7
8
|
this._cancelled = false;
|
|
8
9
|
this._items = [];
|
|
9
10
|
this._stack = [];
|
|
10
11
|
this.setMaxListeners(1000);
|
|
11
|
-
|
|
12
|
+
this._incoming = incoming;
|
|
13
|
+
const form = (this._form = formidable({
|
|
12
14
|
...options,
|
|
13
|
-
filter: (part) =>
|
|
14
|
-
|
|
15
|
-
}
|
|
16
|
-
});
|
|
15
|
+
filter: (part) => !this._cancelled && (!options?.filter || options.filter(part)),
|
|
16
|
+
}));
|
|
17
17
|
form.once('error', () => {
|
|
18
18
|
this._cancelled = true;
|
|
19
19
|
if (this.listenerCount('error') > 0)
|
|
20
20
|
this.emit('error');
|
|
21
21
|
});
|
|
22
|
-
form.on('field', (
|
|
23
|
-
const item = { field, value };
|
|
22
|
+
form.on('field', (fieldName, value) => {
|
|
23
|
+
const item = { fieldName, type: 'field', value };
|
|
24
24
|
this._items.push(item);
|
|
25
25
|
this._stack.push(item);
|
|
26
|
+
this.emit('field', item);
|
|
26
27
|
this.emit('item', item);
|
|
27
28
|
});
|
|
28
|
-
form.on('file', (
|
|
29
|
-
const item = {
|
|
29
|
+
form.on('file', (fieldName, file) => {
|
|
30
|
+
const item = { fieldName, type: 'file', file };
|
|
30
31
|
this._items.push(item);
|
|
31
32
|
this._stack.push(item);
|
|
33
|
+
this.emit('file', item);
|
|
32
34
|
this.emit('item', item);
|
|
33
35
|
});
|
|
34
36
|
}
|
|
@@ -44,7 +46,7 @@ export class MultipartIterator extends EventEmitter {
|
|
|
44
46
|
if (this._form.ended)
|
|
45
47
|
return resolve(undefined);
|
|
46
48
|
this.once('item', () => resolve(this._stack.shift()));
|
|
47
|
-
this.once('error',
|
|
49
|
+
this.once('error', e => reject(e));
|
|
48
50
|
});
|
|
49
51
|
}
|
|
50
52
|
getAll() {
|
|
@@ -64,6 +66,8 @@ export class MultipartIterator extends EventEmitter {
|
|
|
64
66
|
this.resume();
|
|
65
67
|
}
|
|
66
68
|
resume() {
|
|
69
|
+
if (!this._started)
|
|
70
|
+
this._form.parse(this._incoming, () => undefined);
|
|
67
71
|
if (this._form.req)
|
|
68
72
|
this._form.resume();
|
|
69
73
|
}
|
|
@@ -71,10 +75,9 @@ export class MultipartIterator extends EventEmitter {
|
|
|
71
75
|
if (this._form.req)
|
|
72
76
|
this._form.pause();
|
|
73
77
|
}
|
|
74
|
-
async
|
|
78
|
+
async deleteTempFiles() {
|
|
75
79
|
const promises = [];
|
|
76
|
-
this._items
|
|
77
|
-
.forEach(item => {
|
|
80
|
+
this._items.forEach(item => {
|
|
78
81
|
if (!item.file)
|
|
79
82
|
return;
|
|
80
83
|
const file = item.file;
|
|
@@ -82,17 +85,10 @@ export class MultipartIterator extends EventEmitter {
|
|
|
82
85
|
if (file._writeStream.closed)
|
|
83
86
|
return resolve();
|
|
84
87
|
file._writeStream.once('close', resolve);
|
|
85
|
-
})
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
return 0;
|
|
89
|
-
}));
|
|
88
|
+
})
|
|
89
|
+
.then(() => fs.unlink(file.filepath))
|
|
90
|
+
.then(() => 0));
|
|
90
91
|
});
|
|
91
92
|
return Promise.allSettled(promises);
|
|
92
93
|
}
|
|
93
|
-
static async create(incoming, options) {
|
|
94
|
-
const out = new MultipartIterator(options);
|
|
95
|
-
await out._form.parse(incoming);
|
|
96
|
-
return out;
|
|
97
|
-
}
|
|
98
94
|
}
|
|
@@ -1,23 +1,18 @@
|
|
|
1
|
-
/*
|
|
2
|
-
This file contains code blocks from open source NodeJs project
|
|
3
|
-
https://github.com/nodejs/
|
|
4
|
-
*/
|
|
5
|
-
import { Duplex, Readable } from 'stream';
|
|
6
|
-
import { HTTPParser } from '@browsery/http-parser';
|
|
7
1
|
import { isAsyncIterable, isIterable } from '@opra/common';
|
|
8
|
-
import {
|
|
9
|
-
import { convertToHeaders, convertToHeadersDistinct } from '../
|
|
10
|
-
import { convertToRawHeaders } from '../
|
|
2
|
+
import { Duplex, Readable } from 'stream';
|
|
3
|
+
import { convertToHeaders, convertToHeadersDistinct } from '../utils/convert-to-headers.js';
|
|
4
|
+
import { convertToRawHeaders } from '../utils/convert-to-raw-headers.js';
|
|
11
5
|
export const CRLF = Buffer.from('\r\n');
|
|
12
6
|
export const kHeaders = Symbol.for('kHeaders');
|
|
13
7
|
export const kHeadersDistinct = Symbol.for('kHeadersDistinct');
|
|
14
8
|
export const kTrailers = Symbol.for('kTrailers');
|
|
15
9
|
export const kTrailersDistinct = Symbol.for('kTrailersDistinct');
|
|
10
|
+
export const kHttpParser = Symbol.for('kHttpParser');
|
|
16
11
|
/**
|
|
17
12
|
*
|
|
18
|
-
* @class
|
|
13
|
+
* @class NodeIncomingMessageHost
|
|
19
14
|
*/
|
|
20
|
-
export class
|
|
15
|
+
export class NodeIncomingMessageHost extends Duplex {
|
|
21
16
|
constructor(init) {
|
|
22
17
|
super();
|
|
23
18
|
this.rawHeaders = [];
|
|
@@ -38,20 +33,24 @@ export class HttpIncomingMessageHost extends Duplex {
|
|
|
38
33
|
else
|
|
39
34
|
this.body = Buffer.from(JSON.stringify(init.body), 'utf-8');
|
|
40
35
|
}
|
|
41
|
-
if (init.headers)
|
|
36
|
+
if (init.headers) {
|
|
42
37
|
this.rawHeaders = Array.isArray(init.headers) ? init.headers : convertToRawHeaders(init.headers);
|
|
43
|
-
|
|
38
|
+
}
|
|
39
|
+
if (init.trailers) {
|
|
44
40
|
this.rawTrailers = Array.isArray(init.trailers) ? init.trailers : convertToRawHeaders(init.trailers);
|
|
41
|
+
}
|
|
45
42
|
this.ip = init.ip || '';
|
|
46
43
|
this.ips = init.ips || (this.ip ? [this.ip] : []);
|
|
47
44
|
if (this.body && !this.headers['content-length'])
|
|
48
45
|
this.headers['content-length'] = String(this.body.length);
|
|
46
|
+
if (init.params)
|
|
47
|
+
this.params = init.params;
|
|
48
|
+
if (init.cookies)
|
|
49
|
+
this.cookies = init.cookies;
|
|
49
50
|
}
|
|
50
51
|
}
|
|
51
52
|
get httpVersion() {
|
|
52
|
-
return this.httpVersionMajor
|
|
53
|
-
? this.httpVersionMajor + '.' + this.httpVersionMinor
|
|
54
|
-
: '';
|
|
53
|
+
return this.httpVersionMajor ? this.httpVersionMajor + '.' + this.httpVersionMinor : '';
|
|
55
54
|
}
|
|
56
55
|
get headers() {
|
|
57
56
|
if (!this[kHeaders])
|
|
@@ -95,50 +94,12 @@ export class HttpIncomingMessageHost extends Duplex {
|
|
|
95
94
|
}
|
|
96
95
|
const chunk = this._readStream.read(size);
|
|
97
96
|
this.push(chunk);
|
|
98
|
-
// this.push(null);s
|
|
99
97
|
}
|
|
100
98
|
_write(chunk, encoding, callback) {
|
|
101
|
-
const error = this
|
|
99
|
+
const error = this[kHttpParser]?.execute(chunk);
|
|
102
100
|
if (error && typeof error === 'object')
|
|
103
101
|
callback(error);
|
|
104
102
|
else
|
|
105
103
|
callback();
|
|
106
104
|
}
|
|
107
|
-
static from(iterable) {
|
|
108
|
-
if (typeof iterable === 'object' && !(isIterable(iterable) || isAsyncIterable(iterable)))
|
|
109
|
-
return new HttpIncomingMessageHost(iterable);
|
|
110
|
-
const msg = new HttpIncomingMessageHost();
|
|
111
|
-
const parser = msg._httpParser = new HTTPParser(HTTPParser.REQUEST);
|
|
112
|
-
let bodyChunks;
|
|
113
|
-
parser[HTTPParser.kOnHeadersComplete] = (info) => {
|
|
114
|
-
msg.httpVersionMajor = info.versionMajor;
|
|
115
|
-
msg.httpVersionMinor = info.versionMinor;
|
|
116
|
-
msg.rawHeaders = info.headers;
|
|
117
|
-
msg.method = HTTPParser.methods[info.method];
|
|
118
|
-
msg.url = info.url;
|
|
119
|
-
};
|
|
120
|
-
parser[HTTPParser.kOnHeaders] = (trailers) => {
|
|
121
|
-
msg.rawTrailers = trailers;
|
|
122
|
-
};
|
|
123
|
-
parser[HTTPParser.kOnBody] = (chunk, offset, length) => {
|
|
124
|
-
bodyChunks = bodyChunks || [];
|
|
125
|
-
bodyChunks.push(chunk.subarray(offset, offset + length));
|
|
126
|
-
};
|
|
127
|
-
parser[HTTPParser.kOnMessageComplete] = () => {
|
|
128
|
-
msg.complete = true;
|
|
129
|
-
if (bodyChunks)
|
|
130
|
-
msg.body = Buffer.concat(bodyChunks);
|
|
131
|
-
};
|
|
132
|
-
const readable = concatReadable(Readable.from(iterable), Readable.from(CRLF));
|
|
133
|
-
msg.once('finish', () => parser.finish());
|
|
134
|
-
readable.pipe(msg);
|
|
135
|
-
return msg;
|
|
136
|
-
}
|
|
137
|
-
static async fromAsync(iterable) {
|
|
138
|
-
return new Promise((resolve, reject) => {
|
|
139
|
-
const msg = this.from(iterable);
|
|
140
|
-
msg.once('finish', () => resolve(msg));
|
|
141
|
-
msg.once('error', (error) => reject(error));
|
|
142
|
-
});
|
|
143
|
-
}
|
|
144
105
|
}
|
|
@@ -3,15 +3,15 @@
|
|
|
3
3
|
https://github.com/nodejs/
|
|
4
4
|
*/
|
|
5
5
|
import { Duplex } from 'stream';
|
|
6
|
-
import { validateHeaderName, validateHeaderValue, validateString } from '../
|
|
6
|
+
import { validateHeaderName, validateHeaderValue, validateString } from '../utils/common.js';
|
|
7
7
|
export const kOutHeaders = Symbol.for('kOutHeaders');
|
|
8
8
|
export const kOutTrailers = Symbol.for('kOutTrailers');
|
|
9
9
|
// noinspection JSUnusedLocalSymbols
|
|
10
10
|
/**
|
|
11
11
|
*
|
|
12
|
-
* @class
|
|
12
|
+
* @class NodeOutgoingMessageHost
|
|
13
13
|
*/
|
|
14
|
-
export class
|
|
14
|
+
export class NodeOutgoingMessageHost extends Duplex {
|
|
15
15
|
constructor(init) {
|
|
16
16
|
super();
|
|
17
17
|
this._headersSent = false;
|
|
@@ -64,8 +64,7 @@ export class HttpOutgoingMessageHost extends Duplex {
|
|
|
64
64
|
}
|
|
65
65
|
addTrailers(headers) {
|
|
66
66
|
if (headers && typeof headers === 'object') {
|
|
67
|
-
const entries = typeof headers.entries === 'function'
|
|
68
|
-
? headers.entries() : Object.entries(headers);
|
|
67
|
+
const entries = typeof headers.entries === 'function' ? headers.entries() : Object.entries(headers);
|
|
69
68
|
let trailers = this[kOutTrailers];
|
|
70
69
|
if (trailers == null)
|
|
71
70
|
this[kOutTrailers] = trailers = { __proto__: null };
|
|
@@ -78,6 +77,9 @@ export class HttpOutgoingMessageHost extends Duplex {
|
|
|
78
77
|
}
|
|
79
78
|
throw new TypeError('Invalid "headers" argument. Value must be an object or raw headers array');
|
|
80
79
|
}
|
|
80
|
+
flushHeaders() {
|
|
81
|
+
// nothing to do
|
|
82
|
+
}
|
|
81
83
|
setHeader(name, value) {
|
|
82
84
|
if (this.headersSent)
|
|
83
85
|
throw new Error(`Cannot set headers after they are sent to the client`);
|
|
@@ -93,8 +95,7 @@ export class HttpOutgoingMessageHost extends Duplex {
|
|
|
93
95
|
if (this.headersSent)
|
|
94
96
|
throw new Error(`Cannot set headers after they are sent to the client`);
|
|
95
97
|
if (headers && typeof headers === 'object' && !Array.isArray(headers)) {
|
|
96
|
-
const entries = typeof headers.entries === 'function'
|
|
97
|
-
? headers.entries() : Object.entries(headers);
|
|
98
|
+
const entries = typeof headers.entries === 'function' ? headers.entries() : Object.entries(headers);
|
|
98
99
|
for (const entry of entries) {
|
|
99
100
|
this.setHeader(entry[0], entry[1]);
|
|
100
101
|
}
|
|
@@ -142,8 +143,7 @@ export class HttpOutgoingMessageHost extends Duplex {
|
|
|
142
143
|
}
|
|
143
144
|
hasHeader(name) {
|
|
144
145
|
validateString(name);
|
|
145
|
-
return this[kOutHeaders] != null &&
|
|
146
|
-
!!this[kOutHeaders][name.toLowerCase()];
|
|
146
|
+
return this[kOutHeaders] != null && !!this[kOutHeaders][name.toLowerCase()];
|
|
147
147
|
}
|
|
148
148
|
removeHeader(name) {
|
|
149
149
|
validateString(name);
|
|
@@ -188,7 +188,4 @@ export class HttpOutgoingMessageHost extends Duplex {
|
|
|
188
188
|
//
|
|
189
189
|
return this;
|
|
190
190
|
}
|
|
191
|
-
static from(init) {
|
|
192
|
-
return new HttpOutgoingMessageHost(init);
|
|
193
|
-
}
|
|
194
191
|
}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { mergePrototype } from '@opra/common';
|
|
2
|
+
import { isHttpIncoming, isNodeIncomingMessage } from '../../type-guards.js';
|
|
3
|
+
import { HttpIncomingHost } from '../impl/http-incoming.host.js';
|
|
4
|
+
import { NodeIncomingMessage } from './node-incoming-message.interface.js';
|
|
5
|
+
/**
|
|
6
|
+
* @namespace HttpIncoming
|
|
7
|
+
*/
|
|
8
|
+
export var HttpIncoming;
|
|
9
|
+
(function (HttpIncoming) {
|
|
10
|
+
function from(instance) {
|
|
11
|
+
if (isHttpIncoming(instance))
|
|
12
|
+
return instance;
|
|
13
|
+
if (!isNodeIncomingMessage(instance))
|
|
14
|
+
instance = NodeIncomingMessage.from(instance);
|
|
15
|
+
mergePrototype(instance, HttpIncomingHost.prototype);
|
|
16
|
+
const req = instance;
|
|
17
|
+
req.baseUrl = req.baseUrl || '';
|
|
18
|
+
req.params = req.params || {};
|
|
19
|
+
return req;
|
|
20
|
+
}
|
|
21
|
+
HttpIncoming.from = from;
|
|
22
|
+
})(HttpIncoming || (HttpIncoming = {}));
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { mergePrototype } from '@opra/common';
|
|
2
|
+
import { isHttpOutgoing, isNodeOutgoingMessage } from '../../type-guards.js';
|
|
3
|
+
import { HttpOutgoingHost } from '../impl/http-outgoing.host.js';
|
|
4
|
+
import { NodeOutgoingMessage } from './node-outgoing-message.interface.js';
|
|
5
|
+
/**
|
|
6
|
+
* @namespace HttpIncoming
|
|
7
|
+
*/
|
|
8
|
+
export var HttpOutgoing;
|
|
9
|
+
(function (HttpOutgoing) {
|
|
10
|
+
function from(instance) {
|
|
11
|
+
if (isHttpOutgoing(instance))
|
|
12
|
+
return instance;
|
|
13
|
+
if (!isNodeOutgoingMessage(instance))
|
|
14
|
+
instance = NodeOutgoingMessage.from(instance);
|
|
15
|
+
mergePrototype(instance, HttpOutgoingHost.prototype);
|
|
16
|
+
return instance;
|
|
17
|
+
}
|
|
18
|
+
HttpOutgoing.from = from;
|
|
19
|
+
})(HttpOutgoing || (HttpOutgoing = {}));
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import { HTTPParser } from '@browsery/http-parser';
|
|
2
|
+
import { isAsyncIterable, isIterable } from '@opra/common';
|
|
3
|
+
import { Readable } from 'stream';
|
|
4
|
+
import { CRLF, kHttpParser, NodeIncomingMessageHost } from '../impl/node-incoming-message.host.js';
|
|
5
|
+
import { concatReadable } from '../utils/concat-readable.js';
|
|
6
|
+
/**
|
|
7
|
+
*
|
|
8
|
+
* @namespace NodeIncomingMessage
|
|
9
|
+
*/
|
|
10
|
+
export var NodeIncomingMessage;
|
|
11
|
+
(function (NodeIncomingMessage) {
|
|
12
|
+
/**
|
|
13
|
+
* Creates a new NodeIncomingMessage from given argument
|
|
14
|
+
* @param iterable
|
|
15
|
+
*/
|
|
16
|
+
function from(iterable) {
|
|
17
|
+
if (typeof iterable === 'object' && !(isIterable(iterable) || isAsyncIterable(iterable))) {
|
|
18
|
+
return new NodeIncomingMessageHost(iterable);
|
|
19
|
+
}
|
|
20
|
+
const msg = new NodeIncomingMessageHost();
|
|
21
|
+
const parser = (msg[kHttpParser] = new HTTPParser(HTTPParser.REQUEST));
|
|
22
|
+
let bodyChunks;
|
|
23
|
+
parser[HTTPParser.kOnHeadersComplete] = (info) => {
|
|
24
|
+
msg.httpVersionMajor = info.versionMajor;
|
|
25
|
+
msg.httpVersionMinor = info.versionMinor;
|
|
26
|
+
msg.rawHeaders = info.headers;
|
|
27
|
+
msg.method = HTTPParser.methods[info.method];
|
|
28
|
+
msg.url = info.url;
|
|
29
|
+
msg.emit('headers');
|
|
30
|
+
};
|
|
31
|
+
parser[HTTPParser.kOnHeaders] = (trailers) => {
|
|
32
|
+
msg.rawTrailers = trailers;
|
|
33
|
+
};
|
|
34
|
+
parser[HTTPParser.kOnBody] = (chunk, offset, length) => {
|
|
35
|
+
bodyChunks = bodyChunks || [];
|
|
36
|
+
bodyChunks.push(chunk.subarray(offset, offset + length));
|
|
37
|
+
};
|
|
38
|
+
const readable = concatReadable(Readable.from(iterable), Readable.from(CRLF));
|
|
39
|
+
msg.once('finish', () => {
|
|
40
|
+
parser.finish();
|
|
41
|
+
msg.complete = true;
|
|
42
|
+
if (bodyChunks)
|
|
43
|
+
msg.body = Buffer.concat(bodyChunks);
|
|
44
|
+
});
|
|
45
|
+
readable.pipe(msg);
|
|
46
|
+
return msg;
|
|
47
|
+
}
|
|
48
|
+
NodeIncomingMessage.from = from;
|
|
49
|
+
/**
|
|
50
|
+
* Creates a new NodeIncomingMessage from given argument
|
|
51
|
+
* @param iterable
|
|
52
|
+
*/
|
|
53
|
+
async function fromAsync(iterable) {
|
|
54
|
+
return new Promise((resolve, reject) => {
|
|
55
|
+
const msg = from(iterable);
|
|
56
|
+
msg.once('finish', () => resolve(msg));
|
|
57
|
+
msg.once('error', error => reject(error));
|
|
58
|
+
});
|
|
59
|
+
}
|
|
60
|
+
NodeIncomingMessage.fromAsync = fromAsync;
|
|
61
|
+
})(NodeIncomingMessage || (NodeIncomingMessage = {}));
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { NodeOutgoingMessageHost } from '../impl/node-outgoing-message.host.js';
|
|
2
|
+
/**
|
|
3
|
+
*
|
|
4
|
+
* @namespace NodeOutgoingMessage
|
|
5
|
+
*/
|
|
6
|
+
export var NodeOutgoingMessage;
|
|
7
|
+
(function (NodeOutgoingMessage) {
|
|
8
|
+
function from(init) {
|
|
9
|
+
return new NodeOutgoingMessageHost(init);
|
|
10
|
+
}
|
|
11
|
+
NodeOutgoingMessage.from = from;
|
|
12
|
+
})(NodeOutgoingMessage || (NodeOutgoingMessage = {}));
|