[upd] server:lib:plankton
Christian Fraß authored 3 years ago
|
1) /*
2) This file is part of »bacterio-plankton:http«.
3)
4) Copyright 2016-2021 'Christian Fraß, Christian Neubauer, Martin Springwald GbR'
5) <info@greenscale.de>
6)
7) »bacterio-plankton:http« is free software: you can redistribute it and/or modify
8) it under the terms of the GNU Lesser General Public License as published by
9) the Free Software Foundation, either version 3 of the License, or
10) (at your option) any later version.
11)
12) »bacterio-plankton:http« is distributed in the hope that it will be useful,
13) but WITHOUT ANY WARRANTY; without even the implied warranty of
14) MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15) GNU Lesser General Public License for more details.
16)
17) You should have received a copy of the GNU Lesser General Public License
18) along with »bacterio-plankton:http«. If not, see <http://www.gnu.org/licenses/>.
19) */
20) var lib_http;
21) (function (lib_http) {
22) /**
23) * @author fenris <frass@greenscale.de>
24) */
25) let enum_method;
26) (function (enum_method) {
27) enum_method["get"] = "get";
28) enum_method["post"] = "post";
29) enum_method["options"] = "options";
30) // put = "put",
31) // delete = "delete",
32) // head = "head",
33) })(enum_method = lib_http.enum_method || (lib_http.enum_method = {}));
34) })(lib_http || (lib_http = {}));
35) /*
36) This file is part of »bacterio-plankton:http«.
37)
38) Copyright 2016-2021 'Christian Fraß, Christian Neubauer, Martin Springwald GbR'
39) <info@greenscale.de>
40)
41) »bacterio-plankton:http« is free software: you can redistribute it and/or modify
42) it under the terms of the GNU Lesser General Public License as published by
43) the Free Software Foundation, either version 3 of the License, or
44) (at your option) any later version.
45)
46) »bacterio-plankton:http« is distributed in the hope that it will be useful,
47) but WITHOUT ANY WARRANTY; without even the implied warranty of
48) MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
49) GNU Lesser General Public License for more details.
50)
51) You should have received a copy of the GNU Lesser General Public License
52) along with »bacterio-plankton:http«. If not, see <http://www.gnu.org/licenses/>.
53) */
54) var lib_http;
55) (function (lib_http) {
56) /**
57) * @author fenris <frass@greenscale.de>
58) */
59) const linebreak = "\r\n";
60) /**
61) * @author fenris <frass@greenscale.de>
62) */
63) function encode_method(method) {
64) switch (method) {
65) case lib_http.enum_method.get: return "GET";
66) case lib_http.enum_method.post: return "POST";
67) case lib_http.enum_method.options: return "OPTIONS";
68) default: throw (new Error("impossible"));
69) }
70) }
71) /**
72) * @author fenris <frass@greenscale.de>
73) */
74) function decode_method(method_raw) {
75) switch (method_raw) {
76) case "GET": return lib_http.enum_method.get;
77) case "POST": return lib_http.enum_method.post;
78) case "OPTIONS": return lib_http.enum_method.options;
79) default: throw (new Error("unhandled method: " + method_raw));
80) }
81) }
82) /**
83) * @author fenris <frass@greenscale.de>
84) */
85) function get_statustext(statuscode) {
86) switch (statuscode) {
87) case 100: return "Continue";
88) case 101: return "Switching Protocols";
89) case 103: return "Early Hints";
90) case 200: return "OK";
91) case 201: return "Created";
92) case 202: return "Accepted";
93) case 203: return "Non-Authoritative Information";
94) case 204: return "No Content";
95) case 205: return "Reset Content";
96) case 206: return "Partial Content";
97) case 300: return "Multiple Choices";
98) case 301: return "Moved Permanently";
99) case 302: return "Found";
100) case 303: return "See Other";
101) case 304: return "Not Modified";
102) case 307: return "Temporary Redirect";
103) case 308: return "Permanent Redirect";
104) case 400: return "Bad Request";
105) case 401: return "Unauthorized";
106) case 402: return "Payment Required";
107) case 403: return "Forbidden";
108) case 404: return "Not Found";
109) case 405: return "Method Not Allowed";
110) case 406: return "Not Acceptable";
111) case 407: return "Proxy Authentication Required";
112) case 408: return "Request Timeout";
113) case 409: return "Conflict";
114) case 410: return "Gone";
115) case 411: return "Length Required";
116) case 412: return "Precondition Failed";
117) case 413: return "Payload Too Large";
118) case 414: return "URI Too Long";
119) case 415: return "Unsupported Media Type";
120) case 416: return "Range Not Satisfiable";
121) case 417: return "Expectation Failed";
122) case 418: return "I'm a teapot";
123) case 422: return "Unprocessable Entity";
124) case 425: return "Too Early";
125) case 426: return "Upgrade Required";
126) case 428: return "Precondition Required";
127) case 429: return "Too Many Requests";
128) case 431: return "Request Header Fields Too Large";
129) case 451: return "Unavailable For Legal Reasons";
130) case 500: return "Internal Server Error";
131) case 501: return "Not Implemented";
132) case 502: return "Bad Gateway";
133) case 503: return "Service Unavailable";
134) case 504: return "Gateway Timeout";
135) case 505: return "HTTP Version Not Supported";
136) case 506: return "Variant Also Negotiates";
137) case 507: return "Insufficient Storage";
138) case 508: return "Loop Detected";
139) case 510: return "Not Extended";
140) case 511: return "Network Authentication";
141) default: throw (new Error("unhandled statuscode: " + statuscode.toFixed(0)));
142) }
143) }
144) /**
145) * @author fenris <frass@greenscale.de>
146) */
147) function encode_request(request) {
148) let request_raw = "";
149) request_raw += (encode_method(request.method) + " " + request.query + " " + "HTTP/1.1" + linebreak);
150) request_raw += ("Host: " + request.host + linebreak);
151) for (const [key, value] of Object.entries(request.headers)) {
152) request_raw += (key + ": " + value + linebreak);
153) }
154) request_raw += linebreak;
155) request_raw += request.body;
156) return request_raw;
157) }
158) lib_http.encode_request = encode_request;
159) /**
160) * @author fenris <frass@greenscale.de>
161) */
162) function decode_request(request_raw) {
163) const lines = request_raw.split(linebreak);
164) const first = lines.shift();
165) const [method_raw, query, version] = first.split(" ");
166) let headers = {};
167) while (true) {
168) const line = lines.shift();
169) if (line === "") {
170) break;
171) }
172) else {
173) const [key, value] = line.split(": ", 2);
174) headers[key] = value;
175) }
176) }
177) const body = lines.join(linebreak);
178) const request = {
179) "host": headers["Host"],
180) "query": query,
181) "method": decode_method(method_raw),
182) "headers": headers,
183) "body": body,
184) };
185) return request;
186) }
187) lib_http.decode_request = decode_request;
188) /**
189) * @author fenris <frass@greenscale.de>
190) */
191) function encode_response(response) {
192) let response_raw = "";
193) response_raw += ("HTTP/1.1" + " " + response.statuscode + " " + get_statustext(response.statuscode) + linebreak);
194) for (const [key, value] of Object.entries(response.headers)) {
195) response_raw += (key + ": " + value + linebreak);
196) }
197) response_raw += linebreak;
198) response_raw += response.body;
199) return response_raw;
200) }
201) lib_http.encode_response = encode_response;
202) /**
203) * @author fenris <frass@greenscale.de>
204) */
205) function decode_response(response_raw) {
206) const lines = response_raw.split(linebreak);
207) const first = lines.shift();
208) const statuscode = parseInt(first.split(" ")[1]);
209) let headers = {};
210) while (true) {
211) const line = lines.shift();
212) if (line === "") {
213) break;
214) }
215) else {
216) const [key, value] = line.split(": ", 2);
217) headers[key] = value;
218) }
219) }
220) const body = lines.join(linebreak);
221) const response = {
222) "statuscode": statuscode,
223) "headers": headers,
224) "body": body,
225) };
226) return response;
227) }
228) lib_http.decode_response = decode_response;
229) })(lib_http || (lib_http = {}));
|