[php-src] Issue #7990: Build only php -S, passthru(), redirect to server from symlink
| From: | guest271314 | Date: | Sat, 12 Feb 2022 17:09:41 +0000 |
| Subject: | [php-src] Issue #7990: Build only php -S, passthru(), redirect to server from symlink | ||
| Groups: | php.bugs | ||
| Request: | Send a blank email to php-bugs+get-239712@lists.php.net to get a copy of this message | ||
Issue: https://github.com/php/php-src/issues/7990
Comment Author: guest271314
@damianwadley FWIW I figured out how to achieve an appreciable part of the requirement.
First I remove
Content-Security-Policy header from all sites I navigate to https://github.com/guest271314/remove-csp-header
which allows me to reuest localhost from any origin.
Second I use Native Messaging to start PHP built-in server
```
#!/usr/bin/env php
<?php
function server() {
passthru("php -S localhost:8000 index.php");
}
function out($data = "") {
$fp = fopen("php://stdout", "w");
if ($fp) {
server();
$on = array("message" => "Local server running.");
$on_message = json_encode($on);
//Send the length of data
fwrite($fp, pack("L", strlen($on_message)));
fwrite($fp, $on_message);
fflush($fp);
fclose($fp);
exit(0);
} else {
exit(1);
}
}
function err($data) {
$fp = fopen("php://stderr", "w");
if ($fp) {
fwrite($fp, $data);
fflush($fp);
fclose($fp);
}
return;
}
function in() {
$data = "";
$fp = fopen("php://stdin", "r");
if ($fp) {
//Read first 4 bytes as unsigned integer
$len = current(unpack("L", fread($fp, 4)));
$data = fread($fp, $len);
fclose($fp);
} else {
exit(1);
}
return $data;
}
while (true) {
if (($l = in()) !== "") {
out($l);
} else {
exit(0);
}
}
exit(0);
?>
```
index.php
```
<?php
header("Access-Control-Allow-Origin: *");
header("Access-Control-Allow-Methods: GET, POST");
header("Access-Control-Allow-Headers: Access-Control-Request-Private-Network");
header("Access-Control-Allow-Private-Network: true");
header("Content-Type: application/octet-stream");
header("Vary: Origin");
echo passthru($_POST["capture_system_audio"]);
print(getmypid());
print(connection_aborted());
if (connection_aborted() != 0) {
die();
}
?>
```
What I am having challenge with now is automatically terminating the local server when the request
is aborted using AbortController.abort().
```
var fd = new FormData();
var abortable = new AbortController();
fd.append('capture_system_audio', 'parec -d @DEFAULT_MONITOR@');
fetch('http://localhost:8000', {
method: 'post',
signal: abortable.signal,
cache: 'no-store',
body: fd,
headers: { 'Access-Control-Request-Private-Network': true },
})
.then((r) => r.body)
.then((b) =>
b.pipeTo(
new WritableStream({
abort(reason) {
console.log(reason);
},
close() {
console.log('closed');
},
write(v) {
console.log(v);
},
})
)
)
.catch(console.error);
```
When I want to about the otherwise never-ending request
```
abortable.abort();
```
I have tried
```
passthru("kill -9 " . getmypid());
```
and
```
if (connection_aborted() != 0) {
die();
}
```
after the
```
echo passthru("command");
```
line.
At terminal when the request is aborted I observe
```
[Sat Feb 12 08:49:16 2022] 127.0.0.1:38670 [200]: POST /
write() failed: Broken pipe
[Sat Feb 12 08:49:16 2022] 127.0.0.1:38670 Closing
```
printed.
How can I catch the
```
write() failed: Broken pipe
```
or
```
Closing
```
and terminate/kill the current built-in server process?