ServerNegotiatorTest.php 8.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219
  1. <?php
  2. namespace Ratchet\RFC6455\Test\Unit\Handshake;
  3. use GuzzleHttp\Psr7\Message;
  4. use Ratchet\RFC6455\Handshake\RequestVerifier;
  5. use Ratchet\RFC6455\Handshake\ServerNegotiator;
  6. use PHPUnit\Framework\TestCase;
  7. class ServerNegotiatorTest extends TestCase
  8. {
  9. public function testNoUpgradeRequested() {
  10. $negotiator = new ServerNegotiator(new RequestVerifier());
  11. $requestText = 'GET / HTTP/1.1
  12. Host: 127.0.0.1:6789
  13. Connection: keep-alive
  14. Pragma: no-cache
  15. Cache-Control: no-cache
  16. Upgrade-Insecure-Requests: 1
  17. User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/57.0.2987.133 Safari/537.36
  18. Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
  19. Accept-Encoding: gzip, deflate, sdch, br
  20. Accept-Language: en-US,en;q=0.8
  21. ';
  22. $request = Message::parseRequest($requestText);
  23. $response = $negotiator->handshake($request);
  24. $this->assertEquals('1.1', $response->getProtocolVersion());
  25. $this->assertEquals(426, $response->getStatusCode());
  26. $this->assertEquals('Upgrade header MUST be provided', $response->getReasonPhrase());
  27. $this->assertEquals('Upgrade', $response->getHeaderLine('Connection'));
  28. $this->assertEquals('websocket', $response->getHeaderLine('Upgrade'));
  29. $this->assertEquals('13', $response->getHeaderLine('Sec-WebSocket-Version'));
  30. }
  31. public function testNoConnectionUpgradeRequested() {
  32. $negotiator = new ServerNegotiator(new RequestVerifier());
  33. $requestText = 'GET / HTTP/1.1
  34. Host: 127.0.0.1:6789
  35. Connection: keep-alive
  36. Pragma: no-cache
  37. Cache-Control: no-cache
  38. Upgrade: websocket
  39. Upgrade-Insecure-Requests: 1
  40. User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/57.0.2987.133 Safari/537.36
  41. Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
  42. Accept-Encoding: gzip, deflate, sdch, br
  43. Accept-Language: en-US,en;q=0.8
  44. ';
  45. $request = Message::parseRequest($requestText);
  46. $response = $negotiator->handshake($request);
  47. $this->assertEquals('1.1', $response->getProtocolVersion());
  48. $this->assertEquals(400, $response->getStatusCode());
  49. $this->assertEquals('Connection Upgrade MUST be requested', $response->getReasonPhrase());
  50. }
  51. public function testInvalidSecWebsocketKey() {
  52. $negotiator = new ServerNegotiator(new RequestVerifier());
  53. $requestText = 'GET / HTTP/1.1
  54. Host: 127.0.0.1:6789
  55. Connection: Upgrade
  56. Pragma: no-cache
  57. Cache-Control: no-cache
  58. Upgrade: websocket
  59. Sec-WebSocket-Key: 12345
  60. Upgrade-Insecure-Requests: 1
  61. User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/57.0.2987.133 Safari/537.36
  62. Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
  63. Accept-Encoding: gzip, deflate, sdch, br
  64. Accept-Language: en-US,en;q=0.8
  65. ';
  66. $request = Message::parseRequest($requestText);
  67. $response = $negotiator->handshake($request);
  68. $this->assertEquals('1.1', $response->getProtocolVersion());
  69. $this->assertEquals(400, $response->getStatusCode());
  70. $this->assertEquals('Invalid Sec-WebSocket-Key', $response->getReasonPhrase());
  71. }
  72. public function testInvalidSecWebsocketVersion() {
  73. $negotiator = new ServerNegotiator(new RequestVerifier());
  74. $requestText = 'GET / HTTP/1.1
  75. Host: 127.0.0.1:6789
  76. Connection: Upgrade
  77. Pragma: no-cache
  78. Cache-Control: no-cache
  79. Upgrade: websocket
  80. Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==
  81. Upgrade-Insecure-Requests: 1
  82. User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/57.0.2987.133 Safari/537.36
  83. Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
  84. Accept-Encoding: gzip, deflate, sdch, br
  85. Accept-Language: en-US,en;q=0.8
  86. ';
  87. $request = Message::parseRequest($requestText);
  88. $response = $negotiator->handshake($request);
  89. $this->assertEquals('1.1', $response->getProtocolVersion());
  90. $this->assertEquals(426, $response->getStatusCode());
  91. $this->assertEquals('Upgrade Required', $response->getReasonPhrase());
  92. $this->assertEquals('Upgrade', $response->getHeaderLine('Connection'));
  93. $this->assertEquals('websocket', $response->getHeaderLine('Upgrade'));
  94. $this->assertEquals('13', $response->getHeaderLine('Sec-WebSocket-Version'));
  95. }
  96. public function testBadSubprotocolResponse() {
  97. $negotiator = new ServerNegotiator(new RequestVerifier());
  98. $negotiator->setStrictSubProtocolCheck(true);
  99. $negotiator->setSupportedSubProtocols([]);
  100. $requestText = 'GET / HTTP/1.1
  101. Host: 127.0.0.1:6789
  102. Connection: Upgrade
  103. Pragma: no-cache
  104. Cache-Control: no-cache
  105. Upgrade: websocket
  106. Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==
  107. Sec-WebSocket-Version: 13
  108. Sec-WebSocket-Protocol: someprotocol
  109. Upgrade-Insecure-Requests: 1
  110. User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/57.0.2987.133 Safari/537.36
  111. Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
  112. Accept-Encoding: gzip, deflate, sdch, br
  113. Accept-Language: en-US,en;q=0.8
  114. ';
  115. $request = Message::parseRequest($requestText);
  116. $response = $negotiator->handshake($request);
  117. $this->assertEquals('1.1', $response->getProtocolVersion());
  118. $this->assertEquals(426, $response->getStatusCode());
  119. $this->assertEquals('No Sec-WebSocket-Protocols requested supported', $response->getReasonPhrase());
  120. $this->assertEquals('Upgrade', $response->getHeaderLine('Connection'));
  121. $this->assertEquals('websocket', $response->getHeaderLine('Upgrade'));
  122. $this->assertEquals('13', $response->getHeaderLine('Sec-WebSocket-Version'));
  123. }
  124. public function testNonStrictSubprotocolDoesNotIncludeHeaderWhenNoneAgreedOn() {
  125. $negotiator = new ServerNegotiator(new RequestVerifier());
  126. $negotiator->setStrictSubProtocolCheck(false);
  127. $negotiator->setSupportedSubProtocols(['someproto']);
  128. $requestText = 'GET / HTTP/1.1
  129. Host: 127.0.0.1:6789
  130. Connection: Upgrade
  131. Pragma: no-cache
  132. Cache-Control: no-cache
  133. Upgrade: websocket
  134. Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==
  135. Sec-WebSocket-Version: 13
  136. Sec-WebSocket-Protocol: someotherproto
  137. Upgrade-Insecure-Requests: 1
  138. User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/57.0.2987.133 Safari/537.36
  139. Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
  140. Accept-Encoding: gzip, deflate, sdch, br
  141. Accept-Language: en-US,en;q=0.8
  142. ';
  143. $request = Message::parseRequest($requestText);
  144. $response = $negotiator->handshake($request);
  145. $this->assertEquals('1.1', $response->getProtocolVersion());
  146. $this->assertEquals(101, $response->getStatusCode());
  147. $this->assertEquals('Upgrade', $response->getHeaderLine('Connection'));
  148. $this->assertEquals('websocket', $response->getHeaderLine('Upgrade'));
  149. $this->assertFalse($response->hasHeader('Sec-WebSocket-Protocol'));
  150. }
  151. public function testSuggestsAppropriateSubprotocol()
  152. {
  153. $negotiator = new ServerNegotiator(new RequestVerifier());
  154. $negotiator->setStrictSubProtocolCheck(true);
  155. $negotiator->setSupportedSubProtocols(['someproto']);
  156. $requestText = 'GET / HTTP/1.1
  157. Host: localhost:8080
  158. Connection: Upgrade
  159. Upgrade: websocket
  160. Sec-WebSocket-Version: 13
  161. User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/64.0.3282.140 Safari/537.36
  162. Accept-Encoding: gzip, deflate, br
  163. Accept-Language: en-US,en;q=0.9
  164. Sec-WebSocket-Key: HGt8eQax7nAOlXUw0/asPQ==
  165. Sec-WebSocket-Extensions: permessage-deflate; client_max_window_bits
  166. ';
  167. $request = Message::parseRequest($requestText);
  168. $response = $negotiator->handshake($request);
  169. $this->assertEquals('1.1', $response->getProtocolVersion());
  170. $this->assertEquals(426, $response->getStatusCode());
  171. $this->assertEquals('Upgrade', $response->getHeaderLine('Connection'));
  172. $this->assertEquals('websocket', $response->getHeaderLine('Upgrade'));
  173. $this->assertEquals('someproto', $response->getHeaderLine('Sec-WebSocket-Protocol'));
  174. }
  175. }