MockSocket.php 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081
  1. <?php
  2. /**
  3. * This class is used by tests to mock and track various socket/stream calls.
  4. */
  5. namespace WebSocket;
  6. class MockSocket
  7. {
  8. private static $queue = [];
  9. private static $stored = [];
  10. private static $asserter;
  11. // Handler called by function overloads in mock-socket.php
  12. public static function handle($function, $params = [])
  13. {
  14. $current = array_shift(self::$queue);
  15. if ($function == 'get_resource_type' && is_null($current)) {
  16. return null; // Catch destructors
  17. }
  18. self::$asserter->assertEquals($current['function'], $function);
  19. foreach ($current['params'] as $index => $param) {
  20. if (isset($current['input-op'])) {
  21. $param = self::op($current['input-op'], $params, $param);
  22. }
  23. self::$asserter->assertEquals($param, $params[$index], json_encode([$current, $params]));
  24. }
  25. if (isset($current['error'])) {
  26. $map = array_merge(['msg' => 'Error', 'type' => E_USER_NOTICE], (array)$current['error']);
  27. trigger_error($map['msg'], $map['type']);
  28. }
  29. if (isset($current['return-op'])) {
  30. return self::op($current['return-op'], $params, $current['return']);
  31. }
  32. if (isset($current['return'])) {
  33. return $current['return'];
  34. }
  35. return call_user_func_array($function, $params);
  36. }
  37. // Check if all expected calls are performed
  38. public static function isEmpty(): bool
  39. {
  40. return empty(self::$queue);
  41. }
  42. // Initialize call queue
  43. public static function initialize($op_file, $asserter): void
  44. {
  45. $file = dirname(__DIR__) . "/scripts/{$op_file}.json";
  46. self::$queue = json_decode(file_get_contents($file), true);
  47. self::$asserter = $asserter;
  48. }
  49. // Special output handling
  50. private static function op($op, $params, $data)
  51. {
  52. switch ($op) {
  53. case 'chr-array':
  54. // Convert int array to string
  55. $out = '';
  56. foreach ($data as $val) {
  57. $out .= chr($val);
  58. }
  59. return $out;
  60. case 'file':
  61. $content = file_get_contents(__DIR__ . "/{$data[0]}");
  62. return substr($content, $data[1], $data[2]);
  63. case 'key-save':
  64. preg_match('#Sec-WebSocket-Key:\s(.*)$#mUi', $params[1], $matches);
  65. self::$stored['sec-websocket-key'] = trim($matches[1]);
  66. return str_replace('{key}', self::$stored['sec-websocket-key'], $data);
  67. case 'key-respond':
  68. $key = self::$stored['sec-websocket-key'] . '258EAFA5-E914-47DA-95CA-C5AB0DC85B11';
  69. $encoded = base64_encode(pack('H*', sha1($key)));
  70. return str_replace('{key}', $encoded, $data);
  71. }
  72. return $data;
  73. }
  74. }