HeaderTest.php 30 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536
  1. <?php
  2. /**
  3. * Unit Tests for KO7_HTTP_Header
  4. *
  5. * @group ko7
  6. * @group ko7.core
  7. * @group ko7.core.http
  8. * @group ko7.core.http.header
  9. * @group ko7.core.http.header
  10. *
  11. * @package KO7
  12. * @category Tests
  13. *
  14. * @copyright (c) 2007-2016 Kohana Team
  15. * @copyright (c) since 2016 Koseven Team
  16. * @license https://koseven.dev/LICENSE
  17. */
  18. class KO7_HTTP_HeaderTest extends Unittest_TestCase {
  19. /**
  20. * Provides data for test_accept_quality
  21. *
  22. * @return array
  23. */
  24. public function provider_accept_quality()
  25. {
  26. return [
  27. [
  28. [
  29. 'text/html; q=1',
  30. 'text/plain; q=.5',
  31. 'application/json; q=.1',
  32. 'text/*'
  33. ],
  34. [
  35. 'text/html' => (float) 1,
  36. 'text/plain' => 0.5,
  37. 'application/json' => 0.1,
  38. 'text/*' => (float) 1
  39. ]
  40. ],
  41. [
  42. [
  43. 'text/*',
  44. 'text/html; level=1; q=0.4',
  45. 'application/xml+rss; q=0.5; level=4'
  46. ],
  47. [
  48. 'text/*' => (float) 1,
  49. 'text/html; level=1' => 0.4,
  50. 'application/xml+rss; level=4' => 0.5
  51. ]
  52. ]
  53. ];
  54. }
  55. /**
  56. * Tests the `accept_quality` method parses the quality values
  57. * correctly out of header parts
  58. *
  59. * @dataProvider provider_accept_quality
  60. *
  61. * @param array $parts input
  62. * @param array $expected expected output
  63. * @return void
  64. */
  65. public function test_accept_quality(array $parts, array $expected)
  66. {
  67. $out = HTTP_Header::accept_quality($parts);
  68. foreach ($out as $key => $value)
  69. {
  70. $this->assertIsFloat($value);
  71. }
  72. $this->assertSame($expected, $out);
  73. }
  74. /**
  75. * Data provider for test_parse_accept_header
  76. *
  77. * @return array
  78. */
  79. public function provider_parse_accept_header()
  80. {
  81. return [
  82. [
  83. 'text/html, text/plain, text/*, */*',
  84. [
  85. 'text' => [
  86. 'html' => (float) 1,
  87. 'plain' => (float) 1,
  88. '*' => (float) 1
  89. ],
  90. '*' => [
  91. '*' => (float) 1
  92. ]
  93. ]
  94. ],
  95. [
  96. 'text/html; q=.5, application/json, application/xml+rss; level=1; q=.7, text/*, */*',
  97. [
  98. 'text' => [
  99. 'html' => 0.5,
  100. '*' => (float) 1
  101. ],
  102. 'application' => [
  103. 'json' => (float) 1,
  104. 'xml+rss; level=1' => 0.7
  105. ],
  106. '*' => [
  107. '*' => (float) 1
  108. ]
  109. ]
  110. ]
  111. ];
  112. }
  113. /**
  114. * Tests the `parse_accept_header` method parses the Accept: header
  115. * correctly and returns expected output
  116. *
  117. * @dataProvider provider_parse_accept_header
  118. *
  119. * @param string $accept accept in
  120. * @param array $expected expected out
  121. * @return void
  122. */
  123. public function test_parse_accept_header($accept, array $expected)
  124. {
  125. $this->assertSame($expected, HTTP_Header::parse_accept_header($accept));
  126. }
  127. /**
  128. * Provides data for test_parse_charset_header
  129. *
  130. * @return array
  131. */
  132. public function provider_parse_charset_header()
  133. {
  134. return [
  135. [
  136. 'utf-8, utf-10, utf-16, iso-8859-1',
  137. [
  138. 'utf-8' => (float) 1,
  139. 'utf-10' => (float) 1,
  140. 'utf-16' => (float) 1,
  141. 'iso-8859-1'=> (float) 1
  142. ]
  143. ],
  144. [
  145. 'utf-8, utf-10; q=.9, utf-16; q=.5, iso-8859-1; q=.75',
  146. [
  147. 'utf-8' => (float) 1,
  148. 'utf-10' => 0.9,
  149. 'utf-16' => 0.5,
  150. 'iso-8859-1'=> 0.75
  151. ]
  152. ],
  153. [
  154. NULL,
  155. [
  156. '*' => (float) 1
  157. ]
  158. ]
  159. ];
  160. }
  161. /**
  162. * Tests the `parse_charset_header` method parsed the Accept-Charset header
  163. * correctly
  164. *
  165. * @dataProvider provider_parse_charset_header
  166. *
  167. * @param string $accept accept
  168. * @param array $expected expected
  169. * @return void
  170. */
  171. public function test_parse_charset_header($accept, array $expected)
  172. {
  173. $this->assertSame($expected, HTTP_Header::parse_charset_header($accept));
  174. }
  175. /**
  176. * Provides data for test_parse_charset_header
  177. *
  178. * @return array
  179. */
  180. public function provider_parse_encoding_header()
  181. {
  182. return [
  183. [
  184. 'compress, gzip, blowfish',
  185. [
  186. 'compress' => (float) 1,
  187. 'gzip' => (float) 1,
  188. 'blowfish' => (float) 1
  189. ]
  190. ],
  191. [
  192. 'compress, gzip; q=0.12345, blowfish; q=1.0',
  193. [
  194. 'compress' => (float) 1,
  195. 'gzip' => 0.12345,
  196. 'blowfish' => (float) 1
  197. ]
  198. ],
  199. [
  200. NULL,
  201. [
  202. '*' => (float) 1
  203. ]
  204. ],
  205. [
  206. '',
  207. [
  208. 'identity' => (float) 1
  209. ]
  210. ]
  211. ];
  212. }
  213. /**
  214. * Tests the `parse_encoding_header` method parses the Accept-Encoding header
  215. * correctly
  216. *
  217. * @dataProvider provider_parse_encoding_header
  218. *
  219. * @param string $accept accept
  220. * @param array $expected expected
  221. * @return void
  222. */
  223. public function test_parse_encoding_header($accept, array $expected)
  224. {
  225. $this->assertSame($expected, HTTP_Header::parse_encoding_header($accept));
  226. }
  227. /**
  228. * Provides data for test_parse_charset_header
  229. *
  230. * @return array
  231. */
  232. public function provider_parse_language_header()
  233. {
  234. return [
  235. [
  236. 'en, en-us, en-gb, fr, fr-fr, es-es',
  237. [
  238. 'en' => [
  239. '*' => (float) 1,
  240. 'us' => (float) 1,
  241. 'gb' => (float) 1
  242. ],
  243. 'fr' => [
  244. '*' => (float) 1,
  245. 'fr' => (float) 1
  246. ],
  247. 'es' => [
  248. 'es' => (float) 1
  249. ]
  250. ]
  251. ],
  252. [
  253. 'en; q=.9, en-us, en-gb, fr; q=.5, fr-fr; q=0.4, es-es; q=0.9, en-gb-gb; q=.45',
  254. [
  255. 'en' => [
  256. '*' => 0.9,
  257. 'us' => (float) 1,
  258. 'gb' => (float) 1,
  259. 'gb-gb' => 0.45
  260. ],
  261. 'fr' => [
  262. '*' => 0.5,
  263. 'fr' => 0.4
  264. ],
  265. 'es' => [
  266. 'es' => 0.9
  267. ]
  268. ]
  269. ],
  270. [
  271. NULL,
  272. [
  273. '*' => [
  274. '*' => (float) 1
  275. ]
  276. ]
  277. ]
  278. ];
  279. }
  280. /**
  281. * Tests the `parse_language_header` method parses the Accept-Language header
  282. * correctly
  283. *
  284. * @dataProvider provider_parse_language_header
  285. *
  286. * @param string $accept accept
  287. * @param array $expected expected
  288. * @return void
  289. */
  290. public function test_parse_language_header($accept, array $expected)
  291. {
  292. $this->assertSame($expected, HTTP_Header::parse_language_header($accept));
  293. }
  294. /**
  295. * Data provider for test_create_cache_control
  296. *
  297. * @return array
  298. */
  299. public function provider_create_cache_control()
  300. {
  301. return [
  302. [
  303. [
  304. 'public',
  305. 'max-age' => 1800,
  306. 'must-revalidate',
  307. 's-max-age' => 3600
  308. ],
  309. 'public, max-age=1800, must-revalidate, s-max-age=3600'
  310. ],
  311. [
  312. [
  313. 'max-age' => 1800,
  314. 's-max-age' => 1800,
  315. 'public',
  316. 'must-revalidate',
  317. ],
  318. 'max-age=1800, s-max-age=1800, public, must-revalidate'
  319. ],
  320. [
  321. [
  322. 'private',
  323. 'no-cache',
  324. 'max-age' => 0,
  325. 'must-revalidate'
  326. ],
  327. 'private, no-cache, max-age=0, must-revalidate'
  328. ]
  329. ];
  330. }
  331. /**
  332. * Tests that `create_cache_control()` outputs the correct cache control
  333. * string from the supplied input
  334. *
  335. * @dataProvider provider_create_cache_control
  336. *
  337. * @param array $input input
  338. * @param string $expected expected
  339. * @return void
  340. */
  341. public function test_create_cache_control(array $input, $expected)
  342. {
  343. $this->assertSame($expected, HTTP_Header::create_cache_control($input));
  344. }
  345. /**
  346. * Data provider for parse_cache_control
  347. *
  348. * @return array
  349. */
  350. public function provider_parse_cache_control()
  351. {
  352. return [
  353. [
  354. 'public, max-age=1800, must-revalidate, s-max-age=3600',
  355. [
  356. 'public',
  357. 'max-age' => 1800,
  358. 'must-revalidate',
  359. 's-max-age' => 3600
  360. ]
  361. ],
  362. [
  363. 'max-age=1800, s-max-age=1800, public, must-revalidate',
  364. [
  365. 'max-age' => 1800,
  366. 's-max-age' => 1800,
  367. 'public',
  368. 'must-revalidate',
  369. ]
  370. ],
  371. [
  372. 'private, no-cache, max-age=0, must-revalidate',
  373. [
  374. 'private',
  375. 'no-cache',
  376. 'max-age' => 0,
  377. 'must-revalidate'
  378. ]
  379. ]
  380. ];
  381. }
  382. /**
  383. * Tests that `parse_cache_control()` outputs the correct cache control
  384. * parsed data from the input string
  385. *
  386. * @dataProvider provider_parse_cache_control
  387. *
  388. * @param string $input input
  389. * @param array $expected expected
  390. * @return void
  391. */
  392. public function test_parse_cache_control($input, array $expected)
  393. {
  394. $parsed = HTTP_Header::parse_cache_control($input);
  395. $this->assertIsArray($parsed);
  396. foreach ($expected as $key => $value)
  397. {
  398. if (is_int($key))
  399. {
  400. $this->assertTrue(in_array($value, $parsed));
  401. }
  402. else
  403. {
  404. $this->assertTrue(array_key_exists($key, $parsed));
  405. $this->assertSame($value, $parsed[$key]);
  406. }
  407. }
  408. }
  409. /**
  410. * Data provider for test_offsetSet
  411. *
  412. * @return array
  413. */
  414. // @codingStandardsIgnoreStart
  415. public function provider_offsetSet()
  416. // @codingStandardsIgnoreEnd
  417. {
  418. return [
  419. [
  420. [
  421. 'Content-Type' => 'application/x-www-form-urlencoded',
  422. 'Accept' => 'text/html, text/plain; q=.1, */*',
  423. 'Accept-Language' => 'en-gb, en-us, en; q=.1'
  424. ],
  425. [
  426. [
  427. 'Accept-Encoding',
  428. 'compress, gzip',
  429. FALSE
  430. ]
  431. ],
  432. [
  433. 'content-type' => 'application/x-www-form-urlencoded',
  434. 'accept' => 'text/html, text/plain; q=.1, */*',
  435. 'accept-language' => 'en-gb, en-us, en; q=.1',
  436. 'accept-encoding' => 'compress, gzip'
  437. ]
  438. ],
  439. [
  440. [
  441. 'Content-Type' => 'application/x-www-form-urlencoded',
  442. 'Accept' => 'text/html, text/plain; q=.1, */*',
  443. 'Accept-Language' => 'en-gb, en-us, en; q=.1'
  444. ],
  445. [
  446. [
  447. 'Accept-Encoding',
  448. 'compress, gzip',
  449. FALSE
  450. ],
  451. [
  452. 'Accept-Encoding',
  453. 'bzip',
  454. FALSE
  455. ]
  456. ],
  457. [
  458. 'content-type' => 'application/x-www-form-urlencoded',
  459. 'accept' => 'text/html, text/plain; q=.1, */*',
  460. 'accept-language' => 'en-gb, en-us, en; q=.1',
  461. 'accept-encoding' => [
  462. 'compress, gzip',
  463. 'bzip'
  464. ]
  465. ]
  466. ],
  467. [
  468. [
  469. 'Content-Type' => 'application/x-www-form-urlencoded',
  470. 'Accept' => 'text/html, text/plain; q=.1, */*',
  471. 'Accept-Language' => 'en-gb, en-us, en; q=.1'
  472. ],
  473. [
  474. [
  475. 'Accept-Encoding',
  476. 'compress, gzip',
  477. FALSE
  478. ],
  479. [
  480. 'Accept-Encoding',
  481. 'bzip',
  482. TRUE
  483. ],
  484. [
  485. 'Accept',
  486. 'text/*',
  487. FALSE
  488. ]
  489. ],
  490. [
  491. 'content-type' => 'application/x-www-form-urlencoded',
  492. 'accept' => [
  493. 'text/html, text/plain; q=.1, */*',
  494. 'text/*'
  495. ],
  496. 'accept-language' => 'en-gb, en-us, en; q=.1',
  497. 'accept-encoding' => 'bzip'
  498. ]
  499. ],
  500. ];
  501. }
  502. /**
  503. * Ensures that offsetSet normalizes the array keys
  504. *
  505. * @dataProvider provider_offsetSet
  506. *
  507. * @param array $constructor constructor
  508. * @param array $to_set to_set
  509. * @param array $expected expected
  510. * @return void
  511. */
  512. // @codingStandardsIgnoreStart
  513. public function test_offsetSet(array $constructor, array $to_set, array $expected)
  514. // @codingStandardsIgnoreEnd
  515. {
  516. $http_header = new HTTP_Header($constructor);
  517. $reflection = new ReflectionClass($http_header);
  518. $method = $reflection->getMethod('offsetSet');
  519. foreach ($to_set as $args)
  520. {
  521. $method->invokeArgs($http_header, $args);
  522. }
  523. $this->assertSame($expected, $http_header->getArrayCopy());
  524. }
  525. /**
  526. * Data provider for test_offsetGet
  527. *
  528. * @return array
  529. */
  530. // @codingStandardsIgnoreStart
  531. public function provider_offsetGet()
  532. // @codingStandardsIgnoreEnd
  533. {
  534. return [
  535. [
  536. [
  537. 'FoO' => 'bar',
  538. 'START' => 'end',
  539. 'true' => TRUE
  540. ],
  541. 'FOO',
  542. 'bar'
  543. ],
  544. [
  545. [
  546. 'FoO' => 'bar',
  547. 'START' => 'end',
  548. 'true' => TRUE
  549. ],
  550. 'true',
  551. TRUE
  552. ],
  553. [
  554. [
  555. 'FoO' => 'bar',
  556. 'START' => 'end',
  557. 'true' => TRUE
  558. ],
  559. 'True',
  560. TRUE
  561. ],
  562. [
  563. [
  564. 'FoO' => 'bar',
  565. 'START' => 'end',
  566. 'true' => TRUE
  567. ],
  568. 'Start',
  569. 'end'
  570. ],
  571. [
  572. [
  573. 'content-type' => 'bar',
  574. 'Content-Type' => 'end',
  575. 'Accept' => '*/*'
  576. ],
  577. 'content-type',
  578. 'end'
  579. ]
  580. ];
  581. }
  582. /**
  583. * Ensures that offsetGet normalizes the array keys
  584. *
  585. * @dataProvider provider_offsetGet
  586. *
  587. * @param array start state
  588. * @param string key to retrieve
  589. * @param mixed expected
  590. * @return void
  591. */
  592. // @codingStandardsIgnoreStart
  593. public function test_offsetGet(array $state, $key, $expected)
  594. // @codingStandardsIgnoreEnd
  595. {
  596. $header = new HTTP_Header($state);
  597. $this->assertSame($expected, $header->offsetGet($key));
  598. }
  599. /**
  600. * Data provider for test_offsetExists
  601. *
  602. * @return array
  603. */
  604. // @codingStandardsIgnoreStart
  605. public function provider_offsetExists()
  606. // @codingStandardsIgnoreEnd
  607. {
  608. return [
  609. [
  610. [
  611. 'Accept' => 'text/html, application/json',
  612. 'Accept-Language' => 'en, en-GB',
  613. 'Content-Type' => 'application/x-www-form-urlencoded'
  614. ],
  615. 'Content-Type',
  616. TRUE
  617. ],
  618. [
  619. [
  620. 'Accept' => 'text/html, application/json',
  621. 'Accept-Language' => 'en, en-GB',
  622. 'Content-Type' => 'application/x-www-form-urlencoded'
  623. ],
  624. 'CONTENT-TYPE',
  625. TRUE
  626. ],
  627. [
  628. [
  629. 'Accept' => 'text/html, application/json',
  630. 'Accept-Language' => 'en, en-GB',
  631. 'Content-Type' => 'application/x-www-form-urlencoded'
  632. ],
  633. 'accept-language',
  634. TRUE
  635. ],
  636. [
  637. [
  638. 'Accept' => 'text/html, application/json',
  639. 'Accept-Language' => 'en, en-GB',
  640. 'Content-Type' => 'application/x-www-form-urlencoded'
  641. ],
  642. 'x-powered-by',
  643. FALSE
  644. ]
  645. ];
  646. }
  647. /**
  648. * Ensures that offsetExists normalizes the array key
  649. *
  650. * @dataProvider provider_offsetExists
  651. *
  652. * @param array $state state
  653. * @param string $key key
  654. * @param boolean $expected expected
  655. * @return void
  656. */
  657. // @codingStandardsIgnoreStart
  658. public function test_offsetExists(array $state, $key, $expected)
  659. // @codingStandardsIgnoreEnd
  660. {
  661. $header = new HTTP_Header($state);
  662. $this->assertSame($expected, $header->offsetExists($key));
  663. }
  664. /**
  665. * Data provider for test_offsetUnset
  666. *
  667. * @return array
  668. */
  669. // @codingStandardsIgnoreStart
  670. public function provider_offsetUnset()
  671. // @codingStandardsIgnoreEnd
  672. {
  673. return [
  674. [
  675. [
  676. 'Accept' => 'text/html, application/json',
  677. 'Accept-Language' => 'en, en-GB',
  678. 'Content-Type' => 'application/x-www-form-urlencoded'
  679. ],
  680. 'Accept-Language',
  681. [
  682. 'accept' => 'text/html, application/json',
  683. 'content-type' => 'application/x-www-form-urlencoded'
  684. ]
  685. ],
  686. [
  687. [
  688. 'Accept' => 'text/html, application/json',
  689. 'Accept-Language' => 'en, en-GB',
  690. 'Content-Type' => 'application/x-www-form-urlencoded'
  691. ],
  692. 'ACCEPT',
  693. [
  694. 'accept-language' => 'en, en-GB',
  695. 'content-type' => 'application/x-www-form-urlencoded'
  696. ]
  697. ],
  698. [
  699. [
  700. 'Accept' => 'text/html, application/json',
  701. 'Accept-Language' => 'en, en-GB',
  702. 'Content-Type' => 'application/x-www-form-urlencoded'
  703. ],
  704. 'content-type',
  705. [
  706. 'accept' => 'text/html, application/json',
  707. 'accept-language' => 'en, en-GB',
  708. ]
  709. ]
  710. ];
  711. }
  712. /**
  713. * Tests that `offsetUnset` normalizes the key names properly
  714. *
  715. * @dataProvider provider_offsetUnset
  716. *
  717. * @param array $state state
  718. * @param string $remove remove
  719. * @param array $expected expected
  720. * @return void
  721. */
  722. // @codingStandardsIgnoreStart
  723. public function test_offsetUnset(array $state, $remove, array $expected)
  724. // @codingStandardsIgnoreEnd
  725. {
  726. $header = new HTTP_Header($state);
  727. $header->offsetUnset($remove);
  728. $this->assertSame($expected, $header->getArrayCopy());
  729. }
  730. /**
  731. * Provides data for test_parse_header_string
  732. *
  733. * @return array
  734. */
  735. public function provider_parse_header_string()
  736. {
  737. return [
  738. [
  739. [
  740. "Content-Type: application/x-www-form-urlencoded\r\n",
  741. "Accept: text/html, text/plain; q=.5, application/json, */* \r\n",
  742. "X-Powered-By: KO7 Baby \r\n"
  743. ],
  744. [
  745. 'content-type' => 'application/x-www-form-urlencoded',
  746. 'accept' => 'text/html, text/plain; q=.5, application/json, */* ',
  747. 'x-powered-by' => 'KO7 Baby '
  748. ]
  749. ],
  750. [
  751. [
  752. "Content-Type: application/x-www-form-urlencoded\r\n",
  753. "Accept: text/html, text/plain; q=.5, application/json, */* \r\n",
  754. "X-Powered-By: KO7 Baby \r\n",
  755. "Content-Type: application/json\r\n"
  756. ],
  757. [
  758. 'content-type' => [
  759. 'application/x-www-form-urlencoded',
  760. 'application/json'
  761. ],
  762. 'accept' => 'text/html, text/plain; q=.5, application/json, */* ',
  763. 'x-powered-by' => 'KO7 Baby '
  764. ]
  765. ]
  766. ];
  767. }
  768. /**
  769. * Tests that `parse_header_string` performs as expected
  770. *
  771. * @dataProvider provider_parse_header_string
  772. *
  773. * @param array headers
  774. * @param array expected
  775. * @return void
  776. */
  777. public function test_parse_header_string(array $headers, array $expected)
  778. {
  779. $http_header = new HTTP_Header([]);
  780. foreach ($headers as $header)
  781. {
  782. $this->assertEquals(strlen($header), $http_header->parse_header_string(NULL, $header));
  783. }
  784. $this->assertSame($expected, $http_header->getArrayCopy());
  785. }
  786. /**
  787. * Data Provider for test_accepts_at_quality
  788. *
  789. * @return array
  790. */
  791. public function provider_accepts_at_quality()
  792. {
  793. return [
  794. [
  795. [
  796. 'Accept' => 'application/json, text/html; q=.5, text/*; q=.1, */*'
  797. ],
  798. 'application/json',
  799. FALSE,
  800. 1.0
  801. ],
  802. [
  803. [
  804. 'Accept' => 'application/json, text/html; q=.5, text/*; q=.1, */*'
  805. ],
  806. 'text/html',
  807. FALSE,
  808. 0.5
  809. ],
  810. [
  811. [
  812. 'Accept' => 'application/json, text/html; q=.5, text/*; q=.1, */*'
  813. ],
  814. 'text/plain',
  815. FALSE,
  816. 0.1
  817. ],
  818. [
  819. [
  820. 'Accept' => 'application/json, text/html; q=.5, text/*; q=.1, */*'
  821. ],
  822. 'text/plain',
  823. TRUE,
  824. FALSE
  825. ],
  826. [
  827. [
  828. 'Accept' => 'application/json, text/html; q=.5, text/*; q=.1, */*'
  829. ],
  830. 'application/xml',
  831. FALSE,
  832. 1.0
  833. ],
  834. [
  835. [
  836. 'Accept' => 'application/json, text/html; q=.5, text/*; q=.1, */*'
  837. ],
  838. 'application/xml',
  839. TRUE,
  840. FALSE
  841. ],
  842. [
  843. [],
  844. 'application/xml',
  845. FALSE,
  846. 1.0
  847. ],
  848. [
  849. [],
  850. 'application/xml',
  851. TRUE,
  852. FALSE
  853. ]
  854. ];
  855. }
  856. /**
  857. * Tests `accepts_at_quality` parsed the Accept: header as expected
  858. *
  859. * @dataProvider provider_accepts_at_quality
  860. *
  861. * @param array starting state
  862. * @param string accept header to test
  863. * @param boolean explicitly check
  864. * @param mixed expected output
  865. * @return void
  866. */
  867. public function test_accepts_at_quality(array $state, $accept, $explicit, $expected)
  868. {
  869. $header = new HTTP_Header($state);
  870. $this->assertSame($expected, $header->accepts_at_quality($accept, $explicit));
  871. }
  872. /**
  873. * Data provider for test_preferred_accept
  874. *
  875. * @return array
  876. */
  877. public function provider_preferred_accept()
  878. {
  879. return [
  880. [
  881. [
  882. 'Accept' => 'application/json, text/html; q=.5, text/*; q=.1, */*'
  883. ],
  884. [
  885. 'text/html',
  886. 'application/json',
  887. 'text/plain'
  888. ],
  889. FALSE,
  890. 'application/json'
  891. ],
  892. [
  893. [
  894. 'Accept' => 'application/json, text/html; q=.5, text/*; q=.1, */*'
  895. ],
  896. [
  897. 'text/plain',
  898. 'application/xml',
  899. 'image/jpeg'
  900. ],
  901. FALSE,
  902. 'application/xml'
  903. ],
  904. [
  905. [
  906. 'Accept' => 'application/json, text/html; q=.5, text/*; q=.1'
  907. ],
  908. [
  909. 'text/plain',
  910. 'application/xml',
  911. 'image/jpeg'
  912. ],
  913. FALSE,
  914. 'text/plain'
  915. ],
  916. [
  917. [
  918. 'Accept' => 'application/json, text/html; q=.5, text/*; q=.1, */*'
  919. ],
  920. [
  921. 'text/plain',
  922. 'application/xml',
  923. 'image/jpeg'
  924. ],
  925. TRUE,
  926. FALSE
  927. ],
  928. ];
  929. }
  930. /**
  931. * Tests `preferred_accept` returns the correct preferred type
  932. *
  933. * @dataProvider provider_preferred_accept
  934. *
  935. * @param array state
  936. * @param array accepts
  937. * @param string explicit
  938. * @param string expected
  939. * @return void
  940. */
  941. public function test_preferred_accept(array $state, array $accepts, $explicit, $expected)
  942. {
  943. $header = new HTTP_Header($state);
  944. $this->assertSame($expected, $header->preferred_accept($accepts, $explicit));
  945. }
  946. /**
  947. * Data provider for test_accepts_charset_at_quality
  948. *
  949. * @return array
  950. */
  951. public function provider_accepts_charset_at_quality()
  952. {
  953. return [
  954. [
  955. [
  956. 'Accept-Charset' => 'utf-8, utf-10, utf-16, iso-8859-1'
  957. ],
  958. 'utf-8',
  959. 1.0
  960. ],
  961. [
  962. [
  963. 'Accept-Charset' => 'utf-8, utf-10, utf-16, iso-8859-1'
  964. ],
  965. 'utf-16',
  966. 1.0
  967. ],
  968. [
  969. [
  970. 'Accept-Charset' => 'utf-8; q=.1, utf-10, utf-16; q=.2, iso-8859-1'
  971. ],
  972. 'utf-8',
  973. 0.1
  974. ],
  975. [
  976. [
  977. 'Accept-Charset' => 'utf-8; q=.1, utf-10, utf-16; q=.2, iso-8859-1; q=.5'
  978. ],
  979. 'iso-8859-1',
  980. 0.5
  981. ]
  982. ];
  983. }
  984. /**
  985. * Tests `accepts_charset_at_quality` works as expected, returning the correct
  986. * quality value
  987. *
  988. * @dataProvider provider_accepts_charset_at_quality
  989. *
  990. * @param array state
  991. * @param string charset
  992. * @param string expected
  993. * @return void
  994. */
  995. public function test_accepts_charset_at_quality(array $state, $charset, $expected)
  996. {
  997. $header = new HTTP_Header($state);
  998. $this->assertSame($expected, $header->accepts_charset_at_quality($charset));
  999. }
  1000. /**
  1001. * Data provider for test_preferred_charset
  1002. *
  1003. * @return array
  1004. */
  1005. public function provider_preferred_charset()
  1006. {
  1007. return [
  1008. [
  1009. [
  1010. 'Accept-Charset' => 'utf-8, utf-10, utf-16, iso-8859-1'
  1011. ],
  1012. [
  1013. 'utf-8',
  1014. 'utf-16'
  1015. ],
  1016. 'utf-8'
  1017. ],
  1018. [
  1019. [
  1020. 'Accept-Charset' => 'utf-8, utf-10, utf-16, iso-8859-1'
  1021. ],
  1022. [
  1023. 'UTF-10'
  1024. ],
  1025. 'UTF-10'
  1026. ],
  1027. ];
  1028. }
  1029. /**
  1030. * Tests `preferred_charset` works as expected, returning the correct charset
  1031. * from the list supplied
  1032. *
  1033. * @dataProvider provider_preferred_charset
  1034. *
  1035. * @param array state
  1036. * @param array charsets
  1037. * @param string expected
  1038. * @return void
  1039. */
  1040. public function test_preferred_charset(array $state, array $charsets, $expected)
  1041. {
  1042. $header = new HTTP_Header($state);
  1043. $this->assertSame($expected, $header->preferred_charset($charsets));
  1044. }
  1045. /**
  1046. * Data provider for test_accepts_encoding_at_quality
  1047. *
  1048. * @return array
  1049. */
  1050. public function provider_accepts_encoding_at_quality()
  1051. {
  1052. return [
  1053. [
  1054. [
  1055. 'accept-encoding' => 'compress, gzip, blowfish; q=.7, *; q=.5'
  1056. ],
  1057. 'gzip',
  1058. FALSE,
  1059. 1.0
  1060. ],
  1061. [
  1062. [
  1063. 'accept-encoding' => 'compress, gzip, blowfish; q=.7, *; q=.5'
  1064. ],
  1065. 'gzip',
  1066. TRUE,
  1067. 1.0
  1068. ],
  1069. [
  1070. [
  1071. 'accept-encoding' => 'compress, gzip, blowfish; q=.7, *; q=.5'
  1072. ],
  1073. 'blowfish',
  1074. FALSE,
  1075. 0.7
  1076. ],
  1077. [
  1078. [
  1079. 'accept-encoding' => 'compress, gzip, blowfish; q=.7, *; q=.5'
  1080. ],
  1081. 'bzip',
  1082. FALSE,
  1083. 0.5
  1084. ],
  1085. [
  1086. [
  1087. 'accept-encoding' => 'compress, gzip, blowfish; q=.7, *; q=.5'
  1088. ],
  1089. 'bzip',
  1090. TRUE,
  1091. (float) 0
  1092. ]
  1093. ];
  1094. }
  1095. /**
  1096. * Tests `accepts_encoding_at_quality` parses and returns the correct
  1097. * quality value for Accept-Encoding headers
  1098. *
  1099. * @dataProvider provider_accepts_encoding_at_quality
  1100. *
  1101. * @param array state
  1102. * @param string encoding
  1103. * @param boolean explicit
  1104. * @param float expected
  1105. * @return void
  1106. */
  1107. public function test_accepts_encoding_at_quality(array $state, $encoding, $explicit, $expected)
  1108. {
  1109. $header = new HTTP_Header($state);
  1110. $this->assertSame($expected, $header->accepts_encoding_at_quality($encoding, $explicit));
  1111. }
  1112. /**
  1113. * Data provider for test_preferred_encoding
  1114. *
  1115. * @return array
  1116. */
  1117. public function provider_preferred_encoding()
  1118. {
  1119. return [
  1120. [
  1121. [
  1122. 'accept-encoding' => 'compress, gzip, blowfish; q=.7, *; q=.5'
  1123. ],
  1124. ['gzip', 'blowfish', 'bzip'],
  1125. FALSE,
  1126. 'gzip'
  1127. ],
  1128. [
  1129. [
  1130. 'accept-encoding' => 'compress, gzip, blowfish; q=.7, *; q=.5'
  1131. ],
  1132. ['bzip', 'ROT-13'],
  1133. FALSE,
  1134. 'bzip'
  1135. ],
  1136. [
  1137. [
  1138. 'accept-encoding' => 'compress, gzip, blowfish; q=.7, *; q=.5'
  1139. ],
  1140. ['bzip', 'ROT-13'],
  1141. TRUE,
  1142. FALSE
  1143. ],
  1144. [
  1145. [
  1146. 'accept-encoding' => 'compress, gzip, blowfish; q=.2, *; q=.5'
  1147. ],
  1148. ['ROT-13', 'blowfish'],
  1149. FALSE,
  1150. 'ROT-13'
  1151. ],
  1152. ];
  1153. }
  1154. /**
  1155. * Tests that `preferred_encoding` parses and returns the correct
  1156. * encoding type
  1157. *
  1158. * @dataProvider provider_preferred_encoding
  1159. *
  1160. * @param array state in
  1161. * @param array encodings to interrogate
  1162. * @param boolean explicit check
  1163. * @param string expected output
  1164. * @return void
  1165. */
  1166. public function test_preferred_encoding(array $state, array $encodings, $explicit, $expected)
  1167. {
  1168. $header = new HTTP_Header($state);
  1169. $this->assertSame($expected, $header->preferred_encoding($encodings, $explicit));
  1170. }
  1171. /**
  1172. * Data provider for test_accepts_language_at_quality
  1173. *
  1174. * @return array
  1175. */
  1176. public function provider_accepts_language_at_quality()
  1177. {
  1178. return [
  1179. [
  1180. [
  1181. 'accept-language' => 'en-us; q=.9, en-gb; q=.7, en; q=.5, fr-fr; q=.9, fr; q=.8'
  1182. ],
  1183. 'en',
  1184. FALSE,
  1185. 0.5
  1186. ],
  1187. [
  1188. [
  1189. 'accept-language' => 'en-us; q=.9, en-gb; q=.7, en; q=.5, fr-fr; q=.9, fr; q=.8'
  1190. ],
  1191. 'en-gb',
  1192. FALSE,
  1193. 0.7
  1194. ],
  1195. [
  1196. [
  1197. 'accept-language' => 'en-us; q=.9, en-gb; q=.7, en; q=.5, fr-fr; q=.9, fr; q=.8'
  1198. ],
  1199. 'en',
  1200. TRUE,
  1201. 0.5
  1202. ],
  1203. [
  1204. [
  1205. 'accept-language' => 'en-us; q=.9, en-gb; q=.7, en; q=.5, fr-fr; q=.9, fr; q=.8'
  1206. ],
  1207. 'fr-ni',
  1208. FALSE,
  1209. 0.8
  1210. ],
  1211. [
  1212. [
  1213. 'accept-language' => 'en-us; q=.9, en-gb; q=.7, en; q=.5, fr-fr; q=.9, fr; q=.8'
  1214. ],
  1215. 'fr-ni',
  1216. TRUE,
  1217. (float) 0
  1218. ],
  1219. [
  1220. [
  1221. 'accept-language' => 'en-US'
  1222. ],
  1223. 'en-us',
  1224. TRUE,
  1225. (float) 1
  1226. ],
  1227. ];
  1228. }
  1229. /**
  1230. * Tests `accepts_language_at_quality` parses the Accept-Language header
  1231. * correctly and identifies the correct quality supplied, explicit or not
  1232. *
  1233. * @dataProvider provider_accepts_language_at_quality
  1234. *
  1235. * @param array state in
  1236. * @param string language to interrogate
  1237. * @param boolean explicit check
  1238. * @param float expected output
  1239. * @return void
  1240. */
  1241. public function test_accepts_language_at_quality(array $state, $language, $explicit, $expected)
  1242. {
  1243. $header = new HTTP_Header($state);
  1244. $this->assertSame($expected, $header->accepts_language_at_quality($language, $explicit));
  1245. }
  1246. /**
  1247. * Data provider for test_preferred_language
  1248. *
  1249. * @return array
  1250. */
  1251. public function provider_preferred_language()
  1252. {
  1253. return [
  1254. [
  1255. [
  1256. 'accept-language' => 'en-us; q=.9, en-gb; q=.7, en; q=.5, fr-fr; q=.9, fr; q=.8'
  1257. ],
  1258. [
  1259. 'en',
  1260. 'fr',
  1261. 'en-gb'
  1262. ],
  1263. FALSE,
  1264. 'fr'
  1265. ],
  1266. [
  1267. [
  1268. 'accept-language' => 'en-us; q=.9, en-gb; q=.7, en; q=.5, fr-fr; q=.9, fr; q=.8'
  1269. ],
  1270. [
  1271. 'en',
  1272. 'fr',
  1273. 'en-gb'
  1274. ],
  1275. TRUE,
  1276. 'fr'
  1277. ],
  1278. [
  1279. [
  1280. 'accept-language' => 'en-us; q=.9, en-gb; q=.7, en; q=.5, fr-fr; q=.9, fr; q=.8'
  1281. ],
  1282. [
  1283. 'en-au',
  1284. 'fr-ni',
  1285. 'fr'
  1286. ],
  1287. FALSE,
  1288. 'fr-ni'
  1289. ],
  1290. [
  1291. [
  1292. 'accept-language' => 'en-us; q=.9, en-gb; q=.7, en; q=.5, fr-fr; q=.9, fr; q=.8'
  1293. ],
  1294. [
  1295. 'en-au',
  1296. 'fr-ni',
  1297. 'fr'
  1298. ],
  1299. TRUE,
  1300. 'fr'
  1301. ],
  1302. [
  1303. [
  1304. 'accept-language' => 'en-US'
  1305. ],
  1306. [
  1307. 'en-us'
  1308. ],
  1309. TRUE,
  1310. 'en-us'
  1311. ],
  1312. [
  1313. [
  1314. 'accept-language' => 'fr,en-US,en'
  1315. ],
  1316. [
  1317. 'en-us',
  1318. 'fr-fr'
  1319. ],
  1320. FALSE,
  1321. 'fr-fr'
  1322. ],
  1323. [
  1324. [
  1325. 'accept-language' => 'fr,en-US,en'
  1326. ],
  1327. [
  1328. 'fr-fr',
  1329. 'en-us'
  1330. ],
  1331. FALSE,
  1332. 'fr-fr'
  1333. ],
  1334. [
  1335. [
  1336. 'accept-language' => 'fr,en,en-US'
  1337. ],
  1338. [
  1339. 'en-us',
  1340. 'fr-fr'
  1341. ],
  1342. TRUE,
  1343. 'en-us'
  1344. ],
  1345. [
  1346. [
  1347. 'accept-language' => 'fr,en,en-US'
  1348. ],
  1349. [
  1350. 'fr-fr',
  1351. 'en-us'
  1352. ],
  1353. TRUE,
  1354. 'en-us'
  1355. ],
  1356. ];
  1357. }
  1358. /**
  1359. * Tests that `preferred_language` correctly identifies the right
  1360. * language based on the Accept-Language header and `$explicit` setting
  1361. *
  1362. * @dataProvider provider_preferred_language
  1363. *
  1364. * @param array state in
  1365. * @param array languages to interrogate
  1366. * @param boolean explicit check
  1367. * @param string expected output
  1368. * @return void
  1369. */
  1370. public function test_preferred_language(array $state, array $languages, $explicit, $expected)
  1371. {
  1372. $header = new HTTP_Header($state);
  1373. $this->assertSame($expected, $header->preferred_language($languages, $explicit));
  1374. }
  1375. /**
  1376. * Data provider for test_send_headers
  1377. *
  1378. * @return array
  1379. */
  1380. public function provider_send_headers()
  1381. {
  1382. $content_type = KO7::$content_type.'; charset='.KO7::$charset;
  1383. return [
  1384. [
  1385. [],
  1386. [
  1387. 'HTTP/1.1 200 OK',
  1388. 'Content-Type: '.$content_type,
  1389. ],
  1390. FALSE,
  1391. ],
  1392. [
  1393. [],
  1394. [
  1395. 'HTTP/1.1 200 OK',
  1396. 'Content-Type: '.$content_type,
  1397. 'X-Powered-By: '.KO7::version(),
  1398. ],
  1399. TRUE,
  1400. ],
  1401. [
  1402. [
  1403. 'accept' => 'text/html, text/plain, text/*, */*',
  1404. 'accept-charset' => 'utf-8, utf-10, iso-8859-1',
  1405. 'accept-encoding' => 'compress, gzip',
  1406. 'accept-language' => 'en, en-gb, en-us'
  1407. ],
  1408. [
  1409. 'HTTP/1.1 200 OK',
  1410. 'Accept: text/html, text/plain, text/*, */*',
  1411. 'Accept-Charset: utf-8, utf-10, iso-8859-1',
  1412. 'Accept-Encoding: compress, gzip',
  1413. 'Accept-Language: en, en-gb, en-us',
  1414. 'Content-Type: '.$content_type,
  1415. ],
  1416. FALSE
  1417. ],
  1418. [
  1419. [
  1420. 'accept' => 'text/html, text/plain, text/*, */*',
  1421. 'accept-charset' => 'utf-8, utf-10, iso-8859-1',
  1422. 'accept-encoding' => 'compress, gzip',
  1423. 'accept-language' => 'en, en-gb, en-us',
  1424. 'content-type' => 'application/json',
  1425. 'x-powered-by' => 'Mohana',
  1426. 'x-ssl-enabled' => 'TRUE'
  1427. ],
  1428. [
  1429. 'HTTP/1.1 200 OK',
  1430. 'Accept: text/html, text/plain, text/*, */*',
  1431. 'Accept-Charset: utf-8, utf-10, iso-8859-1',
  1432. 'Accept-Encoding: compress, gzip',
  1433. 'Accept-Language: en, en-gb, en-us',
  1434. 'Content-Type: application/json',
  1435. 'X-Powered-By: Mohana',
  1436. 'X-Ssl-Enabled: TRUE'
  1437. ],
  1438. TRUE
  1439. ]
  1440. ];
  1441. }
  1442. /**
  1443. * Tests that send headers processes the headers sent to PHP correctly
  1444. *
  1445. * @dataProvider provider_send_headers
  1446. *
  1447. * @param array state in
  1448. * @param array expected out
  1449. * @return void
  1450. */
  1451. public function test_send_headers(array $state, array $expected, $expose)
  1452. {
  1453. KO7::$expose = $expose;
  1454. $response = new Response;
  1455. $response->headers($state);
  1456. $this->assertSame(
  1457. $expected,
  1458. $response->send_headers(FALSE, [$this, 'send_headers_handler'])
  1459. );
  1460. }
  1461. /**
  1462. * Callback handler for send headers
  1463. *
  1464. * @param array headers
  1465. * @param boolean replace
  1466. * @return array
  1467. */
  1468. public function send_headers_handler($response, $headers, $replace)
  1469. {
  1470. return $headers;
  1471. }
  1472. } // End KO7_HTTP_HeaderTest