objective-http 1.0.3 → 1.0.4

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/package.json CHANGED
@@ -1 +1 @@
1
- {"name":"objective-http","version":"1.0.3","description":"Proxy classes for creating a http server","keywords":["web","web-server","http","http-server","oop"],"author":{"name":"volatilization","email":"volatilization@yandex.ru"},"repository":{"url":"git+https://github.com/volatilization/objective-http.git"},"license":"LGPL-3.0-only","main":"src/js/index.js"}
1
+ {"name":"objective-http","version":"1.0.4","description":"Proxy classes for creating a http server","keywords":["web","web-server","http","http-server","oop"],"author":{"name":"volatilization","email":"volatilization@yandex.ru"},"repository":{"url":"git+https://github.com/volatilization/objective-http.git"},"license":"LGPL-3.0-only","main":"src/js/index.js"}
@@ -16,10 +16,8 @@ module.exports = class ClusteredServer {
16
16
  }
17
17
 
18
18
  } else {
19
- await this.#origin.start();
19
+ return new ClusteredServer(await this.#origin.start(), this.#cluster, this.#options);
20
20
  }
21
-
22
- return this;
23
21
  }
24
22
 
25
23
  options() {
@@ -8,13 +8,22 @@ module.exports = class LoggedServer {
8
8
  }
9
9
 
10
10
  async start() {
11
- await this.#origin.start();
11
+ const server = await this.#origin.start();
12
12
 
13
13
  this.#logger.debug(`HttpServer is running at port: ${this.#origin.options().port}`);
14
14
 
15
- return this;
15
+ return new LoggedServer(server, this.#logger);
16
16
  }
17
17
 
18
+ async stop() {
19
+ const server = await this.#origin.stop();
20
+
21
+ this.#logger.debug(`HttpServer at port: ${this.#origin.options().port} is stopped`);
22
+
23
+ return new LoggedServer(server, this.#logger);
24
+ }
25
+
26
+
18
27
  options() {
19
28
  return this.#origin.options();
20
29
  }
@@ -4,53 +4,74 @@ module.exports = class HttpServer {
4
4
  #response;
5
5
  #endpoints;
6
6
  #options;
7
+ #server;
7
8
 
8
- constructor(http, request, response, endpoints, options) {
9
+ constructor(http, request, response, endpoints, options, server) {
9
10
  this.#http = http;
10
11
  this.#request = request;
11
12
  this.#response = response;
12
13
  this.#endpoints = endpoints;
13
14
  this.#options = options;
15
+ this.#server = server;
14
16
  }
15
17
 
16
18
  start() {
17
- return new Promise(resolve => {
18
- this.#http
19
- .createServer(async (requestStream, responseStream) => {
20
- try {
21
- return await (this.#response
22
- .copy(responseStream, await this.#endpoints
23
- .handle(await (this.#request
24
- .copy(requestStream))
25
- .flush())))
26
- .flush();
19
+ const server = this.#http.createServer(async (requestStream, responseStream) => {
20
+ try {
21
+ return await (this.#response
22
+ .copy(responseStream, await this.#endpoints
23
+ .handle(await (this.#request
24
+ .copy(requestStream))
25
+ .flush())))
26
+ .flush();
27
+
28
+ } catch (e) {
29
+ if (e.cause === 'INVALID_REQUEST') {
30
+ return await (this.#response
31
+ .copy(responseStream, {
32
+ statusCode: 400,
33
+ body: e.message
34
+ }))
35
+ .flush();
36
+ }
37
+
38
+ return await (this.#response
39
+ .copy(responseStream, {
40
+ statusCode: 500,
41
+ body: 'Unexpected server error.'
42
+ }))
43
+ .flush();
44
+ }
45
+ });
27
46
 
28
- } catch (e) {
29
- if (e.cause === 'INVALID_REQUEST') {
30
- return this.#response
31
- .copy(responseStream, {
32
- statusCode: 400,
33
- body: e.message
34
- })
35
- .flush();
36
- }
47
+ return new Promise(resolve => {
48
+ server.listen(
49
+ this.#options,
50
+ () => resolve(new HttpServer(
51
+ this.#http,
52
+ this.#request,
53
+ this.#response,
54
+ this.#endpoints,
55
+ this.#options,
56
+ server))
57
+ );
58
+ });
59
+ }
37
60
 
38
- return this.#response
39
- .copy(responseStream, {
40
- statusCode: 500,
41
- body: 'Unexpected server error.'
42
- })
43
- .flush();
44
- }
45
- })
46
- .listen(
47
- {port: this.#options.port},
48
- () => resolve(this)
49
- );
61
+ stop() {
62
+ return new Promise(resolve => {
63
+ this.#server.close(
64
+ () => resolve(new HttpServer(
65
+ this.#http,
66
+ this.#request,
67
+ this.#response,
68
+ this.#endpoints,
69
+ this.#options))
70
+ );
50
71
  });
51
72
  }
52
73
 
53
74
  options() {
54
75
  return this.#options;
55
76
  }
56
- }
77
+ };
@@ -12,27 +12,24 @@ module.exports = class InputRequest {
12
12
  }
13
13
 
14
14
  flush() {
15
- return new Promise((resolve, reject) => {
16
- try {
17
- this.#inputStream.on('error', (e) => reject(e));
15
+ return new Promise((resolve) => {
16
+ this.#inputStream.once('error', (e) => {
17
+ throw new Error(e.message, {cause: 'INVALID_REQUEST'});
18
+ });
18
19
 
19
- if (!this.#isChunkedInputStream(this.#inputStream)) {
20
- resolve(new InputRequest(
21
- this.#inputStream,
22
- this.#extractOptionsFromInputStream(this.#inputStream)
23
- ));
24
- }
25
-
26
- let chunks = [];
27
- this.#inputStream.on('data', (chunk) => chunks.push(chunk));
28
- this.#inputStream.on('end', () => resolve(new InputRequest(
20
+ if (!this.#isChunkedInputStream(this.#inputStream)) {
21
+ return resolve(new InputRequest(
29
22
  this.#inputStream,
30
- {... this.#extractOptionsFromInputStream(this.#inputStream), body: Buffer.concat(chunks)}
31
- )));
32
-
33
- } catch (e) {
34
- reject(e);
23
+ this.#extractOptionsFromInputStream(this.#inputStream)
24
+ ));
35
25
  }
26
+
27
+ let chunks = [];
28
+ this.#inputStream.on('data', (chunk) => chunks.push(chunk));
29
+ this.#inputStream.on('end', () => resolve(new InputRequest(
30
+ this.#inputStream,
31
+ {... this.#extractOptionsFromInputStream(this.#inputStream), body: Buffer.concat(chunks)}
32
+ )));
36
33
  });
37
34
  }
38
35
 
@@ -51,6 +48,10 @@ module.exports = class InputRequest {
51
48
  return this.#options.body;
52
49
  }
53
50
 
51
+ headers() {
52
+ return this.#options.headers;
53
+ }
54
+
54
55
  #isChunkedInputStream(inputStream) {
55
56
  return ['POST', 'PUT'].some(method => method === inputStream.method.toString().toUpperCase());
56
57
  }
@@ -32,7 +32,16 @@ module.exports = class JsonInputRequest {
32
32
  return null;
33
33
  }
34
34
 
35
- return JSON.parse(this.#origin.body().toString());
35
+ try {
36
+ return JSON.parse(this.#origin.body().toString());
37
+
38
+ } catch (e) {
39
+ throw new Error('Wrong body format. Only JSON accepted.', {cause: 'INVALID_REQUEST'});
40
+ }
41
+ }
42
+
43
+ headers() {
44
+ return this.#origin.headers();
36
45
  }
37
46
 
38
47
  #useChunkMethod(requestMethod) {
@@ -30,4 +30,8 @@ module.exports = class LoggedInputRequest {
30
30
  body() {
31
31
  return this.#origin.body();
32
32
  }
33
+
34
+ headers() {
35
+ return this.#origin.headers();
36
+ }
33
37
  }
@@ -31,6 +31,10 @@ module.exports = class OutputResponse {
31
31
  }
32
32
 
33
33
  #mergeOptions(existedOptions, newOptions) {
34
+ if (newOptions == null) {
35
+ return existedOptions;
36
+ }
37
+
34
38
  if (newOptions.statusCode != null) {
35
39
  existedOptions.statusCode = newOptions.statusCode;
36
40
  }
@@ -1,21 +0,0 @@
1
- name: Publish release
2
-
3
- on:
4
- release:
5
- types: [published]
6
-
7
- jobs:
8
- publish-npm:
9
- runs-on: ubuntu-latest
10
- steps:
11
- - uses: actions/checkout@v3
12
- - uses: actions/setup-node@v3
13
- with:
14
- node-version: 21
15
- registry-url: https://registry.npmjs.org/
16
- - run: npm run prepareToPublish
17
- env:
18
- RELEASE: ${{github.event.release.name}}
19
- - run: npm publish
20
- env:
21
- NODE_AUTH_TOKEN: ${{secrets.npm_token}}