@php-wasm/universal 1.0.28 → 1.1.0
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/index.cjs +5 -5
- package/index.cjs.map +1 -1
- package/index.js +386 -342
- package/index.js.map +1 -1
- package/lib/fs-helpers.d.ts +1 -1
- package/lib/http-cookie-store.d.ts +2 -1
- package/lib/index.d.ts +2 -2
- package/lib/ini.d.ts +1 -1
- package/lib/iterate-files.d.ts +1 -1
- package/lib/load-php-runtime.d.ts +4 -4
- package/lib/php-process-manager.d.ts +1 -1
- package/lib/php-request-handler.d.ts +23 -4
- package/lib/php-worker.d.ts +6 -6
- package/lib/php.d.ts +8 -6
- package/lib/proxy-file-system.d.ts +1 -1
- package/lib/rethrow-file-system-error.d.ts +1 -1
- package/lib/rotate-php-runtime.d.ts +1 -1
- package/lib/stream-read-file-from-php.d.ts +1 -1
- package/lib/supported-php-versions.d.ts +1 -1
- package/lib/universal-php.d.ts +2 -2
- package/lib/write-files-stream-to-php.d.ts +1 -1
- package/lib/write-files.d.ts +3 -3
- package/package.json +17 -10
package/index.js
CHANGED
|
@@ -1,13 +1,8 @@
|
|
|
1
|
-
var
|
|
2
|
-
|
|
3
|
-
throw TypeError("Cannot " + r);
|
|
1
|
+
var C = (t) => {
|
|
2
|
+
throw TypeError(t);
|
|
4
3
|
};
|
|
5
|
-
var
|
|
6
|
-
|
|
7
|
-
throw TypeError("Cannot add the same private member more than once");
|
|
8
|
-
e instanceof WeakSet ? e.add(t) : e.set(t, r);
|
|
9
|
-
}, d = (t, e, r, s) => (V(t, e, "write to private field"), s ? s.call(t, r) : e.set(t, r), r);
|
|
10
|
-
var h = (t, e, r) => (V(t, e, "access private method"), r);
|
|
4
|
+
var I = (t, e, r) => e.has(t) || C("Cannot " + r);
|
|
5
|
+
var c = (t, e, r) => (I(t, e, "read from private field"), r ? r.call(t) : e.get(t)), h = (t, e, r) => e.has(t) ? C("Cannot add the same private member more than once") : e instanceof WeakSet ? e.add(t) : e.set(t, r), m = (t, e, r, s) => (I(t, e, "write to private field"), s ? s.call(t, r) : e.set(t, r), r), d = (t, e, r) => (I(t, e, "access private method"), r);
|
|
11
6
|
import "@php-wasm/node-polyfills";
|
|
12
7
|
import { logger } from "@php-wasm/logger";
|
|
13
8
|
import { dirname, joinPaths, Semaphore, createSpawnHandler, normalizePath, AcquireTimeoutError } from "@php-wasm/util";
|
|
@@ -98,39 +93,64 @@ function getEmscriptenFsError(t) {
|
|
|
98
93
|
return FileErrorCodes[e];
|
|
99
94
|
}
|
|
100
95
|
function rethrowFileSystemError(t = "") {
|
|
101
|
-
return function(r
|
|
102
|
-
|
|
103
|
-
i.value = function(...o) {
|
|
96
|
+
return function(r) {
|
|
97
|
+
return function(...s) {
|
|
104
98
|
try {
|
|
105
|
-
return
|
|
106
|
-
} catch (
|
|
107
|
-
const
|
|
108
|
-
if (
|
|
109
|
-
const
|
|
110
|
-
throw new Error(`${
|
|
111
|
-
cause:
|
|
99
|
+
return r.apply(this, s);
|
|
100
|
+
} catch (i) {
|
|
101
|
+
const o = typeof i == "object" ? i == null ? void 0 : i.errno : null;
|
|
102
|
+
if (o in FileErrorCodes) {
|
|
103
|
+
const n = FileErrorCodes[o], l = typeof s[1] == "string" ? s[1] : null, a = l !== null ? t.replaceAll("{path}", l) : t;
|
|
104
|
+
throw new Error(`${a}: ${n}`, {
|
|
105
|
+
cause: i
|
|
112
106
|
});
|
|
113
107
|
}
|
|
114
|
-
throw
|
|
108
|
+
throw i;
|
|
115
109
|
}
|
|
116
110
|
};
|
|
117
111
|
};
|
|
118
112
|
}
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
}
|
|
124
|
-
|
|
113
|
+
class FSHelpers {
|
|
114
|
+
/**
|
|
115
|
+
* Reads a file from the PHP filesystem and returns it as a string.
|
|
116
|
+
*
|
|
117
|
+
* @throws {@link @php-wasm/universal:ErrnoError} – If the file doesn't exist.
|
|
118
|
+
* @param FS
|
|
119
|
+
* @param path - The file path to read.
|
|
120
|
+
* @returns The file contents.
|
|
121
|
+
*/
|
|
125
122
|
static readFileAsText(e, r) {
|
|
126
|
-
return new TextDecoder().decode(
|
|
123
|
+
return new TextDecoder().decode(FSHelpers.readFileAsBuffer(e, r));
|
|
127
124
|
}
|
|
125
|
+
/**
|
|
126
|
+
* Reads a file from the PHP filesystem and returns it as an array buffer.
|
|
127
|
+
*
|
|
128
|
+
* @throws {@link @php-wasm/universal:ErrnoError} – If the file doesn't exist.
|
|
129
|
+
* @param FS
|
|
130
|
+
* @param path - The file path to read.
|
|
131
|
+
* @returns The file contents.
|
|
132
|
+
*/
|
|
128
133
|
static readFileAsBuffer(e, r) {
|
|
129
134
|
return e.readFile(r);
|
|
130
135
|
}
|
|
136
|
+
/**
|
|
137
|
+
* Overwrites data in a file in the PHP filesystem.
|
|
138
|
+
* Creates a new file if one doesn't exist yet.
|
|
139
|
+
*
|
|
140
|
+
* @param FS
|
|
141
|
+
* @param path - The file path to write to.
|
|
142
|
+
* @param data - The data to write to the file.
|
|
143
|
+
*/
|
|
131
144
|
static writeFile(e, r, s) {
|
|
132
145
|
e.writeFile(r, s);
|
|
133
146
|
}
|
|
147
|
+
/**
|
|
148
|
+
* Removes a file from the PHP filesystem.
|
|
149
|
+
*
|
|
150
|
+
* @throws {@link @php-wasm/universal:ErrnoError} – If the file doesn't exist.
|
|
151
|
+
* @param FS
|
|
152
|
+
* @param path - The file path to remove.
|
|
153
|
+
*/
|
|
134
154
|
static unlink(e, r) {
|
|
135
155
|
e.unlink(r);
|
|
136
156
|
}
|
|
@@ -144,45 +164,74 @@ const _FSHelpers = class m {
|
|
|
144
164
|
*/
|
|
145
165
|
static mv(e, r, s) {
|
|
146
166
|
try {
|
|
147
|
-
const i = e.lookupPath(r).node.mount,
|
|
148
|
-
i.mountpoint !==
|
|
167
|
+
const i = e.lookupPath(r).node.mount, o = FSHelpers.fileExists(e, s) ? e.lookupPath(s).node.mount : e.lookupPath(dirname(s)).node.mount;
|
|
168
|
+
i.mountpoint !== o.mountpoint ? (FSHelpers.copyRecursive(e, r, s), FSHelpers.isDir(e, r) ? FSHelpers.rmdir(e, r, { recursive: !0 }) : e.unlink(r)) : e.rename(r, s);
|
|
149
169
|
} catch (i) {
|
|
150
|
-
const
|
|
151
|
-
throw
|
|
152
|
-
`Could not move ${r} to ${s}: ${
|
|
170
|
+
const o = getEmscriptenFsError(i);
|
|
171
|
+
throw o ? new Error(
|
|
172
|
+
`Could not move ${r} to ${s}: ${o}`,
|
|
153
173
|
{
|
|
154
174
|
cause: i
|
|
155
175
|
}
|
|
156
176
|
) : i;
|
|
157
177
|
}
|
|
158
178
|
}
|
|
179
|
+
/**
|
|
180
|
+
* Removes a directory from the PHP filesystem.
|
|
181
|
+
*
|
|
182
|
+
* @param FS
|
|
183
|
+
* @param path The directory path to remove.
|
|
184
|
+
* @param options Options for the removal.
|
|
185
|
+
*/
|
|
159
186
|
static rmdir(e, r, s = { recursive: !0 }) {
|
|
160
|
-
s != null && s.recursive &&
|
|
161
|
-
const
|
|
162
|
-
|
|
187
|
+
s != null && s.recursive && FSHelpers.listFiles(e, r).forEach((i) => {
|
|
188
|
+
const o = `${r}/${i}`;
|
|
189
|
+
FSHelpers.isDir(e, o) ? FSHelpers.rmdir(e, o, s) : FSHelpers.unlink(e, o);
|
|
163
190
|
}), e.rmdir(r);
|
|
164
191
|
}
|
|
192
|
+
/**
|
|
193
|
+
* Lists the files and directories in the given directory.
|
|
194
|
+
*
|
|
195
|
+
* @param FS
|
|
196
|
+
* @param path - The directory path to list.
|
|
197
|
+
* @param options - Options for the listing.
|
|
198
|
+
* @returns The list of files and directories in the given directory.
|
|
199
|
+
*/
|
|
165
200
|
static listFiles(e, r, s = { prependPath: !1 }) {
|
|
166
|
-
if (!
|
|
201
|
+
if (!FSHelpers.fileExists(e, r))
|
|
167
202
|
return [];
|
|
168
203
|
try {
|
|
169
204
|
const i = e.readdir(r).filter(
|
|
170
|
-
(
|
|
205
|
+
(o) => o !== "." && o !== ".."
|
|
171
206
|
);
|
|
172
207
|
if (s.prependPath) {
|
|
173
|
-
const
|
|
174
|
-
return i.map((
|
|
208
|
+
const o = r.replace(/\/$/, "");
|
|
209
|
+
return i.map((n) => `${o}/${n}`);
|
|
175
210
|
}
|
|
176
211
|
return i;
|
|
177
212
|
} catch (i) {
|
|
178
213
|
return logger.error(i, { path: r }), [];
|
|
179
214
|
}
|
|
180
215
|
}
|
|
216
|
+
/**
|
|
217
|
+
* Checks if a directory exists in the PHP filesystem.
|
|
218
|
+
*
|
|
219
|
+
* @param FS
|
|
220
|
+
* @param path – The path to check.
|
|
221
|
+
* @returns True if the path is a directory, false otherwise.
|
|
222
|
+
*/
|
|
181
223
|
static isDir(e, r) {
|
|
182
|
-
return
|
|
224
|
+
return FSHelpers.fileExists(e, r) ? e.isDir(e.lookupPath(r, { follow: !0 }).node.mode) : !1;
|
|
183
225
|
}
|
|
226
|
+
/**
|
|
227
|
+
* Checks if a file exists in the PHP filesystem.
|
|
228
|
+
*
|
|
229
|
+
* @param FS
|
|
230
|
+
* @param path – The path to check.
|
|
231
|
+
* @returns True if the path is a file, false otherwise.
|
|
232
|
+
*/
|
|
184
233
|
static isFile(e, r) {
|
|
185
|
-
return
|
|
234
|
+
return FSHelpers.fileExists(e, r) ? e.isFile(e.lookupPath(r, { follow: !0 }).node.mode) : !1;
|
|
186
235
|
}
|
|
187
236
|
/**
|
|
188
237
|
* Creates a symlink in the PHP filesystem.
|
|
@@ -202,7 +251,7 @@ const _FSHelpers = class m {
|
|
|
202
251
|
* @returns True if the path is a symlink, false otherwise.
|
|
203
252
|
*/
|
|
204
253
|
static isSymlink(e, r) {
|
|
205
|
-
return
|
|
254
|
+
return FSHelpers.fileExists(e, r) ? e.isLink(e.lookupPath(r).node.mode) : !1;
|
|
206
255
|
}
|
|
207
256
|
/**
|
|
208
257
|
* Reads the target of a symlink in the PHP filesystem.
|
|
@@ -214,9 +263,23 @@ const _FSHelpers = class m {
|
|
|
214
263
|
static readlink(e, r) {
|
|
215
264
|
return e.readlink(r);
|
|
216
265
|
}
|
|
266
|
+
/**
|
|
267
|
+
* Gets the real path of a file in the PHP filesystem.
|
|
268
|
+
* @param FS
|
|
269
|
+
* @param path
|
|
270
|
+
*
|
|
271
|
+
* @returns The real path of the file.
|
|
272
|
+
*/
|
|
217
273
|
static realpath(e, r) {
|
|
218
274
|
return e.lookupPath(r, { follow: !0 }).path;
|
|
219
275
|
}
|
|
276
|
+
/**
|
|
277
|
+
* Checks if a file (or a directory) exists in the PHP filesystem.
|
|
278
|
+
*
|
|
279
|
+
* @param FS
|
|
280
|
+
* @param path - The file path to check.
|
|
281
|
+
* @returns True if the file exists, false otherwise.
|
|
282
|
+
*/
|
|
220
283
|
static fileExists(e, r) {
|
|
221
284
|
try {
|
|
222
285
|
return e.lookupPath(r), !0;
|
|
@@ -224,6 +287,14 @@ const _FSHelpers = class m {
|
|
|
224
287
|
return !1;
|
|
225
288
|
}
|
|
226
289
|
}
|
|
290
|
+
/**
|
|
291
|
+
* Recursively creates a directory with the given path in the PHP filesystem.
|
|
292
|
+
* For example, if the path is `/root/php/data`, and `/root` already exists,
|
|
293
|
+
* it will create the directories `/root/php` and `/root/php/data`.
|
|
294
|
+
*
|
|
295
|
+
* @param FS
|
|
296
|
+
* @param path - The directory path to create.
|
|
297
|
+
*/
|
|
227
298
|
static mkdir(e, r) {
|
|
228
299
|
e.mkdirTree(r);
|
|
229
300
|
}
|
|
@@ -231,56 +302,55 @@ const _FSHelpers = class m {
|
|
|
231
302
|
const i = e.lookupPath(r).node;
|
|
232
303
|
if (e.isDir(i.mode)) {
|
|
233
304
|
e.mkdirTree(s);
|
|
234
|
-
const
|
|
235
|
-
(
|
|
305
|
+
const o = e.readdir(r).filter(
|
|
306
|
+
(n) => n !== "." && n !== ".."
|
|
236
307
|
);
|
|
237
|
-
for (const
|
|
238
|
-
|
|
308
|
+
for (const n of o)
|
|
309
|
+
FSHelpers.copyRecursive(
|
|
239
310
|
e,
|
|
240
|
-
joinPaths(r,
|
|
241
|
-
joinPaths(s,
|
|
311
|
+
joinPaths(r, n),
|
|
312
|
+
joinPaths(s, n)
|
|
242
313
|
);
|
|
243
314
|
} else
|
|
244
315
|
e.writeFile(s, e.readFile(r));
|
|
245
316
|
}
|
|
246
|
-
}
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
let FSHelpers = _FSHelpers;
|
|
317
|
+
}
|
|
318
|
+
FSHelpers.readFileAsText = rethrowFileSystemError('Could not read "{path}"')(
|
|
319
|
+
FSHelpers.readFileAsText
|
|
320
|
+
);
|
|
321
|
+
FSHelpers.readFileAsBuffer = rethrowFileSystemError('Could not read "{path}"')(
|
|
322
|
+
FSHelpers.readFileAsBuffer
|
|
323
|
+
);
|
|
324
|
+
FSHelpers.writeFile = rethrowFileSystemError('Could not write to "{path}"')(
|
|
325
|
+
FSHelpers.writeFile
|
|
326
|
+
);
|
|
327
|
+
FSHelpers.unlink = rethrowFileSystemError('Could not unlink "{path}"')(
|
|
328
|
+
FSHelpers.unlink
|
|
329
|
+
);
|
|
330
|
+
FSHelpers.rmdir = rethrowFileSystemError('Could not remove directory "{path}"')(
|
|
331
|
+
FSHelpers.rmdir
|
|
332
|
+
);
|
|
333
|
+
FSHelpers.listFiles = rethrowFileSystemError(
|
|
334
|
+
'Could not list files in "{path}"'
|
|
335
|
+
)(FSHelpers.listFiles);
|
|
336
|
+
FSHelpers.isDir = rethrowFileSystemError('Could not stat "{path}"')(
|
|
337
|
+
FSHelpers.isDir
|
|
338
|
+
);
|
|
339
|
+
FSHelpers.isFile = rethrowFileSystemError('Could not stat "{path}"')(
|
|
340
|
+
FSHelpers.isFile
|
|
341
|
+
);
|
|
342
|
+
FSHelpers.realpath = rethrowFileSystemError('Could not stat "{path}"')(
|
|
343
|
+
FSHelpers.realpath
|
|
344
|
+
);
|
|
345
|
+
FSHelpers.fileExists = rethrowFileSystemError('Could not stat "{path}"')(
|
|
346
|
+
FSHelpers.fileExists
|
|
347
|
+
);
|
|
348
|
+
FSHelpers.mkdir = rethrowFileSystemError('Could not create directory "{path}"')(
|
|
349
|
+
FSHelpers.mkdir
|
|
350
|
+
);
|
|
351
|
+
FSHelpers.copyRecursive = rethrowFileSystemError(
|
|
352
|
+
'Could not copy files from "{path}"'
|
|
353
|
+
)(FSHelpers.copyRecursive);
|
|
284
354
|
const _private = /* @__PURE__ */ new WeakMap();
|
|
285
355
|
class PHPWorker {
|
|
286
356
|
/** @inheritDoc */
|
|
@@ -428,8 +498,8 @@ const responseTexts = {
|
|
|
428
498
|
200: "OK"
|
|
429
499
|
};
|
|
430
500
|
class PHPResponse {
|
|
431
|
-
constructor(e, r, s, i = "",
|
|
432
|
-
this.httpStatusCode = e, this.headers = r, this.bytes = s, this.exitCode =
|
|
501
|
+
constructor(e, r, s, i = "", o = 0) {
|
|
502
|
+
this.httpStatusCode = e, this.headers = r, this.bytes = s, this.exitCode = o, this.errors = i;
|
|
433
503
|
}
|
|
434
504
|
static forHttpCode(e, r = "") {
|
|
435
505
|
return new PHPResponse(
|
|
@@ -473,27 +543,27 @@ class PHPResponse {
|
|
|
473
543
|
}
|
|
474
544
|
const RuntimeId = Symbol("RuntimeId"), loadedRuntimes = /* @__PURE__ */ new Map();
|
|
475
545
|
let lastRuntimeId = 0;
|
|
476
|
-
async function loadPHPRuntime(t, e
|
|
477
|
-
const
|
|
546
|
+
async function loadPHPRuntime(t, ...e) {
|
|
547
|
+
const r = Object.assign({}, ...e), [s, i, o] = makePromise(), n = t.init(currentJsRuntime, {
|
|
478
548
|
onAbort(a) {
|
|
479
|
-
|
|
549
|
+
o(a), logger.error(a);
|
|
480
550
|
},
|
|
481
551
|
ENV: {},
|
|
482
552
|
// Emscripten sometimes prepends a '/' to the path, which
|
|
483
553
|
// breaks vite dev mode. An identity `locateFile` function
|
|
484
554
|
// fixes it.
|
|
485
555
|
locateFile: (a) => a,
|
|
486
|
-
...
|
|
556
|
+
...r,
|
|
487
557
|
noInitialRun: !0,
|
|
488
558
|
onRuntimeInitialized() {
|
|
489
|
-
|
|
559
|
+
r.onRuntimeInitialized && r.onRuntimeInitialized(n), i();
|
|
490
560
|
}
|
|
491
561
|
});
|
|
492
|
-
await
|
|
493
|
-
const
|
|
494
|
-
return n.FS, n.id =
|
|
495
|
-
return n.outboundNetworkProxyServer && (n.outboundNetworkProxyServer.close(), n.outboundNetworkProxyServer.closeAllConnections()), loadedRuntimes.delete(
|
|
496
|
-
}, n[RuntimeId] =
|
|
562
|
+
await s;
|
|
563
|
+
const l = ++lastRuntimeId;
|
|
564
|
+
return n.FS, n.id = l, n.originalExit = n._exit, n._exit = function(a) {
|
|
565
|
+
return n.outboundNetworkProxyServer && (n.outboundNetworkProxyServer.close(), n.outboundNetworkProxyServer.closeAllConnections()), loadedRuntimes.delete(l), n.originalExit(a);
|
|
566
|
+
}, n[RuntimeId] = l, loadedRuntimes.set(l, n), l;
|
|
497
567
|
}
|
|
498
568
|
function getLoadedRuntime(t) {
|
|
499
569
|
return loadedRuntimes.get(t);
|
|
@@ -506,8 +576,10 @@ const currentJsRuntime = function() {
|
|
|
506
576
|
t.push(r, s);
|
|
507
577
|
});
|
|
508
578
|
return t.unshift(e), t;
|
|
509
|
-
}
|
|
510
|
-
|
|
579
|
+
};
|
|
580
|
+
var _a;
|
|
581
|
+
const kError = Symbol("error"), kMessage = Symbol("message");
|
|
582
|
+
class ErrorEvent2 extends (_a = Event, _a) {
|
|
511
583
|
/**
|
|
512
584
|
* Create a new `ErrorEvent`.
|
|
513
585
|
*
|
|
@@ -551,26 +623,26 @@ function improveWASMErrorReporting(t) {
|
|
|
551
623
|
if (typeof t.wasmExports[r] == "function") {
|
|
552
624
|
const s = t.wasmExports[r];
|
|
553
625
|
t.wasmExports[r] = function(...i) {
|
|
554
|
-
var
|
|
626
|
+
var o;
|
|
555
627
|
try {
|
|
556
628
|
return s(...i);
|
|
557
|
-
} catch (
|
|
558
|
-
if (!(
|
|
559
|
-
throw
|
|
560
|
-
const
|
|
561
|
-
|
|
562
|
-
(
|
|
629
|
+
} catch (n) {
|
|
630
|
+
if (!(n instanceof Error))
|
|
631
|
+
throw n;
|
|
632
|
+
const l = clarifyErrorMessage(
|
|
633
|
+
n,
|
|
634
|
+
(o = t.lastAsyncifyStackSource) == null ? void 0 : o.stack
|
|
563
635
|
);
|
|
564
|
-
if (t.lastAsyncifyStackSource && (
|
|
636
|
+
if (t.lastAsyncifyStackSource && (n.cause = t.lastAsyncifyStackSource), e.hasListeners()) {
|
|
565
637
|
e.dispatchEvent(
|
|
566
638
|
new ErrorEvent("error", {
|
|
567
|
-
error:
|
|
568
|
-
message:
|
|
639
|
+
error: n,
|
|
640
|
+
message: l
|
|
569
641
|
})
|
|
570
642
|
);
|
|
571
643
|
return;
|
|
572
644
|
}
|
|
573
|
-
throw isExitCodeZero(
|
|
645
|
+
throw isExitCodeZero(n) || showCriticalErrorBox(l), n;
|
|
574
646
|
}
|
|
575
647
|
};
|
|
576
648
|
}
|
|
@@ -659,7 +731,7 @@ class PHPExecutionFailureError extends Error {
|
|
|
659
731
|
}
|
|
660
732
|
}
|
|
661
733
|
const PHP_INI_PATH = "/internal/shared/php.ini", AUTO_PREPEND_SCRIPT = "/internal/shared/auto_prepend_file.php";
|
|
662
|
-
var
|
|
734
|
+
var F, P, v, _, x, R, u, N, M, j, U, L, q, $, B, O, D, A, z, W, G;
|
|
663
735
|
class PHP {
|
|
664
736
|
/**
|
|
665
737
|
* Initializes a PHP runtime.
|
|
@@ -669,36 +741,14 @@ class PHP {
|
|
|
669
741
|
* @param requestHandlerOptions - Optional. Options for the PHPRequestHandler. If undefined, no request handler will be initialized.
|
|
670
742
|
*/
|
|
671
743
|
constructor(t) {
|
|
672
|
-
|
|
673
|
-
|
|
674
|
-
|
|
675
|
-
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
*/
|
|
681
|
-
u(this, I);
|
|
682
|
-
u(this, C);
|
|
683
|
-
u(this, A);
|
|
684
|
-
u(this, N);
|
|
685
|
-
u(this, j);
|
|
686
|
-
u(this, M);
|
|
687
|
-
u(this, U);
|
|
688
|
-
u(this, L);
|
|
689
|
-
u(this, q);
|
|
690
|
-
u(this, $);
|
|
691
|
-
u(this, k);
|
|
692
|
-
u(this, O);
|
|
693
|
-
u(this, B);
|
|
694
|
-
u(this, D);
|
|
695
|
-
u(this, R, void 0);
|
|
696
|
-
u(this, g, void 0);
|
|
697
|
-
u(this, w, void 0);
|
|
698
|
-
u(this, _, void 0);
|
|
699
|
-
u(this, y, void 0);
|
|
700
|
-
u(this, x, void 0);
|
|
701
|
-
d(this, g, !1), d(this, w, null), d(this, _, /* @__PURE__ */ new Map()), d(this, y, []), d(this, x, {}), this.semaphore = new Semaphore({ concurrency: 1 }), t !== void 0 && this.initializeRuntime(t);
|
|
744
|
+
h(this, u);
|
|
745
|
+
h(this, F);
|
|
746
|
+
h(this, P, !1);
|
|
747
|
+
h(this, v, null);
|
|
748
|
+
h(this, _, /* @__PURE__ */ new Map());
|
|
749
|
+
h(this, x, []);
|
|
750
|
+
h(this, R, {});
|
|
751
|
+
this.semaphore = new Semaphore({ concurrency: 1 }), t !== void 0 && this.initializeRuntime(t);
|
|
702
752
|
}
|
|
703
753
|
/**
|
|
704
754
|
* Adds an event listener for a PHP event.
|
|
@@ -763,8 +813,8 @@ class PHP {
|
|
|
763
813
|
* @param listener Callback function to handle the message.
|
|
764
814
|
*/
|
|
765
815
|
onMessage(t) {
|
|
766
|
-
return c(this,
|
|
767
|
-
|
|
816
|
+
return c(this, x).push(t), async () => {
|
|
817
|
+
m(this, x, c(this, x).filter(
|
|
768
818
|
(e) => e !== t
|
|
769
819
|
));
|
|
770
820
|
};
|
|
@@ -840,13 +890,13 @@ class PHP {
|
|
|
840
890
|
}
|
|
841
891
|
`
|
|
842
892
|
), e.onMessage = async (r) => {
|
|
843
|
-
for (const s of c(this,
|
|
893
|
+
for (const s of c(this, x)) {
|
|
844
894
|
const i = await s(r);
|
|
845
895
|
if (i)
|
|
846
896
|
return i;
|
|
847
897
|
}
|
|
848
898
|
return "";
|
|
849
|
-
},
|
|
899
|
+
}, m(this, v, improveWASMErrorReporting(e)), this.dispatchEvent({
|
|
850
900
|
type: "runtime.initialized"
|
|
851
901
|
});
|
|
852
902
|
}
|
|
@@ -861,7 +911,7 @@ class PHP {
|
|
|
861
911
|
throw new Error(
|
|
862
912
|
"Could not set SAPI name. This can only be done before the PHP WASM module is initialized.Did you already dispatch any requests?"
|
|
863
913
|
);
|
|
864
|
-
|
|
914
|
+
m(this, F, t);
|
|
865
915
|
}
|
|
866
916
|
/**
|
|
867
917
|
* Changes the current working directory in the PHP filesystem.
|
|
@@ -958,37 +1008,37 @@ class PHP {
|
|
|
958
1008
|
const e = await this.semaphore.acquire();
|
|
959
1009
|
let r;
|
|
960
1010
|
try {
|
|
961
|
-
if (c(this,
|
|
1011
|
+
if (c(this, P) || (d(this, u, M).call(this), m(this, P, !0)), t.scriptPath && !this.fileExists(t.scriptPath))
|
|
962
1012
|
throw new Error(
|
|
963
1013
|
`The script path "${t.scriptPath}" does not exist.`
|
|
964
1014
|
);
|
|
965
|
-
|
|
966
|
-
const s = normalizeHeaders(t.headers || {}), i = s.host || "example.com:443",
|
|
967
|
-
if (
|
|
968
|
-
this.writeFile("/internal/eval.php", t.code),
|
|
1015
|
+
d(this, u, U).call(this, t.relativeUri || ""), d(this, u, B).call(this, t.method || "GET");
|
|
1016
|
+
const s = normalizeHeaders(t.headers || {}), i = s.host || "example.com:443", o = d(this, u, $).call(this, i, t.protocol || "http");
|
|
1017
|
+
if (d(this, u, L).call(this, i), d(this, u, q).call(this, o), d(this, u, O).call(this, s), t.body && (r = d(this, u, D).call(this, t.body)), typeof t.code == "string")
|
|
1018
|
+
this.writeFile("/internal/eval.php", t.code), d(this, u, A).call(this, "/internal/eval.php");
|
|
969
1019
|
else if (typeof t.scriptPath == "string")
|
|
970
|
-
|
|
1020
|
+
d(this, u, A).call(this, t.scriptPath || "");
|
|
971
1021
|
else
|
|
972
1022
|
throw new TypeError(
|
|
973
1023
|
"The request object must have either a `code` or a `scriptPath` property."
|
|
974
1024
|
);
|
|
975
|
-
const
|
|
976
|
-
for (const p in
|
|
977
|
-
|
|
978
|
-
const
|
|
979
|
-
for (const p in
|
|
980
|
-
|
|
981
|
-
const
|
|
982
|
-
if (
|
|
983
|
-
logger.warn("PHP.run() output was:",
|
|
1025
|
+
const n = d(this, u, N).call(this, t.$_SERVER, s, o);
|
|
1026
|
+
for (const p in n)
|
|
1027
|
+
d(this, u, z).call(this, p, n[p]);
|
|
1028
|
+
const l = t.env || {};
|
|
1029
|
+
for (const p in l)
|
|
1030
|
+
d(this, u, W).call(this, p, l[p]);
|
|
1031
|
+
const a = await d(this, u, G).call(this);
|
|
1032
|
+
if (a.exitCode !== 0) {
|
|
1033
|
+
logger.warn("PHP.run() output was:", a.text);
|
|
984
1034
|
const p = new PHPExecutionFailureError(
|
|
985
|
-
`PHP.run() failed with exit code ${
|
|
986
|
-
|
|
1035
|
+
`PHP.run() failed with exit code ${a.exitCode} and the following output: ` + a.errors,
|
|
1036
|
+
a,
|
|
987
1037
|
"request"
|
|
988
1038
|
);
|
|
989
1039
|
throw logger.error(p), p;
|
|
990
1040
|
}
|
|
991
|
-
return
|
|
1041
|
+
return a;
|
|
992
1042
|
} catch (s) {
|
|
993
1043
|
throw this.dispatchEvent({
|
|
994
1044
|
type: "request.error",
|
|
@@ -1188,15 +1238,15 @@ class PHP {
|
|
|
1188
1238
|
*/
|
|
1189
1239
|
async hotSwapPHPRuntime(t, e) {
|
|
1190
1240
|
const r = this[__private__dont__use].FS, s = [];
|
|
1191
|
-
for (const [i,
|
|
1192
|
-
s.push({ mountHandler:
|
|
1241
|
+
for (const [i, o] of Object.entries(c(this, R)))
|
|
1242
|
+
s.push({ mountHandler: o.mountHandler, vfsPath: i }), await o.unmount();
|
|
1193
1243
|
try {
|
|
1194
1244
|
this.exit();
|
|
1195
1245
|
} catch {
|
|
1196
1246
|
}
|
|
1197
|
-
this.initializeRuntime(t), c(this,
|
|
1198
|
-
for (const { mountHandler: i, vfsPath:
|
|
1199
|
-
this.mkdir(
|
|
1247
|
+
this.initializeRuntime(t), c(this, F) && this.setSapiName(c(this, F)), copyFS(r, this[__private__dont__use].FS, "/internal"), e && copyFS(r, this[__private__dont__use].FS, e);
|
|
1248
|
+
for (const { mountHandler: i, vfsPath: o } of s)
|
|
1249
|
+
this.mkdir(o), await this.mount(o, i);
|
|
1200
1250
|
}
|
|
1201
1251
|
/**
|
|
1202
1252
|
* Mounts a filesystem to a given path in the PHP filesystem.
|
|
@@ -1213,10 +1263,10 @@ class PHP {
|
|
|
1213
1263
|
), s = {
|
|
1214
1264
|
mountHandler: e,
|
|
1215
1265
|
unmount: async () => {
|
|
1216
|
-
await r(), delete c(this,
|
|
1266
|
+
await r(), delete c(this, R)[t];
|
|
1217
1267
|
}
|
|
1218
1268
|
};
|
|
1219
|
-
return c(this,
|
|
1269
|
+
return c(this, R)[t] = s, () => {
|
|
1220
1270
|
s.unmount();
|
|
1221
1271
|
};
|
|
1222
1272
|
}
|
|
@@ -1273,25 +1323,34 @@ class PHP {
|
|
|
1273
1323
|
this[__private__dont__use]._exit(t);
|
|
1274
1324
|
} catch {
|
|
1275
1325
|
}
|
|
1276
|
-
|
|
1326
|
+
m(this, P, !1), m(this, v, null), delete this[__private__dont__use].onMessage, delete this[__private__dont__use];
|
|
1277
1327
|
}
|
|
1278
1328
|
[Symbol.dispose]() {
|
|
1279
|
-
c(this,
|
|
1329
|
+
c(this, P) && this.exit(0);
|
|
1280
1330
|
}
|
|
1281
1331
|
}
|
|
1282
|
-
|
|
1332
|
+
F = new WeakMap(), P = new WeakMap(), v = new WeakMap(), _ = new WeakMap(), x = new WeakMap(), R = new WeakMap(), u = new WeakSet(), /**
|
|
1333
|
+
* Prepares the $_SERVER entries for the PHP runtime.
|
|
1334
|
+
*
|
|
1335
|
+
* @param defaults Default entries to include in $_SERVER.
|
|
1336
|
+
* @param headers HTTP headers to include in $_SERVER (as HTTP_ prefixed entries).
|
|
1337
|
+
* @param port HTTP port, used to determine infer $_SERVER['HTTPS'] value if none
|
|
1338
|
+
* was provided.
|
|
1339
|
+
* @returns Computed $_SERVER entries.
|
|
1340
|
+
*/
|
|
1341
|
+
N = function(t, e, r) {
|
|
1283
1342
|
const s = {
|
|
1284
1343
|
...t || {}
|
|
1285
1344
|
};
|
|
1286
1345
|
s.HTTPS = s.HTTPS || r === 443 ? "on" : "off";
|
|
1287
1346
|
for (const i in e) {
|
|
1288
|
-
let
|
|
1289
|
-
["content-type", "content-length"].includes(i.toLowerCase()) && (
|
|
1347
|
+
let o = "HTTP_";
|
|
1348
|
+
["content-type", "content-length"].includes(i.toLowerCase()) && (o = ""), s[`${o}${i.toUpperCase().replace(/-/g, "_")}`] = e[i];
|
|
1290
1349
|
}
|
|
1291
1350
|
return s;
|
|
1292
|
-
},
|
|
1351
|
+
}, M = function() {
|
|
1293
1352
|
this[__private__dont__use].ccall("php_wasm_init", null, [], []);
|
|
1294
|
-
},
|
|
1353
|
+
}, j = function() {
|
|
1295
1354
|
const t = "/internal/headers.json";
|
|
1296
1355
|
if (!this.fileExists(t))
|
|
1297
1356
|
throw new Error(
|
|
@@ -1301,57 +1360,56 @@ R = new WeakMap(), g = new WeakMap(), w = new WeakMap(), _ = new WeakMap(), y =
|
|
|
1301
1360
|
for (const s of e.headers) {
|
|
1302
1361
|
if (!s.includes(": "))
|
|
1303
1362
|
continue;
|
|
1304
|
-
const i = s.indexOf(": "),
|
|
1305
|
-
|
|
1363
|
+
const i = s.indexOf(": "), o = s.substring(0, i).toLowerCase(), n = s.substring(i + 2);
|
|
1364
|
+
o in r || (r[o] = []), r[o].push(n);
|
|
1306
1365
|
}
|
|
1307
1366
|
return {
|
|
1308
1367
|
headers: r,
|
|
1309
1368
|
httpStatusCode: e.status
|
|
1310
1369
|
};
|
|
1311
|
-
},
|
|
1312
|
-
|
|
1370
|
+
}, U = function(t) {
|
|
1371
|
+
this[__private__dont__use].ccall(
|
|
1313
1372
|
"wasm_set_request_uri",
|
|
1314
1373
|
null,
|
|
1315
1374
|
[STRING],
|
|
1316
1375
|
[t]
|
|
1317
|
-
)
|
|
1318
|
-
|
|
1319
|
-
|
|
1320
|
-
|
|
1321
|
-
|
|
1322
|
-
|
|
1323
|
-
|
|
1324
|
-
|
|
1325
|
-
|
|
1326
|
-
}, j = new WeakSet(), Q = function(t) {
|
|
1376
|
+
);
|
|
1377
|
+
let e = "";
|
|
1378
|
+
t.includes("?") && (e = t.substring(t.indexOf("?") + 1)), this[__private__dont__use].ccall(
|
|
1379
|
+
"wasm_set_query_string",
|
|
1380
|
+
null,
|
|
1381
|
+
[STRING],
|
|
1382
|
+
[e]
|
|
1383
|
+
);
|
|
1384
|
+
}, L = function(t) {
|
|
1327
1385
|
this[__private__dont__use].ccall(
|
|
1328
1386
|
"wasm_set_request_host",
|
|
1329
1387
|
null,
|
|
1330
1388
|
[STRING],
|
|
1331
1389
|
[t]
|
|
1332
1390
|
);
|
|
1333
|
-
},
|
|
1391
|
+
}, q = function(t) {
|
|
1334
1392
|
this[__private__dont__use].ccall(
|
|
1335
1393
|
"wasm_set_request_port",
|
|
1336
1394
|
null,
|
|
1337
1395
|
[NUMBER],
|
|
1338
1396
|
[t]
|
|
1339
1397
|
);
|
|
1340
|
-
},
|
|
1398
|
+
}, $ = function(t, e) {
|
|
1341
1399
|
let r;
|
|
1342
1400
|
try {
|
|
1343
1401
|
r = parseInt(new URL(t).port, 10);
|
|
1344
1402
|
} catch {
|
|
1345
1403
|
}
|
|
1346
1404
|
return (!r || isNaN(r) || r === 80) && (r = e === "https" ? 443 : 80), r;
|
|
1347
|
-
},
|
|
1405
|
+
}, B = function(t) {
|
|
1348
1406
|
this[__private__dont__use].ccall(
|
|
1349
1407
|
"wasm_set_request_method",
|
|
1350
1408
|
null,
|
|
1351
1409
|
[STRING],
|
|
1352
1410
|
[t]
|
|
1353
1411
|
);
|
|
1354
|
-
},
|
|
1412
|
+
}, O = function(t) {
|
|
1355
1413
|
t.cookie && this[__private__dont__use].ccall(
|
|
1356
1414
|
"wasm_set_cookies",
|
|
1357
1415
|
null,
|
|
@@ -1368,7 +1426,7 @@ R = new WeakMap(), g = new WeakMap(), w = new WeakMap(), _ = new WeakMap(), y =
|
|
|
1368
1426
|
[NUMBER],
|
|
1369
1427
|
[parseInt(t["content-length"], 10)]
|
|
1370
1428
|
);
|
|
1371
|
-
},
|
|
1429
|
+
}, D = function(t) {
|
|
1372
1430
|
let e, r;
|
|
1373
1431
|
typeof t == "string" ? (logger.warn(
|
|
1374
1432
|
"Passing a string as the request body is deprecated. Please use a Uint8Array instead. See https://github.com/WordPress/wordpress-playground/issues/997 for more details"
|
|
@@ -1391,51 +1449,51 @@ R = new WeakMap(), g = new WeakMap(), w = new WeakMap(), _ = new WeakMap(), y =
|
|
|
1391
1449
|
[NUMBER],
|
|
1392
1450
|
[r]
|
|
1393
1451
|
), s;
|
|
1394
|
-
},
|
|
1452
|
+
}, A = function(t) {
|
|
1395
1453
|
this[__private__dont__use].ccall(
|
|
1396
1454
|
"wasm_set_path_translated",
|
|
1397
1455
|
null,
|
|
1398
1456
|
[STRING],
|
|
1399
1457
|
[t]
|
|
1400
1458
|
);
|
|
1401
|
-
},
|
|
1459
|
+
}, z = function(t, e) {
|
|
1402
1460
|
this[__private__dont__use].ccall(
|
|
1403
1461
|
"wasm_add_SERVER_entry",
|
|
1404
1462
|
null,
|
|
1405
1463
|
[STRING, STRING],
|
|
1406
1464
|
[t, e]
|
|
1407
1465
|
);
|
|
1408
|
-
},
|
|
1466
|
+
}, W = function(t, e) {
|
|
1409
1467
|
this[__private__dont__use].ccall(
|
|
1410
1468
|
"wasm_add_ENV_entry",
|
|
1411
1469
|
null,
|
|
1412
1470
|
[STRING, STRING],
|
|
1413
1471
|
[t, e]
|
|
1414
1472
|
);
|
|
1415
|
-
},
|
|
1473
|
+
}, G = async function() {
|
|
1416
1474
|
var i;
|
|
1417
1475
|
let t, e;
|
|
1418
1476
|
try {
|
|
1419
|
-
t = await new Promise((
|
|
1420
|
-
var
|
|
1477
|
+
t = await new Promise((o, n) => {
|
|
1478
|
+
var a;
|
|
1421
1479
|
e = (p) => {
|
|
1422
1480
|
logger.error(p), logger.error(p.error);
|
|
1423
|
-
const
|
|
1424
|
-
|
|
1425
|
-
}, (
|
|
1481
|
+
const T = new Error("Rethrown");
|
|
1482
|
+
T.cause = p.error, T.betterMessage = p.message, n(T);
|
|
1483
|
+
}, (a = c(this, v)) == null || a.addEventListener(
|
|
1426
1484
|
"error",
|
|
1427
1485
|
e
|
|
1428
1486
|
);
|
|
1429
|
-
const
|
|
1487
|
+
const l = this[__private__dont__use].ccall(
|
|
1430
1488
|
"wasm_sapi_handle_request",
|
|
1431
1489
|
NUMBER,
|
|
1432
1490
|
[],
|
|
1433
1491
|
[],
|
|
1434
1492
|
{ async: !0 }
|
|
1435
1493
|
);
|
|
1436
|
-
return
|
|
1494
|
+
return l instanceof Promise ? l.then(o, n) : o(l);
|
|
1437
1495
|
});
|
|
1438
|
-
} catch (
|
|
1496
|
+
} catch (o) {
|
|
1439
1497
|
for (const p in this)
|
|
1440
1498
|
typeof this[p] == "function" && (this[p] = () => {
|
|
1441
1499
|
throw new Error(
|
|
@@ -1443,12 +1501,12 @@ R = new WeakMap(), g = new WeakMap(), w = new WeakMap(), _ = new WeakMap(), y =
|
|
|
1443
1501
|
);
|
|
1444
1502
|
});
|
|
1445
1503
|
this.functionsMaybeMissingFromAsyncify = getFunctionsMaybeMissingFromAsyncify();
|
|
1446
|
-
const
|
|
1447
|
-
throw
|
|
1504
|
+
const n = o, l = "betterMessage" in n ? n.betterMessage : n.message, a = new Error(l);
|
|
1505
|
+
throw a.cause = n, logger.error(a), a;
|
|
1448
1506
|
} finally {
|
|
1449
|
-
(i = c(this,
|
|
1507
|
+
(i = c(this, v)) == null || i.removeEventListener("error", e);
|
|
1450
1508
|
}
|
|
1451
|
-
const { headers: r, httpStatusCode: s } =
|
|
1509
|
+
const { headers: r, httpStatusCode: s } = d(this, u, j).call(this);
|
|
1452
1510
|
return new PHPResponse(
|
|
1453
1511
|
t === 0 ? s : 500,
|
|
1454
1512
|
r,
|
|
@@ -1477,9 +1535,9 @@ function copyFS(t, e, r) {
|
|
|
1477
1535
|
return;
|
|
1478
1536
|
}
|
|
1479
1537
|
e.mkdirTree(r);
|
|
1480
|
-
const i = t.readdir(r).filter((
|
|
1481
|
-
for (const
|
|
1482
|
-
copyFS(t, e, joinPaths(r,
|
|
1538
|
+
const i = t.readdir(r).filter((o) => o !== "." && o !== "..");
|
|
1539
|
+
for (const o of i)
|
|
1540
|
+
copyFS(t, e, joinPaths(r, o));
|
|
1483
1541
|
}
|
|
1484
1542
|
async function getPhpIniEntries(t, e) {
|
|
1485
1543
|
const r = parse(await t.readFileAsText(PHP_INI_PATH));
|
|
@@ -1514,8 +1572,8 @@ class HttpCookieStore {
|
|
|
1514
1572
|
try {
|
|
1515
1573
|
if (!r.includes("="))
|
|
1516
1574
|
continue;
|
|
1517
|
-
const s = r.indexOf("="), i = r.substring(0, s),
|
|
1518
|
-
this.cookies[i] =
|
|
1575
|
+
const s = r.indexOf("="), i = r.substring(0, s), o = r.substring(s + 1).split(";")[0];
|
|
1576
|
+
this.cookies[i] = o;
|
|
1519
1577
|
} catch (s) {
|
|
1520
1578
|
logger.error(s);
|
|
1521
1579
|
}
|
|
@@ -1541,17 +1599,17 @@ async function* iteratePhpFiles(t, e, {
|
|
|
1541
1599
|
exceptPaths: i = []
|
|
1542
1600
|
} = {}) {
|
|
1543
1601
|
e = normalizePath(e);
|
|
1544
|
-
const
|
|
1545
|
-
for (;
|
|
1546
|
-
const
|
|
1547
|
-
if (!
|
|
1602
|
+
const o = [e];
|
|
1603
|
+
for (; o.length; ) {
|
|
1604
|
+
const n = o.pop();
|
|
1605
|
+
if (!n)
|
|
1548
1606
|
return;
|
|
1549
|
-
const
|
|
1550
|
-
for (const
|
|
1551
|
-
const p = `${
|
|
1607
|
+
const l = await t.listFiles(n);
|
|
1608
|
+
for (const a of l) {
|
|
1609
|
+
const p = `${n}/${a}`;
|
|
1552
1610
|
if (i.includes(p.substring(e.length + 1)))
|
|
1553
1611
|
continue;
|
|
1554
|
-
await t.isDir(p) ?
|
|
1612
|
+
await t.isDir(p) ? o.push(p) : yield new StreamedFile(
|
|
1555
1613
|
streamReadFileFromPHP(t, p),
|
|
1556
1614
|
r ? joinPaths(
|
|
1557
1615
|
s || "",
|
|
@@ -1693,9 +1751,7 @@ const SupportedPHPVersions = [
|
|
|
1693
1751
|
"8.0",
|
|
1694
1752
|
"7.4",
|
|
1695
1753
|
"7.3",
|
|
1696
|
-
"7.2"
|
|
1697
|
-
"7.1",
|
|
1698
|
-
"7.0"
|
|
1754
|
+
"7.2"
|
|
1699
1755
|
], LatestSupportedPHPVersion = SupportedPHPVersions[0], SupportedPHPVersionsList = SupportedPHPVersions, DEFAULT_BASE_URL = "http://example.com";
|
|
1700
1756
|
function toRelativeUrl(t) {
|
|
1701
1757
|
return t.toString().substring(t.origin.length);
|
|
@@ -1708,23 +1764,23 @@ function ensurePathPrefix(t, e) {
|
|
|
1708
1764
|
}
|
|
1709
1765
|
async function encodeAsMultipart(t) {
|
|
1710
1766
|
const e = `----${Math.random().toString(36).slice(2)}`, r = `multipart/form-data; boundary=${e}`, s = new TextEncoder(), i = [];
|
|
1711
|
-
for (const [
|
|
1767
|
+
for (const [a, p] of Object.entries(t))
|
|
1712
1768
|
i.push(`--${e}\r
|
|
1713
|
-
`), i.push(`Content-Disposition: form-data; name="${
|
|
1769
|
+
`), i.push(`Content-Disposition: form-data; name="${a}"`), p instanceof File && i.push(`; filename="${p.name}"`), i.push(`\r
|
|
1714
1770
|
`), p instanceof File && (i.push("Content-Type: application/octet-stream"), i.push(`\r
|
|
1715
1771
|
`)), i.push(`\r
|
|
1716
1772
|
`), p instanceof File ? i.push(await fileToUint8Array(p)) : i.push(p), i.push(`\r
|
|
1717
1773
|
`);
|
|
1718
1774
|
i.push(`--${e}--\r
|
|
1719
1775
|
`);
|
|
1720
|
-
const
|
|
1721
|
-
let
|
|
1722
|
-
for (const
|
|
1723
|
-
|
|
1724
|
-
typeof
|
|
1725
|
-
|
|
1726
|
-
),
|
|
1727
|
-
return { bytes:
|
|
1776
|
+
const o = i.reduce((a, p) => a + p.length, 0), n = new Uint8Array(o);
|
|
1777
|
+
let l = 0;
|
|
1778
|
+
for (const a of i)
|
|
1779
|
+
n.set(
|
|
1780
|
+
typeof a == "string" ? s.encode(a) : a,
|
|
1781
|
+
l
|
|
1782
|
+
), l += a.length;
|
|
1783
|
+
return { bytes: n, contentType: r };
|
|
1728
1784
|
}
|
|
1729
1785
|
function fileToUint8Array(t) {
|
|
1730
1786
|
return t.arrayBuffer().then((e) => new Uint8Array(e));
|
|
@@ -1825,7 +1881,7 @@ const _default = "application/octet-stream", asx = "video/x-ms-asf", atom = "app
|
|
|
1825
1881
|
xspf,
|
|
1826
1882
|
zip
|
|
1827
1883
|
};
|
|
1828
|
-
var
|
|
1884
|
+
var g, S, k, E, H, f, b, y, w, V, J, Y;
|
|
1829
1885
|
class PHPRequestHandler {
|
|
1830
1886
|
/**
|
|
1831
1887
|
* The request handler needs to decide whether to serve a static asset or
|
|
@@ -1839,60 +1895,42 @@ class PHPRequestHandler {
|
|
|
1839
1895
|
* @param config - Request Handler configuration.
|
|
1840
1896
|
*/
|
|
1841
1897
|
constructor(e) {
|
|
1842
|
-
|
|
1843
|
-
|
|
1844
|
-
|
|
1845
|
-
|
|
1846
|
-
|
|
1847
|
-
|
|
1848
|
-
|
|
1849
|
-
|
|
1850
|
-
|
|
1851
|
-
*/
|
|
1852
|
-
u(this, W);
|
|
1853
|
-
/**
|
|
1854
|
-
* Runs the requested PHP file with all the request and $_SERVER
|
|
1855
|
-
* superglobals populated.
|
|
1856
|
-
*
|
|
1857
|
-
* @param request - The request.
|
|
1858
|
-
* @returns The response.
|
|
1859
|
-
*/
|
|
1860
|
-
u(this, G);
|
|
1861
|
-
u(this, P, void 0);
|
|
1862
|
-
u(this, F, void 0);
|
|
1863
|
-
u(this, T, void 0);
|
|
1864
|
-
u(this, E, void 0);
|
|
1865
|
-
u(this, S, void 0);
|
|
1866
|
-
u(this, f, void 0);
|
|
1867
|
-
u(this, H, void 0);
|
|
1868
|
-
u(this, b, void 0);
|
|
1898
|
+
h(this, w);
|
|
1899
|
+
h(this, g);
|
|
1900
|
+
h(this, S);
|
|
1901
|
+
h(this, k);
|
|
1902
|
+
h(this, E);
|
|
1903
|
+
h(this, H);
|
|
1904
|
+
h(this, f);
|
|
1905
|
+
h(this, b);
|
|
1906
|
+
h(this, y);
|
|
1869
1907
|
const {
|
|
1870
1908
|
documentRoot: r = "/www/",
|
|
1871
|
-
absoluteUrl: s = typeof location == "object" ? location
|
|
1909
|
+
absoluteUrl: s = typeof location == "object" ? location.href : DEFAULT_BASE_URL,
|
|
1872
1910
|
rewriteRules: i = [],
|
|
1873
|
-
getFileNotFoundAction:
|
|
1911
|
+
getFileNotFoundAction: o = () => ({ type: "404" })
|
|
1874
1912
|
} = e;
|
|
1875
1913
|
"processManager" in e ? this.processManager = e.processManager : this.processManager = new PHPProcessManager({
|
|
1876
|
-
phpFactory: async (
|
|
1914
|
+
phpFactory: async (a) => {
|
|
1877
1915
|
const p = await e.phpFactory({
|
|
1878
|
-
...
|
|
1916
|
+
...a,
|
|
1879
1917
|
requestHandler: this
|
|
1880
1918
|
});
|
|
1881
1919
|
return p.requestHandler = this, p;
|
|
1882
1920
|
},
|
|
1883
1921
|
maxPhpInstances: e.maxPhpInstances
|
|
1884
|
-
}),
|
|
1885
|
-
const
|
|
1886
|
-
|
|
1887
|
-
const
|
|
1888
|
-
|
|
1889
|
-
c(this,
|
|
1890
|
-
|
|
1891
|
-
].join("")),
|
|
1892
|
-
`${c(this,
|
|
1893
|
-
c(this,
|
|
1922
|
+
}), m(this, y, e.cookieStore === void 0 ? new HttpCookieStore() : e.cookieStore), m(this, g, r);
|
|
1923
|
+
const n = new URL(s);
|
|
1924
|
+
m(this, k, n.hostname), m(this, E, n.port ? Number(n.port) : n.protocol === "https:" ? 443 : 80), m(this, S, (n.protocol || "").replace(":", ""));
|
|
1925
|
+
const l = c(this, E) !== 443 && c(this, E) !== 80;
|
|
1926
|
+
m(this, H, [
|
|
1927
|
+
c(this, k),
|
|
1928
|
+
l ? `:${c(this, E)}` : ""
|
|
1929
|
+
].join("")), m(this, f, n.pathname.replace(/\/+$/, "")), m(this, b, [
|
|
1930
|
+
`${c(this, S)}://`,
|
|
1931
|
+
c(this, H),
|
|
1894
1932
|
c(this, f)
|
|
1895
|
-
].join("")), this.rewriteRules = i, this.getFileNotFoundAction =
|
|
1933
|
+
].join("")), this.rewriteRules = i, this.getFileNotFoundAction = o;
|
|
1896
1934
|
}
|
|
1897
1935
|
async getPrimaryPhp() {
|
|
1898
1936
|
return await this.processManager.getPrimaryPhp();
|
|
@@ -1922,14 +1960,14 @@ class PHPRequestHandler {
|
|
|
1922
1960
|
* The absolute URL of this PHPRequestHandler instance.
|
|
1923
1961
|
*/
|
|
1924
1962
|
get absoluteUrl() {
|
|
1925
|
-
return c(this,
|
|
1963
|
+
return c(this, b);
|
|
1926
1964
|
}
|
|
1927
1965
|
/**
|
|
1928
1966
|
* The directory in the PHP filesystem where the server will look
|
|
1929
1967
|
* for the files to serve. Default: `/var/www`.
|
|
1930
1968
|
*/
|
|
1931
1969
|
get documentRoot() {
|
|
1932
|
-
return c(this,
|
|
1970
|
+
return c(this, g);
|
|
1933
1971
|
}
|
|
1934
1972
|
/**
|
|
1935
1973
|
* Serves the request – either by serving a static file, or by
|
|
@@ -1990,56 +2028,62 @@ class PHPRequestHandler {
|
|
|
1990
2028
|
c(this, f)
|
|
1991
2029
|
),
|
|
1992
2030
|
this.rewriteRules
|
|
1993
|
-
),
|
|
1994
|
-
let
|
|
1995
|
-
if (
|
|
1996
|
-
if (!
|
|
2031
|
+
), o = await this.getPrimaryPhp();
|
|
2032
|
+
let n = joinPaths(c(this, g), i);
|
|
2033
|
+
if (o.isDir(n)) {
|
|
2034
|
+
if (!n.endsWith("/"))
|
|
1997
2035
|
return new PHPResponse(
|
|
1998
2036
|
301,
|
|
1999
2037
|
{ Location: [`${s.pathname}/`] },
|
|
2000
2038
|
new Uint8Array(0)
|
|
2001
2039
|
);
|
|
2002
|
-
for (const
|
|
2003
|
-
const
|
|
2004
|
-
if (
|
|
2005
|
-
|
|
2040
|
+
for (const l of ["index.php", "index.html"]) {
|
|
2041
|
+
const a = joinPaths(n, l);
|
|
2042
|
+
if (o.isFile(a)) {
|
|
2043
|
+
n = a;
|
|
2006
2044
|
break;
|
|
2007
2045
|
}
|
|
2008
2046
|
}
|
|
2009
2047
|
}
|
|
2010
|
-
if (!
|
|
2011
|
-
const
|
|
2048
|
+
if (!o.isFile(n)) {
|
|
2049
|
+
const l = this.getFileNotFoundAction(
|
|
2012
2050
|
i
|
|
2013
2051
|
);
|
|
2014
|
-
switch (
|
|
2052
|
+
switch (l.type) {
|
|
2015
2053
|
case "response":
|
|
2016
|
-
return
|
|
2054
|
+
return l.response;
|
|
2017
2055
|
case "internal-redirect":
|
|
2018
|
-
|
|
2056
|
+
n = joinPaths(c(this, g), l.uri);
|
|
2019
2057
|
break;
|
|
2020
2058
|
case "404":
|
|
2021
2059
|
return PHPResponse.forHttpCode(404);
|
|
2022
2060
|
default:
|
|
2023
2061
|
throw new Error(
|
|
2024
|
-
`Unsupported file-not-found action type: '${
|
|
2062
|
+
`Unsupported file-not-found action type: '${l.type}'`
|
|
2025
2063
|
);
|
|
2026
2064
|
}
|
|
2027
2065
|
}
|
|
2028
|
-
if (
|
|
2029
|
-
if (
|
|
2030
|
-
const
|
|
2066
|
+
if (o.isFile(n))
|
|
2067
|
+
if (n.endsWith(".php")) {
|
|
2068
|
+
const l = {
|
|
2031
2069
|
...e,
|
|
2032
2070
|
// Pass along URL with the #fragment filtered out
|
|
2033
2071
|
url: s.toString()
|
|
2034
2072
|
};
|
|
2035
|
-
return
|
|
2073
|
+
return d(this, w, J).call(this, l, n);
|
|
2036
2074
|
} else
|
|
2037
|
-
return
|
|
2075
|
+
return d(this, w, V).call(this, o, n);
|
|
2038
2076
|
else
|
|
2039
2077
|
return PHPResponse.forHttpCode(404);
|
|
2040
2078
|
}
|
|
2041
2079
|
}
|
|
2042
|
-
|
|
2080
|
+
g = new WeakMap(), S = new WeakMap(), k = new WeakMap(), E = new WeakMap(), H = new WeakMap(), f = new WeakMap(), b = new WeakMap(), y = new WeakMap(), w = new WeakSet(), /**
|
|
2081
|
+
* Serves a static file from the PHP filesystem.
|
|
2082
|
+
*
|
|
2083
|
+
* @param fsPath - Absolute path of the static file to serve.
|
|
2084
|
+
* @returns The response.
|
|
2085
|
+
*/
|
|
2086
|
+
V = function(e, r) {
|
|
2043
2087
|
const s = e.readFileAsBuffer(r);
|
|
2044
2088
|
return new PHPResponse(
|
|
2045
2089
|
200,
|
|
@@ -2054,7 +2098,7 @@ P = new WeakMap(), F = new WeakMap(), T = new WeakMap(), E = new WeakMap(), S =
|
|
|
2054
2098
|
},
|
|
2055
2099
|
s
|
|
2056
2100
|
);
|
|
2057
|
-
},
|
|
2101
|
+
}, J = async function(e, r) {
|
|
2058
2102
|
let s;
|
|
2059
2103
|
try {
|
|
2060
2104
|
s = await this.processManager.acquirePHPInstance();
|
|
@@ -2062,48 +2106,48 @@ P = new WeakMap(), F = new WeakMap(), T = new WeakMap(), E = new WeakMap(), S =
|
|
|
2062
2106
|
return i instanceof MaxPhpInstancesError ? PHPResponse.forHttpCode(502) : PHPResponse.forHttpCode(500);
|
|
2063
2107
|
}
|
|
2064
2108
|
try {
|
|
2065
|
-
return await
|
|
2109
|
+
return await d(this, w, Y).call(this, s.php, e, r);
|
|
2066
2110
|
} finally {
|
|
2067
2111
|
s.reap();
|
|
2068
2112
|
}
|
|
2069
|
-
},
|
|
2113
|
+
}, Y = async function(e, r, s) {
|
|
2070
2114
|
let i = "GET";
|
|
2071
|
-
const
|
|
2072
|
-
host: c(this,
|
|
2073
|
-
...normalizeHeaders(r.headers || {})
|
|
2074
|
-
cookie: c(this, b).getCookieRequestHeader()
|
|
2115
|
+
const o = {
|
|
2116
|
+
host: c(this, H),
|
|
2117
|
+
...normalizeHeaders(r.headers || {})
|
|
2075
2118
|
};
|
|
2076
|
-
|
|
2077
|
-
|
|
2119
|
+
c(this, y) && (o.cookie = c(this, y).getCookieRequestHeader());
|
|
2120
|
+
let n = r.body;
|
|
2121
|
+
if (typeof n == "object" && !(n instanceof Uint8Array)) {
|
|
2078
2122
|
i = "POST";
|
|
2079
|
-
const { bytes:
|
|
2080
|
-
|
|
2123
|
+
const { bytes: l, contentType: a } = await encodeAsMultipart(n);
|
|
2124
|
+
n = l, o["content-type"] = a;
|
|
2081
2125
|
}
|
|
2082
2126
|
try {
|
|
2083
|
-
const
|
|
2127
|
+
const l = await e.run({
|
|
2084
2128
|
relativeUri: ensurePathPrefix(
|
|
2085
2129
|
toRelativeUrl(new URL(r.url)),
|
|
2086
2130
|
c(this, f)
|
|
2087
2131
|
),
|
|
2088
|
-
protocol: c(this,
|
|
2132
|
+
protocol: c(this, S),
|
|
2089
2133
|
method: r.method || i,
|
|
2090
2134
|
$_SERVER: {
|
|
2091
2135
|
REMOTE_ADDR: "127.0.0.1",
|
|
2092
|
-
DOCUMENT_ROOT: c(this,
|
|
2093
|
-
HTTPS: c(this,
|
|
2136
|
+
DOCUMENT_ROOT: c(this, g),
|
|
2137
|
+
HTTPS: c(this, b).startsWith("https://") ? "on" : ""
|
|
2094
2138
|
},
|
|
2095
|
-
body:
|
|
2139
|
+
body: n,
|
|
2096
2140
|
scriptPath: s,
|
|
2097
|
-
headers:
|
|
2141
|
+
headers: o
|
|
2098
2142
|
});
|
|
2099
|
-
return c(this,
|
|
2100
|
-
|
|
2101
|
-
),
|
|
2102
|
-
} catch (
|
|
2103
|
-
const
|
|
2104
|
-
if (
|
|
2105
|
-
return
|
|
2106
|
-
throw
|
|
2143
|
+
return c(this, y) && c(this, y).rememberCookiesFromResponseHeaders(
|
|
2144
|
+
l.headers
|
|
2145
|
+
), l;
|
|
2146
|
+
} catch (l) {
|
|
2147
|
+
const a = l;
|
|
2148
|
+
if (a != null && a.response)
|
|
2149
|
+
return a.response;
|
|
2150
|
+
throw l;
|
|
2107
2151
|
}
|
|
2108
2152
|
};
|
|
2109
2153
|
function inferMimeType(t) {
|
|
@@ -2131,29 +2175,29 @@ function rotatePHPRuntime({
|
|
|
2131
2175
|
maxRequests: s = 400
|
|
2132
2176
|
}) {
|
|
2133
2177
|
let i = 0;
|
|
2134
|
-
async function
|
|
2135
|
-
const
|
|
2178
|
+
async function o() {
|
|
2179
|
+
const a = await t.semaphore.acquire();
|
|
2136
2180
|
try {
|
|
2137
2181
|
await t.hotSwapPHPRuntime(await r(), e), i = 0;
|
|
2138
2182
|
} finally {
|
|
2139
|
-
|
|
2183
|
+
a();
|
|
2140
2184
|
}
|
|
2141
2185
|
}
|
|
2142
|
-
async function
|
|
2143
|
-
++i < s || await
|
|
2186
|
+
async function n() {
|
|
2187
|
+
++i < s || await o();
|
|
2144
2188
|
}
|
|
2145
|
-
async function a
|
|
2146
|
-
|
|
2189
|
+
async function l(a) {
|
|
2190
|
+
a.type === "request.error" && a.source === "php-wasm" && await o();
|
|
2147
2191
|
}
|
|
2148
|
-
return t.addEventListener("request.error",
|
|
2149
|
-
t.removeEventListener("request.error",
|
|
2192
|
+
return t.addEventListener("request.error", l), t.addEventListener("request.end", n), function() {
|
|
2193
|
+
t.removeEventListener("request.error", l), t.removeEventListener("request.end", n);
|
|
2150
2194
|
};
|
|
2151
2195
|
}
|
|
2152
2196
|
async function writeFiles(t, e, r, { rmRoot: s = !1 } = {}) {
|
|
2153
2197
|
s && await t.isDir(e) && await t.rmdir(e, { recursive: !0 });
|
|
2154
|
-
for (const [i,
|
|
2155
|
-
const
|
|
2156
|
-
await t.fileExists(dirname(
|
|
2198
|
+
for (const [i, o] of Object.entries(r)) {
|
|
2199
|
+
const n = joinPaths(e, i);
|
|
2200
|
+
await t.fileExists(dirname(n)) || await t.mkdir(dirname(n)), o instanceof Uint8Array || typeof o == "string" ? await t.writeFile(n, o) : await writeFiles(t, n, o);
|
|
2157
2201
|
}
|
|
2158
2202
|
}
|
|
2159
2203
|
function proxyFileSystem(t, e, r) {
|