HttpTest.php 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125
  1. <?php
  2. use Workerman\Connection\TcpConnection;
  3. use Workerman\Protocols\Http;
  4. use Workerman\Protocols\Http\Request;
  5. use Workerman\Protocols\Http\Response;
  6. it('customizes request class', function () {
  7. //backup old request class
  8. $oldRequestClass = Http::requestClass();
  9. //actual test
  10. $class = new class {
  11. };
  12. Http::requestClass($class::class);
  13. expect(Http::requestClass())->toBe($class::class);
  14. //restore old request class
  15. Http::requestClass($oldRequestClass);
  16. });
  17. it('tests ::input', function () {
  18. $testWithConnectionClose = function (Closure $closure, string $dataContains = null) {
  19. $tcpConnection = Mockery::spy(TcpConnection::class);
  20. $closure($tcpConnection);
  21. if ($dataContains) {
  22. $tcpConnection->shouldHaveReceived('close', function ($actual) use ($dataContains) {
  23. return str_contains($actual, $dataContains);
  24. });
  25. } else {
  26. $tcpConnection->shouldHaveReceived('close');
  27. }
  28. };
  29. //test 413 payload too large
  30. $testWithConnectionClose(function (TcpConnection $tcpConnection) {
  31. expect(Http::input(str_repeat('jhdxr', 3333), $tcpConnection))
  32. ->toBe(0);
  33. }, '413 Payload Too Large');
  34. //example request from ChatGPT :)
  35. $buffer = "POST /path/to/resource HTTP/1.1\r\n" .
  36. "Host: example.com\r\n" .
  37. "Content-Type: application/json\r\n" .
  38. "Content-Length: 27\r\n" .
  39. "\r\n" .
  40. '{"key": "value", "foo": "bar"}';
  41. //unrecognized method
  42. $testWithConnectionClose(function (TcpConnection $tcpConnection) use ($buffer) {
  43. expect(Http::input(str_replace('POST', 'MIAOWU', $buffer), $tcpConnection))
  44. ->toBe(0);
  45. }, '400 Bad Request');
  46. //HTTP 1.1 without Host header
  47. $testWithConnectionClose(function (TcpConnection $tcpConnection) use ($buffer) {
  48. expect(Http::input(str_replace("Host: ", 'NotHost: ', $buffer), $tcpConnection))
  49. ->toBe(0);
  50. }, '400 Bad Request');
  51. //content-length exceeds connection max package size
  52. $testWithConnectionClose(function (TcpConnection $tcpConnection) use ($buffer) {
  53. $tcpConnection->maxPackageSize = 10;
  54. expect(Http::input($buffer, $tcpConnection))
  55. ->toBe(0);
  56. }, '413 Payload Too Large');
  57. });
  58. it('tests ::encode for non-object response', function () {
  59. $tcpConnection = Mockery::mock(TcpConnection::class);
  60. $tcpConnection->headers = [
  61. 'foo' => 'bar',
  62. 'jhdxr' => ['a', 'b'],
  63. ];
  64. $extHeader = "foo: bar\r\n" .
  65. "jhdxr: a\r\n" .
  66. "jhdxr: b\r\n";
  67. expect(Http::encode('xiami', $tcpConnection))
  68. ->toBe("HTTP/1.1 200 OK\r\n" .
  69. "Server: workerman\r\n" .
  70. "{$extHeader}Connection: keep-alive\r\n" .
  71. "Content-Type: text/html;charset=utf-8\r\n" .
  72. "Content-Length: 5\r\n\r\nxiami");
  73. });
  74. it('tests ::encode for ' . Response::class, function () {
  75. $tcpConnection = Mockery::mock(TcpConnection::class);
  76. $tcpConnection->headers = [
  77. 'foo' => 'bar',
  78. 'jhdxr' => ['a', 'b'],
  79. ];
  80. $extHeader = "foo: bar\r\n" .
  81. "jhdxr: a\r\n" .
  82. "jhdxr: b\r\n";
  83. $response = new Response(body: 'xiami');
  84. expect(Http::encode($response, $tcpConnection))
  85. ->toBe("HTTP/1.1 200 OK\r\n" .
  86. "Server: workerman\r\n" .
  87. "{$extHeader}Connection: keep-alive\r\n" .
  88. "Content-Type: text/html;charset=utf-8\r\n" .
  89. "Content-Length: 5\r\n\r\nxiami");
  90. });
  91. it('tests ::decode', function () {
  92. $tcpConnection = Mockery::mock(TcpConnection::class);
  93. //example request from ChatGPT :)
  94. $buffer = "POST /path/to/resource HTTP/1.1\r\n" .
  95. "Host: example.com\r\n" .
  96. "Content-Type: application/json\r\n" .
  97. "Content-Length: 27\r\n" .
  98. "\r\n" .
  99. '{"key": "value", "foo": "bar"}';
  100. $value = expect(Http::decode($buffer, $tcpConnection))
  101. ->toBeInstanceOf(Request::class)
  102. ->value;
  103. //test cache
  104. expect($value == Http::decode($buffer, $tcpConnection))
  105. ->toBeTrue();
  106. });