BxDolAIUnaProxyHttpClient.php 2.2 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667
  1. <?php defined('BX_DOL') or die('hack attempt');
  2. /**
  3. * Copyright (c) UNA, Inc - https://una.io
  4. * MIT License - https://opensource.org/licenses/MIT
  5. *
  6. * @defgroup UnaCore UNA Core
  7. * @{
  8. */
  9. class BxDolAIUnaProxyHttpClient extends NeuronAI\HttpClient\GuzzleHttpClient
  10. {
  11. public function __construct(
  12. protected string $sUnaKey,
  13. protected string $sUnaSecret,
  14. ) {
  15. parent::__construct();
  16. }
  17. public static function encodeBody(array $aBody): string
  18. {
  19. return json_encode($aBody, JSON_UNESCAPED_UNICODE | JSON_THROW_ON_ERROR);
  20. }
  21. public static function sign(string $sRawBody, string $sSecret): string
  22. {
  23. return hash_hmac('sha256', $sRawBody, $sSecret);
  24. }
  25. /**
  26. * Headers for the exact bytes that will be posted. The secret is not a header.
  27. *
  28. * @return array<string, string>
  29. */
  30. public function headersForBody(string $sRawBody): array
  31. {
  32. if ($this->sUnaKey === '' || $this->sUnaSecret === '')
  33. throw new Exception(_t('_sys_agents_una_proxy_unconfigured'));
  34. return [
  35. 'X-Una-Key' => $this->sUnaKey,
  36. 'X-Una-Sign' => self::sign($sRawBody, $this->sUnaSecret),
  37. ];
  38. }
  39. public function runRequest(NeuronAI\HttpClient\HttpRequest $request, array $options, GuzzleHttp\Client $client): Psr\Http\Message\ResponseInterface
  40. {
  41. $sBody = '';
  42. if (is_array($request->body)) {
  43. $sBody = self::encodeBody($request->body);
  44. $request = new NeuronAI\HttpClient\HttpRequest($request->method, $request->uri, $request->headers, $sBody);
  45. }
  46. elseif (is_string($request->body))
  47. $sBody = $request->body;
  48. $aHeaders = $options[\GuzzleHttp\RequestOptions::HEADERS] ?? [];
  49. foreach (array_keys($aHeaders) as $sName) {
  50. if (strcasecmp((string)$sName, 'Authorization') === 0)
  51. unset($aHeaders[$sName]);
  52. }
  53. $options[\GuzzleHttp\RequestOptions::HEADERS] = array_merge($aHeaders, $this->headersForBody($sBody));
  54. unset($options[\GuzzleHttp\RequestOptions::JSON]);
  55. return parent::runRequest($request, $options, $client);
  56. }
  57. }
  58. /** @} */