@recaptime-dev's working patches + fork for Phorge, a community fork of Phabricator. (Upstream dev and stable branches are at upstream/main and upstream/stable respectively.)
hq.recaptime.dev/wiki/Phorge
phorge
phabricator
1<?php
2
3final class ConduitSSHWorkflow extends PhabricatorSSHWorkflow {
4
5 protected function didConstruct() {
6 $this->setName('conduit');
7 $this->setArguments(
8 array(
9 array(
10 'name' => 'method',
11 'wildcard' => true,
12 ),
13 ));
14 }
15
16 public function execute(PhutilArgumentParser $args) {
17 $time_start = microtime(true);
18
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.'));
24 }
25
26 $method = head($methodv);
27
28 $json = $this->readAllInput();
29 $raw_params = null;
30 try {
31 $raw_params = phutil_json_decode($json);
32 } catch (PhutilJSONParserException $ex) {
33 throw new Exception(
34 pht('Invalid JSON input.'),
35 0,
36 $ex);
37 }
38
39 $params = idx($raw_params, 'params', '[]');
40 $params = phutil_json_decode($params);
41 $metadata = idx($params, '__conduit__', array());
42 unset($params['__conduit__']);
43
44 $call = null;
45 $error_code = null;
46 $error_info = null;
47
48 try {
49 $call = new ConduitCall($method, $params);
50 $call->setUser($this->getSSHUser());
51
52 $result = $call->execute();
53 } catch (ConduitException $ex) {
54 $result = null;
55 $error_code = $ex->getMessage();
56 if ($ex->getErrorDescription()) {
57 $error_info = $ex->getErrorDescription();
58 } else if ($call) {
59 $error_info = $call->getErrorDescription($error_code);
60 }
61 }
62
63 $response = id(new ConduitAPIResponse())
64 ->setResult($result)
65 ->setErrorCode($error_code)
66 ->setErrorInfo($error_info);
67
68 $json_out = json_encode($response->toDictionary());
69 $json_out = $json_out."\n";
70
71 $this->getIOChannel()->write($json_out);
72
73 // NOTE: Flush here so we can get an accurate result for the duration,
74 // if the response is large and the receiver is slow to read it.
75 $this->getIOChannel()->flush();
76
77 $connection_id = idx($metadata, 'connectionID');
78 $log = id(new PhabricatorConduitMethodCallLog())
79 ->setCallerPHID($this->getSSHUser()->getPHID())
80 ->setConnectionID($connection_id)
81 ->setMethod($method)
82 ->setError((string)$error_code)
83 ->setDuration(phutil_microseconds_since($time_start))
84 ->save();
85 }
86}