3 final class ConduitSSHWorkflow
extends PhabricatorSSHWorkflow
{
5 protected function didConstruct() {
6 $this->setName('conduit');
16 public function execute(PhutilArgumentParser
$args) {
17 $time_start = microtime(true);
19 $methodv = $args->getArg('method');
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();
31 $raw_params = phutil_json_decode($json);
32 } catch (PhutilJSONParserException
$ex) {
33 throw new PhutilProxyException(
34 pht('Invalid JSON input.'),
38 $params = idx($raw_params, 'params', '[]');
39 $params = phutil_json_decode($params);
40 $metadata = idx($params, '__conduit__', array());
41 unset($params['__conduit__']);
48 $call = new ConduitCall($method, $params);
49 $call->setUser($this->getSSHUser());
51 $result = $call->execute();
52 } catch (ConduitException
$ex) {
54 $error_code = $ex->getMessage();
55 if ($ex->getErrorDescription()) {
56 $error_info = $ex->getErrorDescription();
58 $error_info = $call->getErrorDescription($error_code);
62 $response = id(new ConduitAPIResponse())
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)
81 ->setError((string)$error_code)
82 ->setDuration(phutil_microseconds_since($time_start))