Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
68 changes: 67 additions & 1 deletion src/ManticoreSearch/Client.php
100755 → 100644
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,9 @@ class Client {
/** @var ?string $authToken */
protected ?string $authToken = null;

/** @var ?string $delegatedUser */
protected ?string $delegatedUser = null;

/** @var string $buddyVersion */
protected string $buddyVersion;

Expand Down Expand Up @@ -90,6 +93,21 @@ function () {
$this->clientMap = new Map;
}

/**
* Ensure request-scoped cloned clients do not share mutable internals.
* @return void
*/
public function __clone() {
$this->connectionPool = new ConnectionPool(
function () {
$client = new HttpClient($this->host, $this->port);
$client->set(['timeout' => -1]);
return $client;
}
);
$this->clientMap = new Map;
}

/**
* Set server URL of Manticore searchd to send requests to
* @param string $url it supports http:// prefixed and not
Expand Down Expand Up @@ -121,6 +139,30 @@ public function getServerUrl(): string {
return static::URL_PREFIX . $this->host . ':' . $this->port;
}

/**
* Set delegated user context for outgoing daemon requests.
*
* Context is coroutine-scoped when running in coroutine mode.
* In sync mode it falls back to the instance-local value.
*
* @param ?string $user
* @return static
*/
public function setDelegatedUser(?string $user): static {
$normalizedUser = $user ? trim($user) : null;
// Empty string or null should be null
$this->delegatedUser = $normalizedUser ?: null;
return $this;
}

/**
* Clear delegated user context from current request scope.
* @return static
*/
public function clearDelegatedUser(): static {
return $this->setDelegatedUser(null);
}

/**
* Send the request where request represents the SQL query to be send
* @param string $request
Expand All @@ -134,7 +176,7 @@ public function sendRequest(
string $request,
?string $path = null,
bool $disableAgentHeader = false,
string $requestMethod = 'POST'
string $requestMethod = 'POST',
): Response {
$t = microtime(true);
if ($request === '') {
Expand Down Expand Up @@ -168,6 +210,15 @@ public function sendRequest(
'Content-Type' => $contentTypeHeader,
'User-Agent' => $userAgentHeader,
];

$delegatedUser = $this->resolveDelegatedUser();
$delegatedUserLog = $delegatedUser ?? '<empty>';
Buddy::debug("delegated user for daemon request on /{$path}: {$delegatedUserLog}");

if ($delegatedUser !== null) {
$headers['X-Manticore-User'] = $delegatedUser;
}

// Add authorization header if we have token
if (isset($this->authToken)) {
$headers['Authorization'] = "Bearer {$this->authToken}";
Expand Down Expand Up @@ -254,9 +305,24 @@ public function sendRequestToUrl(
bool $disableAgentHeader = false
): Response {
$client = $this->getClientForUrl($url);

$delegatedUser = $this->resolveDelegatedUser();
if ($delegatedUser === null) {
$client->clearDelegatedUser();
} else {
$client->setDelegatedUser($delegatedUser);
}

return $client->sendRequest($request, $path, $disableAgentHeader);
}

/**
* @return ?string
*/
protected function resolveDelegatedUser(): ?string {
return $this->delegatedUser;
}

/**
* @param string $url
* @return Client
Expand Down
Loading