@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
fork

Configure Feed

Select the types of activity you want to include in your feed.

Route internal conduit calls if other hosts available

Summary:
Ref T2785

Looks for hosts in `conduit.servers` config and if any exist route any conduit calls through any one of the hosts.

Test Plan:
Make some curl calls to public methods (`conduit.ping`), watch the access log for two requests. Make some calls from the UI that require authentication, watch the access log a bit more.

Also ran the unit tests.

Reviewers: epriestley

Reviewed By: epriestley

CC: aran, Korvin

Maniphest Tasks: T2785

Differential Revision: https://secure.phabricator.com/D5970

authored by

Gareth Evans and committed by
epriestley
94e7878a a1a46656

+118 -14
+2
src/__phutil_library_map__.php
··· 830 830 'PhabricatorChatLogQuery' => 'applications/chatlog/PhabricatorChatLogQuery.php', 831 831 'PhabricatorConduitAPIController' => 'applications/conduit/controller/PhabricatorConduitAPIController.php', 832 832 'PhabricatorConduitCertificateToken' => 'applications/conduit/storage/PhabricatorConduitCertificateToken.php', 833 + 'PhabricatorConduitConfigOptions' => 'applications/conduit/config/PhabricatorConduitConfigOptions.php', 833 834 'PhabricatorConduitConnectionLog' => 'applications/conduit/storage/PhabricatorConduitConnectionLog.php', 834 835 'PhabricatorConduitConsoleController' => 'applications/conduit/controller/PhabricatorConduitConsoleController.php', 835 836 'PhabricatorConduitController' => 'applications/conduit/controller/PhabricatorConduitController.php', ··· 2601 2602 'PhabricatorChatLogQuery' => 'PhabricatorCursorPagedPolicyAwareQuery', 2602 2603 'PhabricatorConduitAPIController' => 'PhabricatorConduitController', 2603 2604 'PhabricatorConduitCertificateToken' => 'PhabricatorConduitDAO', 2605 + 'PhabricatorConduitConfigOptions' => 'PhabricatorApplicationConfigOptions', 2604 2606 'PhabricatorConduitConnectionLog' => 'PhabricatorConduitDAO', 2605 2607 'PhabricatorConduitConsoleController' => 'PhabricatorConduitController', 2606 2608 'PhabricatorConduitController' => 'PhabricatorController',
+24 -9
src/aphront/configuration/AphrontApplicationConfiguration.php
··· 113 113 } 114 114 } 115 115 116 - $path = $request->getPath(); 117 - $host = $request->getHost(); 118 - $base_uri = PhabricatorEnv::getEnvConfig('phabricator.base-uri'); 119 - $prod_uri = PhabricatorEnv::getEnvConfig('phabricator.production-uri'); 120 - $file_uri = PhabricatorEnv::getEnvConfig('security.alternate-file-domain'); 116 + $path = $request->getPath(); 117 + $host = $request->getHost(); 118 + $base_uri = PhabricatorEnv::getEnvConfig('phabricator.base-uri'); 119 + $prod_uri = PhabricatorEnv::getEnvConfig('phabricator.production-uri'); 120 + $file_uri = PhabricatorEnv::getEnvConfig( 121 + 'security.alternate-file-domain'); 122 + $conduit_uris = PhabricatorEnv::getEnvConfig('conduit.servers'); 123 + 124 + $uris = array_merge( 125 + array( 126 + $base_uri, 127 + $prod_uri, 128 + $file_uri, 129 + ), 130 + $conduit_uris); 131 + 132 + $host_match = false; 133 + foreach ($uris as $uri) { 134 + if ($host === id(new PhutilURI($uri))->getDomain()) { 135 + $host_match = true; 136 + break; 137 + } 138 + } 121 139 122 140 // NOTE: If the base URI isn't defined yet, don't activate alternate 123 141 // domains. 124 - if ($base_uri && 125 - $host != id(new PhutilURI($base_uri))->getDomain() && 126 - $host != id(new PhutilURI($prod_uri))->getDomain() && 127 - $host != id(new PhutilURI($file_uri))->getDomain()) { 142 + if ($base_uri && !$host_match) { 128 143 129 144 try { 130 145 $blog = id(new PhameBlogQuery())
+54 -3
src/applications/conduit/call/ConduitCall.php
··· 13 13 private $method; 14 14 private $request; 15 15 private $user; 16 + private $servers; 17 + private $forceLocal; 16 18 17 19 public function __construct($method, array $params) { 18 - $this->method = $method; 19 - $this->handler = $this->buildMethodHandler($method); 20 + $this->method = $method; 21 + $this->handler = $this->buildMethodHandler($method); 22 + $this->servers = PhabricatorEnv::getEnvConfig('conduit.servers'); 23 + $this->forceLocal = false; 20 24 21 25 $invalid_params = array_diff_key( 22 26 $params, ··· 27 31 implode("', '", array_keys($invalid_params)) . "'."); 28 32 } 29 33 34 + if ($this->servers) { 35 + $current_host = AphrontRequest::getHTTPHeader('HOST'); 36 + foreach ($this->servers as $server) { 37 + if ($current_host === id(new PhutilURI($server))->getDomain()) { 38 + $this->forceLocal = true; 39 + break; 40 + } 41 + } 42 + } 43 + 30 44 $this->request = new ConduitAPIRequest($params); 31 45 } 32 46 ··· 37 51 38 52 public function getUser() { 39 53 return $this->user; 54 + } 55 + 56 + public function setForceLocal($force_local) { 57 + $this->forceLocal = $force_local; 58 + return $this; 59 + } 60 + 61 + public function shouldForceLocal() { 62 + return $this->forceLocal; 40 63 } 41 64 42 65 public function shouldRequireAuthentication() { ··· 64 87 $this->request->setUser($this->getUser()); 65 88 } 66 89 67 - return $this->handler->executeMethod($this->request); 90 + if (!$this->shouldForceLocal() && $this->servers) { 91 + $server = $this->pickRandomServer($this->servers); 92 + $client = new ConduitClient($server); 93 + $params = $this->request->getAllParameters(); 94 + 95 + $params["__conduit__"]["isProxied"] = true; 96 + 97 + if ($this->handler->shouldRequireAuthentication()) { 98 + $client->callMethodSynchronous( 99 + 'conduit.connect', 100 + array( 101 + 'client' => 'PhabricatorConduit', 102 + 'clientVersion' => '1.0', 103 + 'user' => $this->getUser()->getUserName(), 104 + 'certificate' => $this->getUser()->getConduitCertificate(), 105 + '__conduit__' => $params["__conduit__"], 106 + )); 107 + } 108 + 109 + return $client->callMethodSynchronous( 110 + $this->method, 111 + $params); 112 + } else { 113 + return $this->handler->executeMethod($this->request); 114 + } 115 + } 116 + 117 + protected function pickRandomServer($servers) { 118 + return $servers[array_rand($servers)]; 68 119 } 69 120 70 121 protected function buildMethodHandler($method) {
+3 -1
src/applications/conduit/call/__tests__/ConduitCallTestCase.php
··· 4 4 5 5 public function testConduitPing() { 6 6 $call = new ConduitCall('conduit.ping', array()); 7 + $call->setForceLocal(true); 7 8 $result = $call->execute(); 8 9 9 10 $this->assertEqual(false, empty($result)); 10 11 } 11 12 12 13 public function testConduitAuth() { 13 - $call = new ConduitCall('user.whoami', array()); 14 + $call = new ConduitCall('user.whoami', array(), true); 15 + $call->setForceLocal(true); 14 16 15 17 $caught = null; 16 18 try {
+31
src/applications/conduit/config/PhabricatorConduitConfigOptions.php
··· 1 + <?php 2 + 3 + final class PhabricatorConduitConfigOptions 4 + extends PhabricatorApplicationConfigOptions { 5 + 6 + public function getName() { 7 + return pht("Conduit"); 8 + } 9 + 10 + public function getDescription() { 11 + return pht("Configure conduit."); 12 + } 13 + 14 + public function getOptions() { 15 + return array( 16 + $this->newOption("conduit.servers", "list<string>", array()) 17 + ->setLocked(true) 18 + ->setSummary(pht("Servers that conduit can connect to.")) 19 + ->setDescription( 20 + pht( 21 + "Set an array of servers where conduit can connect to. This is ". 22 + "an advanced option. Don't touch this unless you know what you ". 23 + "are doing.")) 24 + ->addExample( 25 + '["http://phabricator2.example.com/", '. 26 + '"http://phabricator3.example.com/]"', 27 + pht('Valid Setting')), 28 + ); 29 + } 30 + 31 + }
+2 -1
src/applications/conduit/controller/PhabricatorConduitAPIController.php
··· 35 35 $metadata = idx($params, '__conduit__', array()); 36 36 unset($params['__conduit__']); 37 37 38 - $call = new ConduitCall($method, $params); 38 + $call = new ConduitCall( 39 + $method, $params, idx($metadata, 'isProxied', false)); 39 40 40 41 $result = null; 41 42
+2
src/applications/differential/conduit/ConduitAPI_differential_finishpostponedlinters_Method.php
··· 98 98 'diff_id' => $diff_id, 99 99 'name' => 'arc:lint', 100 100 'data' => json_encode($messages))); 101 + $call->setForceLocal(true); 101 102 $call->setUser($request->getUser()); 102 103 $call->execute(); 103 104 $call = new ConduitCall( ··· 106 107 'diff_id' => $diff_id, 107 108 'name' => 'arc:lint-postponed', 108 109 'data' => json_encode($postponed_linters))); 110 + $call->setForceLocal(true); 109 111 $call->setUser($request->getUser()); 110 112 $call->execute(); 111 113