public function willWriteMessageCallback(PhabricatorSSHPassthruCommand $command, $message)
 {
     $command = $message['command'];
     // Check if this is a readonly command.
     $is_readonly = false;
     if ($command == 'batch') {
         $cmds = idx($message['arguments'], 'cmds');
         if (DiffusionMercurialWireProtocol::isReadOnlyBatchCommand($cmds)) {
             $is_readonly = true;
         }
     } else {
         if (DiffusionMercurialWireProtocol::isReadOnlyCommand($command)) {
             $is_readonly = true;
         }
     }
     if (!$is_readonly) {
         $this->requireWriteAccess();
         $this->didSeeWrite = true;
     }
     $raw_message = $message['raw'];
     if ($command == 'capabilities') {
         $raw_message = DiffusionMercurialWireProtocol::filterBundle2Capability($raw_message);
     }
     // If we're good, return the raw message data.
     return $raw_message;
 }
 private function isReadOnlyRequest(PhabricatorRepository $repository)
 {
     $request = $this->getRequest();
     $method = $_SERVER['REQUEST_METHOD'];
     // TODO: This implementation is safe by default, but very incomplete.
     switch ($repository->getVersionControlSystem()) {
         case PhabricatorRepositoryType::REPOSITORY_TYPE_GIT:
             $service = $request->getStr('service');
             $path = $this->getRequestDirectoryPath($repository);
             // NOTE: Service names are the reverse of what you might expect, as they
             // are from the point of view of the server. The main read service is
             // "git-upload-pack", and the main write service is "git-receive-pack".
             if ($method == 'GET' && $path == '/info/refs' && $service == 'git-upload-pack') {
                 return true;
             }
             if ($path == '/git-upload-pack') {
                 return true;
             }
             break;
         case PhabricatorRepositoryType::REPOSITORY_TYPE_MERCURIAL:
             $cmd = $request->getStr('cmd');
             if ($cmd == 'batch') {
                 $cmds = idx($this->getMercurialArguments(), 'cmds');
                 return DiffusionMercurialWireProtocol::isReadOnlyBatchCommand($cmds);
             }
             return DiffusionMercurialWireProtocol::isReadOnlyCommand($cmd);
         case PhabricatorRepositoryType::REPOSITORY_TYPE_SVN:
             break;
     }
     return false;
 }