1
0

RequestTest.php 9.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236
  1. <?php declare(strict_types=1);
  2. use PHPUnit\Framework\TestCase;
  3. use PrivateBin\Request;
  4. class RequestTest extends TestCase
  5. {
  6. public function reset()
  7. {
  8. $_SERVER = array();
  9. $_GET = array();
  10. $_POST = array();
  11. }
  12. /**
  13. * Returns random query safe characters.
  14. *
  15. * @access public
  16. * @return string
  17. */
  18. public function getRandomQueryChars()
  19. {
  20. $queryChars = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ=';
  21. $queryCharCount = strlen($queryChars) - 1;
  22. $resultLength = random_int(1, 10);
  23. $result = '';
  24. for ($i = 0; $i < $resultLength; ++$i) {
  25. $result .= $queryChars[random_int(0, $queryCharCount)];
  26. }
  27. return $result;
  28. }
  29. public function testView()
  30. {
  31. $this->reset();
  32. $_SERVER['REQUEST_METHOD'] = 'GET';
  33. $request = new Request;
  34. $this->assertFalse($request->isJsonApiCall(), 'is HTML call');
  35. $this->assertEquals('view', $request->getOperation());
  36. }
  37. public function testRead()
  38. {
  39. $this->reset();
  40. $id = Helper::getRandomId();
  41. $_SERVER['REQUEST_METHOD'] = 'GET';
  42. $_SERVER['QUERY_STRING'] = $id;
  43. $_GET[$id] = '';
  44. $request = new Request;
  45. $this->assertFalse($request->isJsonApiCall(), 'is HTML call');
  46. $this->assertEquals($id, $request->getParam('pasteid'));
  47. $this->assertEquals('read', $request->getOperation());
  48. }
  49. /**
  50. * paste IDs are 8 bytes hex encoded strings, if unlucky, this turns into
  51. * a numeric string that PHP will cast to an int, for example in array keys
  52. * @see https://www.php.net/manual/en/language.types.array.php
  53. */
  54. public function testReadNumeric()
  55. {
  56. $this->reset();
  57. $id = '1234567812345678';
  58. $_SERVER['REQUEST_METHOD'] = 'GET';
  59. $_SERVER['QUERY_STRING'] = $id;
  60. $_GET[$id] = '';
  61. $request = new Request;
  62. $this->assertFalse($request->isJsonApiCall(), 'is HTML call');
  63. $this->assertEquals($id, $request->getParam('pasteid'));
  64. $this->assertEquals('read', $request->getOperation());
  65. }
  66. public function testDelete()
  67. {
  68. $this->reset();
  69. $id = Helper::getRandomId();
  70. $_SERVER['REQUEST_METHOD'] = 'GET';
  71. $_GET['pasteid'] = $id;
  72. $_GET['deletetoken'] = 'bar';
  73. $request = new Request;
  74. $this->assertFalse($request->isJsonApiCall(), 'is HTML call');
  75. $this->assertEquals('delete', $request->getOperation());
  76. $this->assertEquals($id, $request->getParam('pasteid'));
  77. $this->assertEquals('bar', $request->getParam('deletetoken'));
  78. }
  79. public function testApiCreate()
  80. {
  81. $this->reset();
  82. $_SERVER['REQUEST_METHOD'] = 'PUT';
  83. $_SERVER['HTTP_X_REQUESTED_WITH'] = 'JSONHttpRequest';
  84. $file = Helper::createTempFile();
  85. file_put_contents($file, '{"ct":"foo"}');
  86. Request::setInputStream($file);
  87. $request = new Request;
  88. unlink($file);
  89. $this->assertTrue($request->isJsonApiCall(), 'is JSON API call');
  90. $this->assertEquals('create', $request->getOperation());
  91. $this->assertEquals('foo', $request->getParam('ct'));
  92. }
  93. public function testApiCreateAlternative()
  94. {
  95. $this->reset();
  96. $_SERVER['REQUEST_METHOD'] = 'POST';
  97. $_SERVER['HTTP_ACCEPT'] = 'application/json, text/javascript, */*; q=0.01';
  98. $file = Helper::createTempFile();
  99. file_put_contents($file, '{"ct":"foo"}');
  100. Request::setInputStream($file);
  101. $request = new Request;
  102. $this->assertTrue($request->isJsonApiCall(), 'is JSON API call');
  103. $this->assertEquals('create', $request->getOperation());
  104. $this->assertEquals('foo', $request->getParam('ct'));
  105. }
  106. public function testApiRead()
  107. {
  108. $this->reset();
  109. $id = Helper::getRandomId();
  110. $_SERVER['REQUEST_METHOD'] = 'GET';
  111. $_SERVER['HTTP_ACCEPT'] = 'application/json, text/javascript, */*; q=0.01';
  112. $_SERVER['QUERY_STRING'] = $id;
  113. $_GET[$id] = '';
  114. $request = new Request;
  115. $this->assertTrue($request->isJsonApiCall(), 'is JSON API call');
  116. $this->assertEquals($id, $request->getParam('pasteid'));
  117. $this->assertEquals('read', $request->getOperation());
  118. }
  119. public function testApiDelete()
  120. {
  121. $this->reset();
  122. $id = Helper::getRandomId();
  123. $_SERVER['REQUEST_METHOD'] = 'POST';
  124. $_SERVER['HTTP_X_REQUESTED_WITH'] = 'JSONHttpRequest';
  125. $_SERVER['QUERY_STRING'] = $id;
  126. $_GET = array($id => '');
  127. $file = Helper::createTempFile();
  128. file_put_contents($file, '{"deletetoken":"bar"}');
  129. Request::setInputStream($file);
  130. $request = new Request;
  131. $this->assertTrue($request->isJsonApiCall(), 'is JSON API call');
  132. $this->assertEquals('delete', $request->getOperation());
  133. $this->assertEquals($id, $request->getParam('pasteid'));
  134. $this->assertEquals('bar', $request->getParam('deletetoken'));
  135. }
  136. public function testPostGarbage()
  137. {
  138. $this->reset();
  139. $_SERVER['REQUEST_METHOD'] = 'POST';
  140. $file = Helper::createTempFile();
  141. file_put_contents($file, random_bytes(256));
  142. Request::setInputStream($file);
  143. $request = new Request;
  144. unlink($file);
  145. $this->assertFalse($request->isJsonApiCall(), 'is HTML call');
  146. $this->assertEquals('create', $request->getOperation());
  147. }
  148. public function testReadWithNegotiation()
  149. {
  150. $this->reset();
  151. $id = Helper::getRandomId();
  152. $_SERVER['REQUEST_METHOD'] = 'GET';
  153. $_SERVER['HTTP_ACCEPT'] = 'text/html,text/html; charset=UTF-8,application/xhtml+xml, application/xml;q=0.9,*/*;q=0.8, text/csv,application/json';
  154. $_SERVER['QUERY_STRING'] = $id;
  155. $_GET[$id] = '';
  156. $request = new Request;
  157. $this->assertFalse($request->isJsonApiCall(), 'is HTML call');
  158. $this->assertEquals($id, $request->getParam('pasteid'));
  159. $this->assertEquals('read', $request->getOperation());
  160. }
  161. public function testReadWithXhtmlNegotiation()
  162. {
  163. $this->reset();
  164. $id = Helper::getRandomId();
  165. $_SERVER['REQUEST_METHOD'] = 'GET';
  166. $_SERVER['HTTP_ACCEPT'] = 'application/xhtml+xml,text/html,text/html; charset=UTF-8, application/xml;q=0.9,*/*;q=0.8, text/csv,application/json';
  167. $_SERVER['QUERY_STRING'] = $id;
  168. $_GET[$id] = '';
  169. $request = new Request;
  170. $this->assertFalse($request->isJsonApiCall(), 'is HTML call');
  171. $this->assertEquals($id, $request->getParam('pasteid'));
  172. $this->assertEquals('read', $request->getOperation());
  173. }
  174. public function testApiReadWithNegotiation()
  175. {
  176. $this->reset();
  177. $id = Helper::getRandomId();
  178. $_SERVER['REQUEST_METHOD'] = 'GET';
  179. $_SERVER['HTTP_ACCEPT'] = 'text/plain,text/csv, application/xml;q=0.9, application/json, text/html,text/html; charset=UTF-8,application/xhtml+xml, */*;q=0.8';
  180. $_SERVER['QUERY_STRING'] = $id;
  181. $_GET[$id] = '';
  182. $request = new Request;
  183. $this->assertTrue($request->isJsonApiCall(), 'is JSON Api call');
  184. $this->assertEquals($id, $request->getParam('pasteid'));
  185. $this->assertEquals('read', $request->getOperation());
  186. }
  187. public function testReadWithFailedNegotiation()
  188. {
  189. $this->reset();
  190. $id = Helper::getRandomId();
  191. $_SERVER['REQUEST_METHOD'] = 'GET';
  192. $_SERVER['HTTP_ACCEPT'] = 'text/plain,text/csv, application/xml;q=0.9, */*;q=0.8';
  193. $_SERVER['QUERY_STRING'] = $id;
  194. $_GET[$id] = '';
  195. $request = new Request;
  196. $this->assertFalse($request->isJsonApiCall(), 'is HTML call');
  197. $this->assertEquals($id, $request->getParam('pasteid'));
  198. $this->assertEquals('read', $request->getOperation());
  199. }
  200. public function testPasteIdExtraction()
  201. {
  202. $this->reset();
  203. $id = Helper::getRandomId();
  204. $path = '/' . $this->getRandomQueryChars() . '/';
  205. $queryParams = array($id);
  206. $queryParamCount = random_int(1, 5);
  207. for ($i = 0; $i < $queryParamCount; ++$i) {
  208. array_push($queryParams, $this->getRandomQueryChars());
  209. }
  210. shuffle($queryParams);
  211. $_SERVER['REQUEST_METHOD'] = 'GET';
  212. $_SERVER['QUERY_STRING'] = implode('&', $queryParams);
  213. $_SERVER['REQUEST_URI'] = $path . '?' . $_SERVER['QUERY_STRING'];
  214. $_GET[$id] = '';
  215. $request = new Request;
  216. $this->assertEquals($id, $request->getParam('pasteid'));
  217. $this->assertEquals($path, $request->getRequestUri());
  218. }
  219. }