@gjsify/http 0.3.16 → 0.3.17
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/esm/client-request.js +1 -240
- package/lib/esm/constants.js +1 -105
- package/lib/esm/incoming-message.js +1 -68
- package/lib/esm/index.js +1 -126
- package/lib/esm/server-request-socket.js +1 -71
- package/lib/esm/server.js +1 -391
- package/lib/esm/validators.js +1 -23
- package/package.json +14 -14
- package/tsconfig.tsbuildinfo +1 -1
|
@@ -1,240 +1 @@
|
|
|
1
|
-
import
|
|
2
|
-
import { OutgoingMessage } from "./server.js";
|
|
3
|
-
import GLib from "@girs/glib-2.0";
|
|
4
|
-
import Soup from "@girs/soup-3.0";
|
|
5
|
-
import Gio from "@girs/gio-2.0";
|
|
6
|
-
import { Buffer } from "node:buffer";
|
|
7
|
-
import { URL } from "node:url";
|
|
8
|
-
import { readBytesAsync } from "@gjsify/utils";
|
|
9
|
-
|
|
10
|
-
//#region src/client-request.ts
|
|
11
|
-
/**
|
|
12
|
-
* ClientRequest — Writable stream representing an outgoing HTTP request.
|
|
13
|
-
*
|
|
14
|
-
* Usage:
|
|
15
|
-
* const req = http.request(options, (res) => { ... });
|
|
16
|
-
* req.write(body);
|
|
17
|
-
* req.end();
|
|
18
|
-
*/
|
|
19
|
-
var ClientRequest = class extends OutgoingMessage {
|
|
20
|
-
method;
|
|
21
|
-
path;
|
|
22
|
-
protocol;
|
|
23
|
-
host;
|
|
24
|
-
hostname;
|
|
25
|
-
port;
|
|
26
|
-
aborted = false;
|
|
27
|
-
reusedSocket = false;
|
|
28
|
-
maxHeadersCount = 2e3;
|
|
29
|
-
_chunks = [];
|
|
30
|
-
_session;
|
|
31
|
-
_message;
|
|
32
|
-
_cancellable;
|
|
33
|
-
_timeout = 0;
|
|
34
|
-
_timeoutTimer = null;
|
|
35
|
-
_responseCallback;
|
|
36
|
-
constructor(url, options, callback) {
|
|
37
|
-
super();
|
|
38
|
-
let opts;
|
|
39
|
-
if (typeof url === "string" || url instanceof URL) {
|
|
40
|
-
const parsed = typeof url === "string" ? new URL(url) : url;
|
|
41
|
-
opts = {
|
|
42
|
-
protocol: parsed.protocol,
|
|
43
|
-
hostname: parsed.hostname,
|
|
44
|
-
port: parsed.port ? Number(parsed.port) : undefined,
|
|
45
|
-
path: parsed.pathname + parsed.search,
|
|
46
|
-
...typeof options === "object" ? options : {}
|
|
47
|
-
};
|
|
48
|
-
if (typeof options === "function") {
|
|
49
|
-
callback = options;
|
|
50
|
-
}
|
|
51
|
-
} else {
|
|
52
|
-
opts = url;
|
|
53
|
-
if (typeof options === "function") {
|
|
54
|
-
callback = options;
|
|
55
|
-
}
|
|
56
|
-
}
|
|
57
|
-
this.method = (opts.method || "GET").toUpperCase();
|
|
58
|
-
this.protocol = opts.protocol || "http:";
|
|
59
|
-
this.hostname = opts.hostname || opts.host?.split(":")[0] || "localhost";
|
|
60
|
-
this.port = Number(opts.port) || (this.protocol === "https:" ? 443 : 80);
|
|
61
|
-
this.path = opts.path || "/";
|
|
62
|
-
this.host = opts.host || `${this.hostname}:${this.port}`;
|
|
63
|
-
this._timeout = opts.timeout || 0;
|
|
64
|
-
if (callback) {
|
|
65
|
-
this._responseCallback = callback;
|
|
66
|
-
this.once("response", callback);
|
|
67
|
-
}
|
|
68
|
-
if (opts.headers) {
|
|
69
|
-
for (const [key, value] of Object.entries(opts.headers)) {
|
|
70
|
-
this.setHeader(key, value);
|
|
71
|
-
}
|
|
72
|
-
}
|
|
73
|
-
if (opts.setHost !== false && !this._headers.has("host")) {
|
|
74
|
-
const defaultPort = this.protocol === "https:" ? 443 : 80;
|
|
75
|
-
const hostHeader = this.port === defaultPort ? this.hostname : `${this.hostname}:${this.port}`;
|
|
76
|
-
this.setHeader("Host", hostHeader);
|
|
77
|
-
}
|
|
78
|
-
if (opts.auth && !this._headers.has("authorization")) {
|
|
79
|
-
this.setHeader("Authorization", "Basic " + Buffer.from(opts.auth).toString("base64"));
|
|
80
|
-
}
|
|
81
|
-
if (opts.signal) {
|
|
82
|
-
if (opts.signal.aborted) {
|
|
83
|
-
this.abort();
|
|
84
|
-
} else {
|
|
85
|
-
opts.signal.addEventListener("abort", () => this.abort(), { once: true });
|
|
86
|
-
}
|
|
87
|
-
}
|
|
88
|
-
const uri = GLib.Uri.parse(this._buildUrl(), GLib.UriFlags.NONE);
|
|
89
|
-
this._session = new Soup.Session();
|
|
90
|
-
this._message = new Soup.Message({
|
|
91
|
-
method: this.method,
|
|
92
|
-
uri
|
|
93
|
-
});
|
|
94
|
-
this._cancellable = new Gio.Cancellable();
|
|
95
|
-
if (this._timeout > 0) {
|
|
96
|
-
this._session.timeout = Math.ceil(this._timeout / 1e3);
|
|
97
|
-
this._timeoutTimer = setTimeout(() => {
|
|
98
|
-
this._timeoutTimer = null;
|
|
99
|
-
this.emit("timeout");
|
|
100
|
-
}, this._timeout);
|
|
101
|
-
}
|
|
102
|
-
}
|
|
103
|
-
_buildUrl() {
|
|
104
|
-
const proto = this.protocol.endsWith(":") ? this.protocol : this.protocol + ":";
|
|
105
|
-
const defaultPort = proto === "https:" ? 443 : 80;
|
|
106
|
-
const portStr = this.port === defaultPort ? "" : `:${this.port}`;
|
|
107
|
-
return `${proto}//${this.hostname}${portStr}${this.path}`;
|
|
108
|
-
}
|
|
109
|
-
/** Get raw header names and values as a flat array. */
|
|
110
|
-
getRawHeaderNames() {
|
|
111
|
-
return Array.from(this._headers.keys());
|
|
112
|
-
}
|
|
113
|
-
/** Flush headers — marks headers as sent. */
|
|
114
|
-
flushHeaders() {
|
|
115
|
-
if (!this.headersSent) {
|
|
116
|
-
this._applyHeaders();
|
|
117
|
-
}
|
|
118
|
-
}
|
|
119
|
-
/** Set timeout for the request. Emits 'timeout' if no response within msecs. */
|
|
120
|
-
setTimeout(msecs, callback) {
|
|
121
|
-
this._timeout = msecs;
|
|
122
|
-
if (this._timeoutTimer) {
|
|
123
|
-
clearTimeout(this._timeoutTimer);
|
|
124
|
-
this._timeoutTimer = null;
|
|
125
|
-
}
|
|
126
|
-
if (callback) this.once("timeout", callback);
|
|
127
|
-
if (msecs > 0) {
|
|
128
|
-
this._session.timeout = Math.ceil(msecs / 1e3);
|
|
129
|
-
this._timeoutTimer = setTimeout(() => {
|
|
130
|
-
this._timeoutTimer = null;
|
|
131
|
-
this.emit("timeout");
|
|
132
|
-
}, msecs);
|
|
133
|
-
}
|
|
134
|
-
return this;
|
|
135
|
-
}
|
|
136
|
-
/** Abort the request. */
|
|
137
|
-
abort() {
|
|
138
|
-
if (this.aborted) return;
|
|
139
|
-
this.aborted = true;
|
|
140
|
-
if (this._timeoutTimer) {
|
|
141
|
-
clearTimeout(this._timeoutTimer);
|
|
142
|
-
this._timeoutTimer = null;
|
|
143
|
-
}
|
|
144
|
-
this._cancellable.cancel();
|
|
145
|
-
this.emit("abort");
|
|
146
|
-
this.destroy();
|
|
147
|
-
}
|
|
148
|
-
/** Writable stream _write implementation — collect body chunks. */
|
|
149
|
-
_write(chunk, encoding, callback) {
|
|
150
|
-
const buf = Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk, encoding);
|
|
151
|
-
this._chunks.push(buf);
|
|
152
|
-
callback();
|
|
153
|
-
}
|
|
154
|
-
/** Called when the writable stream ends — send the request. */
|
|
155
|
-
_final(callback) {
|
|
156
|
-
this._sendRequest().then(() => callback()).catch((err) => callback(err));
|
|
157
|
-
}
|
|
158
|
-
_applyHeaders() {
|
|
159
|
-
if (this.headersSent) return;
|
|
160
|
-
this.headersSent = true;
|
|
161
|
-
const requestHeaders = this._message.get_request_headers();
|
|
162
|
-
for (const [key, value] of this._headers) {
|
|
163
|
-
if (Array.isArray(value)) {
|
|
164
|
-
for (const v of value) {
|
|
165
|
-
requestHeaders.append(key, v);
|
|
166
|
-
}
|
|
167
|
-
} else {
|
|
168
|
-
requestHeaders.replace(key, value);
|
|
169
|
-
}
|
|
170
|
-
}
|
|
171
|
-
}
|
|
172
|
-
async _sendRequest() {
|
|
173
|
-
this._applyHeaders();
|
|
174
|
-
const body = Buffer.concat(this._chunks);
|
|
175
|
-
if (body.length > 0) {
|
|
176
|
-
const contentType = this._headers.get("content-type") || "application/octet-stream";
|
|
177
|
-
this._message.set_request_body_from_bytes(contentType, new GLib.Bytes(body));
|
|
178
|
-
}
|
|
179
|
-
try {
|
|
180
|
-
const inputStream = await new Promise((resolve, reject) => {
|
|
181
|
-
this._session.send_async(this._message, GLib.PRIORITY_DEFAULT, this._cancellable, (_self, asyncRes) => {
|
|
182
|
-
try {
|
|
183
|
-
const stream = this._session.send_finish(asyncRes);
|
|
184
|
-
resolve(stream);
|
|
185
|
-
} catch (error) {
|
|
186
|
-
reject(error);
|
|
187
|
-
}
|
|
188
|
-
});
|
|
189
|
-
});
|
|
190
|
-
const bodyChunks = [];
|
|
191
|
-
try {
|
|
192
|
-
let chunk;
|
|
193
|
-
while ((chunk = await readBytesAsync(inputStream, 4096, GLib.PRIORITY_DEFAULT, this._cancellable)) !== null) {
|
|
194
|
-
bodyChunks.push(Buffer.from(chunk));
|
|
195
|
-
}
|
|
196
|
-
} catch (readErr) {}
|
|
197
|
-
const res = new IncomingMessage();
|
|
198
|
-
res.statusCode = this._message.status_code;
|
|
199
|
-
res.statusMessage = this._message.get_reason_phrase();
|
|
200
|
-
res.httpVersion = "1.1";
|
|
201
|
-
const responseHeaders = this._message.get_response_headers();
|
|
202
|
-
responseHeaders.foreach((name, value) => {
|
|
203
|
-
const lower = name.toLowerCase();
|
|
204
|
-
res.rawHeaders.push(name, value);
|
|
205
|
-
if (lower in res.headers) {
|
|
206
|
-
const existing = res.headers[lower];
|
|
207
|
-
if (Array.isArray(existing)) {
|
|
208
|
-
existing.push(value);
|
|
209
|
-
} else {
|
|
210
|
-
res.headers[lower] = [existing, value];
|
|
211
|
-
}
|
|
212
|
-
} else {
|
|
213
|
-
res.headers[lower] = value;
|
|
214
|
-
}
|
|
215
|
-
});
|
|
216
|
-
this.finished = true;
|
|
217
|
-
if (this._timeoutTimer) {
|
|
218
|
-
clearTimeout(this._timeoutTimer);
|
|
219
|
-
this._timeoutTimer = null;
|
|
220
|
-
}
|
|
221
|
-
this.emit("response", res);
|
|
222
|
-
setTimeout(() => {
|
|
223
|
-
for (const buf of bodyChunks) {
|
|
224
|
-
res.push(buf);
|
|
225
|
-
}
|
|
226
|
-
res.push(null);
|
|
227
|
-
res.complete = true;
|
|
228
|
-
}, 0);
|
|
229
|
-
} catch (error) {
|
|
230
|
-
if (this.aborted) {
|
|
231
|
-
this.emit("abort");
|
|
232
|
-
} else {
|
|
233
|
-
this.emit("error", error instanceof Error ? error : new Error(String(error)));
|
|
234
|
-
}
|
|
235
|
-
}
|
|
236
|
-
}
|
|
237
|
-
};
|
|
238
|
-
|
|
239
|
-
//#endregion
|
|
240
|
-
export { ClientRequest };
|
|
1
|
+
import{IncomingMessage as e}from"./incoming-message.js";import{OutgoingMessage as t}from"./server.js";import n from"@girs/glib-2.0";import r from"@girs/soup-3.0";import i from"@girs/gio-2.0";import{Buffer as a}from"node:buffer";import{URL as o}from"node:url";import{readBytesAsync as s}from"@gjsify/utils";var c=class extends t{method;path;protocol;host;hostname;port;aborted=!1;reusedSocket=!1;maxHeadersCount=2e3;_chunks=[];_session;_message;_cancellable;_timeout=0;_timeoutTimer=null;_responseCallback;constructor(e,t,s){super();let c;if(typeof e==`string`||e instanceof o){let n=typeof e==`string`?new o(e):e;c={protocol:n.protocol,hostname:n.hostname,port:n.port?Number(n.port):void 0,path:n.pathname+n.search,...typeof t==`object`?t:{}},typeof t==`function`&&(s=t)}else c=e,typeof t==`function`&&(s=t);if(this.method=(c.method||`GET`).toUpperCase(),this.protocol=c.protocol||`http:`,this.hostname=c.hostname||c.host?.split(`:`)[0]||`localhost`,this.port=Number(c.port)||(this.protocol===`https:`?443:80),this.path=c.path||`/`,this.host=c.host||`${this.hostname}:${this.port}`,this._timeout=c.timeout||0,s&&(this._responseCallback=s,this.once(`response`,s)),c.headers)for(let[e,t]of Object.entries(c.headers))this.setHeader(e,t);if(c.setHost!==!1&&!this._headers.has(`host`)){let e=this.protocol===`https:`?443:80,t=this.port===e?this.hostname:`${this.hostname}:${this.port}`;this.setHeader(`Host`,t)}c.auth&&!this._headers.has(`authorization`)&&this.setHeader(`Authorization`,`Basic `+a.from(c.auth).toString(`base64`)),c.signal&&(c.signal.aborted?this.abort():c.signal.addEventListener(`abort`,()=>this.abort(),{once:!0}));let l=n.Uri.parse(this._buildUrl(),n.UriFlags.NONE);this._session=new r.Session,this._message=new r.Message({method:this.method,uri:l}),this._cancellable=new i.Cancellable,this._timeout>0&&(this._session.timeout=Math.ceil(this._timeout/1e3),this._timeoutTimer=setTimeout(()=>{this._timeoutTimer=null,this.emit(`timeout`)},this._timeout))}_buildUrl(){let e=this.protocol.endsWith(`:`)?this.protocol:this.protocol+`:`,t=e===`https:`?443:80,n=this.port===t?``:`:${this.port}`;return`${e}//${this.hostname}${n}${this.path}`}getRawHeaderNames(){return Array.from(this._headers.keys())}flushHeaders(){this.headersSent||this._applyHeaders()}setTimeout(e,t){return this._timeout=e,this._timeoutTimer&&=(clearTimeout(this._timeoutTimer),null),t&&this.once(`timeout`,t),e>0&&(this._session.timeout=Math.ceil(e/1e3),this._timeoutTimer=setTimeout(()=>{this._timeoutTimer=null,this.emit(`timeout`)},e)),this}abort(){this.aborted||(this.aborted=!0,this._timeoutTimer&&=(clearTimeout(this._timeoutTimer),null),this._cancellable.cancel(),this.emit(`abort`),this.destroy())}_write(e,t,n){let r=a.isBuffer(e)?e:a.from(e,t);this._chunks.push(r),n()}_final(e){this._sendRequest().then(()=>e()).catch(t=>e(t))}_applyHeaders(){if(this.headersSent)return;this.headersSent=!0;let e=this._message.get_request_headers();for(let[t,n]of this._headers)if(Array.isArray(n))for(let r of n)e.append(t,r);else e.replace(t,n)}async _sendRequest(){this._applyHeaders();let t=a.concat(this._chunks);if(t.length>0){let e=this._headers.get(`content-type`)||`application/octet-stream`;this._message.set_request_body_from_bytes(e,new n.Bytes(t))}try{let t=await new Promise((e,t)=>{this._session.send_async(this._message,n.PRIORITY_DEFAULT,this._cancellable,(n,r)=>{try{e(this._session.send_finish(r))}catch(e){t(e)}})}),r=[];try{let e;for(;(e=await s(t,4096,n.PRIORITY_DEFAULT,this._cancellable))!==null;)r.push(a.from(e))}catch{}let i=new e;i.statusCode=this._message.status_code,i.statusMessage=this._message.get_reason_phrase(),i.httpVersion=`1.1`,this._message.get_response_headers().foreach((e,t)=>{let n=e.toLowerCase();if(i.rawHeaders.push(e,t),n in i.headers){let e=i.headers[n];Array.isArray(e)?e.push(t):i.headers[n]=[e,t]}else i.headers[n]=t}),this.finished=!0,this._timeoutTimer&&=(clearTimeout(this._timeoutTimer),null),this.emit(`response`,i),setTimeout(()=>{for(let e of r)i.push(e);i.push(null),i.complete=!0},0)}catch(e){this.aborted?this.emit(`abort`):this.emit(`error`,e instanceof Error?e:Error(String(e)))}}};export{c as ClientRequest};
|
package/lib/esm/constants.js
CHANGED
|
@@ -1,105 +1 @@
|
|
|
1
|
-
|
|
2
|
-
const STATUS_CODES = {
|
|
3
|
-
100: "Continue",
|
|
4
|
-
101: "Switching Protocols",
|
|
5
|
-
102: "Processing",
|
|
6
|
-
103: "Early Hints",
|
|
7
|
-
200: "OK",
|
|
8
|
-
201: "Created",
|
|
9
|
-
202: "Accepted",
|
|
10
|
-
203: "Non-Authoritative Information",
|
|
11
|
-
204: "No Content",
|
|
12
|
-
205: "Reset Content",
|
|
13
|
-
206: "Partial Content",
|
|
14
|
-
207: "Multi-Status",
|
|
15
|
-
208: "Already Reported",
|
|
16
|
-
226: "IM Used",
|
|
17
|
-
300: "Multiple Choices",
|
|
18
|
-
301: "Moved Permanently",
|
|
19
|
-
302: "Found",
|
|
20
|
-
303: "See Other",
|
|
21
|
-
304: "Not Modified",
|
|
22
|
-
305: "Use Proxy",
|
|
23
|
-
307: "Temporary Redirect",
|
|
24
|
-
308: "Permanent Redirect",
|
|
25
|
-
400: "Bad Request",
|
|
26
|
-
401: "Unauthorized",
|
|
27
|
-
402: "Payment Required",
|
|
28
|
-
403: "Forbidden",
|
|
29
|
-
404: "Not Found",
|
|
30
|
-
405: "Method Not Allowed",
|
|
31
|
-
406: "Not Acceptable",
|
|
32
|
-
407: "Proxy Authentication Required",
|
|
33
|
-
408: "Request Timeout",
|
|
34
|
-
409: "Conflict",
|
|
35
|
-
410: "Gone",
|
|
36
|
-
411: "Length Required",
|
|
37
|
-
412: "Precondition Failed",
|
|
38
|
-
413: "Payload Too Large",
|
|
39
|
-
414: "URI Too Long",
|
|
40
|
-
415: "Unsupported Media Type",
|
|
41
|
-
416: "Range Not Satisfiable",
|
|
42
|
-
417: "Expectation Failed",
|
|
43
|
-
418: "I'm a Teapot",
|
|
44
|
-
421: "Misdirected Request",
|
|
45
|
-
422: "Unprocessable Entity",
|
|
46
|
-
423: "Locked",
|
|
47
|
-
424: "Failed Dependency",
|
|
48
|
-
425: "Too Early",
|
|
49
|
-
426: "Upgrade Required",
|
|
50
|
-
428: "Precondition Required",
|
|
51
|
-
429: "Too Many Requests",
|
|
52
|
-
431: "Request Header Fields Too Large",
|
|
53
|
-
451: "Unavailable For Legal Reasons",
|
|
54
|
-
500: "Internal Server Error",
|
|
55
|
-
501: "Not Implemented",
|
|
56
|
-
502: "Bad Gateway",
|
|
57
|
-
503: "Service Unavailable",
|
|
58
|
-
504: "Gateway Timeout",
|
|
59
|
-
505: "HTTP Version Not Supported",
|
|
60
|
-
506: "Variant Also Negotiates",
|
|
61
|
-
507: "Insufficient Storage",
|
|
62
|
-
508: "Loop Detected",
|
|
63
|
-
510: "Not Extended",
|
|
64
|
-
511: "Network Authentication Required"
|
|
65
|
-
};
|
|
66
|
-
const METHODS = [
|
|
67
|
-
"ACL",
|
|
68
|
-
"BIND",
|
|
69
|
-
"CHECKOUT",
|
|
70
|
-
"CONNECT",
|
|
71
|
-
"COPY",
|
|
72
|
-
"DELETE",
|
|
73
|
-
"GET",
|
|
74
|
-
"HEAD",
|
|
75
|
-
"LINK",
|
|
76
|
-
"LOCK",
|
|
77
|
-
"M-SEARCH",
|
|
78
|
-
"MERGE",
|
|
79
|
-
"MKACTIVITY",
|
|
80
|
-
"MKCALENDAR",
|
|
81
|
-
"MKCOL",
|
|
82
|
-
"MOVE",
|
|
83
|
-
"NOTIFY",
|
|
84
|
-
"OPTIONS",
|
|
85
|
-
"PATCH",
|
|
86
|
-
"POST",
|
|
87
|
-
"PRI",
|
|
88
|
-
"PROPFIND",
|
|
89
|
-
"PROPPATCH",
|
|
90
|
-
"PURGE",
|
|
91
|
-
"PUT",
|
|
92
|
-
"REBIND",
|
|
93
|
-
"REPORT",
|
|
94
|
-
"SEARCH",
|
|
95
|
-
"SOURCE",
|
|
96
|
-
"SUBSCRIBE",
|
|
97
|
-
"TRACE",
|
|
98
|
-
"UNBIND",
|
|
99
|
-
"UNLINK",
|
|
100
|
-
"UNLOCK",
|
|
101
|
-
"UNSUBSCRIBE"
|
|
102
|
-
];
|
|
103
|
-
|
|
104
|
-
//#endregion
|
|
105
|
-
export { METHODS, STATUS_CODES };
|
|
1
|
+
const e={100:`Continue`,101:`Switching Protocols`,102:`Processing`,103:`Early Hints`,200:`OK`,201:`Created`,202:`Accepted`,203:`Non-Authoritative Information`,204:`No Content`,205:`Reset Content`,206:`Partial Content`,207:`Multi-Status`,208:`Already Reported`,226:`IM Used`,300:`Multiple Choices`,301:`Moved Permanently`,302:`Found`,303:`See Other`,304:`Not Modified`,305:`Use Proxy`,307:`Temporary Redirect`,308:`Permanent Redirect`,400:`Bad Request`,401:`Unauthorized`,402:`Payment Required`,403:`Forbidden`,404:`Not Found`,405:`Method Not Allowed`,406:`Not Acceptable`,407:`Proxy Authentication Required`,408:`Request Timeout`,409:`Conflict`,410:`Gone`,411:`Length Required`,412:`Precondition Failed`,413:`Payload Too Large`,414:`URI Too Long`,415:`Unsupported Media Type`,416:`Range Not Satisfiable`,417:`Expectation Failed`,418:`I'm a Teapot`,421:`Misdirected Request`,422:`Unprocessable Entity`,423:`Locked`,424:`Failed Dependency`,425:`Too Early`,426:`Upgrade Required`,428:`Precondition Required`,429:`Too Many Requests`,431:`Request Header Fields Too Large`,451:`Unavailable For Legal Reasons`,500:`Internal Server Error`,501:`Not Implemented`,502:`Bad Gateway`,503:`Service Unavailable`,504:`Gateway Timeout`,505:`HTTP Version Not Supported`,506:`Variant Also Negotiates`,507:`Insufficient Storage`,508:`Loop Detected`,510:`Not Extended`,511:`Network Authentication Required`},t=`ACL.BIND.CHECKOUT.CONNECT.COPY.DELETE.GET.HEAD.LINK.LOCK.M-SEARCH.MERGE.MKACTIVITY.MKCALENDAR.MKCOL.MOVE.NOTIFY.OPTIONS.PATCH.POST.PRI.PROPFIND.PROPPATCH.PURGE.PUT.REBIND.REPORT.SEARCH.SOURCE.SUBSCRIBE.TRACE.UNBIND.UNLINK.UNLOCK.UNSUBSCRIBE`.split(`.`);export{t as METHODS,e as STATUS_CODES};
|
|
@@ -1,68 +1 @@
|
|
|
1
|
-
import
|
|
2
|
-
import { Readable } from "node:stream";
|
|
3
|
-
|
|
4
|
-
//#region src/incoming-message.ts
|
|
5
|
-
/**
|
|
6
|
-
* IncomingMessage — Readable stream for HTTP request (server-side) or response (client-side).
|
|
7
|
-
*/
|
|
8
|
-
var IncomingMessage = class extends Readable {
|
|
9
|
-
httpVersion = "1.1";
|
|
10
|
-
httpVersionMajor = 1;
|
|
11
|
-
httpVersionMinor = 1;
|
|
12
|
-
headers = {};
|
|
13
|
-
rawHeaders = [];
|
|
14
|
-
method;
|
|
15
|
-
url;
|
|
16
|
-
statusCode;
|
|
17
|
-
statusMessage;
|
|
18
|
-
complete = false;
|
|
19
|
-
socket = null;
|
|
20
|
-
aborted = false;
|
|
21
|
-
/** Node.js legacy alias for socket — needed by engine.io and other HTTP consumers. */
|
|
22
|
-
get connection() {
|
|
23
|
-
return this.socket;
|
|
24
|
-
}
|
|
25
|
-
_timeoutTimer = null;
|
|
26
|
-
constructor() {
|
|
27
|
-
super();
|
|
28
|
-
}
|
|
29
|
-
_read(_size) {}
|
|
30
|
-
_autoClose() {}
|
|
31
|
-
/** Finish the readable stream with the body data (used by server-side handler). */
|
|
32
|
-
_pushBody(body) {
|
|
33
|
-
if (body && body.length > 0) {
|
|
34
|
-
this.push(Buffer.from(body));
|
|
35
|
-
}
|
|
36
|
-
this.push(null);
|
|
37
|
-
this.complete = true;
|
|
38
|
-
if (this._timeoutTimer) {
|
|
39
|
-
clearTimeout(this._timeoutTimer);
|
|
40
|
-
this._timeoutTimer = null;
|
|
41
|
-
}
|
|
42
|
-
}
|
|
43
|
-
setTimeout(msecs, callback) {
|
|
44
|
-
if (this._timeoutTimer) {
|
|
45
|
-
clearTimeout(this._timeoutTimer);
|
|
46
|
-
this._timeoutTimer = null;
|
|
47
|
-
}
|
|
48
|
-
if (callback) this.once("timeout", callback);
|
|
49
|
-
if (msecs > 0) {
|
|
50
|
-
this._timeoutTimer = setTimeout(() => {
|
|
51
|
-
this._timeoutTimer = null;
|
|
52
|
-
this.emit("timeout");
|
|
53
|
-
}, msecs);
|
|
54
|
-
}
|
|
55
|
-
return this;
|
|
56
|
-
}
|
|
57
|
-
destroy(error) {
|
|
58
|
-
if (this._timeoutTimer) {
|
|
59
|
-
clearTimeout(this._timeoutTimer);
|
|
60
|
-
this._timeoutTimer = null;
|
|
61
|
-
}
|
|
62
|
-
this.aborted = true;
|
|
63
|
-
return super.destroy(error);
|
|
64
|
-
}
|
|
65
|
-
};
|
|
66
|
-
|
|
67
|
-
//#endregion
|
|
68
|
-
export { IncomingMessage };
|
|
1
|
+
import{Buffer as e}from"node:buffer";import{Readable as t}from"node:stream";var n=class extends t{httpVersion=`1.1`;httpVersionMajor=1;httpVersionMinor=1;headers={};rawHeaders=[];method;url;statusCode;statusMessage;complete=!1;socket=null;aborted=!1;get connection(){return this.socket}_timeoutTimer=null;constructor(){super()}_read(e){}_autoClose(){}_pushBody(t){t&&t.length>0&&this.push(e.from(t)),this.push(null),this.complete=!0,this._timeoutTimer&&=(clearTimeout(this._timeoutTimer),null)}setTimeout(e,t){return this._timeoutTimer&&=(clearTimeout(this._timeoutTimer),null),t&&this.once(`timeout`,t),e>0&&(this._timeoutTimer=setTimeout(()=>{this._timeoutTimer=null,this.emit(`timeout`)},e)),this}destroy(e){return this._timeoutTimer&&=(clearTimeout(this._timeoutTimer),null),this.aborted=!0,super.destroy(e)}};export{n as IncomingMessage};
|
package/lib/esm/index.js
CHANGED
|
@@ -1,126 +1 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { IncomingMessage } from "./incoming-message.js";
|
|
3
|
-
import { OutgoingMessage, Server, ServerResponse } from "./server.js";
|
|
4
|
-
import { ClientRequest } from "./client-request.js";
|
|
5
|
-
import { validateHeaderName, validateHeaderValue } from "./validators.js";
|
|
6
|
-
import { URL } from "node:url";
|
|
7
|
-
|
|
8
|
-
//#region src/index.ts
|
|
9
|
-
/**
|
|
10
|
-
* Agent class for connection pooling.
|
|
11
|
-
* Soup.Session handles actual TCP connection pooling internally.
|
|
12
|
-
* This class provides the Node.js-compatible API surface for frameworks.
|
|
13
|
-
*/
|
|
14
|
-
var Agent = class {
|
|
15
|
-
defaultPort = 80;
|
|
16
|
-
protocol = "http:";
|
|
17
|
-
maxSockets;
|
|
18
|
-
maxTotalSockets;
|
|
19
|
-
maxFreeSockets;
|
|
20
|
-
keepAliveMsecs;
|
|
21
|
-
keepAlive;
|
|
22
|
-
scheduling;
|
|
23
|
-
/** Pending requests per host (compatibility — Soup manages internally). */
|
|
24
|
-
requests = {};
|
|
25
|
-
/** Active sockets per host (compatibility — Soup manages internally). */
|
|
26
|
-
sockets = {};
|
|
27
|
-
/** Idle sockets per host (compatibility — Soup manages internally). */
|
|
28
|
-
freeSockets = {};
|
|
29
|
-
constructor(options) {
|
|
30
|
-
this.keepAlive = options?.keepAlive ?? false;
|
|
31
|
-
this.keepAliveMsecs = options?.keepAliveMsecs ?? 1e3;
|
|
32
|
-
this.maxSockets = options?.maxSockets ?? Infinity;
|
|
33
|
-
this.maxTotalSockets = options?.maxTotalSockets ?? Infinity;
|
|
34
|
-
this.maxFreeSockets = options?.maxFreeSockets ?? 256;
|
|
35
|
-
this.scheduling = options?.scheduling ?? "lifo";
|
|
36
|
-
}
|
|
37
|
-
/** Destroy the agent and close idle connections. */
|
|
38
|
-
destroy() {}
|
|
39
|
-
/** Return a connection pool key for the given options. */
|
|
40
|
-
getName(options) {
|
|
41
|
-
let name = options.host || "localhost";
|
|
42
|
-
if (options.port) name += ":" + options.port;
|
|
43
|
-
if (options.localAddress) name += ":" + options.localAddress;
|
|
44
|
-
if (options.family === 4 || options.family === 6) name += ":" + options.family;
|
|
45
|
-
return name;
|
|
46
|
-
}
|
|
47
|
-
};
|
|
48
|
-
const globalAgent = new Agent();
|
|
49
|
-
/**
|
|
50
|
-
* Create an HTTP server.
|
|
51
|
-
*/
|
|
52
|
-
function createServer(options, requestListener) {
|
|
53
|
-
if (typeof options === "function") {
|
|
54
|
-
return new Server(options);
|
|
55
|
-
}
|
|
56
|
-
return new Server(requestListener);
|
|
57
|
-
}
|
|
58
|
-
/**
|
|
59
|
-
* Make an HTTP request.
|
|
60
|
-
*
|
|
61
|
-
* @param url URL string, URL object, or request options
|
|
62
|
-
* @param options Request options (if url is string/URL)
|
|
63
|
-
* @param callback Response callback
|
|
64
|
-
*/
|
|
65
|
-
function request(url, options, callback) {
|
|
66
|
-
return new ClientRequest(url, options, callback);
|
|
67
|
-
}
|
|
68
|
-
/**
|
|
69
|
-
* Make an HTTP GET request (convenience wrapper that calls req.end() automatically).
|
|
70
|
-
*/
|
|
71
|
-
function get(url, options, callback) {
|
|
72
|
-
let opts;
|
|
73
|
-
let cb = callback;
|
|
74
|
-
if (typeof url === "string" || url instanceof URL) {
|
|
75
|
-
opts = typeof options === "object" ? {
|
|
76
|
-
...options,
|
|
77
|
-
method: "GET"
|
|
78
|
-
} : { method: "GET" };
|
|
79
|
-
if (typeof options === "function") cb = options;
|
|
80
|
-
} else {
|
|
81
|
-
opts = {
|
|
82
|
-
...url,
|
|
83
|
-
method: "GET"
|
|
84
|
-
};
|
|
85
|
-
if (typeof options === "function") cb = options;
|
|
86
|
-
url = opts;
|
|
87
|
-
}
|
|
88
|
-
const req = typeof url === "string" || url instanceof URL ? new ClientRequest(url, {
|
|
89
|
-
...opts,
|
|
90
|
-
method: "GET"
|
|
91
|
-
}, cb) : new ClientRequest({
|
|
92
|
-
...opts,
|
|
93
|
-
method: "GET"
|
|
94
|
-
}, cb);
|
|
95
|
-
req.end();
|
|
96
|
-
return req;
|
|
97
|
-
}
|
|
98
|
-
/** Max header size in bytes. */
|
|
99
|
-
const maxHeaderSize = 16384;
|
|
100
|
-
/**
|
|
101
|
-
* Set the maximum number of idle HTTP parsers. Soup.Session handles
|
|
102
|
-
* connection pooling internally, so this is a no-op for compatibility.
|
|
103
|
-
* @since v18.8.0
|
|
104
|
-
*/
|
|
105
|
-
function setMaxIdleHTTPParsers(_max) {}
|
|
106
|
-
var src_default = {
|
|
107
|
-
STATUS_CODES,
|
|
108
|
-
METHODS,
|
|
109
|
-
Server,
|
|
110
|
-
IncomingMessage,
|
|
111
|
-
OutgoingMessage,
|
|
112
|
-
ServerResponse,
|
|
113
|
-
ClientRequest,
|
|
114
|
-
Agent,
|
|
115
|
-
globalAgent,
|
|
116
|
-
createServer,
|
|
117
|
-
request,
|
|
118
|
-
get,
|
|
119
|
-
validateHeaderName,
|
|
120
|
-
validateHeaderValue,
|
|
121
|
-
maxHeaderSize,
|
|
122
|
-
setMaxIdleHTTPParsers
|
|
123
|
-
};
|
|
124
|
-
|
|
125
|
-
//#endregion
|
|
126
|
-
export { Agent, ClientRequest, IncomingMessage, METHODS, OutgoingMessage, STATUS_CODES, Server, ServerResponse, createServer, src_default as default, get, globalAgent, maxHeaderSize, request, setMaxIdleHTTPParsers, validateHeaderName, validateHeaderValue };
|
|
1
|
+
import{METHODS as e,STATUS_CODES as t}from"./constants.js";import{IncomingMessage as n}from"./incoming-message.js";import{OutgoingMessage as r,Server as i,ServerResponse as a}from"./server.js";import{ClientRequest as o}from"./client-request.js";import{validateHeaderName as s,validateHeaderValue as c}from"./validators.js";import{URL as l}from"node:url";var u=class{defaultPort=80;protocol=`http:`;maxSockets;maxTotalSockets;maxFreeSockets;keepAliveMsecs;keepAlive;scheduling;requests={};sockets={};freeSockets={};constructor(e){this.keepAlive=e?.keepAlive??!1,this.keepAliveMsecs=e?.keepAliveMsecs??1e3,this.maxSockets=e?.maxSockets??1/0,this.maxTotalSockets=e?.maxTotalSockets??1/0,this.maxFreeSockets=e?.maxFreeSockets??256,this.scheduling=e?.scheduling??`lifo`}destroy(){}getName(e){let t=e.host||`localhost`;return e.port&&(t+=`:`+e.port),e.localAddress&&(t+=`:`+e.localAddress),(e.family===4||e.family===6)&&(t+=`:`+e.family),t}};const d=new u;function f(e,t){return typeof e==`function`?new i(e):new i(t)}function p(e,t,n){return new o(e,t,n)}function m(e,t,n){let r,i=n;typeof e==`string`||e instanceof l?(r=typeof t==`object`?{...t,method:`GET`}:{method:`GET`},typeof t==`function`&&(i=t)):(r={...e,method:`GET`},typeof t==`function`&&(i=t),e=r);let a=typeof e==`string`||e instanceof l?new o(e,{...r,method:`GET`},i):new o({...r,method:`GET`},i);return a.end(),a}const h=16384;function g(e){}var _={STATUS_CODES:t,METHODS:e,Server:i,IncomingMessage:n,OutgoingMessage:r,ServerResponse:a,ClientRequest:o,Agent:u,globalAgent:d,createServer:f,request:p,get:m,validateHeaderName:s,validateHeaderValue:c,maxHeaderSize:h,setMaxIdleHTTPParsers:g};export{u as Agent,o as ClientRequest,n as IncomingMessage,e as METHODS,r as OutgoingMessage,t as STATUS_CODES,i as Server,a as ServerResponse,f as createServer,_ as default,m as get,d as globalAgent,h as maxHeaderSize,p as request,g as setMaxIdleHTTPParsers,s as validateHeaderName,c as validateHeaderValue};
|
|
@@ -1,71 +1 @@
|
|
|
1
|
-
import
|
|
2
|
-
|
|
3
|
-
//#region src/server-request-socket.ts
|
|
4
|
-
var ServerRequestSocket = class extends Duplex {
|
|
5
|
-
remoteAddress;
|
|
6
|
-
remotePort;
|
|
7
|
-
localAddress;
|
|
8
|
-
localPort;
|
|
9
|
-
remoteFamily = "IPv4";
|
|
10
|
-
encrypted;
|
|
11
|
-
connecting = false;
|
|
12
|
-
pending = false;
|
|
13
|
-
bytesRead = 0;
|
|
14
|
-
bytesWritten = 0;
|
|
15
|
-
_bridgeRes;
|
|
16
|
-
_bridgePaused = false;
|
|
17
|
-
constructor(remoteAddress, remotePort, localAddress, localPort, bridgeRes, encrypted = false) {
|
|
18
|
-
super({ allowHalfOpen: true });
|
|
19
|
-
this.remoteAddress = remoteAddress;
|
|
20
|
-
this.remotePort = remotePort;
|
|
21
|
-
this.localAddress = localAddress;
|
|
22
|
-
this.localPort = localPort;
|
|
23
|
-
this.encrypted = encrypted;
|
|
24
|
-
this._bridgeRes = bridgeRes;
|
|
25
|
-
}
|
|
26
|
-
pause() {
|
|
27
|
-
if (this._bridgePaused) return this;
|
|
28
|
-
this._bridgePaused = true;
|
|
29
|
-
return super.pause();
|
|
30
|
-
}
|
|
31
|
-
resume() {
|
|
32
|
-
if (!this._bridgePaused) return super.resume();
|
|
33
|
-
this._bridgePaused = false;
|
|
34
|
-
return super.resume();
|
|
35
|
-
}
|
|
36
|
-
_read(_size) {}
|
|
37
|
-
_write(_chunk, _encoding, cb) {
|
|
38
|
-
cb();
|
|
39
|
-
}
|
|
40
|
-
destroySoon() {
|
|
41
|
-
if (!this.writableEnded) this.end();
|
|
42
|
-
if (this.writableFinished) this.destroy();
|
|
43
|
-
else this.once("finish", () => this.destroy());
|
|
44
|
-
}
|
|
45
|
-
setTimeout(_timeout, cb) {
|
|
46
|
-
if (cb) this.once("timeout", cb);
|
|
47
|
-
return this;
|
|
48
|
-
}
|
|
49
|
-
setNoDelay(_noDelay) {
|
|
50
|
-
return this;
|
|
51
|
-
}
|
|
52
|
-
setKeepAlive(_enable, _delay) {
|
|
53
|
-
return this;
|
|
54
|
-
}
|
|
55
|
-
ref() {
|
|
56
|
-
return this;
|
|
57
|
-
}
|
|
58
|
-
unref() {
|
|
59
|
-
return this;
|
|
60
|
-
}
|
|
61
|
-
address() {
|
|
62
|
-
return {
|
|
63
|
-
address: this.localAddress,
|
|
64
|
-
family: "IPv4",
|
|
65
|
-
port: this.localPort
|
|
66
|
-
};
|
|
67
|
-
}
|
|
68
|
-
};
|
|
69
|
-
|
|
70
|
-
//#endregion
|
|
71
|
-
export { ServerRequestSocket };
|
|
1
|
+
import{Duplex as e}from"node:stream";var t=class extends e{remoteAddress;remotePort;localAddress;localPort;remoteFamily=`IPv4`;encrypted;connecting=!1;pending=!1;bytesRead=0;bytesWritten=0;_bridgeRes;_bridgePaused=!1;constructor(e,t,n,r,i,a=!1){super({allowHalfOpen:!0}),this.remoteAddress=e,this.remotePort=t,this.localAddress=n,this.localPort=r,this.encrypted=a,this._bridgeRes=i}pause(){return this._bridgePaused?this:(this._bridgePaused=!0,super.pause())}resume(){return this._bridgePaused&&=!1,super.resume()}_read(e){}_write(e,t,n){n()}destroySoon(){this.writableEnded||this.end(),this.writableFinished?this.destroy():this.once(`finish`,()=>this.destroy())}setTimeout(e,t){return t&&this.once(`timeout`,t),this}setNoDelay(e){return this}setKeepAlive(e,t){return this}ref(){return this}unref(){return this}address(){return{address:this.localAddress,family:`IPv4`,port:this.localPort}}};export{t as ServerRequestSocket};
|