xref: /expo/packages/@expo/server/build/vendor/http.js (revision e9783df2)
1"use strict";
2Object.defineProperty(exports, "__esModule", { value: true });
3exports.respond = exports.convertHeaders = exports.convertRequest = exports.createRequestHandler = void 0;
4const node_1 = require("@remix-run/node");
5const __1 = require("..");
6const environment_1 = require("../environment");
7/**
8 * Returns a request handler for http that serves the response using Remix.
9 */
10function createRequestHandler({ build }, setup) {
11    const handleRequest = (0, __1.createRequestHandler)(build, setup);
12    return async (req, res, next) => {
13        if (!req?.url || !req.method) {
14            return next();
15        }
16        try {
17            const request = convertRequest(req, res);
18            const response = await handleRequest(request);
19            await respond(res, response);
20        }
21        catch (error) {
22            // http doesn't support async functions, so we have to pass along the
23            // error manually using next().
24            next(error);
25        }
26    };
27}
28exports.createRequestHandler = createRequestHandler;
29// Convert an http request to an expo request
30function convertRequest(req, res) {
31    const url = new URL(req.url, `http://${req.headers.host}`);
32    // Abort action/loaders once we can no longer write a response
33    const controller = new node_1.AbortController();
34    res.on('close', () => controller.abort());
35    const init = {
36        method: req.method,
37        headers: convertHeaders(req.headers),
38        // Cast until reason/throwIfAborted added
39        // https://github.com/mysticatea/abort-controller/issues/36
40        signal: controller.signal,
41    };
42    if (req.method !== 'GET' && req.method !== 'HEAD') {
43        init.body = req;
44    }
45    return new environment_1.ExpoRequest(url.href, init);
46}
47exports.convertRequest = convertRequest;
48function convertHeaders(requestHeaders) {
49    const headers = new node_1.Headers();
50    for (const [key, values] of Object.entries(requestHeaders)) {
51        if (values) {
52            if (Array.isArray(values)) {
53                for (const value of values) {
54                    headers.append(key, value);
55                }
56            }
57            else {
58                headers.set(key, values);
59            }
60        }
61    }
62    return headers;
63}
64exports.convertHeaders = convertHeaders;
65async function respond(res, expoRes) {
66    res.statusMessage = expoRes.statusText;
67    res.statusCode = expoRes.status;
68    for (const [key, values] of Object.entries(expoRes.headers.raw())) {
69        for (const value of values) {
70            res.setHeader(key, value);
71        }
72    }
73    if (expoRes.body) {
74        await (0, node_1.writeReadableStreamToWritable)(expoRes.body, res);
75    }
76    else {
77        res.end();
78    }
79}
80exports.respond = respond;
81//# sourceMappingURL=http.js.map