Correct Aphlict websocket URI construction after PHP8 compatibility changes
[phabricator.git] / src / applications / conduit / ssh / ConduitSSHWorkflow.php
blob0b4bd3cdefde0bf5b33c1b981800e2fa8de5cacf
1 <?php
3 final class ConduitSSHWorkflow extends PhabricatorSSHWorkflow {
5 protected function didConstruct() {
6 $this->setName('conduit');
7 $this->setArguments(
8 array(
9 array(
10 'name' => 'method',
11 'wildcard' => true,
13 ));
16 public function execute(PhutilArgumentParser $args) {
17 $time_start = microtime(true);
19 $methodv = $args->getArg('method');
20 if (!$methodv) {
21 throw new Exception(pht('No Conduit method provided.'));
22 } else if (count($methodv) > 1) {
23 throw new Exception(pht('Too many Conduit methods provided.'));
26 $method = head($methodv);
28 $json = $this->readAllInput();
29 $raw_params = null;
30 try {
31 $raw_params = phutil_json_decode($json);
32 } catch (PhutilJSONParserException $ex) {
33 throw new PhutilProxyException(
34 pht('Invalid JSON input.'),
35 $ex);
38 $params = idx($raw_params, 'params', '[]');
39 $params = phutil_json_decode($params);
40 $metadata = idx($params, '__conduit__', array());
41 unset($params['__conduit__']);
43 $call = null;
44 $error_code = null;
45 $error_info = null;
47 try {
48 $call = new ConduitCall($method, $params);
49 $call->setUser($this->getSSHUser());
51 $result = $call->execute();
52 } catch (ConduitException $ex) {
53 $result = null;
54 $error_code = $ex->getMessage();
55 if ($ex->getErrorDescription()) {
56 $error_info = $ex->getErrorDescription();
57 } else if ($call) {
58 $error_info = $call->getErrorDescription($error_code);
62 $response = id(new ConduitAPIResponse())
63 ->setResult($result)
64 ->setErrorCode($error_code)
65 ->setErrorInfo($error_info);
67 $json_out = json_encode($response->toDictionary());
68 $json_out = $json_out."\n";
70 $this->getIOChannel()->write($json_out);
72 // NOTE: Flush here so we can get an accurate result for the duration,
73 // if the response is large and the receiver is slow to read it.
74 $this->getIOChannel()->flush();
76 $connection_id = idx($metadata, 'connectionID');
77 $log = id(new PhabricatorConduitMethodCallLog())
78 ->setCallerPHID($this->getSSHUser()->getPHID())
79 ->setConnectionID($connection_id)
80 ->setMethod($method)
81 ->setError((string)$error_code)
82 ->setDuration(phutil_microseconds_since($time_start))
83 ->save();