Report abuse

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
function Point2ToPoint3(app) {

    function pop(object, key, fallback) {
        var value = object[key];
        delete object[key];
        return value || fallback;
    }

    return function(env) {
        var request = {};
        if (env.jsgi && env.version && env.jsgi.version.toString() == "0,3") {
            return app(env);
        }

        // required top level
        var required = {
            method: "REQUEST_METHOD", // RFC 2616
            version: "SERVER_PROTOCOL", // RFC 2616
            scheme: "jsgi.url_scheme", // RFC 2616
            host: "SERVER_NAME", // RFC 2616
            port: "SERVER_PORT", // RFC 2616
            scriptName: "SCRIPT_NAME", // RFC 3875: scriptPath?
            pathInfo: "PATH_INFO", // RFC 3875: extraPath? Should we normalize /../?
            queryString: "QUERY_STRING", // RFC 2616: query?
            input: "jsgi.input"
        };

        for (var key in required) {
            request[key] = pop(env, required[key]);
        }

        request.port = Number(request.port); // always an integer
        request.version = request.version // parse, why not?
            .split("/")[1] // ignore "HTTP/"
            .split(" ")[0] // RFC 2616 allows an extension-version...huh?
            .split(";")[0] // RFC 2616 doesn't allow params
            .split(".")
            .map(function(i) {
                return Number(i);
            });

        // optional top level
        var optional = {
            authType: "AUTH_TYPE", // authenticationType?
            pathTranslated: "PATH_TRANSLATED", // duplicate data, delete instead?
            remoteAddr: "REMOTE_ADDR", // remoteAddress?
            remoteHost: "REMOTE_HOST",
            remoteIdent: "REMOTE_IDENT", // remoteIdentity?
            remoteUser: "REMOTE_USER",
            serverSoftware: "SERVER_SOFTWARE" // is this ever useful?
        };
        for (var key in optional) {
            if (env[optional[key]]) {
                request[key] = pop(env, optional[key]);
            }
        }

        // headers
        request.headers = {};
        for (var key in env) {
            if (key.length > 5 && key.indexOf("HTTP_" == 0)) {
                var header = key.substring(5).replace(/_/g, "-").toLowerCase();
                request.headers[header] = pop(env, key);
            }
        }
        if (env.CONTENT_TYPE) {
            request.headers["content-type"] = Number(pop(env, "CONTENT_TYPE"));
        }
        if (env.CONTENT_LENGTH) {
            request.headers["content-length"] = String(pop(env, "CONTENT_LENGTH"));
        }

        // jsgi
        request.jsgi = {};
        delete env["jsgi.version"];
        request.jsgi.version = [0, 3];

        request.jsgi.errors = pop(env, "jsgi.errors");
        request.jsgi.multithread = pop(env, "jsgi.multithread");
        request.jsgi.multiprocess = pop(env, "jsgi.multiprocess");
        request.jsgi.runonce = pop(env, "jsgi.run_once"); // runOnce?
        request.jsgi.async = false; // no 0.2 servers support promises, right?
        if (env.GATEWAY_INTERFACE) {
            request.jsgi.cgi = env.GATEWAY_INTERFACE
                .split("/")[1] // ignore "CGI/"
                .split(" ")[0] // ignore anything trailing
                .split(";")[0] // RFC 3875 doesn't allow params
                .split(".")
                .map(function(i) {
                    return Number(i);
                });
            delete env.GATEWAY_INTERFACE;
        }

        // env
        // JSGI 0.2 doesn't require an iterable env so delete everything
        // we know about and just stick everything else in request.env
        request.env = env;

        // TODO should we lint for changes like !scriptName.endsWith("/")?

        return app(request);
    }
}