HeaderTest.php 31 KB

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