@php-wasm/universal 1.1.2 → 1.1.3
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 +9 -7
- package/index.cjs.map +1 -1
- package/index.js +585 -340
- package/index.js.map +1 -1
- package/lib/index.d.ts +3 -3
- package/lib/is-exit-code.d.ts +9 -0
- package/lib/php-process-manager.d.ts +15 -1
- package/lib/php-response.d.ts +54 -3
- package/lib/php.d.ts +104 -7
- package/lib/wasm-error-reporting.d.ts +2 -2
- package/package.json +7 -7
- package/lib/is-exit-code-zero.d.ts +0 -7
package/index.js
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
var
|
|
1
|
+
var D = (t) => {
|
|
2
2
|
throw TypeError(t);
|
|
3
3
|
};
|
|
4
|
-
var
|
|
5
|
-
var c = (t, e, r) => (
|
|
4
|
+
var U = (t, e, r) => e.has(t) || D("Cannot " + r);
|
|
5
|
+
var c = (t, e, r) => (U(t, e, "read from private field"), r ? r.call(t) : e.get(t)), h = (t, e, r) => e.has(t) ? D("Cannot add the same private member more than once") : e instanceof WeakSet ? e.add(t) : e.set(t, r), m = (t, e, r, s) => (U(t, e, "write to private field"), s ? s.call(t, r) : e.set(t, r), r), d = (t, e, r) => (U(t, e, "access private method"), r);
|
|
6
6
|
import "@php-wasm/node-polyfills";
|
|
7
7
|
import { logger } from "@php-wasm/logger";
|
|
8
8
|
import { dirname, joinPaths, Semaphore, createSpawnHandler, normalizePath, AcquireTimeoutError } from "@php-wasm/util";
|
|
@@ -98,10 +98,10 @@ function rethrowFileSystemError(t = "") {
|
|
|
98
98
|
try {
|
|
99
99
|
return r.apply(this, s);
|
|
100
100
|
} catch (i) {
|
|
101
|
-
const
|
|
102
|
-
if (
|
|
103
|
-
const
|
|
104
|
-
throw new Error(`${
|
|
101
|
+
const n = typeof i == "object" ? i == null ? void 0 : i.errno : null;
|
|
102
|
+
if (n in FileErrorCodes) {
|
|
103
|
+
const o = FileErrorCodes[n], a = typeof s[1] == "string" ? s[1] : null, l = a !== null ? t.replaceAll("{path}", a) : t;
|
|
104
|
+
throw new Error(`${l}: ${o}`, {
|
|
105
105
|
cause: i
|
|
106
106
|
});
|
|
107
107
|
}
|
|
@@ -164,12 +164,12 @@ class FSHelpers {
|
|
|
164
164
|
*/
|
|
165
165
|
static mv(e, r, s) {
|
|
166
166
|
try {
|
|
167
|
-
const i = e.lookupPath(r).node.mount,
|
|
168
|
-
i.mountpoint !==
|
|
167
|
+
const i = e.lookupPath(r).node.mount, n = FSHelpers.fileExists(e, s) ? e.lookupPath(s).node.mount : e.lookupPath(dirname(s)).node.mount;
|
|
168
|
+
i.mountpoint !== n.mountpoint ? (FSHelpers.copyRecursive(e, r, s), FSHelpers.isDir(e, r) ? FSHelpers.rmdir(e, r, { recursive: !0 }) : e.unlink(r)) : e.rename(r, s);
|
|
169
169
|
} catch (i) {
|
|
170
|
-
const
|
|
171
|
-
throw
|
|
172
|
-
`Could not move ${r} to ${s}: ${
|
|
170
|
+
const n = getEmscriptenFsError(i);
|
|
171
|
+
throw n ? new Error(
|
|
172
|
+
`Could not move ${r} to ${s}: ${n}`,
|
|
173
173
|
{
|
|
174
174
|
cause: i
|
|
175
175
|
}
|
|
@@ -185,9 +185,9 @@ class FSHelpers {
|
|
|
185
185
|
*/
|
|
186
186
|
static rmdir(e, r, s = { recursive: !0 }) {
|
|
187
187
|
s != null && s.recursive && FSHelpers.listFiles(e, r).forEach((i) => {
|
|
188
|
-
const
|
|
189
|
-
FSHelpers.isDir(e,
|
|
190
|
-
}), e.rmdir(r);
|
|
188
|
+
const n = `${r}/${i}`;
|
|
189
|
+
FSHelpers.isDir(e, n) ? FSHelpers.rmdir(e, n, s) : FSHelpers.unlink(e, n);
|
|
190
|
+
}), e.getPath(e.lookupPath(r).node) === e.cwd() && e.chdir(joinPaths(e.cwd(), "..")), e.rmdir(r);
|
|
191
191
|
}
|
|
192
192
|
/**
|
|
193
193
|
* Lists the files and directories in the given directory.
|
|
@@ -202,11 +202,11 @@ class FSHelpers {
|
|
|
202
202
|
return [];
|
|
203
203
|
try {
|
|
204
204
|
const i = e.readdir(r).filter(
|
|
205
|
-
(
|
|
205
|
+
(n) => n !== "." && n !== ".."
|
|
206
206
|
);
|
|
207
207
|
if (s.prependPath) {
|
|
208
|
-
const
|
|
209
|
-
return i.map((
|
|
208
|
+
const n = r.replace(/\/$/, "");
|
|
209
|
+
return i.map((o) => `${n}/${o}`);
|
|
210
210
|
}
|
|
211
211
|
return i;
|
|
212
212
|
} catch (i) {
|
|
@@ -302,14 +302,14 @@ class FSHelpers {
|
|
|
302
302
|
const i = e.lookupPath(r).node;
|
|
303
303
|
if (e.isDir(i.mode)) {
|
|
304
304
|
e.mkdirTree(s);
|
|
305
|
-
const
|
|
306
|
-
(
|
|
305
|
+
const n = e.readdir(r).filter(
|
|
306
|
+
(o) => o !== "." && o !== ".."
|
|
307
307
|
);
|
|
308
|
-
for (const
|
|
308
|
+
for (const o of n)
|
|
309
309
|
FSHelpers.copyRecursive(
|
|
310
310
|
e,
|
|
311
|
-
joinPaths(r,
|
|
312
|
-
joinPaths(s,
|
|
311
|
+
joinPaths(r, o),
|
|
312
|
+
joinPaths(s, o)
|
|
313
313
|
);
|
|
314
314
|
} else
|
|
315
315
|
e.writeFile(s, e.readFile(r));
|
|
@@ -497,9 +497,100 @@ const responseTexts = {
|
|
|
497
497
|
201: "Created",
|
|
498
498
|
200: "OK"
|
|
499
499
|
};
|
|
500
|
+
class StreamedPHPResponse {
|
|
501
|
+
constructor(e, r, s, i) {
|
|
502
|
+
this.parsedHeaders = null, this.cachedStdoutText = null, this.cachedStderrText = null, this.headersStream = e, this.stdout = r, this.stderr = s, this.exitCode = i;
|
|
503
|
+
}
|
|
504
|
+
/**
|
|
505
|
+
* True if the response is successful (HTTP status code 200-399),
|
|
506
|
+
* false otherwise.
|
|
507
|
+
*/
|
|
508
|
+
async ok() {
|
|
509
|
+
try {
|
|
510
|
+
const e = await this.httpStatusCode;
|
|
511
|
+
return e >= 200 && e < 400;
|
|
512
|
+
} catch {
|
|
513
|
+
return !1;
|
|
514
|
+
}
|
|
515
|
+
}
|
|
516
|
+
/**
|
|
517
|
+
* Resolves when the response has finished processing – either successfully or not.
|
|
518
|
+
*/
|
|
519
|
+
get finished() {
|
|
520
|
+
return Promise.allSettled([this.exitCode.finally(() => {
|
|
521
|
+
})]).then(
|
|
522
|
+
() => {
|
|
523
|
+
}
|
|
524
|
+
);
|
|
525
|
+
}
|
|
526
|
+
/**
|
|
527
|
+
* Resolves once HTTP headers are available.
|
|
528
|
+
*/
|
|
529
|
+
get headers() {
|
|
530
|
+
return this.getParsedHeaders().then((e) => e.headers);
|
|
531
|
+
}
|
|
532
|
+
/**
|
|
533
|
+
* Resolves once HTTP status code is available.
|
|
534
|
+
*/
|
|
535
|
+
get httpStatusCode() {
|
|
536
|
+
return Promise.race([
|
|
537
|
+
this.getParsedHeaders().then((e) => e.httpStatusCode),
|
|
538
|
+
this.exitCode.then(
|
|
539
|
+
(e) => e !== 0 ? 500 : void 0
|
|
540
|
+
)
|
|
541
|
+
]).then((e) => e !== void 0 ? e : this.getParsedHeaders().then(
|
|
542
|
+
(r) => r.httpStatusCode,
|
|
543
|
+
() => 200
|
|
544
|
+
)).catch(() => 500);
|
|
545
|
+
}
|
|
546
|
+
/**
|
|
547
|
+
* Exposes the stdout bytes as they're produced by the PHP instance
|
|
548
|
+
*/
|
|
549
|
+
get stdoutText() {
|
|
550
|
+
return this.cachedStdoutText || (this.cachedStdoutText = streamToText(this.stdout)), this.cachedStdoutText;
|
|
551
|
+
}
|
|
552
|
+
/**
|
|
553
|
+
* Exposes the stderr bytes as they're produced by the PHP instance
|
|
554
|
+
*/
|
|
555
|
+
get stderrText() {
|
|
556
|
+
return this.cachedStderrText || (this.cachedStderrText = streamToText(this.stderr)), this.cachedStderrText;
|
|
557
|
+
}
|
|
558
|
+
async getParsedHeaders() {
|
|
559
|
+
return this.parsedHeaders || (this.parsedHeaders = parseHeadersStream(this.headersStream)), await this.parsedHeaders;
|
|
560
|
+
}
|
|
561
|
+
}
|
|
562
|
+
async function parseHeadersStream(t) {
|
|
563
|
+
const e = await streamToText(t);
|
|
564
|
+
let r;
|
|
565
|
+
try {
|
|
566
|
+
r = JSON.parse(e);
|
|
567
|
+
} catch {
|
|
568
|
+
return { headers: {}, httpStatusCode: 200 };
|
|
569
|
+
}
|
|
570
|
+
const s = {};
|
|
571
|
+
for (const i of r.headers) {
|
|
572
|
+
if (!i.includes(": "))
|
|
573
|
+
continue;
|
|
574
|
+
const n = i.indexOf(": "), o = i.substring(0, n).toLowerCase(), a = i.substring(n + 2);
|
|
575
|
+
o in s || (s[o] = []), s[o].push(a);
|
|
576
|
+
}
|
|
577
|
+
return {
|
|
578
|
+
headers: s,
|
|
579
|
+
httpStatusCode: r.status
|
|
580
|
+
};
|
|
581
|
+
}
|
|
582
|
+
async function streamToText(t) {
|
|
583
|
+
const e = t.pipeThrough(new TextDecoderStream()).getReader(), r = [];
|
|
584
|
+
for (; ; ) {
|
|
585
|
+
const { done: s, value: i } = await e.read();
|
|
586
|
+
if (s)
|
|
587
|
+
return r.join("");
|
|
588
|
+
i && r.push(i);
|
|
589
|
+
}
|
|
590
|
+
}
|
|
500
591
|
class PHPResponse {
|
|
501
|
-
constructor(e, r, s, i = "",
|
|
502
|
-
this.httpStatusCode = e, this.headers = r, this.bytes = s, this.exitCode =
|
|
592
|
+
constructor(e, r, s, i = "", n = 0) {
|
|
593
|
+
this.httpStatusCode = e, this.headers = r, this.bytes = s, this.exitCode = n, this.errors = i;
|
|
503
594
|
}
|
|
504
595
|
static forHttpCode(e, r = "") {
|
|
505
596
|
return new PHPResponse(
|
|
@@ -519,6 +610,15 @@ class PHPResponse {
|
|
|
519
610
|
e.exitCode
|
|
520
611
|
);
|
|
521
612
|
}
|
|
613
|
+
static async fromStreamedResponse(e) {
|
|
614
|
+
return await e.finished, new PHPResponse(
|
|
615
|
+
await e.httpStatusCode,
|
|
616
|
+
await e.headers,
|
|
617
|
+
new TextEncoder().encode(await e.stdoutText),
|
|
618
|
+
await e.stderrText,
|
|
619
|
+
await e.exitCode
|
|
620
|
+
);
|
|
621
|
+
}
|
|
522
622
|
toRawData() {
|
|
523
623
|
return {
|
|
524
624
|
headers: this.headers,
|
|
@@ -544,26 +644,26 @@ class PHPResponse {
|
|
|
544
644
|
const RuntimeId = Symbol("RuntimeId"), loadedRuntimes = /* @__PURE__ */ new Map();
|
|
545
645
|
let lastRuntimeId = 0;
|
|
546
646
|
async function loadPHPRuntime(t, ...e) {
|
|
547
|
-
const r = Object.assign({}, ...e), [s, i,
|
|
548
|
-
onAbort(
|
|
549
|
-
|
|
647
|
+
const r = Object.assign({}, ...e), [s, i, n] = makePromise(), o = t.init(currentJsRuntime, {
|
|
648
|
+
onAbort(l) {
|
|
649
|
+
n(l), logger.error(l);
|
|
550
650
|
},
|
|
551
651
|
ENV: {},
|
|
552
652
|
// Emscripten sometimes prepends a '/' to the path, which
|
|
553
653
|
// breaks vite dev mode. An identity `locateFile` function
|
|
554
654
|
// fixes it.
|
|
555
|
-
locateFile: (
|
|
655
|
+
locateFile: (l) => l,
|
|
556
656
|
...r,
|
|
557
657
|
noInitialRun: !0,
|
|
558
658
|
onRuntimeInitialized() {
|
|
559
|
-
r.onRuntimeInitialized && r.onRuntimeInitialized(
|
|
659
|
+
r.onRuntimeInitialized && r.onRuntimeInitialized(o), i();
|
|
560
660
|
}
|
|
561
661
|
});
|
|
562
662
|
await s;
|
|
563
|
-
const
|
|
564
|
-
return
|
|
565
|
-
return
|
|
566
|
-
},
|
|
663
|
+
const a = ++lastRuntimeId;
|
|
664
|
+
return o.FS, o.id = a, o.originalExit = o._exit, o._exit = function(l) {
|
|
665
|
+
return o.outboundNetworkProxyServer && (o.outboundNetworkProxyServer.close(), o.outboundNetworkProxyServer.closeAllConnections()), loadedRuntimes.delete(a), o.originalExit(l);
|
|
666
|
+
}, o[RuntimeId] = a, loadedRuntimes.set(a, o), a;
|
|
567
667
|
}
|
|
568
668
|
function getLoadedRuntime(t) {
|
|
569
669
|
return loadedRuntimes.get(t);
|
|
@@ -600,18 +700,26 @@ class ErrorEvent2 extends (_a = Event, _a) {
|
|
|
600
700
|
Object.defineProperty(ErrorEvent2.prototype, "error", { enumerable: !0 });
|
|
601
701
|
Object.defineProperty(ErrorEvent2.prototype, "message", { enumerable: !0 });
|
|
602
702
|
const ErrorEvent = typeof globalThis.ErrorEvent == "function" ? globalThis.ErrorEvent : ErrorEvent2;
|
|
603
|
-
function
|
|
604
|
-
return t instanceof Error ? "exitCode" in t
|
|
703
|
+
function isExitCode(t) {
|
|
704
|
+
return t instanceof Error ? "exitCode" in t || (t == null ? void 0 : t.name) === "ExitStatus" && "status" in t : !1;
|
|
605
705
|
}
|
|
606
706
|
class UnhandledRejectionsTarget extends EventTarget {
|
|
607
707
|
constructor() {
|
|
608
708
|
super(...arguments), this.listenersCount = 0;
|
|
609
709
|
}
|
|
610
|
-
addEventListener(e, r) {
|
|
611
|
-
++this.listenersCount, super.addEventListener(
|
|
710
|
+
addEventListener(e, r, s) {
|
|
711
|
+
++this.listenersCount, super.addEventListener(
|
|
712
|
+
e,
|
|
713
|
+
r,
|
|
714
|
+
s
|
|
715
|
+
);
|
|
612
716
|
}
|
|
613
|
-
removeEventListener(e, r) {
|
|
614
|
-
--this.listenersCount, super.removeEventListener(
|
|
717
|
+
removeEventListener(e, r, s) {
|
|
718
|
+
--this.listenersCount, super.removeEventListener(
|
|
719
|
+
e,
|
|
720
|
+
r,
|
|
721
|
+
s
|
|
722
|
+
);
|
|
615
723
|
}
|
|
616
724
|
hasListeners() {
|
|
617
725
|
return this.listenersCount > 0;
|
|
@@ -623,26 +731,24 @@ function improveWASMErrorReporting(t) {
|
|
|
623
731
|
if (typeof t.wasmExports[r] == "function") {
|
|
624
732
|
const s = t.wasmExports[r];
|
|
625
733
|
t.wasmExports[r] = function(...i) {
|
|
626
|
-
var
|
|
734
|
+
var n;
|
|
627
735
|
try {
|
|
628
736
|
return s(...i);
|
|
629
|
-
} catch (
|
|
630
|
-
if (!(
|
|
631
|
-
throw
|
|
632
|
-
const
|
|
633
|
-
|
|
634
|
-
(
|
|
737
|
+
} catch (o) {
|
|
738
|
+
if (!(o instanceof Error))
|
|
739
|
+
throw o;
|
|
740
|
+
const a = clarifyErrorMessage(
|
|
741
|
+
o,
|
|
742
|
+
(n = t.lastAsyncifyStackSource) == null ? void 0 : n.stack
|
|
635
743
|
);
|
|
636
|
-
if (t.lastAsyncifyStackSource && (
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
);
|
|
643
|
-
return;
|
|
744
|
+
if (t.lastAsyncifyStackSource && (o.cause = t.lastAsyncifyStackSource), e.hasListeners()) {
|
|
745
|
+
const l = new ErrorEvent("error", {
|
|
746
|
+
error: o,
|
|
747
|
+
message: a
|
|
748
|
+
});
|
|
749
|
+
throw e.dispatchEvent(l), o;
|
|
644
750
|
}
|
|
645
|
-
throw
|
|
751
|
+
throw (!isExitCode(o) || o.exitCode !== 0) && showCriticalErrorBox(a), o;
|
|
646
752
|
}
|
|
647
753
|
};
|
|
648
754
|
}
|
|
@@ -731,7 +837,7 @@ class PHPExecutionFailureError extends Error {
|
|
|
731
837
|
}
|
|
732
838
|
}
|
|
733
839
|
const PHP_INI_PATH = "/internal/shared/php.ini", AUTO_PREPEND_SCRIPT = "/internal/shared/auto_prepend_file.php";
|
|
734
|
-
var
|
|
840
|
+
var b, f, E, P, R, T, p, z, q, W, G, V, J, Y, K, X, L, Q, $, B;
|
|
735
841
|
class PHP {
|
|
736
842
|
/**
|
|
737
843
|
* Initializes a PHP runtime.
|
|
@@ -741,13 +847,13 @@ class PHP {
|
|
|
741
847
|
* @param requestHandlerOptions - Optional. Options for the PHPRequestHandler. If undefined, no request handler will be initialized.
|
|
742
848
|
*/
|
|
743
849
|
constructor(t) {
|
|
744
|
-
h(this,
|
|
745
|
-
h(this,
|
|
746
|
-
h(this,
|
|
747
|
-
h(this,
|
|
748
|
-
h(this,
|
|
749
|
-
h(this,
|
|
750
|
-
h(this,
|
|
850
|
+
h(this, p);
|
|
851
|
+
h(this, b);
|
|
852
|
+
h(this, f, !1);
|
|
853
|
+
h(this, E, null);
|
|
854
|
+
h(this, P, /* @__PURE__ */ new Map());
|
|
855
|
+
h(this, R, []);
|
|
856
|
+
h(this, T, {});
|
|
751
857
|
this.semaphore = new Semaphore({ concurrency: 1 }), t !== void 0 && this.initializeRuntime(t);
|
|
752
858
|
}
|
|
753
859
|
/**
|
|
@@ -756,7 +862,7 @@ class PHP {
|
|
|
756
862
|
* @param listener - The listener function to be called when the event is triggered.
|
|
757
863
|
*/
|
|
758
864
|
addEventListener(t, e) {
|
|
759
|
-
c(this,
|
|
865
|
+
c(this, P).has(t) || c(this, P).set(t, /* @__PURE__ */ new Set()), c(this, P).get(t).add(e);
|
|
760
866
|
}
|
|
761
867
|
/**
|
|
762
868
|
* Removes an event listener for a PHP event.
|
|
@@ -765,10 +871,10 @@ class PHP {
|
|
|
765
871
|
*/
|
|
766
872
|
removeEventListener(t, e) {
|
|
767
873
|
var r;
|
|
768
|
-
(r = c(this,
|
|
874
|
+
(r = c(this, P).get(t)) == null || r.delete(e);
|
|
769
875
|
}
|
|
770
876
|
dispatchEvent(t) {
|
|
771
|
-
const e = c(this,
|
|
877
|
+
const e = c(this, P).get(t.type);
|
|
772
878
|
if (e)
|
|
773
879
|
for (const r of e)
|
|
774
880
|
r(t);
|
|
@@ -813,8 +919,8 @@ class PHP {
|
|
|
813
919
|
* @param listener Callback function to handle the message.
|
|
814
920
|
*/
|
|
815
921
|
onMessage(t) {
|
|
816
|
-
return c(this,
|
|
817
|
-
m(this,
|
|
922
|
+
return c(this, R).push(t), async () => {
|
|
923
|
+
m(this, R, c(this, R).filter(
|
|
818
924
|
(e) => e !== t
|
|
819
925
|
));
|
|
820
926
|
};
|
|
@@ -890,13 +996,13 @@ class PHP {
|
|
|
890
996
|
}
|
|
891
997
|
`
|
|
892
998
|
), e.onMessage = async (r) => {
|
|
893
|
-
for (const s of c(this,
|
|
999
|
+
for (const s of c(this, R)) {
|
|
894
1000
|
const i = await s(r);
|
|
895
1001
|
if (i)
|
|
896
1002
|
return i;
|
|
897
1003
|
}
|
|
898
1004
|
return "";
|
|
899
|
-
}, m(this,
|
|
1005
|
+
}, m(this, E, improveWASMErrorReporting(e)), this.dispatchEvent({
|
|
900
1006
|
type: "runtime.initialized"
|
|
901
1007
|
});
|
|
902
1008
|
}
|
|
@@ -911,7 +1017,7 @@ class PHP {
|
|
|
911
1017
|
throw new Error(
|
|
912
1018
|
"Could not set SAPI name. This can only be done before the PHP WASM module is initialized.Did you already dispatch any requests?"
|
|
913
1019
|
);
|
|
914
|
-
m(this,
|
|
1020
|
+
m(this, b, t);
|
|
915
1021
|
}
|
|
916
1022
|
/**
|
|
917
1023
|
* Changes the current working directory in the PHP filesystem.
|
|
@@ -995,66 +1101,179 @@ class PHP {
|
|
|
995
1101
|
*
|
|
996
1102
|
* @example
|
|
997
1103
|
* ```js
|
|
998
|
-
* const result = await php.run(
|
|
999
|
-
*
|
|
1000
|
-
*
|
|
1001
|
-
*
|
|
1104
|
+
* const result = await php.run({
|
|
1105
|
+
* code: `<?php
|
|
1106
|
+
* $fp = fopen('php://stderr', 'w');
|
|
1107
|
+
* fwrite($fp, "Hello, world!");
|
|
1108
|
+
* `
|
|
1109
|
+
* });
|
|
1002
1110
|
* // result.errors === "Hello, world!"
|
|
1003
1111
|
* ```
|
|
1004
1112
|
*
|
|
1005
|
-
* @
|
|
1113
|
+
* @deprecated Use stream() instead.
|
|
1114
|
+
* @param request - PHP runtime options.
|
|
1006
1115
|
*/
|
|
1007
1116
|
async run(t) {
|
|
1117
|
+
const e = await this.runStream(t), r = await PHPResponse.fromStreamedResponse(
|
|
1118
|
+
e
|
|
1119
|
+
);
|
|
1120
|
+
if (r.exitCode !== 0) {
|
|
1121
|
+
logger.warn("PHP.run() output was:", r.text);
|
|
1122
|
+
const s = new PHPExecutionFailureError(
|
|
1123
|
+
`PHP.run() failed with exit code ${r.exitCode} and the following output: ` + r.errors + `
|
|
1124
|
+
|
|
1125
|
+
` + r.text,
|
|
1126
|
+
r,
|
|
1127
|
+
"request"
|
|
1128
|
+
);
|
|
1129
|
+
throw logger.error(s), this.dispatchEvent({
|
|
1130
|
+
type: "request.error",
|
|
1131
|
+
error: new Error(
|
|
1132
|
+
"PHP.run() failed with exit code " + r.exitCode
|
|
1133
|
+
),
|
|
1134
|
+
// Distinguish between PHP request and PHP-wasm errors
|
|
1135
|
+
source: "request"
|
|
1136
|
+
}), s;
|
|
1137
|
+
}
|
|
1138
|
+
return r;
|
|
1139
|
+
}
|
|
1140
|
+
/**
|
|
1141
|
+
* Runs PHP code and returns a StreamedPHPResponse object that can be used to
|
|
1142
|
+
* process the output incrementally.
|
|
1143
|
+
*
|
|
1144
|
+
* This low-level method directly interacts with the WebAssembly
|
|
1145
|
+
* PHP interpreter and provides streaming capabilities for processing
|
|
1146
|
+
* PHP output as it becomes available.
|
|
1147
|
+
*
|
|
1148
|
+
* Every time you call stream(), it prepares the PHP
|
|
1149
|
+
* environment and:
|
|
1150
|
+
*
|
|
1151
|
+
* * Resets the internal PHP state
|
|
1152
|
+
* * Populates superglobals ($_SERVER, $_GET, etc.)
|
|
1153
|
+
* * Handles file uploads
|
|
1154
|
+
* * Populates input streams (stdin, argv, etc.)
|
|
1155
|
+
* * Sets the current working directory
|
|
1156
|
+
*
|
|
1157
|
+
* You can use stream() in two primary modes:
|
|
1158
|
+
*
|
|
1159
|
+
* ### Code snippet mode
|
|
1160
|
+
*
|
|
1161
|
+
* In this mode, you pass a string containing PHP code to run.
|
|
1162
|
+
*
|
|
1163
|
+
* ```ts
|
|
1164
|
+
* const streamedResponse = await php.stream({
|
|
1165
|
+
* code: `<?php echo "Hello world!";`
|
|
1166
|
+
* });
|
|
1167
|
+
* // Process output incrementally
|
|
1168
|
+
* for await (const chunk of streamedResponse.text) {
|
|
1169
|
+
* console.log(chunk);
|
|
1170
|
+
* }
|
|
1171
|
+
* ```
|
|
1172
|
+
*
|
|
1173
|
+
* In this mode, information like __DIR__ or __FILE__ isn't very
|
|
1174
|
+
* useful because the code is not associated with any file.
|
|
1175
|
+
*
|
|
1176
|
+
* Under the hood, the PHP snippet is passed to the `zend_eval_string`
|
|
1177
|
+
* C function.
|
|
1178
|
+
*
|
|
1179
|
+
* ### File mode
|
|
1180
|
+
*
|
|
1181
|
+
* In the file mode, you pass a scriptPath and PHP executes a file
|
|
1182
|
+
* found at that path:
|
|
1183
|
+
*
|
|
1184
|
+
* ```ts
|
|
1185
|
+
* php.writeFile(
|
|
1186
|
+
* "/www/index.php",
|
|
1187
|
+
* `<?php echo "Hello world!";"`
|
|
1188
|
+
* );
|
|
1189
|
+
* const streamedResponse = await php.stream({
|
|
1190
|
+
* scriptPath: "/www/index.php"
|
|
1191
|
+
* });
|
|
1192
|
+
* // Process output incrementally
|
|
1193
|
+
* for await (const chunk of streamedResponse.text) {
|
|
1194
|
+
* console.log(chunk);
|
|
1195
|
+
* }
|
|
1196
|
+
* ```
|
|
1197
|
+
*
|
|
1198
|
+
* In this mode, you can rely on path-related information like __DIR__
|
|
1199
|
+
* or __FILE__.
|
|
1200
|
+
*
|
|
1201
|
+
* Under the hood, the PHP file is executed with the `php_execute_script`
|
|
1202
|
+
* C function.
|
|
1203
|
+
*
|
|
1204
|
+
* The `stream()` method cannot be used in conjunction with `cli()`.
|
|
1205
|
+
*
|
|
1206
|
+
* @example
|
|
1207
|
+
* ```js
|
|
1208
|
+
* const streamedResponse = await php.stream({
|
|
1209
|
+
* code: `<?php
|
|
1210
|
+
* for ($i = 0; $i < 5; $i++) {
|
|
1211
|
+
* echo "Line $i\n";
|
|
1212
|
+
* flush();
|
|
1213
|
+
* }
|
|
1214
|
+
* `
|
|
1215
|
+
* });
|
|
1216
|
+
*
|
|
1217
|
+
* // Process output as it becomes available
|
|
1218
|
+
* for await (const chunk of streamedResponse.text) {
|
|
1219
|
+
* console.log('Received:', chunk);
|
|
1220
|
+
* }
|
|
1221
|
+
*
|
|
1222
|
+
* // Get the final exit code
|
|
1223
|
+
* const exitCode = await streamedResponse.exitCode;
|
|
1224
|
+
* console.log('Exit code:', exitCode);
|
|
1225
|
+
* ```
|
|
1226
|
+
*
|
|
1227
|
+
* @see run() – a synchronous version of this method.
|
|
1228
|
+
* @param request - PHP runtime options.
|
|
1229
|
+
* @returns A StreamedPHPResponse object.
|
|
1230
|
+
*/
|
|
1231
|
+
async runStream(t) {
|
|
1008
1232
|
const e = await this.semaphore.acquire();
|
|
1009
1233
|
let r;
|
|
1010
|
-
|
|
1011
|
-
if (c(this,
|
|
1234
|
+
const s = d(this, p, B).call(this, () => {
|
|
1235
|
+
if (c(this, f) || (d(this, p, q).call(this), m(this, f, !0)), t.scriptPath && !this.fileExists(t.scriptPath))
|
|
1012
1236
|
throw new Error(
|
|
1013
1237
|
`The script path "${t.scriptPath}" does not exist.`
|
|
1014
1238
|
);
|
|
1015
|
-
d(this,
|
|
1016
|
-
const
|
|
1017
|
-
if (d(this,
|
|
1018
|
-
this.writeFile("/internal/eval.php", t.code), d(this,
|
|
1239
|
+
d(this, p, W).call(this, t.relativeUri || ""), d(this, p, Y).call(this, t.method || "GET");
|
|
1240
|
+
const i = normalizeHeaders(t.headers || {}), n = i.host || "example.com:443", o = d(this, p, J).call(this, n, t.protocol || "http");
|
|
1241
|
+
if (d(this, p, G).call(this, n), d(this, p, V).call(this, o), d(this, p, K).call(this, i), t.body && (r = d(this, p, X).call(this, t.body)), typeof t.code == "string")
|
|
1242
|
+
this.writeFile("/internal/eval.php", t.code), d(this, p, L).call(this, "/internal/eval.php");
|
|
1019
1243
|
else if (typeof t.scriptPath == "string")
|
|
1020
|
-
d(this,
|
|
1244
|
+
d(this, p, L).call(this, t.scriptPath || "");
|
|
1021
1245
|
else
|
|
1022
1246
|
throw new TypeError(
|
|
1023
1247
|
"The request object must have either a `code` or a `scriptPath` property."
|
|
1024
1248
|
);
|
|
1025
|
-
const
|
|
1026
|
-
for (const
|
|
1027
|
-
d(this,
|
|
1249
|
+
const a = d(this, p, z).call(this, t.$_SERVER, i, o);
|
|
1250
|
+
for (const u in a)
|
|
1251
|
+
d(this, p, Q).call(this, u, a[u]);
|
|
1028
1252
|
const l = t.env || {};
|
|
1029
|
-
for (const
|
|
1030
|
-
d(this,
|
|
1031
|
-
|
|
1032
|
-
|
|
1033
|
-
|
|
1034
|
-
|
|
1035
|
-
|
|
1036
|
-
|
|
1037
|
-
|
|
1038
|
-
|
|
1039
|
-
|
|
1040
|
-
|
|
1041
|
-
return a;
|
|
1042
|
-
} catch (s) {
|
|
1043
|
-
throw this.dispatchEvent({
|
|
1253
|
+
for (const u in l)
|
|
1254
|
+
d(this, p, $).call(this, u, l[u]);
|
|
1255
|
+
return c(this, f) || (d(this, p, q).call(this), m(this, f, !0)), this[__private__dont__use].ccall(
|
|
1256
|
+
"wasm_sapi_handle_request",
|
|
1257
|
+
NUMBER,
|
|
1258
|
+
[],
|
|
1259
|
+
[],
|
|
1260
|
+
{ async: !0 }
|
|
1261
|
+
);
|
|
1262
|
+
});
|
|
1263
|
+
return await s.catch((i) => {
|
|
1264
|
+
this.dispatchEvent({
|
|
1044
1265
|
type: "request.error",
|
|
1045
|
-
error:
|
|
1266
|
+
error: i,
|
|
1046
1267
|
// Distinguish between PHP request and PHP-wasm errors
|
|
1047
|
-
source:
|
|
1048
|
-
})
|
|
1049
|
-
}
|
|
1050
|
-
|
|
1051
|
-
|
|
1052
|
-
|
|
1053
|
-
|
|
1054
|
-
|
|
1055
|
-
|
|
1056
|
-
}
|
|
1057
|
-
}
|
|
1268
|
+
source: i.source ?? "php-wasm"
|
|
1269
|
+
});
|
|
1270
|
+
}).finally(() => {
|
|
1271
|
+
r && this[__private__dont__use].free(r);
|
|
1272
|
+
}).finally(() => {
|
|
1273
|
+
e(), this.dispatchEvent({
|
|
1274
|
+
type: "request.end"
|
|
1275
|
+
});
|
|
1276
|
+
}), s;
|
|
1058
1277
|
}
|
|
1059
1278
|
/**
|
|
1060
1279
|
* Defines a constant in the PHP runtime.
|
|
@@ -1238,15 +1457,15 @@ class PHP {
|
|
|
1238
1457
|
*/
|
|
1239
1458
|
async hotSwapPHPRuntime(t, e) {
|
|
1240
1459
|
const r = this[__private__dont__use].FS, s = [];
|
|
1241
|
-
for (const [i,
|
|
1242
|
-
s.push({ mountHandler:
|
|
1460
|
+
for (const [i, n] of Object.entries(c(this, T)))
|
|
1461
|
+
s.push({ mountHandler: n.mountHandler, vfsPath: i }), await n.unmount();
|
|
1243
1462
|
try {
|
|
1244
1463
|
this.exit();
|
|
1245
1464
|
} catch {
|
|
1246
1465
|
}
|
|
1247
|
-
this.initializeRuntime(t), c(this,
|
|
1248
|
-
for (const { mountHandler: i, vfsPath:
|
|
1249
|
-
this.mkdir(
|
|
1466
|
+
this.initializeRuntime(t), c(this, b) && this.setSapiName(c(this, b)), copyFS(r, this[__private__dont__use].FS, "/internal"), e && copyFS(r, this[__private__dont__use].FS, e);
|
|
1467
|
+
for (const { mountHandler: i, vfsPath: n } of s)
|
|
1468
|
+
this.mkdir(n), await this.mount(n, i);
|
|
1250
1469
|
}
|
|
1251
1470
|
/**
|
|
1252
1471
|
* Mounts a filesystem to a given path in the PHP filesystem.
|
|
@@ -1263,10 +1482,10 @@ class PHP {
|
|
|
1263
1482
|
), s = {
|
|
1264
1483
|
mountHandler: e,
|
|
1265
1484
|
unmount: async () => {
|
|
1266
|
-
await r(), delete c(this,
|
|
1485
|
+
await r(), delete c(this, T)[t];
|
|
1267
1486
|
}
|
|
1268
1487
|
};
|
|
1269
|
-
return c(this,
|
|
1488
|
+
return c(this, T)[t] = s, () => {
|
|
1270
1489
|
s.unmount();
|
|
1271
1490
|
};
|
|
1272
1491
|
}
|
|
@@ -1283,29 +1502,21 @@ class PHP {
|
|
|
1283
1502
|
* @param argv - The arguments to pass to the CLI.
|
|
1284
1503
|
* @returns The exit code of the CLI session.
|
|
1285
1504
|
*/
|
|
1286
|
-
async cli(t) {
|
|
1287
|
-
|
|
1505
|
+
async cli(t, e = {}) {
|
|
1506
|
+
const r = await this.semaphore.acquire(), s = e.env || {};
|
|
1507
|
+
for (const [i, n] of Object.entries(s))
|
|
1508
|
+
d(this, p, $).call(this, i, n);
|
|
1509
|
+
t = [t[0], "-c", PHP_INI_PATH, ...t.slice(1)];
|
|
1510
|
+
for (const i of t)
|
|
1288
1511
|
this[__private__dont__use].ccall(
|
|
1289
1512
|
"wasm_add_cli_arg",
|
|
1290
1513
|
null,
|
|
1291
1514
|
[STRING],
|
|
1292
|
-
[
|
|
1293
|
-
);
|
|
1294
|
-
try {
|
|
1295
|
-
return await this[__private__dont__use].ccall(
|
|
1296
|
-
"run_cli",
|
|
1297
|
-
null,
|
|
1298
|
-
[],
|
|
1299
|
-
[],
|
|
1300
|
-
{
|
|
1301
|
-
async: !0
|
|
1302
|
-
}
|
|
1515
|
+
[i]
|
|
1303
1516
|
);
|
|
1304
|
-
|
|
1305
|
-
|
|
1306
|
-
|
|
1307
|
-
throw e;
|
|
1308
|
-
}
|
|
1517
|
+
return await d(this, p, B).call(this, () => this[__private__dont__use].ccall("run_cli", null, [], [], {
|
|
1518
|
+
async: !0
|
|
1519
|
+
})).then((i) => (i.exitCode.finally(r), i));
|
|
1309
1520
|
}
|
|
1310
1521
|
setSkipShebang(t) {
|
|
1311
1522
|
this[__private__dont__use].ccall(
|
|
@@ -1323,13 +1534,13 @@ class PHP {
|
|
|
1323
1534
|
this[__private__dont__use]._exit(t);
|
|
1324
1535
|
} catch {
|
|
1325
1536
|
}
|
|
1326
|
-
m(this,
|
|
1537
|
+
m(this, f, !1), m(this, E, null), delete this[__private__dont__use].onMessage, delete this[__private__dont__use];
|
|
1327
1538
|
}
|
|
1328
1539
|
[Symbol.dispose]() {
|
|
1329
|
-
c(this,
|
|
1540
|
+
c(this, f) && this.exit(0);
|
|
1330
1541
|
}
|
|
1331
1542
|
}
|
|
1332
|
-
|
|
1543
|
+
b = new WeakMap(), f = new WeakMap(), E = new WeakMap(), P = new WeakMap(), R = new WeakMap(), T = new WeakMap(), p = new WeakSet(), /**
|
|
1333
1544
|
* Prepares the $_SERVER entries for the PHP runtime.
|
|
1334
1545
|
*
|
|
1335
1546
|
* @param defaults Default entries to include in $_SERVER.
|
|
@@ -1338,36 +1549,19 @@ F = new WeakMap(), P = new WeakMap(), v = new WeakMap(), _ = new WeakMap(), x =
|
|
|
1338
1549
|
* was provided.
|
|
1339
1550
|
* @returns Computed $_SERVER entries.
|
|
1340
1551
|
*/
|
|
1341
|
-
|
|
1552
|
+
z = function(t, e, r) {
|
|
1342
1553
|
const s = {
|
|
1343
1554
|
...t || {}
|
|
1344
1555
|
};
|
|
1345
1556
|
s.HTTPS = s.HTTPS || r === 443 ? "on" : "off";
|
|
1346
1557
|
for (const i in e) {
|
|
1347
|
-
let
|
|
1348
|
-
["content-type", "content-length"].includes(i.toLowerCase()) && (
|
|
1558
|
+
let n = "HTTP_";
|
|
1559
|
+
["content-type", "content-length"].includes(i.toLowerCase()) && (n = ""), s[`${n}${i.toUpperCase().replace(/-/g, "_")}`] = e[i];
|
|
1349
1560
|
}
|
|
1350
1561
|
return s;
|
|
1351
|
-
},
|
|
1562
|
+
}, q = function() {
|
|
1352
1563
|
this[__private__dont__use].ccall("php_wasm_init", null, [], []);
|
|
1353
|
-
},
|
|
1354
|
-
const t = "/internal/headers.json";
|
|
1355
|
-
if (!this.fileExists(t))
|
|
1356
|
-
throw new Error(
|
|
1357
|
-
"SAPI Error: Could not find response headers file."
|
|
1358
|
-
);
|
|
1359
|
-
const e = JSON.parse(this.readFileAsText(t)), r = {};
|
|
1360
|
-
for (const s of e.headers) {
|
|
1361
|
-
if (!s.includes(": "))
|
|
1362
|
-
continue;
|
|
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);
|
|
1365
|
-
}
|
|
1366
|
-
return {
|
|
1367
|
-
headers: r,
|
|
1368
|
-
httpStatusCode: e.status
|
|
1369
|
-
};
|
|
1370
|
-
}, U = function(t) {
|
|
1564
|
+
}, W = function(t) {
|
|
1371
1565
|
this[__private__dont__use].ccall(
|
|
1372
1566
|
"wasm_set_request_uri",
|
|
1373
1567
|
null,
|
|
@@ -1381,35 +1575,35 @@ N = function(t, e, r) {
|
|
|
1381
1575
|
[STRING],
|
|
1382
1576
|
[e]
|
|
1383
1577
|
);
|
|
1384
|
-
},
|
|
1578
|
+
}, G = function(t) {
|
|
1385
1579
|
this[__private__dont__use].ccall(
|
|
1386
1580
|
"wasm_set_request_host",
|
|
1387
1581
|
null,
|
|
1388
1582
|
[STRING],
|
|
1389
1583
|
[t]
|
|
1390
1584
|
);
|
|
1391
|
-
},
|
|
1585
|
+
}, V = function(t) {
|
|
1392
1586
|
this[__private__dont__use].ccall(
|
|
1393
1587
|
"wasm_set_request_port",
|
|
1394
1588
|
null,
|
|
1395
1589
|
[NUMBER],
|
|
1396
1590
|
[t]
|
|
1397
1591
|
);
|
|
1398
|
-
},
|
|
1592
|
+
}, J = function(t, e) {
|
|
1399
1593
|
let r;
|
|
1400
1594
|
try {
|
|
1401
1595
|
r = parseInt(new URL(t).port, 10);
|
|
1402
1596
|
} catch {
|
|
1403
1597
|
}
|
|
1404
1598
|
return (!r || isNaN(r) || r === 80) && (r = e === "https" ? 443 : 80), r;
|
|
1405
|
-
},
|
|
1599
|
+
}, Y = function(t) {
|
|
1406
1600
|
this[__private__dont__use].ccall(
|
|
1407
1601
|
"wasm_set_request_method",
|
|
1408
1602
|
null,
|
|
1409
1603
|
[STRING],
|
|
1410
1604
|
[t]
|
|
1411
1605
|
);
|
|
1412
|
-
},
|
|
1606
|
+
}, K = function(t) {
|
|
1413
1607
|
t.cookie && this[__private__dont__use].ccall(
|
|
1414
1608
|
"wasm_set_cookies",
|
|
1415
1609
|
null,
|
|
@@ -1426,7 +1620,7 @@ N = function(t, e, r) {
|
|
|
1426
1620
|
[NUMBER],
|
|
1427
1621
|
[parseInt(t["content-length"], 10)]
|
|
1428
1622
|
);
|
|
1429
|
-
},
|
|
1623
|
+
}, X = function(t) {
|
|
1430
1624
|
let e, r;
|
|
1431
1625
|
typeof t == "string" ? (logger.warn(
|
|
1432
1626
|
"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"
|
|
@@ -1449,70 +1643,88 @@ N = function(t, e, r) {
|
|
|
1449
1643
|
[NUMBER],
|
|
1450
1644
|
[r]
|
|
1451
1645
|
), s;
|
|
1452
|
-
},
|
|
1646
|
+
}, L = function(t) {
|
|
1453
1647
|
this[__private__dont__use].ccall(
|
|
1454
1648
|
"wasm_set_path_translated",
|
|
1455
1649
|
null,
|
|
1456
1650
|
[STRING],
|
|
1457
1651
|
[t]
|
|
1458
1652
|
);
|
|
1459
|
-
},
|
|
1653
|
+
}, Q = function(t, e) {
|
|
1460
1654
|
this[__private__dont__use].ccall(
|
|
1461
1655
|
"wasm_add_SERVER_entry",
|
|
1462
1656
|
null,
|
|
1463
1657
|
[STRING, STRING],
|
|
1464
1658
|
[t, e]
|
|
1465
1659
|
);
|
|
1466
|
-
},
|
|
1660
|
+
}, $ = function(t, e) {
|
|
1467
1661
|
this[__private__dont__use].ccall(
|
|
1468
1662
|
"wasm_add_ENV_entry",
|
|
1469
1663
|
null,
|
|
1470
1664
|
[STRING, STRING],
|
|
1471
1665
|
[t, e]
|
|
1472
1666
|
);
|
|
1473
|
-
},
|
|
1474
|
-
|
|
1475
|
-
|
|
1476
|
-
|
|
1477
|
-
|
|
1478
|
-
|
|
1479
|
-
|
|
1480
|
-
|
|
1481
|
-
|
|
1482
|
-
|
|
1483
|
-
|
|
1667
|
+
}, B = async function(t) {
|
|
1668
|
+
const e = this[__private__dont__use], r = await createInvertedReadableStream();
|
|
1669
|
+
e.onHeaders = (w) => {
|
|
1670
|
+
a || s || r.controller.enqueue(w.slice());
|
|
1671
|
+
};
|
|
1672
|
+
let s = !1;
|
|
1673
|
+
const i = () => {
|
|
1674
|
+
s || (s = !0, r.controller.close());
|
|
1675
|
+
}, n = await createInvertedReadableStream();
|
|
1676
|
+
e.onStdout = (w) => {
|
|
1677
|
+
i(), !a && n.controller.enqueue(w.slice());
|
|
1678
|
+
};
|
|
1679
|
+
const o = await createInvertedReadableStream();
|
|
1680
|
+
e.onStderr = (w) => {
|
|
1681
|
+
a || o.controller.enqueue(w.slice());
|
|
1682
|
+
};
|
|
1683
|
+
let a = !1, l;
|
|
1684
|
+
const O = (async () => {
|
|
1685
|
+
var w;
|
|
1686
|
+
try {
|
|
1687
|
+
return await Promise.race([
|
|
1688
|
+
t(),
|
|
1689
|
+
new Promise((A, M) => {
|
|
1690
|
+
var F;
|
|
1691
|
+
l = (y) => {
|
|
1692
|
+
if (logger.error(y), logger.error(y.error), !isExitCode(y.error)) {
|
|
1693
|
+
const j = new Error("Rethrown");
|
|
1694
|
+
j.cause = y.error, j.betterMessage = y.message, M(j);
|
|
1695
|
+
}
|
|
1696
|
+
}, (F = c(this, E)) == null || F.addEventListener(
|
|
1697
|
+
"error",
|
|
1698
|
+
l,
|
|
1699
|
+
{ once: !0 }
|
|
1700
|
+
);
|
|
1701
|
+
})
|
|
1702
|
+
]);
|
|
1703
|
+
} catch (S) {
|
|
1704
|
+
if (isExitCode(S))
|
|
1705
|
+
return S.exitCode;
|
|
1706
|
+
n.controller.error(S), o.controller.error(S), r.controller.error(S), a = !0;
|
|
1707
|
+
for (const y in this)
|
|
1708
|
+
typeof this[y] == "function" && (this[y] = () => {
|
|
1709
|
+
throw new Error(
|
|
1710
|
+
"PHP runtime has crashed – see the earlier error for details."
|
|
1711
|
+
);
|
|
1712
|
+
});
|
|
1713
|
+
this.functionsMaybeMissingFromAsyncify = getFunctionsMaybeMissingFromAsyncify();
|
|
1714
|
+
const A = S, M = "betterMessage" in A ? A.betterMessage : A.message, F = new Error(M);
|
|
1715
|
+
throw F.cause = A, logger.error(F), F;
|
|
1716
|
+
} finally {
|
|
1717
|
+
a || (n.controller.close(), o.controller.close(), i(), a = !0), (w = c(this, E)) == null || w.removeEventListener(
|
|
1484
1718
|
"error",
|
|
1485
|
-
|
|
1486
|
-
);
|
|
1487
|
-
const l = this[__private__dont__use].ccall(
|
|
1488
|
-
"wasm_sapi_handle_request",
|
|
1489
|
-
NUMBER,
|
|
1490
|
-
[],
|
|
1491
|
-
[],
|
|
1492
|
-
{ async: !0 }
|
|
1719
|
+
l
|
|
1493
1720
|
);
|
|
1494
|
-
|
|
1495
|
-
|
|
1496
|
-
|
|
1497
|
-
|
|
1498
|
-
|
|
1499
|
-
|
|
1500
|
-
|
|
1501
|
-
);
|
|
1502
|
-
});
|
|
1503
|
-
this.functionsMaybeMissingFromAsyncify = getFunctionsMaybeMissingFromAsyncify();
|
|
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;
|
|
1506
|
-
} finally {
|
|
1507
|
-
(i = c(this, v)) == null || i.removeEventListener("error", e);
|
|
1508
|
-
}
|
|
1509
|
-
const { headers: r, httpStatusCode: s } = d(this, u, j).call(this);
|
|
1510
|
-
return new PHPResponse(
|
|
1511
|
-
t === 0 ? s : 500,
|
|
1512
|
-
r,
|
|
1513
|
-
this.readFileAsBuffer("/internal/stdout"),
|
|
1514
|
-
this.readFileAsText("/internal/stderr"),
|
|
1515
|
-
t
|
|
1721
|
+
}
|
|
1722
|
+
})();
|
|
1723
|
+
return new StreamedPHPResponse(
|
|
1724
|
+
r.stream,
|
|
1725
|
+
n.stream,
|
|
1726
|
+
o.stream,
|
|
1727
|
+
O
|
|
1516
1728
|
);
|
|
1517
1729
|
};
|
|
1518
1730
|
function normalizeHeaders(t) {
|
|
@@ -1535,9 +1747,27 @@ function copyFS(t, e, r) {
|
|
|
1535
1747
|
return;
|
|
1536
1748
|
}
|
|
1537
1749
|
e.mkdirTree(r);
|
|
1538
|
-
const i = t.readdir(r).filter((
|
|
1539
|
-
for (const
|
|
1540
|
-
copyFS(t, e, joinPaths(r,
|
|
1750
|
+
const i = t.readdir(r).filter((n) => n !== "." && n !== "..");
|
|
1751
|
+
for (const n of i)
|
|
1752
|
+
copyFS(t, e, joinPaths(r, n));
|
|
1753
|
+
}
|
|
1754
|
+
async function createInvertedReadableStream(t = {}) {
|
|
1755
|
+
let e;
|
|
1756
|
+
const r = new Promise(
|
|
1757
|
+
(n) => {
|
|
1758
|
+
e = n;
|
|
1759
|
+
}
|
|
1760
|
+
), s = new ReadableStream({
|
|
1761
|
+
...t,
|
|
1762
|
+
start(n) {
|
|
1763
|
+
if (e(n), t.start)
|
|
1764
|
+
return t.start(n);
|
|
1765
|
+
}
|
|
1766
|
+
}), i = await r;
|
|
1767
|
+
return {
|
|
1768
|
+
stream: s,
|
|
1769
|
+
controller: i
|
|
1770
|
+
};
|
|
1541
1771
|
}
|
|
1542
1772
|
async function getPhpIniEntries(t, e) {
|
|
1543
1773
|
const r = parse(await t.readFileAsText(PHP_INI_PATH));
|
|
@@ -1572,8 +1802,8 @@ class HttpCookieStore {
|
|
|
1572
1802
|
try {
|
|
1573
1803
|
if (!r.includes("="))
|
|
1574
1804
|
continue;
|
|
1575
|
-
const s = r.indexOf("="), i = r.substring(0, s),
|
|
1576
|
-
this.cookies[i] =
|
|
1805
|
+
const s = r.indexOf("="), i = r.substring(0, s), n = r.substring(s + 1).split(";")[0];
|
|
1806
|
+
this.cookies[i] = n;
|
|
1577
1807
|
} catch (s) {
|
|
1578
1808
|
logger.error(s);
|
|
1579
1809
|
}
|
|
@@ -1599,22 +1829,22 @@ async function* iteratePhpFiles(t, e, {
|
|
|
1599
1829
|
exceptPaths: i = []
|
|
1600
1830
|
} = {}) {
|
|
1601
1831
|
e = normalizePath(e);
|
|
1602
|
-
const
|
|
1603
|
-
for (;
|
|
1604
|
-
const
|
|
1605
|
-
if (!
|
|
1832
|
+
const n = [e];
|
|
1833
|
+
for (; n.length; ) {
|
|
1834
|
+
const o = n.pop();
|
|
1835
|
+
if (!o)
|
|
1606
1836
|
return;
|
|
1607
|
-
const
|
|
1608
|
-
for (const
|
|
1609
|
-
const
|
|
1610
|
-
if (i.includes(
|
|
1837
|
+
const a = await t.listFiles(o);
|
|
1838
|
+
for (const l of a) {
|
|
1839
|
+
const u = `${o}/${l}`;
|
|
1840
|
+
if (i.includes(u.substring(e.length + 1)))
|
|
1611
1841
|
continue;
|
|
1612
|
-
await t.isDir(
|
|
1613
|
-
streamReadFileFromPHP(t,
|
|
1842
|
+
await t.isDir(u) ? n.push(u) : yield new StreamedFile(
|
|
1843
|
+
streamReadFileFromPHP(t, u),
|
|
1614
1844
|
r ? joinPaths(
|
|
1615
1845
|
s || "",
|
|
1616
|
-
|
|
1617
|
-
) :
|
|
1846
|
+
u.substring(e.length + 1)
|
|
1847
|
+
) : u
|
|
1618
1848
|
);
|
|
1619
1849
|
}
|
|
1620
1850
|
}
|
|
@@ -1661,11 +1891,7 @@ class PHPProcessManager {
|
|
|
1661
1891
|
throw new Error(
|
|
1662
1892
|
"phpFactory or primaryPhp must be set before calling getPrimaryPhp()."
|
|
1663
1893
|
);
|
|
1664
|
-
|
|
1665
|
-
const e = await this.spawn({ isPrimary: !0 });
|
|
1666
|
-
this.primaryPhp = e.php;
|
|
1667
|
-
}
|
|
1668
|
-
return this.primaryPhp;
|
|
1894
|
+
return this.primaryPhp || (this.primaryPhpPromise || (this.primaryPhpPromise = this.spawn({ isPrimary: !0 })), this.primaryPhp = (await this.primaryPhpPromise).php, this.primaryPhpPromise = void 0), this.primaryPhp;
|
|
1669
1895
|
}
|
|
1670
1896
|
/**
|
|
1671
1897
|
* Get a PHP instance.
|
|
@@ -1674,17 +1900,32 @@ class PHPProcessManager {
|
|
|
1674
1900
|
* instance, or a newly spawned PHP instance – depending on the resource
|
|
1675
1901
|
* availability.
|
|
1676
1902
|
*
|
|
1903
|
+
* @param considerPrimary - Whether to consider the primary PHP instance.
|
|
1904
|
+
* It matters because PHP.cli() sets the SAPI to CLI and
|
|
1905
|
+
* kills the entire process after it finishes running,
|
|
1906
|
+
* making the primary PHP instance non-reusable for
|
|
1907
|
+
* subsequent .run() calls. This is fine for one-off
|
|
1908
|
+
* child PHP instances, but not for the primary PHP
|
|
1909
|
+
* that's meant to continue working for the entire duration
|
|
1910
|
+
* of the ProcessManager lifetime. Therefore, we don't
|
|
1911
|
+
* consider the primary PHP instance by default unless
|
|
1912
|
+
* the caller explicitly requests it.
|
|
1913
|
+
*
|
|
1677
1914
|
* @throws {MaxPhpInstancesError} when the maximum number of PHP instances is reached
|
|
1678
1915
|
* and the waiting timeout is exceeded.
|
|
1679
1916
|
*/
|
|
1680
|
-
async acquirePHPInstance(
|
|
1681
|
-
|
|
1917
|
+
async acquirePHPInstance({
|
|
1918
|
+
considerPrimary: e = !0
|
|
1919
|
+
} = {}) {
|
|
1920
|
+
if (this.primaryPhp || await this.getPrimaryPhp(), this.primaryIdle && e)
|
|
1682
1921
|
return this.primaryIdle = !1, {
|
|
1683
1922
|
php: await this.getPrimaryPhp(),
|
|
1684
|
-
reap: () =>
|
|
1923
|
+
reap: () => {
|
|
1924
|
+
this.primaryIdle = !0;
|
|
1925
|
+
}
|
|
1685
1926
|
};
|
|
1686
|
-
const
|
|
1687
|
-
return this.semaphore.remaining > 0 ? this.nextInstance = this.spawn({ isPrimary: !1 }) : this.nextInstance = null, await
|
|
1927
|
+
const r = this.nextInstance || this.spawn({ isPrimary: !1 });
|
|
1928
|
+
return this.semaphore.remaining > 0 ? this.nextInstance = this.spawn({ isPrimary: !1 }) : this.nextInstance = null, await r;
|
|
1688
1929
|
}
|
|
1689
1930
|
/**
|
|
1690
1931
|
* Initiated spawning of a new PHP instance.
|
|
@@ -1693,7 +1934,7 @@ class PHPProcessManager {
|
|
|
1693
1934
|
* for PHP to spawn.
|
|
1694
1935
|
*/
|
|
1695
1936
|
spawn(e) {
|
|
1696
|
-
if (e.isPrimary && this.
|
|
1937
|
+
if (e.isPrimary && this.primaryPhpPromise && !this.primaryPhp)
|
|
1697
1938
|
throw new Error(
|
|
1698
1939
|
"Requested spawning a primary PHP instance when another primary instance already started spawning."
|
|
1699
1940
|
);
|
|
@@ -1764,23 +2005,23 @@ function ensurePathPrefix(t, e) {
|
|
|
1764
2005
|
}
|
|
1765
2006
|
async function encodeAsMultipart(t) {
|
|
1766
2007
|
const e = `----${Math.random().toString(36).slice(2)}`, r = `multipart/form-data; boundary=${e}`, s = new TextEncoder(), i = [];
|
|
1767
|
-
for (const [
|
|
2008
|
+
for (const [l, u] of Object.entries(t))
|
|
1768
2009
|
i.push(`--${e}\r
|
|
1769
|
-
`), i.push(`Content-Disposition: form-data; name="${
|
|
1770
|
-
`),
|
|
2010
|
+
`), i.push(`Content-Disposition: form-data; name="${l}"`), u instanceof File && i.push(`; filename="${u.name}"`), i.push(`\r
|
|
2011
|
+
`), u instanceof File && (i.push("Content-Type: application/octet-stream"), i.push(`\r
|
|
1771
2012
|
`)), i.push(`\r
|
|
1772
|
-
`),
|
|
2013
|
+
`), u instanceof File ? i.push(await fileToUint8Array(u)) : i.push(u), i.push(`\r
|
|
1773
2014
|
`);
|
|
1774
2015
|
i.push(`--${e}--\r
|
|
1775
2016
|
`);
|
|
1776
|
-
const
|
|
1777
|
-
let
|
|
1778
|
-
for (const
|
|
1779
|
-
|
|
1780
|
-
typeof
|
|
1781
|
-
|
|
1782
|
-
),
|
|
1783
|
-
return { bytes:
|
|
2017
|
+
const n = i.reduce((l, u) => l + u.length, 0), o = new Uint8Array(n);
|
|
2018
|
+
let a = 0;
|
|
2019
|
+
for (const l of i)
|
|
2020
|
+
o.set(
|
|
2021
|
+
typeof l == "string" ? s.encode(l) : l,
|
|
2022
|
+
a
|
|
2023
|
+
), a += l.length;
|
|
2024
|
+
return { bytes: o, contentType: r };
|
|
1784
2025
|
}
|
|
1785
2026
|
function fileToUint8Array(t) {
|
|
1786
2027
|
return t.arrayBuffer().then((e) => new Uint8Array(e));
|
|
@@ -1881,7 +2122,7 @@ const _default = "application/octet-stream", asx = "video/x-ms-asf", atom = "app
|
|
|
1881
2122
|
xspf,
|
|
1882
2123
|
zip
|
|
1883
2124
|
};
|
|
1884
|
-
var g,
|
|
2125
|
+
var g, k, N, H, I, _, C, v, x, Z, ee, te;
|
|
1885
2126
|
class PHPRequestHandler {
|
|
1886
2127
|
/**
|
|
1887
2128
|
* The request handler needs to decide whether to serve a static asset or
|
|
@@ -1895,42 +2136,42 @@ class PHPRequestHandler {
|
|
|
1895
2136
|
* @param config - Request Handler configuration.
|
|
1896
2137
|
*/
|
|
1897
2138
|
constructor(e) {
|
|
1898
|
-
h(this,
|
|
2139
|
+
h(this, x);
|
|
1899
2140
|
h(this, g);
|
|
1900
|
-
h(this, S);
|
|
1901
2141
|
h(this, k);
|
|
1902
|
-
h(this,
|
|
2142
|
+
h(this, N);
|
|
1903
2143
|
h(this, H);
|
|
1904
|
-
h(this,
|
|
1905
|
-
h(this,
|
|
1906
|
-
h(this,
|
|
2144
|
+
h(this, I);
|
|
2145
|
+
h(this, _);
|
|
2146
|
+
h(this, C);
|
|
2147
|
+
h(this, v);
|
|
1907
2148
|
const {
|
|
1908
2149
|
documentRoot: r = "/www/",
|
|
1909
2150
|
absoluteUrl: s = typeof location == "object" ? location.href : DEFAULT_BASE_URL,
|
|
1910
2151
|
rewriteRules: i = [],
|
|
1911
|
-
getFileNotFoundAction:
|
|
2152
|
+
getFileNotFoundAction: n = () => ({ type: "404" })
|
|
1912
2153
|
} = e;
|
|
1913
2154
|
"processManager" in e ? this.processManager = e.processManager : this.processManager = new PHPProcessManager({
|
|
1914
|
-
phpFactory: async (
|
|
1915
|
-
const
|
|
1916
|
-
...
|
|
2155
|
+
phpFactory: async (l) => {
|
|
2156
|
+
const u = await e.phpFactory({
|
|
2157
|
+
...l,
|
|
1917
2158
|
requestHandler: this
|
|
1918
2159
|
});
|
|
1919
|
-
return
|
|
2160
|
+
return u.isDir(r) || u.mkdir(r), u.chdir(r), u.requestHandler = this, u;
|
|
1920
2161
|
},
|
|
1921
2162
|
maxPhpInstances: e.maxPhpInstances
|
|
1922
|
-
}), m(this,
|
|
1923
|
-
const
|
|
1924
|
-
m(this,
|
|
1925
|
-
const
|
|
1926
|
-
m(this,
|
|
1927
|
-
c(this,
|
|
1928
|
-
|
|
1929
|
-
].join("")), m(this,
|
|
1930
|
-
`${c(this,
|
|
1931
|
-
c(this,
|
|
1932
|
-
c(this,
|
|
1933
|
-
].join("")), this.rewriteRules = i, this.getFileNotFoundAction =
|
|
2163
|
+
}), m(this, v, e.cookieStore === void 0 ? new HttpCookieStore() : e.cookieStore), m(this, g, r);
|
|
2164
|
+
const o = new URL(s);
|
|
2165
|
+
m(this, N, o.hostname), m(this, H, o.port ? Number(o.port) : o.protocol === "https:" ? 443 : 80), m(this, k, (o.protocol || "").replace(":", ""));
|
|
2166
|
+
const a = c(this, H) !== 443 && c(this, H) !== 80;
|
|
2167
|
+
m(this, I, [
|
|
2168
|
+
c(this, N),
|
|
2169
|
+
a ? `:${c(this, H)}` : ""
|
|
2170
|
+
].join("")), m(this, _, o.pathname.replace(/\/+$/, "")), m(this, C, [
|
|
2171
|
+
`${c(this, k)}://`,
|
|
2172
|
+
c(this, I),
|
|
2173
|
+
c(this, _)
|
|
2174
|
+
].join("")), this.rewriteRules = i, this.getFileNotFoundAction = n;
|
|
1934
2175
|
}
|
|
1935
2176
|
async getPrimaryPhp() {
|
|
1936
2177
|
return await this.processManager.getPrimaryPhp();
|
|
@@ -1954,13 +2195,13 @@ class PHPRequestHandler {
|
|
|
1954
2195
|
*/
|
|
1955
2196
|
internalUrlToPath(e) {
|
|
1956
2197
|
const r = new URL(e);
|
|
1957
|
-
return r.pathname.startsWith(c(this,
|
|
2198
|
+
return r.pathname.startsWith(c(this, _)) && (r.pathname = r.pathname.slice(c(this, _).length)), toRelativeUrl(r);
|
|
1958
2199
|
}
|
|
1959
2200
|
/**
|
|
1960
2201
|
* The absolute URL of this PHPRequestHandler instance.
|
|
1961
2202
|
*/
|
|
1962
2203
|
get absoluteUrl() {
|
|
1963
|
-
return c(this,
|
|
2204
|
+
return c(this, C);
|
|
1964
2205
|
}
|
|
1965
2206
|
/**
|
|
1966
2207
|
* The directory in the PHP filesystem where the server will look
|
|
@@ -2025,65 +2266,65 @@ class PHPRequestHandler {
|
|
|
2025
2266
|
), i = applyRewriteRules(
|
|
2026
2267
|
removePathPrefix(
|
|
2027
2268
|
decodeURIComponent(s.pathname),
|
|
2028
|
-
c(this,
|
|
2269
|
+
c(this, _)
|
|
2029
2270
|
),
|
|
2030
2271
|
this.rewriteRules
|
|
2031
|
-
),
|
|
2032
|
-
let
|
|
2033
|
-
if (
|
|
2034
|
-
if (!
|
|
2272
|
+
), n = await this.getPrimaryPhp();
|
|
2273
|
+
let o = joinPaths(c(this, g), i);
|
|
2274
|
+
if (n.isDir(o)) {
|
|
2275
|
+
if (!o.endsWith("/"))
|
|
2035
2276
|
return new PHPResponse(
|
|
2036
2277
|
301,
|
|
2037
2278
|
{ Location: [`${s.pathname}/`] },
|
|
2038
2279
|
new Uint8Array(0)
|
|
2039
2280
|
);
|
|
2040
|
-
for (const
|
|
2041
|
-
const
|
|
2042
|
-
if (
|
|
2043
|
-
|
|
2281
|
+
for (const a of ["index.php", "index.html"]) {
|
|
2282
|
+
const l = joinPaths(o, a);
|
|
2283
|
+
if (n.isFile(l)) {
|
|
2284
|
+
o = l;
|
|
2044
2285
|
break;
|
|
2045
2286
|
}
|
|
2046
2287
|
}
|
|
2047
2288
|
}
|
|
2048
|
-
if (!
|
|
2049
|
-
const
|
|
2289
|
+
if (!n.isFile(o)) {
|
|
2290
|
+
const a = this.getFileNotFoundAction(
|
|
2050
2291
|
i
|
|
2051
2292
|
);
|
|
2052
|
-
switch (
|
|
2293
|
+
switch (a.type) {
|
|
2053
2294
|
case "response":
|
|
2054
|
-
return
|
|
2295
|
+
return a.response;
|
|
2055
2296
|
case "internal-redirect":
|
|
2056
|
-
|
|
2297
|
+
o = joinPaths(c(this, g), a.uri);
|
|
2057
2298
|
break;
|
|
2058
2299
|
case "404":
|
|
2059
2300
|
return PHPResponse.forHttpCode(404);
|
|
2060
2301
|
default:
|
|
2061
2302
|
throw new Error(
|
|
2062
|
-
`Unsupported file-not-found action type: '${
|
|
2303
|
+
`Unsupported file-not-found action type: '${a.type}'`
|
|
2063
2304
|
);
|
|
2064
2305
|
}
|
|
2065
2306
|
}
|
|
2066
|
-
if (
|
|
2067
|
-
if (
|
|
2068
|
-
const
|
|
2307
|
+
if (n.isFile(o))
|
|
2308
|
+
if (o.endsWith(".php")) {
|
|
2309
|
+
const a = {
|
|
2069
2310
|
...e,
|
|
2070
2311
|
// Pass along URL with the #fragment filtered out
|
|
2071
2312
|
url: s.toString()
|
|
2072
2313
|
};
|
|
2073
|
-
return d(this,
|
|
2314
|
+
return d(this, x, ee).call(this, a, o);
|
|
2074
2315
|
} else
|
|
2075
|
-
return d(this,
|
|
2316
|
+
return d(this, x, Z).call(this, n, o);
|
|
2076
2317
|
else
|
|
2077
2318
|
return PHPResponse.forHttpCode(404);
|
|
2078
2319
|
}
|
|
2079
2320
|
}
|
|
2080
|
-
g = new WeakMap(),
|
|
2321
|
+
g = new WeakMap(), k = new WeakMap(), N = new WeakMap(), H = new WeakMap(), I = new WeakMap(), _ = new WeakMap(), C = new WeakMap(), v = new WeakMap(), x = new WeakSet(), /**
|
|
2081
2322
|
* Serves a static file from the PHP filesystem.
|
|
2082
2323
|
*
|
|
2083
2324
|
* @param fsPath - Absolute path of the static file to serve.
|
|
2084
2325
|
* @returns The response.
|
|
2085
2326
|
*/
|
|
2086
|
-
|
|
2327
|
+
Z = function(e, r) {
|
|
2087
2328
|
const s = e.readFileAsBuffer(r);
|
|
2088
2329
|
return new PHPResponse(
|
|
2089
2330
|
200,
|
|
@@ -2098,56 +2339,58 @@ V = function(e, r) {
|
|
|
2098
2339
|
},
|
|
2099
2340
|
s
|
|
2100
2341
|
);
|
|
2101
|
-
},
|
|
2342
|
+
}, ee = async function(e, r) {
|
|
2102
2343
|
let s;
|
|
2103
2344
|
try {
|
|
2104
|
-
s = await this.processManager.acquirePHPInstance(
|
|
2345
|
+
s = await this.processManager.acquirePHPInstance({
|
|
2346
|
+
considerPrimary: !0
|
|
2347
|
+
});
|
|
2105
2348
|
} catch (i) {
|
|
2106
2349
|
return i instanceof MaxPhpInstancesError ? PHPResponse.forHttpCode(502) : PHPResponse.forHttpCode(500);
|
|
2107
2350
|
}
|
|
2108
2351
|
try {
|
|
2109
|
-
return await d(this,
|
|
2352
|
+
return await d(this, x, te).call(this, s.php, e, r);
|
|
2110
2353
|
} finally {
|
|
2111
2354
|
s.reap();
|
|
2112
2355
|
}
|
|
2113
|
-
},
|
|
2356
|
+
}, te = async function(e, r, s) {
|
|
2114
2357
|
let i = "GET";
|
|
2115
|
-
const
|
|
2116
|
-
host: c(this,
|
|
2358
|
+
const n = {
|
|
2359
|
+
host: c(this, I),
|
|
2117
2360
|
...normalizeHeaders(r.headers || {})
|
|
2118
2361
|
};
|
|
2119
|
-
c(this,
|
|
2120
|
-
let
|
|
2121
|
-
if (typeof
|
|
2362
|
+
c(this, v) && (n.cookie = c(this, v).getCookieRequestHeader());
|
|
2363
|
+
let o = r.body;
|
|
2364
|
+
if (typeof o == "object" && !(o instanceof Uint8Array)) {
|
|
2122
2365
|
i = "POST";
|
|
2123
|
-
const { bytes:
|
|
2124
|
-
|
|
2366
|
+
const { bytes: a, contentType: l } = await encodeAsMultipart(o);
|
|
2367
|
+
o = a, n["content-type"] = l;
|
|
2125
2368
|
}
|
|
2126
2369
|
try {
|
|
2127
|
-
const
|
|
2370
|
+
const a = await e.run({
|
|
2128
2371
|
relativeUri: ensurePathPrefix(
|
|
2129
2372
|
toRelativeUrl(new URL(r.url)),
|
|
2130
|
-
c(this,
|
|
2373
|
+
c(this, _)
|
|
2131
2374
|
),
|
|
2132
|
-
protocol: c(this,
|
|
2375
|
+
protocol: c(this, k),
|
|
2133
2376
|
method: r.method || i,
|
|
2134
2377
|
$_SERVER: {
|
|
2135
2378
|
REMOTE_ADDR: "127.0.0.1",
|
|
2136
2379
|
DOCUMENT_ROOT: c(this, g),
|
|
2137
|
-
HTTPS: c(this,
|
|
2380
|
+
HTTPS: c(this, C).startsWith("https://") ? "on" : ""
|
|
2138
2381
|
},
|
|
2139
|
-
body:
|
|
2382
|
+
body: o,
|
|
2140
2383
|
scriptPath: s,
|
|
2141
|
-
headers:
|
|
2384
|
+
headers: n
|
|
2142
2385
|
});
|
|
2143
|
-
return c(this,
|
|
2144
|
-
|
|
2145
|
-
),
|
|
2146
|
-
} catch (
|
|
2147
|
-
const
|
|
2148
|
-
if (
|
|
2149
|
-
return
|
|
2150
|
-
throw
|
|
2386
|
+
return c(this, v) && c(this, v).rememberCookiesFromResponseHeaders(
|
|
2387
|
+
a.headers
|
|
2388
|
+
), a;
|
|
2389
|
+
} catch (a) {
|
|
2390
|
+
const l = a;
|
|
2391
|
+
if (l != null && l.response)
|
|
2392
|
+
return l.response;
|
|
2393
|
+
throw a;
|
|
2151
2394
|
}
|
|
2152
2395
|
};
|
|
2153
2396
|
function inferMimeType(t) {
|
|
@@ -2175,29 +2418,29 @@ function rotatePHPRuntime({
|
|
|
2175
2418
|
maxRequests: s = 400
|
|
2176
2419
|
}) {
|
|
2177
2420
|
let i = 0;
|
|
2178
|
-
async function
|
|
2179
|
-
const
|
|
2421
|
+
async function n() {
|
|
2422
|
+
const l = await t.semaphore.acquire();
|
|
2180
2423
|
try {
|
|
2181
2424
|
await t.hotSwapPHPRuntime(await r(), e), i = 0;
|
|
2182
2425
|
} finally {
|
|
2183
|
-
|
|
2426
|
+
l();
|
|
2184
2427
|
}
|
|
2185
2428
|
}
|
|
2186
|
-
async function
|
|
2187
|
-
++i < s || await
|
|
2429
|
+
async function o() {
|
|
2430
|
+
++i < s || await n();
|
|
2188
2431
|
}
|
|
2189
|
-
async function l
|
|
2190
|
-
|
|
2432
|
+
async function a(l) {
|
|
2433
|
+
l.type === "request.error" && l.source === "php-wasm" && await n();
|
|
2191
2434
|
}
|
|
2192
|
-
return t.addEventListener("request.error",
|
|
2193
|
-
t.removeEventListener("request.error",
|
|
2435
|
+
return t.addEventListener("request.error", a), t.addEventListener("request.end", o), function() {
|
|
2436
|
+
t.removeEventListener("request.error", a), t.removeEventListener("request.end", o);
|
|
2194
2437
|
};
|
|
2195
2438
|
}
|
|
2196
2439
|
async function writeFiles(t, e, r, { rmRoot: s = !1 } = {}) {
|
|
2197
2440
|
s && await t.isDir(e) && await t.rmdir(e, { recursive: !0 });
|
|
2198
|
-
for (const [i,
|
|
2199
|
-
const
|
|
2200
|
-
await t.fileExists(dirname(
|
|
2441
|
+
for (const [i, n] of Object.entries(r)) {
|
|
2442
|
+
const o = joinPaths(e, i);
|
|
2443
|
+
await t.fileExists(dirname(o)) || await t.mkdir(dirname(o)), n instanceof Uint8Array || typeof n == "string" ? await t.writeFile(o, n) : await writeFiles(t, o, n);
|
|
2201
2444
|
}
|
|
2202
2445
|
}
|
|
2203
2446
|
function proxyFileSystem(t, e, r) {
|
|
@@ -2220,10 +2463,12 @@ export {
|
|
|
2220
2463
|
HttpCookieStore,
|
|
2221
2464
|
LatestSupportedPHPVersion,
|
|
2222
2465
|
PHP,
|
|
2466
|
+
PHPExecutionFailureError,
|
|
2223
2467
|
PHPProcessManager,
|
|
2224
2468
|
PHPRequestHandler,
|
|
2225
2469
|
PHPResponse,
|
|
2226
2470
|
PHPWorker,
|
|
2471
|
+
StreamedPHPResponse,
|
|
2227
2472
|
SupportedPHPVersions,
|
|
2228
2473
|
SupportedPHPVersionsList,
|
|
2229
2474
|
UnhandledRejectionsTarget,
|
|
@@ -2232,7 +2477,7 @@ export {
|
|
|
2232
2477
|
ensurePathPrefix,
|
|
2233
2478
|
getLoadedRuntime,
|
|
2234
2479
|
getPhpIniEntries,
|
|
2235
|
-
|
|
2480
|
+
isExitCode,
|
|
2236
2481
|
iteratePhpFiles as iterateFiles,
|
|
2237
2482
|
loadPHPRuntime,
|
|
2238
2483
|
proxyFileSystem,
|