@php-wasm/universal 2.0.7 → 2.0.9
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 +2 -2
- package/index.cjs.map +1 -1
- package/index.js +3 -3
- package/index.js.map +1 -1
- package/package.json +7 -7
package/index.cjs
CHANGED
|
@@ -80,13 +80,13 @@ ${JSON.stringify(t.headers,null,2)}
|
|
|
80
80
|
==== PHP stderr ====
|
|
81
81
|
|
|
82
82
|
`),process.stderr.write(t.errors)),process.stderr.write(`
|
|
83
|
-
`)}class HttpCookieStore{constructor(){this.cookies={}}rememberCookiesFromResponseHeaders(e){if(e!=null&&e["set-cookie"])for(const r of e["set-cookie"])try{if(!r.includes("="))continue;const s=r.indexOf("="),n=r.substring(0,s),i=r.substring(s+1).split(";")[0];this.cookies[n]=i}catch(s){logger.logger.error(s)}}getCookieRequestHeader(){const e=[];for(const r in this.cookies)e.push(`${r}=${this.cookies[r]}`);return e.join("; ")}}function streamReadFileFromPHP(t,e){return new ReadableStream({async pull(r){const s=await t.readFileAsBuffer(e);r.enqueue(s),r.close()}})}async function*iteratePhpFiles(t,e,{relativePaths:r=!0,pathPrefix:s,exceptPaths:n=[]}={}){e=util.normalizePath(e);const i=[e];for(;i.length;){const o=i.pop();if(!o)return;const a=await t.listFiles(o);for(const l of a){const c=`${o}/${l}`;if(n.includes(c.substring(e.length+1)))continue;await t.isDir(c)?i.push(c):yield new streamCompression.StreamedFile(streamReadFileFromPHP(t,c),r?util.joinPaths(s||"",c.substring(e.length+1)):c)}}}function writeFilesStreamToPhp(t,e){return new WritableStream({async write(r){const s=util.joinPaths(e,r.name);r.type==="directory"?await t.mkdir(s):(await t.mkdir(util.dirname(s)),await t.writeFile(s,new Uint8Array(await r.arrayBuffer())))}})}class MaxPhpInstancesError extends Error{constructor(e){super(`Requested more concurrent PHP instances than the limit (${e}).`),this.name=this.constructor.name}}class PHPProcessManager{constructor(e){this.primaryIdle=!0,this.nextInstance=null,this.allInstances=[],this.maxPhpInstances=(e==null?void 0:e.maxPhpInstances)??5,this.phpFactory=e==null?void 0:e.phpFactory,this.primaryPhp=e==null?void 0:e.primaryPhp,this.semaphore=new util.Semaphore({concurrency:this.maxPhpInstances,timeout:(e==null?void 0:e.timeout)||5e3})}async getPrimaryPhp(){if(!this.phpFactory&&!this.primaryPhp)throw new Error("phpFactory or primaryPhp must be set before calling getPrimaryPhp().");return this.primaryPhp||(this.primaryPhpPromise||(this.primaryPhpPromise=this.spawn({isPrimary:!0})),this.primaryPhp=(await this.primaryPhpPromise).php,this.primaryPhpPromise=void 0),this.primaryPhp}async acquirePHPInstance({considerPrimary:e=!1}={}){if(this.primaryPhp||await this.getPrimaryPhp(),this.primaryIdle&&e)return this.primaryIdle=!1,{php:await this.getPrimaryPhp(),reap:()=>{this.primaryIdle=!0}};const r=this.nextInstance||this.spawn({isPrimary:!1});return this.semaphore.remaining>0?this.nextInstance=this.spawn({isPrimary:!1}):this.nextInstance=null,await r}spawn(e){if(e.isPrimary&&this.allInstances.length>0)throw new Error("Requested spawning a primary PHP instance when another primary instance already started spawning.");const r=this.doSpawn(e);this.allInstances.push(r);const s=()=>{this.allInstances=this.allInstances.filter(n=>n!==r)};return r.catch(n=>{throw s(),n}).then(n=>({...n,reap:()=>{s(),n.reap()}}))}async doSpawn(e){let r;try{r=await this.semaphore.acquire()}catch(s){throw s instanceof util.AcquireTimeoutError?new MaxPhpInstancesError(this.maxPhpInstances):s}try{const s=await this.phpFactory(e);return{php:s,reap(){s.exit(),r()}}}catch(s){throw r(),s}}async[Symbol.asyncDispose](){this.primaryPhp&&this.primaryPhp.exit(),await Promise.all(this.allInstances.map(e=>e.then(({reap:r})=>r())))}}const SupportedPHPVersions=["8.4","8.3","8.2","8.1","8.0","7.4","7.3","7.2"],LatestSupportedPHPVersion=SupportedPHPVersions[0],SupportedPHPVersionsList=SupportedPHPVersions,DEFAULT_BASE_URL="http://example.com";function toRelativeUrl(t){return t.toString().substring(t.origin.length)}function removePathPrefix(t,e){return!e||!t.startsWith(e)?t:t.substring(e.length)}function ensurePathPrefix(t,e){return!e||t.startsWith(e)?t:e+t}async function encodeAsMultipart(t){const e=`----${Math.random().toString(36).slice(2)}`,r=`multipart/form-data; boundary=${e}`,s=new TextEncoder,n=[];for(const[l,c]of Object.entries(t))n.push(`--${e}\r
|
|
83
|
+
`)}class HttpCookieStore{constructor(){this.cookies={}}rememberCookiesFromResponseHeaders(e){if(e!=null&&e["set-cookie"])for(const r of e["set-cookie"])try{if(!r.includes("="))continue;const s=r.indexOf("="),n=r.substring(0,s),i=r.substring(s+1).split(";")[0];this.cookies[n]=i}catch(s){logger.logger.error(s)}}getCookieRequestHeader(){const e=[];for(const r in this.cookies)e.push(`${r}=${this.cookies[r]}`);return e.join("; ")}}function streamReadFileFromPHP(t,e){return new ReadableStream({async pull(r){const s=await t.readFileAsBuffer(e);r.enqueue(s),r.close()}})}async function*iteratePhpFiles(t,e,{relativePaths:r=!0,pathPrefix:s,exceptPaths:n=[]}={}){e=util.normalizePath(e);const i=[e];for(;i.length;){const o=i.pop();if(!o)return;const a=await t.listFiles(o);for(const l of a){const c=`${o}/${l}`;if(n.includes(c.substring(e.length+1)))continue;await t.isDir(c)?i.push(c):yield new streamCompression.StreamedFile(streamReadFileFromPHP(t,c),r?util.joinPaths(s||"",c.substring(e.length+1)):c)}}}function writeFilesStreamToPhp(t,e){return new WritableStream({async write(r){const s=util.joinPaths(e,r.name);r.type==="directory"?await t.mkdir(s):(await t.mkdir(util.dirname(s)),await t.writeFile(s,new Uint8Array(await r.arrayBuffer())))}})}class MaxPhpInstancesError extends Error{constructor(e){super(`Requested more concurrent PHP instances than the limit (${e}).`),this.name=this.constructor.name}}class PHPProcessManager{constructor(e){this.primaryIdle=!0,this.nextInstance=null,this.allInstances=[],this.maxPhpInstances=(e==null?void 0:e.maxPhpInstances)??5,this.phpFactory=e==null?void 0:e.phpFactory,this.primaryPhp=e==null?void 0:e.primaryPhp,this.semaphore=new util.Semaphore({concurrency:this.maxPhpInstances,timeout:(e==null?void 0:e.timeout)||5e3})}async getPrimaryPhp(){if(!this.phpFactory&&!this.primaryPhp)throw new Error("phpFactory or primaryPhp must be set before calling getPrimaryPhp().");return this.primaryPhp||(this.primaryPhpPromise||(this.primaryPhpPromise=this.spawn({isPrimary:!0})),this.primaryPhp=(await this.primaryPhpPromise).php,this.primaryPhpPromise=void 0),this.primaryPhp}async acquirePHPInstance({considerPrimary:e=!1}={}){if(this.primaryPhp||await this.getPrimaryPhp(),this.primaryIdle&&e)return this.primaryIdle=!1,{php:await this.getPrimaryPhp(),reap:()=>{this.primaryIdle=!0}};const r=this.nextInstance||this.spawn({isPrimary:!1});return this.semaphore.remaining>0?this.nextInstance=this.spawn({isPrimary:!1}):this.nextInstance=null,await r}spawn(e){if(e.isPrimary&&this.allInstances.length>0)throw new Error("Requested spawning a primary PHP instance when another primary instance already started spawning.");const r=this.doSpawn(e);this.allInstances.push(r);const s=()=>{this.allInstances=this.allInstances.filter(n=>n!==r)};return r.catch(n=>{throw s(),n}).then(n=>({...n,reap:()=>{s(),n.reap()}}))}async doSpawn(e){let r;try{r=await this.semaphore.acquire()}catch(s){throw s instanceof util.AcquireTimeoutError?new MaxPhpInstancesError(this.maxPhpInstances):s}try{const s=await this.phpFactory(e);return{php:s,reap(){s.exit(),r()}}}catch(s){throw r(),s}}async[Symbol.asyncDispose](){this.primaryPhp&&this.primaryPhp.exit(),await Promise.all(this.allInstances.map(e=>e.then(({reap:r})=>r())))}}const SupportedPHPVersions=["8.4","8.3","8.2","8.1","8.0","7.4","7.3","7.2"],LatestSupportedPHPVersion=SupportedPHPVersions[0],SupportedPHPVersionsList=SupportedPHPVersions,DEFAULT_BASE_URL="http://example.com";function toRelativeUrl(t){return t.origin==="null"?t.toString():t.toString().substring(t.origin.length)}function removePathPrefix(t,e){return!e||!t.startsWith(e)?t:t.substring(e.length)}function ensurePathPrefix(t,e){return!e||t.startsWith(e)?t:e+t}async function encodeAsMultipart(t){const e=`----${Math.random().toString(36).slice(2)}`,r=`multipart/form-data; boundary=${e}`,s=new TextEncoder,n=[];for(const[l,c]of Object.entries(t))n.push(`--${e}\r
|
|
84
84
|
`),n.push(`Content-Disposition: form-data; name="${l}"`),c instanceof File&&n.push(`; filename="${c.name}"`),n.push(`\r
|
|
85
85
|
`),c instanceof File&&(n.push("Content-Type: application/octet-stream"),n.push(`\r
|
|
86
86
|
`)),n.push(`\r
|
|
87
87
|
`),c instanceof File?n.push(await fileToUint8Array(c)):n.push(c),n.push(`\r
|
|
88
88
|
`);n.push(`--${e}--\r
|
|
89
|
-
`);const i=n.reduce((l,c)=>l+c.length,0),o=new Uint8Array(i);let a=0;for(const l of n)o.set(typeof l=="string"?s.encode(l):l,a),a+=l.length;return{bytes:o,contentType:r}}function fileToUint8Array(t){return t.arrayBuffer().then(e=>new Uint8Array(e))}const _default="application/octet-stream",asx="video/x-ms-asf",atom="application/atom+xml",avi="video/x-msvideo",avif="image/avif",bin="application/octet-stream",bmp="image/x-ms-bmp",cco="application/x-cocoa",css="text/css",data="application/octet-stream",deb="application/octet-stream",der="application/x-x509-ca-cert",dmg="application/octet-stream",doc="application/msword",docx="application/vnd.openxmlformats-officedocument.wordprocessingml.document",eot="application/vnd.ms-fontobject",flv="video/x-flv",gif="image/gif",gz="application/gzip",hqx="application/mac-binhex40",htc="text/x-component",html="text/html",ico="image/x-icon",iso="application/octet-stream",jad="text/vnd.sun.j2me.app-descriptor",jar="application/java-archive",jardiff="application/x-java-archive-diff",jng="image/x-jng",jnlp="application/x-java-jnlp-file",jpg="image/jpeg",jpeg="image/jpeg",js="application/javascript",json="application/json",kml="application/vnd.google-earth.kml+xml",kmz="application/vnd.google-earth.kmz",m3u8="application/vnd.apple.mpegurl",m4a="audio/x-m4a",m4v="video/x-m4v",md="text/plain",mid="audio/midi",mml="text/mathml",mng="video/x-mng",mov="video/quicktime",mp3="audio/mpeg",mp4="video/mp4",mpeg="video/mpeg",msi="application/octet-stream",odg="application/vnd.oasis.opendocument.graphics",odp="application/vnd.oasis.opendocument.presentation",ods="application/vnd.oasis.opendocument.spreadsheet",odt="application/vnd.oasis.opendocument.text",ogg="audio/ogg",otf="font/otf",pdf="application/pdf",pl="application/x-perl",png="image/png",ppt="application/vnd.ms-powerpoint",pptx="application/vnd.openxmlformats-officedocument.presentationml.presentation",prc="application/x-pilot",ps="application/postscript",ra="audio/x-realaudio",rar="application/x-rar-compressed",rpm="application/x-redhat-package-manager",rss="application/rss+xml",rtf="application/rtf",run="application/x-makeself",sea="application/x-sea",sit="application/x-stuffit",svg="image/svg+xml",swf="application/x-shockwave-flash",tcl="application/x-tcl",tar="application/x-tar",tif="image/tiff",ts="video/mp2t",ttf="font/ttf",txt="text/plain",wasm="application/wasm",wbmp="image/vnd.wap.wbmp",webm="video/webm",webp="image/webp",wml="text/vnd.wap.wml",wmlc="application/vnd.wap.wmlc",wmv="video/x-ms-wmv",woff="font/woff",woff2="font/woff2",xhtml="application/xhtml+xml",xls="application/vnd.ms-excel",xlsx="application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",xml="text/xml",xpi="application/x-xpinstall",xspf="application/xspf+xml",zip="application/zip",mimeTypes={_default,"3gpp":"video/3gpp","7z":"application/x-7z-compressed",asx,atom,avi,avif,bin,bmp,cco,css,data,deb,der,dmg,doc,docx,eot,flv,gif,gz,hqx,htc,html,ico,iso,jad,jar,jardiff,jng,jnlp,jpg,jpeg,js,json,kml,kmz,m3u8,m4a,m4v,md,mid,mml,mng,mov,mp3,mp4,mpeg,msi,odg,odp,ods,odt,ogg,otf,pdf,pl,png,ppt,pptx,prc,ps,ra,rar,rpm,rss,rtf,run,sea,sit,svg,swf,tcl,tar,tif,ts,ttf,txt,wasm,wbmp,webm,webp,wml,wmlc,wmv,woff,woff2,xhtml,xls,xlsx,xml,xpi,xspf,zip};var v,C,M,F,I,P,A,R,H,Z,ee,te;class PHPRequestHandler{constructor(e){_(this,H);_(this,v);_(this,C);_(this,M);_(this,F);_(this,I);_(this,P);_(this,A);_(this,R);const{documentRoot:r="/www/",absoluteUrl:s=typeof location=="object"?location.href:DEFAULT_BASE_URL,rewriteRules:n=[],getFileNotFoundAction:i=()=>({type:"404"})}=e;"processManager"in e?this.processManager=e.processManager:this.processManager=new PHPProcessManager({phpFactory:async l=>{const c=await e.phpFactory({...l,requestHandler:this});return c.isDir(r)||c.mkdir(r),c.chdir(r),c.requestHandler=this,c},maxPhpInstances:e.maxPhpInstances}),f(this,R,e.cookieStore===void 0?new HttpCookieStore:e.cookieStore),f(this,v,r);const o=new URL(s);f(this,M,o.hostname),f(this,F,o.port?Number(o.port):o.protocol==="https:"?443:80),f(this,C,(o.protocol||"").replace(":",""));const a=u(this,F)!==443&&u(this,F)!==80;f(this,I,[u(this,M),a?`:${u(this,F)}`:""].join("")),f(this,P,o.pathname.replace(/\/+$/,"")),f(this,A,[`${u(this,C)}://`,u(this,I),u(this,P)].join("")),this.rewriteRules=n,this.getFileNotFoundAction=i}async getPrimaryPhp(){return await this.processManager.getPrimaryPhp()}pathToInternalUrl(e){return`${this.absoluteUrl}${e}`}internalUrlToPath(e){const r=new URL(e);return r.pathname.startsWith(u(this,P))&&(r.pathname=r.pathname.slice(u(this,P).length)),toRelativeUrl(r)}get absoluteUrl(){return u(this,A)}get documentRoot(){return u(this,v)}async request(e){const r=URL.canParse(e.url),s=new URL(e.url.split("#")[0],r?void 0:DEFAULT_BASE_URL),n=applyRewriteRules(removePathPrefix(decodeURIComponent(s.pathname),u(this,P)),this.rewriteRules),i=await this.getPrimaryPhp();let o=util.joinPaths(u(this,v),n);if(i.isDir(o)){if(!o.endsWith("/"))return new PHPResponse(301,{Location:[`${s.pathname}/`]},new Uint8Array(0));for(const a of["index.php","index.html"]){const l=util.joinPaths(o,a);if(i.isFile(l)){o=l;break}}}if(!i.isFile(o)){const a=this.getFileNotFoundAction(n);switch(a.type){case"response":return a.response;case"internal-redirect":o=util.joinPaths(u(this,v),a.uri);break;case"404":return PHPResponse.forHttpCode(404);default:throw new Error(`Unsupported file-not-found action type: '${a.type}'`)}}if(i.isFile(o))if(o.endsWith(".php")){const a={...e,url:s.toString()},l=await m(this,H,ee).call(this,a,o);return l.ok()&&l.exitCode!==0?new PHPResponse(500,l.headers,l.bytes,l.errors,l.exitCode):l}else return m(this,H,Z).call(this,i,o);else return PHPResponse.forHttpCode(404)}async[Symbol.asyncDispose](){await this.processManager[Symbol.asyncDispose]()}}v=new WeakMap,C=new WeakMap,M=new WeakMap,F=new WeakMap,I=new WeakMap,P=new WeakMap,A=new WeakMap,R=new WeakMap,H=new WeakSet,Z=function(e,r){const s=e.readFileAsBuffer(r);return new PHPResponse(200,{"content-length":[`${s.byteLength}`],"content-type":[inferMimeType(r)],"accept-ranges":["bytes"],"cache-control":["public, max-age=0"]},s)},ee=async function(e,r){let s;try{s=await this.processManager.acquirePHPInstance({considerPrimary:!0})}catch(n){return n instanceof MaxPhpInstancesError?PHPResponse.forHttpCode(502):PHPResponse.forHttpCode(500)}try{return await m(this,H,te).call(this,s.php,e,r)}finally{s.reap()}},te=async function(e,r,s){let n="GET";const i={host:u(this,I),...normalizeHeaders(r.headers||{})};u(this,R)&&(i.cookie=u(this,R).getCookieRequestHeader());let o=r.body;if(typeof o=="object"&&!(o instanceof Uint8Array)){n="POST";const{bytes:a,contentType:l}=await encodeAsMultipart(o);o=a,i["content-type"]=l}try{const a=await e.run({relativeUri:ensurePathPrefix(toRelativeUrl(new URL(r.url)),u(this,P)),protocol:u(this,C),method:r.method||n,$_SERVER:{REMOTE_ADDR:"127.0.0.1",DOCUMENT_ROOT:u(this,v),HTTPS:u(this,A).startsWith("https://")?"on":""},body:o,scriptPath:s,headers:i});return u(this,R)&&u(this,R).rememberCookiesFromResponseHeaders(a.headers),a}catch(a){const l=a;if(l!=null&&l.response)return l.response;throw a}};function inferMimeType(t){const e=t.split(".").pop();return mimeTypes[e]||mimeTypes._default}function applyRewriteRules(t,e){for(const r of e)if(new RegExp(r.match).test(t))return t.replace(r.match,r.replacement);return t}function rotatePHPRuntime({php:t,cwd:e,recreateRuntime:r,maxRequests:s=400}){let n=0;async function i(){const l=await t.semaphore.acquire();try{await t.hotSwapPHPRuntime(await r(),e),n=0}finally{l()}}async function o(){++n<s||await i()}async function a(l){l.type==="request.error"&&l.source==="php-wasm"&&await i()}return t.addEventListener("request.error",a),t.addEventListener("request.end",o),function(){t.removeEventListener("request.error",a),t.removeEventListener("request.end",o)}}async function writeFiles(t,e,r,{rmRoot:s=!1}={}){s&&await t.isDir(e)&&await t.rmdir(e,{recursive:!0});for(const[n,i]of Object.entries(r)){const o=util.joinPaths(e,n);await t.fileExists(util.dirname(o))||await t.mkdir(util.dirname(o)),i instanceof Uint8Array||typeof i=="string"?await t.writeFile(o,i):await writeFiles(t,o,i)}}function proxyFileSystem(t,e,r){const s=Object.getOwnPropertySymbols(t)[0];for(const n of r)e.fileExists(n)||e.mkdir(n),t.fileExists(n)||t.mkdir(n),e[s].FS.mount(e[s].PROXYFS,{root:n,fs:t[s].FS},n)}function sandboxedSpawnHandlerFactory(t){return util.createSpawnHandler(async function(e,r,s){r.notifySpawn(),e[0]==="exec"&&e.shift(),(e[0].endsWith(".php")||e[0].endsWith(".phar"))&&e.unshift("php");const n=e[0].split("/").pop();if(e[0]==="/usr/bin/env"&&e[1]==="stty"&&e[2]==="size")r.stdout("18 140"),r.exit(0);else if(n==="tput"&&e[1]==="cols")r.stdout("140"),r.exit(0);else if(n==="less")r.on("stdin",i=>{r.stdout(i)}),r.exit(0);else if(n==="php"){const{php:i,reap:o}=await t.acquirePHPInstance({considerPrimary:!1});i.chdir(s.cwd);try{const a=await i.cli(e,{env:{...s.env,SCRIPT_PATH:e[1],SHELL_PIPE:"0"}});a.stdout.pipeTo(new WritableStream({write(l){r.stdout(l)}})),a.stderr.pipeTo(new WritableStream({write(l){r.stderr(l)}})),r.exit(await a.exitCode)}catch(a){throw r.exit(1),a}finally{o()}}else r.exit(1)})}function exposeSync(t,e,r,s=["*"]){return expose(t,e,s,r.afterResponseSent)}function createSyncProxy(t,e=[],r){return new Proxy(()=>{},{get(s,n){return n==="then"&&!e.length?{then:(i,o)=>o(createSyncProxy(t,[],r))}:createSyncProxy(t,[...e,n],r)},set(s,n,i){const[o,a]=toWireValue(i);return r.send(t,{type:MessageType.SET,path:[...e,n].map(String),value:o},a),!0},apply(s,n,i){if(e.at(-1)==="bind")return createSyncProxy(t,e.slice(0,-1),r);const[a,l]=processArguments(i),c=r.send(t,{type:MessageType.APPLY,path:e.map(String),argumentList:a},l);return fromWireValue(c)},construct(s,n){const[i,o]=processArguments(n),a=r.send(t,{type:MessageType.CONSTRUCT,path:e.map(String),argumentList:i},o);return fromWireValue(a)}})}function wrapSync(t,e){return createSyncProxy(t,[],e)}class NodeSABSyncReceiveMessageTransport{static async create(){if(!NodeSABSyncReceiveMessageTransport.receiveMessageOnPort)try{NodeSABSyncReceiveMessageTransport.receiveMessageOnPort=require("worker_threads").receiveMessageOnPort}catch{NodeSABSyncReceiveMessageTransport.receiveMessageOnPort=await import("worker_threads").then(e=>e.receiveMessageOnPort)}return new NodeSABSyncReceiveMessageTransport}constructor(){}afterResponseSent(e){const{notifyBuffer:r}=e.data;if(r){const s=new Int32Array(r);s[0]=1,Atomics.notify(s,0)}}send(e,r,s){var c;const n=new SharedArrayBuffer(4),i=new Int32Array(n);i[0]=0;const o=generateUUID();if(e.postMessage({...r,id:o,notifyBuffer:n},s),Atomics.wait(i,0,0,5e3)==="timed-out")throw new Error("Timeout waiting for response");for(;;){const p=NodeSABSyncReceiveMessageTransport.receiveMessageOnPort(e);if(((c=p.message)==null?void 0:c.id)===o)return p.message;if(!p)throw new Error("No response received")}}}/**
|
|
89
|
+
`);const i=n.reduce((l,c)=>l+c.length,0),o=new Uint8Array(i);let a=0;for(const l of n)o.set(typeof l=="string"?s.encode(l):l,a),a+=l.length;return{bytes:o,contentType:r}}function fileToUint8Array(t){return t.arrayBuffer().then(e=>new Uint8Array(e))}const _default="application/octet-stream",asx="video/x-ms-asf",atom="application/atom+xml",avi="video/x-msvideo",avif="image/avif",bin="application/octet-stream",bmp="image/x-ms-bmp",cco="application/x-cocoa",css="text/css",data="application/octet-stream",deb="application/octet-stream",der="application/x-x509-ca-cert",dmg="application/octet-stream",doc="application/msword",docx="application/vnd.openxmlformats-officedocument.wordprocessingml.document",eot="application/vnd.ms-fontobject",flv="video/x-flv",gif="image/gif",gz="application/gzip",hqx="application/mac-binhex40",htc="text/x-component",html="text/html",ico="image/x-icon",iso="application/octet-stream",jad="text/vnd.sun.j2me.app-descriptor",jar="application/java-archive",jardiff="application/x-java-archive-diff",jng="image/x-jng",jnlp="application/x-java-jnlp-file",jpg="image/jpeg",jpeg="image/jpeg",js="application/javascript",json="application/json",kml="application/vnd.google-earth.kml+xml",kmz="application/vnd.google-earth.kmz",m3u8="application/vnd.apple.mpegurl",m4a="audio/x-m4a",m4v="video/x-m4v",md="text/plain",mid="audio/midi",mml="text/mathml",mng="video/x-mng",mov="video/quicktime",mp3="audio/mpeg",mp4="video/mp4",mpeg="video/mpeg",msi="application/octet-stream",odg="application/vnd.oasis.opendocument.graphics",odp="application/vnd.oasis.opendocument.presentation",ods="application/vnd.oasis.opendocument.spreadsheet",odt="application/vnd.oasis.opendocument.text",ogg="audio/ogg",otf="font/otf",pdf="application/pdf",pl="application/x-perl",png="image/png",ppt="application/vnd.ms-powerpoint",pptx="application/vnd.openxmlformats-officedocument.presentationml.presentation",prc="application/x-pilot",ps="application/postscript",ra="audio/x-realaudio",rar="application/x-rar-compressed",rpm="application/x-redhat-package-manager",rss="application/rss+xml",rtf="application/rtf",run="application/x-makeself",sea="application/x-sea",sit="application/x-stuffit",svg="image/svg+xml",swf="application/x-shockwave-flash",tcl="application/x-tcl",tar="application/x-tar",tif="image/tiff",ts="video/mp2t",ttf="font/ttf",txt="text/plain",wasm="application/wasm",wbmp="image/vnd.wap.wbmp",webm="video/webm",webp="image/webp",wml="text/vnd.wap.wml",wmlc="application/vnd.wap.wmlc",wmv="video/x-ms-wmv",woff="font/woff",woff2="font/woff2",xhtml="application/xhtml+xml",xls="application/vnd.ms-excel",xlsx="application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",xml="text/xml",xpi="application/x-xpinstall",xspf="application/xspf+xml",zip="application/zip",mimeTypes={_default,"3gpp":"video/3gpp","7z":"application/x-7z-compressed",asx,atom,avi,avif,bin,bmp,cco,css,data,deb,der,dmg,doc,docx,eot,flv,gif,gz,hqx,htc,html,ico,iso,jad,jar,jardiff,jng,jnlp,jpg,jpeg,js,json,kml,kmz,m3u8,m4a,m4v,md,mid,mml,mng,mov,mp3,mp4,mpeg,msi,odg,odp,ods,odt,ogg,otf,pdf,pl,png,ppt,pptx,prc,ps,ra,rar,rpm,rss,rtf,run,sea,sit,svg,swf,tcl,tar,tif,ts,ttf,txt,wasm,wbmp,webm,webp,wml,wmlc,wmv,woff,woff2,xhtml,xls,xlsx,xml,xpi,xspf,zip};var v,C,M,F,I,P,A,R,H,Z,ee,te;class PHPRequestHandler{constructor(e){_(this,H);_(this,v);_(this,C);_(this,M);_(this,F);_(this,I);_(this,P);_(this,A);_(this,R);const{documentRoot:r="/www/",absoluteUrl:s=typeof location=="object"?location.href:DEFAULT_BASE_URL,rewriteRules:n=[],getFileNotFoundAction:i=()=>({type:"404"})}=e;"processManager"in e?this.processManager=e.processManager:this.processManager=new PHPProcessManager({phpFactory:async l=>{const c=await e.phpFactory({...l,requestHandler:this});return c.isDir(r)||c.mkdir(r),c.chdir(r),c.requestHandler=this,c},maxPhpInstances:e.maxPhpInstances}),f(this,R,e.cookieStore===void 0?new HttpCookieStore:e.cookieStore),f(this,v,r);const o=new URL(s);f(this,M,o.hostname),f(this,F,o.port?Number(o.port):o.protocol==="https:"?443:80),f(this,C,(o.protocol||"").replace(":",""));const a=u(this,F)!==443&&u(this,F)!==80;f(this,I,[u(this,M),a?`:${u(this,F)}`:""].join("")),f(this,P,o.pathname.replace(/\/+$/,"")),f(this,A,[`${u(this,C)}://`,u(this,I),u(this,P)].join("")),this.rewriteRules=n,this.getFileNotFoundAction=i}async getPrimaryPhp(){return await this.processManager.getPrimaryPhp()}pathToInternalUrl(e){return e.startsWith("/")||(e=`/${e}`),`${this.absoluteUrl}${e}`}internalUrlToPath(e){const r=new URL(e,"https://playground.internal");return r.pathname.startsWith(u(this,P))&&(r.pathname=r.pathname.slice(u(this,P).length)),toRelativeUrl(r)}get absoluteUrl(){return u(this,A)}get documentRoot(){return u(this,v)}async request(e){const r=URL.canParse(e.url),s=new URL(e.url.split("#")[0],r?void 0:DEFAULT_BASE_URL),n=applyRewriteRules(removePathPrefix(decodeURIComponent(s.pathname),u(this,P)),this.rewriteRules),i=await this.getPrimaryPhp();let o=util.joinPaths(u(this,v),n);if(i.isDir(o)){if(!o.endsWith("/"))return new PHPResponse(301,{Location:[`${s.pathname}/`]},new Uint8Array(0));for(const a of["index.php","index.html"]){const l=util.joinPaths(o,a);if(i.isFile(l)){o=l;break}}}if(!i.isFile(o)){const a=this.getFileNotFoundAction(n);switch(a.type){case"response":return a.response;case"internal-redirect":o=util.joinPaths(u(this,v),a.uri);break;case"404":return PHPResponse.forHttpCode(404);default:throw new Error(`Unsupported file-not-found action type: '${a.type}'`)}}if(i.isFile(o))if(o.endsWith(".php")){const a={...e,url:s.toString()},l=await m(this,H,ee).call(this,a,o);return l.ok()&&l.exitCode!==0?new PHPResponse(500,l.headers,l.bytes,l.errors,l.exitCode):l}else return m(this,H,Z).call(this,i,o);else return PHPResponse.forHttpCode(404)}async[Symbol.asyncDispose](){await this.processManager[Symbol.asyncDispose]()}}v=new WeakMap,C=new WeakMap,M=new WeakMap,F=new WeakMap,I=new WeakMap,P=new WeakMap,A=new WeakMap,R=new WeakMap,H=new WeakSet,Z=function(e,r){const s=e.readFileAsBuffer(r);return new PHPResponse(200,{"content-length":[`${s.byteLength}`],"content-type":[inferMimeType(r)],"accept-ranges":["bytes"],"cache-control":["public, max-age=0"]},s)},ee=async function(e,r){let s;try{s=await this.processManager.acquirePHPInstance({considerPrimary:!0})}catch(n){return n instanceof MaxPhpInstancesError?PHPResponse.forHttpCode(502):PHPResponse.forHttpCode(500)}try{return await m(this,H,te).call(this,s.php,e,r)}finally{s.reap()}},te=async function(e,r,s){let n="GET";const i={host:u(this,I),...normalizeHeaders(r.headers||{})};u(this,R)&&(i.cookie=u(this,R).getCookieRequestHeader());let o=r.body;if(typeof o=="object"&&!(o instanceof Uint8Array)){n="POST";const{bytes:a,contentType:l}=await encodeAsMultipart(o);o=a,i["content-type"]=l}try{const a=await e.run({relativeUri:ensurePathPrefix(toRelativeUrl(new URL(r.url)),u(this,P)),protocol:u(this,C),method:r.method||n,$_SERVER:{REMOTE_ADDR:"127.0.0.1",DOCUMENT_ROOT:u(this,v),HTTPS:u(this,A).startsWith("https://")?"on":""},body:o,scriptPath:s,headers:i});return u(this,R)&&u(this,R).rememberCookiesFromResponseHeaders(a.headers),a}catch(a){const l=a;if(l!=null&&l.response)return l.response;throw a}};function inferMimeType(t){const e=t.split(".").pop();return mimeTypes[e]||mimeTypes._default}function applyRewriteRules(t,e){for(const r of e)if(new RegExp(r.match).test(t))return t.replace(r.match,r.replacement);return t}function rotatePHPRuntime({php:t,cwd:e,recreateRuntime:r,maxRequests:s=400}){let n=0;async function i(){const l=await t.semaphore.acquire();try{await t.hotSwapPHPRuntime(await r(),e),n=0}finally{l()}}async function o(){++n<s||await i()}async function a(l){l.type==="request.error"&&l.source==="php-wasm"&&await i()}return t.addEventListener("request.error",a),t.addEventListener("request.end",o),function(){t.removeEventListener("request.error",a),t.removeEventListener("request.end",o)}}async function writeFiles(t,e,r,{rmRoot:s=!1}={}){s&&await t.isDir(e)&&await t.rmdir(e,{recursive:!0});for(const[n,i]of Object.entries(r)){const o=util.joinPaths(e,n);await t.fileExists(util.dirname(o))||await t.mkdir(util.dirname(o)),i instanceof Uint8Array||typeof i=="string"?await t.writeFile(o,i):await writeFiles(t,o,i)}}function proxyFileSystem(t,e,r){const s=Object.getOwnPropertySymbols(t)[0];for(const n of r)e.fileExists(n)||e.mkdir(n),t.fileExists(n)||t.mkdir(n),e[s].FS.mount(e[s].PROXYFS,{root:n,fs:t[s].FS},n)}function sandboxedSpawnHandlerFactory(t){return util.createSpawnHandler(async function(e,r,s){r.notifySpawn(),e[0]==="exec"&&e.shift(),(e[0].endsWith(".php")||e[0].endsWith(".phar"))&&e.unshift("php");const n=e[0].split("/").pop();if(e[0]==="/usr/bin/env"&&e[1]==="stty"&&e[2]==="size")r.stdout("18 140"),r.exit(0);else if(n==="tput"&&e[1]==="cols")r.stdout("140"),r.exit(0);else if(n==="less")r.on("stdin",i=>{r.stdout(i)}),r.exit(0);else if(n==="php"){const{php:i,reap:o}=await t.acquirePHPInstance({considerPrimary:!1});i.chdir(s.cwd);try{const a=await i.cli(e,{env:{...s.env,SCRIPT_PATH:e[1],SHELL_PIPE:"0"}});a.stdout.pipeTo(new WritableStream({write(l){r.stdout(l)}})),a.stderr.pipeTo(new WritableStream({write(l){r.stderr(l)}})),r.exit(await a.exitCode)}catch(a){throw r.exit(1),a}finally{o()}}else r.exit(1)})}function exposeSync(t,e,r,s=["*"]){return expose(t,e,s,r.afterResponseSent)}function createSyncProxy(t,e=[],r){return new Proxy(()=>{},{get(s,n){return n==="then"&&!e.length?{then:(i,o)=>o(createSyncProxy(t,[],r))}:createSyncProxy(t,[...e,n],r)},set(s,n,i){const[o,a]=toWireValue(i);return r.send(t,{type:MessageType.SET,path:[...e,n].map(String),value:o},a),!0},apply(s,n,i){if(e.at(-1)==="bind")return createSyncProxy(t,e.slice(0,-1),r);const[a,l]=processArguments(i),c=r.send(t,{type:MessageType.APPLY,path:e.map(String),argumentList:a},l);return fromWireValue(c)},construct(s,n){const[i,o]=processArguments(n),a=r.send(t,{type:MessageType.CONSTRUCT,path:e.map(String),argumentList:i},o);return fromWireValue(a)}})}function wrapSync(t,e){return createSyncProxy(t,[],e)}class NodeSABSyncReceiveMessageTransport{static async create(){if(!NodeSABSyncReceiveMessageTransport.receiveMessageOnPort)try{NodeSABSyncReceiveMessageTransport.receiveMessageOnPort=require("worker_threads").receiveMessageOnPort}catch{NodeSABSyncReceiveMessageTransport.receiveMessageOnPort=await import("worker_threads").then(e=>e.receiveMessageOnPort)}return new NodeSABSyncReceiveMessageTransport}constructor(){}afterResponseSent(e){const{notifyBuffer:r}=e.data;if(r){const s=new Int32Array(r);s[0]=1,Atomics.notify(s,0)}}send(e,r,s){var c;const n=new SharedArrayBuffer(4),i=new Int32Array(n);i[0]=0;const o=generateUUID();if(e.postMessage({...r,id:o,notifyBuffer:n},s),Atomics.wait(i,0,0,5e3)==="timed-out")throw new Error("Timeout waiting for response");for(;;){const p=NodeSABSyncReceiveMessageTransport.receiveMessageOnPort(e);if(((c=p.message)==null?void 0:c.id)===o)return p.message;if(!p)throw new Error("No response received")}}}/**
|
|
90
90
|
* Original, unmodified Comlink library from Google:
|
|
91
91
|
*
|
|
92
92
|
* @license
|