graphql-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.
package/lib/use/koa.d.mts CHANGED
@@ -1,7 +1,8 @@
1
1
  /// <reference types="node" />
2
- import type { Middleware, Response } from 'koa';
2
+ import type { Middleware, ParameterizedContext, Response } from 'koa';
3
3
  import type { IncomingMessage } from 'http';
4
4
  import { HandlerOptions as RawHandlerOptions, OperationContext } from '../handler.mjs';
5
+ import { RequestParams } from '../common.mjs';
5
6
  /**
6
7
  * The context in the request for the handler.
7
8
  *
@@ -10,6 +11,51 @@ import { HandlerOptions as RawHandlerOptions, OperationContext } from '../handle
10
11
  export interface RequestContext {
11
12
  res: Response;
12
13
  }
14
+ /**
15
+ * The GraphQL over HTTP spec compliant request parser for an incoming GraphQL request.
16
+ *
17
+ * If the HTTP request _is not_ a [well-formatted GraphQL over HTTP request](https://graphql.github.io/graphql-over-http/draft/#sec-Request), the function will respond
18
+ * on Koa's `ParameterizedContext` response and return `null`.
19
+ *
20
+ * If the HTTP request _is_ a [well-formatted GraphQL over HTTP request](https://graphql.github.io/graphql-over-http/draft/#sec-Request), but is invalid or malformed,
21
+ * the function will throw an error and it is up to the user to handle and respond as they see fit.
22
+ *
23
+ * ```js
24
+ * import Koa from 'koa'; // yarn add koa
25
+ * import mount from 'koa-mount'; // yarn add koa-mount
26
+ * import { parseRequestParams } from 'graphql-http/lib/use/koa';
27
+ *
28
+ * const app = new Koa();
29
+ * app.use(
30
+ * mount('/', async (ctx) => {
31
+ * try {
32
+ * const maybeParams = await parseRequestParams(ctx);
33
+ * if (!maybeParams) {
34
+ * // not a well-formatted GraphQL over HTTP request,
35
+ * // parser responded and there's nothing else to do
36
+ * return;
37
+ * }
38
+ *
39
+ * // well-formatted GraphQL over HTTP request,
40
+ * // with valid parameters
41
+ * ctx.response.status = 200;
42
+ * ctx.body = JSON.stringify(maybeParams, null, ' ');
43
+ * } catch (err) {
44
+ * // well-formatted GraphQL over HTTP request,
45
+ * // but with invalid parameters
46
+ * ctx.response.status = 400;
47
+ * ctx.body = err.message;
48
+ * }
49
+ * }),
50
+ * );
51
+ *
52
+ * app.listen({ port: 4000 });
53
+ * console.log('Listening to port 4000');
54
+ * ```
55
+ *
56
+ * @category Server/koa
57
+ */
58
+ export declare function parseRequestParams(ctx: ParameterizedContext): Promise<RequestParams | null>;
13
59
  /**
14
60
  * Handler options when using the koa adapter.
15
61
  *
package/lib/use/koa.d.ts CHANGED
@@ -1,7 +1,8 @@
1
1
  /// <reference types="node" />
2
- import type { Middleware, Response } from 'koa';
2
+ import type { Middleware, ParameterizedContext, Response } from 'koa';
3
3
  import type { IncomingMessage } from 'http';
4
4
  import { HandlerOptions as RawHandlerOptions, OperationContext } from '../handler';
5
+ import { RequestParams } from '../common';
5
6
  /**
6
7
  * The context in the request for the handler.
7
8
  *
@@ -10,6 +11,51 @@ import { HandlerOptions as RawHandlerOptions, OperationContext } from '../handle
10
11
  export interface RequestContext {
11
12
  res: Response;
12
13
  }
14
+ /**
15
+ * The GraphQL over HTTP spec compliant request parser for an incoming GraphQL request.
16
+ *
17
+ * If the HTTP request _is not_ a [well-formatted GraphQL over HTTP request](https://graphql.github.io/graphql-over-http/draft/#sec-Request), the function will respond
18
+ * on Koa's `ParameterizedContext` response and return `null`.
19
+ *
20
+ * If the HTTP request _is_ a [well-formatted GraphQL over HTTP request](https://graphql.github.io/graphql-over-http/draft/#sec-Request), but is invalid or malformed,
21
+ * the function will throw an error and it is up to the user to handle and respond as they see fit.
22
+ *
23
+ * ```js
24
+ * import Koa from 'koa'; // yarn add koa
25
+ * import mount from 'koa-mount'; // yarn add koa-mount
26
+ * import { parseRequestParams } from 'graphql-http/lib/use/koa';
27
+ *
28
+ * const app = new Koa();
29
+ * app.use(
30
+ * mount('/', async (ctx) => {
31
+ * try {
32
+ * const maybeParams = await parseRequestParams(ctx);
33
+ * if (!maybeParams) {
34
+ * // not a well-formatted GraphQL over HTTP request,
35
+ * // parser responded and there's nothing else to do
36
+ * return;
37
+ * }
38
+ *
39
+ * // well-formatted GraphQL over HTTP request,
40
+ * // with valid parameters
41
+ * ctx.response.status = 200;
42
+ * ctx.body = JSON.stringify(maybeParams, null, ' ');
43
+ * } catch (err) {
44
+ * // well-formatted GraphQL over HTTP request,
45
+ * // but with invalid parameters
46
+ * ctx.response.status = 400;
47
+ * ctx.body = err.message;
48
+ * }
49
+ * }),
50
+ * );
51
+ *
52
+ * app.listen({ port: 4000 });
53
+ * console.log('Listening to port 4000');
54
+ * ```
55
+ *
56
+ * @category Server/koa
57
+ */
58
+ export declare function parseRequestParams(ctx: ParameterizedContext): Promise<RequestParams | null>;
13
59
  /**
14
60
  * Handler options when using the koa adapter.
15
61
  *
package/lib/use/koa.js CHANGED
@@ -1,7 +1,69 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.createHandler = void 0;
3
+ exports.createHandler = exports.parseRequestParams = void 0;
4
4
  const handler_1 = require("../handler");
5
+ /**
6
+ * The GraphQL over HTTP spec compliant request parser for an incoming GraphQL request.
7
+ *
8
+ * If the HTTP request _is not_ a [well-formatted GraphQL over HTTP request](https://graphql.github.io/graphql-over-http/draft/#sec-Request), the function will respond
9
+ * on Koa's `ParameterizedContext` response and return `null`.
10
+ *
11
+ * If the HTTP request _is_ a [well-formatted GraphQL over HTTP request](https://graphql.github.io/graphql-over-http/draft/#sec-Request), but is invalid or malformed,
12
+ * the function will throw an error and it is up to the user to handle and respond as they see fit.
13
+ *
14
+ * ```js
15
+ * import Koa from 'koa'; // yarn add koa
16
+ * import mount from 'koa-mount'; // yarn add koa-mount
17
+ * import { parseRequestParams } from 'graphql-http/lib/use/koa';
18
+ *
19
+ * const app = new Koa();
20
+ * app.use(
21
+ * mount('/', async (ctx) => {
22
+ * try {
23
+ * const maybeParams = await parseRequestParams(ctx);
24
+ * if (!maybeParams) {
25
+ * // not a well-formatted GraphQL over HTTP request,
26
+ * // parser responded and there's nothing else to do
27
+ * return;
28
+ * }
29
+ *
30
+ * // well-formatted GraphQL over HTTP request,
31
+ * // with valid parameters
32
+ * ctx.response.status = 200;
33
+ * ctx.body = JSON.stringify(maybeParams, null, ' ');
34
+ * } catch (err) {
35
+ * // well-formatted GraphQL over HTTP request,
36
+ * // but with invalid parameters
37
+ * ctx.response.status = 400;
38
+ * ctx.body = err.message;
39
+ * }
40
+ * }),
41
+ * );
42
+ *
43
+ * app.listen({ port: 4000 });
44
+ * console.log('Listening to port 4000');
45
+ * ```
46
+ *
47
+ * @category Server/koa
48
+ */
49
+ async function parseRequestParams(ctx) {
50
+ const rawReq = toRequest(ctx);
51
+ const paramsOrRes = await (0, handler_1.parseRequestParams)(rawReq);
52
+ if (!('query' in paramsOrRes)) {
53
+ const [body, init] = paramsOrRes;
54
+ ctx.body = body;
55
+ ctx.response.status = init.status;
56
+ ctx.response.message = init.statusText;
57
+ if (init.headers) {
58
+ for (const [name, value] of Object.entries(init.headers)) {
59
+ ctx.response.set(name, value);
60
+ }
61
+ }
62
+ return null;
63
+ }
64
+ return paramsOrRes;
65
+ }
66
+ exports.parseRequestParams = parseRequestParams;
5
67
  /**
6
68
  * Create a GraphQL over HTTP spec compliant request handler for
7
69
  * the Koa framework.
@@ -36,6 +98,7 @@ function createHandler(options) {
36
98
  }
37
99
  return new Promise((resolve) => {
38
100
  let body = '';
101
+ ctx.req.setEncoding('utf-8');
39
102
  ctx.req.on('data', (chunk) => (body += chunk));
40
103
  ctx.req.on('end', () => resolve(body));
41
104
  });
@@ -62,3 +125,24 @@ function createHandler(options) {
62
125
  };
63
126
  }
64
127
  exports.createHandler = createHandler;
128
+ function toRequest(ctx) {
129
+ return {
130
+ url: ctx.url,
131
+ method: ctx.method,
132
+ headers: ctx.headers,
133
+ body: () => {
134
+ if (ctx.body) {
135
+ // in case koa has a body parser
136
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
137
+ return ctx.body;
138
+ }
139
+ return new Promise((resolve) => {
140
+ let body = '';
141
+ ctx.req.on('data', (chunk) => (body += chunk));
142
+ ctx.req.on('end', () => resolve(body));
143
+ });
144
+ },
145
+ raw: ctx.req,
146
+ context: { res: ctx.response },
147
+ };
148
+ }
package/lib/use/koa.mjs CHANGED
@@ -1,4 +1,65 @@
1
- import { createHandler as createRawHandler, } from '../handler.mjs';
1
+ import { createHandler as createRawHandler, parseRequestParams as rawParseRequestParams, } from '../handler.mjs';
2
+ /**
3
+ * The GraphQL over HTTP spec compliant request parser for an incoming GraphQL request.
4
+ *
5
+ * If the HTTP request _is not_ a [well-formatted GraphQL over HTTP request](https://graphql.github.io/graphql-over-http/draft/#sec-Request), the function will respond
6
+ * on Koa's `ParameterizedContext` response and return `null`.
7
+ *
8
+ * If the HTTP request _is_ a [well-formatted GraphQL over HTTP request](https://graphql.github.io/graphql-over-http/draft/#sec-Request), but is invalid or malformed,
9
+ * the function will throw an error and it is up to the user to handle and respond as they see fit.
10
+ *
11
+ * ```js
12
+ * import Koa from 'koa'; // yarn add koa
13
+ * import mount from 'koa-mount'; // yarn add koa-mount
14
+ * import { parseRequestParams } from 'graphql-http/lib/use/koa';
15
+ *
16
+ * const app = new Koa();
17
+ * app.use(
18
+ * mount('/', async (ctx) => {
19
+ * try {
20
+ * const maybeParams = await parseRequestParams(ctx);
21
+ * if (!maybeParams) {
22
+ * // not a well-formatted GraphQL over HTTP request,
23
+ * // parser responded and there's nothing else to do
24
+ * return;
25
+ * }
26
+ *
27
+ * // well-formatted GraphQL over HTTP request,
28
+ * // with valid parameters
29
+ * ctx.response.status = 200;
30
+ * ctx.body = JSON.stringify(maybeParams, null, ' ');
31
+ * } catch (err) {
32
+ * // well-formatted GraphQL over HTTP request,
33
+ * // but with invalid parameters
34
+ * ctx.response.status = 400;
35
+ * ctx.body = err.message;
36
+ * }
37
+ * }),
38
+ * );
39
+ *
40
+ * app.listen({ port: 4000 });
41
+ * console.log('Listening to port 4000');
42
+ * ```
43
+ *
44
+ * @category Server/koa
45
+ */
46
+ export async function parseRequestParams(ctx) {
47
+ const rawReq = toRequest(ctx);
48
+ const paramsOrRes = await rawParseRequestParams(rawReq);
49
+ if (!('query' in paramsOrRes)) {
50
+ const [body, init] = paramsOrRes;
51
+ ctx.body = body;
52
+ ctx.response.status = init.status;
53
+ ctx.response.message = init.statusText;
54
+ if (init.headers) {
55
+ for (const [name, value] of Object.entries(init.headers)) {
56
+ ctx.response.set(name, value);
57
+ }
58
+ }
59
+ return null;
60
+ }
61
+ return paramsOrRes;
62
+ }
2
63
  /**
3
64
  * Create a GraphQL over HTTP spec compliant request handler for
4
65
  * the Koa framework.
@@ -33,6 +94,7 @@ export function createHandler(options) {
33
94
  }
34
95
  return new Promise((resolve) => {
35
96
  let body = '';
97
+ ctx.req.setEncoding('utf-8');
36
98
  ctx.req.on('data', (chunk) => (body += chunk));
37
99
  ctx.req.on('end', () => resolve(body));
38
100
  });
@@ -58,3 +120,24 @@ export function createHandler(options) {
58
120
  }
59
121
  };
60
122
  }
123
+ function toRequest(ctx) {
124
+ return {
125
+ url: ctx.url,
126
+ method: ctx.method,
127
+ headers: ctx.headers,
128
+ body: () => {
129
+ if (ctx.body) {
130
+ // in case koa has a body parser
131
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
132
+ return ctx.body;
133
+ }
134
+ return new Promise((resolve) => {
135
+ let body = '';
136
+ ctx.req.on('data', (chunk) => (body += chunk));
137
+ ctx.req.on('end', () => resolve(body));
138
+ });
139
+ },
140
+ raw: ctx.req,
141
+ context: { res: ctx.response },
142
+ };
143
+ }
@@ -1,5 +1,6 @@
1
1
  import type { HttpRequest, HttpResponse } from 'uWebSockets.js';
2
2
  import { HandlerOptions as RawHandlerOptions, OperationContext } from '../handler.mjs';
3
+ import { RequestParams } from '../common.mjs';
3
4
  /**
4
5
  * The context in the request for the handler.
5
6
  *
@@ -8,6 +9,60 @@ import { HandlerOptions as RawHandlerOptions, OperationContext } from '../handle
8
9
  export interface RequestContext {
9
10
  res: HttpResponse;
10
11
  }
12
+ /**
13
+ * The GraphQL over HTTP spec compliant request parser for an incoming GraphQL request.
14
+ *
15
+ * It is important to pass in the `abortedRef` so that the parser does not perform any
16
+ * operations on a disposed request (see example).
17
+ *
18
+ * If the HTTP request _is not_ a [well-formatted GraphQL over HTTP request](https://graphql.github.io/graphql-over-http/draft/#sec-Request), the function will respond
19
+ * on the `HttpResponse` argument and return `null`.
20
+ *
21
+ * If the HTTP request _is_ a [well-formatted GraphQL over HTTP request](https://graphql.github.io/graphql-over-http/draft/#sec-Request), but is invalid or malformed,
22
+ * the function will throw an error and it is up to the user to handle and respond as they see fit.
23
+ *
24
+ * ```js
25
+ * import uWS from 'uWebSockets.js'; // yarn add uWebSockets.js@uNetworking/uWebSockets.js#<version>
26
+ * import { parseRequestParams } from 'graphql-http/lib/use/uWebSockets';
27
+ *
28
+ * uWS
29
+ * .App()
30
+ * .any('/graphql', async (res, req) => {
31
+ * const abortedRef = { current: false };
32
+ * res.onAborted(() => (abortedRef.current = true));
33
+ * try {
34
+ * const maybeParams = await parseRequestParams(req, res, abortedRef);
35
+ * if (!maybeParams) {
36
+ * // not a well-formatted GraphQL over HTTP request,
37
+ * // parser responded and there's nothing else to do
38
+ * return;
39
+ * }
40
+ *
41
+ * // well-formatted GraphQL over HTTP request,
42
+ * // with valid parameters
43
+ * if (!abortedRef.current) {
44
+ * res.writeStatus('200 OK');
45
+ * res.end(JSON.stringify(maybeParams, null, ' '));
46
+ * }
47
+ * } catch (err) {
48
+ * // well-formatted GraphQL over HTTP request,
49
+ * // but with invalid parameters
50
+ * if (!abortedRef.current) {
51
+ * res.writeStatus('400 Bad Request');
52
+ * res.end(err.message);
53
+ * }
54
+ * }
55
+ * })
56
+ * .listen(4000, () => {
57
+ * console.log('Listening to port 4000');
58
+ * });
59
+ * ```
60
+ *
61
+ * @category Server/uWebSockets
62
+ */
63
+ export declare function parseRequestParams(req: HttpRequest, res: HttpResponse, abortedRef: {
64
+ current: boolean;
65
+ }): Promise<RequestParams | null>;
11
66
  /**
12
67
  * Handler options when using the http adapter.
13
68
  *
@@ -1,5 +1,6 @@
1
1
  import type { HttpRequest, HttpResponse } from 'uWebSockets.js';
2
2
  import { HandlerOptions as RawHandlerOptions, OperationContext } from '../handler';
3
+ import { RequestParams } from '../common';
3
4
  /**
4
5
  * The context in the request for the handler.
5
6
  *
@@ -8,6 +9,60 @@ import { HandlerOptions as RawHandlerOptions, OperationContext } from '../handle
8
9
  export interface RequestContext {
9
10
  res: HttpResponse;
10
11
  }
12
+ /**
13
+ * The GraphQL over HTTP spec compliant request parser for an incoming GraphQL request.
14
+ *
15
+ * It is important to pass in the `abortedRef` so that the parser does not perform any
16
+ * operations on a disposed request (see example).
17
+ *
18
+ * If the HTTP request _is not_ a [well-formatted GraphQL over HTTP request](https://graphql.github.io/graphql-over-http/draft/#sec-Request), the function will respond
19
+ * on the `HttpResponse` argument and return `null`.
20
+ *
21
+ * If the HTTP request _is_ a [well-formatted GraphQL over HTTP request](https://graphql.github.io/graphql-over-http/draft/#sec-Request), but is invalid or malformed,
22
+ * the function will throw an error and it is up to the user to handle and respond as they see fit.
23
+ *
24
+ * ```js
25
+ * import uWS from 'uWebSockets.js'; // yarn add uWebSockets.js@uNetworking/uWebSockets.js#<version>
26
+ * import { parseRequestParams } from 'graphql-http/lib/use/uWebSockets';
27
+ *
28
+ * uWS
29
+ * .App()
30
+ * .any('/graphql', async (res, req) => {
31
+ * const abortedRef = { current: false };
32
+ * res.onAborted(() => (abortedRef.current = true));
33
+ * try {
34
+ * const maybeParams = await parseRequestParams(req, res, abortedRef);
35
+ * if (!maybeParams) {
36
+ * // not a well-formatted GraphQL over HTTP request,
37
+ * // parser responded and there's nothing else to do
38
+ * return;
39
+ * }
40
+ *
41
+ * // well-formatted GraphQL over HTTP request,
42
+ * // with valid parameters
43
+ * if (!abortedRef.current) {
44
+ * res.writeStatus('200 OK');
45
+ * res.end(JSON.stringify(maybeParams, null, ' '));
46
+ * }
47
+ * } catch (err) {
48
+ * // well-formatted GraphQL over HTTP request,
49
+ * // but with invalid parameters
50
+ * if (!abortedRef.current) {
51
+ * res.writeStatus('400 Bad Request');
52
+ * res.end(err.message);
53
+ * }
54
+ * }
55
+ * })
56
+ * .listen(4000, () => {
57
+ * console.log('Listening to port 4000');
58
+ * });
59
+ * ```
60
+ *
61
+ * @category Server/uWebSockets
62
+ */
63
+ export declare function parseRequestParams(req: HttpRequest, res: HttpResponse, abortedRef: {
64
+ current: boolean;
65
+ }): Promise<RequestParams | null>;
11
66
  /**
12
67
  * Handler options when using the http adapter.
13
68
  *
@@ -1,7 +1,82 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.createHandler = void 0;
3
+ exports.createHandler = exports.parseRequestParams = void 0;
4
4
  const handler_1 = require("../handler");
5
+ /**
6
+ * The GraphQL over HTTP spec compliant request parser for an incoming GraphQL request.
7
+ *
8
+ * It is important to pass in the `abortedRef` so that the parser does not perform any
9
+ * operations on a disposed request (see example).
10
+ *
11
+ * If the HTTP request _is not_ a [well-formatted GraphQL over HTTP request](https://graphql.github.io/graphql-over-http/draft/#sec-Request), the function will respond
12
+ * on the `HttpResponse` argument and return `null`.
13
+ *
14
+ * If the HTTP request _is_ a [well-formatted GraphQL over HTTP request](https://graphql.github.io/graphql-over-http/draft/#sec-Request), but is invalid or malformed,
15
+ * the function will throw an error and it is up to the user to handle and respond as they see fit.
16
+ *
17
+ * ```js
18
+ * import uWS from 'uWebSockets.js'; // yarn add uWebSockets.js@uNetworking/uWebSockets.js#<version>
19
+ * import { parseRequestParams } from 'graphql-http/lib/use/uWebSockets';
20
+ *
21
+ * uWS
22
+ * .App()
23
+ * .any('/graphql', async (res, req) => {
24
+ * const abortedRef = { current: false };
25
+ * res.onAborted(() => (abortedRef.current = true));
26
+ * try {
27
+ * const maybeParams = await parseRequestParams(req, res, abortedRef);
28
+ * if (!maybeParams) {
29
+ * // not a well-formatted GraphQL over HTTP request,
30
+ * // parser responded and there's nothing else to do
31
+ * return;
32
+ * }
33
+ *
34
+ * // well-formatted GraphQL over HTTP request,
35
+ * // with valid parameters
36
+ * if (!abortedRef.current) {
37
+ * res.writeStatus('200 OK');
38
+ * res.end(JSON.stringify(maybeParams, null, ' '));
39
+ * }
40
+ * } catch (err) {
41
+ * // well-formatted GraphQL over HTTP request,
42
+ * // but with invalid parameters
43
+ * if (!abortedRef.current) {
44
+ * res.writeStatus('400 Bad Request');
45
+ * res.end(err.message);
46
+ * }
47
+ * }
48
+ * })
49
+ * .listen(4000, () => {
50
+ * console.log('Listening to port 4000');
51
+ * });
52
+ * ```
53
+ *
54
+ * @category Server/uWebSockets
55
+ */
56
+ async function parseRequestParams(req, res, abortedRef) {
57
+ const rawReq = toRequest(req, res, abortedRef);
58
+ const paramsOrRes = await (0, handler_1.parseRequestParams)(rawReq);
59
+ if (!('query' in paramsOrRes)) {
60
+ if (!abortedRef.current) {
61
+ const [body, init] = paramsOrRes;
62
+ res.cork(() => {
63
+ res.writeStatus(`${init.status} ${init.statusText}`);
64
+ for (const [key, val] of Object.entries(init.headers || {})) {
65
+ res.writeHeader(key, val);
66
+ }
67
+ if (body) {
68
+ res.end(body);
69
+ }
70
+ else {
71
+ res.endWithoutBody();
72
+ }
73
+ });
74
+ }
75
+ return null;
76
+ }
77
+ return paramsOrRes;
78
+ }
79
+ exports.parseRequestParams = parseRequestParams;
5
80
  /**
6
81
  * Create a GraphQL over HTTP spec compliant request handler for
7
82
  * the Node environment [uWebSockets.js module](https://github.com/uNetworking/uWebSockets.js/).
@@ -24,36 +99,11 @@ const handler_1 = require("../handler");
24
99
  function createHandler(options) {
25
100
  const handle = (0, handler_1.createHandler)(options);
26
101
  return async function requestListener(res, req) {
27
- let aborted = false;
28
- res.onAborted(() => (aborted = true));
102
+ const abortedRef = { current: false };
103
+ res.onAborted(() => (abortedRef.current = true));
29
104
  try {
30
- let url = req.getUrl();
31
- const query = req.getQuery();
32
- if (query) {
33
- url += '?' + query;
34
- }
35
- const [body, init] = await handle({
36
- url,
37
- method: req.getMethod().toUpperCase(),
38
- headers: { get: (key) => req.getHeader(key) },
39
- body: () => new Promise((resolve) => {
40
- let body = '';
41
- if (aborted) {
42
- resolve(body);
43
- }
44
- else {
45
- res.onData((chunk, isLast) => {
46
- body += Buffer.from(chunk, 0, chunk.byteLength).toString();
47
- if (isLast) {
48
- resolve(body);
49
- }
50
- });
51
- }
52
- }),
53
- raw: req,
54
- context: { res },
55
- });
56
- if (!aborted) {
105
+ const [body, init] = await handle(toRequest(req, res, abortedRef));
106
+ if (!abortedRef.current) {
57
107
  res.cork(() => {
58
108
  res.writeStatus(`${init.status} ${init.statusText}`);
59
109
  for (const [key, val] of Object.entries(init.headers || {})) {
@@ -73,7 +123,7 @@ function createHandler(options) {
73
123
  // If you wish to handle them differently, consider implementing your own request handler.
74
124
  console.error('Internal error occurred during request handling. ' +
75
125
  'Please check your implementation.', err);
76
- if (!aborted) {
126
+ if (!abortedRef.current) {
77
127
  res.cork(() => {
78
128
  res.writeStatus('500 Internal Server Error').endWithoutBody();
79
129
  });
@@ -82,3 +132,31 @@ function createHandler(options) {
82
132
  };
83
133
  }
84
134
  exports.createHandler = createHandler;
135
+ function toRequest(req, res, abortedRef) {
136
+ let url = req.getUrl();
137
+ const query = req.getQuery();
138
+ if (query) {
139
+ url += '?' + query;
140
+ }
141
+ return {
142
+ url,
143
+ method: req.getMethod().toUpperCase(),
144
+ headers: { get: (key) => req.getHeader(key) },
145
+ body: () => new Promise((resolve) => {
146
+ let body = '';
147
+ if (abortedRef.current) {
148
+ resolve(body);
149
+ }
150
+ else {
151
+ res.onData((chunk, isLast) => {
152
+ body += Buffer.from(chunk, 0, chunk.byteLength).toString();
153
+ if (isLast) {
154
+ resolve(body);
155
+ }
156
+ });
157
+ }
158
+ }),
159
+ raw: req,
160
+ context: { res },
161
+ };
162
+ }