rocket_cors/src/rocket_cors/lib.rs.html

5823 lines
375 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<!DOCTYPE html><html lang="en"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><meta name="generator" content="rustdoc"><meta name="description" content="Source to the Rust file `src/lib.rs`."><meta name="keywords" content="rust, rustlang, rust-lang"><title>lib.rs.html -- source</title><link rel="stylesheet" type="text/css" href="../../normalize.css"><link rel="stylesheet" type="text/css" href="../../rustdoc.css" id="mainThemeStyle"><link rel="stylesheet" type="text/css" href="../../dark.css"><link rel="stylesheet" type="text/css" href="../../light.css" id="themeStyle"><script src="../../storage.js"></script><noscript><link rel="stylesheet" href="../../noscript.css"></noscript><link rel="shortcut icon" href="../../favicon.ico"><style type="text/css">#crate-search{background-image:url("../../down-arrow.svg");}</style></head><body class="rustdoc source"><!--[if lte IE 8]><div class="warning">This old browser is unsupported and will most likely display funky things.</div><![endif]--><nav class="sidebar"><div class="sidebar-menu">&#9776;</div><a href='../../rocket_cors/index.html'><div class='logo-container'><img src='../../rust-logo.png' alt='logo'></div></a></nav><div class="theme-picker"><button id="theme-picker" aria-label="Pick another theme!"><img src="../../brush.svg" width="18" alt="Pick another theme!"></button><div id="theme-choices"></div></div><script src="../../theme.js"></script><nav class="sub"><form class="search-form js-only"><div class="search-container"><div><select id="crate-search"><option value="All crates">All crates</option></select><input class="search-input" name="search" autocomplete="off" spellcheck="false" placeholder="Click or press S to search, ? for more options…" type="search"></div><a id="settings-menu" href="../../settings.html"><img src="../../wheel.svg" width="18" alt="Change settings"></a></div></form></nav><section id="main" class="content"><pre class="line-numbers"><span id="1"> 1</span>
<span id="2"> 2</span>
<span id="3"> 3</span>
<span id="4"> 4</span>
<span id="5"> 5</span>
<span id="6"> 6</span>
<span id="7"> 7</span>
<span id="8"> 8</span>
<span id="9"> 9</span>
<span id="10"> 10</span>
<span id="11"> 11</span>
<span id="12"> 12</span>
<span id="13"> 13</span>
<span id="14"> 14</span>
<span id="15"> 15</span>
<span id="16"> 16</span>
<span id="17"> 17</span>
<span id="18"> 18</span>
<span id="19"> 19</span>
<span id="20"> 20</span>
<span id="21"> 21</span>
<span id="22"> 22</span>
<span id="23"> 23</span>
<span id="24"> 24</span>
<span id="25"> 25</span>
<span id="26"> 26</span>
<span id="27"> 27</span>
<span id="28"> 28</span>
<span id="29"> 29</span>
<span id="30"> 30</span>
<span id="31"> 31</span>
<span id="32"> 32</span>
<span id="33"> 33</span>
<span id="34"> 34</span>
<span id="35"> 35</span>
<span id="36"> 36</span>
<span id="37"> 37</span>
<span id="38"> 38</span>
<span id="39"> 39</span>
<span id="40"> 40</span>
<span id="41"> 41</span>
<span id="42"> 42</span>
<span id="43"> 43</span>
<span id="44"> 44</span>
<span id="45"> 45</span>
<span id="46"> 46</span>
<span id="47"> 47</span>
<span id="48"> 48</span>
<span id="49"> 49</span>
<span id="50"> 50</span>
<span id="51"> 51</span>
<span id="52"> 52</span>
<span id="53"> 53</span>
<span id="54"> 54</span>
<span id="55"> 55</span>
<span id="56"> 56</span>
<span id="57"> 57</span>
<span id="58"> 58</span>
<span id="59"> 59</span>
<span id="60"> 60</span>
<span id="61"> 61</span>
<span id="62"> 62</span>
<span id="63"> 63</span>
<span id="64"> 64</span>
<span id="65"> 65</span>
<span id="66"> 66</span>
<span id="67"> 67</span>
<span id="68"> 68</span>
<span id="69"> 69</span>
<span id="70"> 70</span>
<span id="71"> 71</span>
<span id="72"> 72</span>
<span id="73"> 73</span>
<span id="74"> 74</span>
<span id="75"> 75</span>
<span id="76"> 76</span>
<span id="77"> 77</span>
<span id="78"> 78</span>
<span id="79"> 79</span>
<span id="80"> 80</span>
<span id="81"> 81</span>
<span id="82"> 82</span>
<span id="83"> 83</span>
<span id="84"> 84</span>
<span id="85"> 85</span>
<span id="86"> 86</span>
<span id="87"> 87</span>
<span id="88"> 88</span>
<span id="89"> 89</span>
<span id="90"> 90</span>
<span id="91"> 91</span>
<span id="92"> 92</span>
<span id="93"> 93</span>
<span id="94"> 94</span>
<span id="95"> 95</span>
<span id="96"> 96</span>
<span id="97"> 97</span>
<span id="98"> 98</span>
<span id="99"> 99</span>
<span id="100"> 100</span>
<span id="101"> 101</span>
<span id="102"> 102</span>
<span id="103"> 103</span>
<span id="104"> 104</span>
<span id="105"> 105</span>
<span id="106"> 106</span>
<span id="107"> 107</span>
<span id="108"> 108</span>
<span id="109"> 109</span>
<span id="110"> 110</span>
<span id="111"> 111</span>
<span id="112"> 112</span>
<span id="113"> 113</span>
<span id="114"> 114</span>
<span id="115"> 115</span>
<span id="116"> 116</span>
<span id="117"> 117</span>
<span id="118"> 118</span>
<span id="119"> 119</span>
<span id="120"> 120</span>
<span id="121"> 121</span>
<span id="122"> 122</span>
<span id="123"> 123</span>
<span id="124"> 124</span>
<span id="125"> 125</span>
<span id="126"> 126</span>
<span id="127"> 127</span>
<span id="128"> 128</span>
<span id="129"> 129</span>
<span id="130"> 130</span>
<span id="131"> 131</span>
<span id="132"> 132</span>
<span id="133"> 133</span>
<span id="134"> 134</span>
<span id="135"> 135</span>
<span id="136"> 136</span>
<span id="137"> 137</span>
<span id="138"> 138</span>
<span id="139"> 139</span>
<span id="140"> 140</span>
<span id="141"> 141</span>
<span id="142"> 142</span>
<span id="143"> 143</span>
<span id="144"> 144</span>
<span id="145"> 145</span>
<span id="146"> 146</span>
<span id="147"> 147</span>
<span id="148"> 148</span>
<span id="149"> 149</span>
<span id="150"> 150</span>
<span id="151"> 151</span>
<span id="152"> 152</span>
<span id="153"> 153</span>
<span id="154"> 154</span>
<span id="155"> 155</span>
<span id="156"> 156</span>
<span id="157"> 157</span>
<span id="158"> 158</span>
<span id="159"> 159</span>
<span id="160"> 160</span>
<span id="161"> 161</span>
<span id="162"> 162</span>
<span id="163"> 163</span>
<span id="164"> 164</span>
<span id="165"> 165</span>
<span id="166"> 166</span>
<span id="167"> 167</span>
<span id="168"> 168</span>
<span id="169"> 169</span>
<span id="170"> 170</span>
<span id="171"> 171</span>
<span id="172"> 172</span>
<span id="173"> 173</span>
<span id="174"> 174</span>
<span id="175"> 175</span>
<span id="176"> 176</span>
<span id="177"> 177</span>
<span id="178"> 178</span>
<span id="179"> 179</span>
<span id="180"> 180</span>
<span id="181"> 181</span>
<span id="182"> 182</span>
<span id="183"> 183</span>
<span id="184"> 184</span>
<span id="185"> 185</span>
<span id="186"> 186</span>
<span id="187"> 187</span>
<span id="188"> 188</span>
<span id="189"> 189</span>
<span id="190"> 190</span>
<span id="191"> 191</span>
<span id="192"> 192</span>
<span id="193"> 193</span>
<span id="194"> 194</span>
<span id="195"> 195</span>
<span id="196"> 196</span>
<span id="197"> 197</span>
<span id="198"> 198</span>
<span id="199"> 199</span>
<span id="200"> 200</span>
<span id="201"> 201</span>
<span id="202"> 202</span>
<span id="203"> 203</span>
<span id="204"> 204</span>
<span id="205"> 205</span>
<span id="206"> 206</span>
<span id="207"> 207</span>
<span id="208"> 208</span>
<span id="209"> 209</span>
<span id="210"> 210</span>
<span id="211"> 211</span>
<span id="212"> 212</span>
<span id="213"> 213</span>
<span id="214"> 214</span>
<span id="215"> 215</span>
<span id="216"> 216</span>
<span id="217"> 217</span>
<span id="218"> 218</span>
<span id="219"> 219</span>
<span id="220"> 220</span>
<span id="221"> 221</span>
<span id="222"> 222</span>
<span id="223"> 223</span>
<span id="224"> 224</span>
<span id="225"> 225</span>
<span id="226"> 226</span>
<span id="227"> 227</span>
<span id="228"> 228</span>
<span id="229"> 229</span>
<span id="230"> 230</span>
<span id="231"> 231</span>
<span id="232"> 232</span>
<span id="233"> 233</span>
<span id="234"> 234</span>
<span id="235"> 235</span>
<span id="236"> 236</span>
<span id="237"> 237</span>
<span id="238"> 238</span>
<span id="239"> 239</span>
<span id="240"> 240</span>
<span id="241"> 241</span>
<span id="242"> 242</span>
<span id="243"> 243</span>
<span id="244"> 244</span>
<span id="245"> 245</span>
<span id="246"> 246</span>
<span id="247"> 247</span>
<span id="248"> 248</span>
<span id="249"> 249</span>
<span id="250"> 250</span>
<span id="251"> 251</span>
<span id="252"> 252</span>
<span id="253"> 253</span>
<span id="254"> 254</span>
<span id="255"> 255</span>
<span id="256"> 256</span>
<span id="257"> 257</span>
<span id="258"> 258</span>
<span id="259"> 259</span>
<span id="260"> 260</span>
<span id="261"> 261</span>
<span id="262"> 262</span>
<span id="263"> 263</span>
<span id="264"> 264</span>
<span id="265"> 265</span>
<span id="266"> 266</span>
<span id="267"> 267</span>
<span id="268"> 268</span>
<span id="269"> 269</span>
<span id="270"> 270</span>
<span id="271"> 271</span>
<span id="272"> 272</span>
<span id="273"> 273</span>
<span id="274"> 274</span>
<span id="275"> 275</span>
<span id="276"> 276</span>
<span id="277"> 277</span>
<span id="278"> 278</span>
<span id="279"> 279</span>
<span id="280"> 280</span>
<span id="281"> 281</span>
<span id="282"> 282</span>
<span id="283"> 283</span>
<span id="284"> 284</span>
<span id="285"> 285</span>
<span id="286"> 286</span>
<span id="287"> 287</span>
<span id="288"> 288</span>
<span id="289"> 289</span>
<span id="290"> 290</span>
<span id="291"> 291</span>
<span id="292"> 292</span>
<span id="293"> 293</span>
<span id="294"> 294</span>
<span id="295"> 295</span>
<span id="296"> 296</span>
<span id="297"> 297</span>
<span id="298"> 298</span>
<span id="299"> 299</span>
<span id="300"> 300</span>
<span id="301"> 301</span>
<span id="302"> 302</span>
<span id="303"> 303</span>
<span id="304"> 304</span>
<span id="305"> 305</span>
<span id="306"> 306</span>
<span id="307"> 307</span>
<span id="308"> 308</span>
<span id="309"> 309</span>
<span id="310"> 310</span>
<span id="311"> 311</span>
<span id="312"> 312</span>
<span id="313"> 313</span>
<span id="314"> 314</span>
<span id="315"> 315</span>
<span id="316"> 316</span>
<span id="317"> 317</span>
<span id="318"> 318</span>
<span id="319"> 319</span>
<span id="320"> 320</span>
<span id="321"> 321</span>
<span id="322"> 322</span>
<span id="323"> 323</span>
<span id="324"> 324</span>
<span id="325"> 325</span>
<span id="326"> 326</span>
<span id="327"> 327</span>
<span id="328"> 328</span>
<span id="329"> 329</span>
<span id="330"> 330</span>
<span id="331"> 331</span>
<span id="332"> 332</span>
<span id="333"> 333</span>
<span id="334"> 334</span>
<span id="335"> 335</span>
<span id="336"> 336</span>
<span id="337"> 337</span>
<span id="338"> 338</span>
<span id="339"> 339</span>
<span id="340"> 340</span>
<span id="341"> 341</span>
<span id="342"> 342</span>
<span id="343"> 343</span>
<span id="344"> 344</span>
<span id="345"> 345</span>
<span id="346"> 346</span>
<span id="347"> 347</span>
<span id="348"> 348</span>
<span id="349"> 349</span>
<span id="350"> 350</span>
<span id="351"> 351</span>
<span id="352"> 352</span>
<span id="353"> 353</span>
<span id="354"> 354</span>
<span id="355"> 355</span>
<span id="356"> 356</span>
<span id="357"> 357</span>
<span id="358"> 358</span>
<span id="359"> 359</span>
<span id="360"> 360</span>
<span id="361"> 361</span>
<span id="362"> 362</span>
<span id="363"> 363</span>
<span id="364"> 364</span>
<span id="365"> 365</span>
<span id="366"> 366</span>
<span id="367"> 367</span>
<span id="368"> 368</span>
<span id="369"> 369</span>
<span id="370"> 370</span>
<span id="371"> 371</span>
<span id="372"> 372</span>
<span id="373"> 373</span>
<span id="374"> 374</span>
<span id="375"> 375</span>
<span id="376"> 376</span>
<span id="377"> 377</span>
<span id="378"> 378</span>
<span id="379"> 379</span>
<span id="380"> 380</span>
<span id="381"> 381</span>
<span id="382"> 382</span>
<span id="383"> 383</span>
<span id="384"> 384</span>
<span id="385"> 385</span>
<span id="386"> 386</span>
<span id="387"> 387</span>
<span id="388"> 388</span>
<span id="389"> 389</span>
<span id="390"> 390</span>
<span id="391"> 391</span>
<span id="392"> 392</span>
<span id="393"> 393</span>
<span id="394"> 394</span>
<span id="395"> 395</span>
<span id="396"> 396</span>
<span id="397"> 397</span>
<span id="398"> 398</span>
<span id="399"> 399</span>
<span id="400"> 400</span>
<span id="401"> 401</span>
<span id="402"> 402</span>
<span id="403"> 403</span>
<span id="404"> 404</span>
<span id="405"> 405</span>
<span id="406"> 406</span>
<span id="407"> 407</span>
<span id="408"> 408</span>
<span id="409"> 409</span>
<span id="410"> 410</span>
<span id="411"> 411</span>
<span id="412"> 412</span>
<span id="413"> 413</span>
<span id="414"> 414</span>
<span id="415"> 415</span>
<span id="416"> 416</span>
<span id="417"> 417</span>
<span id="418"> 418</span>
<span id="419"> 419</span>
<span id="420"> 420</span>
<span id="421"> 421</span>
<span id="422"> 422</span>
<span id="423"> 423</span>
<span id="424"> 424</span>
<span id="425"> 425</span>
<span id="426"> 426</span>
<span id="427"> 427</span>
<span id="428"> 428</span>
<span id="429"> 429</span>
<span id="430"> 430</span>
<span id="431"> 431</span>
<span id="432"> 432</span>
<span id="433"> 433</span>
<span id="434"> 434</span>
<span id="435"> 435</span>
<span id="436"> 436</span>
<span id="437"> 437</span>
<span id="438"> 438</span>
<span id="439"> 439</span>
<span id="440"> 440</span>
<span id="441"> 441</span>
<span id="442"> 442</span>
<span id="443"> 443</span>
<span id="444"> 444</span>
<span id="445"> 445</span>
<span id="446"> 446</span>
<span id="447"> 447</span>
<span id="448"> 448</span>
<span id="449"> 449</span>
<span id="450"> 450</span>
<span id="451"> 451</span>
<span id="452"> 452</span>
<span id="453"> 453</span>
<span id="454"> 454</span>
<span id="455"> 455</span>
<span id="456"> 456</span>
<span id="457"> 457</span>
<span id="458"> 458</span>
<span id="459"> 459</span>
<span id="460"> 460</span>
<span id="461"> 461</span>
<span id="462"> 462</span>
<span id="463"> 463</span>
<span id="464"> 464</span>
<span id="465"> 465</span>
<span id="466"> 466</span>
<span id="467"> 467</span>
<span id="468"> 468</span>
<span id="469"> 469</span>
<span id="470"> 470</span>
<span id="471"> 471</span>
<span id="472"> 472</span>
<span id="473"> 473</span>
<span id="474"> 474</span>
<span id="475"> 475</span>
<span id="476"> 476</span>
<span id="477"> 477</span>
<span id="478"> 478</span>
<span id="479"> 479</span>
<span id="480"> 480</span>
<span id="481"> 481</span>
<span id="482"> 482</span>
<span id="483"> 483</span>
<span id="484"> 484</span>
<span id="485"> 485</span>
<span id="486"> 486</span>
<span id="487"> 487</span>
<span id="488"> 488</span>
<span id="489"> 489</span>
<span id="490"> 490</span>
<span id="491"> 491</span>
<span id="492"> 492</span>
<span id="493"> 493</span>
<span id="494"> 494</span>
<span id="495"> 495</span>
<span id="496"> 496</span>
<span id="497"> 497</span>
<span id="498"> 498</span>
<span id="499"> 499</span>
<span id="500"> 500</span>
<span id="501"> 501</span>
<span id="502"> 502</span>
<span id="503"> 503</span>
<span id="504"> 504</span>
<span id="505"> 505</span>
<span id="506"> 506</span>
<span id="507"> 507</span>
<span id="508"> 508</span>
<span id="509"> 509</span>
<span id="510"> 510</span>
<span id="511"> 511</span>
<span id="512"> 512</span>
<span id="513"> 513</span>
<span id="514"> 514</span>
<span id="515"> 515</span>
<span id="516"> 516</span>
<span id="517"> 517</span>
<span id="518"> 518</span>
<span id="519"> 519</span>
<span id="520"> 520</span>
<span id="521"> 521</span>
<span id="522"> 522</span>
<span id="523"> 523</span>
<span id="524"> 524</span>
<span id="525"> 525</span>
<span id="526"> 526</span>
<span id="527"> 527</span>
<span id="528"> 528</span>
<span id="529"> 529</span>
<span id="530"> 530</span>
<span id="531"> 531</span>
<span id="532"> 532</span>
<span id="533"> 533</span>
<span id="534"> 534</span>
<span id="535"> 535</span>
<span id="536"> 536</span>
<span id="537"> 537</span>
<span id="538"> 538</span>
<span id="539"> 539</span>
<span id="540"> 540</span>
<span id="541"> 541</span>
<span id="542"> 542</span>
<span id="543"> 543</span>
<span id="544"> 544</span>
<span id="545"> 545</span>
<span id="546"> 546</span>
<span id="547"> 547</span>
<span id="548"> 548</span>
<span id="549"> 549</span>
<span id="550"> 550</span>
<span id="551"> 551</span>
<span id="552"> 552</span>
<span id="553"> 553</span>
<span id="554"> 554</span>
<span id="555"> 555</span>
<span id="556"> 556</span>
<span id="557"> 557</span>
<span id="558"> 558</span>
<span id="559"> 559</span>
<span id="560"> 560</span>
<span id="561"> 561</span>
<span id="562"> 562</span>
<span id="563"> 563</span>
<span id="564"> 564</span>
<span id="565"> 565</span>
<span id="566"> 566</span>
<span id="567"> 567</span>
<span id="568"> 568</span>
<span id="569"> 569</span>
<span id="570"> 570</span>
<span id="571"> 571</span>
<span id="572"> 572</span>
<span id="573"> 573</span>
<span id="574"> 574</span>
<span id="575"> 575</span>
<span id="576"> 576</span>
<span id="577"> 577</span>
<span id="578"> 578</span>
<span id="579"> 579</span>
<span id="580"> 580</span>
<span id="581"> 581</span>
<span id="582"> 582</span>
<span id="583"> 583</span>
<span id="584"> 584</span>
<span id="585"> 585</span>
<span id="586"> 586</span>
<span id="587"> 587</span>
<span id="588"> 588</span>
<span id="589"> 589</span>
<span id="590"> 590</span>
<span id="591"> 591</span>
<span id="592"> 592</span>
<span id="593"> 593</span>
<span id="594"> 594</span>
<span id="595"> 595</span>
<span id="596"> 596</span>
<span id="597"> 597</span>
<span id="598"> 598</span>
<span id="599"> 599</span>
<span id="600"> 600</span>
<span id="601"> 601</span>
<span id="602"> 602</span>
<span id="603"> 603</span>
<span id="604"> 604</span>
<span id="605"> 605</span>
<span id="606"> 606</span>
<span id="607"> 607</span>
<span id="608"> 608</span>
<span id="609"> 609</span>
<span id="610"> 610</span>
<span id="611"> 611</span>
<span id="612"> 612</span>
<span id="613"> 613</span>
<span id="614"> 614</span>
<span id="615"> 615</span>
<span id="616"> 616</span>
<span id="617"> 617</span>
<span id="618"> 618</span>
<span id="619"> 619</span>
<span id="620"> 620</span>
<span id="621"> 621</span>
<span id="622"> 622</span>
<span id="623"> 623</span>
<span id="624"> 624</span>
<span id="625"> 625</span>
<span id="626"> 626</span>
<span id="627"> 627</span>
<span id="628"> 628</span>
<span id="629"> 629</span>
<span id="630"> 630</span>
<span id="631"> 631</span>
<span id="632"> 632</span>
<span id="633"> 633</span>
<span id="634"> 634</span>
<span id="635"> 635</span>
<span id="636"> 636</span>
<span id="637"> 637</span>
<span id="638"> 638</span>
<span id="639"> 639</span>
<span id="640"> 640</span>
<span id="641"> 641</span>
<span id="642"> 642</span>
<span id="643"> 643</span>
<span id="644"> 644</span>
<span id="645"> 645</span>
<span id="646"> 646</span>
<span id="647"> 647</span>
<span id="648"> 648</span>
<span id="649"> 649</span>
<span id="650"> 650</span>
<span id="651"> 651</span>
<span id="652"> 652</span>
<span id="653"> 653</span>
<span id="654"> 654</span>
<span id="655"> 655</span>
<span id="656"> 656</span>
<span id="657"> 657</span>
<span id="658"> 658</span>
<span id="659"> 659</span>
<span id="660"> 660</span>
<span id="661"> 661</span>
<span id="662"> 662</span>
<span id="663"> 663</span>
<span id="664"> 664</span>
<span id="665"> 665</span>
<span id="666"> 666</span>
<span id="667"> 667</span>
<span id="668"> 668</span>
<span id="669"> 669</span>
<span id="670"> 670</span>
<span id="671"> 671</span>
<span id="672"> 672</span>
<span id="673"> 673</span>
<span id="674"> 674</span>
<span id="675"> 675</span>
<span id="676"> 676</span>
<span id="677"> 677</span>
<span id="678"> 678</span>
<span id="679"> 679</span>
<span id="680"> 680</span>
<span id="681"> 681</span>
<span id="682"> 682</span>
<span id="683"> 683</span>
<span id="684"> 684</span>
<span id="685"> 685</span>
<span id="686"> 686</span>
<span id="687"> 687</span>
<span id="688"> 688</span>
<span id="689"> 689</span>
<span id="690"> 690</span>
<span id="691"> 691</span>
<span id="692"> 692</span>
<span id="693"> 693</span>
<span id="694"> 694</span>
<span id="695"> 695</span>
<span id="696"> 696</span>
<span id="697"> 697</span>
<span id="698"> 698</span>
<span id="699"> 699</span>
<span id="700"> 700</span>
<span id="701"> 701</span>
<span id="702"> 702</span>
<span id="703"> 703</span>
<span id="704"> 704</span>
<span id="705"> 705</span>
<span id="706"> 706</span>
<span id="707"> 707</span>
<span id="708"> 708</span>
<span id="709"> 709</span>
<span id="710"> 710</span>
<span id="711"> 711</span>
<span id="712"> 712</span>
<span id="713"> 713</span>
<span id="714"> 714</span>
<span id="715"> 715</span>
<span id="716"> 716</span>
<span id="717"> 717</span>
<span id="718"> 718</span>
<span id="719"> 719</span>
<span id="720"> 720</span>
<span id="721"> 721</span>
<span id="722"> 722</span>
<span id="723"> 723</span>
<span id="724"> 724</span>
<span id="725"> 725</span>
<span id="726"> 726</span>
<span id="727"> 727</span>
<span id="728"> 728</span>
<span id="729"> 729</span>
<span id="730"> 730</span>
<span id="731"> 731</span>
<span id="732"> 732</span>
<span id="733"> 733</span>
<span id="734"> 734</span>
<span id="735"> 735</span>
<span id="736"> 736</span>
<span id="737"> 737</span>
<span id="738"> 738</span>
<span id="739"> 739</span>
<span id="740"> 740</span>
<span id="741"> 741</span>
<span id="742"> 742</span>
<span id="743"> 743</span>
<span id="744"> 744</span>
<span id="745"> 745</span>
<span id="746"> 746</span>
<span id="747"> 747</span>
<span id="748"> 748</span>
<span id="749"> 749</span>
<span id="750"> 750</span>
<span id="751"> 751</span>
<span id="752"> 752</span>
<span id="753"> 753</span>
<span id="754"> 754</span>
<span id="755"> 755</span>
<span id="756"> 756</span>
<span id="757"> 757</span>
<span id="758"> 758</span>
<span id="759"> 759</span>
<span id="760"> 760</span>
<span id="761"> 761</span>
<span id="762"> 762</span>
<span id="763"> 763</span>
<span id="764"> 764</span>
<span id="765"> 765</span>
<span id="766"> 766</span>
<span id="767"> 767</span>
<span id="768"> 768</span>
<span id="769"> 769</span>
<span id="770"> 770</span>
<span id="771"> 771</span>
<span id="772"> 772</span>
<span id="773"> 773</span>
<span id="774"> 774</span>
<span id="775"> 775</span>
<span id="776"> 776</span>
<span id="777"> 777</span>
<span id="778"> 778</span>
<span id="779"> 779</span>
<span id="780"> 780</span>
<span id="781"> 781</span>
<span id="782"> 782</span>
<span id="783"> 783</span>
<span id="784"> 784</span>
<span id="785"> 785</span>
<span id="786"> 786</span>
<span id="787"> 787</span>
<span id="788"> 788</span>
<span id="789"> 789</span>
<span id="790"> 790</span>
<span id="791"> 791</span>
<span id="792"> 792</span>
<span id="793"> 793</span>
<span id="794"> 794</span>
<span id="795"> 795</span>
<span id="796"> 796</span>
<span id="797"> 797</span>
<span id="798"> 798</span>
<span id="799"> 799</span>
<span id="800"> 800</span>
<span id="801"> 801</span>
<span id="802"> 802</span>
<span id="803"> 803</span>
<span id="804"> 804</span>
<span id="805"> 805</span>
<span id="806"> 806</span>
<span id="807"> 807</span>
<span id="808"> 808</span>
<span id="809"> 809</span>
<span id="810"> 810</span>
<span id="811"> 811</span>
<span id="812"> 812</span>
<span id="813"> 813</span>
<span id="814"> 814</span>
<span id="815"> 815</span>
<span id="816"> 816</span>
<span id="817"> 817</span>
<span id="818"> 818</span>
<span id="819"> 819</span>
<span id="820"> 820</span>
<span id="821"> 821</span>
<span id="822"> 822</span>
<span id="823"> 823</span>
<span id="824"> 824</span>
<span id="825"> 825</span>
<span id="826"> 826</span>
<span id="827"> 827</span>
<span id="828"> 828</span>
<span id="829"> 829</span>
<span id="830"> 830</span>
<span id="831"> 831</span>
<span id="832"> 832</span>
<span id="833"> 833</span>
<span id="834"> 834</span>
<span id="835"> 835</span>
<span id="836"> 836</span>
<span id="837"> 837</span>
<span id="838"> 838</span>
<span id="839"> 839</span>
<span id="840"> 840</span>
<span id="841"> 841</span>
<span id="842"> 842</span>
<span id="843"> 843</span>
<span id="844"> 844</span>
<span id="845"> 845</span>
<span id="846"> 846</span>
<span id="847"> 847</span>
<span id="848"> 848</span>
<span id="849"> 849</span>
<span id="850"> 850</span>
<span id="851"> 851</span>
<span id="852"> 852</span>
<span id="853"> 853</span>
<span id="854"> 854</span>
<span id="855"> 855</span>
<span id="856"> 856</span>
<span id="857"> 857</span>
<span id="858"> 858</span>
<span id="859"> 859</span>
<span id="860"> 860</span>
<span id="861"> 861</span>
<span id="862"> 862</span>
<span id="863"> 863</span>
<span id="864"> 864</span>
<span id="865"> 865</span>
<span id="866"> 866</span>
<span id="867"> 867</span>
<span id="868"> 868</span>
<span id="869"> 869</span>
<span id="870"> 870</span>
<span id="871"> 871</span>
<span id="872"> 872</span>
<span id="873"> 873</span>
<span id="874"> 874</span>
<span id="875"> 875</span>
<span id="876"> 876</span>
<span id="877"> 877</span>
<span id="878"> 878</span>
<span id="879"> 879</span>
<span id="880"> 880</span>
<span id="881"> 881</span>
<span id="882"> 882</span>
<span id="883"> 883</span>
<span id="884"> 884</span>
<span id="885"> 885</span>
<span id="886"> 886</span>
<span id="887"> 887</span>
<span id="888"> 888</span>
<span id="889"> 889</span>
<span id="890"> 890</span>
<span id="891"> 891</span>
<span id="892"> 892</span>
<span id="893"> 893</span>
<span id="894"> 894</span>
<span id="895"> 895</span>
<span id="896"> 896</span>
<span id="897"> 897</span>
<span id="898"> 898</span>
<span id="899"> 899</span>
<span id="900"> 900</span>
<span id="901"> 901</span>
<span id="902"> 902</span>
<span id="903"> 903</span>
<span id="904"> 904</span>
<span id="905"> 905</span>
<span id="906"> 906</span>
<span id="907"> 907</span>
<span id="908"> 908</span>
<span id="909"> 909</span>
<span id="910"> 910</span>
<span id="911"> 911</span>
<span id="912"> 912</span>
<span id="913"> 913</span>
<span id="914"> 914</span>
<span id="915"> 915</span>
<span id="916"> 916</span>
<span id="917"> 917</span>
<span id="918"> 918</span>
<span id="919"> 919</span>
<span id="920"> 920</span>
<span id="921"> 921</span>
<span id="922"> 922</span>
<span id="923"> 923</span>
<span id="924"> 924</span>
<span id="925"> 925</span>
<span id="926"> 926</span>
<span id="927"> 927</span>
<span id="928"> 928</span>
<span id="929"> 929</span>
<span id="930"> 930</span>
<span id="931"> 931</span>
<span id="932"> 932</span>
<span id="933"> 933</span>
<span id="934"> 934</span>
<span id="935"> 935</span>
<span id="936"> 936</span>
<span id="937"> 937</span>
<span id="938"> 938</span>
<span id="939"> 939</span>
<span id="940"> 940</span>
<span id="941"> 941</span>
<span id="942"> 942</span>
<span id="943"> 943</span>
<span id="944"> 944</span>
<span id="945"> 945</span>
<span id="946"> 946</span>
<span id="947"> 947</span>
<span id="948"> 948</span>
<span id="949"> 949</span>
<span id="950"> 950</span>
<span id="951"> 951</span>
<span id="952"> 952</span>
<span id="953"> 953</span>
<span id="954"> 954</span>
<span id="955"> 955</span>
<span id="956"> 956</span>
<span id="957"> 957</span>
<span id="958"> 958</span>
<span id="959"> 959</span>
<span id="960"> 960</span>
<span id="961"> 961</span>
<span id="962"> 962</span>
<span id="963"> 963</span>
<span id="964"> 964</span>
<span id="965"> 965</span>
<span id="966"> 966</span>
<span id="967"> 967</span>
<span id="968"> 968</span>
<span id="969"> 969</span>
<span id="970"> 970</span>
<span id="971"> 971</span>
<span id="972"> 972</span>
<span id="973"> 973</span>
<span id="974"> 974</span>
<span id="975"> 975</span>
<span id="976"> 976</span>
<span id="977"> 977</span>
<span id="978"> 978</span>
<span id="979"> 979</span>
<span id="980"> 980</span>
<span id="981"> 981</span>
<span id="982"> 982</span>
<span id="983"> 983</span>
<span id="984"> 984</span>
<span id="985"> 985</span>
<span id="986"> 986</span>
<span id="987"> 987</span>
<span id="988"> 988</span>
<span id="989"> 989</span>
<span id="990"> 990</span>
<span id="991"> 991</span>
<span id="992"> 992</span>
<span id="993"> 993</span>
<span id="994"> 994</span>
<span id="995"> 995</span>
<span id="996"> 996</span>
<span id="997"> 997</span>
<span id="998"> 998</span>
<span id="999"> 999</span>
<span id="1000">1000</span>
<span id="1001">1001</span>
<span id="1002">1002</span>
<span id="1003">1003</span>
<span id="1004">1004</span>
<span id="1005">1005</span>
<span id="1006">1006</span>
<span id="1007">1007</span>
<span id="1008">1008</span>
<span id="1009">1009</span>
<span id="1010">1010</span>
<span id="1011">1011</span>
<span id="1012">1012</span>
<span id="1013">1013</span>
<span id="1014">1014</span>
<span id="1015">1015</span>
<span id="1016">1016</span>
<span id="1017">1017</span>
<span id="1018">1018</span>
<span id="1019">1019</span>
<span id="1020">1020</span>
<span id="1021">1021</span>
<span id="1022">1022</span>
<span id="1023">1023</span>
<span id="1024">1024</span>
<span id="1025">1025</span>
<span id="1026">1026</span>
<span id="1027">1027</span>
<span id="1028">1028</span>
<span id="1029">1029</span>
<span id="1030">1030</span>
<span id="1031">1031</span>
<span id="1032">1032</span>
<span id="1033">1033</span>
<span id="1034">1034</span>
<span id="1035">1035</span>
<span id="1036">1036</span>
<span id="1037">1037</span>
<span id="1038">1038</span>
<span id="1039">1039</span>
<span id="1040">1040</span>
<span id="1041">1041</span>
<span id="1042">1042</span>
<span id="1043">1043</span>
<span id="1044">1044</span>
<span id="1045">1045</span>
<span id="1046">1046</span>
<span id="1047">1047</span>
<span id="1048">1048</span>
<span id="1049">1049</span>
<span id="1050">1050</span>
<span id="1051">1051</span>
<span id="1052">1052</span>
<span id="1053">1053</span>
<span id="1054">1054</span>
<span id="1055">1055</span>
<span id="1056">1056</span>
<span id="1057">1057</span>
<span id="1058">1058</span>
<span id="1059">1059</span>
<span id="1060">1060</span>
<span id="1061">1061</span>
<span id="1062">1062</span>
<span id="1063">1063</span>
<span id="1064">1064</span>
<span id="1065">1065</span>
<span id="1066">1066</span>
<span id="1067">1067</span>
<span id="1068">1068</span>
<span id="1069">1069</span>
<span id="1070">1070</span>
<span id="1071">1071</span>
<span id="1072">1072</span>
<span id="1073">1073</span>
<span id="1074">1074</span>
<span id="1075">1075</span>
<span id="1076">1076</span>
<span id="1077">1077</span>
<span id="1078">1078</span>
<span id="1079">1079</span>
<span id="1080">1080</span>
<span id="1081">1081</span>
<span id="1082">1082</span>
<span id="1083">1083</span>
<span id="1084">1084</span>
<span id="1085">1085</span>
<span id="1086">1086</span>
<span id="1087">1087</span>
<span id="1088">1088</span>
<span id="1089">1089</span>
<span id="1090">1090</span>
<span id="1091">1091</span>
<span id="1092">1092</span>
<span id="1093">1093</span>
<span id="1094">1094</span>
<span id="1095">1095</span>
<span id="1096">1096</span>
<span id="1097">1097</span>
<span id="1098">1098</span>
<span id="1099">1099</span>
<span id="1100">1100</span>
<span id="1101">1101</span>
<span id="1102">1102</span>
<span id="1103">1103</span>
<span id="1104">1104</span>
<span id="1105">1105</span>
<span id="1106">1106</span>
<span id="1107">1107</span>
<span id="1108">1108</span>
<span id="1109">1109</span>
<span id="1110">1110</span>
<span id="1111">1111</span>
<span id="1112">1112</span>
<span id="1113">1113</span>
<span id="1114">1114</span>
<span id="1115">1115</span>
<span id="1116">1116</span>
<span id="1117">1117</span>
<span id="1118">1118</span>
<span id="1119">1119</span>
<span id="1120">1120</span>
<span id="1121">1121</span>
<span id="1122">1122</span>
<span id="1123">1123</span>
<span id="1124">1124</span>
<span id="1125">1125</span>
<span id="1126">1126</span>
<span id="1127">1127</span>
<span id="1128">1128</span>
<span id="1129">1129</span>
<span id="1130">1130</span>
<span id="1131">1131</span>
<span id="1132">1132</span>
<span id="1133">1133</span>
<span id="1134">1134</span>
<span id="1135">1135</span>
<span id="1136">1136</span>
<span id="1137">1137</span>
<span id="1138">1138</span>
<span id="1139">1139</span>
<span id="1140">1140</span>
<span id="1141">1141</span>
<span id="1142">1142</span>
<span id="1143">1143</span>
<span id="1144">1144</span>
<span id="1145">1145</span>
<span id="1146">1146</span>
<span id="1147">1147</span>
<span id="1148">1148</span>
<span id="1149">1149</span>
<span id="1150">1150</span>
<span id="1151">1151</span>
<span id="1152">1152</span>
<span id="1153">1153</span>
<span id="1154">1154</span>
<span id="1155">1155</span>
<span id="1156">1156</span>
<span id="1157">1157</span>
<span id="1158">1158</span>
<span id="1159">1159</span>
<span id="1160">1160</span>
<span id="1161">1161</span>
<span id="1162">1162</span>
<span id="1163">1163</span>
<span id="1164">1164</span>
<span id="1165">1165</span>
<span id="1166">1166</span>
<span id="1167">1167</span>
<span id="1168">1168</span>
<span id="1169">1169</span>
<span id="1170">1170</span>
<span id="1171">1171</span>
<span id="1172">1172</span>
<span id="1173">1173</span>
<span id="1174">1174</span>
<span id="1175">1175</span>
<span id="1176">1176</span>
<span id="1177">1177</span>
<span id="1178">1178</span>
<span id="1179">1179</span>
<span id="1180">1180</span>
<span id="1181">1181</span>
<span id="1182">1182</span>
<span id="1183">1183</span>
<span id="1184">1184</span>
<span id="1185">1185</span>
<span id="1186">1186</span>
<span id="1187">1187</span>
<span id="1188">1188</span>
<span id="1189">1189</span>
<span id="1190">1190</span>
<span id="1191">1191</span>
<span id="1192">1192</span>
<span id="1193">1193</span>
<span id="1194">1194</span>
<span id="1195">1195</span>
<span id="1196">1196</span>
<span id="1197">1197</span>
<span id="1198">1198</span>
<span id="1199">1199</span>
<span id="1200">1200</span>
<span id="1201">1201</span>
<span id="1202">1202</span>
<span id="1203">1203</span>
<span id="1204">1204</span>
<span id="1205">1205</span>
<span id="1206">1206</span>
<span id="1207">1207</span>
<span id="1208">1208</span>
<span id="1209">1209</span>
<span id="1210">1210</span>
<span id="1211">1211</span>
<span id="1212">1212</span>
<span id="1213">1213</span>
<span id="1214">1214</span>
<span id="1215">1215</span>
<span id="1216">1216</span>
<span id="1217">1217</span>
<span id="1218">1218</span>
<span id="1219">1219</span>
<span id="1220">1220</span>
<span id="1221">1221</span>
<span id="1222">1222</span>
<span id="1223">1223</span>
<span id="1224">1224</span>
<span id="1225">1225</span>
<span id="1226">1226</span>
<span id="1227">1227</span>
<span id="1228">1228</span>
<span id="1229">1229</span>
<span id="1230">1230</span>
<span id="1231">1231</span>
<span id="1232">1232</span>
<span id="1233">1233</span>
<span id="1234">1234</span>
<span id="1235">1235</span>
<span id="1236">1236</span>
<span id="1237">1237</span>
<span id="1238">1238</span>
<span id="1239">1239</span>
<span id="1240">1240</span>
<span id="1241">1241</span>
<span id="1242">1242</span>
<span id="1243">1243</span>
<span id="1244">1244</span>
<span id="1245">1245</span>
<span id="1246">1246</span>
<span id="1247">1247</span>
<span id="1248">1248</span>
<span id="1249">1249</span>
<span id="1250">1250</span>
<span id="1251">1251</span>
<span id="1252">1252</span>
<span id="1253">1253</span>
<span id="1254">1254</span>
<span id="1255">1255</span>
<span id="1256">1256</span>
<span id="1257">1257</span>
<span id="1258">1258</span>
<span id="1259">1259</span>
<span id="1260">1260</span>
<span id="1261">1261</span>
<span id="1262">1262</span>
<span id="1263">1263</span>
<span id="1264">1264</span>
<span id="1265">1265</span>
<span id="1266">1266</span>
<span id="1267">1267</span>
<span id="1268">1268</span>
<span id="1269">1269</span>
<span id="1270">1270</span>
<span id="1271">1271</span>
<span id="1272">1272</span>
<span id="1273">1273</span>
<span id="1274">1274</span>
<span id="1275">1275</span>
<span id="1276">1276</span>
<span id="1277">1277</span>
<span id="1278">1278</span>
<span id="1279">1279</span>
<span id="1280">1280</span>
<span id="1281">1281</span>
<span id="1282">1282</span>
<span id="1283">1283</span>
<span id="1284">1284</span>
<span id="1285">1285</span>
<span id="1286">1286</span>
<span id="1287">1287</span>
<span id="1288">1288</span>
<span id="1289">1289</span>
<span id="1290">1290</span>
<span id="1291">1291</span>
<span id="1292">1292</span>
<span id="1293">1293</span>
<span id="1294">1294</span>
<span id="1295">1295</span>
<span id="1296">1296</span>
<span id="1297">1297</span>
<span id="1298">1298</span>
<span id="1299">1299</span>
<span id="1300">1300</span>
<span id="1301">1301</span>
<span id="1302">1302</span>
<span id="1303">1303</span>
<span id="1304">1304</span>
<span id="1305">1305</span>
<span id="1306">1306</span>
<span id="1307">1307</span>
<span id="1308">1308</span>
<span id="1309">1309</span>
<span id="1310">1310</span>
<span id="1311">1311</span>
<span id="1312">1312</span>
<span id="1313">1313</span>
<span id="1314">1314</span>
<span id="1315">1315</span>
<span id="1316">1316</span>
<span id="1317">1317</span>
<span id="1318">1318</span>
<span id="1319">1319</span>
<span id="1320">1320</span>
<span id="1321">1321</span>
<span id="1322">1322</span>
<span id="1323">1323</span>
<span id="1324">1324</span>
<span id="1325">1325</span>
<span id="1326">1326</span>
<span id="1327">1327</span>
<span id="1328">1328</span>
<span id="1329">1329</span>
<span id="1330">1330</span>
<span id="1331">1331</span>
<span id="1332">1332</span>
<span id="1333">1333</span>
<span id="1334">1334</span>
<span id="1335">1335</span>
<span id="1336">1336</span>
<span id="1337">1337</span>
<span id="1338">1338</span>
<span id="1339">1339</span>
<span id="1340">1340</span>
<span id="1341">1341</span>
<span id="1342">1342</span>
<span id="1343">1343</span>
<span id="1344">1344</span>
<span id="1345">1345</span>
<span id="1346">1346</span>
<span id="1347">1347</span>
<span id="1348">1348</span>
<span id="1349">1349</span>
<span id="1350">1350</span>
<span id="1351">1351</span>
<span id="1352">1352</span>
<span id="1353">1353</span>
<span id="1354">1354</span>
<span id="1355">1355</span>
<span id="1356">1356</span>
<span id="1357">1357</span>
<span id="1358">1358</span>
<span id="1359">1359</span>
<span id="1360">1360</span>
<span id="1361">1361</span>
<span id="1362">1362</span>
<span id="1363">1363</span>
<span id="1364">1364</span>
<span id="1365">1365</span>
<span id="1366">1366</span>
<span id="1367">1367</span>
<span id="1368">1368</span>
<span id="1369">1369</span>
<span id="1370">1370</span>
<span id="1371">1371</span>
<span id="1372">1372</span>
<span id="1373">1373</span>
<span id="1374">1374</span>
<span id="1375">1375</span>
<span id="1376">1376</span>
<span id="1377">1377</span>
<span id="1378">1378</span>
<span id="1379">1379</span>
<span id="1380">1380</span>
<span id="1381">1381</span>
<span id="1382">1382</span>
<span id="1383">1383</span>
<span id="1384">1384</span>
<span id="1385">1385</span>
<span id="1386">1386</span>
<span id="1387">1387</span>
<span id="1388">1388</span>
<span id="1389">1389</span>
<span id="1390">1390</span>
<span id="1391">1391</span>
<span id="1392">1392</span>
<span id="1393">1393</span>
<span id="1394">1394</span>
<span id="1395">1395</span>
<span id="1396">1396</span>
<span id="1397">1397</span>
<span id="1398">1398</span>
<span id="1399">1399</span>
<span id="1400">1400</span>
<span id="1401">1401</span>
<span id="1402">1402</span>
<span id="1403">1403</span>
<span id="1404">1404</span>
<span id="1405">1405</span>
<span id="1406">1406</span>
<span id="1407">1407</span>
<span id="1408">1408</span>
<span id="1409">1409</span>
<span id="1410">1410</span>
<span id="1411">1411</span>
<span id="1412">1412</span>
<span id="1413">1413</span>
<span id="1414">1414</span>
<span id="1415">1415</span>
<span id="1416">1416</span>
<span id="1417">1417</span>
<span id="1418">1418</span>
<span id="1419">1419</span>
<span id="1420">1420</span>
<span id="1421">1421</span>
<span id="1422">1422</span>
<span id="1423">1423</span>
<span id="1424">1424</span>
<span id="1425">1425</span>
<span id="1426">1426</span>
<span id="1427">1427</span>
<span id="1428">1428</span>
<span id="1429">1429</span>
<span id="1430">1430</span>
<span id="1431">1431</span>
<span id="1432">1432</span>
<span id="1433">1433</span>
<span id="1434">1434</span>
<span id="1435">1435</span>
<span id="1436">1436</span>
<span id="1437">1437</span>
<span id="1438">1438</span>
<span id="1439">1439</span>
<span id="1440">1440</span>
<span id="1441">1441</span>
<span id="1442">1442</span>
<span id="1443">1443</span>
<span id="1444">1444</span>
<span id="1445">1445</span>
<span id="1446">1446</span>
<span id="1447">1447</span>
<span id="1448">1448</span>
<span id="1449">1449</span>
<span id="1450">1450</span>
<span id="1451">1451</span>
<span id="1452">1452</span>
<span id="1453">1453</span>
<span id="1454">1454</span>
<span id="1455">1455</span>
<span id="1456">1456</span>
<span id="1457">1457</span>
<span id="1458">1458</span>
<span id="1459">1459</span>
<span id="1460">1460</span>
<span id="1461">1461</span>
<span id="1462">1462</span>
<span id="1463">1463</span>
<span id="1464">1464</span>
<span id="1465">1465</span>
<span id="1466">1466</span>
<span id="1467">1467</span>
<span id="1468">1468</span>
<span id="1469">1469</span>
<span id="1470">1470</span>
<span id="1471">1471</span>
<span id="1472">1472</span>
<span id="1473">1473</span>
<span id="1474">1474</span>
<span id="1475">1475</span>
<span id="1476">1476</span>
<span id="1477">1477</span>
<span id="1478">1478</span>
<span id="1479">1479</span>
<span id="1480">1480</span>
<span id="1481">1481</span>
<span id="1482">1482</span>
<span id="1483">1483</span>
<span id="1484">1484</span>
<span id="1485">1485</span>
<span id="1486">1486</span>
<span id="1487">1487</span>
<span id="1488">1488</span>
<span id="1489">1489</span>
<span id="1490">1490</span>
<span id="1491">1491</span>
<span id="1492">1492</span>
<span id="1493">1493</span>
<span id="1494">1494</span>
<span id="1495">1495</span>
<span id="1496">1496</span>
<span id="1497">1497</span>
<span id="1498">1498</span>
<span id="1499">1499</span>
<span id="1500">1500</span>
<span id="1501">1501</span>
<span id="1502">1502</span>
<span id="1503">1503</span>
<span id="1504">1504</span>
<span id="1505">1505</span>
<span id="1506">1506</span>
<span id="1507">1507</span>
<span id="1508">1508</span>
<span id="1509">1509</span>
<span id="1510">1510</span>
<span id="1511">1511</span>
<span id="1512">1512</span>
<span id="1513">1513</span>
<span id="1514">1514</span>
<span id="1515">1515</span>
<span id="1516">1516</span>
<span id="1517">1517</span>
<span id="1518">1518</span>
<span id="1519">1519</span>
<span id="1520">1520</span>
<span id="1521">1521</span>
<span id="1522">1522</span>
<span id="1523">1523</span>
<span id="1524">1524</span>
<span id="1525">1525</span>
<span id="1526">1526</span>
<span id="1527">1527</span>
<span id="1528">1528</span>
<span id="1529">1529</span>
<span id="1530">1530</span>
<span id="1531">1531</span>
<span id="1532">1532</span>
<span id="1533">1533</span>
<span id="1534">1534</span>
<span id="1535">1535</span>
<span id="1536">1536</span>
<span id="1537">1537</span>
<span id="1538">1538</span>
<span id="1539">1539</span>
<span id="1540">1540</span>
<span id="1541">1541</span>
<span id="1542">1542</span>
<span id="1543">1543</span>
<span id="1544">1544</span>
<span id="1545">1545</span>
<span id="1546">1546</span>
<span id="1547">1547</span>
<span id="1548">1548</span>
<span id="1549">1549</span>
<span id="1550">1550</span>
<span id="1551">1551</span>
<span id="1552">1552</span>
<span id="1553">1553</span>
<span id="1554">1554</span>
<span id="1555">1555</span>
<span id="1556">1556</span>
<span id="1557">1557</span>
<span id="1558">1558</span>
<span id="1559">1559</span>
<span id="1560">1560</span>
<span id="1561">1561</span>
<span id="1562">1562</span>
<span id="1563">1563</span>
<span id="1564">1564</span>
<span id="1565">1565</span>
<span id="1566">1566</span>
<span id="1567">1567</span>
<span id="1568">1568</span>
<span id="1569">1569</span>
<span id="1570">1570</span>
<span id="1571">1571</span>
<span id="1572">1572</span>
<span id="1573">1573</span>
<span id="1574">1574</span>
<span id="1575">1575</span>
<span id="1576">1576</span>
<span id="1577">1577</span>
<span id="1578">1578</span>
<span id="1579">1579</span>
<span id="1580">1580</span>
<span id="1581">1581</span>
<span id="1582">1582</span>
<span id="1583">1583</span>
<span id="1584">1584</span>
<span id="1585">1585</span>
<span id="1586">1586</span>
<span id="1587">1587</span>
<span id="1588">1588</span>
<span id="1589">1589</span>
<span id="1590">1590</span>
<span id="1591">1591</span>
<span id="1592">1592</span>
<span id="1593">1593</span>
<span id="1594">1594</span>
<span id="1595">1595</span>
<span id="1596">1596</span>
<span id="1597">1597</span>
<span id="1598">1598</span>
<span id="1599">1599</span>
<span id="1600">1600</span>
<span id="1601">1601</span>
<span id="1602">1602</span>
<span id="1603">1603</span>
<span id="1604">1604</span>
<span id="1605">1605</span>
<span id="1606">1606</span>
<span id="1607">1607</span>
<span id="1608">1608</span>
<span id="1609">1609</span>
<span id="1610">1610</span>
<span id="1611">1611</span>
<span id="1612">1612</span>
<span id="1613">1613</span>
<span id="1614">1614</span>
<span id="1615">1615</span>
<span id="1616">1616</span>
<span id="1617">1617</span>
<span id="1618">1618</span>
<span id="1619">1619</span>
<span id="1620">1620</span>
<span id="1621">1621</span>
<span id="1622">1622</span>
<span id="1623">1623</span>
<span id="1624">1624</span>
<span id="1625">1625</span>
<span id="1626">1626</span>
<span id="1627">1627</span>
<span id="1628">1628</span>
<span id="1629">1629</span>
<span id="1630">1630</span>
<span id="1631">1631</span>
<span id="1632">1632</span>
<span id="1633">1633</span>
<span id="1634">1634</span>
<span id="1635">1635</span>
<span id="1636">1636</span>
<span id="1637">1637</span>
<span id="1638">1638</span>
<span id="1639">1639</span>
<span id="1640">1640</span>
<span id="1641">1641</span>
<span id="1642">1642</span>
<span id="1643">1643</span>
<span id="1644">1644</span>
<span id="1645">1645</span>
<span id="1646">1646</span>
<span id="1647">1647</span>
<span id="1648">1648</span>
<span id="1649">1649</span>
<span id="1650">1650</span>
<span id="1651">1651</span>
<span id="1652">1652</span>
<span id="1653">1653</span>
<span id="1654">1654</span>
<span id="1655">1655</span>
<span id="1656">1656</span>
<span id="1657">1657</span>
<span id="1658">1658</span>
<span id="1659">1659</span>
<span id="1660">1660</span>
<span id="1661">1661</span>
<span id="1662">1662</span>
<span id="1663">1663</span>
<span id="1664">1664</span>
<span id="1665">1665</span>
<span id="1666">1666</span>
<span id="1667">1667</span>
<span id="1668">1668</span>
<span id="1669">1669</span>
<span id="1670">1670</span>
<span id="1671">1671</span>
<span id="1672">1672</span>
<span id="1673">1673</span>
<span id="1674">1674</span>
<span id="1675">1675</span>
<span id="1676">1676</span>
<span id="1677">1677</span>
<span id="1678">1678</span>
<span id="1679">1679</span>
<span id="1680">1680</span>
<span id="1681">1681</span>
<span id="1682">1682</span>
<span id="1683">1683</span>
<span id="1684">1684</span>
<span id="1685">1685</span>
<span id="1686">1686</span>
<span id="1687">1687</span>
<span id="1688">1688</span>
<span id="1689">1689</span>
<span id="1690">1690</span>
<span id="1691">1691</span>
<span id="1692">1692</span>
<span id="1693">1693</span>
<span id="1694">1694</span>
<span id="1695">1695</span>
<span id="1696">1696</span>
<span id="1697">1697</span>
<span id="1698">1698</span>
<span id="1699">1699</span>
<span id="1700">1700</span>
<span id="1701">1701</span>
<span id="1702">1702</span>
<span id="1703">1703</span>
<span id="1704">1704</span>
<span id="1705">1705</span>
<span id="1706">1706</span>
<span id="1707">1707</span>
<span id="1708">1708</span>
<span id="1709">1709</span>
<span id="1710">1710</span>
<span id="1711">1711</span>
<span id="1712">1712</span>
<span id="1713">1713</span>
<span id="1714">1714</span>
<span id="1715">1715</span>
<span id="1716">1716</span>
<span id="1717">1717</span>
<span id="1718">1718</span>
<span id="1719">1719</span>
<span id="1720">1720</span>
<span id="1721">1721</span>
<span id="1722">1722</span>
<span id="1723">1723</span>
<span id="1724">1724</span>
<span id="1725">1725</span>
<span id="1726">1726</span>
<span id="1727">1727</span>
<span id="1728">1728</span>
<span id="1729">1729</span>
<span id="1730">1730</span>
<span id="1731">1731</span>
<span id="1732">1732</span>
<span id="1733">1733</span>
<span id="1734">1734</span>
<span id="1735">1735</span>
<span id="1736">1736</span>
<span id="1737">1737</span>
<span id="1738">1738</span>
<span id="1739">1739</span>
<span id="1740">1740</span>
<span id="1741">1741</span>
<span id="1742">1742</span>
<span id="1743">1743</span>
<span id="1744">1744</span>
<span id="1745">1745</span>
<span id="1746">1746</span>
<span id="1747">1747</span>
<span id="1748">1748</span>
<span id="1749">1749</span>
<span id="1750">1750</span>
<span id="1751">1751</span>
<span id="1752">1752</span>
<span id="1753">1753</span>
<span id="1754">1754</span>
<span id="1755">1755</span>
<span id="1756">1756</span>
<span id="1757">1757</span>
<span id="1758">1758</span>
<span id="1759">1759</span>
<span id="1760">1760</span>
<span id="1761">1761</span>
<span id="1762">1762</span>
<span id="1763">1763</span>
<span id="1764">1764</span>
<span id="1765">1765</span>
<span id="1766">1766</span>
<span id="1767">1767</span>
<span id="1768">1768</span>
<span id="1769">1769</span>
<span id="1770">1770</span>
<span id="1771">1771</span>
<span id="1772">1772</span>
<span id="1773">1773</span>
<span id="1774">1774</span>
<span id="1775">1775</span>
<span id="1776">1776</span>
<span id="1777">1777</span>
<span id="1778">1778</span>
<span id="1779">1779</span>
<span id="1780">1780</span>
<span id="1781">1781</span>
<span id="1782">1782</span>
<span id="1783">1783</span>
<span id="1784">1784</span>
<span id="1785">1785</span>
<span id="1786">1786</span>
<span id="1787">1787</span>
<span id="1788">1788</span>
<span id="1789">1789</span>
<span id="1790">1790</span>
<span id="1791">1791</span>
<span id="1792">1792</span>
<span id="1793">1793</span>
<span id="1794">1794</span>
<span id="1795">1795</span>
<span id="1796">1796</span>
<span id="1797">1797</span>
<span id="1798">1798</span>
<span id="1799">1799</span>
<span id="1800">1800</span>
<span id="1801">1801</span>
<span id="1802">1802</span>
<span id="1803">1803</span>
<span id="1804">1804</span>
<span id="1805">1805</span>
<span id="1806">1806</span>
<span id="1807">1807</span>
<span id="1808">1808</span>
<span id="1809">1809</span>
<span id="1810">1810</span>
<span id="1811">1811</span>
<span id="1812">1812</span>
<span id="1813">1813</span>
<span id="1814">1814</span>
<span id="1815">1815</span>
<span id="1816">1816</span>
<span id="1817">1817</span>
<span id="1818">1818</span>
<span id="1819">1819</span>
<span id="1820">1820</span>
<span id="1821">1821</span>
<span id="1822">1822</span>
<span id="1823">1823</span>
<span id="1824">1824</span>
<span id="1825">1825</span>
<span id="1826">1826</span>
<span id="1827">1827</span>
<span id="1828">1828</span>
<span id="1829">1829</span>
<span id="1830">1830</span>
<span id="1831">1831</span>
<span id="1832">1832</span>
<span id="1833">1833</span>
<span id="1834">1834</span>
<span id="1835">1835</span>
<span id="1836">1836</span>
<span id="1837">1837</span>
<span id="1838">1838</span>
<span id="1839">1839</span>
<span id="1840">1840</span>
<span id="1841">1841</span>
<span id="1842">1842</span>
<span id="1843">1843</span>
<span id="1844">1844</span>
<span id="1845">1845</span>
<span id="1846">1846</span>
<span id="1847">1847</span>
<span id="1848">1848</span>
<span id="1849">1849</span>
<span id="1850">1850</span>
<span id="1851">1851</span>
<span id="1852">1852</span>
<span id="1853">1853</span>
<span id="1854">1854</span>
<span id="1855">1855</span>
<span id="1856">1856</span>
<span id="1857">1857</span>
<span id="1858">1858</span>
<span id="1859">1859</span>
<span id="1860">1860</span>
<span id="1861">1861</span>
<span id="1862">1862</span>
<span id="1863">1863</span>
<span id="1864">1864</span>
<span id="1865">1865</span>
<span id="1866">1866</span>
<span id="1867">1867</span>
<span id="1868">1868</span>
<span id="1869">1869</span>
<span id="1870">1870</span>
<span id="1871">1871</span>
<span id="1872">1872</span>
<span id="1873">1873</span>
<span id="1874">1874</span>
<span id="1875">1875</span>
<span id="1876">1876</span>
<span id="1877">1877</span>
<span id="1878">1878</span>
<span id="1879">1879</span>
<span id="1880">1880</span>
<span id="1881">1881</span>
<span id="1882">1882</span>
<span id="1883">1883</span>
<span id="1884">1884</span>
<span id="1885">1885</span>
<span id="1886">1886</span>
<span id="1887">1887</span>
<span id="1888">1888</span>
<span id="1889">1889</span>
<span id="1890">1890</span>
<span id="1891">1891</span>
<span id="1892">1892</span>
<span id="1893">1893</span>
<span id="1894">1894</span>
<span id="1895">1895</span>
<span id="1896">1896</span>
<span id="1897">1897</span>
<span id="1898">1898</span>
<span id="1899">1899</span>
<span id="1900">1900</span>
<span id="1901">1901</span>
<span id="1902">1902</span>
<span id="1903">1903</span>
<span id="1904">1904</span>
<span id="1905">1905</span>
<span id="1906">1906</span>
<span id="1907">1907</span>
<span id="1908">1908</span>
<span id="1909">1909</span>
<span id="1910">1910</span>
<span id="1911">1911</span>
<span id="1912">1912</span>
<span id="1913">1913</span>
<span id="1914">1914</span>
<span id="1915">1915</span>
<span id="1916">1916</span>
<span id="1917">1917</span>
<span id="1918">1918</span>
<span id="1919">1919</span>
<span id="1920">1920</span>
<span id="1921">1921</span>
<span id="1922">1922</span>
<span id="1923">1923</span>
<span id="1924">1924</span>
<span id="1925">1925</span>
<span id="1926">1926</span>
<span id="1927">1927</span>
<span id="1928">1928</span>
<span id="1929">1929</span>
<span id="1930">1930</span>
<span id="1931">1931</span>
<span id="1932">1932</span>
<span id="1933">1933</span>
<span id="1934">1934</span>
<span id="1935">1935</span>
<span id="1936">1936</span>
<span id="1937">1937</span>
<span id="1938">1938</span>
<span id="1939">1939</span>
<span id="1940">1940</span>
<span id="1941">1941</span>
<span id="1942">1942</span>
<span id="1943">1943</span>
<span id="1944">1944</span>
<span id="1945">1945</span>
<span id="1946">1946</span>
<span id="1947">1947</span>
<span id="1948">1948</span>
<span id="1949">1949</span>
<span id="1950">1950</span>
<span id="1951">1951</span>
<span id="1952">1952</span>
<span id="1953">1953</span>
<span id="1954">1954</span>
<span id="1955">1955</span>
<span id="1956">1956</span>
<span id="1957">1957</span>
<span id="1958">1958</span>
<span id="1959">1959</span>
<span id="1960">1960</span>
<span id="1961">1961</span>
<span id="1962">1962</span>
<span id="1963">1963</span>
<span id="1964">1964</span>
<span id="1965">1965</span>
<span id="1966">1966</span>
<span id="1967">1967</span>
<span id="1968">1968</span>
<span id="1969">1969</span>
<span id="1970">1970</span>
<span id="1971">1971</span>
<span id="1972">1972</span>
<span id="1973">1973</span>
<span id="1974">1974</span>
<span id="1975">1975</span>
<span id="1976">1976</span>
<span id="1977">1977</span>
<span id="1978">1978</span>
<span id="1979">1979</span>
<span id="1980">1980</span>
<span id="1981">1981</span>
<span id="1982">1982</span>
<span id="1983">1983</span>
<span id="1984">1984</span>
<span id="1985">1985</span>
<span id="1986">1986</span>
<span id="1987">1987</span>
<span id="1988">1988</span>
<span id="1989">1989</span>
<span id="1990">1990</span>
<span id="1991">1991</span>
<span id="1992">1992</span>
<span id="1993">1993</span>
<span id="1994">1994</span>
<span id="1995">1995</span>
<span id="1996">1996</span>
<span id="1997">1997</span>
<span id="1998">1998</span>
<span id="1999">1999</span>
<span id="2000">2000</span>
<span id="2001">2001</span>
<span id="2002">2002</span>
<span id="2003">2003</span>
<span id="2004">2004</span>
<span id="2005">2005</span>
<span id="2006">2006</span>
<span id="2007">2007</span>
<span id="2008">2008</span>
<span id="2009">2009</span>
<span id="2010">2010</span>
<span id="2011">2011</span>
<span id="2012">2012</span>
<span id="2013">2013</span>
<span id="2014">2014</span>
<span id="2015">2015</span>
<span id="2016">2016</span>
<span id="2017">2017</span>
<span id="2018">2018</span>
<span id="2019">2019</span>
<span id="2020">2020</span>
<span id="2021">2021</span>
<span id="2022">2022</span>
<span id="2023">2023</span>
<span id="2024">2024</span>
<span id="2025">2025</span>
<span id="2026">2026</span>
<span id="2027">2027</span>
<span id="2028">2028</span>
<span id="2029">2029</span>
<span id="2030">2030</span>
<span id="2031">2031</span>
<span id="2032">2032</span>
<span id="2033">2033</span>
<span id="2034">2034</span>
<span id="2035">2035</span>
<span id="2036">2036</span>
<span id="2037">2037</span>
<span id="2038">2038</span>
<span id="2039">2039</span>
<span id="2040">2040</span>
<span id="2041">2041</span>
<span id="2042">2042</span>
<span id="2043">2043</span>
<span id="2044">2044</span>
<span id="2045">2045</span>
<span id="2046">2046</span>
<span id="2047">2047</span>
<span id="2048">2048</span>
<span id="2049">2049</span>
<span id="2050">2050</span>
<span id="2051">2051</span>
<span id="2052">2052</span>
<span id="2053">2053</span>
<span id="2054">2054</span>
<span id="2055">2055</span>
<span id="2056">2056</span>
<span id="2057">2057</span>
<span id="2058">2058</span>
<span id="2059">2059</span>
<span id="2060">2060</span>
<span id="2061">2061</span>
<span id="2062">2062</span>
<span id="2063">2063</span>
<span id="2064">2064</span>
<span id="2065">2065</span>
<span id="2066">2066</span>
<span id="2067">2067</span>
<span id="2068">2068</span>
<span id="2069">2069</span>
<span id="2070">2070</span>
<span id="2071">2071</span>
<span id="2072">2072</span>
<span id="2073">2073</span>
<span id="2074">2074</span>
<span id="2075">2075</span>
<span id="2076">2076</span>
<span id="2077">2077</span>
<span id="2078">2078</span>
<span id="2079">2079</span>
<span id="2080">2080</span>
<span id="2081">2081</span>
<span id="2082">2082</span>
<span id="2083">2083</span>
<span id="2084">2084</span>
<span id="2085">2085</span>
<span id="2086">2086</span>
<span id="2087">2087</span>
<span id="2088">2088</span>
<span id="2089">2089</span>
<span id="2090">2090</span>
<span id="2091">2091</span>
<span id="2092">2092</span>
<span id="2093">2093</span>
<span id="2094">2094</span>
<span id="2095">2095</span>
<span id="2096">2096</span>
<span id="2097">2097</span>
<span id="2098">2098</span>
<span id="2099">2099</span>
<span id="2100">2100</span>
<span id="2101">2101</span>
<span id="2102">2102</span>
<span id="2103">2103</span>
<span id="2104">2104</span>
<span id="2105">2105</span>
<span id="2106">2106</span>
<span id="2107">2107</span>
<span id="2108">2108</span>
<span id="2109">2109</span>
<span id="2110">2110</span>
<span id="2111">2111</span>
<span id="2112">2112</span>
<span id="2113">2113</span>
<span id="2114">2114</span>
<span id="2115">2115</span>
<span id="2116">2116</span>
<span id="2117">2117</span>
<span id="2118">2118</span>
<span id="2119">2119</span>
<span id="2120">2120</span>
<span id="2121">2121</span>
<span id="2122">2122</span>
<span id="2123">2123</span>
<span id="2124">2124</span>
<span id="2125">2125</span>
<span id="2126">2126</span>
<span id="2127">2127</span>
<span id="2128">2128</span>
<span id="2129">2129</span>
<span id="2130">2130</span>
<span id="2131">2131</span>
<span id="2132">2132</span>
<span id="2133">2133</span>
<span id="2134">2134</span>
<span id="2135">2135</span>
<span id="2136">2136</span>
<span id="2137">2137</span>
<span id="2138">2138</span>
<span id="2139">2139</span>
<span id="2140">2140</span>
<span id="2141">2141</span>
<span id="2142">2142</span>
<span id="2143">2143</span>
<span id="2144">2144</span>
<span id="2145">2145</span>
<span id="2146">2146</span>
<span id="2147">2147</span>
<span id="2148">2148</span>
<span id="2149">2149</span>
<span id="2150">2150</span>
<span id="2151">2151</span>
<span id="2152">2152</span>
<span id="2153">2153</span>
<span id="2154">2154</span>
<span id="2155">2155</span>
<span id="2156">2156</span>
<span id="2157">2157</span>
<span id="2158">2158</span>
<span id="2159">2159</span>
<span id="2160">2160</span>
<span id="2161">2161</span>
<span id="2162">2162</span>
<span id="2163">2163</span>
<span id="2164">2164</span>
<span id="2165">2165</span>
<span id="2166">2166</span>
<span id="2167">2167</span>
<span id="2168">2168</span>
<span id="2169">2169</span>
<span id="2170">2170</span>
<span id="2171">2171</span>
<span id="2172">2172</span>
<span id="2173">2173</span>
<span id="2174">2174</span>
<span id="2175">2175</span>
<span id="2176">2176</span>
<span id="2177">2177</span>
<span id="2178">2178</span>
<span id="2179">2179</span>
<span id="2180">2180</span>
<span id="2181">2181</span>
<span id="2182">2182</span>
<span id="2183">2183</span>
<span id="2184">2184</span>
<span id="2185">2185</span>
<span id="2186">2186</span>
<span id="2187">2187</span>
<span id="2188">2188</span>
<span id="2189">2189</span>
<span id="2190">2190</span>
<span id="2191">2191</span>
<span id="2192">2192</span>
<span id="2193">2193</span>
<span id="2194">2194</span>
<span id="2195">2195</span>
<span id="2196">2196</span>
<span id="2197">2197</span>
<span id="2198">2198</span>
<span id="2199">2199</span>
<span id="2200">2200</span>
<span id="2201">2201</span>
<span id="2202">2202</span>
<span id="2203">2203</span>
<span id="2204">2204</span>
<span id="2205">2205</span>
<span id="2206">2206</span>
<span id="2207">2207</span>
<span id="2208">2208</span>
<span id="2209">2209</span>
<span id="2210">2210</span>
<span id="2211">2211</span>
<span id="2212">2212</span>
<span id="2213">2213</span>
<span id="2214">2214</span>
<span id="2215">2215</span>
<span id="2216">2216</span>
<span id="2217">2217</span>
<span id="2218">2218</span>
<span id="2219">2219</span>
<span id="2220">2220</span>
<span id="2221">2221</span>
<span id="2222">2222</span>
<span id="2223">2223</span>
<span id="2224">2224</span>
<span id="2225">2225</span>
<span id="2226">2226</span>
<span id="2227">2227</span>
<span id="2228">2228</span>
<span id="2229">2229</span>
<span id="2230">2230</span>
<span id="2231">2231</span>
<span id="2232">2232</span>
<span id="2233">2233</span>
<span id="2234">2234</span>
<span id="2235">2235</span>
<span id="2236">2236</span>
<span id="2237">2237</span>
<span id="2238">2238</span>
<span id="2239">2239</span>
<span id="2240">2240</span>
<span id="2241">2241</span>
<span id="2242">2242</span>
<span id="2243">2243</span>
<span id="2244">2244</span>
<span id="2245">2245</span>
<span id="2246">2246</span>
<span id="2247">2247</span>
<span id="2248">2248</span>
<span id="2249">2249</span>
<span id="2250">2250</span>
<span id="2251">2251</span>
<span id="2252">2252</span>
<span id="2253">2253</span>
<span id="2254">2254</span>
<span id="2255">2255</span>
<span id="2256">2256</span>
<span id="2257">2257</span>
<span id="2258">2258</span>
<span id="2259">2259</span>
<span id="2260">2260</span>
<span id="2261">2261</span>
<span id="2262">2262</span>
<span id="2263">2263</span>
<span id="2264">2264</span>
<span id="2265">2265</span>
<span id="2266">2266</span>
<span id="2267">2267</span>
<span id="2268">2268</span>
<span id="2269">2269</span>
<span id="2270">2270</span>
<span id="2271">2271</span>
<span id="2272">2272</span>
<span id="2273">2273</span>
<span id="2274">2274</span>
<span id="2275">2275</span>
<span id="2276">2276</span>
<span id="2277">2277</span>
<span id="2278">2278</span>
<span id="2279">2279</span>
<span id="2280">2280</span>
<span id="2281">2281</span>
<span id="2282">2282</span>
<span id="2283">2283</span>
<span id="2284">2284</span>
<span id="2285">2285</span>
<span id="2286">2286</span>
<span id="2287">2287</span>
<span id="2288">2288</span>
<span id="2289">2289</span>
<span id="2290">2290</span>
<span id="2291">2291</span>
<span id="2292">2292</span>
<span id="2293">2293</span>
<span id="2294">2294</span>
<span id="2295">2295</span>
<span id="2296">2296</span>
<span id="2297">2297</span>
<span id="2298">2298</span>
<span id="2299">2299</span>
<span id="2300">2300</span>
<span id="2301">2301</span>
<span id="2302">2302</span>
<span id="2303">2303</span>
<span id="2304">2304</span>
<span id="2305">2305</span>
<span id="2306">2306</span>
<span id="2307">2307</span>
<span id="2308">2308</span>
<span id="2309">2309</span>
<span id="2310">2310</span>
<span id="2311">2311</span>
<span id="2312">2312</span>
<span id="2313">2313</span>
<span id="2314">2314</span>
<span id="2315">2315</span>
<span id="2316">2316</span>
<span id="2317">2317</span>
<span id="2318">2318</span>
<span id="2319">2319</span>
<span id="2320">2320</span>
<span id="2321">2321</span>
<span id="2322">2322</span>
<span id="2323">2323</span>
<span id="2324">2324</span>
<span id="2325">2325</span>
<span id="2326">2326</span>
<span id="2327">2327</span>
<span id="2328">2328</span>
<span id="2329">2329</span>
<span id="2330">2330</span>
<span id="2331">2331</span>
<span id="2332">2332</span>
<span id="2333">2333</span>
<span id="2334">2334</span>
<span id="2335">2335</span>
<span id="2336">2336</span>
<span id="2337">2337</span>
<span id="2338">2338</span>
<span id="2339">2339</span>
<span id="2340">2340</span>
<span id="2341">2341</span>
<span id="2342">2342</span>
<span id="2343">2343</span>
<span id="2344">2344</span>
<span id="2345">2345</span>
<span id="2346">2346</span>
<span id="2347">2347</span>
<span id="2348">2348</span>
<span id="2349">2349</span>
<span id="2350">2350</span>
<span id="2351">2351</span>
<span id="2352">2352</span>
<span id="2353">2353</span>
<span id="2354">2354</span>
<span id="2355">2355</span>
<span id="2356">2356</span>
<span id="2357">2357</span>
<span id="2358">2358</span>
<span id="2359">2359</span>
<span id="2360">2360</span>
<span id="2361">2361</span>
<span id="2362">2362</span>
<span id="2363">2363</span>
<span id="2364">2364</span>
<span id="2365">2365</span>
<span id="2366">2366</span>
<span id="2367">2367</span>
<span id="2368">2368</span>
<span id="2369">2369</span>
<span id="2370">2370</span>
<span id="2371">2371</span>
<span id="2372">2372</span>
<span id="2373">2373</span>
<span id="2374">2374</span>
<span id="2375">2375</span>
<span id="2376">2376</span>
<span id="2377">2377</span>
<span id="2378">2378</span>
<span id="2379">2379</span>
<span id="2380">2380</span>
<span id="2381">2381</span>
<span id="2382">2382</span>
<span id="2383">2383</span>
<span id="2384">2384</span>
<span id="2385">2385</span>
<span id="2386">2386</span>
<span id="2387">2387</span>
<span id="2388">2388</span>
<span id="2389">2389</span>
<span id="2390">2390</span>
<span id="2391">2391</span>
<span id="2392">2392</span>
<span id="2393">2393</span>
<span id="2394">2394</span>
<span id="2395">2395</span>
<span id="2396">2396</span>
<span id="2397">2397</span>
<span id="2398">2398</span>
<span id="2399">2399</span>
<span id="2400">2400</span>
<span id="2401">2401</span>
<span id="2402">2402</span>
<span id="2403">2403</span>
<span id="2404">2404</span>
<span id="2405">2405</span>
<span id="2406">2406</span>
<span id="2407">2407</span>
<span id="2408">2408</span>
<span id="2409">2409</span>
<span id="2410">2410</span>
<span id="2411">2411</span>
<span id="2412">2412</span>
<span id="2413">2413</span>
<span id="2414">2414</span>
<span id="2415">2415</span>
<span id="2416">2416</span>
<span id="2417">2417</span>
<span id="2418">2418</span>
<span id="2419">2419</span>
<span id="2420">2420</span>
<span id="2421">2421</span>
<span id="2422">2422</span>
<span id="2423">2423</span>
<span id="2424">2424</span>
<span id="2425">2425</span>
<span id="2426">2426</span>
<span id="2427">2427</span>
<span id="2428">2428</span>
<span id="2429">2429</span>
<span id="2430">2430</span>
<span id="2431">2431</span>
<span id="2432">2432</span>
<span id="2433">2433</span>
<span id="2434">2434</span>
<span id="2435">2435</span>
<span id="2436">2436</span>
<span id="2437">2437</span>
<span id="2438">2438</span>
<span id="2439">2439</span>
<span id="2440">2440</span>
<span id="2441">2441</span>
<span id="2442">2442</span>
<span id="2443">2443</span>
<span id="2444">2444</span>
<span id="2445">2445</span>
<span id="2446">2446</span>
<span id="2447">2447</span>
<span id="2448">2448</span>
<span id="2449">2449</span>
<span id="2450">2450</span>
<span id="2451">2451</span>
<span id="2452">2452</span>
<span id="2453">2453</span>
<span id="2454">2454</span>
<span id="2455">2455</span>
<span id="2456">2456</span>
<span id="2457">2457</span>
<span id="2458">2458</span>
<span id="2459">2459</span>
<span id="2460">2460</span>
<span id="2461">2461</span>
<span id="2462">2462</span>
<span id="2463">2463</span>
<span id="2464">2464</span>
<span id="2465">2465</span>
<span id="2466">2466</span>
<span id="2467">2467</span>
<span id="2468">2468</span>
<span id="2469">2469</span>
<span id="2470">2470</span>
<span id="2471">2471</span>
<span id="2472">2472</span>
<span id="2473">2473</span>
<span id="2474">2474</span>
<span id="2475">2475</span>
<span id="2476">2476</span>
<span id="2477">2477</span>
<span id="2478">2478</span>
<span id="2479">2479</span>
<span id="2480">2480</span>
<span id="2481">2481</span>
<span id="2482">2482</span>
<span id="2483">2483</span>
<span id="2484">2484</span>
<span id="2485">2485</span>
<span id="2486">2486</span>
<span id="2487">2487</span>
<span id="2488">2488</span>
<span id="2489">2489</span>
<span id="2490">2490</span>
<span id="2491">2491</span>
<span id="2492">2492</span>
<span id="2493">2493</span>
<span id="2494">2494</span>
<span id="2495">2495</span>
<span id="2496">2496</span>
<span id="2497">2497</span>
<span id="2498">2498</span>
<span id="2499">2499</span>
<span id="2500">2500</span>
<span id="2501">2501</span>
<span id="2502">2502</span>
<span id="2503">2503</span>
<span id="2504">2504</span>
<span id="2505">2505</span>
<span id="2506">2506</span>
<span id="2507">2507</span>
<span id="2508">2508</span>
<span id="2509">2509</span>
<span id="2510">2510</span>
<span id="2511">2511</span>
<span id="2512">2512</span>
<span id="2513">2513</span>
<span id="2514">2514</span>
<span id="2515">2515</span>
<span id="2516">2516</span>
<span id="2517">2517</span>
<span id="2518">2518</span>
<span id="2519">2519</span>
<span id="2520">2520</span>
<span id="2521">2521</span>
<span id="2522">2522</span>
<span id="2523">2523</span>
<span id="2524">2524</span>
<span id="2525">2525</span>
<span id="2526">2526</span>
<span id="2527">2527</span>
<span id="2528">2528</span>
<span id="2529">2529</span>
<span id="2530">2530</span>
<span id="2531">2531</span>
<span id="2532">2532</span>
<span id="2533">2533</span>
<span id="2534">2534</span>
<span id="2535">2535</span>
<span id="2536">2536</span>
<span id="2537">2537</span>
<span id="2538">2538</span>
<span id="2539">2539</span>
<span id="2540">2540</span>
<span id="2541">2541</span>
<span id="2542">2542</span>
<span id="2543">2543</span>
<span id="2544">2544</span>
<span id="2545">2545</span>
<span id="2546">2546</span>
<span id="2547">2547</span>
<span id="2548">2548</span>
<span id="2549">2549</span>
<span id="2550">2550</span>
<span id="2551">2551</span>
<span id="2552">2552</span>
<span id="2553">2553</span>
<span id="2554">2554</span>
<span id="2555">2555</span>
<span id="2556">2556</span>
<span id="2557">2557</span>
<span id="2558">2558</span>
<span id="2559">2559</span>
<span id="2560">2560</span>
<span id="2561">2561</span>
<span id="2562">2562</span>
<span id="2563">2563</span>
<span id="2564">2564</span>
<span id="2565">2565</span>
<span id="2566">2566</span>
<span id="2567">2567</span>
<span id="2568">2568</span>
<span id="2569">2569</span>
<span id="2570">2570</span>
<span id="2571">2571</span>
<span id="2572">2572</span>
<span id="2573">2573</span>
<span id="2574">2574</span>
<span id="2575">2575</span>
<span id="2576">2576</span>
<span id="2577">2577</span>
<span id="2578">2578</span>
<span id="2579">2579</span>
<span id="2580">2580</span>
<span id="2581">2581</span>
<span id="2582">2582</span>
<span id="2583">2583</span>
<span id="2584">2584</span>
<span id="2585">2585</span>
<span id="2586">2586</span>
<span id="2587">2587</span>
<span id="2588">2588</span>
<span id="2589">2589</span>
<span id="2590">2590</span>
<span id="2591">2591</span>
<span id="2592">2592</span>
<span id="2593">2593</span>
<span id="2594">2594</span>
<span id="2595">2595</span>
<span id="2596">2596</span>
<span id="2597">2597</span>
<span id="2598">2598</span>
<span id="2599">2599</span>
<span id="2600">2600</span>
<span id="2601">2601</span>
<span id="2602">2602</span>
<span id="2603">2603</span>
<span id="2604">2604</span>
<span id="2605">2605</span>
<span id="2606">2606</span>
<span id="2607">2607</span>
<span id="2608">2608</span>
<span id="2609">2609</span>
<span id="2610">2610</span>
<span id="2611">2611</span>
<span id="2612">2612</span>
<span id="2613">2613</span>
<span id="2614">2614</span>
<span id="2615">2615</span>
<span id="2616">2616</span>
<span id="2617">2617</span>
<span id="2618">2618</span>
<span id="2619">2619</span>
<span id="2620">2620</span>
<span id="2621">2621</span>
<span id="2622">2622</span>
<span id="2623">2623</span>
<span id="2624">2624</span>
<span id="2625">2625</span>
<span id="2626">2626</span>
<span id="2627">2627</span>
<span id="2628">2628</span>
<span id="2629">2629</span>
<span id="2630">2630</span>
<span id="2631">2631</span>
<span id="2632">2632</span>
<span id="2633">2633</span>
<span id="2634">2634</span>
<span id="2635">2635</span>
<span id="2636">2636</span>
<span id="2637">2637</span>
<span id="2638">2638</span>
<span id="2639">2639</span>
<span id="2640">2640</span>
<span id="2641">2641</span>
<span id="2642">2642</span>
<span id="2643">2643</span>
<span id="2644">2644</span>
<span id="2645">2645</span>
<span id="2646">2646</span>
<span id="2647">2647</span>
<span id="2648">2648</span>
<span id="2649">2649</span>
<span id="2650">2650</span>
<span id="2651">2651</span>
<span id="2652">2652</span>
<span id="2653">2653</span>
<span id="2654">2654</span>
<span id="2655">2655</span>
<span id="2656">2656</span>
<span id="2657">2657</span>
<span id="2658">2658</span>
<span id="2659">2659</span>
<span id="2660">2660</span>
<span id="2661">2661</span>
<span id="2662">2662</span>
<span id="2663">2663</span>
<span id="2664">2664</span>
<span id="2665">2665</span>
<span id="2666">2666</span>
<span id="2667">2667</span>
<span id="2668">2668</span>
<span id="2669">2669</span>
<span id="2670">2670</span>
<span id="2671">2671</span>
<span id="2672">2672</span>
<span id="2673">2673</span>
<span id="2674">2674</span>
<span id="2675">2675</span>
<span id="2676">2676</span>
<span id="2677">2677</span>
<span id="2678">2678</span>
<span id="2679">2679</span>
<span id="2680">2680</span>
<span id="2681">2681</span>
<span id="2682">2682</span>
<span id="2683">2683</span>
<span id="2684">2684</span>
<span id="2685">2685</span>
<span id="2686">2686</span>
<span id="2687">2687</span>
<span id="2688">2688</span>
<span id="2689">2689</span>
<span id="2690">2690</span>
<span id="2691">2691</span>
<span id="2692">2692</span>
<span id="2693">2693</span>
<span id="2694">2694</span>
<span id="2695">2695</span>
<span id="2696">2696</span>
<span id="2697">2697</span>
<span id="2698">2698</span>
<span id="2699">2699</span>
<span id="2700">2700</span>
<span id="2701">2701</span>
<span id="2702">2702</span>
<span id="2703">2703</span>
<span id="2704">2704</span>
<span id="2705">2705</span>
<span id="2706">2706</span>
<span id="2707">2707</span>
<span id="2708">2708</span>
<span id="2709">2709</span>
<span id="2710">2710</span>
<span id="2711">2711</span>
<span id="2712">2712</span>
<span id="2713">2713</span>
<span id="2714">2714</span>
<span id="2715">2715</span>
<span id="2716">2716</span>
<span id="2717">2717</span>
<span id="2718">2718</span>
<span id="2719">2719</span>
<span id="2720">2720</span>
<span id="2721">2721</span>
<span id="2722">2722</span>
<span id="2723">2723</span>
<span id="2724">2724</span>
<span id="2725">2725</span>
<span id="2726">2726</span>
<span id="2727">2727</span>
<span id="2728">2728</span>
<span id="2729">2729</span>
<span id="2730">2730</span>
<span id="2731">2731</span>
<span id="2732">2732</span>
<span id="2733">2733</span>
<span id="2734">2734</span>
<span id="2735">2735</span>
<span id="2736">2736</span>
<span id="2737">2737</span>
<span id="2738">2738</span>
<span id="2739">2739</span>
<span id="2740">2740</span>
<span id="2741">2741</span>
<span id="2742">2742</span>
<span id="2743">2743</span>
<span id="2744">2744</span>
<span id="2745">2745</span>
<span id="2746">2746</span>
<span id="2747">2747</span>
<span id="2748">2748</span>
<span id="2749">2749</span>
<span id="2750">2750</span>
<span id="2751">2751</span>
<span id="2752">2752</span>
<span id="2753">2753</span>
<span id="2754">2754</span>
<span id="2755">2755</span>
<span id="2756">2756</span>
<span id="2757">2757</span>
<span id="2758">2758</span>
<span id="2759">2759</span>
<span id="2760">2760</span>
<span id="2761">2761</span>
<span id="2762">2762</span>
<span id="2763">2763</span>
<span id="2764">2764</span>
<span id="2765">2765</span>
<span id="2766">2766</span>
<span id="2767">2767</span>
<span id="2768">2768</span>
<span id="2769">2769</span>
<span id="2770">2770</span>
<span id="2771">2771</span>
<span id="2772">2772</span>
<span id="2773">2773</span>
<span id="2774">2774</span>
<span id="2775">2775</span>
<span id="2776">2776</span>
<span id="2777">2777</span>
<span id="2778">2778</span>
<span id="2779">2779</span>
<span id="2780">2780</span>
<span id="2781">2781</span>
<span id="2782">2782</span>
<span id="2783">2783</span>
<span id="2784">2784</span>
<span id="2785">2785</span>
<span id="2786">2786</span>
<span id="2787">2787</span>
<span id="2788">2788</span>
<span id="2789">2789</span>
<span id="2790">2790</span>
<span id="2791">2791</span>
<span id="2792">2792</span>
<span id="2793">2793</span>
<span id="2794">2794</span>
<span id="2795">2795</span>
<span id="2796">2796</span>
<span id="2797">2797</span>
<span id="2798">2798</span>
<span id="2799">2799</span>
<span id="2800">2800</span>
<span id="2801">2801</span>
<span id="2802">2802</span>
<span id="2803">2803</span>
<span id="2804">2804</span>
<span id="2805">2805</span>
<span id="2806">2806</span>
<span id="2807">2807</span>
<span id="2808">2808</span>
<span id="2809">2809</span>
<span id="2810">2810</span>
<span id="2811">2811</span>
<span id="2812">2812</span>
<span id="2813">2813</span>
<span id="2814">2814</span>
<span id="2815">2815</span>
<span id="2816">2816</span>
<span id="2817">2817</span>
<span id="2818">2818</span>
<span id="2819">2819</span>
<span id="2820">2820</span>
<span id="2821">2821</span>
<span id="2822">2822</span>
<span id="2823">2823</span>
<span id="2824">2824</span>
<span id="2825">2825</span>
<span id="2826">2826</span>
<span id="2827">2827</span>
<span id="2828">2828</span>
<span id="2829">2829</span>
<span id="2830">2830</span>
<span id="2831">2831</span>
<span id="2832">2832</span>
<span id="2833">2833</span>
<span id="2834">2834</span>
<span id="2835">2835</span>
<span id="2836">2836</span>
<span id="2837">2837</span>
<span id="2838">2838</span>
<span id="2839">2839</span>
<span id="2840">2840</span>
<span id="2841">2841</span>
<span id="2842">2842</span>
<span id="2843">2843</span>
<span id="2844">2844</span>
<span id="2845">2845</span>
<span id="2846">2846</span>
<span id="2847">2847</span>
<span id="2848">2848</span>
<span id="2849">2849</span>
<span id="2850">2850</span>
<span id="2851">2851</span>
<span id="2852">2852</span>
<span id="2853">2853</span>
<span id="2854">2854</span>
<span id="2855">2855</span>
<span id="2856">2856</span>
<span id="2857">2857</span>
<span id="2858">2858</span>
<span id="2859">2859</span>
<span id="2860">2860</span>
<span id="2861">2861</span>
<span id="2862">2862</span>
<span id="2863">2863</span>
<span id="2864">2864</span>
<span id="2865">2865</span>
<span id="2866">2866</span>
<span id="2867">2867</span>
<span id="2868">2868</span>
<span id="2869">2869</span>
<span id="2870">2870</span>
<span id="2871">2871</span>
<span id="2872">2872</span>
<span id="2873">2873</span>
<span id="2874">2874</span>
<span id="2875">2875</span>
<span id="2876">2876</span>
<span id="2877">2877</span>
<span id="2878">2878</span>
<span id="2879">2879</span>
<span id="2880">2880</span>
<span id="2881">2881</span>
<span id="2882">2882</span>
<span id="2883">2883</span>
<span id="2884">2884</span>
<span id="2885">2885</span>
<span id="2886">2886</span>
<span id="2887">2887</span>
<span id="2888">2888</span>
<span id="2889">2889</span>
<span id="2890">2890</span>
<span id="2891">2891</span>
<span id="2892">2892</span>
<span id="2893">2893</span>
<span id="2894">2894</span>
<span id="2895">2895</span>
<span id="2896">2896</span>
<span id="2897">2897</span>
<span id="2898">2898</span>
<span id="2899">2899</span>
<span id="2900">2900</span>
<span id="2901">2901</span>
<span id="2902">2902</span>
<span id="2903">2903</span>
<span id="2904">2904</span>
<span id="2905">2905</span>
<span id="2906">2906</span>
<span id="2907">2907</span>
<span id="2908">2908</span>
<span id="2909">2909</span>
<span id="2910">2910</span>
</pre><div class="example-wrap"><pre class="rust ">
<span class="doccomment">/*!
[![Build Status](https://travis-ci.org/lawliet89/rocket_cors.svg)](https://travis-ci.org/lawliet89/rocket_cors)
[![Repository](https://img.shields.io/github/tag/lawliet89/rocket_cors.svg)](https://github.com/lawliet89/rocket_cors)
[![Crates.io](https://img.shields.io/crates/v/rocket_cors.svg)](https://crates.io/crates/rocket_cors)
- Documentation: [master branch](https://lawliet89.github.io/rocket_cors) | [stable](https://docs.rs/rocket_cors)
Cross-origin resource sharing (CORS) for [Rocket](https://rocket.rs/) applications
## Requirements
- Nightly Rust
- Rocket &gt;= 0.4
If you are using Rocket 0.3, use the `0.3.0` version of this crate.
### Nightly Rust
Rocket requires nightly Rust. You should probably install Rust with
[rustup](https://www.rustup.rs/), then override the code directory to use nightly instead of
stable. See
[installation instructions](https://rocket.rs/guide/getting-started/#installing-rust).
In particular, `rocket_cors` is currently targetted for the latest `nightly`. Older nightlies
might work, but they are subject to the minimum that Rocket sets.
## Installation
Add the following to Cargo.toml:
```toml
rocket_cors = &quot;0.5.1&quot;
```
To use the latest `master` branch, for example:
```toml
rocket_cors = { git = &quot;https://github.com/lawliet89/rocket_cors&quot;, branch = &quot;master&quot; }
```
## Features
By default, a `serialization` feature is enabled in this crate that allows you to (de)serialize
the [`CorsOptions`] struct that is described below. If you would like to disable this, simply
change your `Cargo.toml` to:
```toml
rocket_cors = { version = &quot;0.5.1&quot;, default-features = false }
```
## Usage
Before you can add CORS responses to your application, you need to create a [`CorsOptions`]
struct that will hold the settings. Then, you need to create a [`Cors`] struct using
[`CorsOptions::to_cors`] which will validate and optimise the settings for Rocket to use.
Each of the examples can be run off the repository via `cargo run --example xxx` where `xxx` is
- `fairing`
- `guard`
- `manual`
### `CorsOptions` Struct
The [`CorsOptions`] struct contains the settings for CORS requests to be validated
and for responses to be generated. Defaults are defined for every field in the struct, and
are documented on the [`CorsOptions`] page. You can also deserialize
the struct from some format like JSON, YAML or TOML when the default `serialization` feature
is enabled.
### `Cors` Struct
The [`Cors`] struct is what will be used with Rocket. After creating or deserializing a
[`CorsOptions`] struct, use [`CorsOptions::to_cors`] to create a [`Cors`] struct.
### Three modes of operation
You can add CORS to your routes via one of three ways, in descending order of ease and in
ascending order of flexibility.
- Fairing (should only used exclusively)
- Request Guard
- Truly Manual
Unfortunately, you cannot mix and match Fairing with any other of the methods, due to the
limitation of Rocket&#39;s fairing API. That is, the checks for Fairing will always happen first,
and if they fail, the route is never executed and so your guard or manual checks will never
get executed.
You can, however, mix and match guards and manual checks.
In summary:
| | Fairing | Request Guard | Manual |
|:---------------------------------------:|:-------:|:-------------:|:------:|
| Must apply to all routes | ✔ | ✗ | ✗ |
| Different settings for different routes | ✗ | ✗ | ✔ |
| May define custom OPTIONS routes | ✗ | ✔ | ✔ |
### Fairing
Fairing is the easiest to use and also the most inflexible. You don&#39;t have to define `OPTIONS`
routes for your application, and the checks are done transparently.
However, you can only have one set of settings that must apply to all routes. You cannot opt
any route out of CORS checks.
To use this, simply create a [`Cors`] from [`CorsOptions::to_cors`] and then
[`attach`](https://api.rocket.rs/rocket/struct.Rocket.html#method.attach) it to Rocket.
Refer to the [example](https://github.com/lawliet89/rocket_cors/blob/master/examples/fairing.rs).
#### Injected Route
The fairing implementation will inject a route during attachment to Rocket. This route is used
to handle errors during CORS validation.
This is due to the limitation in Rocket&#39;s Fairing
[lifecycle](https://rocket.rs/guide/fairings/). Ideally, we want to validate the CORS request
during `on_request`, and if the validation fails, we want to stop the route from even executing
to
1) prevent side effects
1) prevent resource usage from unnecessary computation
The only way to do this is to hijack the request and route it to our own injected route to
handle errors. Rocket does not allow Fairings to stop the processing of a route.
You can configure the behaviour of the injected route through a couple of fields in the
[`CorsOptions`].
### Request Guard
Using request guard requires you to sacrifice the convenience of Fairings for being able to
opt some routes out of CORS checks and enforcement. _BUT_ you are still restricted to only
one set of CORS settings and you have to mount additional routes to catch and process OPTIONS
requests. The `OPTIONS` routes are used for CORS preflight checks.
You will have to do the following:
- Create a [`Cors`] from [`CorsOptions`] and during Rocket&#39;s ignite, add the struct to
Rocket&#39;s [managed state](https://rocket.rs/guide/state/#managed-state).
- For all the routes that you want to enforce CORS on, you can mount either some
[catch all route](catch_all_options_routes) or define your own route for the OPTIONS
verb.
- Then in all the routes you want to enforce CORS on, add a
[Request Guard](https://rocket.rs/guide/requests/#request-guards) for the
[`Guard`](Guard) struct in the route arguments. You should not wrap this in an
`Option` or `Result` because the guard will let non-CORS requests through and will take over
error handling in case of errors.
- In your routes, to add CORS headers to your responses, use the appropriate functions on the
[`Guard`](Guard) for a `Response` or a `Responder`.
Refer to the [example](https://github.com/lawliet89/rocket_cors/blob/master/examples/guard.rs).
## Truly Manual
This mode is the most difficult to use but offers the most amount of flexibility.
You might have to understand how the library works internally to know how to use this mode.
In exchange, you can selectively choose which routes to offer CORS protection to, and you
can mix and match CORS settings for the routes. You can combine usage of this mode with
&quot;guard&quot; to offer a mix of ease of use and flexibility.
You really do not need to use this unless you have a truly ad-hoc need to respond to CORS
differently in a route. For example, you have a `ping` endpoint that allows all origins but
the rest of your routes do not.
### Handler
This mode requires that you pass in a closure that will be lazily evaluated once a CORS request
has been validated. If validation fails, the closure will not be run. You should put any code
that has any side effects or with an appreciable computation cost inside this handler.
### Steps to perform:
- You will first need to have a [`Cors`] struct ready. This struct can be borrowed with a lifetime
at least as long as `&#39;r` which is the lifetime of a Rocket request. `&#39;static` works too.
In this case, you might as well use the `Guard` method above and place the `Cors` struct in
Rocket&#39;s [state](https://rocket.rs/guide/state/).
Alternatively, you can create a [`Cors`] struct directly in the route.
- Your routes _might_ need to have a `&#39;r` lifetime and return `impl Responder&lt;&#39;r&gt;`. See below.
- Using the [`Cors`] struct, use either the
[`Cors::respond_owned`] or
[`Cors::respond_borrowed`] function and pass in a handler
that will be executed once CORS validation is successful.
- Your handler will be passed a [`Guard`] which you will have to use to
add CORS headers into your own response.
- You will have to manually define your own `OPTIONS` routes.
### Notes about route lifetime
You might have to specify a `&#39;r` lifetime in your routes and then return `impl Responder&lt;&#39;r&gt;`.
If you are not sure what to do, you can try to leave the lifetime out and then add it in
when the compiler complains.
Generally, you will need to manually annotate the lifetime for the following cases where
the compiler is unable to [elide](https://doc.rust-lang.org/beta/nomicon/lifetime-elision.html)
the lifetime:
- Your function arguments do not borrow anything.
- Your function arguments borrow from more than one lifetime.
- Your function arguments borrow from a lifetime that is shorter than the `&#39;r` lifetime
required.
You can see examples when the lifetime annotation is required (or not) in `examples/manual.rs`.
See the [example](https://github.com/lawliet89/rocket_cors/blob/master/examples/manual.rs).
## Mixing Guard and Manual
You can mix `Guard` and `Truly Manual` modes together for your application. For example, your
application might restrict the Origins that can access it, except for one `ping` route that
allows all access.
See the [example](https://github.com/lawliet89/rocket_cors/blob/master/examples/guard.rs).
## Reference
- [Fetch CORS Specification](https://fetch.spec.whatwg.org/#cors-protocol)
- [Supplanted W3C CORS Specification](https://www.w3.org/TR/cors/)
- [Resource Advice](https://w3c.github.io/webappsec-cors-for-developers/#resources)
*/</span>
<span class="attribute">#![<span class="ident">deny</span>(
<span class="ident">const_err</span>,
<span class="ident">dead_code</span>,
<span class="ident">deprecated</span>,
<span class="ident">exceeding_bitshifts</span>,
<span class="ident">improper_ctypes</span>,
<span class="ident">missing_docs</span>,
<span class="ident">mutable_transmutes</span>,
<span class="ident">no_mangle_const_items</span>,
<span class="ident">non_camel_case_types</span>,
<span class="ident">non_shorthand_field_patterns</span>,
<span class="ident">non_upper_case_globals</span>,
<span class="ident">overflowing_literals</span>,
<span class="ident">path_statements</span>,
<span class="ident">plugin_as_library</span>,
<span class="ident">stable_features</span>,
<span class="ident">trivial_casts</span>,
<span class="ident">trivial_numeric_casts</span>,
<span class="ident">unconditional_recursion</span>,
<span class="ident">unknown_crate_types</span>,
<span class="ident">unreachable_code</span>,
<span class="ident">unused_allocation</span>,
<span class="ident">unused_assignments</span>,
<span class="ident">unused_attributes</span>,
<span class="ident">unused_comparisons</span>,
<span class="ident">unused_extern_crates</span>,
<span class="ident">unused_features</span>,
<span class="ident">unused_imports</span>,
<span class="ident">unused_import_braces</span>,
<span class="ident">unused_qualifications</span>,
<span class="ident">unused_must_use</span>,
<span class="ident">unused_mut</span>,
<span class="ident">unused_parens</span>,
<span class="ident">unused_results</span>,
<span class="ident">unused_unsafe</span>,
<span class="ident">variant_size_differences</span>,
<span class="ident">warnings</span>,
<span class="ident">while_true</span>
)]</span>
<span class="attribute">#![<span class="ident">allow</span>(
<span class="ident">missing_copy_implementations</span>,
<span class="ident">missing_debug_implementations</span>,
<span class="ident">unknown_lints</span>,
<span class="ident">unsafe_code</span>,
<span class="ident">intra_doc_link_resolution_failure</span>
)]</span>
<span class="attribute">#![<span class="ident">doc</span>(<span class="ident">test</span>(<span class="ident">attr</span>(<span class="ident">allow</span>(<span class="ident">unused_variables</span>), <span class="ident">deny</span>(<span class="ident">warnings</span>))))]</span>
<span class="attribute">#[<span class="ident">cfg</span>(<span class="ident">test</span>)]</span>
<span class="attribute">#[<span class="ident">macro_use</span>]</span>
<span class="kw">mod</span> <span class="ident">test_macros</span>;
<span class="kw">mod</span> <span class="ident">fairing</span>;
<span class="kw">pub</span> <span class="kw">mod</span> <span class="ident">headers</span>;
<span class="kw">use</span> <span class="ident">std</span>::<span class="ident">borrow</span>::<span class="ident">Cow</span>;
<span class="kw">use</span> <span class="ident">std</span>::<span class="ident">collections</span>::<span class="ident">HashSet</span>;
<span class="kw">use</span> <span class="ident">std</span>::<span class="ident">error</span>;
<span class="kw">use</span> <span class="ident">std</span>::<span class="ident">fmt</span>;
<span class="kw">use</span> <span class="ident">std</span>::<span class="ident">marker</span>::<span class="ident">PhantomData</span>;
<span class="kw">use</span> <span class="ident">std</span>::<span class="ident">ops</span>::<span class="ident">Deref</span>;
<span class="kw">use</span> <span class="ident">std</span>::<span class="ident">str</span>::<span class="ident">FromStr</span>;
<span class="kw">use</span> ::<span class="ident">log</span>::{<span class="ident">debug</span>, <span class="ident">error</span>, <span class="ident">info</span>, <span class="ident">log</span>};
<span class="kw">use</span> <span class="ident">regex</span>::<span class="ident">RegexSet</span>;
<span class="kw">use</span> <span class="ident">rocket</span>::<span class="ident">http</span>::{<span class="self">self</span>, <span class="ident">Status</span>};
<span class="kw">use</span> <span class="ident">rocket</span>::<span class="ident">request</span>::{<span class="ident">FromRequest</span>, <span class="ident">Request</span>};
<span class="kw">use</span> <span class="ident">rocket</span>::<span class="ident">response</span>;
<span class="kw">use</span> <span class="ident">rocket</span>::{<span class="ident">debug_</span>, <span class="ident">error_</span>, <span class="ident">info_</span>, <span class="ident">log_</span>, <span class="ident">Outcome</span>, <span class="ident">State</span>};
<span class="attribute">#[<span class="ident">cfg</span>(<span class="ident">feature</span> <span class="op">=</span> <span class="string">&quot;serialization&quot;</span>)]</span>
<span class="kw">use</span> <span class="ident">serde_derive</span>::{<span class="ident">Deserialize</span>, <span class="ident">Serialize</span>};
<span class="kw">use</span> <span class="kw">crate</span>::<span class="ident">headers</span>::{
<span class="ident">AccessControlRequestHeaders</span>, <span class="ident">AccessControlRequestMethod</span>, <span class="ident">HeaderFieldName</span>, <span class="ident">HeaderFieldNamesSet</span>,
<span class="ident">Origin</span>,
};
<span class="doccomment">/// Errors during operations</span>
<span class="doccomment">///</span>
<span class="doccomment">/// This enum implements `rocket::response::Responder` which will return an appropriate status code</span>
<span class="doccomment">/// while printing out the error in the console.</span>
<span class="doccomment">/// Because these errors are usually the result of an error while trying to respond to a CORS</span>
<span class="doccomment">/// request, CORS headers cannot be added to the response and your applications requesting CORS</span>
<span class="doccomment">/// will not be able to see the status code.</span>
<span class="attribute">#[<span class="ident">derive</span>(<span class="ident">Debug</span>)]</span>
<span class="kw">pub</span> <span class="kw">enum</span> <span class="ident">Error</span> {
<span class="doccomment">/// The HTTP request header `Origin` is required but was not provided</span>
<span class="ident">MissingOrigin</span>,
<span class="doccomment">/// The HTTP request header `Origin` could not be parsed correctly.</span>
<span class="ident">BadOrigin</span>(<span class="ident">url</span>::<span class="ident">ParseError</span>),
<span class="doccomment">/// The configured Allowed Origins are Opaque origins. Use a Regex instead.</span>
<span class="ident">OpaqueAllowedOrigin</span>(<span class="ident">Vec</span><span class="op">&lt;</span><span class="ident">String</span><span class="op">&gt;</span>),
<span class="doccomment">/// The request header `Access-Control-Request-Method` is required but is missing</span>
<span class="ident">MissingRequestMethod</span>,
<span class="doccomment">/// The request header `Access-Control-Request-Method` has an invalid value</span>
<span class="ident">BadRequestMethod</span>,
<span class="doccomment">/// The request header `Access-Control-Request-Headers` is required but is missing.</span>
<span class="ident">MissingRequestHeaders</span>,
<span class="doccomment">/// Origin is not allowed to make this request</span>
<span class="ident">OriginNotAllowed</span>(<span class="ident">String</span>),
<span class="doccomment">/// Requested method is not allowed</span>
<span class="ident">MethodNotAllowed</span>(<span class="ident">String</span>),
<span class="doccomment">/// A regular expression compilation error</span>
<span class="ident">RegexError</span>(<span class="ident">regex</span>::<span class="ident">Error</span>),
<span class="doccomment">/// One or more headers requested are not allowed</span>
<span class="ident">HeadersNotAllowed</span>,
<span class="doccomment">/// Credentials are allowed, but the Origin is set to &quot;*&quot;. This is not allowed by W3C</span>
<span class="doccomment">///</span>
<span class="doccomment">/// This is a misconfiguration. Check the docuemntation for `Cors`.</span>
<span class="ident">CredentialsWithWildcardOrigin</span>,
<span class="doccomment">/// A CORS Request Guard was used, but no CORS Options was available in Rocket&#39;s state</span>
<span class="doccomment">///</span>
<span class="doccomment">/// This is a misconfiguration. Use `Rocket::manage` to add a CORS options to managed state.</span>
<span class="ident">MissingCorsInRocketState</span>,
<span class="doccomment">/// The `on_response` handler of Fairing could not find the injected header from the Request.</span>
<span class="doccomment">/// Either some other fairing has removed it, or this is a bug.</span>
<span class="ident">MissingInjectedHeader</span>,
}
<span class="kw">impl</span> <span class="ident">Error</span> {
<span class="kw">fn</span> <span class="ident">status</span>(<span class="kw-2">&amp;</span><span class="self">self</span>) <span class="op">-</span><span class="op">&gt;</span> <span class="ident">Status</span> {
<span class="kw">match</span> <span class="kw-2">*</span><span class="self">self</span> {
<span class="ident">Error</span>::<span class="ident">MissingOrigin</span>
<span class="op">|</span> <span class="ident">Error</span>::<span class="ident">OriginNotAllowed</span>(<span class="kw">_</span>)
<span class="op">|</span> <span class="ident">Error</span>::<span class="ident">MethodNotAllowed</span>(<span class="kw">_</span>)
<span class="op">|</span> <span class="ident">Error</span>::<span class="ident">HeadersNotAllowed</span> <span class="op">=</span><span class="op">&gt;</span> <span class="ident">Status</span>::<span class="ident">Forbidden</span>,
<span class="ident">Error</span>::<span class="ident">CredentialsWithWildcardOrigin</span>
<span class="op">|</span> <span class="ident">Error</span>::<span class="ident">MissingCorsInRocketState</span>
<span class="op">|</span> <span class="ident">Error</span>::<span class="ident">MissingInjectedHeader</span> <span class="op">=</span><span class="op">&gt;</span> <span class="ident">Status</span>::<span class="ident">InternalServerError</span>,
<span class="kw">_</span> <span class="op">=</span><span class="op">&gt;</span> <span class="ident">Status</span>::<span class="ident">BadRequest</span>,
}
}
}
<span class="kw">impl</span> <span class="ident">fmt</span>::<span class="ident">Display</span> <span class="kw">for</span> <span class="ident">Error</span> {
<span class="kw">fn</span> <span class="ident">fmt</span>(<span class="kw-2">&amp;</span><span class="self">self</span>, <span class="ident">f</span>: <span class="kw-2">&amp;</span><span class="kw-2">mut</span> <span class="ident">fmt</span>::<span class="ident">Formatter</span>) <span class="op">-</span><span class="op">&gt;</span> <span class="ident">fmt</span>::<span class="prelude-ty">Result</span> {
<span class="kw">match</span> <span class="self">self</span> {
<span class="ident">Error</span>::<span class="ident">MissingOrigin</span> <span class="op">=</span><span class="op">&gt;</span> <span class="macro">write</span><span class="macro">!</span>(
<span class="ident">f</span>,
<span class="string">&quot;The request header `Origin` is \
required but is missing&quot;</span>
),
<span class="ident">Error</span>::<span class="ident">BadOrigin</span>(<span class="kw">_</span>) <span class="op">=</span><span class="op">&gt;</span> <span class="macro">write</span><span class="macro">!</span>(<span class="ident">f</span>, <span class="string">&quot;The request header `Origin` contains an invalid URL&quot;</span>),
<span class="ident">Error</span>::<span class="ident">MissingRequestMethod</span> <span class="op">=</span><span class="op">&gt;</span> <span class="macro">write</span><span class="macro">!</span>(
<span class="ident">f</span>,
<span class="string">&quot;The request header `Access-Control-Request-Method` \
is required but is missing&quot;</span>
),
<span class="ident">Error</span>::<span class="ident">BadRequestMethod</span> <span class="op">=</span><span class="op">&gt;</span> <span class="macro">write</span><span class="macro">!</span>(
<span class="ident">f</span>,
<span class="string">&quot;The request header `Access-Control-Request-Method` has an invalid value&quot;</span>
),
<span class="ident">Error</span>::<span class="ident">MissingRequestHeaders</span> <span class="op">=</span><span class="op">&gt;</span> <span class="macro">write</span><span class="macro">!</span>(
<span class="ident">f</span>,
<span class="string">&quot;The request header `Access-Control-Request-Headers` \
is required but is missing&quot;</span>
),
<span class="ident">Error</span>::<span class="ident">OriginNotAllowed</span>(<span class="ident">origin</span>) <span class="op">=</span><span class="op">&gt;</span> <span class="macro">write</span><span class="macro">!</span>(
<span class="ident">f</span>,
<span class="string">&quot;Origin &#39;{}&#39; is \
not allowed to request&quot;</span>,
<span class="ident">origin</span>
),
<span class="ident">Error</span>::<span class="ident">MethodNotAllowed</span>(<span class="ident">method</span>) <span class="op">=</span><span class="op">&gt;</span> <span class="macro">write</span><span class="macro">!</span>(<span class="ident">f</span>, <span class="string">&quot;Method &#39;{}&#39; is not allowed&quot;</span>, <span class="kw-2">&amp;</span><span class="ident">method</span>),
<span class="ident">Error</span>::<span class="ident">HeadersNotAllowed</span> <span class="op">=</span><span class="op">&gt;</span> <span class="macro">write</span><span class="macro">!</span>(<span class="ident">f</span>, <span class="string">&quot;Headers are not allowed&quot;</span>),
<span class="ident">Error</span>::<span class="ident">CredentialsWithWildcardOrigin</span> <span class="op">=</span><span class="op">&gt;</span> <span class="macro">write</span><span class="macro">!</span>(
<span class="ident">f</span>,
<span class="string">&quot;Credentials are allowed, but the Origin is set to \&quot;*\&quot;. \
This is not allowed by W3C&quot;</span>
),
<span class="ident">Error</span>::<span class="ident">MissingCorsInRocketState</span> <span class="op">=</span><span class="op">&gt;</span> <span class="macro">write</span><span class="macro">!</span>(
<span class="ident">f</span>,
<span class="string">&quot;A CORS Request Guard was used, but no CORS Options \
was available in Rocket&#39;s state&quot;</span>
),
<span class="ident">Error</span>::<span class="ident">MissingInjectedHeader</span> <span class="op">=</span><span class="op">&gt;</span> {
<span class="macro">write</span><span class="macro">!</span>(<span class="ident">f</span>,
<span class="string">&quot;The `on_response` handler of Fairing could not find the injected header from the \
Request. Either some other fairing has removed it, or this is a bug.&quot;</span>)
}
<span class="ident">Error</span>::<span class="ident">OpaqueAllowedOrigin</span>(<span class="kw-2">ref</span> <span class="ident">origins</span>) <span class="op">=</span><span class="op">&gt;</span> <span class="macro">write</span><span class="macro">!</span>(
<span class="ident">f</span>,
<span class="string">&quot;The configured Origins &#39;{}&#39; are Opaque Origins. \
Use regex instead.&quot;</span>,
<span class="ident">origins</span>.<span class="ident">join</span>(<span class="string">&quot;; &quot;</span>)
),
<span class="ident">Error</span>::<span class="ident">RegexError</span>(<span class="kw-2">ref</span> <span class="ident">e</span>) <span class="op">=</span><span class="op">&gt;</span> <span class="macro">write</span><span class="macro">!</span>(<span class="ident">f</span>, <span class="string">&quot;{}&quot;</span>, <span class="ident">e</span>),
}
}
}
<span class="kw">impl</span> <span class="ident">error</span>::<span class="ident">Error</span> <span class="kw">for</span> <span class="ident">Error</span> {
<span class="kw">fn</span> <span class="ident">cause</span>(<span class="kw-2">&amp;</span><span class="self">self</span>) <span class="op">-</span><span class="op">&gt;</span> <span class="prelude-ty">Option</span><span class="op">&lt;</span><span class="kw-2">&amp;</span><span class="kw">dyn</span> <span class="ident">error</span>::<span class="ident">Error</span><span class="op">&gt;</span> {
<span class="kw">match</span> <span class="kw-2">*</span><span class="self">self</span> {
<span class="ident">Error</span>::<span class="ident">BadOrigin</span>(<span class="kw-2">ref</span> <span class="ident">e</span>) <span class="op">=</span><span class="op">&gt;</span> <span class="prelude-val">Some</span>(<span class="ident">e</span>),
<span class="kw">_</span> <span class="op">=</span><span class="op">&gt;</span> <span class="prelude-val">Some</span>(<span class="self">self</span>),
}
}
}
<span class="kw">impl</span><span class="op">&lt;</span><span class="lifetime">&#39;r</span><span class="op">&gt;</span> <span class="ident">response</span>::<span class="ident">Responder</span><span class="op">&lt;</span><span class="lifetime">&#39;r</span><span class="op">&gt;</span> <span class="kw">for</span> <span class="ident">Error</span> {
<span class="kw">fn</span> <span class="ident">respond_to</span>(<span class="self">self</span>, <span class="kw">_</span>: <span class="kw-2">&amp;</span><span class="ident">Request</span><span class="op">&lt;</span><span class="lifetime">&#39;_</span><span class="op">&gt;</span>) <span class="op">-</span><span class="op">&gt;</span> <span class="prelude-ty">Result</span><span class="op">&lt;</span><span class="ident">response</span>::<span class="ident">Response</span><span class="op">&lt;</span><span class="lifetime">&#39;r</span><span class="op">&gt;</span>, <span class="ident">Status</span><span class="op">&gt;</span> {
<span class="macro">error_</span><span class="macro">!</span>(<span class="string">&quot;CORS Error: {}&quot;</span>, <span class="self">self</span>);
<span class="prelude-val">Err</span>(<span class="self">self</span>.<span class="ident">status</span>())
}
}
<span class="kw">impl</span> <span class="ident">From</span><span class="op">&lt;</span><span class="ident">url</span>::<span class="ident">ParseError</span><span class="op">&gt;</span> <span class="kw">for</span> <span class="ident">Error</span> {
<span class="kw">fn</span> <span class="ident">from</span>(<span class="ident">error</span>: <span class="ident">url</span>::<span class="ident">ParseError</span>) <span class="op">-</span><span class="op">&gt;</span> <span class="self">Self</span> {
<span class="ident">Error</span>::<span class="ident">BadOrigin</span>(<span class="ident">error</span>)
}
}
<span class="kw">impl</span> <span class="ident">From</span><span class="op">&lt;</span><span class="ident">regex</span>::<span class="ident">Error</span><span class="op">&gt;</span> <span class="kw">for</span> <span class="ident">Error</span> {
<span class="kw">fn</span> <span class="ident">from</span>(<span class="ident">error</span>: <span class="ident">regex</span>::<span class="ident">Error</span>) <span class="op">-</span><span class="op">&gt;</span> <span class="self">Self</span> {
<span class="ident">Error</span>::<span class="ident">RegexError</span>(<span class="ident">error</span>)
}
}
<span class="doccomment">/// An enum signifying that some of type T is allowed, or `All` (everything is allowed).</span>
<span class="doccomment">///</span>
<span class="doccomment">/// `Default` is implemented for this enum and is `All`.</span>
<span class="doccomment">///</span>
<span class="doccomment">/// This enum is serialized and deserialized</span>
<span class="doccomment">/// [&quot;Externally tagged&quot;](https://serde.rs/enum-representations.html)</span>
<span class="attribute">#[<span class="ident">derive</span>(<span class="ident">Clone</span>, <span class="ident">Debug</span>, <span class="ident">Eq</span>, <span class="ident">PartialEq</span>)]</span>
<span class="attribute">#[<span class="ident">cfg_attr</span>(<span class="ident">feature</span> <span class="op">=</span> <span class="string">&quot;serialization&quot;</span>, <span class="ident">derive</span>(<span class="ident">Serialize</span>, <span class="ident">Deserialize</span>))]</span>
<span class="kw">pub</span> <span class="kw">enum</span> <span class="ident">AllOrSome</span><span class="op">&lt;</span><span class="ident">T</span><span class="op">&gt;</span> {
<span class="doccomment">/// Everything is allowed. Usually equivalent to the &quot;*&quot; value.</span>
<span class="ident">All</span>,
<span class="doccomment">/// Only some of `T` is allowed</span>
<span class="prelude-val">Some</span>(<span class="ident">T</span>),
}
<span class="kw">impl</span><span class="op">&lt;</span><span class="ident">T</span><span class="op">&gt;</span> <span class="ident">Default</span> <span class="kw">for</span> <span class="ident">AllOrSome</span><span class="op">&lt;</span><span class="ident">T</span><span class="op">&gt;</span> {
<span class="kw">fn</span> <span class="ident">default</span>() <span class="op">-</span><span class="op">&gt;</span> <span class="self">Self</span> {
<span class="ident">AllOrSome</span>::<span class="ident">All</span>
}
}
<span class="kw">impl</span><span class="op">&lt;</span><span class="ident">T</span><span class="op">&gt;</span> <span class="ident">AllOrSome</span><span class="op">&lt;</span><span class="ident">T</span><span class="op">&gt;</span> {
<span class="doccomment">/// Returns whether this is an `All` variant</span>
<span class="kw">pub</span> <span class="kw">fn</span> <span class="ident">is_all</span>(<span class="kw-2">&amp;</span><span class="self">self</span>) <span class="op">-</span><span class="op">&gt;</span> <span class="ident">bool</span> {
<span class="kw">match</span> <span class="self">self</span> {
<span class="ident">AllOrSome</span>::<span class="ident">All</span> <span class="op">=</span><span class="op">&gt;</span> <span class="bool-val">true</span>,
<span class="ident">AllOrSome</span>::<span class="prelude-val">Some</span>(<span class="kw">_</span>) <span class="op">=</span><span class="op">&gt;</span> <span class="bool-val">false</span>,
}
}
<span class="doccomment">/// Returns whether this is a `Some` variant</span>
<span class="kw">pub</span> <span class="kw">fn</span> <span class="ident">is_some</span>(<span class="kw-2">&amp;</span><span class="self">self</span>) <span class="op">-</span><span class="op">&gt;</span> <span class="ident">bool</span> {
<span class="op">!</span><span class="self">self</span>.<span class="ident">is_all</span>()
}
<span class="doccomment">/// Unwrap a `Some` variant and get its inner value</span>
<span class="doccomment">///</span>
<span class="doccomment">/// # Panics</span>
<span class="doccomment">/// Panics if the variant is `All`</span>
<span class="kw">pub</span> <span class="kw">fn</span> <span class="ident">unwrap</span>(<span class="self">self</span>) <span class="op">-</span><span class="op">&gt;</span> <span class="ident">T</span> {
<span class="kw">match</span> <span class="self">self</span> {
<span class="ident">AllOrSome</span>::<span class="ident">All</span> <span class="op">=</span><span class="op">&gt;</span> <span class="macro">panic</span><span class="macro">!</span>(<span class="string">&quot;Attempting to unwrap an `All`&quot;</span>),
<span class="ident">AllOrSome</span>::<span class="prelude-val">Some</span>(<span class="ident">inner</span>) <span class="op">=</span><span class="op">&gt;</span> <span class="ident">inner</span>,
}
}
}
<span class="doccomment">/// A wrapper type around `rocket::http::Method` to support serialization and deserialization</span>
<span class="attribute">#[<span class="ident">derive</span>(<span class="ident">Clone</span>, <span class="ident">Copy</span>, <span class="ident">PartialEq</span>, <span class="ident">Eq</span>, <span class="ident">Hash</span>, <span class="ident">Debug</span>)]</span>
<span class="kw">pub</span> <span class="kw">struct</span> <span class="ident">Method</span>(<span class="ident">http</span>::<span class="ident">Method</span>);
<span class="kw">impl</span> <span class="ident">FromStr</span> <span class="kw">for</span> <span class="ident">Method</span> {
<span class="kw">type</span> <span class="prelude-val">Err</span> <span class="op">=</span> ();
<span class="kw">fn</span> <span class="ident">from_str</span>(<span class="ident">s</span>: <span class="kw-2">&amp;</span><span class="ident">str</span>) <span class="op">-</span><span class="op">&gt;</span> <span class="prelude-ty">Result</span><span class="op">&lt;</span><span class="self">Self</span>, <span class="self">Self</span>::<span class="prelude-val">Err</span><span class="op">&gt;</span> {
<span class="kw">let</span> <span class="ident">method</span> <span class="op">=</span> <span class="ident">http</span>::<span class="ident">Method</span>::<span class="ident">from_str</span>(<span class="ident">s</span>)<span class="question-mark">?</span>;
<span class="prelude-val">Ok</span>(<span class="ident">Method</span>(<span class="ident">method</span>))
}
}
<span class="kw">impl</span> <span class="ident">Deref</span> <span class="kw">for</span> <span class="ident">Method</span> {
<span class="kw">type</span> <span class="ident">Target</span> <span class="op">=</span> <span class="ident">http</span>::<span class="ident">Method</span>;
<span class="kw">fn</span> <span class="ident">deref</span>(<span class="kw-2">&amp;</span><span class="self">self</span>) <span class="op">-</span><span class="op">&gt;</span> <span class="kw-2">&amp;</span><span class="self">Self</span>::<span class="ident">Target</span> {
<span class="kw-2">&amp;</span><span class="self">self</span>.<span class="number">0</span>
}
}
<span class="kw">impl</span> <span class="ident">From</span><span class="op">&lt;</span><span class="ident">http</span>::<span class="ident">Method</span><span class="op">&gt;</span> <span class="kw">for</span> <span class="ident">Method</span> {
<span class="kw">fn</span> <span class="ident">from</span>(<span class="ident">method</span>: <span class="ident">http</span>::<span class="ident">Method</span>) <span class="op">-</span><span class="op">&gt;</span> <span class="self">Self</span> {
<span class="ident">Method</span>(<span class="ident">method</span>)
}
}
<span class="kw">impl</span> <span class="ident">fmt</span>::<span class="ident">Display</span> <span class="kw">for</span> <span class="ident">Method</span> {
<span class="kw">fn</span> <span class="ident">fmt</span>(<span class="kw-2">&amp;</span><span class="self">self</span>, <span class="ident">f</span>: <span class="kw-2">&amp;</span><span class="kw-2">mut</span> <span class="ident">fmt</span>::<span class="ident">Formatter</span><span class="op">&lt;</span><span class="lifetime">&#39;_</span><span class="op">&gt;</span>) <span class="op">-</span><span class="op">&gt;</span> <span class="ident">fmt</span>::<span class="prelude-ty">Result</span> {
<span class="ident">fmt</span>::<span class="ident">Display</span>::<span class="ident">fmt</span>(<span class="kw-2">&amp;</span><span class="self">self</span>.<span class="number">0</span>, <span class="ident">f</span>)
}
}
<span class="attribute">#[<span class="ident">cfg</span>(<span class="ident">feature</span> <span class="op">=</span> <span class="string">&quot;serialization&quot;</span>)]</span>
<span class="kw">mod</span> <span class="ident">method_serde</span> {
<span class="kw">use</span> <span class="ident">std</span>::<span class="ident">fmt</span>;
<span class="kw">use</span> <span class="ident">std</span>::<span class="ident">str</span>::<span class="ident">FromStr</span>;
<span class="kw">use</span> <span class="ident">serde</span>::{<span class="self">self</span>, <span class="ident">Deserialize</span>, <span class="ident">Serialize</span>};
<span class="kw">use</span> <span class="kw">crate</span>::<span class="ident">Method</span>;
<span class="kw">impl</span> <span class="ident">Serialize</span> <span class="kw">for</span> <span class="ident">Method</span> {
<span class="kw">fn</span> <span class="ident">serialize</span><span class="op">&lt;</span><span class="ident">S</span><span class="op">&gt;</span>(<span class="kw-2">&amp;</span><span class="self">self</span>, <span class="ident">serializer</span>: <span class="ident">S</span>) <span class="op">-</span><span class="op">&gt;</span> <span class="prelude-ty">Result</span><span class="op">&lt;</span><span class="ident">S</span>::<span class="prelude-val">Ok</span>, <span class="ident">S</span>::<span class="ident">Error</span><span class="op">&gt;</span>
<span class="kw">where</span>
<span class="ident">S</span>: <span class="ident">serde</span>::<span class="ident">Serializer</span>,
{
<span class="ident">serializer</span>.<span class="ident">serialize_str</span>(<span class="self">self</span>.<span class="ident">as_str</span>())
}
}
<span class="kw">impl</span><span class="op">&lt;</span><span class="lifetime">&#39;de</span><span class="op">&gt;</span> <span class="ident">Deserialize</span><span class="op">&lt;</span><span class="lifetime">&#39;de</span><span class="op">&gt;</span> <span class="kw">for</span> <span class="ident">Method</span> {
<span class="kw">fn</span> <span class="ident">deserialize</span><span class="op">&lt;</span><span class="ident">D</span><span class="op">&gt;</span>(<span class="ident">deserializer</span>: <span class="ident">D</span>) <span class="op">-</span><span class="op">&gt;</span> <span class="prelude-ty">Result</span><span class="op">&lt;</span><span class="ident">Method</span>, <span class="ident">D</span>::<span class="ident">Error</span><span class="op">&gt;</span>
<span class="kw">where</span>
<span class="ident">D</span>: <span class="ident">serde</span>::<span class="ident">Deserializer</span><span class="op">&lt;</span><span class="lifetime">&#39;de</span><span class="op">&gt;</span>,
{
<span class="kw">use</span> <span class="ident">serde</span>::<span class="ident">de</span>::{<span class="self">self</span>, <span class="ident">Visitor</span>};
<span class="kw">struct</span> <span class="ident">MethodVisitor</span>;
<span class="kw">impl</span><span class="op">&lt;</span><span class="lifetime">&#39;de</span><span class="op">&gt;</span> <span class="ident">Visitor</span><span class="op">&lt;</span><span class="lifetime">&#39;de</span><span class="op">&gt;</span> <span class="kw">for</span> <span class="ident">MethodVisitor</span> {
<span class="kw">type</span> <span class="ident">Value</span> <span class="op">=</span> <span class="ident">Method</span>;
<span class="kw">fn</span> <span class="ident">expecting</span>(<span class="kw-2">&amp;</span><span class="self">self</span>, <span class="ident">formatter</span>: <span class="kw-2">&amp;</span><span class="kw-2">mut</span> <span class="ident">fmt</span>::<span class="ident">Formatter</span><span class="op">&lt;</span><span class="lifetime">&#39;_</span><span class="op">&gt;</span>) <span class="op">-</span><span class="op">&gt;</span> <span class="ident">fmt</span>::<span class="prelude-ty">Result</span> {
<span class="ident">formatter</span>.<span class="ident">write_str</span>(<span class="string">&quot;a string containing a HTTP Verb&quot;</span>)
}
<span class="kw">fn</span> <span class="ident">visit_str</span><span class="op">&lt;</span><span class="ident">E</span><span class="op">&gt;</span>(<span class="self">self</span>, <span class="ident">s</span>: <span class="kw-2">&amp;</span><span class="ident">str</span>) <span class="op">-</span><span class="op">&gt;</span> <span class="prelude-ty">Result</span><span class="op">&lt;</span><span class="self">Self</span>::<span class="ident">Value</span>, <span class="ident">E</span><span class="op">&gt;</span>
<span class="kw">where</span>
<span class="ident">E</span>: <span class="ident">de</span>::<span class="ident">Error</span>,
{
<span class="kw">match</span> <span class="self">Self</span>::<span class="ident">Value</span>::<span class="ident">from_str</span>(<span class="ident">s</span>) {
<span class="prelude-val">Ok</span>(<span class="ident">value</span>) <span class="op">=</span><span class="op">&gt;</span> <span class="prelude-val">Ok</span>(<span class="ident">value</span>),
<span class="prelude-val">Err</span>(<span class="ident">e</span>) <span class="op">=</span><span class="op">&gt;</span> <span class="prelude-val">Err</span>(<span class="ident">de</span>::<span class="ident">Error</span>::<span class="ident">custom</span>(<span class="macro">format</span><span class="macro">!</span>(<span class="string">&quot;{:?}&quot;</span>, <span class="ident">e</span>))),
}
}
}
<span class="ident">deserializer</span>.<span class="ident">deserialize_string</span>(<span class="ident">MethodVisitor</span>)
}
}
}
<span class="doccomment">/// A list of allowed origins. Either Some origins are allowed, or all origins are allowed.</span>
<span class="doccomment">///</span>
<span class="doccomment">/// Exact matches are matched exactly with the</span>
<span class="doccomment">/// [ASCII Serialization](https://html.spec.whatwg.org/multipage/origin.html#ascii-serialisation-of-an-origin)</span>
<span class="doccomment">/// of the origin.</span>
<span class="doccomment">///</span>
<span class="doccomment">/// Regular expressions are tested for matches against the</span>
<span class="doccomment">/// [ASCII Serialization](https://html.spec.whatwg.org/multipage/origin.html#ascii-serialisation-of-an-origin)</span>
<span class="doccomment">/// of the origin.</span>
<span class="doccomment">///</span>
<span class="doccomment">/// # Opaque Origins</span>
<span class="doccomment">/// The [specification](https://html.spec.whatwg.org/multipage/origin.html) defines an Opaque Origin</span>
<span class="doccomment">/// as one that cannot be recreated. You can refer to the source code for the [`url::Url::origin`]</span>
<span class="doccomment">/// method to see how an Opaque Origin is determined. Examples of Opaque origins might include</span>
<span class="doccomment">/// schemes like `file://` or Browser specific schemes like `&quot;moz-extension://` or</span>
<span class="doccomment">/// `chrome-extension://`.</span>
<span class="doccomment">///</span>
<span class="doccomment">/// Opaque Origins cannot be matched exactly. You must use Regex to match Opaque Origins. If you</span>
<span class="doccomment">/// attempt to create [`Cors`] from [`CorsOptions`], you will get an error.</span>
<span class="doccomment">/// # Warning about Regex expressions</span>
<span class="doccomment">/// By default, regex expressions are</span>
<span class="doccomment">/// [unanchored](https://docs.rs/regex/1.1.2/regex/struct.RegexSet.html#method.is_match).</span>
<span class="doccomment">///</span>
<span class="doccomment">/// This means that if the regex does not start with `^` or `\A`, or end with `$` or `\z`,</span>
<span class="doccomment">/// then it is permitted to match anywhere in the text. You are encouraged to use the anchors when</span>
<span class="doccomment">/// crafting your Regex expressions.</span>
<span class="doccomment">///</span>
<span class="doccomment">/// # Examples</span>
<span class="doccomment">/// ```rust</span>
<span class="doccomment">/// use rocket_cors::AllowedOrigins;</span>
<span class="doccomment">///</span>
<span class="doccomment">/// let exact = [&quot;https://www.acme.com&quot;];</span>
<span class="doccomment">/// let regex = [&quot;^https://(.+).acme.com$&quot;];</span>
<span class="doccomment">///</span>
<span class="doccomment">/// let all_origins = AllowedOrigins::all();</span>
<span class="doccomment">/// let some_origins = AllowedOrigins::some_exact(&amp;exact);</span>
<span class="doccomment">/// let null_origins = AllowedOrigins::some_null();</span>
<span class="doccomment">/// let regex_origins = AllowedOrigins::some_regex(&amp;regex);</span>
<span class="doccomment">/// let mixed_origins = AllowedOrigins::some(&amp;exact, &amp;regex);</span>
<span class="doccomment">/// ```</span>
<span class="doccomment">///</span>
<span class="kw">pub</span> <span class="kw">type</span> <span class="ident">AllowedOrigins</span> <span class="op">=</span> <span class="ident">AllOrSome</span><span class="op">&lt;</span><span class="ident">Origins</span><span class="op">&gt;</span>;
<span class="kw">impl</span> <span class="ident">AllowedOrigins</span> {
<span class="doccomment">/// Allows some origins, with a mix of exact matches or regex matches</span>
<span class="doccomment">///</span>
<span class="doccomment">/// Validation is not performed at this stage, but at a later stage.</span>
<span class="doccomment">///</span>
<span class="doccomment">/// Exact matches are matched exactly with the</span>
<span class="doccomment">/// [ASCII Serialization](https://html.spec.whatwg.org/multipage/origin.html#ascii-serialisation-of-an-origin)</span>
<span class="doccomment">/// of the origin.</span>
<span class="doccomment">///</span>
<span class="doccomment">/// Regular expressions are tested for matches against the</span>
<span class="doccomment">/// [ASCII Serialization](https://html.spec.whatwg.org/multipage/origin.html#ascii-serialisation-of-an-origin)</span>
<span class="doccomment">/// of the origin.</span>
<span class="doccomment">///</span>
<span class="doccomment">/// # Opaque Origins</span>
<span class="doccomment">/// The [specification](https://html.spec.whatwg.org/multipage/origin.html) defines an Opaque Origin</span>
<span class="doccomment">/// as one that cannot be recreated. You can refer to the source code for the [`url::Url::origin`]</span>
<span class="doccomment">/// method to see how an Opaque Origin is determined. Examples of Opaque origins might include</span>
<span class="doccomment">/// schemes like `file://` or Browser specific schemes like `&quot;moz-extension://` or</span>
<span class="doccomment">/// `chrome-extension://`.</span>
<span class="doccomment">///</span>
<span class="doccomment">/// Opaque Origins cannot be matched exactly. You must use Regex to match Opaque Origins. If you</span>
<span class="doccomment">/// attempt to create [`Cors`] from [`CorsOptions`], you will get an error.</span>
<span class="doccomment">/// # Warning about Regex expressions</span>
<span class="doccomment">/// By default, regex expressions are</span>
<span class="doccomment">/// [unanchored](https://docs.rs/regex/1.1.2/regex/struct.RegexSet.html#method.is_match).</span>
<span class="doccomment">///</span>
<span class="doccomment">/// This means that if the regex does not start with `^` or `\A`, or end with `$` or `\z`,</span>
<span class="doccomment">/// then it is permitted to match anywhere in the text. You are encouraged to use the anchors when</span>
<span class="doccomment">/// crafting your Regex expressions.</span>
<span class="attribute">#[<span class="ident">allow</span>(<span class="ident">clippy</span>::<span class="ident">needless_lifetimes</span>)]</span>
<span class="kw">pub</span> <span class="kw">fn</span> <span class="ident">some</span><span class="op">&lt;</span><span class="lifetime">&#39;a</span>, <span class="lifetime">&#39;b</span>, <span class="ident">S1</span>: <span class="ident">AsRef</span><span class="op">&lt;</span><span class="ident">str</span><span class="op">&gt;</span>, <span class="ident">S2</span>: <span class="ident">AsRef</span><span class="op">&lt;</span><span class="ident">str</span><span class="op">&gt;</span><span class="op">&gt;</span>(<span class="ident">exact</span>: <span class="kw-2">&amp;</span><span class="lifetime">&#39;a</span> [<span class="ident">S1</span>], <span class="ident">regex</span>: <span class="kw-2">&amp;</span><span class="lifetime">&#39;b</span> [<span class="ident">S2</span>]) <span class="op">-</span><span class="op">&gt;</span> <span class="self">Self</span> {
<span class="ident">AllOrSome</span>::<span class="prelude-val">Some</span>(<span class="ident">Origins</span> {
<span class="ident">exact</span>: <span class="prelude-val">Some</span>(<span class="ident">exact</span>.<span class="ident">iter</span>().<span class="ident">map</span>(<span class="op">|</span><span class="ident">s</span><span class="op">|</span> <span class="ident">s</span>.<span class="ident">as_ref</span>().<span class="ident">to_string</span>()).<span class="ident">collect</span>()),
<span class="ident">regex</span>: <span class="prelude-val">Some</span>(<span class="ident">regex</span>.<span class="ident">iter</span>().<span class="ident">map</span>(<span class="op">|</span><span class="ident">s</span><span class="op">|</span> <span class="ident">s</span>.<span class="ident">as_ref</span>().<span class="ident">to_string</span>()).<span class="ident">collect</span>()),
..<span class="ident">Default</span>::<span class="ident">default</span>()
})
}
<span class="doccomment">/// Allows some _exact_ origins</span>
<span class="doccomment">///</span>
<span class="doccomment">/// Validation is not performed at this stage, but at a later stage.</span>
<span class="doccomment">///</span>
<span class="doccomment">/// Exact matches are matched exactly with the</span>
<span class="doccomment">/// [ASCII Serialization](https://html.spec.whatwg.org/multipage/origin.html#ascii-serialisation-of-an-origin)</span>
<span class="doccomment">/// of the origin.</span>
<span class="doccomment">/// # Opaque Origins</span>
<span class="doccomment">/// The [specification](https://html.spec.whatwg.org/multipage/origin.html) defines an Opaque Origin</span>
<span class="doccomment">/// as one that cannot be recreated. You can refer to the source code for the [`url::Url::origin`]</span>
<span class="doccomment">/// method to see how an Opaque Origin is determined. Examples of Opaque origins might include</span>
<span class="doccomment">/// schemes like `file://` or Browser specific schemes like `&quot;moz-extension://` or</span>
<span class="doccomment">/// `chrome-extension://`.</span>
<span class="kw">pub</span> <span class="kw">fn</span> <span class="ident">some_exact</span><span class="op">&lt;</span><span class="ident">S</span>: <span class="ident">AsRef</span><span class="op">&lt;</span><span class="ident">str</span><span class="op">&gt;</span><span class="op">&gt;</span>(<span class="ident">exact</span>: <span class="kw-2">&amp;</span>[<span class="ident">S</span>]) <span class="op">-</span><span class="op">&gt;</span> <span class="self">Self</span> {
<span class="ident">AllOrSome</span>::<span class="prelude-val">Some</span>(<span class="ident">Origins</span> {
<span class="ident">exact</span>: <span class="prelude-val">Some</span>(<span class="ident">exact</span>.<span class="ident">iter</span>().<span class="ident">map</span>(<span class="op">|</span><span class="ident">s</span><span class="op">|</span> <span class="ident">s</span>.<span class="ident">as_ref</span>().<span class="ident">to_string</span>()).<span class="ident">collect</span>()),
..<span class="ident">Default</span>::<span class="ident">default</span>()
})
}
<span class="doccomment">/// Allow some regular expression origins</span>
<span class="doccomment">///</span>
<span class="doccomment">/// Validation is not performed at this stage, but at a later stage.</span>
<span class="doccomment">///</span>
<span class="doccomment">/// Regular expressions are tested for matches against the</span>
<span class="doccomment">/// [ASCII Serialization](https://html.spec.whatwg.org/multipage/origin.html#ascii-serialisation-of-an-origin)</span>
<span class="doccomment">/// of the origin.</span>
<span class="doccomment">///</span>
<span class="doccomment">/// # Warning about Regex expressions</span>
<span class="doccomment">/// By default, regex expressions are</span>
<span class="doccomment">/// [unanchored](https://docs.rs/regex/1.1.2/regex/struct.RegexSet.html#method.is_match).</span>
<span class="doccomment">///</span>
<span class="doccomment">/// This means that if the regex does not start with `^` or `\A`, or end with `$` or `\z`,</span>
<span class="doccomment">/// then it is permitted to match anywhere in the text. You are encouraged to use the anchors when</span>
<span class="doccomment">/// crafting your Regex expressions.</span>
<span class="kw">pub</span> <span class="kw">fn</span> <span class="ident">some_regex</span><span class="op">&lt;</span><span class="ident">S</span>: <span class="ident">AsRef</span><span class="op">&lt;</span><span class="ident">str</span><span class="op">&gt;</span><span class="op">&gt;</span>(<span class="ident">regex</span>: <span class="kw-2">&amp;</span>[<span class="ident">S</span>]) <span class="op">-</span><span class="op">&gt;</span> <span class="self">Self</span> {
<span class="ident">AllOrSome</span>::<span class="prelude-val">Some</span>(<span class="ident">Origins</span> {
<span class="ident">regex</span>: <span class="prelude-val">Some</span>(<span class="ident">regex</span>.<span class="ident">iter</span>().<span class="ident">map</span>(<span class="op">|</span><span class="ident">s</span><span class="op">|</span> <span class="ident">s</span>.<span class="ident">as_ref</span>().<span class="ident">to_string</span>()).<span class="ident">collect</span>()),
..<span class="ident">Default</span>::<span class="ident">default</span>()
})
}
<span class="doccomment">/// Allow some `null` origins</span>
<span class="kw">pub</span> <span class="kw">fn</span> <span class="ident">some_null</span>() <span class="op">-</span><span class="op">&gt;</span> <span class="self">Self</span> {
<span class="ident">AllOrSome</span>::<span class="prelude-val">Some</span>(<span class="ident">Origins</span> {
<span class="ident">allow_null</span>: <span class="bool-val">true</span>,
..<span class="ident">Default</span>::<span class="ident">default</span>()
})
}
<span class="doccomment">/// Allows all origins</span>
<span class="kw">pub</span> <span class="kw">fn</span> <span class="ident">all</span>() <span class="op">-</span><span class="op">&gt;</span> <span class="self">Self</span> {
<span class="ident">AllOrSome</span>::<span class="ident">All</span>
}
}
<span class="doccomment">/// Origins that are allowed to make CORS requests.</span>
<span class="doccomment">///</span>
<span class="doccomment">/// An origin is defined according to the defined</span>
<span class="doccomment">/// [syntax](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Origin).</span>
<span class="doccomment">///</span>
<span class="doccomment">/// Origins can be specified as an exact match or using regex.</span>
<span class="doccomment">///</span>
<span class="doccomment">/// These Origins are specified as logical `ORs`. That is, if any of the origins match, the entire</span>
<span class="doccomment">/// request is considered to be valid.</span>
<span class="doccomment">///</span>
<span class="doccomment">/// Exact matches are matched exactly with the</span>
<span class="doccomment">/// [ASCII Serialization](https://html.spec.whatwg.org/multipage/origin.html#ascii-serialisation-of-an-origin)</span>
<span class="doccomment">/// of the origin.</span>
<span class="doccomment">///</span>
<span class="doccomment">/// Regular expressions are tested for matches against the</span>
<span class="doccomment">/// [ASCII Serialization](https://html.spec.whatwg.org/multipage/origin.html#ascii-serialisation-of-an-origin)</span>
<span class="doccomment">/// of the origin.</span>
<span class="doccomment">///</span>
<span class="doccomment">/// # Opaque Origins</span>
<span class="doccomment">/// The [specification](https://html.spec.whatwg.org/multipage/origin.html) defines an Opaque Origin</span>
<span class="doccomment">/// as one that cannot be recreated. You can refer to the source code for the [`url::Url::origin`]</span>
<span class="doccomment">/// method to see how an Opaque Origin is determined. Examples of Opaque origins might include</span>
<span class="doccomment">/// schemes like `file://` or Browser specific schemes like `&quot;moz-extension://` or</span>
<span class="doccomment">/// `chrome-extension://`.</span>
<span class="doccomment">///</span>
<span class="doccomment">/// Opaque Origins cannot be matched exactly. You must use Regex to match Opaque Origins. If you</span>
<span class="doccomment">/// attempt to create [`Cors`] from [`CorsOptions`], you will get an error.</span>
<span class="doccomment">///</span>
<span class="doccomment">/// # Warning about Regex expressions</span>
<span class="doccomment">/// By default, regex expressions are</span>
<span class="doccomment">/// [unanchored](https://docs.rs/regex/1.1.2/regex/struct.RegexSet.html#method.is_match).</span>
<span class="doccomment">///</span>
<span class="doccomment">/// This means that if the regex does not start with `^` or `\A`, or end with `$` or `\z`,</span>
<span class="doccomment">/// then it is permitted to match anywhere in the text. You are encouraged to use the anchors when</span>
<span class="doccomment">/// crafting your Regex expressions.</span>
<span class="attribute">#[<span class="ident">derive</span>(<span class="ident">Clone</span>, <span class="ident">PartialEq</span>, <span class="ident">Eq</span>, <span class="ident">Debug</span>, <span class="ident">Default</span>)]</span>
<span class="attribute">#[<span class="ident">cfg_attr</span>(<span class="ident">feature</span> <span class="op">=</span> <span class="string">&quot;serialization&quot;</span>, <span class="ident">derive</span>(<span class="ident">Serialize</span>, <span class="ident">Deserialize</span>))]</span>
<span class="attribute">#[<span class="ident">cfg_attr</span>(<span class="ident">feature</span> <span class="op">=</span> <span class="string">&quot;serialization&quot;</span>, <span class="ident">serde</span>(<span class="ident">default</span>))]</span>
<span class="kw">pub</span> <span class="kw">struct</span> <span class="ident">Origins</span> {
<span class="doccomment">/// Whether null origins are accepted</span>
<span class="attribute">#[<span class="ident">cfg_attr</span>(<span class="ident">feature</span> <span class="op">=</span> <span class="string">&quot;serialization&quot;</span>, <span class="ident">serde</span>(<span class="ident">default</span>))]</span>
<span class="kw">pub</span> <span class="ident">allow_null</span>: <span class="ident">bool</span>,
<span class="doccomment">/// Origins that must be matched exactly as provided.</span>
<span class="doccomment">///</span>
<span class="doccomment">/// These __must__ be valid URL strings that will be parsed and validated when</span>
<span class="doccomment">/// creating [`Cors`].</span>
<span class="doccomment">///</span>
<span class="doccomment">/// Exact matches are matched exactly with the</span>
<span class="doccomment">/// [ASCII Serialization](https://html.spec.whatwg.org/multipage/origin.html#ascii-serialisation-of-an-origin)</span>
<span class="doccomment">/// of the origin.</span>
<span class="doccomment">///</span>
<span class="doccomment">/// # Opaque Origins</span>
<span class="doccomment">/// The [specification](https://html.spec.whatwg.org/multipage/origin.html) defines an Opaque Origin</span>
<span class="doccomment">/// as one that cannot be recreated. You can refer to the source code for the [`url::Url::origin`]</span>
<span class="doccomment">/// method to see how an Opaque Origin is determined. Examples of Opaque origins might include</span>
<span class="doccomment">/// schemes like `file://` or Browser specific schemes like `&quot;moz-extension://` or</span>
<span class="doccomment">/// `chrome-extension://`.</span>
<span class="doccomment">///</span>
<span class="doccomment">/// Opaque Origins cannot be matched exactly. You must use Regex to match Opaque Origins. If you</span>
<span class="doccomment">/// attempt to create [`Cors`] from [`CorsOptions`], you will get an error.</span>
<span class="attribute">#[<span class="ident">cfg_attr</span>(<span class="ident">feature</span> <span class="op">=</span> <span class="string">&quot;serialization&quot;</span>, <span class="ident">serde</span>(<span class="ident">default</span>))]</span>
<span class="kw">pub</span> <span class="ident">exact</span>: <span class="prelude-ty">Option</span><span class="op">&lt;</span><span class="ident">HashSet</span><span class="op">&lt;</span><span class="ident">String</span><span class="op">&gt;</span><span class="op">&gt;</span>,
<span class="doccomment">/// Origins that will be matched via __any__ regex in this list.</span>
<span class="doccomment">///</span>
<span class="doccomment">/// These __must__ be valid Regex that will be parsed and validated when creating [`Cors`].</span>
<span class="doccomment">///</span>
<span class="doccomment">/// The regex will be matched according to the</span>
<span class="doccomment">/// [ASCII serialization](https://html.spec.whatwg.org/multipage/#ascii-serialisation-of-an-origin)</span>
<span class="doccomment">/// of the incoming Origin.</span>
<span class="doccomment">///</span>
<span class="doccomment">/// For more information on the syntax of Regex in Rust, see the</span>
<span class="doccomment">/// [documentation](https://docs.rs/regex).</span>
<span class="doccomment">///</span>
<span class="doccomment">/// Regular expressions are tested for matches against the</span>
<span class="doccomment">/// [ASCII Serialization](https://html.spec.whatwg.org/multipage/origin.html#ascii-serialisation-of-an-origin)</span>
<span class="doccomment">/// of the origin.</span>
<span class="doccomment">///</span>
<span class="doccomment">/// # Warning about Regex expressions</span>
<span class="doccomment">/// By default, regex expressions are</span>
<span class="doccomment">/// [unanchored](https://docs.rs/regex/1.1.2/regex/struct.RegexSet.html#method.is_match).</span>
<span class="attribute">#[<span class="ident">cfg_attr</span>(<span class="ident">feature</span> <span class="op">=</span> <span class="string">&quot;serialization&quot;</span>, <span class="ident">serde</span>(<span class="ident">default</span>))]</span>
<span class="kw">pub</span> <span class="ident">regex</span>: <span class="prelude-ty">Option</span><span class="op">&lt;</span><span class="ident">HashSet</span><span class="op">&lt;</span><span class="ident">String</span><span class="op">&gt;</span><span class="op">&gt;</span>,
}
<span class="doccomment">/// Parsed set of configured allowed origins</span>
<span class="attribute">#[<span class="ident">derive</span>(<span class="ident">Clone</span>, <span class="ident">Debug</span>)]</span>
<span class="kw">pub</span>(<span class="kw">crate</span>) <span class="kw">struct</span> <span class="ident">ParsedAllowedOrigins</span> {
<span class="kw">pub</span> <span class="ident">allow_null</span>: <span class="ident">bool</span>,
<span class="kw">pub</span> <span class="ident">exact</span>: <span class="ident">HashSet</span><span class="op">&lt;</span><span class="ident">url</span>::<span class="ident">Origin</span><span class="op">&gt;</span>,
<span class="kw">pub</span> <span class="ident">regex</span>: <span class="prelude-ty">Option</span><span class="op">&lt;</span><span class="ident">RegexSet</span><span class="op">&gt;</span>,
}
<span class="kw">impl</span> <span class="ident">ParsedAllowedOrigins</span> {
<span class="kw">fn</span> <span class="ident">parse</span>(<span class="ident">origins</span>: <span class="kw-2">&amp;</span><span class="ident">Origins</span>) <span class="op">-</span><span class="op">&gt;</span> <span class="prelude-ty">Result</span><span class="op">&lt;</span><span class="self">Self</span>, <span class="ident">Error</span><span class="op">&gt;</span> {
<span class="kw">let</span> <span class="ident">exact</span>: <span class="prelude-ty">Result</span><span class="op">&lt;</span><span class="ident">Vec</span><span class="op">&lt;</span>(<span class="kw-2">&amp;</span><span class="ident">str</span>, <span class="ident">url</span>::<span class="ident">Origin</span>)<span class="op">&gt;</span>, <span class="ident">Error</span><span class="op">&gt;</span> <span class="op">=</span> <span class="kw">match</span> <span class="kw-2">&amp;</span><span class="ident">origins</span>.<span class="ident">exact</span> {
<span class="prelude-val">Some</span>(<span class="ident">exact</span>) <span class="op">=</span><span class="op">&gt;</span> <span class="ident">exact</span>
.<span class="ident">iter</span>()
.<span class="ident">map</span>(<span class="op">|</span><span class="ident">url</span><span class="op">|</span> <span class="prelude-val">Ok</span>((<span class="ident">url</span>.<span class="ident">as_str</span>(), <span class="ident">to_origin</span>(<span class="ident">url</span>.<span class="ident">as_str</span>())<span class="question-mark">?</span>)))
.<span class="ident">collect</span>(),
<span class="prelude-val">None</span> <span class="op">=</span><span class="op">&gt;</span> <span class="prelude-val">Ok</span>(<span class="ident">Default</span>::<span class="ident">default</span>()),
};
<span class="kw">let</span> <span class="ident">exact</span> <span class="op">=</span> <span class="ident">exact</span><span class="question-mark">?</span>;
<span class="comment">// Let&#39;s check if they are Opaque</span>
<span class="kw">let</span> (<span class="ident">tuple</span>, <span class="ident">opaque</span>): (<span class="ident">Vec</span><span class="op">&lt;</span><span class="kw">_</span><span class="op">&gt;</span>, <span class="ident">Vec</span><span class="op">&lt;</span><span class="kw">_</span><span class="op">&gt;</span>) <span class="op">=</span>
<span class="ident">exact</span>.<span class="ident">into_iter</span>().<span class="ident">partition</span>(<span class="op">|</span>(<span class="kw">_</span>, <span class="ident">url</span>)<span class="op">|</span> <span class="ident">url</span>.<span class="ident">is_tuple</span>());
<span class="kw">if</span> <span class="op">!</span><span class="ident">opaque</span>.<span class="ident">is_empty</span>() {
<span class="kw">return</span> <span class="prelude-val">Err</span>(<span class="ident">Error</span>::<span class="ident">OpaqueAllowedOrigin</span>(
<span class="ident">opaque</span>
.<span class="ident">into_iter</span>()
.<span class="ident">map</span>(<span class="op">|</span>(<span class="ident">original</span>, <span class="kw">_</span>)<span class="op">|</span> <span class="ident">original</span>.<span class="ident">to_string</span>())
.<span class="ident">collect</span>(),
));
}
<span class="kw">let</span> <span class="ident">exact</span> <span class="op">=</span> <span class="ident">tuple</span>.<span class="ident">into_iter</span>().<span class="ident">map</span>(<span class="op">|</span>(<span class="kw">_</span>, <span class="ident">url</span>)<span class="op">|</span> <span class="ident">url</span>).<span class="ident">collect</span>();
<span class="kw">let</span> <span class="ident">regex</span> <span class="op">=</span> <span class="kw">match</span> <span class="kw-2">&amp;</span><span class="ident">origins</span>.<span class="ident">regex</span> {
<span class="prelude-val">None</span> <span class="op">=</span><span class="op">&gt;</span> <span class="prelude-val">None</span>,
<span class="prelude-val">Some</span>(<span class="kw-2">ref</span> <span class="ident">regex</span>) <span class="op">=</span><span class="op">&gt;</span> <span class="prelude-val">Some</span>(<span class="ident">RegexSet</span>::<span class="ident">new</span>(<span class="ident">regex</span>)<span class="question-mark">?</span>),
};
<span class="prelude-val">Ok</span>(<span class="self">Self</span> {
<span class="ident">allow_null</span>: <span class="ident">origins</span>.<span class="ident">allow_null</span>,
<span class="ident">exact</span>,
<span class="ident">regex</span>,
})
}
<span class="kw">fn</span> <span class="ident">verify</span>(<span class="kw-2">&amp;</span><span class="self">self</span>, <span class="ident">origin</span>: <span class="kw-2">&amp;</span><span class="ident">Origin</span>) <span class="op">-</span><span class="op">&gt;</span> <span class="ident">bool</span> {
<span class="macro">info_</span><span class="macro">!</span>(<span class="string">&quot;Verifying origin: {}&quot;</span>, <span class="ident">origin</span>);
<span class="kw">match</span> <span class="ident">origin</span> {
<span class="ident">Origin</span>::<span class="ident">Null</span> <span class="op">=</span><span class="op">&gt;</span> {
<span class="macro">info_</span><span class="macro">!</span>(<span class="string">&quot;Origin is null. Allowing? {}&quot;</span>, <span class="self">self</span>.<span class="ident">allow_null</span>);
<span class="self">self</span>.<span class="ident">allow_null</span>
}
<span class="ident">Origin</span>::<span class="ident">Parsed</span>(<span class="kw-2">ref</span> <span class="ident">parsed</span>) <span class="op">=</span><span class="op">&gt;</span> {
<span class="macro">assert</span><span class="macro">!</span>(
<span class="ident">parsed</span>.<span class="ident">is_tuple</span>(),
<span class="string">&quot;Parsed Origin is not tuple. This is a bug. Please report&quot;</span>
);
<span class="comment">// Verify by exact, then regex</span>
<span class="kw">if</span> <span class="self">self</span>.<span class="ident">exact</span>.<span class="ident">get</span>(<span class="ident">parsed</span>).<span class="ident">is_some</span>() {
<span class="macro">info_</span><span class="macro">!</span>(<span class="string">&quot;Origin has an exact match&quot;</span>);
<span class="kw">return</span> <span class="bool-val">true</span>;
}
<span class="kw">if</span> <span class="kw">let</span> <span class="prelude-val">Some</span>(<span class="ident">regex_set</span>) <span class="op">=</span> <span class="kw-2">&amp;</span><span class="self">self</span>.<span class="ident">regex</span> {
<span class="kw">let</span> <span class="ident">regex_match</span> <span class="op">=</span> <span class="ident">regex_set</span>.<span class="ident">is_match</span>(<span class="kw-2">&amp;</span><span class="ident">parsed</span>.<span class="ident">ascii_serialization</span>());
<span class="macro">debug_</span><span class="macro">!</span>(<span class="string">&quot;Matching against regex set {:#?}&quot;</span>, <span class="ident">regex_set</span>);
<span class="macro">info_</span><span class="macro">!</span>(<span class="string">&quot;Origin has a regex match? {}&quot;</span>, <span class="ident">regex_match</span>);
<span class="kw">return</span> <span class="ident">regex_match</span>;
}
<span class="macro">info</span><span class="macro">!</span>(<span class="string">&quot;Origin does not match anything&quot;</span>);
<span class="bool-val">false</span>
}
<span class="ident">Origin</span>::<span class="ident">Opaque</span>(<span class="kw-2">ref</span> <span class="ident">opaque</span>) <span class="op">=</span><span class="op">&gt;</span> {
<span class="kw">if</span> <span class="kw">let</span> <span class="prelude-val">Some</span>(<span class="ident">regex_set</span>) <span class="op">=</span> <span class="kw-2">&amp;</span><span class="self">self</span>.<span class="ident">regex</span> {
<span class="kw">let</span> <span class="ident">regex_match</span> <span class="op">=</span> <span class="ident">regex_set</span>.<span class="ident">is_match</span>(<span class="ident">opaque</span>);
<span class="macro">debug_</span><span class="macro">!</span>(<span class="string">&quot;Matching against regex set {:#?}&quot;</span>, <span class="ident">regex_set</span>);
<span class="macro">info_</span><span class="macro">!</span>(<span class="string">&quot;Origin has a regex match? {}&quot;</span>, <span class="ident">regex_match</span>);
<span class="kw">return</span> <span class="ident">regex_match</span>;
}
<span class="macro">info</span><span class="macro">!</span>(<span class="string">&quot;Origin does not match anything&quot;</span>);
<span class="bool-val">false</span>
}
}
}
}
<span class="doccomment">/// A list of allowed methods</span>
<span class="doccomment">///</span>
<span class="doccomment">/// The [list](https://api.rocket.rs/rocket/http/enum.Method.html)</span>
<span class="doccomment">/// of methods is whatever is supported by Rocket.</span>
<span class="doccomment">///</span>
<span class="doccomment">/// # Example</span>
<span class="doccomment">/// ```rust</span>
<span class="doccomment">/// use std::str::FromStr;</span>
<span class="doccomment">/// use rocket_cors::AllowedMethods;</span>
<span class="doccomment">///</span>
<span class="doccomment">/// let allowed_methods: AllowedMethods = [&quot;Get&quot;, &quot;Post&quot;, &quot;Delete&quot;]</span>
<span class="doccomment">/// .iter()</span>
<span class="doccomment">/// .map(|s| FromStr::from_str(s).unwrap())</span>
<span class="doccomment">/// .collect();</span>
<span class="doccomment">/// ```</span>
<span class="kw">pub</span> <span class="kw">type</span> <span class="ident">AllowedMethods</span> <span class="op">=</span> <span class="ident">HashSet</span><span class="op">&lt;</span><span class="ident">Method</span><span class="op">&gt;</span>;
<span class="doccomment">/// A list of allowed headers</span>
<span class="doccomment">///</span>
<span class="doccomment">/// # Examples</span>
<span class="doccomment">/// ```rust</span>
<span class="doccomment">/// use rocket_cors::AllowedHeaders;</span>
<span class="doccomment">///</span>
<span class="doccomment">/// let all_headers = AllowedHeaders::all();</span>
<span class="doccomment">/// let some_headers = AllowedHeaders::some(&amp;[&quot;Authorization&quot;, &quot;Accept&quot;]);</span>
<span class="doccomment">/// ```</span>
<span class="kw">pub</span> <span class="kw">type</span> <span class="ident">AllowedHeaders</span> <span class="op">=</span> <span class="ident">AllOrSome</span><span class="op">&lt;</span><span class="ident">HashSet</span><span class="op">&lt;</span><span class="ident">HeaderFieldName</span><span class="op">&gt;</span><span class="op">&gt;</span>;
<span class="kw">impl</span> <span class="ident">AllowedHeaders</span> {
<span class="doccomment">/// Allow some headers</span>
<span class="kw">pub</span> <span class="kw">fn</span> <span class="ident">some</span>(<span class="ident">headers</span>: <span class="kw-2">&amp;</span>[<span class="kw-2">&amp;</span><span class="ident">str</span>]) <span class="op">-</span><span class="op">&gt;</span> <span class="self">Self</span> {
<span class="ident">AllOrSome</span>::<span class="prelude-val">Some</span>(<span class="ident">headers</span>.<span class="ident">iter</span>().<span class="ident">map</span>(<span class="op">|</span><span class="ident">s</span><span class="op">|</span> (<span class="kw-2">*</span><span class="ident">s</span>).<span class="ident">to_string</span>().<span class="ident">into</span>()).<span class="ident">collect</span>())
}
<span class="doccomment">/// Allows all headers</span>
<span class="kw">pub</span> <span class="kw">fn</span> <span class="ident">all</span>() <span class="op">-</span><span class="op">&gt;</span> <span class="self">Self</span> {
<span class="ident">AllOrSome</span>::<span class="ident">All</span>
}
}
<span class="doccomment">/// Configuration options for CORS request handling.</span>
<span class="doccomment">///</span>
<span class="doccomment">/// You create a new copy of this struct by defining the configurations in the fields below.</span>
<span class="doccomment">/// This struct can also be deserialized by serde with the `serialization` feature which is</span>
<span class="doccomment">/// enabled by default.</span>
<span class="doccomment">///</span>
<span class="doccomment">/// [`Default`](https://doc.rust-lang.org/std/default/trait.Default.html) is implemented for this</span>
<span class="doccomment">/// struct. The default for each field is described in the docuementation for the field.</span>
<span class="doccomment">///</span>
<span class="doccomment">/// Before you can use this with Rocket, you will need to call the [`CorsOptions::to_cors`] method.</span>
<span class="doccomment">///</span>
<span class="doccomment">/// # Examples</span>
<span class="doccomment">///</span>
<span class="doccomment">/// You can run an example from the repository to demonstrate the JSON serialization with</span>
<span class="doccomment">/// `cargo run --example json`.</span>
<span class="doccomment">///</span>
<span class="doccomment">/// ## Pure default</span>
<span class="doccomment">/// ```rust</span>
<span class="doccomment">/// let default = rocket_cors::CorsOptions::default();</span>
<span class="doccomment">/// ```</span>
<span class="doccomment">///</span>
<span class="doccomment">/// ## JSON Examples</span>
<span class="doccomment">/// ### Default</span>
<span class="doccomment">///</span>
<span class="doccomment">/// ```json</span>
<span class="doccomment">/// {</span>
<span class="doccomment">/// &quot;allowed_origins&quot;: &quot;All&quot;,</span>
<span class="doccomment">/// &quot;allowed_methods&quot;: [</span>
<span class="doccomment">/// &quot;POST&quot;,</span>
<span class="doccomment">/// &quot;PATCH&quot;,</span>
<span class="doccomment">/// &quot;PUT&quot;,</span>
<span class="doccomment">/// &quot;DELETE&quot;,</span>
<span class="doccomment">/// &quot;HEAD&quot;,</span>
<span class="doccomment">/// &quot;OPTIONS&quot;,</span>
<span class="doccomment">/// &quot;GET&quot;</span>
<span class="doccomment">/// ],</span>
<span class="doccomment">/// &quot;allowed_headers&quot;: &quot;All&quot;,</span>
<span class="doccomment">/// &quot;allow_credentials&quot;: false,</span>
<span class="doccomment">/// &quot;expose_headers&quot;: [],</span>
<span class="doccomment">/// &quot;max_age&quot;: null,</span>
<span class="doccomment">/// &quot;send_wildcard&quot;: false,</span>
<span class="doccomment">/// &quot;fairing_route_base&quot;: &quot;/cors&quot;,</span>
<span class="doccomment">/// &quot;fairing_route_rank&quot;: 0</span>
<span class="doccomment">/// }</span>
<span class="doccomment">/// ```</span>
<span class="doccomment">/// ### Defined</span>
<span class="doccomment">/// ```json</span>
<span class="doccomment">/// {</span>
<span class="doccomment">/// &quot;allowed_origins&quot;: {</span>
<span class="doccomment">/// &quot;Some&quot;: {</span>
<span class="doccomment">/// &quot;exact&quot;: [&quot;https://www.acme.com&quot;],</span>
<span class="doccomment">/// &quot;regex&quot;: [&quot;^https://www.example-[A-z0-9]*.com$&quot;]</span>
<span class="doccomment">/// }</span>
<span class="doccomment">/// },</span>
<span class="doccomment">/// &quot;allowed_methods&quot;: [</span>
<span class="doccomment">/// &quot;POST&quot;,</span>
<span class="doccomment">/// &quot;DELETE&quot;,</span>
<span class="doccomment">/// &quot;GET&quot;</span>
<span class="doccomment">/// ],</span>
<span class="doccomment">/// &quot;allowed_headers&quot;: {</span>
<span class="doccomment">/// &quot;Some&quot;: [</span>
<span class="doccomment">/// &quot;Accept&quot;,</span>
<span class="doccomment">/// &quot;Authorization&quot;</span>
<span class="doccomment">/// ]</span>
<span class="doccomment">/// },</span>
<span class="doccomment">/// &quot;allow_credentials&quot;: true,</span>
<span class="doccomment">/// &quot;expose_headers&quot;: [</span>
<span class="doccomment">/// &quot;Content-Type&quot;,</span>
<span class="doccomment">/// &quot;X-Custom&quot;</span>
<span class="doccomment">/// ],</span>
<span class="doccomment">/// &quot;max_age&quot;: 42,</span>
<span class="doccomment">/// &quot;send_wildcard&quot;: false,</span>
<span class="doccomment">/// &quot;fairing_route_base&quot;: &quot;/mycors&quot;</span>
<span class="doccomment">/// }</span>
<span class="doccomment">///</span>
<span class="doccomment">/// ```</span>
<span class="attribute">#[<span class="ident">derive</span>(<span class="ident">Eq</span>, <span class="ident">PartialEq</span>, <span class="ident">Clone</span>, <span class="ident">Debug</span>)]</span>
<span class="attribute">#[<span class="ident">cfg_attr</span>(<span class="ident">feature</span> <span class="op">=</span> <span class="string">&quot;serialization&quot;</span>, <span class="ident">derive</span>(<span class="ident">Serialize</span>, <span class="ident">Deserialize</span>))]</span>
<span class="kw">pub</span> <span class="kw">struct</span> <span class="ident">CorsOptions</span> {
<span class="doccomment">/// Origins that are allowed to make requests.</span>
<span class="doccomment">/// Will be verified against the `Origin` request header.</span>
<span class="doccomment">///</span>
<span class="doccomment">/// When `All` is set, and `send_wildcard` is set, &quot;*&quot; will be sent in</span>
<span class="doccomment">/// the `Access-Control-Allow-Origin` response header. Otherwise, the client&#39;s `Origin` request</span>
<span class="doccomment">/// header will be echoed back in the `Access-Control-Allow-Origin` response header.</span>
<span class="doccomment">///</span>
<span class="doccomment">/// When `Some` is set, the client&#39;s `Origin` request header will be checked in a</span>
<span class="doccomment">/// case-sensitive manner.</span>
<span class="doccomment">///</span>
<span class="doccomment">/// This is the `list of origins` in the</span>
<span class="doccomment">/// [Resource Processing Model](https://www.w3.org/TR/cors/#resource-processing-model).</span>
<span class="doccomment">///</span>
<span class="doccomment">/// Defaults to `All`.</span>
<span class="doccomment">///</span>
<span class="attribute">#[<span class="ident">cfg_attr</span>(<span class="ident">feature</span> <span class="op">=</span> <span class="string">&quot;serialization&quot;</span>, <span class="ident">serde</span>(<span class="ident">default</span>))]</span>
<span class="kw">pub</span> <span class="ident">allowed_origins</span>: <span class="ident">AllowedOrigins</span>,
<span class="doccomment">/// The list of methods which the allowed origins are allowed to access for</span>
<span class="doccomment">/// non-simple requests.</span>
<span class="doccomment">///</span>
<span class="doccomment">/// This is the `list of methods` in the</span>
<span class="doccomment">/// [Resource Processing Model](https://www.w3.org/TR/cors/#resource-processing-model).</span>
<span class="doccomment">///</span>
<span class="doccomment">/// Defaults to `[GET, HEAD, POST, OPTIONS, PUT, PATCH, DELETE]`</span>
<span class="attribute">#[<span class="ident">cfg_attr</span>(
<span class="ident">feature</span> <span class="op">=</span> <span class="string">&quot;serialization&quot;</span>,
<span class="ident">serde</span>(<span class="ident">default</span> <span class="op">=</span> <span class="string">&quot;CorsOptions::default_allowed_methods&quot;</span>)
)]</span>
<span class="kw">pub</span> <span class="ident">allowed_methods</span>: <span class="ident">AllowedMethods</span>,
<span class="doccomment">/// The list of header field names which can be used when this resource is accessed by allowed</span>
<span class="doccomment">/// origins.</span>
<span class="doccomment">///</span>
<span class="doccomment">/// If `All` is set, whatever is requested by the client in `Access-Control-Request-Headers`</span>
<span class="doccomment">/// will be echoed back in the `Access-Control-Allow-Headers` header.</span>
<span class="doccomment">///</span>
<span class="doccomment">/// This is the `list of headers` in the</span>
<span class="doccomment">/// [Resource Processing Model](https://www.w3.org/TR/cors/#resource-processing-model).</span>
<span class="doccomment">///</span>
<span class="doccomment">/// Defaults to `All`.</span>
<span class="attribute">#[<span class="ident">cfg_attr</span>(<span class="ident">feature</span> <span class="op">=</span> <span class="string">&quot;serialization&quot;</span>, <span class="ident">serde</span>(<span class="ident">default</span>))]</span>
<span class="kw">pub</span> <span class="ident">allowed_headers</span>: <span class="ident">AllowedHeaders</span>,
<span class="doccomment">/// Allows users to make authenticated requests.</span>
<span class="doccomment">/// If true, injects the `Access-Control-Allow-Credentials` header in responses.</span>
<span class="doccomment">/// This allows cookies and credentials to be submitted across domains.</span>
<span class="doccomment">///</span>
<span class="doccomment">/// This **CANNOT** be used in conjunction with `allowed_origins` set to `All` and</span>
<span class="doccomment">/// `send_wildcard` set to `true`. Depending on the mode of usage, this will either result</span>
<span class="doccomment">/// in an `Error::CredentialsWithWildcardOrigin` error during Rocket launch or runtime.</span>
<span class="doccomment">///</span>
<span class="doccomment">/// Defaults to `false`.</span>
<span class="attribute">#[<span class="ident">cfg_attr</span>(<span class="ident">feature</span> <span class="op">=</span> <span class="string">&quot;serialization&quot;</span>, <span class="ident">serde</span>(<span class="ident">default</span>))]</span>
<span class="kw">pub</span> <span class="ident">allow_credentials</span>: <span class="ident">bool</span>,
<span class="doccomment">/// The list of headers which are safe to expose to the API of a CORS API specification.</span>
<span class="doccomment">/// This corresponds to the `Access-Control-Expose-Headers` responde header.</span>
<span class="doccomment">///</span>
<span class="doccomment">/// This is the `list of exposed headers` in the</span>
<span class="doccomment">/// [Resource Processing Model](https://www.w3.org/TR/cors/#resource-processing-model).</span>
<span class="doccomment">///</span>
<span class="doccomment">/// This defaults to an empty set.</span>
<span class="attribute">#[<span class="ident">cfg_attr</span>(<span class="ident">feature</span> <span class="op">=</span> <span class="string">&quot;serialization&quot;</span>, <span class="ident">serde</span>(<span class="ident">default</span>))]</span>
<span class="kw">pub</span> <span class="ident">expose_headers</span>: <span class="ident">HashSet</span><span class="op">&lt;</span><span class="ident">String</span><span class="op">&gt;</span>,
<span class="doccomment">/// The maximum time for which this CORS request maybe cached. This value is set as the</span>
<span class="doccomment">/// `Access-Control-Max-Age` header.</span>
<span class="doccomment">///</span>
<span class="doccomment">/// This defaults to `None` (unset).</span>
<span class="attribute">#[<span class="ident">cfg_attr</span>(<span class="ident">feature</span> <span class="op">=</span> <span class="string">&quot;serialization&quot;</span>, <span class="ident">serde</span>(<span class="ident">default</span>))]</span>
<span class="kw">pub</span> <span class="ident">max_age</span>: <span class="prelude-ty">Option</span><span class="op">&lt;</span><span class="ident">usize</span><span class="op">&gt;</span>,
<span class="doccomment">/// If true, and the `allowed_origins` parameter is `All`, a wildcard</span>
<span class="doccomment">/// `Access-Control-Allow-Origin` response header is sent, rather than the requests</span>
<span class="doccomment">/// `Origin` header.</span>
<span class="doccomment">///</span>
<span class="doccomment">/// This is the `supports credentials flag` in the</span>
<span class="doccomment">/// [Resource Processing Model](https://www.w3.org/TR/cors/#resource-processing-model).</span>
<span class="doccomment">///</span>
<span class="doccomment">/// This **CANNOT** be used in conjunction with `allowed_origins` set to `All` and</span>
<span class="doccomment">/// `allow_credentials` set to `true`. Depending on the mode of usage, this will either result</span>
<span class="doccomment">/// in an `Error::CredentialsWithWildcardOrigin` error during Rocket launch or runtime.</span>
<span class="doccomment">///</span>
<span class="doccomment">/// Defaults to `false`.</span>
<span class="attribute">#[<span class="ident">cfg_attr</span>(<span class="ident">feature</span> <span class="op">=</span> <span class="string">&quot;serialization&quot;</span>, <span class="ident">serde</span>(<span class="ident">default</span>))]</span>
<span class="kw">pub</span> <span class="ident">send_wildcard</span>: <span class="ident">bool</span>,
<span class="doccomment">/// When used as Fairing, Cors will need to redirect failed CORS checks to a custom route</span>
<span class="doccomment">/// mounted by the fairing. Specify the base of the route so that it doesn&#39;t clash with any</span>
<span class="doccomment">/// of your existing routes.</span>
<span class="doccomment">///</span>
<span class="doccomment">/// Defaults to &quot;/cors&quot;</span>
<span class="attribute">#[<span class="ident">cfg_attr</span>(
<span class="ident">feature</span> <span class="op">=</span> <span class="string">&quot;serialization&quot;</span>,
<span class="ident">serde</span>(<span class="ident">default</span> <span class="op">=</span> <span class="string">&quot;CorsOptions::default_fairing_route_base&quot;</span>)
)]</span>
<span class="kw">pub</span> <span class="ident">fairing_route_base</span>: <span class="ident">String</span>,
<span class="doccomment">/// When used as Fairing, Cors will need to redirect failed CORS checks to a custom route</span>
<span class="doccomment">/// mounted by the fairing. Specify the rank of the route so that it doesn&#39;t clash with any</span>
<span class="doccomment">/// of your existing routes. Remember that a higher ranked route has lower priority.</span>
<span class="doccomment">///</span>
<span class="doccomment">/// Defaults to 0</span>
<span class="attribute">#[<span class="ident">cfg_attr</span>(
<span class="ident">feature</span> <span class="op">=</span> <span class="string">&quot;serialization&quot;</span>,
<span class="ident">serde</span>(<span class="ident">default</span> <span class="op">=</span> <span class="string">&quot;CorsOptions::default_fairing_route_rank&quot;</span>)
)]</span>
<span class="kw">pub</span> <span class="ident">fairing_route_rank</span>: <span class="ident">isize</span>,
}
<span class="kw">impl</span> <span class="ident">Default</span> <span class="kw">for</span> <span class="ident">CorsOptions</span> {
<span class="kw">fn</span> <span class="ident">default</span>() <span class="op">-</span><span class="op">&gt;</span> <span class="self">Self</span> {
<span class="self">Self</span> {
<span class="ident">allowed_origins</span>: <span class="ident">Default</span>::<span class="ident">default</span>(),
<span class="ident">allowed_methods</span>: <span class="self">Self</span>::<span class="ident">default_allowed_methods</span>(),
<span class="ident">allowed_headers</span>: <span class="ident">Default</span>::<span class="ident">default</span>(),
<span class="ident">allow_credentials</span>: <span class="ident">Default</span>::<span class="ident">default</span>(),
<span class="ident">expose_headers</span>: <span class="ident">Default</span>::<span class="ident">default</span>(),
<span class="ident">max_age</span>: <span class="ident">Default</span>::<span class="ident">default</span>(),
<span class="ident">send_wildcard</span>: <span class="ident">Default</span>::<span class="ident">default</span>(),
<span class="ident">fairing_route_base</span>: <span class="self">Self</span>::<span class="ident">default_fairing_route_base</span>(),
<span class="ident">fairing_route_rank</span>: <span class="self">Self</span>::<span class="ident">default_fairing_route_rank</span>(),
}
}
}
<span class="kw">impl</span> <span class="ident">CorsOptions</span> {
<span class="kw">fn</span> <span class="ident">default_allowed_methods</span>() <span class="op">-</span><span class="op">&gt;</span> <span class="ident">HashSet</span><span class="op">&lt;</span><span class="ident">Method</span><span class="op">&gt;</span> {
<span class="kw">use</span> <span class="ident">rocket</span>::<span class="ident">http</span>::<span class="ident">Method</span>;
<span class="macro">vec</span><span class="macro">!</span>[
<span class="ident">Method</span>::<span class="ident">Get</span>,
<span class="ident">Method</span>::<span class="ident">Head</span>,
<span class="ident">Method</span>::<span class="ident">Post</span>,
<span class="ident">Method</span>::<span class="ident">Options</span>,
<span class="ident">Method</span>::<span class="ident">Put</span>,
<span class="ident">Method</span>::<span class="ident">Patch</span>,
<span class="ident">Method</span>::<span class="ident">Delete</span>,
]
.<span class="ident">into_iter</span>()
.<span class="ident">map</span>(<span class="ident">From</span>::<span class="ident">from</span>)
.<span class="ident">collect</span>()
}
<span class="kw">fn</span> <span class="ident">default_fairing_route_base</span>() <span class="op">-</span><span class="op">&gt;</span> <span class="ident">String</span> {
<span class="string">&quot;/cors&quot;</span>.<span class="ident">to_string</span>()
}
<span class="kw">fn</span> <span class="ident">default_fairing_route_rank</span>() <span class="op">-</span><span class="op">&gt;</span> <span class="ident">isize</span> {
<span class="number">0</span>
}
<span class="doccomment">/// Validates if any of the settings are disallowed, incorrect, or illegal</span>
<span class="kw">pub</span> <span class="kw">fn</span> <span class="ident">validate</span>(<span class="kw-2">&amp;</span><span class="self">self</span>) <span class="op">-</span><span class="op">&gt;</span> <span class="prelude-ty">Result</span><span class="op">&lt;</span>(), <span class="ident">Error</span><span class="op">&gt;</span> {
<span class="kw">if</span> <span class="self">self</span>.<span class="ident">allowed_origins</span>.<span class="ident">is_all</span>() <span class="kw-2">&amp;</span><span class="op">&amp;</span> <span class="self">self</span>.<span class="ident">send_wildcard</span> <span class="kw-2">&amp;</span><span class="op">&amp;</span> <span class="self">self</span>.<span class="ident">allow_credentials</span> {
<span class="kw">return</span> <span class="prelude-val">Err</span>(<span class="ident">Error</span>::<span class="ident">CredentialsWithWildcardOrigin</span>);
}
<span class="prelude-val">Ok</span>(())
}
<span class="doccomment">/// Creates a [`Cors`] struct that can be used to respond to requests or as a Rocket Fairing</span>
<span class="kw">pub</span> <span class="kw">fn</span> <span class="ident">to_cors</span>(<span class="kw-2">&amp;</span><span class="self">self</span>) <span class="op">-</span><span class="op">&gt;</span> <span class="prelude-ty">Result</span><span class="op">&lt;</span><span class="ident">Cors</span>, <span class="ident">Error</span><span class="op">&gt;</span> {
<span class="ident">Cors</span>::<span class="ident">from_options</span>(<span class="self">self</span>)
}
}
<span class="doccomment">/// Response generator and [Fairing](https://rocket.rs/guide/fairings/) for CORS</span>
<span class="doccomment">///</span>
<span class="doccomment">/// This struct can be as Fairing or in an ad-hoc manner to generate CORS response. See the</span>
<span class="doccomment">/// documentation at the [crate root](index.html) for usage information.</span>
<span class="doccomment">///</span>
<span class="doccomment">/// This struct can be created by using [`CorsOptions::to_cors`] or [`Cors::from_options`].</span>
<span class="attribute">#[<span class="ident">derive</span>(<span class="ident">Clone</span>, <span class="ident">Debug</span>)]</span>
<span class="kw">pub</span> <span class="kw">struct</span> <span class="ident">Cors</span> {
<span class="kw">pub</span>(<span class="kw">crate</span>) <span class="ident">allowed_origins</span>: <span class="ident">AllOrSome</span><span class="op">&lt;</span><span class="ident">ParsedAllowedOrigins</span><span class="op">&gt;</span>,
<span class="kw">pub</span>(<span class="kw">crate</span>) <span class="ident">allowed_methods</span>: <span class="ident">AllowedMethods</span>,
<span class="kw">pub</span>(<span class="kw">crate</span>) <span class="ident">allowed_headers</span>: <span class="ident">AllOrSome</span><span class="op">&lt;</span><span class="ident">HashSet</span><span class="op">&lt;</span><span class="ident">HeaderFieldName</span><span class="op">&gt;</span><span class="op">&gt;</span>,
<span class="kw">pub</span>(<span class="kw">crate</span>) <span class="ident">allow_credentials</span>: <span class="ident">bool</span>,
<span class="kw">pub</span>(<span class="kw">crate</span>) <span class="ident">expose_headers</span>: <span class="ident">HashSet</span><span class="op">&lt;</span><span class="ident">String</span><span class="op">&gt;</span>,
<span class="kw">pub</span>(<span class="kw">crate</span>) <span class="ident">max_age</span>: <span class="prelude-ty">Option</span><span class="op">&lt;</span><span class="ident">usize</span><span class="op">&gt;</span>,
<span class="kw">pub</span>(<span class="kw">crate</span>) <span class="ident">send_wildcard</span>: <span class="ident">bool</span>,
<span class="kw">pub</span>(<span class="kw">crate</span>) <span class="ident">fairing_route_base</span>: <span class="ident">String</span>,
<span class="kw">pub</span>(<span class="kw">crate</span>) <span class="ident">fairing_route_rank</span>: <span class="ident">isize</span>,
}
<span class="kw">impl</span> <span class="ident">Cors</span> {
<span class="doccomment">/// Create a `Cors` struct from a [`CorsOptions`]</span>
<span class="kw">pub</span> <span class="kw">fn</span> <span class="ident">from_options</span>(<span class="ident">options</span>: <span class="kw-2">&amp;</span><span class="ident">CorsOptions</span>) <span class="op">-</span><span class="op">&gt;</span> <span class="prelude-ty">Result</span><span class="op">&lt;</span><span class="self">Self</span>, <span class="ident">Error</span><span class="op">&gt;</span> {
<span class="ident">options</span>.<span class="ident">validate</span>()<span class="question-mark">?</span>;
<span class="kw">let</span> <span class="ident">allowed_origins</span> <span class="op">=</span> <span class="ident">parse_allowed_origins</span>(<span class="kw-2">&amp;</span><span class="ident">options</span>.<span class="ident">allowed_origins</span>)<span class="question-mark">?</span>;
<span class="prelude-val">Ok</span>(<span class="ident">Cors</span> {
<span class="ident">allowed_origins</span>,
<span class="ident">allowed_methods</span>: <span class="ident">options</span>.<span class="ident">allowed_methods</span>.<span class="ident">clone</span>(),
<span class="ident">allowed_headers</span>: <span class="ident">options</span>.<span class="ident">allowed_headers</span>.<span class="ident">clone</span>(),
<span class="ident">allow_credentials</span>: <span class="ident">options</span>.<span class="ident">allow_credentials</span>,
<span class="ident">expose_headers</span>: <span class="ident">options</span>.<span class="ident">expose_headers</span>.<span class="ident">clone</span>(),
<span class="ident">max_age</span>: <span class="ident">options</span>.<span class="ident">max_age</span>,
<span class="ident">send_wildcard</span>: <span class="ident">options</span>.<span class="ident">send_wildcard</span>,
<span class="ident">fairing_route_base</span>: <span class="ident">options</span>.<span class="ident">fairing_route_base</span>.<span class="ident">clone</span>(),
<span class="ident">fairing_route_rank</span>: <span class="ident">options</span>.<span class="ident">fairing_route_rank</span>,
})
}
<span class="doccomment">/// Manually respond to a request with CORS checks and headers using an Owned `Cors`.</span>
<span class="doccomment">///</span>
<span class="doccomment">/// Use this variant when your `Cors` struct will not live at least as long as the whole `&#39;r`</span>
<span class="doccomment">/// lifetime of the request.</span>
<span class="doccomment">///</span>
<span class="doccomment">/// After the CORS checks are done, the passed in handler closure will be run to generate a</span>
<span class="doccomment">/// final response. You will have to merge your response with the `Guard` that you have been</span>
<span class="doccomment">/// passed in to include the CORS headers.</span>
<span class="doccomment">///</span>
<span class="doccomment">/// See the documentation at the [crate root](index.html) for usage information.</span>
<span class="kw">pub</span> <span class="kw">fn</span> <span class="ident">respond_owned</span><span class="op">&lt;</span><span class="lifetime">&#39;r</span>, <span class="ident">F</span>, <span class="ident">R</span><span class="op">&gt;</span>(<span class="self">self</span>, <span class="ident">handler</span>: <span class="ident">F</span>) <span class="op">-</span><span class="op">&gt;</span> <span class="prelude-ty">Result</span><span class="op">&lt;</span><span class="ident">ManualResponder</span><span class="op">&lt;</span><span class="lifetime">&#39;r</span>, <span class="ident">F</span>, <span class="ident">R</span><span class="op">&gt;</span>, <span class="ident">Error</span><span class="op">&gt;</span>
<span class="kw">where</span>
<span class="ident">F</span>: <span class="ident">FnOnce</span>(<span class="ident">Guard</span><span class="op">&lt;</span><span class="lifetime">&#39;r</span><span class="op">&gt;</span>) <span class="op">-</span><span class="op">&gt;</span> <span class="ident">R</span> <span class="op">+</span> <span class="lifetime">&#39;r</span>,
<span class="ident">R</span>: <span class="ident">response</span>::<span class="ident">Responder</span><span class="op">&lt;</span><span class="lifetime">&#39;r</span><span class="op">&gt;</span>,
{
<span class="prelude-val">Ok</span>(<span class="ident">ManualResponder</span>::<span class="ident">new</span>(<span class="ident">Cow</span>::<span class="ident">Owned</span>(<span class="self">self</span>), <span class="ident">handler</span>))
}
<span class="doccomment">/// Manually respond to a request with CORS checks and headers using a borrowed `Cors`.</span>
<span class="doccomment">///</span>
<span class="doccomment">/// Use this variant when your `Cors` struct will live at least as long as the whole `&#39;r`</span>
<span class="doccomment">/// lifetime of the request. If you are getting your `Cors` from Rocket&#39;s state, you will have</span>
<span class="doccomment">/// to use the [`inner` function](https://api.rocket.rs/rocket/struct.State.html#method.inner)</span>
<span class="doccomment">/// to get a longer borrowed lifetime.</span>
<span class="doccomment">///</span>
<span class="doccomment">/// After the CORS checks are done, the passed in handler closure will be run to generate a</span>
<span class="doccomment">/// final response. You will have to merge your response with the `Guard` that you have been</span>
<span class="doccomment">/// passed in to include the CORS headers.</span>
<span class="doccomment">///</span>
<span class="doccomment">/// See the documentation at the [crate root](index.html) for usage information.</span>
<span class="kw">pub</span> <span class="kw">fn</span> <span class="ident">respond_borrowed</span><span class="op">&lt;</span><span class="lifetime">&#39;r</span>, <span class="ident">F</span>, <span class="ident">R</span><span class="op">&gt;</span>(
<span class="kw-2">&amp;</span><span class="lifetime">&#39;r</span> <span class="self">self</span>,
<span class="ident">handler</span>: <span class="ident">F</span>,
) <span class="op">-</span><span class="op">&gt;</span> <span class="prelude-ty">Result</span><span class="op">&lt;</span><span class="ident">ManualResponder</span><span class="op">&lt;</span><span class="lifetime">&#39;r</span>, <span class="ident">F</span>, <span class="ident">R</span><span class="op">&gt;</span>, <span class="ident">Error</span><span class="op">&gt;</span>
<span class="kw">where</span>
<span class="ident">F</span>: <span class="ident">FnOnce</span>(<span class="ident">Guard</span><span class="op">&lt;</span><span class="lifetime">&#39;r</span><span class="op">&gt;</span>) <span class="op">-</span><span class="op">&gt;</span> <span class="ident">R</span> <span class="op">+</span> <span class="lifetime">&#39;r</span>,
<span class="ident">R</span>: <span class="ident">response</span>::<span class="ident">Responder</span><span class="op">&lt;</span><span class="lifetime">&#39;r</span><span class="op">&gt;</span>,
{
<span class="prelude-val">Ok</span>(<span class="ident">ManualResponder</span>::<span class="ident">new</span>(<span class="ident">Cow</span>::<span class="ident">Borrowed</span>(<span class="self">self</span>), <span class="ident">handler</span>))
}
}
<span class="doccomment">/// A CORS Response which provides the following CORS headers:</span>
<span class="doccomment">///</span>
<span class="doccomment">/// - `Access-Control-Allow-Origin`</span>
<span class="doccomment">/// - `Access-Control-Expose-Headers`</span>
<span class="doccomment">/// - `Access-Control-Max-Age`</span>
<span class="doccomment">/// - `Access-Control-Allow-Credentials`</span>
<span class="doccomment">/// - `Access-Control-Allow-Methods`</span>
<span class="doccomment">/// - `Access-Control-Allow-Headers`</span>
<span class="doccomment">///</span>
<span class="doccomment">/// The following headers will be merged:</span>
<span class="doccomment">/// - `Vary`</span>
<span class="doccomment">///</span>
<span class="doccomment">/// You can get this struct by using `Cors::validate_request` in an ad-hoc manner.</span>
<span class="attribute">#[<span class="ident">derive</span>(<span class="ident">Eq</span>, <span class="ident">PartialEq</span>, <span class="ident">Debug</span>)]</span>
<span class="kw">pub</span>(<span class="kw">crate</span>) <span class="kw">struct</span> <span class="ident">Response</span> {
<span class="ident">allow_origin</span>: <span class="prelude-ty">Option</span><span class="op">&lt;</span><span class="ident">AllOrSome</span><span class="op">&lt;</span><span class="ident">String</span><span class="op">&gt;</span><span class="op">&gt;</span>,
<span class="ident">allow_methods</span>: <span class="ident">HashSet</span><span class="op">&lt;</span><span class="ident">Method</span><span class="op">&gt;</span>,
<span class="ident">allow_headers</span>: <span class="ident">HeaderFieldNamesSet</span>,
<span class="ident">allow_credentials</span>: <span class="ident">bool</span>,
<span class="ident">expose_headers</span>: <span class="ident">HeaderFieldNamesSet</span>,
<span class="ident">max_age</span>: <span class="prelude-ty">Option</span><span class="op">&lt;</span><span class="ident">usize</span><span class="op">&gt;</span>,
<span class="ident">vary_origin</span>: <span class="ident">bool</span>,
}
<span class="kw">impl</span> <span class="ident">Response</span> {
<span class="doccomment">/// Create an empty `Response`</span>
<span class="kw">fn</span> <span class="ident">new</span>() <span class="op">-</span><span class="op">&gt;</span> <span class="self">Self</span> {
<span class="self">Self</span> {
<span class="ident">allow_origin</span>: <span class="prelude-val">None</span>,
<span class="ident">allow_headers</span>: <span class="ident">HashSet</span>::<span class="ident">new</span>(),
<span class="ident">allow_methods</span>: <span class="ident">HashSet</span>::<span class="ident">new</span>(),
<span class="ident">allow_credentials</span>: <span class="bool-val">false</span>,
<span class="ident">expose_headers</span>: <span class="ident">HashSet</span>::<span class="ident">new</span>(),
<span class="ident">max_age</span>: <span class="prelude-val">None</span>,
<span class="ident">vary_origin</span>: <span class="bool-val">false</span>,
}
}
<span class="doccomment">/// Consumes the `Response` and return an altered response with origin and `vary_origin` set</span>
<span class="kw">fn</span> <span class="ident">origin</span>(<span class="kw-2">mut</span> <span class="self">self</span>, <span class="ident">origin</span>: <span class="kw-2">&amp;</span><span class="ident">str</span>, <span class="ident">vary_origin</span>: <span class="ident">bool</span>) <span class="op">-</span><span class="op">&gt;</span> <span class="self">Self</span> {
<span class="self">self</span>.<span class="ident">allow_origin</span> <span class="op">=</span> <span class="prelude-val">Some</span>(<span class="ident">AllOrSome</span>::<span class="prelude-val">Some</span>(<span class="ident">origin</span>.<span class="ident">to_string</span>()));
<span class="self">self</span>.<span class="ident">vary_origin</span> <span class="op">=</span> <span class="ident">vary_origin</span>;
<span class="self">self</span>
}
<span class="doccomment">/// Consumes the `Response` and return an altered response with origin set to &quot;*&quot;</span>
<span class="kw">fn</span> <span class="ident">any</span>(<span class="kw-2">mut</span> <span class="self">self</span>) <span class="op">-</span><span class="op">&gt;</span> <span class="self">Self</span> {
<span class="self">self</span>.<span class="ident">allow_origin</span> <span class="op">=</span> <span class="prelude-val">Some</span>(<span class="ident">AllOrSome</span>::<span class="ident">All</span>);
<span class="self">self</span>
}
<span class="doccomment">/// Consumes the Response and set credentials</span>
<span class="kw">fn</span> <span class="ident">credentials</span>(<span class="kw-2">mut</span> <span class="self">self</span>, <span class="ident">value</span>: <span class="ident">bool</span>) <span class="op">-</span><span class="op">&gt;</span> <span class="self">Self</span> {
<span class="self">self</span>.<span class="ident">allow_credentials</span> <span class="op">=</span> <span class="ident">value</span>;
<span class="self">self</span>
}
<span class="doccomment">/// Consumes the CORS, set expose_headers to</span>
<span class="doccomment">/// passed headers and returns changed CORS</span>
<span class="kw">fn</span> <span class="ident">exposed_headers</span>(<span class="kw-2">mut</span> <span class="self">self</span>, <span class="ident">headers</span>: <span class="kw-2">&amp;</span>[<span class="kw-2">&amp;</span><span class="ident">str</span>]) <span class="op">-</span><span class="op">&gt;</span> <span class="self">Self</span> {
<span class="self">self</span>.<span class="ident">expose_headers</span> <span class="op">=</span> <span class="ident">headers</span>.<span class="ident">iter</span>().<span class="ident">map</span>(<span class="op">|</span><span class="ident">s</span><span class="op">|</span> (<span class="kw-2">*</span><span class="ident">s</span>).<span class="ident">to_string</span>().<span class="ident">into</span>()).<span class="ident">collect</span>();
<span class="self">self</span>
}
<span class="doccomment">/// Consumes the CORS, set max_age to</span>
<span class="doccomment">/// passed value and returns changed CORS</span>
<span class="kw">fn</span> <span class="ident">max_age</span>(<span class="kw-2">mut</span> <span class="self">self</span>, <span class="ident">value</span>: <span class="prelude-ty">Option</span><span class="op">&lt;</span><span class="ident">usize</span><span class="op">&gt;</span>) <span class="op">-</span><span class="op">&gt;</span> <span class="self">Self</span> {
<span class="self">self</span>.<span class="ident">max_age</span> <span class="op">=</span> <span class="ident">value</span>;
<span class="self">self</span>
}
<span class="doccomment">/// Consumes the CORS, set allow_methods to</span>
<span class="doccomment">/// passed methods and returns changed CORS</span>
<span class="kw">fn</span> <span class="ident">methods</span>(<span class="kw-2">mut</span> <span class="self">self</span>, <span class="ident">methods</span>: <span class="kw-2">&amp;</span><span class="ident">HashSet</span><span class="op">&lt;</span><span class="ident">Method</span><span class="op">&gt;</span>) <span class="op">-</span><span class="op">&gt;</span> <span class="self">Self</span> {
<span class="self">self</span>.<span class="ident">allow_methods</span> <span class="op">=</span> <span class="ident">methods</span>.<span class="ident">clone</span>();
<span class="self">self</span>
}
<span class="doccomment">/// Consumes the CORS, set allow_headers to</span>
<span class="doccomment">/// passed headers and returns changed CORS</span>
<span class="kw">fn</span> <span class="ident">headers</span>(<span class="kw-2">mut</span> <span class="self">self</span>, <span class="ident">headers</span>: <span class="kw-2">&amp;</span>[<span class="kw-2">&amp;</span><span class="ident">str</span>]) <span class="op">-</span><span class="op">&gt;</span> <span class="self">Self</span> {
<span class="self">self</span>.<span class="ident">allow_headers</span> <span class="op">=</span> <span class="ident">headers</span>.<span class="ident">iter</span>().<span class="ident">map</span>(<span class="op">|</span><span class="ident">s</span><span class="op">|</span> (<span class="kw-2">*</span><span class="ident">s</span>).<span class="ident">to_string</span>().<span class="ident">into</span>()).<span class="ident">collect</span>();
<span class="self">self</span>
}
<span class="doccomment">/// Consumes the `Response` and return a `Responder` that wraps a</span>
<span class="doccomment">/// provided `rocket:response::Responder` with CORS headers</span>
<span class="kw">pub</span> <span class="kw">fn</span> <span class="ident">responder</span><span class="op">&lt;</span><span class="lifetime">&#39;r</span>, <span class="ident">R</span>: <span class="ident">response</span>::<span class="ident">Responder</span><span class="op">&lt;</span><span class="lifetime">&#39;r</span><span class="op">&gt;</span><span class="op">&gt;</span>(<span class="self">self</span>, <span class="ident">responder</span>: <span class="ident">R</span>) <span class="op">-</span><span class="op">&gt;</span> <span class="ident">Responder</span><span class="op">&lt;</span><span class="lifetime">&#39;r</span>, <span class="ident">R</span><span class="op">&gt;</span> {
<span class="ident">Responder</span>::<span class="ident">new</span>(<span class="ident">responder</span>, <span class="self">self</span>)
}
<span class="doccomment">/// Merge a `rocket::Response` with this CORS response. This is usually used in the final step</span>
<span class="doccomment">/// of a route to return a value for the route.</span>
<span class="doccomment">///</span>
<span class="doccomment">/// This will overwrite any existing CORS headers</span>
<span class="kw">pub</span> <span class="kw">fn</span> <span class="ident">response</span><span class="op">&lt;</span><span class="lifetime">&#39;r</span><span class="op">&gt;</span>(<span class="kw-2">&amp;</span><span class="self">self</span>, <span class="ident">base</span>: <span class="ident">response</span>::<span class="ident">Response</span><span class="op">&lt;</span><span class="lifetime">&#39;r</span><span class="op">&gt;</span>) <span class="op">-</span><span class="op">&gt;</span> <span class="ident">response</span>::<span class="ident">Response</span><span class="op">&lt;</span><span class="lifetime">&#39;r</span><span class="op">&gt;</span> {
<span class="kw">let</span> <span class="kw-2">mut</span> <span class="ident">response</span> <span class="op">=</span> <span class="ident">response</span>::<span class="ident">Response</span>::<span class="ident">build_from</span>(<span class="ident">base</span>).<span class="ident">finalize</span>();
<span class="self">self</span>.<span class="ident">merge</span>(<span class="kw-2">&amp;</span><span class="kw-2">mut</span> <span class="ident">response</span>);
<span class="ident">response</span>
}
<span class="doccomment">/// Merge CORS headers with an existing `rocket::Response`.</span>
<span class="doccomment">///</span>
<span class="doccomment">/// This will overwrite any existing CORS headers</span>
<span class="kw">fn</span> <span class="ident">merge</span>(<span class="kw-2">&amp;</span><span class="self">self</span>, <span class="ident">response</span>: <span class="kw-2">&amp;</span><span class="kw-2">mut</span> <span class="ident">response</span>::<span class="ident">Response</span><span class="op">&lt;</span><span class="lifetime">&#39;_</span><span class="op">&gt;</span>) {
<span class="comment">// TODO: We should be able to remove this</span>
<span class="kw">let</span> <span class="ident">origin</span> <span class="op">=</span> <span class="kw">match</span> <span class="self">self</span>.<span class="ident">allow_origin</span> {
<span class="prelude-val">None</span> <span class="op">=</span><span class="op">&gt;</span> {
<span class="comment">// This is not a CORS response</span>
<span class="kw">return</span>;
}
<span class="prelude-val">Some</span>(<span class="kw-2">ref</span> <span class="ident">origin</span>) <span class="op">=</span><span class="op">&gt;</span> <span class="ident">origin</span>,
};
<span class="kw">let</span> <span class="ident">origin</span> <span class="op">=</span> <span class="kw">match</span> <span class="kw-2">*</span><span class="ident">origin</span> {
<span class="ident">AllOrSome</span>::<span class="ident">All</span> <span class="op">=</span><span class="op">&gt;</span> <span class="string">&quot;*&quot;</span>.<span class="ident">to_string</span>(),
<span class="ident">AllOrSome</span>::<span class="prelude-val">Some</span>(<span class="kw-2">ref</span> <span class="ident">origin</span>) <span class="op">=</span><span class="op">&gt;</span> <span class="ident">origin</span>.<span class="ident">to_string</span>(),
};
<span class="kw">let</span> <span class="kw">_</span> <span class="op">=</span> <span class="ident">response</span>.<span class="ident">set_raw_header</span>(<span class="string">&quot;Access-Control-Allow-Origin&quot;</span>, <span class="ident">origin</span>);
<span class="kw">if</span> <span class="self">self</span>.<span class="ident">allow_credentials</span> {
<span class="kw">let</span> <span class="kw">_</span> <span class="op">=</span> <span class="ident">response</span>.<span class="ident">set_raw_header</span>(<span class="string">&quot;Access-Control-Allow-Credentials&quot;</span>, <span class="string">&quot;true&quot;</span>);
} <span class="kw">else</span> {
<span class="ident">response</span>.<span class="ident">remove_header</span>(<span class="string">&quot;Access-Control-Allow-Credentials&quot;</span>);
}
<span class="kw">if</span> <span class="op">!</span><span class="self">self</span>.<span class="ident">expose_headers</span>.<span class="ident">is_empty</span>() {
<span class="kw">let</span> <span class="ident">headers</span>: <span class="ident">Vec</span><span class="op">&lt;</span><span class="ident">String</span><span class="op">&gt;</span> <span class="op">=</span> <span class="self">self</span>
.<span class="ident">expose_headers</span>
.<span class="ident">iter</span>()
.<span class="ident">map</span>(<span class="op">|</span><span class="ident">s</span><span class="op">|</span> <span class="ident">s</span>.<span class="ident">deref</span>().<span class="ident">to_string</span>())
.<span class="ident">collect</span>();
<span class="kw">let</span> <span class="ident">headers</span> <span class="op">=</span> <span class="ident">headers</span>.<span class="ident">join</span>(<span class="string">&quot;, &quot;</span>);
<span class="kw">let</span> <span class="kw">_</span> <span class="op">=</span> <span class="ident">response</span>.<span class="ident">set_raw_header</span>(<span class="string">&quot;Access-Control-Expose-Headers&quot;</span>, <span class="ident">headers</span>);
} <span class="kw">else</span> {
<span class="ident">response</span>.<span class="ident">remove_header</span>(<span class="string">&quot;Access-Control-Expose-Headers&quot;</span>);
}
<span class="kw">if</span> <span class="op">!</span><span class="self">self</span>.<span class="ident">allow_headers</span>.<span class="ident">is_empty</span>() {
<span class="kw">let</span> <span class="ident">headers</span>: <span class="ident">Vec</span><span class="op">&lt;</span><span class="ident">String</span><span class="op">&gt;</span> <span class="op">=</span> <span class="self">self</span>
.<span class="ident">allow_headers</span>
.<span class="ident">iter</span>()
.<span class="ident">map</span>(<span class="op">|</span><span class="ident">s</span><span class="op">|</span> <span class="ident">s</span>.<span class="ident">deref</span>().<span class="ident">to_string</span>())
.<span class="ident">collect</span>();
<span class="kw">let</span> <span class="ident">headers</span> <span class="op">=</span> <span class="ident">headers</span>.<span class="ident">join</span>(<span class="string">&quot;, &quot;</span>);
<span class="kw">let</span> <span class="kw">_</span> <span class="op">=</span> <span class="ident">response</span>.<span class="ident">set_raw_header</span>(<span class="string">&quot;Access-Control-Allow-Headers&quot;</span>, <span class="ident">headers</span>);
} <span class="kw">else</span> {
<span class="ident">response</span>.<span class="ident">remove_header</span>(<span class="string">&quot;Access-Control-Allow-Headers&quot;</span>);
}
<span class="kw">if</span> <span class="op">!</span><span class="self">self</span>.<span class="ident">allow_methods</span>.<span class="ident">is_empty</span>() {
<span class="kw">let</span> <span class="ident">methods</span>: <span class="ident">Vec</span><span class="op">&lt;</span><span class="kw">_</span><span class="op">&gt;</span> <span class="op">=</span> <span class="self">self</span>.<span class="ident">allow_methods</span>.<span class="ident">iter</span>().<span class="ident">map</span>(<span class="op">|</span><span class="ident">m</span><span class="op">|</span> <span class="ident">m</span>.<span class="ident">as_str</span>()).<span class="ident">collect</span>();
<span class="kw">let</span> <span class="ident">methods</span> <span class="op">=</span> <span class="ident">methods</span>.<span class="ident">join</span>(<span class="string">&quot;, &quot;</span>);
<span class="kw">let</span> <span class="kw">_</span> <span class="op">=</span> <span class="ident">response</span>.<span class="ident">set_raw_header</span>(<span class="string">&quot;Access-Control-Allow-Methods&quot;</span>, <span class="ident">methods</span>);
} <span class="kw">else</span> {
<span class="ident">response</span>.<span class="ident">remove_header</span>(<span class="string">&quot;Access-Control-Allow-Methods&quot;</span>);
}
<span class="kw">if</span> <span class="self">self</span>.<span class="ident">max_age</span>.<span class="ident">is_some</span>() {
<span class="kw">let</span> <span class="ident">max_age</span> <span class="op">=</span> <span class="self">self</span>.<span class="ident">max_age</span>.<span class="ident">unwrap</span>();
<span class="kw">let</span> <span class="kw">_</span> <span class="op">=</span> <span class="ident">response</span>.<span class="ident">set_raw_header</span>(<span class="string">&quot;Access-Control-Max-Age&quot;</span>, <span class="ident">max_age</span>.<span class="ident">to_string</span>());
} <span class="kw">else</span> {
<span class="ident">response</span>.<span class="ident">remove_header</span>(<span class="string">&quot;Access-Control-Max-Age&quot;</span>);
}
<span class="kw">if</span> <span class="self">self</span>.<span class="ident">vary_origin</span> {
<span class="ident">response</span>.<span class="ident">adjoin_raw_header</span>(<span class="string">&quot;Vary&quot;</span>, <span class="string">&quot;Origin&quot;</span>);
}
}
<span class="doccomment">/// Validate and create a new CORS Response from a request and settings</span>
<span class="kw">pub</span> <span class="kw">fn</span> <span class="ident">validate_and_build</span><span class="op">&lt;</span><span class="lifetime">&#39;a</span>, <span class="lifetime">&#39;r</span><span class="op">&gt;</span>(
<span class="ident">options</span>: <span class="kw-2">&amp;</span><span class="lifetime">&#39;a</span> <span class="ident">Cors</span>,
<span class="ident">request</span>: <span class="kw-2">&amp;</span><span class="lifetime">&#39;a</span> <span class="ident">Request</span><span class="op">&lt;</span><span class="lifetime">&#39;r</span><span class="op">&gt;</span>,
) <span class="op">-</span><span class="op">&gt;</span> <span class="prelude-ty">Result</span><span class="op">&lt;</span><span class="self">Self</span>, <span class="ident">Error</span><span class="op">&gt;</span> {
<span class="ident">validate_and_build</span>(<span class="ident">options</span>, <span class="ident">request</span>)
}
}
<span class="doccomment">/// A [request guard](https://rocket.rs/guide/requests/#request-guards) to check CORS headers</span>
<span class="doccomment">/// before a route is run. Will not execute the route if checks fail.</span>
<span class="doccomment">///</span>
<span class="doccomment">/// See the documentation at the [crate root](index.html) for usage information.</span>
<span class="doccomment">///</span>
<span class="doccomment">/// You should not wrap this in an</span>
<span class="doccomment">/// `Option` or `Result` because the guard will let non-CORS requests through and will take over</span>
<span class="doccomment">/// error handling in case of errors.</span>
<span class="doccomment">/// In essence, this is just a wrapper around `Response` with a `&#39;r` borrowed lifetime so users</span>
<span class="doccomment">/// don&#39;t have to keep specifying the lifetimes in their routes</span>
<span class="kw">pub</span> <span class="kw">struct</span> <span class="ident">Guard</span><span class="op">&lt;</span><span class="lifetime">&#39;r</span><span class="op">&gt;</span> {
<span class="ident">response</span>: <span class="ident">Response</span>,
<span class="ident">marker</span>: <span class="ident">PhantomData</span><span class="op">&lt;</span><span class="kw-2">&amp;</span><span class="lifetime">&#39;r</span> <span class="ident">Response</span><span class="op">&gt;</span>,
}
<span class="kw">impl</span><span class="op">&lt;</span><span class="lifetime">&#39;r</span><span class="op">&gt;</span> <span class="ident">Guard</span><span class="op">&lt;</span><span class="lifetime">&#39;r</span><span class="op">&gt;</span> {
<span class="kw">fn</span> <span class="ident">new</span>(<span class="ident">response</span>: <span class="ident">Response</span>) <span class="op">-</span><span class="op">&gt;</span> <span class="self">Self</span> {
<span class="self">Self</span> {
<span class="ident">response</span>,
<span class="ident">marker</span>: <span class="ident">PhantomData</span>,
}
}
<span class="doccomment">/// Consumes the Guard and return a `Responder` that wraps a</span>
<span class="doccomment">/// provided `rocket:response::Responder` with CORS headers</span>
<span class="kw">pub</span> <span class="kw">fn</span> <span class="ident">responder</span><span class="op">&lt;</span><span class="ident">R</span>: <span class="ident">response</span>::<span class="ident">Responder</span><span class="op">&lt;</span><span class="lifetime">&#39;r</span><span class="op">&gt;</span><span class="op">&gt;</span>(<span class="self">self</span>, <span class="ident">responder</span>: <span class="ident">R</span>) <span class="op">-</span><span class="op">&gt;</span> <span class="ident">Responder</span><span class="op">&lt;</span><span class="lifetime">&#39;r</span>, <span class="ident">R</span><span class="op">&gt;</span> {
<span class="self">self</span>.<span class="ident">response</span>.<span class="ident">responder</span>(<span class="ident">responder</span>)
}
<span class="doccomment">/// Merge a `rocket::Response` with this CORS Guard. This is usually used in the final step</span>
<span class="doccomment">/// of a route to return a value for the route.</span>
<span class="doccomment">///</span>
<span class="doccomment">/// This will overwrite any existing CORS headers</span>
<span class="kw">pub</span> <span class="kw">fn</span> <span class="ident">response</span>(<span class="kw-2">&amp;</span><span class="self">self</span>, <span class="ident">base</span>: <span class="ident">response</span>::<span class="ident">Response</span><span class="op">&lt;</span><span class="lifetime">&#39;r</span><span class="op">&gt;</span>) <span class="op">-</span><span class="op">&gt;</span> <span class="ident">response</span>::<span class="ident">Response</span><span class="op">&lt;</span><span class="lifetime">&#39;r</span><span class="op">&gt;</span> {
<span class="self">self</span>.<span class="ident">response</span>.<span class="ident">response</span>(<span class="ident">base</span>)
}
}
<span class="kw">impl</span><span class="op">&lt;</span><span class="lifetime">&#39;a</span>, <span class="lifetime">&#39;r</span><span class="op">&gt;</span> <span class="ident">FromRequest</span><span class="op">&lt;</span><span class="lifetime">&#39;a</span>, <span class="lifetime">&#39;r</span><span class="op">&gt;</span> <span class="kw">for</span> <span class="ident">Guard</span><span class="op">&lt;</span><span class="lifetime">&#39;r</span><span class="op">&gt;</span> {
<span class="kw">type</span> <span class="ident">Error</span> <span class="op">=</span> <span class="ident">Error</span>;
<span class="kw">fn</span> <span class="ident">from_request</span>(<span class="ident">request</span>: <span class="kw-2">&amp;</span><span class="lifetime">&#39;a</span> <span class="ident">Request</span><span class="op">&lt;</span><span class="lifetime">&#39;r</span><span class="op">&gt;</span>) <span class="op">-</span><span class="op">&gt;</span> <span class="ident">rocket</span>::<span class="ident">request</span>::<span class="ident">Outcome</span><span class="op">&lt;</span><span class="self">Self</span>, <span class="self">Self</span>::<span class="ident">Error</span><span class="op">&gt;</span> {
<span class="kw">let</span> <span class="ident">options</span> <span class="op">=</span> <span class="kw">match</span> <span class="ident">request</span>.<span class="ident">guard</span>::<span class="op">&lt;</span><span class="ident">State</span><span class="op">&lt;</span><span class="lifetime">&#39;_</span>, <span class="ident">Cors</span><span class="op">&gt;</span><span class="op">&gt;</span>() {
<span class="ident">Outcome</span>::<span class="ident">Success</span>(<span class="ident">options</span>) <span class="op">=</span><span class="op">&gt;</span> <span class="ident">options</span>,
<span class="kw">_</span> <span class="op">=</span><span class="op">&gt;</span> {
<span class="kw">let</span> <span class="ident">error</span> <span class="op">=</span> <span class="ident">Error</span>::<span class="ident">MissingCorsInRocketState</span>;
<span class="kw">return</span> <span class="ident">Outcome</span>::<span class="ident">Failure</span>((<span class="ident">error</span>.<span class="ident">status</span>(), <span class="ident">error</span>));
}
};
<span class="kw">match</span> <span class="ident">Response</span>::<span class="ident">validate_and_build</span>(<span class="kw-2">&amp;</span><span class="ident">options</span>, <span class="ident">request</span>) {
<span class="prelude-val">Ok</span>(<span class="ident">response</span>) <span class="op">=</span><span class="op">&gt;</span> <span class="ident">Outcome</span>::<span class="ident">Success</span>(<span class="self">Self</span>::<span class="ident">new</span>(<span class="ident">response</span>)),
<span class="prelude-val">Err</span>(<span class="ident">error</span>) <span class="op">=</span><span class="op">&gt;</span> <span class="ident">Outcome</span>::<span class="ident">Failure</span>((<span class="ident">error</span>.<span class="ident">status</span>(), <span class="ident">error</span>)),
}
}
}
<span class="doccomment">/// A [`Responder`](https://rocket.rs/guide/responses/#responder) which will simply wraps another</span>
<span class="doccomment">/// `Responder` with CORS headers.</span>
<span class="doccomment">///</span>
<span class="doccomment">/// The following CORS headers will be overwritten:</span>
<span class="doccomment">///</span>
<span class="doccomment">/// - `Access-Control-Allow-Origin`</span>
<span class="doccomment">/// - `Access-Control-Expose-Headers`</span>
<span class="doccomment">/// - `Access-Control-Max-Age`</span>
<span class="doccomment">/// - `Access-Control-Allow-Credentials`</span>
<span class="doccomment">/// - `Access-Control-Allow-Methods`</span>
<span class="doccomment">/// - `Access-Control-Allow-Headers`</span>
<span class="doccomment">///</span>
<span class="doccomment">/// The following headers will be merged:</span>
<span class="doccomment">/// - `Vary`</span>
<span class="doccomment">///</span>
<span class="doccomment">/// See the documentation at the [crate root](index.html) for usage information.</span>
<span class="attribute">#[<span class="ident">derive</span>(<span class="ident">Debug</span>)]</span>
<span class="kw">pub</span> <span class="kw">struct</span> <span class="ident">Responder</span><span class="op">&lt;</span><span class="lifetime">&#39;r</span>, <span class="ident">R</span><span class="op">&gt;</span> {
<span class="ident">responder</span>: <span class="ident">R</span>,
<span class="ident">cors_response</span>: <span class="ident">Response</span>,
<span class="ident">marker</span>: <span class="ident">PhantomData</span><span class="op">&lt;</span><span class="kw">dyn</span> <span class="ident">response</span>::<span class="ident">Responder</span><span class="op">&lt;</span><span class="lifetime">&#39;r</span><span class="op">&gt;</span><span class="op">&gt;</span>,
}
<span class="kw">impl</span><span class="op">&lt;</span><span class="lifetime">&#39;r</span>, <span class="ident">R</span>: <span class="ident">response</span>::<span class="ident">Responder</span><span class="op">&lt;</span><span class="lifetime">&#39;r</span><span class="op">&gt;</span><span class="op">&gt;</span> <span class="ident">Responder</span><span class="op">&lt;</span><span class="lifetime">&#39;r</span>, <span class="ident">R</span><span class="op">&gt;</span> {
<span class="kw">fn</span> <span class="ident">new</span>(<span class="ident">responder</span>: <span class="ident">R</span>, <span class="ident">cors_response</span>: <span class="ident">Response</span>) <span class="op">-</span><span class="op">&gt;</span> <span class="self">Self</span> {
<span class="self">Self</span> {
<span class="ident">responder</span>,
<span class="ident">cors_response</span>,
<span class="ident">marker</span>: <span class="ident">PhantomData</span>,
}
}
<span class="doccomment">/// Respond to a request</span>
<span class="kw">fn</span> <span class="ident">respond</span>(<span class="self">self</span>, <span class="ident">request</span>: <span class="kw-2">&amp;</span><span class="ident">Request</span><span class="op">&lt;</span><span class="lifetime">&#39;_</span><span class="op">&gt;</span>) <span class="op">-</span><span class="op">&gt;</span> <span class="ident">response</span>::<span class="prelude-ty">Result</span><span class="op">&lt;</span><span class="lifetime">&#39;r</span><span class="op">&gt;</span> {
<span class="kw">let</span> <span class="kw-2">mut</span> <span class="ident">response</span> <span class="op">=</span> <span class="self">self</span>.<span class="ident">responder</span>.<span class="ident">respond_to</span>(<span class="ident">request</span>)<span class="question-mark">?</span>; <span class="comment">// handle status errors?</span>
<span class="self">self</span>.<span class="ident">cors_response</span>.<span class="ident">merge</span>(<span class="kw-2">&amp;</span><span class="kw-2">mut</span> <span class="ident">response</span>);
<span class="prelude-val">Ok</span>(<span class="ident">response</span>)
}
}
<span class="kw">impl</span><span class="op">&lt;</span><span class="lifetime">&#39;r</span>, <span class="ident">R</span>: <span class="ident">response</span>::<span class="ident">Responder</span><span class="op">&lt;</span><span class="lifetime">&#39;r</span><span class="op">&gt;</span><span class="op">&gt;</span> <span class="ident">response</span>::<span class="ident">Responder</span><span class="op">&lt;</span><span class="lifetime">&#39;r</span><span class="op">&gt;</span> <span class="kw">for</span> <span class="ident">Responder</span><span class="op">&lt;</span><span class="lifetime">&#39;r</span>, <span class="ident">R</span><span class="op">&gt;</span> {
<span class="kw">fn</span> <span class="ident">respond_to</span>(<span class="self">self</span>, <span class="ident">request</span>: <span class="kw-2">&amp;</span><span class="ident">Request</span><span class="op">&lt;</span><span class="lifetime">&#39;_</span><span class="op">&gt;</span>) <span class="op">-</span><span class="op">&gt;</span> <span class="ident">response</span>::<span class="prelude-ty">Result</span><span class="op">&lt;</span><span class="lifetime">&#39;r</span><span class="op">&gt;</span> {
<span class="self">self</span>.<span class="ident">respond</span>(<span class="ident">request</span>)
}
}
<span class="doccomment">/// A Manual Responder used in the &quot;truly manual&quot; mode of operation.</span>
<span class="doccomment">///</span>
<span class="doccomment">/// See the documentation at the [crate root](index.html) for usage information.</span>
<span class="kw">pub</span> <span class="kw">struct</span> <span class="ident">ManualResponder</span><span class="op">&lt;</span><span class="lifetime">&#39;r</span>, <span class="ident">F</span>, <span class="ident">R</span><span class="op">&gt;</span> {
<span class="ident">options</span>: <span class="ident">Cow</span><span class="op">&lt;</span><span class="lifetime">&#39;r</span>, <span class="ident">Cors</span><span class="op">&gt;</span>,
<span class="ident">handler</span>: <span class="ident">F</span>,
<span class="ident">marker</span>: <span class="ident">PhantomData</span><span class="op">&lt;</span><span class="ident">R</span><span class="op">&gt;</span>,
}
<span class="kw">impl</span><span class="op">&lt;</span><span class="lifetime">&#39;r</span>, <span class="ident">F</span>, <span class="ident">R</span><span class="op">&gt;</span> <span class="ident">ManualResponder</span><span class="op">&lt;</span><span class="lifetime">&#39;r</span>, <span class="ident">F</span>, <span class="ident">R</span><span class="op">&gt;</span>
<span class="kw">where</span>
<span class="ident">F</span>: <span class="ident">FnOnce</span>(<span class="ident">Guard</span><span class="op">&lt;</span><span class="lifetime">&#39;r</span><span class="op">&gt;</span>) <span class="op">-</span><span class="op">&gt;</span> <span class="ident">R</span> <span class="op">+</span> <span class="lifetime">&#39;r</span>,
<span class="ident">R</span>: <span class="ident">response</span>::<span class="ident">Responder</span><span class="op">&lt;</span><span class="lifetime">&#39;r</span><span class="op">&gt;</span>,
{
<span class="doccomment">/// Create a new manual responder by passing in either a borrowed or owned `Cors` option.</span>
<span class="doccomment">///</span>
<span class="doccomment">/// A borrowed `Cors` option must live for the entirety of the `&#39;r` lifetime which is the</span>
<span class="doccomment">/// lifetime of the entire Rocket request.</span>
<span class="kw">fn</span> <span class="ident">new</span>(<span class="ident">options</span>: <span class="ident">Cow</span><span class="op">&lt;</span><span class="lifetime">&#39;r</span>, <span class="ident">Cors</span><span class="op">&gt;</span>, <span class="ident">handler</span>: <span class="ident">F</span>) <span class="op">-</span><span class="op">&gt;</span> <span class="self">Self</span> {
<span class="kw">let</span> <span class="ident">marker</span> <span class="op">=</span> <span class="ident">PhantomData</span>;
<span class="self">Self</span> {
<span class="ident">options</span>,
<span class="ident">handler</span>,
<span class="ident">marker</span>,
}
}
<span class="kw">fn</span> <span class="ident">build_guard</span>(<span class="kw-2">&amp;</span><span class="self">self</span>, <span class="ident">request</span>: <span class="kw-2">&amp;</span><span class="ident">Request</span><span class="op">&lt;</span><span class="lifetime">&#39;_</span><span class="op">&gt;</span>) <span class="op">-</span><span class="op">&gt;</span> <span class="prelude-ty">Result</span><span class="op">&lt;</span><span class="ident">Guard</span><span class="op">&lt;</span><span class="lifetime">&#39;r</span><span class="op">&gt;</span>, <span class="ident">Error</span><span class="op">&gt;</span> {
<span class="kw">let</span> <span class="ident">response</span> <span class="op">=</span> <span class="ident">Response</span>::<span class="ident">validate_and_build</span>(<span class="kw-2">&amp;</span><span class="self">self</span>.<span class="ident">options</span>, <span class="ident">request</span>)<span class="question-mark">?</span>;
<span class="prelude-val">Ok</span>(<span class="ident">Guard</span>::<span class="ident">new</span>(<span class="ident">response</span>))
}
}
<span class="kw">impl</span><span class="op">&lt;</span><span class="lifetime">&#39;r</span>, <span class="ident">F</span>, <span class="ident">R</span><span class="op">&gt;</span> <span class="ident">response</span>::<span class="ident">Responder</span><span class="op">&lt;</span><span class="lifetime">&#39;r</span><span class="op">&gt;</span> <span class="kw">for</span> <span class="ident">ManualResponder</span><span class="op">&lt;</span><span class="lifetime">&#39;r</span>, <span class="ident">F</span>, <span class="ident">R</span><span class="op">&gt;</span>
<span class="kw">where</span>
<span class="ident">F</span>: <span class="ident">FnOnce</span>(<span class="ident">Guard</span><span class="op">&lt;</span><span class="lifetime">&#39;r</span><span class="op">&gt;</span>) <span class="op">-</span><span class="op">&gt;</span> <span class="ident">R</span> <span class="op">+</span> <span class="lifetime">&#39;r</span>,
<span class="ident">R</span>: <span class="ident">response</span>::<span class="ident">Responder</span><span class="op">&lt;</span><span class="lifetime">&#39;r</span><span class="op">&gt;</span>,
{
<span class="kw">fn</span> <span class="ident">respond_to</span>(<span class="self">self</span>, <span class="ident">request</span>: <span class="kw-2">&amp;</span><span class="ident">Request</span><span class="op">&lt;</span><span class="lifetime">&#39;_</span><span class="op">&gt;</span>) <span class="op">-</span><span class="op">&gt;</span> <span class="ident">response</span>::<span class="prelude-ty">Result</span><span class="op">&lt;</span><span class="lifetime">&#39;r</span><span class="op">&gt;</span> {
<span class="kw">let</span> <span class="ident">guard</span> <span class="op">=</span> <span class="kw">match</span> <span class="self">self</span>.<span class="ident">build_guard</span>(<span class="ident">request</span>) {
<span class="prelude-val">Ok</span>(<span class="ident">guard</span>) <span class="op">=</span><span class="op">&gt;</span> <span class="ident">guard</span>,
<span class="prelude-val">Err</span>(<span class="ident">err</span>) <span class="op">=</span><span class="op">&gt;</span> {
<span class="macro">error_</span><span class="macro">!</span>(<span class="string">&quot;CORS error: {}&quot;</span>, <span class="ident">err</span>);
<span class="kw">return</span> <span class="prelude-val">Err</span>(<span class="ident">err</span>.<span class="ident">status</span>());
}
};
(<span class="self">self</span>.<span class="ident">handler</span>)(<span class="ident">guard</span>).<span class="ident">respond_to</span>(<span class="ident">request</span>)
}
}
<span class="doccomment">/// Result of CORS validation.</span>
<span class="doccomment">///</span>
<span class="doccomment">/// The variants hold enough information to build a response to the validation result</span>
<span class="attribute">#[<span class="ident">derive</span>(<span class="ident">Debug</span>, <span class="ident">Eq</span>, <span class="ident">PartialEq</span>)]</span>
<span class="attribute">#[<span class="ident">allow</span>(<span class="ident">variant_size_differences</span>)]</span>
<span class="kw">enum</span> <span class="ident">ValidationResult</span> {
<span class="doccomment">/// Not a CORS request</span>
<span class="prelude-val">None</span>,
<span class="doccomment">/// Successful preflight request</span>
<span class="ident">Preflight</span> {
<span class="ident">origin</span>: <span class="ident">String</span>,
<span class="ident">headers</span>: <span class="prelude-ty">Option</span><span class="op">&lt;</span><span class="ident">AccessControlRequestHeaders</span><span class="op">&gt;</span>,
},
<span class="doccomment">/// Successful actual request</span>
<span class="ident">Request</span> { <span class="ident">origin</span>: <span class="ident">String</span> },
}
<span class="doccomment">/// Convert a str to a URL Origin</span>
<span class="kw">fn</span> <span class="ident">to_origin</span><span class="op">&lt;</span><span class="ident">S</span>: <span class="ident">AsRef</span><span class="op">&lt;</span><span class="ident">str</span><span class="op">&gt;</span><span class="op">&gt;</span>(<span class="ident">origin</span>: <span class="ident">S</span>) <span class="op">-</span><span class="op">&gt;</span> <span class="prelude-ty">Result</span><span class="op">&lt;</span><span class="ident">url</span>::<span class="ident">Origin</span>, <span class="ident">Error</span><span class="op">&gt;</span> {
<span class="prelude-val">Ok</span>(<span class="ident">url</span>::<span class="ident">Url</span>::<span class="ident">parse</span>(<span class="ident">origin</span>.<span class="ident">as_ref</span>())<span class="question-mark">?</span>.<span class="ident">origin</span>())
}
<span class="doccomment">/// Parse and process allowed origins</span>
<span class="kw">fn</span> <span class="ident">parse_allowed_origins</span>(
<span class="ident">origins</span>: <span class="kw-2">&amp;</span><span class="ident">AllowedOrigins</span>,
) <span class="op">-</span><span class="op">&gt;</span> <span class="prelude-ty">Result</span><span class="op">&lt;</span><span class="ident">AllOrSome</span><span class="op">&lt;</span><span class="ident">ParsedAllowedOrigins</span><span class="op">&gt;</span>, <span class="ident">Error</span><span class="op">&gt;</span> {
<span class="kw">match</span> <span class="ident">origins</span> {
<span class="ident">AllOrSome</span>::<span class="ident">All</span> <span class="op">=</span><span class="op">&gt;</span> <span class="prelude-val">Ok</span>(<span class="ident">AllOrSome</span>::<span class="ident">All</span>),
<span class="ident">AllOrSome</span>::<span class="prelude-val">Some</span>(<span class="ident">origins</span>) <span class="op">=</span><span class="op">&gt;</span> {
<span class="kw">let</span> <span class="ident">parsed</span> <span class="op">=</span> <span class="ident">ParsedAllowedOrigins</span>::<span class="ident">parse</span>(<span class="ident">origins</span>)<span class="question-mark">?</span>;
<span class="prelude-val">Ok</span>(<span class="ident">AllOrSome</span>::<span class="prelude-val">Some</span>(<span class="ident">parsed</span>))
}
}
}
<span class="doccomment">/// Validates a request for CORS and returns a CORS Response</span>
<span class="kw">fn</span> <span class="ident">validate_and_build</span>(<span class="ident">options</span>: <span class="kw-2">&amp;</span><span class="ident">Cors</span>, <span class="ident">request</span>: <span class="kw-2">&amp;</span><span class="ident">Request</span><span class="op">&lt;</span><span class="lifetime">&#39;_</span><span class="op">&gt;</span>) <span class="op">-</span><span class="op">&gt;</span> <span class="prelude-ty">Result</span><span class="op">&lt;</span><span class="ident">Response</span>, <span class="ident">Error</span><span class="op">&gt;</span> {
<span class="kw">let</span> <span class="ident">result</span> <span class="op">=</span> <span class="ident">validate</span>(<span class="ident">options</span>, <span class="ident">request</span>)<span class="question-mark">?</span>;
<span class="prelude-val">Ok</span>(<span class="kw">match</span> <span class="ident">result</span> {
<span class="ident">ValidationResult</span>::<span class="prelude-val">None</span> <span class="op">=</span><span class="op">&gt;</span> <span class="ident">Response</span>::<span class="ident">new</span>(),
<span class="ident">ValidationResult</span>::<span class="ident">Preflight</span> { <span class="ident">origin</span>, <span class="ident">headers</span> } <span class="op">=</span><span class="op">&gt;</span> {
<span class="ident">preflight_response</span>(<span class="ident">options</span>, <span class="kw-2">&amp;</span><span class="ident">origin</span>, <span class="ident">headers</span>.<span class="ident">as_ref</span>())
}
<span class="ident">ValidationResult</span>::<span class="ident">Request</span> { <span class="ident">origin</span> } <span class="op">=</span><span class="op">&gt;</span> <span class="ident">actual_request_response</span>(<span class="ident">options</span>, <span class="kw-2">&amp;</span><span class="ident">origin</span>),
})
}
<span class="doccomment">/// Validate a CORS request</span>
<span class="kw">fn</span> <span class="ident">validate</span>(<span class="ident">options</span>: <span class="kw-2">&amp;</span><span class="ident">Cors</span>, <span class="ident">request</span>: <span class="kw-2">&amp;</span><span class="ident">Request</span><span class="op">&lt;</span><span class="lifetime">&#39;_</span><span class="op">&gt;</span>) <span class="op">-</span><span class="op">&gt;</span> <span class="prelude-ty">Result</span><span class="op">&lt;</span><span class="ident">ValidationResult</span>, <span class="ident">Error</span><span class="op">&gt;</span> {
<span class="comment">// 1. If the Origin header is not present terminate this set of steps.</span>
<span class="comment">// The request is outside the scope of this specification.</span>
<span class="kw">let</span> <span class="ident">origin</span> <span class="op">=</span> <span class="ident">origin</span>(<span class="ident">request</span>)<span class="question-mark">?</span>;
<span class="kw">let</span> <span class="ident">origin</span> <span class="op">=</span> <span class="kw">match</span> <span class="ident">origin</span> {
<span class="prelude-val">None</span> <span class="op">=</span><span class="op">&gt;</span> {
<span class="comment">// Not a CORS request</span>
<span class="kw">return</span> <span class="prelude-val">Ok</span>(<span class="ident">ValidationResult</span>::<span class="prelude-val">None</span>);
}
<span class="prelude-val">Some</span>(<span class="ident">origin</span>) <span class="op">=</span><span class="op">&gt;</span> <span class="ident">origin</span>,
};
<span class="comment">// Check if the request verb is an OPTION or something else</span>
<span class="kw">match</span> <span class="ident">request</span>.<span class="ident">method</span>() {
<span class="ident">http</span>::<span class="ident">Method</span>::<span class="ident">Options</span> <span class="op">=</span><span class="op">&gt;</span> {
<span class="kw">let</span> <span class="ident">method</span> <span class="op">=</span> <span class="ident">request_method</span>(<span class="ident">request</span>)<span class="question-mark">?</span>;
<span class="kw">let</span> <span class="ident">headers</span> <span class="op">=</span> <span class="ident">request_headers</span>(<span class="ident">request</span>)<span class="question-mark">?</span>;
<span class="ident">preflight_validate</span>(<span class="ident">options</span>, <span class="kw-2">&amp;</span><span class="ident">origin</span>, <span class="kw-2">&amp;</span><span class="ident">method</span>, <span class="kw-2">&amp;</span><span class="ident">headers</span>)<span class="question-mark">?</span>;
<span class="prelude-val">Ok</span>(<span class="ident">ValidationResult</span>::<span class="ident">Preflight</span> {
<span class="ident">origin</span>: <span class="ident">origin</span>.<span class="ident">to_string</span>(),
<span class="ident">headers</span>,
})
}
<span class="kw">_</span> <span class="op">=</span><span class="op">&gt;</span> {
<span class="ident">actual_request_validate</span>(<span class="ident">options</span>, <span class="kw-2">&amp;</span><span class="ident">origin</span>)<span class="question-mark">?</span>;
<span class="prelude-val">Ok</span>(<span class="ident">ValidationResult</span>::<span class="ident">Request</span> {
<span class="ident">origin</span>: <span class="ident">origin</span>.<span class="ident">to_string</span>(),
})
}
}
}
<span class="doccomment">/// Consumes the responder and based on the provided list of allowed origins,</span>
<span class="doccomment">/// check if the requested origin is allowed.</span>
<span class="doccomment">/// Useful for pre-flight and during requests</span>
<span class="kw">fn</span> <span class="ident">validate_origin</span>(
<span class="ident">origin</span>: <span class="kw-2">&amp;</span><span class="ident">Origin</span>,
<span class="ident">allowed_origins</span>: <span class="kw-2">&amp;</span><span class="ident">AllOrSome</span><span class="op">&lt;</span><span class="ident">ParsedAllowedOrigins</span><span class="op">&gt;</span>,
) <span class="op">-</span><span class="op">&gt;</span> <span class="prelude-ty">Result</span><span class="op">&lt;</span>(), <span class="ident">Error</span><span class="op">&gt;</span> {
<span class="kw">match</span> <span class="kw-2">*</span><span class="ident">allowed_origins</span> {
<span class="comment">// Always matching is acceptable since the list of origins can be unbounded.</span>
<span class="ident">AllOrSome</span>::<span class="ident">All</span> <span class="op">=</span><span class="op">&gt;</span> <span class="prelude-val">Ok</span>(()),
<span class="ident">AllOrSome</span>::<span class="prelude-val">Some</span>(<span class="kw-2">ref</span> <span class="ident">allowed_origins</span>) <span class="op">=</span><span class="op">&gt;</span> {
<span class="kw">if</span> <span class="ident">allowed_origins</span>.<span class="ident">verify</span>(<span class="ident">origin</span>) {
<span class="prelude-val">Ok</span>(())
} <span class="kw">else</span> {
<span class="prelude-val">Err</span>(<span class="ident">Error</span>::<span class="ident">OriginNotAllowed</span>(<span class="ident">origin</span>.<span class="ident">to_string</span>()))
}
}
}
}
<span class="doccomment">/// Validate allowed methods</span>
<span class="kw">fn</span> <span class="ident">validate_allowed_method</span>(
<span class="ident">method</span>: <span class="kw-2">&amp;</span><span class="ident">AccessControlRequestMethod</span>,
<span class="ident">allowed_methods</span>: <span class="kw-2">&amp;</span><span class="ident">AllowedMethods</span>,
) <span class="op">-</span><span class="op">&gt;</span> <span class="prelude-ty">Result</span><span class="op">&lt;</span>(), <span class="ident">Error</span><span class="op">&gt;</span> {
<span class="kw">let</span> <span class="kw-2">&amp;</span><span class="ident">AccessControlRequestMethod</span>(<span class="kw-2">ref</span> <span class="ident">request_method</span>) <span class="op">=</span> <span class="ident">method</span>;
<span class="kw">if</span> <span class="op">!</span><span class="ident">allowed_methods</span>.<span class="ident">iter</span>().<span class="ident">any</span>(<span class="op">|</span><span class="ident">m</span><span class="op">|</span> <span class="ident">m</span> <span class="op">=</span><span class="op">=</span> <span class="ident">request_method</span>) {
<span class="kw">return</span> <span class="prelude-val">Err</span>(<span class="ident">Error</span>::<span class="ident">MethodNotAllowed</span>(<span class="ident">method</span>.<span class="number">0</span>.<span class="ident">to_string</span>()));
}
<span class="comment">// TODO: Subset to route? Or just the method requested for?</span>
<span class="prelude-val">Ok</span>(())
}
<span class="doccomment">/// Validate allowed headers</span>
<span class="kw">fn</span> <span class="ident">validate_allowed_headers</span>(
<span class="ident">headers</span>: <span class="kw-2">&amp;</span><span class="ident">AccessControlRequestHeaders</span>,
<span class="ident">allowed_headers</span>: <span class="kw-2">&amp;</span><span class="ident">AllowedHeaders</span>,
) <span class="op">-</span><span class="op">&gt;</span> <span class="prelude-ty">Result</span><span class="op">&lt;</span>(), <span class="ident">Error</span><span class="op">&gt;</span> {
<span class="kw">let</span> <span class="kw-2">&amp;</span><span class="ident">AccessControlRequestHeaders</span>(<span class="kw-2">ref</span> <span class="ident">headers</span>) <span class="op">=</span> <span class="ident">headers</span>;
<span class="kw">match</span> <span class="kw-2">*</span><span class="ident">allowed_headers</span> {
<span class="ident">AllOrSome</span>::<span class="ident">All</span> <span class="op">=</span><span class="op">&gt;</span> <span class="prelude-val">Ok</span>(()),
<span class="ident">AllOrSome</span>::<span class="prelude-val">Some</span>(<span class="kw-2">ref</span> <span class="ident">allowed_headers</span>) <span class="op">=</span><span class="op">&gt;</span> {
<span class="kw">if</span> <span class="op">!</span><span class="ident">headers</span>.<span class="ident">is_empty</span>() <span class="kw-2">&amp;</span><span class="op">&amp;</span> <span class="op">!</span><span class="ident">headers</span>.<span class="ident">is_subset</span>(<span class="ident">allowed_headers</span>) {
<span class="kw">return</span> <span class="prelude-val">Err</span>(<span class="ident">Error</span>::<span class="ident">HeadersNotAllowed</span>);
}
<span class="prelude-val">Ok</span>(())
}
}
}
<span class="doccomment">/// Gets the `Origin` request header from the request</span>
<span class="kw">fn</span> <span class="ident">origin</span>(<span class="ident">request</span>: <span class="kw-2">&amp;</span><span class="ident">Request</span><span class="op">&lt;</span><span class="lifetime">&#39;_</span><span class="op">&gt;</span>) <span class="op">-</span><span class="op">&gt;</span> <span class="prelude-ty">Result</span><span class="op">&lt;</span><span class="prelude-ty">Option</span><span class="op">&lt;</span><span class="ident">Origin</span><span class="op">&gt;</span>, <span class="ident">Error</span><span class="op">&gt;</span> {
<span class="kw">match</span> <span class="ident">Origin</span>::<span class="ident">from_request</span>(<span class="ident">request</span>) {
<span class="ident">Outcome</span>::<span class="ident">Forward</span>(()) <span class="op">=</span><span class="op">&gt;</span> <span class="prelude-val">Ok</span>(<span class="prelude-val">None</span>),
<span class="ident">Outcome</span>::<span class="ident">Success</span>(<span class="ident">origin</span>) <span class="op">=</span><span class="op">&gt;</span> <span class="prelude-val">Ok</span>(<span class="prelude-val">Some</span>(<span class="ident">origin</span>)),
<span class="ident">Outcome</span>::<span class="ident">Failure</span>((<span class="kw">_</span>, <span class="ident">err</span>)) <span class="op">=</span><span class="op">&gt;</span> <span class="prelude-val">Err</span>(<span class="ident">err</span>),
}
}
<span class="doccomment">/// Gets the `Access-Control-Request-Method` request header from the request</span>
<span class="kw">fn</span> <span class="ident">request_method</span>(<span class="ident">request</span>: <span class="kw-2">&amp;</span><span class="ident">Request</span><span class="op">&lt;</span><span class="lifetime">&#39;_</span><span class="op">&gt;</span>) <span class="op">-</span><span class="op">&gt;</span> <span class="prelude-ty">Result</span><span class="op">&lt;</span><span class="prelude-ty">Option</span><span class="op">&lt;</span><span class="ident">AccessControlRequestMethod</span><span class="op">&gt;</span>, <span class="ident">Error</span><span class="op">&gt;</span> {
<span class="kw">match</span> <span class="ident">AccessControlRequestMethod</span>::<span class="ident">from_request</span>(<span class="ident">request</span>) {
<span class="ident">Outcome</span>::<span class="ident">Forward</span>(()) <span class="op">=</span><span class="op">&gt;</span> <span class="prelude-val">Ok</span>(<span class="prelude-val">None</span>),
<span class="ident">Outcome</span>::<span class="ident">Success</span>(<span class="ident">method</span>) <span class="op">=</span><span class="op">&gt;</span> <span class="prelude-val">Ok</span>(<span class="prelude-val">Some</span>(<span class="ident">method</span>)),
<span class="ident">Outcome</span>::<span class="ident">Failure</span>((<span class="kw">_</span>, <span class="ident">err</span>)) <span class="op">=</span><span class="op">&gt;</span> <span class="prelude-val">Err</span>(<span class="ident">err</span>),
}
}
<span class="doccomment">/// Gets the `Access-Control-Request-Headers` request header from the request</span>
<span class="kw">fn</span> <span class="ident">request_headers</span>(<span class="ident">request</span>: <span class="kw-2">&amp;</span><span class="ident">Request</span><span class="op">&lt;</span><span class="lifetime">&#39;_</span><span class="op">&gt;</span>) <span class="op">-</span><span class="op">&gt;</span> <span class="prelude-ty">Result</span><span class="op">&lt;</span><span class="prelude-ty">Option</span><span class="op">&lt;</span><span class="ident">AccessControlRequestHeaders</span><span class="op">&gt;</span>, <span class="ident">Error</span><span class="op">&gt;</span> {
<span class="kw">match</span> <span class="ident">AccessControlRequestHeaders</span>::<span class="ident">from_request</span>(<span class="ident">request</span>) {
<span class="ident">Outcome</span>::<span class="ident">Forward</span>(()) <span class="op">=</span><span class="op">&gt;</span> <span class="prelude-val">Ok</span>(<span class="prelude-val">None</span>),
<span class="ident">Outcome</span>::<span class="ident">Success</span>(<span class="ident">geaders</span>) <span class="op">=</span><span class="op">&gt;</span> <span class="prelude-val">Ok</span>(<span class="prelude-val">Some</span>(<span class="ident">geaders</span>)),
<span class="ident">Outcome</span>::<span class="ident">Failure</span>((<span class="kw">_</span>, <span class="ident">err</span>)) <span class="op">=</span><span class="op">&gt;</span> <span class="prelude-val">Err</span>(<span class="ident">err</span>),
}
}
<span class="doccomment">/// Do pre-flight validation checks</span>
<span class="doccomment">///</span>
<span class="doccomment">/// This implementation references the</span>
<span class="doccomment">/// [W3C recommendation](https://www.w3.org/TR/cors/#resource-preflight-requests)</span>
<span class="doccomment">/// and [Fetch specification](https://fetch.spec.whatwg.org/#cors-preflight-fetch)</span>
<span class="kw">fn</span> <span class="ident">preflight_validate</span>(
<span class="ident">options</span>: <span class="kw-2">&amp;</span><span class="ident">Cors</span>,
<span class="ident">origin</span>: <span class="kw-2">&amp;</span><span class="ident">Origin</span>,
<span class="ident">method</span>: <span class="kw-2">&amp;</span><span class="prelude-ty">Option</span><span class="op">&lt;</span><span class="ident">AccessControlRequestMethod</span><span class="op">&gt;</span>,
<span class="ident">headers</span>: <span class="kw-2">&amp;</span><span class="prelude-ty">Option</span><span class="op">&lt;</span><span class="ident">AccessControlRequestHeaders</span><span class="op">&gt;</span>,
) <span class="op">-</span><span class="op">&gt;</span> <span class="prelude-ty">Result</span><span class="op">&lt;</span>(), <span class="ident">Error</span><span class="op">&gt;</span> {
<span class="comment">// Note: All header parse failures are dealt with in the `FromRequest` trait implementation</span>
<span class="comment">// 2. If the value of the Origin header is not a case-sensitive match for any of the values</span>
<span class="comment">// in list of origins do not set any additional headers and terminate this set of steps.</span>
<span class="ident">validate_origin</span>(<span class="ident">origin</span>, <span class="kw-2">&amp;</span><span class="ident">options</span>.<span class="ident">allowed_origins</span>)<span class="question-mark">?</span>;
<span class="comment">// 3. Let `method` be the value as result of parsing the Access-Control-Request-Method</span>
<span class="comment">// header.</span>
<span class="comment">// If there is no Access-Control-Request-Method header or if parsing failed,</span>
<span class="comment">// do not set any additional headers and terminate this set of steps.</span>
<span class="comment">// The request is outside the scope of this specification.</span>
<span class="kw">let</span> <span class="ident">method</span> <span class="op">=</span> <span class="ident">method</span>.<span class="ident">as_ref</span>().<span class="ident">ok_or_else</span>(<span class="op">|</span><span class="op">|</span> <span class="ident">Error</span>::<span class="ident">MissingRequestMethod</span>)<span class="question-mark">?</span>;
<span class="comment">// 4. Let header field-names be the values as result of parsing the</span>
<span class="comment">// Access-Control-Request-Headers headers.</span>
<span class="comment">// If there are no Access-Control-Request-Headers headers</span>
<span class="comment">// let header field-names be the empty list.</span>
<span class="comment">// If parsing failed do not set any additional headers and terminate this set of steps.</span>
<span class="comment">// The request is outside the scope of this specification.</span>
<span class="comment">// 5. If method is not a case-sensitive match for any of the values in list of methods</span>
<span class="comment">// do not set any additional headers and terminate this set of steps.</span>
<span class="ident">validate_allowed_method</span>(<span class="ident">method</span>, <span class="kw-2">&amp;</span><span class="ident">options</span>.<span class="ident">allowed_methods</span>)<span class="question-mark">?</span>;
<span class="comment">// 6. If any of the header field-names is not a ASCII case-insensitive match for any of the</span>
<span class="comment">// values in list of headers do not set any additional headers and terminate this set of</span>
<span class="comment">// steps.</span>
<span class="kw">if</span> <span class="kw">let</span> <span class="prelude-val">Some</span>(<span class="kw-2">ref</span> <span class="ident">headers</span>) <span class="op">=</span> <span class="kw-2">*</span><span class="ident">headers</span> {
<span class="ident">validate_allowed_headers</span>(<span class="ident">headers</span>, <span class="kw-2">&amp;</span><span class="ident">options</span>.<span class="ident">allowed_headers</span>)<span class="question-mark">?</span>;
}
<span class="prelude-val">Ok</span>(())
}
<span class="doccomment">/// Build a response for pre-flight checks</span>
<span class="doccomment">///</span>
<span class="doccomment">/// This implementation references the</span>
<span class="doccomment">/// [W3C recommendation](https://www.w3.org/TR/cors/#resource-preflight-requests)</span>
<span class="doccomment">/// and [Fetch specification](https://fetch.spec.whatwg.org/#cors-preflight-fetch).</span>
<span class="kw">fn</span> <span class="ident">preflight_response</span>(
<span class="ident">options</span>: <span class="kw-2">&amp;</span><span class="ident">Cors</span>,
<span class="ident">origin</span>: <span class="kw-2">&amp;</span><span class="ident">str</span>,
<span class="ident">headers</span>: <span class="prelude-ty">Option</span><span class="op">&lt;</span><span class="kw-2">&amp;</span><span class="ident">AccessControlRequestHeaders</span><span class="op">&gt;</span>,
) <span class="op">-</span><span class="op">&gt;</span> <span class="ident">Response</span> {
<span class="kw">let</span> <span class="ident">response</span> <span class="op">=</span> <span class="ident">Response</span>::<span class="ident">new</span>();
<span class="comment">// 7. If the resource supports credentials add a single Access-Control-Allow-Origin header,</span>
<span class="comment">// with the value of the Origin header as value, and add a</span>
<span class="comment">// single Access-Control-Allow-Credentials header with the case-sensitive string &quot;true&quot; as</span>
<span class="comment">// value.</span>
<span class="comment">// Otherwise, add a single Access-Control-Allow-Origin header,</span>
<span class="comment">// with either the value of the Origin header or the string &quot;*&quot; as value.</span>
<span class="comment">// Note: The string &quot;*&quot; cannot be used for a resource that supports credentials.</span>
<span class="comment">// Validation has been done in options.validate</span>
<span class="kw">let</span> <span class="ident">response</span> <span class="op">=</span> <span class="kw">match</span> <span class="ident">options</span>.<span class="ident">allowed_origins</span> {
<span class="ident">AllOrSome</span>::<span class="ident">All</span> <span class="op">=</span><span class="op">&gt;</span> {
<span class="kw">if</span> <span class="ident">options</span>.<span class="ident">send_wildcard</span> {
<span class="ident">response</span>.<span class="ident">any</span>()
} <span class="kw">else</span> {
<span class="ident">response</span>.<span class="ident">origin</span>(<span class="ident">origin</span>, <span class="bool-val">true</span>)
}
}
<span class="ident">AllOrSome</span>::<span class="prelude-val">Some</span>(<span class="kw">_</span>) <span class="op">=</span><span class="op">&gt;</span> <span class="ident">response</span>.<span class="ident">origin</span>(<span class="ident">origin</span>, <span class="bool-val">false</span>),
};
<span class="kw">let</span> <span class="ident">response</span> <span class="op">=</span> <span class="ident">response</span>.<span class="ident">credentials</span>(<span class="ident">options</span>.<span class="ident">allow_credentials</span>);
<span class="comment">// 8. Optionally add a single Access-Control-Max-Age header</span>
<span class="comment">// with as value the amount of seconds the user agent is allowed to cache the result of the</span>
<span class="comment">// request.</span>
<span class="kw">let</span> <span class="ident">response</span> <span class="op">=</span> <span class="ident">response</span>.<span class="ident">max_age</span>(<span class="ident">options</span>.<span class="ident">max_age</span>);
<span class="comment">// 9. If method is a simple method this step may be skipped.</span>
<span class="comment">// Add one or more Access-Control-Allow-Methods headers consisting of</span>
<span class="comment">// (a subset of) the list of methods.</span>
<span class="comment">// If a method is a simple method it does not need to be listed, but this is not prohibited.</span>
<span class="comment">// Since the list of methods can be unbounded,</span>
<span class="comment">// simply returning the method indicated by Access-Control-Request-Method</span>
<span class="comment">// (if supported) can be enough.</span>
<span class="kw">let</span> <span class="ident">response</span> <span class="op">=</span> <span class="ident">response</span>.<span class="ident">methods</span>(<span class="kw-2">&amp;</span><span class="ident">options</span>.<span class="ident">allowed_methods</span>);
<span class="comment">// 10. If each of the header field-names is a simple header and none is Content-Type,</span>
<span class="comment">// this step may be skipped.</span>
<span class="comment">// Add one or more Access-Control-Allow-Headers headers consisting of (a subset of)</span>
<span class="comment">// the list of headers.</span>
<span class="comment">// If a header field name is a simple header and is not Content-Type,</span>
<span class="comment">// it is not required to be listed. Content-Type is to be listed as only a</span>
<span class="comment">// subset of its values makes it qualify as simple header.</span>
<span class="comment">// Since the list of headers can be unbounded, simply returning supported headers</span>
<span class="comment">// from Access-Control-Allow-Headers can be enough.</span>
<span class="comment">// We do not do anything special with simple headers</span>
<span class="kw">if</span> <span class="kw">let</span> <span class="prelude-val">Some</span>(<span class="ident">headers</span>) <span class="op">=</span> <span class="ident">headers</span> {
<span class="kw">let</span> <span class="kw-2">&amp;</span><span class="ident">AccessControlRequestHeaders</span>(<span class="kw-2">ref</span> <span class="ident">headers</span>) <span class="op">=</span> <span class="ident">headers</span>;
<span class="ident">response</span>.<span class="ident">headers</span>(
<span class="ident">headers</span>
.<span class="ident">iter</span>()
.<span class="ident">map</span>(<span class="op">|</span><span class="ident">s</span><span class="op">|</span> <span class="kw-2">&amp;</span><span class="kw-2">*</span><span class="kw-2">*</span><span class="ident">s</span>.<span class="ident">deref</span>())
.<span class="ident">collect</span>::<span class="op">&lt;</span><span class="ident">Vec</span><span class="op">&lt;</span><span class="kw-2">&amp;</span><span class="ident">str</span><span class="op">&gt;</span><span class="op">&gt;</span>()
.<span class="ident">as_slice</span>(),
)
} <span class="kw">else</span> {
<span class="ident">response</span>
}
}
<span class="doccomment">/// Do checks for an actual request</span>
<span class="doccomment">///</span>
<span class="doccomment">/// This implementation references the</span>
<span class="doccomment">/// [W3C recommendation](https://www.w3.org/TR/cors/#resource-requests)</span>
<span class="doccomment">/// and [Fetch specification](https://fetch.spec.whatwg.org/#cors-preflight-fetch).</span>
<span class="kw">fn</span> <span class="ident">actual_request_validate</span>(<span class="ident">options</span>: <span class="kw-2">&amp;</span><span class="ident">Cors</span>, <span class="ident">origin</span>: <span class="kw-2">&amp;</span><span class="ident">Origin</span>) <span class="op">-</span><span class="op">&gt;</span> <span class="prelude-ty">Result</span><span class="op">&lt;</span>(), <span class="ident">Error</span><span class="op">&gt;</span> {
<span class="comment">// Note: All header parse failures are dealt with in the `FromRequest` trait implementation</span>
<span class="comment">// 2. If the value of the Origin header is not a case-sensitive match for any of the values</span>
<span class="comment">// in list of origins, do not set any additional headers and terminate this set of steps.</span>
<span class="comment">// Always matching is acceptable since the list of origins can be unbounded.</span>
<span class="ident">validate_origin</span>(<span class="ident">origin</span>, <span class="kw-2">&amp;</span><span class="ident">options</span>.<span class="ident">allowed_origins</span>)<span class="question-mark">?</span>;
<span class="prelude-val">Ok</span>(())
}
<span class="doccomment">/// Build the response for an actual request</span>
<span class="doccomment">///</span>
<span class="doccomment">/// This implementation references the</span>
<span class="doccomment">/// [W3C recommendation](https://www.w3.org/TR/cors/#resource-requests)</span>
<span class="doccomment">/// and [Fetch specification](https://fetch.spec.whatwg.org/#cors-preflight-fetch)</span>
<span class="kw">fn</span> <span class="ident">actual_request_response</span>(<span class="ident">options</span>: <span class="kw-2">&amp;</span><span class="ident">Cors</span>, <span class="ident">origin</span>: <span class="kw-2">&amp;</span><span class="ident">str</span>) <span class="op">-</span><span class="op">&gt;</span> <span class="ident">Response</span> {
<span class="kw">let</span> <span class="ident">response</span> <span class="op">=</span> <span class="ident">Response</span>::<span class="ident">new</span>();
<span class="comment">// 3. If the resource supports credentials add a single Access-Control-Allow-Origin header,</span>
<span class="comment">// with the value of the Origin header as value, and add a</span>
<span class="comment">// single Access-Control-Allow-Credentials header with the case-sensitive string &quot;true&quot; as</span>
<span class="comment">// value.</span>
<span class="comment">// Otherwise, add a single Access-Control-Allow-Origin header,</span>
<span class="comment">// with either the value of the Origin header or the string &quot;*&quot; as value.</span>
<span class="comment">// Note: The string &quot;*&quot; cannot be used for a resource that supports credentials.</span>
<span class="comment">// Validation has been done in options.validate</span>
<span class="kw">let</span> <span class="ident">response</span> <span class="op">=</span> <span class="kw">match</span> <span class="ident">options</span>.<span class="ident">allowed_origins</span> {
<span class="ident">AllOrSome</span>::<span class="ident">All</span> <span class="op">=</span><span class="op">&gt;</span> {
<span class="kw">if</span> <span class="ident">options</span>.<span class="ident">send_wildcard</span> {
<span class="ident">response</span>.<span class="ident">any</span>()
} <span class="kw">else</span> {
<span class="ident">response</span>.<span class="ident">origin</span>(<span class="ident">origin</span>, <span class="bool-val">true</span>)
}
}
<span class="ident">AllOrSome</span>::<span class="prelude-val">Some</span>(<span class="kw">_</span>) <span class="op">=</span><span class="op">&gt;</span> <span class="ident">response</span>.<span class="ident">origin</span>(<span class="ident">origin</span>, <span class="bool-val">false</span>),
};
<span class="kw">let</span> <span class="ident">response</span> <span class="op">=</span> <span class="ident">response</span>.<span class="ident">credentials</span>(<span class="ident">options</span>.<span class="ident">allow_credentials</span>);
<span class="comment">// 4. If the list of exposed headers is not empty add one or more</span>
<span class="comment">// Access-Control-Expose-Headers headers, with as values the header field names given in</span>
<span class="comment">// the list of exposed headers.</span>
<span class="comment">// By not adding the appropriate headers resource can also clear the preflight result cache</span>
<span class="comment">// of all entries where origin is a case-sensitive match for the value of the Origin header</span>
<span class="comment">// and url is a case-sensitive match for the URL of the resource.</span>
<span class="ident">response</span>.<span class="ident">exposed_headers</span>(
<span class="ident">options</span>
.<span class="ident">expose_headers</span>
.<span class="ident">iter</span>()
.<span class="ident">map</span>(<span class="op">|</span><span class="ident">s</span><span class="op">|</span> <span class="kw-2">&amp;</span><span class="kw-2">*</span><span class="kw-2">*</span><span class="ident">s</span>)
.<span class="ident">collect</span>::<span class="op">&lt;</span><span class="ident">Vec</span><span class="op">&lt;</span><span class="kw-2">&amp;</span><span class="ident">str</span><span class="op">&gt;</span><span class="op">&gt;</span>()
.<span class="ident">as_slice</span>(),
)
}
<span class="doccomment">/// Returns &quot;catch all&quot; OPTIONS routes that you can mount to catch all OPTIONS request. Only works</span>
<span class="doccomment">/// if you have put a `Cors` struct into Rocket&#39;s managed state.</span>
<span class="doccomment">///</span>
<span class="doccomment">/// This route has very high rank (and therefore low priority) of</span>
<span class="doccomment">/// [max value](https://doc.rust-lang.org/nightly/std/primitive.isize.html#method.max_value)</span>
<span class="doccomment">/// so you can define your own to override this route&#39;s behaviour.</span>
<span class="doccomment">///</span>
<span class="doccomment">/// See the documentation at the [crate root](index.html) for usage information.</span>
<span class="kw">pub</span> <span class="kw">fn</span> <span class="ident">catch_all_options_routes</span>() <span class="op">-</span><span class="op">&gt;</span> <span class="ident">Vec</span><span class="op">&lt;</span><span class="ident">rocket</span>::<span class="ident">Route</span><span class="op">&gt;</span> {
<span class="macro">vec</span><span class="macro">!</span>[
<span class="ident">rocket</span>::<span class="ident">Route</span>::<span class="ident">ranked</span>(
<span class="ident">isize</span>::<span class="ident">max_value</span>(),
<span class="ident">http</span>::<span class="ident">Method</span>::<span class="ident">Options</span>,
<span class="string">&quot;/&quot;</span>,
<span class="ident">catch_all_options_route_handler</span>,
),
<span class="ident">rocket</span>::<span class="ident">Route</span>::<span class="ident">ranked</span>(
<span class="ident">isize</span>::<span class="ident">max_value</span>(),
<span class="ident">http</span>::<span class="ident">Method</span>::<span class="ident">Options</span>,
<span class="string">&quot;/&lt;catch_all_options_route..&gt;&quot;</span>,
<span class="ident">catch_all_options_route_handler</span>,
),
]
}
<span class="doccomment">/// Handler for the &quot;catch all options route&quot;</span>
<span class="kw">fn</span> <span class="ident">catch_all_options_route_handler</span><span class="op">&lt;</span><span class="lifetime">&#39;r</span><span class="op">&gt;</span>(
<span class="ident">request</span>: <span class="kw-2">&amp;</span><span class="lifetime">&#39;r</span> <span class="ident">Request</span><span class="op">&lt;</span><span class="lifetime">&#39;_</span><span class="op">&gt;</span>,
<span class="kw">_</span>: <span class="ident">rocket</span>::<span class="ident">Data</span>,
) <span class="op">-</span><span class="op">&gt;</span> <span class="ident">rocket</span>::<span class="ident">handler</span>::<span class="ident">Outcome</span><span class="op">&lt;</span><span class="lifetime">&#39;r</span><span class="op">&gt;</span> {
<span class="kw">let</span> <span class="ident">guard</span>: <span class="ident">Guard</span><span class="op">&lt;</span><span class="lifetime">&#39;_</span><span class="op">&gt;</span> <span class="op">=</span> <span class="kw">match</span> <span class="ident">request</span>.<span class="ident">guard</span>() {
<span class="ident">Outcome</span>::<span class="ident">Success</span>(<span class="ident">guard</span>) <span class="op">=</span><span class="op">&gt;</span> <span class="ident">guard</span>,
<span class="ident">Outcome</span>::<span class="ident">Failure</span>((<span class="ident">status</span>, <span class="kw">_</span>)) <span class="op">=</span><span class="op">&gt;</span> <span class="kw">return</span> <span class="ident">rocket</span>::<span class="ident">handler</span>::<span class="ident">Outcome</span>::<span class="ident">failure</span>(<span class="ident">status</span>),
<span class="ident">Outcome</span>::<span class="ident">Forward</span>(()) <span class="op">=</span><span class="op">&gt;</span> <span class="macro">unreachable</span><span class="macro">!</span>(<span class="string">&quot;Should not be reachable&quot;</span>),
};
<span class="macro">info_</span><span class="macro">!</span>(
<span class="string">&quot;\&quot;Catch all\&quot; handling of CORS `OPTIONS` preflight for request {}&quot;</span>,
<span class="ident">request</span>
);
<span class="ident">rocket</span>::<span class="ident">handler</span>::<span class="ident">Outcome</span>::<span class="ident">from</span>(<span class="ident">request</span>, <span class="ident">guard</span>.<span class="ident">responder</span>(()))
}
<span class="attribute">#[<span class="ident">cfg</span>(<span class="ident">test</span>)]</span>
<span class="kw">mod</span> <span class="ident">tests</span> {
<span class="kw">use</span> <span class="ident">std</span>::<span class="ident">str</span>::<span class="ident">FromStr</span>;
<span class="kw">use</span> <span class="ident">rocket</span>::<span class="ident">http</span>::<span class="ident">Header</span>;
<span class="kw">use</span> <span class="ident">rocket</span>::<span class="ident">local</span>::<span class="ident">Client</span>;
<span class="attribute">#[<span class="ident">cfg</span>(<span class="ident">feature</span> <span class="op">=</span> <span class="string">&quot;serialization&quot;</span>)]</span>
<span class="kw">use</span> <span class="ident">serde_json</span>;
<span class="kw">use</span> <span class="kw">super</span>::<span class="kw-2">*</span>;
<span class="kw">use</span> <span class="kw">crate</span>::<span class="ident">http</span>::<span class="ident">Method</span>;
<span class="kw">fn</span> <span class="ident">to_parsed_origin</span><span class="op">&lt;</span><span class="ident">S</span>: <span class="ident">AsRef</span><span class="op">&lt;</span><span class="ident">str</span><span class="op">&gt;</span><span class="op">&gt;</span>(<span class="ident">origin</span>: <span class="ident">S</span>) <span class="op">-</span><span class="op">&gt;</span> <span class="prelude-ty">Result</span><span class="op">&lt;</span><span class="ident">Origin</span>, <span class="ident">Error</span><span class="op">&gt;</span> {
<span class="ident">Origin</span>::<span class="ident">from_str</span>(<span class="ident">origin</span>.<span class="ident">as_ref</span>())
}
<span class="kw">fn</span> <span class="ident">make_cors_options</span>() <span class="op">-</span><span class="op">&gt;</span> <span class="ident">CorsOptions</span> {
<span class="kw">let</span> <span class="ident">allowed_origins</span> <span class="op">=</span> <span class="ident">AllowedOrigins</span>::<span class="ident">some_exact</span>(<span class="kw-2">&amp;</span>[<span class="string">&quot;https://www.acme.com&quot;</span>]);
<span class="ident">CorsOptions</span> {
<span class="ident">allowed_origins</span>,
<span class="ident">allowed_methods</span>: <span class="macro">vec</span><span class="macro">!</span>[<span class="ident">http</span>::<span class="ident">Method</span>::<span class="ident">Get</span>]
.<span class="ident">into_iter</span>()
.<span class="ident">map</span>(<span class="ident">From</span>::<span class="ident">from</span>)
.<span class="ident">collect</span>(),
<span class="ident">allowed_headers</span>: <span class="ident">AllowedHeaders</span>::<span class="ident">some</span>(<span class="kw-2">&amp;</span>[<span class="kw-2">&amp;</span><span class="string">&quot;Authorization&quot;</span>, <span class="string">&quot;Accept&quot;</span>]),
<span class="ident">allow_credentials</span>: <span class="bool-val">true</span>,
<span class="ident">expose_headers</span>: [<span class="string">&quot;Content-Type&quot;</span>, <span class="string">&quot;X-Custom&quot;</span>]
.<span class="ident">iter</span>()
.<span class="ident">map</span>(<span class="op">|</span><span class="ident">s</span><span class="op">|</span> (<span class="kw-2">*</span><span class="ident">s</span>).<span class="ident">to_string</span>())
.<span class="ident">collect</span>(),
..<span class="ident">Default</span>::<span class="ident">default</span>()
}
}
<span class="kw">fn</span> <span class="ident">make_invalid_options</span>() <span class="op">-</span><span class="op">&gt;</span> <span class="ident">CorsOptions</span> {
<span class="kw">let</span> <span class="kw-2">mut</span> <span class="ident">cors</span> <span class="op">=</span> <span class="ident">make_cors_options</span>();
<span class="ident">cors</span>.<span class="ident">allow_credentials</span> <span class="op">=</span> <span class="bool-val">true</span>;
<span class="ident">cors</span>.<span class="ident">allowed_origins</span> <span class="op">=</span> <span class="ident">AllOrSome</span>::<span class="ident">All</span>;
<span class="ident">cors</span>.<span class="ident">send_wildcard</span> <span class="op">=</span> <span class="bool-val">true</span>;
<span class="ident">cors</span>
}
<span class="doccomment">/// Make a client with no routes for unit testing</span>
<span class="kw">fn</span> <span class="ident">make_client</span>() <span class="op">-</span><span class="op">&gt;</span> <span class="ident">Client</span> {
<span class="kw">let</span> <span class="ident">rocket</span> <span class="op">=</span> <span class="ident">rocket</span>::<span class="ident">ignite</span>();
<span class="ident">Client</span>::<span class="ident">new</span>(<span class="ident">rocket</span>).<span class="ident">expect</span>(<span class="string">&quot;valid rocket instance&quot;</span>)
}
<span class="comment">// CORS options test</span>
<span class="attribute">#[<span class="ident">test</span>]</span>
<span class="kw">fn</span> <span class="ident">cors_is_validated</span>() {
<span class="macro">assert</span><span class="macro">!</span>(<span class="ident">make_cors_options</span>().<span class="ident">validate</span>().<span class="ident">is_ok</span>())
}
<span class="attribute">#[<span class="ident">test</span>]</span>
<span class="attribute">#[<span class="ident">should_panic</span>(<span class="ident">expected</span> <span class="op">=</span> <span class="string">&quot;CredentialsWithWildcardOrigin&quot;</span>)]</span>
<span class="kw">fn</span> <span class="ident">cors_validates_illegal_allow_credentials</span>() {
<span class="kw">let</span> <span class="ident">cors</span> <span class="op">=</span> <span class="ident">make_invalid_options</span>();
<span class="ident">cors</span>.<span class="ident">validate</span>().<span class="ident">unwrap</span>();
}
<span class="doccomment">/// Check that the the default deserialization matches the one returned by `Default::default`</span>
<span class="attribute">#[<span class="ident">cfg</span>(<span class="ident">feature</span> <span class="op">=</span> <span class="string">&quot;serialization&quot;</span>)]</span>
<span class="attribute">#[<span class="ident">test</span>]</span>
<span class="kw">fn</span> <span class="ident">cors_default_deserialization_is_correct</span>() {
<span class="kw">let</span> <span class="ident">deserialized</span>: <span class="ident">CorsOptions</span> <span class="op">=</span> <span class="ident">serde_json</span>::<span class="ident">from_str</span>(<span class="string">&quot;{}&quot;</span>).<span class="ident">expect</span>(<span class="string">&quot;To not fail&quot;</span>);
<span class="macro">assert_eq</span><span class="macro">!</span>(<span class="ident">deserialized</span>, <span class="ident">CorsOptions</span>::<span class="ident">default</span>());
<span class="kw">let</span> <span class="ident">expected_json</span> <span class="op">=</span> <span class="string">r#&quot;
{
&quot;allowed_origins&quot;: &quot;All&quot;,
&quot;allowed_methods&quot;: [
&quot;POST&quot;,
&quot;PATCH&quot;,
&quot;PUT&quot;,
&quot;DELETE&quot;,
&quot;HEAD&quot;,
&quot;OPTIONS&quot;,
&quot;GET&quot;
],
&quot;allowed_headers&quot;: &quot;All&quot;,
&quot;allow_credentials&quot;: false,
&quot;expose_headers&quot;: [],
&quot;max_age&quot;: null,
&quot;send_wildcard&quot;: false,
&quot;fairing_route_base&quot;: &quot;/cors&quot;,
&quot;fairing_route_rank&quot;: 0
}
&quot;#</span>;
<span class="kw">let</span> <span class="ident">actual</span>: <span class="ident">CorsOptions</span> <span class="op">=</span> <span class="ident">serde_json</span>::<span class="ident">from_str</span>(<span class="ident">expected_json</span>).<span class="ident">expect</span>(<span class="string">&quot;to not fail&quot;</span>);
<span class="macro">assert_eq</span><span class="macro">!</span>(<span class="ident">actual</span>, <span class="ident">CorsOptions</span>::<span class="ident">default</span>());
}
<span class="doccomment">/// Checks that the example provided can actually be deserialized</span>
<span class="attribute">#[<span class="ident">cfg</span>(<span class="ident">feature</span> <span class="op">=</span> <span class="string">&quot;serialization&quot;</span>)]</span>
<span class="attribute">#[<span class="ident">test</span>]</span>
<span class="kw">fn</span> <span class="ident">cors_options_example_can_be_deserialized</span>() {
<span class="kw">let</span> <span class="ident">json</span> <span class="op">=</span> <span class="string">r#&quot;{
&quot;allowed_origins&quot;: {
&quot;Some&quot;: {
&quot;exact&quot;: [&quot;https://www.acme.com&quot;],
&quot;regex&quot;: [&quot;^https://www.example-[A-z0-9]*.com$&quot;]
}
},
&quot;allowed_methods&quot;: [
&quot;POST&quot;,
&quot;DELETE&quot;,
&quot;GET&quot;
],
&quot;allowed_headers&quot;: {
&quot;Some&quot;: [
&quot;Accept&quot;,
&quot;Authorization&quot;
]
},
&quot;allow_credentials&quot;: true,
&quot;expose_headers&quot;: [
&quot;Content-Type&quot;,
&quot;X-Custom&quot;
],
&quot;max_age&quot;: 42,
&quot;send_wildcard&quot;: false,
&quot;fairing_route_base&quot;: &quot;/mycors&quot;
}&quot;#</span>;
<span class="kw">let</span> <span class="kw">_</span>: <span class="ident">CorsOptions</span> <span class="op">=</span> <span class="ident">serde_json</span>::<span class="ident">from_str</span>(<span class="ident">json</span>).<span class="ident">expect</span>(<span class="string">&quot;to not fail&quot;</span>);
}
<span class="attribute">#[<span class="ident">test</span>]</span>
<span class="kw">fn</span> <span class="ident">allowed_some_origins_allows_different_lifetimes</span>() {
<span class="kw">let</span> <span class="ident">static_exact</span> <span class="op">=</span> [<span class="string">&quot;http://www.example.com&quot;</span>];
<span class="kw">let</span> <span class="ident">random_allocation</span> <span class="op">=</span> <span class="macro">vec</span><span class="macro">!</span>[<span class="number">1</span>, <span class="number">2</span>, <span class="number">3</span>];
<span class="kw">let</span> <span class="ident">port</span>: <span class="kw-2">*</span><span class="kw">const</span> <span class="ident">Vec</span><span class="op">&lt;</span><span class="ident">i32</span><span class="op">&gt;</span> <span class="op">=</span> <span class="kw-2">&amp;</span><span class="ident">random_allocation</span>;
<span class="kw">let</span> <span class="ident">port</span> <span class="op">=</span> <span class="ident">port</span> <span class="kw">as</span> <span class="ident">u16</span>;
<span class="kw">let</span> <span class="ident">random_regex</span> <span class="op">=</span> <span class="macro">vec</span><span class="macro">!</span>[<span class="macro">format</span><span class="macro">!</span>(<span class="string">&quot;https://(.+):{}&quot;</span>, <span class="ident">port</span>)];
<span class="comment">// Should compile</span>
<span class="kw">let</span> <span class="kw">_</span> <span class="op">=</span> <span class="ident">AllowedOrigins</span>::<span class="ident">some</span>(<span class="kw-2">&amp;</span><span class="ident">static_exact</span>, <span class="kw-2">&amp;</span><span class="ident">random_regex</span>);
}
<span class="comment">// `ParsedAllowedOrigins::parse` tests</span>
<span class="attribute">#[<span class="ident">test</span>]</span>
<span class="kw">fn</span> <span class="ident">allowed_origins_are_parsed_correctly</span>() {
<span class="kw">let</span> <span class="ident">allowed_origins</span> <span class="op">=</span> <span class="macro">not_err</span><span class="macro">!</span>(<span class="ident">parse_allowed_origins</span>(<span class="kw-2">&amp;</span><span class="ident">AllowedOrigins</span>::<span class="ident">some</span>(
<span class="kw-2">&amp;</span>[<span class="string">&quot;https://www.acme.com&quot;</span>],
<span class="kw-2">&amp;</span>[<span class="string">&quot;^https://www.example-[A-z0-9]+.com$&quot;</span>]
)));
<span class="macro">assert</span><span class="macro">!</span>(<span class="ident">allowed_origins</span>.<span class="ident">is_some</span>());
<span class="kw">let</span> <span class="ident">expected_exact</span>: <span class="ident">HashSet</span><span class="op">&lt;</span><span class="ident">url</span>::<span class="ident">Origin</span><span class="op">&gt;</span> <span class="op">=</span> [<span class="ident">url</span>::<span class="ident">Url</span>::<span class="ident">from_str</span>(<span class="string">&quot;https://www.acme.com&quot;</span>)
.<span class="ident">expect</span>(<span class="string">&quot;not to fail&quot;</span>)
.<span class="ident">origin</span>()]
.<span class="ident">iter</span>()
.<span class="ident">map</span>(<span class="ident">Clone</span>::<span class="ident">clone</span>)
.<span class="ident">collect</span>();
<span class="kw">let</span> <span class="ident">expected_regex</span> <span class="op">=</span> [<span class="string">&quot;^https://www.example-[A-z0-9]+.com$&quot;</span>];
<span class="kw">let</span> <span class="ident">actual</span> <span class="op">=</span> <span class="ident">allowed_origins</span>.<span class="ident">unwrap</span>();
<span class="macro">assert_eq</span><span class="macro">!</span>(<span class="ident">expected_exact</span>, <span class="ident">actual</span>.<span class="ident">exact</span>);
<span class="macro">assert_eq</span><span class="macro">!</span>(<span class="ident">expected_regex</span>, <span class="ident">actual</span>.<span class="ident">regex</span>.<span class="ident">expect</span>(<span class="string">&quot;to be some&quot;</span>).<span class="ident">patterns</span>());
}
<span class="attribute">#[<span class="ident">test</span>]</span>
<span class="kw">fn</span> <span class="ident">allowed_origins_errors_on_opaque_exact</span>() {
<span class="kw">let</span> <span class="ident">error</span> <span class="op">=</span> <span class="ident">parse_allowed_origins</span>(<span class="kw-2">&amp;</span><span class="ident">AllowedOrigins</span>::<span class="ident">some</span>::<span class="op">&lt;</span><span class="kw">_</span>, <span class="kw-2">&amp;</span><span class="ident">str</span><span class="op">&gt;</span>(
<span class="kw-2">&amp;</span>[
<span class="string">&quot;chrome-extension://something&quot;</span>,
<span class="string">&quot;moz-extension://something&quot;</span>,
<span class="string">&quot;https://valid.com&quot;</span>,
],
<span class="kw-2">&amp;</span>[],
))
.<span class="ident">unwrap_err</span>();
<span class="kw">match</span> <span class="ident">error</span> {
<span class="ident">Error</span>::<span class="ident">OpaqueAllowedOrigin</span>(<span class="kw-2">mut</span> <span class="ident">origins</span>) <span class="op">=</span><span class="op">&gt;</span> {
<span class="ident">origins</span>.<span class="ident">sort</span>();
<span class="macro">assert_eq</span><span class="macro">!</span>(
<span class="ident">origins</span>,
[<span class="string">&quot;chrome-extension://something&quot;</span>, <span class="string">&quot;moz-extension://something&quot;</span>]
);
}
<span class="ident">others</span> <span class="op">=</span><span class="op">&gt;</span> {
<span class="macro">panic</span><span class="macro">!</span>(<span class="string">&quot;Unexpected error: {:#?}&quot;</span>, <span class="ident">others</span>);
}
};
}
<span class="comment">// The following tests check validation</span>
<span class="attribute">#[<span class="ident">test</span>]</span>
<span class="kw">fn</span> <span class="ident">validate_origin_allows_all_origins</span>() {
<span class="kw">let</span> <span class="ident">url</span> <span class="op">=</span> <span class="string">&quot;https://www.example.com&quot;</span>;
<span class="kw">let</span> <span class="ident">origin</span> <span class="op">=</span> <span class="macro">not_err</span><span class="macro">!</span>(<span class="ident">to_parsed_origin</span>(<span class="kw-2">&amp;</span><span class="ident">url</span>));
<span class="kw">let</span> <span class="ident">allowed_origins</span> <span class="op">=</span> <span class="ident">AllOrSome</span>::<span class="ident">All</span>;
<span class="macro">not_err</span><span class="macro">!</span>(<span class="ident">validate_origin</span>(<span class="kw-2">&amp;</span><span class="ident">origin</span>, <span class="kw-2">&amp;</span><span class="ident">allowed_origins</span>));
}
<span class="attribute">#[<span class="ident">test</span>]</span>
<span class="kw">fn</span> <span class="ident">validate_origin_allows_origin</span>() {
<span class="kw">let</span> <span class="ident">url</span> <span class="op">=</span> <span class="string">&quot;https://www.example.com&quot;</span>;
<span class="kw">let</span> <span class="ident">origin</span> <span class="op">=</span> <span class="macro">not_err</span><span class="macro">!</span>(<span class="ident">to_parsed_origin</span>(<span class="kw-2">&amp;</span><span class="ident">url</span>));
<span class="kw">let</span> <span class="ident">allowed_origins</span> <span class="op">=</span> <span class="macro">not_err</span><span class="macro">!</span>(<span class="ident">parse_allowed_origins</span>(<span class="kw-2">&amp;</span><span class="ident">AllowedOrigins</span>::<span class="ident">some_exact</span>(<span class="kw-2">&amp;</span>[
<span class="string">&quot;https://www.example.com&quot;</span>
])));
<span class="macro">not_err</span><span class="macro">!</span>(<span class="ident">validate_origin</span>(<span class="kw-2">&amp;</span><span class="ident">origin</span>, <span class="kw-2">&amp;</span><span class="ident">allowed_origins</span>));
}
<span class="attribute">#[<span class="ident">test</span>]</span>
<span class="kw">fn</span> <span class="ident">validate_origin_handles_punycode_properly</span>() {
<span class="comment">// Test a variety of scenarios where the Origin and settings are in punycode, or not</span>
<span class="kw">let</span> <span class="ident">cases</span> <span class="op">=</span> <span class="macro">vec</span><span class="macro">!</span>[
(<span class="string">&quot;https://аpple.com&quot;</span>, <span class="string">&quot;https://аpple.com&quot;</span>),
(<span class="string">&quot;https://аpple.com&quot;</span>, <span class="string">&quot;https://xn--pple-43d.com&quot;</span>),
(<span class="string">&quot;https://xn--pple-43d.com&quot;</span>, <span class="string">&quot;https://аpple.com&quot;</span>),
(<span class="string">&quot;https://xn--pple-43d.com&quot;</span>, <span class="string">&quot;https://xn--pple-43d.com&quot;</span>),
];
<span class="kw">for</span> (<span class="ident">url</span>, <span class="ident">allowed_origin</span>) <span class="kw">in</span> <span class="ident">cases</span> {
<span class="kw">let</span> <span class="ident">origin</span> <span class="op">=</span> <span class="macro">not_err</span><span class="macro">!</span>(<span class="ident">to_parsed_origin</span>(<span class="kw-2">&amp;</span><span class="ident">url</span>));
<span class="kw">let</span> <span class="ident">allowed_origins</span> <span class="op">=</span> <span class="macro">not_err</span><span class="macro">!</span>(<span class="ident">parse_allowed_origins</span>(<span class="kw-2">&amp;</span><span class="ident">AllowedOrigins</span>::<span class="ident">some_exact</span>(<span class="kw-2">&amp;</span>[
<span class="ident">allowed_origin</span>
])));
<span class="macro">not_err</span><span class="macro">!</span>(<span class="ident">validate_origin</span>(<span class="kw-2">&amp;</span><span class="ident">origin</span>, <span class="kw-2">&amp;</span><span class="ident">allowed_origins</span>));
}
}
<span class="attribute">#[<span class="ident">test</span>]</span>
<span class="kw">fn</span> <span class="ident">validate_origin_validates_regex</span>() {
<span class="kw">let</span> <span class="ident">allowed_origins</span> <span class="op">=</span> <span class="macro">not_err</span><span class="macro">!</span>(<span class="ident">parse_allowed_origins</span>(<span class="kw-2">&amp;</span><span class="ident">AllowedOrigins</span>::<span class="ident">some_regex</span>(<span class="kw-2">&amp;</span>[
<span class="string">&quot;^https://www.example-[A-z0-9]+.com$&quot;</span>,
<span class="string">&quot;^https://(.+).acme.com$&quot;</span>,
])));
<span class="kw">let</span> <span class="ident">url</span> <span class="op">=</span> <span class="string">&quot;https://www.example-something.com&quot;</span>;
<span class="kw">let</span> <span class="ident">origin</span> <span class="op">=</span> <span class="macro">not_err</span><span class="macro">!</span>(<span class="ident">to_parsed_origin</span>(<span class="kw-2">&amp;</span><span class="ident">url</span>));
<span class="macro">not_err</span><span class="macro">!</span>(<span class="ident">validate_origin</span>(<span class="kw-2">&amp;</span><span class="ident">origin</span>, <span class="kw-2">&amp;</span><span class="ident">allowed_origins</span>));
<span class="kw">let</span> <span class="ident">url</span> <span class="op">=</span> <span class="string">&quot;https://subdomain.acme.com&quot;</span>;
<span class="kw">let</span> <span class="ident">origin</span> <span class="op">=</span> <span class="macro">not_err</span><span class="macro">!</span>(<span class="ident">to_parsed_origin</span>(<span class="kw-2">&amp;</span><span class="ident">url</span>));
<span class="macro">not_err</span><span class="macro">!</span>(<span class="ident">validate_origin</span>(<span class="kw-2">&amp;</span><span class="ident">origin</span>, <span class="kw-2">&amp;</span><span class="ident">allowed_origins</span>));
}
<span class="attribute">#[<span class="ident">test</span>]</span>
<span class="kw">fn</span> <span class="ident">validate_origin_validates_opaque_origins</span>() {
<span class="kw">let</span> <span class="ident">url</span> <span class="op">=</span> <span class="string">&quot;moz-extension://8c7c4444-e29f-…cb8-1ade813dbd12/js/content.js:505&quot;</span>;
<span class="kw">let</span> <span class="ident">origin</span> <span class="op">=</span> <span class="macro">not_err</span><span class="macro">!</span>(<span class="ident">to_parsed_origin</span>(<span class="kw-2">&amp;</span><span class="ident">url</span>));
<span class="kw">let</span> <span class="ident">allowed_origins</span> <span class="op">=</span> <span class="macro">not_err</span><span class="macro">!</span>(<span class="ident">parse_allowed_origins</span>(<span class="kw-2">&amp;</span><span class="ident">AllowedOrigins</span>::<span class="ident">some_regex</span>(<span class="kw-2">&amp;</span>[
<span class="string">&quot;moz-extension://.*&quot;</span>
])));
<span class="macro">not_err</span><span class="macro">!</span>(<span class="ident">validate_origin</span>(<span class="kw-2">&amp;</span><span class="ident">origin</span>, <span class="kw-2">&amp;</span><span class="ident">allowed_origins</span>));
}
<span class="attribute">#[<span class="ident">test</span>]</span>
<span class="kw">fn</span> <span class="ident">validate_origin_validates_mixed_settings</span>() {
<span class="kw">let</span> <span class="ident">allowed_origins</span> <span class="op">=</span> <span class="macro">not_err</span><span class="macro">!</span>(<span class="ident">parse_allowed_origins</span>(<span class="kw-2">&amp;</span><span class="ident">AllowedOrigins</span>::<span class="ident">some</span>(
<span class="kw-2">&amp;</span>[<span class="string">&quot;https://www.acme.com&quot;</span>],
<span class="kw-2">&amp;</span>[<span class="string">&quot;^https://www.example-[A-z0-9]+.com$&quot;</span>]
)));
<span class="kw">let</span> <span class="ident">url</span> <span class="op">=</span> <span class="string">&quot;https://www.example-something123.com&quot;</span>;
<span class="kw">let</span> <span class="ident">origin</span> <span class="op">=</span> <span class="macro">not_err</span><span class="macro">!</span>(<span class="ident">to_parsed_origin</span>(<span class="kw-2">&amp;</span><span class="ident">url</span>));
<span class="macro">not_err</span><span class="macro">!</span>(<span class="ident">validate_origin</span>(<span class="kw-2">&amp;</span><span class="ident">origin</span>, <span class="kw-2">&amp;</span><span class="ident">allowed_origins</span>));
<span class="kw">let</span> <span class="ident">url</span> <span class="op">=</span> <span class="string">&quot;https://www.acme.com&quot;</span>;
<span class="kw">let</span> <span class="ident">origin</span> <span class="op">=</span> <span class="macro">not_err</span><span class="macro">!</span>(<span class="ident">to_parsed_origin</span>(<span class="kw-2">&amp;</span><span class="ident">url</span>));
<span class="macro">not_err</span><span class="macro">!</span>(<span class="ident">validate_origin</span>(<span class="kw-2">&amp;</span><span class="ident">origin</span>, <span class="kw-2">&amp;</span><span class="ident">allowed_origins</span>));
}
<span class="attribute">#[<span class="ident">test</span>]</span>
<span class="attribute">#[<span class="ident">should_panic</span>(<span class="ident">expected</span> <span class="op">=</span> <span class="string">&quot;OriginNotAllowed&quot;</span>)]</span>
<span class="kw">fn</span> <span class="ident">validate_origin_rejects_invalid_origin</span>() {
<span class="kw">let</span> <span class="ident">url</span> <span class="op">=</span> <span class="string">&quot;https://www.acme.com&quot;</span>;
<span class="kw">let</span> <span class="ident">origin</span> <span class="op">=</span> <span class="macro">not_err</span><span class="macro">!</span>(<span class="ident">to_parsed_origin</span>(<span class="kw-2">&amp;</span><span class="ident">url</span>));
<span class="kw">let</span> <span class="ident">allowed_origins</span> <span class="op">=</span> <span class="macro">not_err</span><span class="macro">!</span>(<span class="ident">parse_allowed_origins</span>(<span class="kw-2">&amp;</span><span class="ident">AllowedOrigins</span>::<span class="ident">some_exact</span>(<span class="kw-2">&amp;</span>[
<span class="string">&quot;https://www.example.com&quot;</span>
])));
<span class="ident">validate_origin</span>(<span class="kw-2">&amp;</span><span class="ident">origin</span>, <span class="kw-2">&amp;</span><span class="ident">allowed_origins</span>).<span class="ident">unwrap</span>();
}
<span class="attribute">#[<span class="ident">test</span>]</span>
<span class="kw">fn</span> <span class="ident">response_sets_allow_origin_without_vary_correctly</span>() {
<span class="kw">let</span> <span class="ident">response</span> <span class="op">=</span> <span class="ident">Response</span>::<span class="ident">new</span>();
<span class="kw">let</span> <span class="ident">response</span> <span class="op">=</span> <span class="ident">response</span>.<span class="ident">origin</span>(<span class="string">&quot;https://www.example.com&quot;</span>, <span class="bool-val">false</span>);
<span class="comment">// Build response and check built response header</span>
<span class="kw">let</span> <span class="ident">expected_header</span> <span class="op">=</span> <span class="macro">vec</span><span class="macro">!</span>[<span class="string">&quot;https://www.example.com&quot;</span>];
<span class="kw">let</span> <span class="ident">response</span> <span class="op">=</span> <span class="ident">response</span>.<span class="ident">response</span>(<span class="ident">response</span>::<span class="ident">Response</span>::<span class="ident">new</span>());
<span class="kw">let</span> <span class="ident">actual_header</span>: <span class="ident">Vec</span><span class="op">&lt;</span><span class="kw">_</span><span class="op">&gt;</span> <span class="op">=</span> <span class="ident">response</span>
.<span class="ident">headers</span>()
.<span class="ident">get</span>(<span class="string">&quot;Access-Control-Allow-Origin&quot;</span>)
.<span class="ident">collect</span>();
<span class="macro">assert_eq</span><span class="macro">!</span>(<span class="ident">expected_header</span>, <span class="ident">actual_header</span>);
<span class="macro">assert</span><span class="macro">!</span>(<span class="ident">response</span>.<span class="ident">headers</span>().<span class="ident">get</span>(<span class="string">&quot;Vary&quot;</span>).<span class="ident">next</span>().<span class="ident">is_none</span>());
}
<span class="attribute">#[<span class="ident">test</span>]</span>
<span class="kw">fn</span> <span class="ident">response_sets_allow_origin_with_vary_correctly</span>() {
<span class="kw">let</span> <span class="ident">response</span> <span class="op">=</span> <span class="ident">Response</span>::<span class="ident">new</span>();
<span class="kw">let</span> <span class="ident">response</span> <span class="op">=</span> <span class="ident">response</span>.<span class="ident">origin</span>(<span class="string">&quot;https://www.example.com&quot;</span>, <span class="bool-val">true</span>);
<span class="comment">// Build response and check built response header</span>
<span class="kw">let</span> <span class="ident">expected_header</span> <span class="op">=</span> <span class="macro">vec</span><span class="macro">!</span>[<span class="string">&quot;https://www.example.com&quot;</span>];
<span class="kw">let</span> <span class="ident">response</span> <span class="op">=</span> <span class="ident">response</span>.<span class="ident">response</span>(<span class="ident">response</span>::<span class="ident">Response</span>::<span class="ident">new</span>());
<span class="kw">let</span> <span class="ident">actual_header</span>: <span class="ident">Vec</span><span class="op">&lt;</span><span class="kw">_</span><span class="op">&gt;</span> <span class="op">=</span> <span class="ident">response</span>
.<span class="ident">headers</span>()
.<span class="ident">get</span>(<span class="string">&quot;Access-Control-Allow-Origin&quot;</span>)
.<span class="ident">collect</span>();
<span class="macro">assert_eq</span><span class="macro">!</span>(<span class="ident">expected_header</span>, <span class="ident">actual_header</span>);
}
<span class="attribute">#[<span class="ident">test</span>]</span>
<span class="kw">fn</span> <span class="ident">response_sets_any_origin_correctly</span>() {
<span class="kw">let</span> <span class="ident">response</span> <span class="op">=</span> <span class="ident">Response</span>::<span class="ident">new</span>();
<span class="kw">let</span> <span class="ident">response</span> <span class="op">=</span> <span class="ident">response</span>.<span class="ident">any</span>();
<span class="comment">// Build response and check built response header</span>
<span class="kw">let</span> <span class="ident">expected_header</span> <span class="op">=</span> <span class="macro">vec</span><span class="macro">!</span>[<span class="string">&quot;*&quot;</span>];
<span class="kw">let</span> <span class="ident">response</span> <span class="op">=</span> <span class="ident">response</span>.<span class="ident">response</span>(<span class="ident">response</span>::<span class="ident">Response</span>::<span class="ident">new</span>());
<span class="kw">let</span> <span class="ident">actual_header</span>: <span class="ident">Vec</span><span class="op">&lt;</span><span class="kw">_</span><span class="op">&gt;</span> <span class="op">=</span> <span class="ident">response</span>
.<span class="ident">headers</span>()
.<span class="ident">get</span>(<span class="string">&quot;Access-Control-Allow-Origin&quot;</span>)
.<span class="ident">collect</span>();
<span class="macro">assert_eq</span><span class="macro">!</span>(<span class="ident">expected_header</span>, <span class="ident">actual_header</span>);
}
<span class="attribute">#[<span class="ident">test</span>]</span>
<span class="kw">fn</span> <span class="ident">response_sets_exposed_headers_correctly</span>() {
<span class="kw">let</span> <span class="ident">headers</span> <span class="op">=</span> <span class="macro">vec</span><span class="macro">!</span>[<span class="string">&quot;Bar&quot;</span>, <span class="string">&quot;Baz&quot;</span>, <span class="string">&quot;Foo&quot;</span>];
<span class="kw">let</span> <span class="ident">response</span> <span class="op">=</span> <span class="ident">Response</span>::<span class="ident">new</span>();
<span class="kw">let</span> <span class="ident">response</span> <span class="op">=</span> <span class="ident">response</span>.<span class="ident">origin</span>(<span class="string">&quot;https://www.example.com&quot;</span>, <span class="bool-val">false</span>);
<span class="kw">let</span> <span class="ident">response</span> <span class="op">=</span> <span class="ident">response</span>.<span class="ident">exposed_headers</span>(<span class="kw-2">&amp;</span><span class="ident">headers</span>);
<span class="comment">// Build response and check built response header</span>
<span class="kw">let</span> <span class="ident">response</span> <span class="op">=</span> <span class="ident">response</span>.<span class="ident">response</span>(<span class="ident">response</span>::<span class="ident">Response</span>::<span class="ident">new</span>());
<span class="kw">let</span> <span class="ident">actual_header</span>: <span class="ident">Vec</span><span class="op">&lt;</span><span class="kw">_</span><span class="op">&gt;</span> <span class="op">=</span> <span class="ident">response</span>
.<span class="ident">headers</span>()
.<span class="ident">get</span>(<span class="string">&quot;Access-Control-Expose-Headers&quot;</span>)
.<span class="ident">collect</span>();
<span class="macro">assert_eq</span><span class="macro">!</span>(<span class="number">1</span>, <span class="ident">actual_header</span>.<span class="ident">len</span>());
<span class="kw">let</span> <span class="kw-2">mut</span> <span class="ident">actual_headers</span>: <span class="ident">Vec</span><span class="op">&lt;</span><span class="ident">String</span><span class="op">&gt;</span> <span class="op">=</span> <span class="ident">actual_header</span>[<span class="number">0</span>]
.<span class="ident">split</span>(<span class="string">&#39;,&#39;</span>)
.<span class="ident">map</span>(<span class="op">|</span><span class="ident">header</span><span class="op">|</span> <span class="ident">header</span>.<span class="ident">trim</span>().<span class="ident">to_string</span>())
.<span class="ident">collect</span>();
<span class="ident">actual_headers</span>.<span class="ident">sort</span>();
<span class="macro">assert_eq</span><span class="macro">!</span>(<span class="ident">headers</span>, <span class="ident">actual_headers</span>);
}
<span class="attribute">#[<span class="ident">test</span>]</span>
<span class="kw">fn</span> <span class="ident">response_sets_max_age_correctly</span>() {
<span class="kw">let</span> <span class="ident">response</span> <span class="op">=</span> <span class="ident">Response</span>::<span class="ident">new</span>();
<span class="kw">let</span> <span class="ident">response</span> <span class="op">=</span> <span class="ident">response</span>.<span class="ident">origin</span>(<span class="string">&quot;https://www.example.com&quot;</span>, <span class="bool-val">false</span>);
<span class="kw">let</span> <span class="ident">response</span> <span class="op">=</span> <span class="ident">response</span>.<span class="ident">max_age</span>(<span class="prelude-val">Some</span>(<span class="number">42</span>));
<span class="comment">// Build response and check built response header</span>
<span class="kw">let</span> <span class="ident">expected_header</span> <span class="op">=</span> <span class="macro">vec</span><span class="macro">!</span>[<span class="string">&quot;42&quot;</span>];
<span class="kw">let</span> <span class="ident">response</span> <span class="op">=</span> <span class="ident">response</span>.<span class="ident">response</span>(<span class="ident">response</span>::<span class="ident">Response</span>::<span class="ident">new</span>());
<span class="kw">let</span> <span class="ident">actual_header</span>: <span class="ident">Vec</span><span class="op">&lt;</span><span class="kw">_</span><span class="op">&gt;</span> <span class="op">=</span> <span class="ident">response</span>.<span class="ident">headers</span>().<span class="ident">get</span>(<span class="string">&quot;Access-Control-Max-Age&quot;</span>).<span class="ident">collect</span>();
<span class="macro">assert_eq</span><span class="macro">!</span>(<span class="ident">expected_header</span>, <span class="ident">actual_header</span>);
}
<span class="attribute">#[<span class="ident">test</span>]</span>
<span class="kw">fn</span> <span class="ident">response_does_not_set_max_age_when_none</span>() {
<span class="kw">let</span> <span class="ident">response</span> <span class="op">=</span> <span class="ident">Response</span>::<span class="ident">new</span>();
<span class="kw">let</span> <span class="ident">response</span> <span class="op">=</span> <span class="ident">response</span>.<span class="ident">origin</span>(<span class="string">&quot;https://www.example.com&quot;</span>, <span class="bool-val">false</span>);
<span class="kw">let</span> <span class="ident">response</span> <span class="op">=</span> <span class="ident">response</span>.<span class="ident">max_age</span>(<span class="prelude-val">None</span>);
<span class="comment">// Build response and check built response header</span>
<span class="kw">let</span> <span class="ident">response</span> <span class="op">=</span> <span class="ident">response</span>.<span class="ident">response</span>(<span class="ident">response</span>::<span class="ident">Response</span>::<span class="ident">new</span>());
<span class="macro">assert</span><span class="macro">!</span>(<span class="ident">response</span>
.<span class="ident">headers</span>()
.<span class="ident">get</span>(<span class="string">&quot;Access-Control-Max-Age&quot;</span>)
.<span class="ident">next</span>()
.<span class="ident">is_none</span>())
}
<span class="attribute">#[<span class="ident">test</span>]</span>
<span class="kw">fn</span> <span class="ident">allowed_methods_validated_correctly</span>() {
<span class="kw">let</span> <span class="ident">allowed_methods</span> <span class="op">=</span> <span class="macro">vec</span><span class="macro">!</span>[<span class="ident">Method</span>::<span class="ident">Get</span>, <span class="ident">Method</span>::<span class="ident">Head</span>, <span class="ident">Method</span>::<span class="ident">Post</span>]
.<span class="ident">into_iter</span>()
.<span class="ident">map</span>(<span class="ident">From</span>::<span class="ident">from</span>)
.<span class="ident">collect</span>();
<span class="kw">let</span> <span class="ident">method</span> <span class="op">=</span> <span class="string">&quot;GET&quot;</span>;
<span class="macro">not_err</span><span class="macro">!</span>(<span class="ident">validate_allowed_method</span>(
<span class="kw-2">&amp;</span><span class="ident">FromStr</span>::<span class="ident">from_str</span>(<span class="ident">method</span>).<span class="ident">expect</span>(<span class="string">&quot;not to fail&quot;</span>),
<span class="kw-2">&amp;</span><span class="ident">allowed_methods</span>,
));
}
<span class="attribute">#[<span class="ident">test</span>]</span>
<span class="attribute">#[<span class="ident">should_panic</span>(<span class="ident">expected</span> <span class="op">=</span> <span class="string">&quot;MethodNotAllowed&quot;</span>)]</span>
<span class="kw">fn</span> <span class="ident">allowed_methods_errors_on_disallowed_method</span>() {
<span class="kw">let</span> <span class="ident">allowed_methods</span> <span class="op">=</span> <span class="macro">vec</span><span class="macro">!</span>[<span class="ident">Method</span>::<span class="ident">Get</span>, <span class="ident">Method</span>::<span class="ident">Head</span>, <span class="ident">Method</span>::<span class="ident">Post</span>]
.<span class="ident">into_iter</span>()
.<span class="ident">map</span>(<span class="ident">From</span>::<span class="ident">from</span>)
.<span class="ident">collect</span>();
<span class="kw">let</span> <span class="ident">method</span> <span class="op">=</span> <span class="string">&quot;DELETE&quot;</span>;
<span class="ident">validate_allowed_method</span>(
<span class="kw-2">&amp;</span><span class="ident">FromStr</span>::<span class="ident">from_str</span>(<span class="ident">method</span>).<span class="ident">expect</span>(<span class="string">&quot;not to fail&quot;</span>),
<span class="kw-2">&amp;</span><span class="ident">allowed_methods</span>,
)
.<span class="ident">unwrap</span>()
}
<span class="attribute">#[<span class="ident">test</span>]</span>
<span class="kw">fn</span> <span class="ident">all_allowed_headers_are_validated_correctly</span>() {
<span class="kw">let</span> <span class="ident">allowed_headers</span> <span class="op">=</span> <span class="ident">AllOrSome</span>::<span class="ident">All</span>;
<span class="kw">let</span> <span class="ident">requested_headers</span> <span class="op">=</span> <span class="macro">vec</span><span class="macro">!</span>[<span class="string">&quot;Bar&quot;</span>, <span class="string">&quot;Foo&quot;</span>];
<span class="macro">not_err</span><span class="macro">!</span>(<span class="ident">validate_allowed_headers</span>(
<span class="kw-2">&amp;</span><span class="ident">FromStr</span>::<span class="ident">from_str</span>(<span class="kw-2">&amp;</span><span class="ident">requested_headers</span>.<span class="ident">join</span>(<span class="string">&quot;,&quot;</span>)).<span class="ident">unwrap</span>(),
<span class="kw-2">&amp;</span><span class="ident">allowed_headers</span>,
));
}
<span class="doccomment">/// `Response::allowed_headers` should check that headers are allowed, and only</span>
<span class="doccomment">/// echoes back the list that is actually requested for and not the whole list</span>
<span class="attribute">#[<span class="ident">test</span>]</span>
<span class="kw">fn</span> <span class="ident">allowed_headers_are_validated_correctly</span>() {
<span class="kw">let</span> <span class="ident">allowed_headers</span> <span class="op">=</span> <span class="macro">vec</span><span class="macro">!</span>[<span class="string">&quot;Bar&quot;</span>, <span class="string">&quot;Baz&quot;</span>, <span class="string">&quot;Foo&quot;</span>];
<span class="kw">let</span> <span class="ident">requested_headers</span> <span class="op">=</span> <span class="macro">vec</span><span class="macro">!</span>[<span class="string">&quot;Bar&quot;</span>, <span class="string">&quot;Foo&quot;</span>];
<span class="macro">not_err</span><span class="macro">!</span>(<span class="ident">validate_allowed_headers</span>(
<span class="kw-2">&amp;</span><span class="ident">FromStr</span>::<span class="ident">from_str</span>(<span class="kw-2">&amp;</span><span class="ident">requested_headers</span>.<span class="ident">join</span>(<span class="string">&quot;,&quot;</span>)).<span class="ident">unwrap</span>(),
<span class="kw-2">&amp;</span><span class="ident">AllOrSome</span>::<span class="prelude-val">Some</span>(
<span class="ident">allowed_headers</span>
.<span class="ident">iter</span>()
.<span class="ident">map</span>(<span class="op">|</span><span class="ident">s</span><span class="op">|</span> <span class="ident">FromStr</span>::<span class="ident">from_str</span>(<span class="kw-2">*</span><span class="ident">s</span>).<span class="ident">unwrap</span>())
.<span class="ident">collect</span>(),
),
));
}
<span class="attribute">#[<span class="ident">test</span>]</span>
<span class="attribute">#[<span class="ident">should_panic</span>(<span class="ident">expected</span> <span class="op">=</span> <span class="string">&quot;HeadersNotAllowed&quot;</span>)]</span>
<span class="kw">fn</span> <span class="ident">allowed_headers_errors_on_non_subset</span>() {
<span class="kw">let</span> <span class="ident">allowed_headers</span> <span class="op">=</span> <span class="macro">vec</span><span class="macro">!</span>[<span class="string">&quot;Bar&quot;</span>, <span class="string">&quot;Baz&quot;</span>, <span class="string">&quot;Foo&quot;</span>];
<span class="kw">let</span> <span class="ident">requested_headers</span> <span class="op">=</span> <span class="macro">vec</span><span class="macro">!</span>[<span class="string">&quot;Bar&quot;</span>, <span class="string">&quot;Foo&quot;</span>, <span class="string">&quot;Unknown&quot;</span>];
<span class="ident">validate_allowed_headers</span>(
<span class="kw-2">&amp;</span><span class="ident">FromStr</span>::<span class="ident">from_str</span>(<span class="kw-2">&amp;</span><span class="ident">requested_headers</span>.<span class="ident">join</span>(<span class="string">&quot;,&quot;</span>)).<span class="ident">unwrap</span>(),
<span class="kw-2">&amp;</span><span class="ident">AllOrSome</span>::<span class="prelude-val">Some</span>(
<span class="ident">allowed_headers</span>
.<span class="ident">iter</span>()
.<span class="ident">map</span>(<span class="op">|</span><span class="ident">s</span><span class="op">|</span> <span class="ident">FromStr</span>::<span class="ident">from_str</span>(<span class="kw-2">*</span><span class="ident">s</span>).<span class="ident">unwrap</span>())
.<span class="ident">collect</span>(),
),
)
.<span class="ident">unwrap</span>();
}
<span class="attribute">#[<span class="ident">test</span>]</span>
<span class="kw">fn</span> <span class="ident">response_does_not_build_if_origin_is_not_set</span>() {
<span class="kw">let</span> <span class="ident">response</span> <span class="op">=</span> <span class="ident">Response</span>::<span class="ident">new</span>();
<span class="kw">let</span> <span class="ident">response</span> <span class="op">=</span> <span class="ident">response</span>.<span class="ident">response</span>(<span class="ident">response</span>::<span class="ident">Response</span>::<span class="ident">new</span>());
<span class="kw">let</span> <span class="ident">headers</span>: <span class="ident">Vec</span><span class="op">&lt;</span><span class="kw">_</span><span class="op">&gt;</span> <span class="op">=</span> <span class="ident">response</span>.<span class="ident">headers</span>().<span class="ident">iter</span>().<span class="ident">collect</span>();
<span class="macro">assert_eq</span><span class="macro">!</span>(<span class="ident">headers</span>.<span class="ident">len</span>(), <span class="number">0</span>);
}
<span class="attribute">#[<span class="ident">test</span>]</span>
<span class="kw">fn</span> <span class="ident">response_build_removes_existing_cors_headers_and_keeps_others</span>() {
<span class="kw">use</span> <span class="ident">std</span>::<span class="ident">io</span>::<span class="ident">Cursor</span>;
<span class="kw">let</span> <span class="ident">original</span> <span class="op">=</span> <span class="ident">response</span>::<span class="ident">Response</span>::<span class="ident">build</span>()
.<span class="ident">status</span>(<span class="ident">Status</span>::<span class="ident">ImATeapot</span>)
.<span class="ident">raw_header</span>(<span class="string">&quot;X-Teapot-Make&quot;</span>, <span class="string">&quot;Rocket&quot;</span>)
.<span class="ident">raw_header</span>(<span class="string">&quot;Access-Control-Max-Age&quot;</span>, <span class="string">&quot;42&quot;</span>)
.<span class="ident">sized_body</span>(<span class="ident">Cursor</span>::<span class="ident">new</span>(<span class="string">&quot;Brewing the best coffee!&quot;</span>))
.<span class="ident">finalize</span>();
<span class="kw">let</span> <span class="ident">response</span> <span class="op">=</span> <span class="ident">Response</span>::<span class="ident">new</span>();
<span class="kw">let</span> <span class="ident">response</span> <span class="op">=</span> <span class="ident">response</span>.<span class="ident">origin</span>(<span class="string">&quot;https://www.example.com&quot;</span>, <span class="bool-val">false</span>);
<span class="kw">let</span> <span class="ident">response</span> <span class="op">=</span> <span class="ident">response</span>.<span class="ident">response</span>(<span class="ident">original</span>);
<span class="comment">// Check CORS header</span>
<span class="kw">let</span> <span class="ident">expected_header</span> <span class="op">=</span> <span class="macro">vec</span><span class="macro">!</span>[<span class="string">&quot;https://www.example.com&quot;</span>];
<span class="kw">let</span> <span class="ident">actual_header</span>: <span class="ident">Vec</span><span class="op">&lt;</span><span class="kw">_</span><span class="op">&gt;</span> <span class="op">=</span> <span class="ident">response</span>
.<span class="ident">headers</span>()
.<span class="ident">get</span>(<span class="string">&quot;Access-Control-Allow-Origin&quot;</span>)
.<span class="ident">collect</span>();
<span class="macro">assert_eq</span><span class="macro">!</span>(<span class="ident">expected_header</span>, <span class="ident">actual_header</span>);
<span class="comment">// Check other header</span>
<span class="kw">let</span> <span class="ident">expected_header</span> <span class="op">=</span> <span class="macro">vec</span><span class="macro">!</span>[<span class="string">&quot;Rocket&quot;</span>];
<span class="kw">let</span> <span class="ident">actual_header</span>: <span class="ident">Vec</span><span class="op">&lt;</span><span class="kw">_</span><span class="op">&gt;</span> <span class="op">=</span> <span class="ident">response</span>.<span class="ident">headers</span>().<span class="ident">get</span>(<span class="string">&quot;X-Teapot-Make&quot;</span>).<span class="ident">collect</span>();
<span class="macro">assert_eq</span><span class="macro">!</span>(<span class="ident">expected_header</span>, <span class="ident">actual_header</span>);
<span class="comment">// Check that `Access-Control-Max-Age` is removed</span>
<span class="macro">assert</span><span class="macro">!</span>(<span class="ident">response</span>
.<span class="ident">headers</span>()
.<span class="ident">get</span>(<span class="string">&quot;Access-Control-Max-Age&quot;</span>)
.<span class="ident">next</span>()
.<span class="ident">is_none</span>());
}
<span class="attribute">#[<span class="ident">derive</span>(<span class="ident">Debug</span>, <span class="ident">PartialEq</span>)]</span>
<span class="attribute">#[<span class="ident">cfg_attr</span>(<span class="ident">feature</span> <span class="op">=</span> <span class="string">&quot;serialization&quot;</span>, <span class="ident">derive</span>(<span class="ident">Serialize</span>, <span class="ident">Deserialize</span>))]</span>
<span class="kw">struct</span> <span class="ident">MethodTest</span> {
<span class="ident">method</span>: <span class="kw">crate</span>::<span class="ident">Method</span>,
}
<span class="attribute">#[<span class="ident">cfg</span>(<span class="ident">feature</span> <span class="op">=</span> <span class="string">&quot;serialization&quot;</span>)]</span>
<span class="attribute">#[<span class="ident">test</span>]</span>
<span class="kw">fn</span> <span class="ident">method_serde_roundtrip</span>() {
<span class="kw">use</span> <span class="ident">serde_test</span>::{<span class="ident">assert_tokens</span>, <span class="ident">Token</span>};
<span class="kw">let</span> <span class="ident">test</span> <span class="op">=</span> <span class="ident">MethodTest</span> {
<span class="ident">method</span>: <span class="ident">From</span>::<span class="ident">from</span>(<span class="ident">http</span>::<span class="ident">Method</span>::<span class="ident">Get</span>),
};
<span class="ident">assert_tokens</span>(
<span class="kw-2">&amp;</span><span class="ident">test</span>,
<span class="kw-2">&amp;</span>[
<span class="ident">Token</span>::<span class="ident">Struct</span> {
<span class="ident">name</span>: <span class="string">&quot;MethodTest&quot;</span>,
<span class="ident">len</span>: <span class="number">1</span>,
},
<span class="ident">Token</span>::<span class="ident">Str</span>(<span class="string">&quot;method&quot;</span>),
<span class="ident">Token</span>::<span class="ident">Str</span>(<span class="string">&quot;GET&quot;</span>),
<span class="ident">Token</span>::<span class="ident">StructEnd</span>,
],
);
}
<span class="attribute">#[<span class="ident">test</span>]</span>
<span class="kw">fn</span> <span class="ident">preflight_validated_correctly</span>() {
<span class="kw">let</span> <span class="ident">cors</span> <span class="op">=</span> <span class="ident">make_cors_options</span>().<span class="ident">to_cors</span>().<span class="ident">expect</span>(<span class="string">&quot;To not fail&quot;</span>);
<span class="kw">let</span> <span class="ident">client</span> <span class="op">=</span> <span class="ident">make_client</span>();
<span class="kw">let</span> <span class="ident">origin_header</span> <span class="op">=</span>
<span class="ident">Header</span>::<span class="ident">from</span>(<span class="ident">hyper</span>::<span class="ident">header</span>::<span class="ident">Origin</span>::<span class="ident">from_str</span>(<span class="string">&quot;https://www.acme.com&quot;</span>).<span class="ident">unwrap</span>());
<span class="kw">let</span> <span class="ident">method_header</span> <span class="op">=</span> <span class="ident">Header</span>::<span class="ident">from</span>(<span class="ident">hyper</span>::<span class="ident">header</span>::<span class="ident">AccessControlRequestMethod</span>(
<span class="ident">hyper</span>::<span class="ident">method</span>::<span class="ident">Method</span>::<span class="ident">Get</span>,
));
<span class="kw">let</span> <span class="ident">request_headers</span> <span class="op">=</span>
<span class="ident">hyper</span>::<span class="ident">header</span>::<span class="ident">AccessControlRequestHeaders</span>(<span class="macro">vec</span><span class="macro">!</span>[
<span class="ident">FromStr</span>::<span class="ident">from_str</span>(<span class="string">&quot;Authorization&quot;</span>).<span class="ident">unwrap</span>()
]);
<span class="kw">let</span> <span class="ident">request_headers</span> <span class="op">=</span> <span class="ident">Header</span>::<span class="ident">from</span>(<span class="ident">request_headers</span>);
<span class="kw">let</span> <span class="ident">request</span> <span class="op">=</span> <span class="ident">client</span>
.<span class="ident">options</span>(<span class="string">&quot;/&quot;</span>)
.<span class="ident">header</span>(<span class="ident">origin_header</span>)
.<span class="ident">header</span>(<span class="ident">method_header</span>)
.<span class="ident">header</span>(<span class="ident">request_headers</span>);
<span class="kw">let</span> <span class="ident">result</span> <span class="op">=</span> <span class="ident">validate</span>(<span class="kw-2">&amp;</span><span class="ident">cors</span>, <span class="ident">request</span>.<span class="ident">inner</span>()).<span class="ident">expect</span>(<span class="string">&quot;to not fail&quot;</span>);
<span class="kw">let</span> <span class="ident">expected_result</span> <span class="op">=</span> <span class="ident">ValidationResult</span>::<span class="ident">Preflight</span> {
<span class="ident">origin</span>: <span class="string">&quot;https://www.acme.com&quot;</span>.<span class="ident">to_string</span>(),
<span class="comment">// Checks that only a subset of allowed headers are returned</span>
<span class="comment">// -- i.e. whatever is requested for</span>
<span class="ident">headers</span>: <span class="prelude-val">Some</span>(<span class="ident">FromStr</span>::<span class="ident">from_str</span>(<span class="string">&quot;Authorization&quot;</span>).<span class="ident">unwrap</span>()),
};
<span class="macro">assert_eq</span><span class="macro">!</span>(<span class="ident">expected_result</span>, <span class="ident">result</span>);
}
<span class="attribute">#[<span class="ident">test</span>]</span>
<span class="kw">fn</span> <span class="ident">preflight_validation_allows_all_origin</span>() {
<span class="kw">let</span> <span class="kw-2">mut</span> <span class="ident">options</span> <span class="op">=</span> <span class="ident">make_cors_options</span>();
<span class="ident">options</span>.<span class="ident">allowed_origins</span> <span class="op">=</span> <span class="ident">AllOrSome</span>::<span class="ident">All</span>;
<span class="kw">let</span> <span class="ident">cors</span> <span class="op">=</span> <span class="ident">options</span>.<span class="ident">to_cors</span>().<span class="ident">expect</span>(<span class="string">&quot;To not fail&quot;</span>);
<span class="kw">let</span> <span class="ident">client</span> <span class="op">=</span> <span class="ident">make_client</span>();
<span class="kw">let</span> <span class="ident">origin_header</span> <span class="op">=</span>
<span class="ident">Header</span>::<span class="ident">from</span>(<span class="ident">hyper</span>::<span class="ident">header</span>::<span class="ident">Origin</span>::<span class="ident">from_str</span>(<span class="string">&quot;https://www.example.com&quot;</span>).<span class="ident">unwrap</span>());
<span class="kw">let</span> <span class="ident">method_header</span> <span class="op">=</span> <span class="ident">Header</span>::<span class="ident">from</span>(<span class="ident">hyper</span>::<span class="ident">header</span>::<span class="ident">AccessControlRequestMethod</span>(
<span class="ident">hyper</span>::<span class="ident">method</span>::<span class="ident">Method</span>::<span class="ident">Get</span>,
));
<span class="kw">let</span> <span class="ident">request_headers</span> <span class="op">=</span>
<span class="ident">hyper</span>::<span class="ident">header</span>::<span class="ident">AccessControlRequestHeaders</span>(<span class="macro">vec</span><span class="macro">!</span>[
<span class="ident">FromStr</span>::<span class="ident">from_str</span>(<span class="string">&quot;Authorization&quot;</span>).<span class="ident">unwrap</span>()
]);
<span class="kw">let</span> <span class="ident">request_headers</span> <span class="op">=</span> <span class="ident">Header</span>::<span class="ident">from</span>(<span class="ident">request_headers</span>);
<span class="kw">let</span> <span class="ident">request</span> <span class="op">=</span> <span class="ident">client</span>
.<span class="ident">options</span>(<span class="string">&quot;/&quot;</span>)
.<span class="ident">header</span>(<span class="ident">origin_header</span>)
.<span class="ident">header</span>(<span class="ident">method_header</span>)
.<span class="ident">header</span>(<span class="ident">request_headers</span>);
<span class="kw">let</span> <span class="ident">result</span> <span class="op">=</span> <span class="ident">validate</span>(<span class="kw-2">&amp;</span><span class="ident">cors</span>, <span class="ident">request</span>.<span class="ident">inner</span>()).<span class="ident">expect</span>(<span class="string">&quot;to not fail&quot;</span>);
<span class="kw">let</span> <span class="ident">expected_result</span> <span class="op">=</span> <span class="ident">ValidationResult</span>::<span class="ident">Preflight</span> {
<span class="ident">origin</span>: <span class="string">&quot;https://www.example.com&quot;</span>.<span class="ident">to_string</span>(),
<span class="ident">headers</span>: <span class="prelude-val">Some</span>(<span class="ident">FromStr</span>::<span class="ident">from_str</span>(<span class="string">&quot;Authorization&quot;</span>).<span class="ident">unwrap</span>()),
};
<span class="macro">assert_eq</span><span class="macro">!</span>(<span class="ident">expected_result</span>, <span class="ident">result</span>);
}
<span class="attribute">#[<span class="ident">test</span>]</span>
<span class="attribute">#[<span class="ident">should_panic</span>(<span class="ident">expected</span> <span class="op">=</span> <span class="string">&quot;OriginNotAllowed&quot;</span>)]</span>
<span class="kw">fn</span> <span class="ident">preflight_validation_errors_on_invalid_origin</span>() {
<span class="kw">let</span> <span class="ident">cors</span> <span class="op">=</span> <span class="ident">make_cors_options</span>().<span class="ident">to_cors</span>().<span class="ident">expect</span>(<span class="string">&quot;To not fail&quot;</span>);
<span class="kw">let</span> <span class="ident">client</span> <span class="op">=</span> <span class="ident">make_client</span>();
<span class="kw">let</span> <span class="ident">origin_header</span> <span class="op">=</span>
<span class="ident">Header</span>::<span class="ident">from</span>(<span class="ident">hyper</span>::<span class="ident">header</span>::<span class="ident">Origin</span>::<span class="ident">from_str</span>(<span class="string">&quot;https://www.example.com&quot;</span>).<span class="ident">unwrap</span>());
<span class="kw">let</span> <span class="ident">method_header</span> <span class="op">=</span> <span class="ident">Header</span>::<span class="ident">from</span>(<span class="ident">hyper</span>::<span class="ident">header</span>::<span class="ident">AccessControlRequestMethod</span>(
<span class="ident">hyper</span>::<span class="ident">method</span>::<span class="ident">Method</span>::<span class="ident">Get</span>,
));
<span class="kw">let</span> <span class="ident">request_headers</span> <span class="op">=</span>
<span class="ident">hyper</span>::<span class="ident">header</span>::<span class="ident">AccessControlRequestHeaders</span>(<span class="macro">vec</span><span class="macro">!</span>[
<span class="ident">FromStr</span>::<span class="ident">from_str</span>(<span class="string">&quot;Authorization&quot;</span>).<span class="ident">unwrap</span>()
]);
<span class="kw">let</span> <span class="ident">request_headers</span> <span class="op">=</span> <span class="ident">Header</span>::<span class="ident">from</span>(<span class="ident">request_headers</span>);
<span class="kw">let</span> <span class="ident">request</span> <span class="op">=</span> <span class="ident">client</span>
.<span class="ident">options</span>(<span class="string">&quot;/&quot;</span>)
.<span class="ident">header</span>(<span class="ident">origin_header</span>)
.<span class="ident">header</span>(<span class="ident">method_header</span>)
.<span class="ident">header</span>(<span class="ident">request_headers</span>);
<span class="kw">let</span> <span class="kw">_</span> <span class="op">=</span> <span class="ident">validate</span>(<span class="kw-2">&amp;</span><span class="ident">cors</span>, <span class="ident">request</span>.<span class="ident">inner</span>()).<span class="ident">unwrap</span>();
}
<span class="attribute">#[<span class="ident">test</span>]</span>
<span class="attribute">#[<span class="ident">should_panic</span>(<span class="ident">expected</span> <span class="op">=</span> <span class="string">&quot;MissingRequestMethod&quot;</span>)]</span>
<span class="kw">fn</span> <span class="ident">preflight_validation_errors_on_missing_request_method</span>() {
<span class="kw">let</span> <span class="ident">cors</span> <span class="op">=</span> <span class="ident">make_cors_options</span>().<span class="ident">to_cors</span>().<span class="ident">expect</span>(<span class="string">&quot;To not fail&quot;</span>);
<span class="kw">let</span> <span class="ident">client</span> <span class="op">=</span> <span class="ident">make_client</span>();
<span class="kw">let</span> <span class="ident">origin_header</span> <span class="op">=</span>
<span class="ident">Header</span>::<span class="ident">from</span>(<span class="ident">hyper</span>::<span class="ident">header</span>::<span class="ident">Origin</span>::<span class="ident">from_str</span>(<span class="string">&quot;https://www.acme.com&quot;</span>).<span class="ident">unwrap</span>());
<span class="kw">let</span> <span class="ident">request_headers</span> <span class="op">=</span>
<span class="ident">hyper</span>::<span class="ident">header</span>::<span class="ident">AccessControlRequestHeaders</span>(<span class="macro">vec</span><span class="macro">!</span>[
<span class="ident">FromStr</span>::<span class="ident">from_str</span>(<span class="string">&quot;Authorization&quot;</span>).<span class="ident">unwrap</span>()
]);
<span class="kw">let</span> <span class="ident">request_headers</span> <span class="op">=</span> <span class="ident">Header</span>::<span class="ident">from</span>(<span class="ident">request_headers</span>);
<span class="kw">let</span> <span class="ident">request</span> <span class="op">=</span> <span class="ident">client</span>
.<span class="ident">options</span>(<span class="string">&quot;/&quot;</span>)
.<span class="ident">header</span>(<span class="ident">origin_header</span>)
.<span class="ident">header</span>(<span class="ident">request_headers</span>);
<span class="kw">let</span> <span class="kw">_</span> <span class="op">=</span> <span class="ident">validate</span>(<span class="kw-2">&amp;</span><span class="ident">cors</span>, <span class="ident">request</span>.<span class="ident">inner</span>()).<span class="ident">unwrap</span>();
}
<span class="attribute">#[<span class="ident">test</span>]</span>
<span class="attribute">#[<span class="ident">should_panic</span>(<span class="ident">expected</span> <span class="op">=</span> <span class="string">&quot;MethodNotAllowed&quot;</span>)]</span>
<span class="kw">fn</span> <span class="ident">preflight_validation_errors_on_disallowed_method</span>() {
<span class="kw">let</span> <span class="ident">cors</span> <span class="op">=</span> <span class="ident">make_cors_options</span>().<span class="ident">to_cors</span>().<span class="ident">expect</span>(<span class="string">&quot;To not fail&quot;</span>);
<span class="kw">let</span> <span class="ident">client</span> <span class="op">=</span> <span class="ident">make_client</span>();
<span class="kw">let</span> <span class="ident">origin_header</span> <span class="op">=</span>
<span class="ident">Header</span>::<span class="ident">from</span>(<span class="ident">hyper</span>::<span class="ident">header</span>::<span class="ident">Origin</span>::<span class="ident">from_str</span>(<span class="string">&quot;https://www.acme.com&quot;</span>).<span class="ident">unwrap</span>());
<span class="kw">let</span> <span class="ident">method_header</span> <span class="op">=</span> <span class="ident">Header</span>::<span class="ident">from</span>(<span class="ident">hyper</span>::<span class="ident">header</span>::<span class="ident">AccessControlRequestMethod</span>(
<span class="ident">hyper</span>::<span class="ident">method</span>::<span class="ident">Method</span>::<span class="ident">Post</span>,
));
<span class="kw">let</span> <span class="ident">request_headers</span> <span class="op">=</span>
<span class="ident">hyper</span>::<span class="ident">header</span>::<span class="ident">AccessControlRequestHeaders</span>(<span class="macro">vec</span><span class="macro">!</span>[
<span class="ident">FromStr</span>::<span class="ident">from_str</span>(<span class="string">&quot;Authorization&quot;</span>).<span class="ident">unwrap</span>()
]);
<span class="kw">let</span> <span class="ident">request_headers</span> <span class="op">=</span> <span class="ident">Header</span>::<span class="ident">from</span>(<span class="ident">request_headers</span>);
<span class="kw">let</span> <span class="ident">request</span> <span class="op">=</span> <span class="ident">client</span>
.<span class="ident">options</span>(<span class="string">&quot;/&quot;</span>)
.<span class="ident">header</span>(<span class="ident">origin_header</span>)
.<span class="ident">header</span>(<span class="ident">method_header</span>)
.<span class="ident">header</span>(<span class="ident">request_headers</span>);
<span class="kw">let</span> <span class="kw">_</span> <span class="op">=</span> <span class="ident">validate</span>(<span class="kw-2">&amp;</span><span class="ident">cors</span>, <span class="ident">request</span>.<span class="ident">inner</span>()).<span class="ident">unwrap</span>();
}
<span class="attribute">#[<span class="ident">test</span>]</span>
<span class="attribute">#[<span class="ident">should_panic</span>(<span class="ident">expected</span> <span class="op">=</span> <span class="string">&quot;HeadersNotAllowed&quot;</span>)]</span>
<span class="kw">fn</span> <span class="ident">preflight_validation_errors_on_disallowed_headers</span>() {
<span class="kw">let</span> <span class="ident">cors</span> <span class="op">=</span> <span class="ident">make_cors_options</span>().<span class="ident">to_cors</span>().<span class="ident">expect</span>(<span class="string">&quot;To not fail&quot;</span>);
<span class="kw">let</span> <span class="ident">client</span> <span class="op">=</span> <span class="ident">make_client</span>();
<span class="kw">let</span> <span class="ident">origin_header</span> <span class="op">=</span>
<span class="ident">Header</span>::<span class="ident">from</span>(<span class="ident">hyper</span>::<span class="ident">header</span>::<span class="ident">Origin</span>::<span class="ident">from_str</span>(<span class="string">&quot;https://www.acme.com&quot;</span>).<span class="ident">unwrap</span>());
<span class="kw">let</span> <span class="ident">method_header</span> <span class="op">=</span> <span class="ident">Header</span>::<span class="ident">from</span>(<span class="ident">hyper</span>::<span class="ident">header</span>::<span class="ident">AccessControlRequestMethod</span>(
<span class="ident">hyper</span>::<span class="ident">method</span>::<span class="ident">Method</span>::<span class="ident">Get</span>,
));
<span class="kw">let</span> <span class="ident">request_headers</span> <span class="op">=</span> <span class="ident">hyper</span>::<span class="ident">header</span>::<span class="ident">AccessControlRequestHeaders</span>(<span class="macro">vec</span><span class="macro">!</span>[
<span class="ident">FromStr</span>::<span class="ident">from_str</span>(<span class="string">&quot;Authorization&quot;</span>).<span class="ident">unwrap</span>(),
<span class="ident">FromStr</span>::<span class="ident">from_str</span>(<span class="string">&quot;X-NOT-ALLOWED&quot;</span>).<span class="ident">unwrap</span>(),
]);
<span class="kw">let</span> <span class="ident">request_headers</span> <span class="op">=</span> <span class="ident">Header</span>::<span class="ident">from</span>(<span class="ident">request_headers</span>);
<span class="kw">let</span> <span class="ident">request</span> <span class="op">=</span> <span class="ident">client</span>
.<span class="ident">options</span>(<span class="string">&quot;/&quot;</span>)
.<span class="ident">header</span>(<span class="ident">origin_header</span>)
.<span class="ident">header</span>(<span class="ident">method_header</span>)
.<span class="ident">header</span>(<span class="ident">request_headers</span>);
<span class="kw">let</span> <span class="kw">_</span> <span class="op">=</span> <span class="ident">validate</span>(<span class="kw-2">&amp;</span><span class="ident">cors</span>, <span class="ident">request</span>.<span class="ident">inner</span>()).<span class="ident">unwrap</span>();
}
<span class="attribute">#[<span class="ident">test</span>]</span>
<span class="kw">fn</span> <span class="ident">actual_request_validated_correctly</span>() {
<span class="kw">let</span> <span class="ident">cors</span> <span class="op">=</span> <span class="ident">make_cors_options</span>().<span class="ident">to_cors</span>().<span class="ident">expect</span>(<span class="string">&quot;To not fail&quot;</span>);
<span class="kw">let</span> <span class="ident">client</span> <span class="op">=</span> <span class="ident">make_client</span>();
<span class="kw">let</span> <span class="ident">origin_header</span> <span class="op">=</span>
<span class="ident">Header</span>::<span class="ident">from</span>(<span class="ident">hyper</span>::<span class="ident">header</span>::<span class="ident">Origin</span>::<span class="ident">from_str</span>(<span class="string">&quot;https://www.acme.com&quot;</span>).<span class="ident">unwrap</span>());
<span class="kw">let</span> <span class="ident">request</span> <span class="op">=</span> <span class="ident">client</span>.<span class="ident">get</span>(<span class="string">&quot;/&quot;</span>).<span class="ident">header</span>(<span class="ident">origin_header</span>);
<span class="kw">let</span> <span class="ident">result</span> <span class="op">=</span> <span class="ident">validate</span>(<span class="kw-2">&amp;</span><span class="ident">cors</span>, <span class="ident">request</span>.<span class="ident">inner</span>()).<span class="ident">expect</span>(<span class="string">&quot;to not fail&quot;</span>);
<span class="kw">let</span> <span class="ident">expected_result</span> <span class="op">=</span> <span class="ident">ValidationResult</span>::<span class="ident">Request</span> {
<span class="ident">origin</span>: <span class="string">&quot;https://www.acme.com&quot;</span>.<span class="ident">to_string</span>(),
};
<span class="macro">assert_eq</span><span class="macro">!</span>(<span class="ident">expected_result</span>, <span class="ident">result</span>);
}
<span class="attribute">#[<span class="ident">test</span>]</span>
<span class="kw">fn</span> <span class="ident">actual_request_validation_allows_all_origin</span>() {
<span class="kw">let</span> <span class="kw-2">mut</span> <span class="ident">options</span> <span class="op">=</span> <span class="ident">make_cors_options</span>();
<span class="ident">options</span>.<span class="ident">allowed_origins</span> <span class="op">=</span> <span class="ident">AllOrSome</span>::<span class="ident">All</span>;
<span class="kw">let</span> <span class="ident">cors</span> <span class="op">=</span> <span class="ident">options</span>.<span class="ident">to_cors</span>().<span class="ident">expect</span>(<span class="string">&quot;To not fail&quot;</span>);
<span class="kw">let</span> <span class="ident">client</span> <span class="op">=</span> <span class="ident">make_client</span>();
<span class="kw">let</span> <span class="ident">origin_header</span> <span class="op">=</span>
<span class="ident">Header</span>::<span class="ident">from</span>(<span class="ident">hyper</span>::<span class="ident">header</span>::<span class="ident">Origin</span>::<span class="ident">from_str</span>(<span class="string">&quot;https://www.example.com&quot;</span>).<span class="ident">unwrap</span>());
<span class="kw">let</span> <span class="ident">request</span> <span class="op">=</span> <span class="ident">client</span>.<span class="ident">get</span>(<span class="string">&quot;/&quot;</span>).<span class="ident">header</span>(<span class="ident">origin_header</span>);
<span class="kw">let</span> <span class="ident">result</span> <span class="op">=</span> <span class="ident">validate</span>(<span class="kw-2">&amp;</span><span class="ident">cors</span>, <span class="ident">request</span>.<span class="ident">inner</span>()).<span class="ident">expect</span>(<span class="string">&quot;to not fail&quot;</span>);
<span class="kw">let</span> <span class="ident">expected_result</span> <span class="op">=</span> <span class="ident">ValidationResult</span>::<span class="ident">Request</span> {
<span class="ident">origin</span>: <span class="string">&quot;https://www.example.com&quot;</span>.<span class="ident">to_string</span>(),
};
<span class="macro">assert_eq</span><span class="macro">!</span>(<span class="ident">expected_result</span>, <span class="ident">result</span>);
}
<span class="attribute">#[<span class="ident">test</span>]</span>
<span class="attribute">#[<span class="ident">should_panic</span>(<span class="ident">expected</span> <span class="op">=</span> <span class="string">&quot;OriginNotAllowed&quot;</span>)]</span>
<span class="kw">fn</span> <span class="ident">actual_request_validation_errors_on_incorrect_origin</span>() {
<span class="kw">let</span> <span class="ident">cors</span> <span class="op">=</span> <span class="ident">make_cors_options</span>().<span class="ident">to_cors</span>().<span class="ident">expect</span>(<span class="string">&quot;To not fail&quot;</span>);
<span class="kw">let</span> <span class="ident">client</span> <span class="op">=</span> <span class="ident">make_client</span>();
<span class="kw">let</span> <span class="ident">origin_header</span> <span class="op">=</span>
<span class="ident">Header</span>::<span class="ident">from</span>(<span class="ident">hyper</span>::<span class="ident">header</span>::<span class="ident">Origin</span>::<span class="ident">from_str</span>(<span class="string">&quot;https://www.example.com&quot;</span>).<span class="ident">unwrap</span>());
<span class="kw">let</span> <span class="ident">request</span> <span class="op">=</span> <span class="ident">client</span>.<span class="ident">get</span>(<span class="string">&quot;/&quot;</span>).<span class="ident">header</span>(<span class="ident">origin_header</span>);
<span class="kw">let</span> <span class="kw">_</span> <span class="op">=</span> <span class="ident">validate</span>(<span class="kw-2">&amp;</span><span class="ident">cors</span>, <span class="ident">request</span>.<span class="ident">inner</span>()).<span class="ident">unwrap</span>();
}
<span class="attribute">#[<span class="ident">test</span>]</span>
<span class="kw">fn</span> <span class="ident">non_cors_request_return_empty_response</span>() {
<span class="kw">let</span> <span class="ident">cors</span> <span class="op">=</span> <span class="ident">make_cors_options</span>().<span class="ident">to_cors</span>().<span class="ident">expect</span>(<span class="string">&quot;To not fail&quot;</span>);
<span class="kw">let</span> <span class="ident">client</span> <span class="op">=</span> <span class="ident">make_client</span>();
<span class="kw">let</span> <span class="ident">request</span> <span class="op">=</span> <span class="ident">client</span>.<span class="ident">options</span>(<span class="string">&quot;/&quot;</span>);
<span class="kw">let</span> <span class="ident">response</span> <span class="op">=</span> <span class="ident">validate_and_build</span>(<span class="kw-2">&amp;</span><span class="ident">cors</span>, <span class="ident">request</span>.<span class="ident">inner</span>()).<span class="ident">expect</span>(<span class="string">&quot;to not fail&quot;</span>);
<span class="kw">let</span> <span class="ident">expected_response</span> <span class="op">=</span> <span class="ident">Response</span>::<span class="ident">new</span>();
<span class="macro">assert_eq</span><span class="macro">!</span>(<span class="ident">expected_response</span>, <span class="ident">response</span>);
}
<span class="attribute">#[<span class="ident">test</span>]</span>
<span class="kw">fn</span> <span class="ident">preflight_validated_and_built_correctly</span>() {
<span class="kw">let</span> <span class="ident">options</span> <span class="op">=</span> <span class="ident">make_cors_options</span>();
<span class="kw">let</span> <span class="ident">cors</span> <span class="op">=</span> <span class="ident">options</span>.<span class="ident">to_cors</span>().<span class="ident">expect</span>(<span class="string">&quot;To not fail&quot;</span>);
<span class="kw">let</span> <span class="ident">client</span> <span class="op">=</span> <span class="ident">make_client</span>();
<span class="kw">let</span> <span class="ident">origin_header</span> <span class="op">=</span>
<span class="ident">Header</span>::<span class="ident">from</span>(<span class="ident">hyper</span>::<span class="ident">header</span>::<span class="ident">Origin</span>::<span class="ident">from_str</span>(<span class="string">&quot;https://www.acme.com&quot;</span>).<span class="ident">unwrap</span>());
<span class="kw">let</span> <span class="ident">method_header</span> <span class="op">=</span> <span class="ident">Header</span>::<span class="ident">from</span>(<span class="ident">hyper</span>::<span class="ident">header</span>::<span class="ident">AccessControlRequestMethod</span>(
<span class="ident">hyper</span>::<span class="ident">method</span>::<span class="ident">Method</span>::<span class="ident">Get</span>,
));
<span class="kw">let</span> <span class="ident">request_headers</span> <span class="op">=</span>
<span class="ident">hyper</span>::<span class="ident">header</span>::<span class="ident">AccessControlRequestHeaders</span>(<span class="macro">vec</span><span class="macro">!</span>[
<span class="ident">FromStr</span>::<span class="ident">from_str</span>(<span class="string">&quot;Authorization&quot;</span>).<span class="ident">unwrap</span>()
]);
<span class="kw">let</span> <span class="ident">request_headers</span> <span class="op">=</span> <span class="ident">Header</span>::<span class="ident">from</span>(<span class="ident">request_headers</span>);
<span class="kw">let</span> <span class="ident">request</span> <span class="op">=</span> <span class="ident">client</span>
.<span class="ident">options</span>(<span class="string">&quot;/&quot;</span>)
.<span class="ident">header</span>(<span class="ident">origin_header</span>)
.<span class="ident">header</span>(<span class="ident">method_header</span>)
.<span class="ident">header</span>(<span class="ident">request_headers</span>);
<span class="kw">let</span> <span class="ident">response</span> <span class="op">=</span> <span class="ident">validate_and_build</span>(<span class="kw-2">&amp;</span><span class="ident">cors</span>, <span class="ident">request</span>.<span class="ident">inner</span>()).<span class="ident">expect</span>(<span class="string">&quot;to not fail&quot;</span>);
<span class="kw">let</span> <span class="ident">expected_response</span> <span class="op">=</span> <span class="ident">Response</span>::<span class="ident">new</span>()
.<span class="ident">origin</span>(<span class="string">&quot;https://www.acme.com&quot;</span>, <span class="bool-val">false</span>)
.<span class="ident">headers</span>(<span class="kw-2">&amp;</span>[<span class="string">&quot;Authorization&quot;</span>])
.<span class="ident">methods</span>(<span class="kw-2">&amp;</span><span class="ident">options</span>.<span class="ident">allowed_methods</span>)
.<span class="ident">credentials</span>(<span class="ident">options</span>.<span class="ident">allow_credentials</span>)
.<span class="ident">max_age</span>(<span class="ident">options</span>.<span class="ident">max_age</span>);
<span class="macro">assert_eq</span><span class="macro">!</span>(<span class="ident">expected_response</span>, <span class="ident">response</span>);
}
<span class="doccomment">/// Tests that when All origins are allowed and send_wildcard disabled, the vary header is set</span>
<span class="doccomment">/// in the response and the requested origin is echoed</span>
<span class="attribute">#[<span class="ident">test</span>]</span>
<span class="kw">fn</span> <span class="ident">preflight_all_origins_with_vary</span>() {
<span class="kw">let</span> <span class="kw-2">mut</span> <span class="ident">options</span> <span class="op">=</span> <span class="ident">make_cors_options</span>();
<span class="ident">options</span>.<span class="ident">allowed_origins</span> <span class="op">=</span> <span class="ident">AllOrSome</span>::<span class="ident">All</span>;
<span class="ident">options</span>.<span class="ident">send_wildcard</span> <span class="op">=</span> <span class="bool-val">false</span>;
<span class="kw">let</span> <span class="ident">cors</span> <span class="op">=</span> <span class="ident">options</span>.<span class="ident">to_cors</span>().<span class="ident">expect</span>(<span class="string">&quot;To not fail&quot;</span>);
<span class="kw">let</span> <span class="ident">client</span> <span class="op">=</span> <span class="ident">make_client</span>();
<span class="kw">let</span> <span class="ident">origin_header</span> <span class="op">=</span>
<span class="ident">Header</span>::<span class="ident">from</span>(<span class="ident">hyper</span>::<span class="ident">header</span>::<span class="ident">Origin</span>::<span class="ident">from_str</span>(<span class="string">&quot;https://www.acme.com&quot;</span>).<span class="ident">unwrap</span>());
<span class="kw">let</span> <span class="ident">method_header</span> <span class="op">=</span> <span class="ident">Header</span>::<span class="ident">from</span>(<span class="ident">hyper</span>::<span class="ident">header</span>::<span class="ident">AccessControlRequestMethod</span>(
<span class="ident">hyper</span>::<span class="ident">method</span>::<span class="ident">Method</span>::<span class="ident">Get</span>,
));
<span class="kw">let</span> <span class="ident">request_headers</span> <span class="op">=</span>
<span class="ident">hyper</span>::<span class="ident">header</span>::<span class="ident">AccessControlRequestHeaders</span>(<span class="macro">vec</span><span class="macro">!</span>[
<span class="ident">FromStr</span>::<span class="ident">from_str</span>(<span class="string">&quot;Authorization&quot;</span>).<span class="ident">unwrap</span>()
]);
<span class="kw">let</span> <span class="ident">request_headers</span> <span class="op">=</span> <span class="ident">Header</span>::<span class="ident">from</span>(<span class="ident">request_headers</span>);
<span class="kw">let</span> <span class="ident">request</span> <span class="op">=</span> <span class="ident">client</span>
.<span class="ident">options</span>(<span class="string">&quot;/&quot;</span>)
.<span class="ident">header</span>(<span class="ident">origin_header</span>)
.<span class="ident">header</span>(<span class="ident">method_header</span>)
.<span class="ident">header</span>(<span class="ident">request_headers</span>);
<span class="kw">let</span> <span class="ident">response</span> <span class="op">=</span> <span class="ident">validate_and_build</span>(<span class="kw-2">&amp;</span><span class="ident">cors</span>, <span class="ident">request</span>.<span class="ident">inner</span>()).<span class="ident">expect</span>(<span class="string">&quot;to not fail&quot;</span>);
<span class="kw">let</span> <span class="ident">expected_response</span> <span class="op">=</span> <span class="ident">Response</span>::<span class="ident">new</span>()
.<span class="ident">origin</span>(<span class="string">&quot;https://www.acme.com&quot;</span>, <span class="bool-val">true</span>)
.<span class="ident">headers</span>(<span class="kw-2">&amp;</span>[<span class="string">&quot;Authorization&quot;</span>])
.<span class="ident">methods</span>(<span class="kw-2">&amp;</span><span class="ident">options</span>.<span class="ident">allowed_methods</span>)
.<span class="ident">credentials</span>(<span class="ident">options</span>.<span class="ident">allow_credentials</span>)
.<span class="ident">max_age</span>(<span class="ident">options</span>.<span class="ident">max_age</span>);
<span class="macro">assert_eq</span><span class="macro">!</span>(<span class="ident">expected_response</span>, <span class="ident">response</span>);
}
<span class="doccomment">/// Tests that when All origins are allowed and send_wildcard enabled, the origin is set to &quot;*&quot;</span>
<span class="attribute">#[<span class="ident">test</span>]</span>
<span class="kw">fn</span> <span class="ident">preflight_all_origins_with_wildcard</span>() {
<span class="kw">let</span> <span class="kw-2">mut</span> <span class="ident">options</span> <span class="op">=</span> <span class="ident">make_cors_options</span>();
<span class="ident">options</span>.<span class="ident">allowed_origins</span> <span class="op">=</span> <span class="ident">AllOrSome</span>::<span class="ident">All</span>;
<span class="ident">options</span>.<span class="ident">send_wildcard</span> <span class="op">=</span> <span class="bool-val">true</span>;
<span class="ident">options</span>.<span class="ident">allow_credentials</span> <span class="op">=</span> <span class="bool-val">false</span>;
<span class="kw">let</span> <span class="ident">cors</span> <span class="op">=</span> <span class="ident">options</span>.<span class="ident">to_cors</span>().<span class="ident">expect</span>(<span class="string">&quot;To not fail&quot;</span>);
<span class="kw">let</span> <span class="ident">client</span> <span class="op">=</span> <span class="ident">make_client</span>();
<span class="kw">let</span> <span class="ident">origin_header</span> <span class="op">=</span>
<span class="ident">Header</span>::<span class="ident">from</span>(<span class="ident">hyper</span>::<span class="ident">header</span>::<span class="ident">Origin</span>::<span class="ident">from_str</span>(<span class="string">&quot;https://www.acme.com&quot;</span>).<span class="ident">unwrap</span>());
<span class="kw">let</span> <span class="ident">method_header</span> <span class="op">=</span> <span class="ident">Header</span>::<span class="ident">from</span>(<span class="ident">hyper</span>::<span class="ident">header</span>::<span class="ident">AccessControlRequestMethod</span>(
<span class="ident">hyper</span>::<span class="ident">method</span>::<span class="ident">Method</span>::<span class="ident">Get</span>,
));
<span class="kw">let</span> <span class="ident">request_headers</span> <span class="op">=</span>
<span class="ident">hyper</span>::<span class="ident">header</span>::<span class="ident">AccessControlRequestHeaders</span>(<span class="macro">vec</span><span class="macro">!</span>[
<span class="ident">FromStr</span>::<span class="ident">from_str</span>(<span class="string">&quot;Authorization&quot;</span>).<span class="ident">unwrap</span>()
]);
<span class="kw">let</span> <span class="ident">request_headers</span> <span class="op">=</span> <span class="ident">Header</span>::<span class="ident">from</span>(<span class="ident">request_headers</span>);
<span class="kw">let</span> <span class="ident">request</span> <span class="op">=</span> <span class="ident">client</span>
.<span class="ident">options</span>(<span class="string">&quot;/&quot;</span>)
.<span class="ident">header</span>(<span class="ident">origin_header</span>)
.<span class="ident">header</span>(<span class="ident">method_header</span>)
.<span class="ident">header</span>(<span class="ident">request_headers</span>);
<span class="kw">let</span> <span class="ident">response</span> <span class="op">=</span> <span class="ident">validate_and_build</span>(<span class="kw-2">&amp;</span><span class="ident">cors</span>, <span class="ident">request</span>.<span class="ident">inner</span>()).<span class="ident">expect</span>(<span class="string">&quot;to not fail&quot;</span>);
<span class="kw">let</span> <span class="ident">expected_response</span> <span class="op">=</span> <span class="ident">Response</span>::<span class="ident">new</span>()
.<span class="ident">any</span>()
.<span class="ident">headers</span>(<span class="kw-2">&amp;</span>[<span class="string">&quot;Authorization&quot;</span>])
.<span class="ident">methods</span>(<span class="kw-2">&amp;</span><span class="ident">options</span>.<span class="ident">allowed_methods</span>)
.<span class="ident">credentials</span>(<span class="ident">options</span>.<span class="ident">allow_credentials</span>)
.<span class="ident">max_age</span>(<span class="ident">options</span>.<span class="ident">max_age</span>);
<span class="macro">assert_eq</span><span class="macro">!</span>(<span class="ident">expected_response</span>, <span class="ident">response</span>);
}
<span class="attribute">#[<span class="ident">test</span>]</span>
<span class="kw">fn</span> <span class="ident">actual_request_validated_and_built_correctly</span>() {
<span class="kw">let</span> <span class="ident">options</span> <span class="op">=</span> <span class="ident">make_cors_options</span>();
<span class="kw">let</span> <span class="ident">cors</span> <span class="op">=</span> <span class="ident">options</span>.<span class="ident">to_cors</span>().<span class="ident">expect</span>(<span class="string">&quot;To not fail&quot;</span>);
<span class="kw">let</span> <span class="ident">client</span> <span class="op">=</span> <span class="ident">make_client</span>();
<span class="kw">let</span> <span class="ident">origin_header</span> <span class="op">=</span>
<span class="ident">Header</span>::<span class="ident">from</span>(<span class="ident">hyper</span>::<span class="ident">header</span>::<span class="ident">Origin</span>::<span class="ident">from_str</span>(<span class="string">&quot;https://www.acme.com&quot;</span>).<span class="ident">unwrap</span>());
<span class="kw">let</span> <span class="ident">request</span> <span class="op">=</span> <span class="ident">client</span>.<span class="ident">get</span>(<span class="string">&quot;/&quot;</span>).<span class="ident">header</span>(<span class="ident">origin_header</span>);
<span class="kw">let</span> <span class="ident">response</span> <span class="op">=</span> <span class="ident">validate_and_build</span>(<span class="kw-2">&amp;</span><span class="ident">cors</span>, <span class="ident">request</span>.<span class="ident">inner</span>()).<span class="ident">expect</span>(<span class="string">&quot;to not fail&quot;</span>);
<span class="kw">let</span> <span class="ident">expected_response</span> <span class="op">=</span> <span class="ident">Response</span>::<span class="ident">new</span>()
.<span class="ident">origin</span>(<span class="string">&quot;https://www.acme.com&quot;</span>, <span class="bool-val">false</span>)
.<span class="ident">credentials</span>(<span class="ident">options</span>.<span class="ident">allow_credentials</span>)
.<span class="ident">exposed_headers</span>(<span class="kw-2">&amp;</span>[<span class="string">&quot;Content-Type&quot;</span>, <span class="string">&quot;X-Custom&quot;</span>]);
<span class="macro">assert_eq</span><span class="macro">!</span>(<span class="ident">expected_response</span>, <span class="ident">response</span>);
}
<span class="attribute">#[<span class="ident">test</span>]</span>
<span class="kw">fn</span> <span class="ident">actual_request_all_origins_with_vary</span>() {
<span class="kw">let</span> <span class="kw-2">mut</span> <span class="ident">options</span> <span class="op">=</span> <span class="ident">make_cors_options</span>();
<span class="ident">options</span>.<span class="ident">allowed_origins</span> <span class="op">=</span> <span class="ident">AllOrSome</span>::<span class="ident">All</span>;
<span class="ident">options</span>.<span class="ident">send_wildcard</span> <span class="op">=</span> <span class="bool-val">false</span>;
<span class="ident">options</span>.<span class="ident">allow_credentials</span> <span class="op">=</span> <span class="bool-val">false</span>;
<span class="kw">let</span> <span class="ident">cors</span> <span class="op">=</span> <span class="ident">options</span>.<span class="ident">to_cors</span>().<span class="ident">expect</span>(<span class="string">&quot;To not fail&quot;</span>);
<span class="kw">let</span> <span class="ident">client</span> <span class="op">=</span> <span class="ident">make_client</span>();
<span class="kw">let</span> <span class="ident">origin_header</span> <span class="op">=</span>
<span class="ident">Header</span>::<span class="ident">from</span>(<span class="ident">hyper</span>::<span class="ident">header</span>::<span class="ident">Origin</span>::<span class="ident">from_str</span>(<span class="string">&quot;https://www.acme.com&quot;</span>).<span class="ident">unwrap</span>());
<span class="kw">let</span> <span class="ident">request</span> <span class="op">=</span> <span class="ident">client</span>.<span class="ident">get</span>(<span class="string">&quot;/&quot;</span>).<span class="ident">header</span>(<span class="ident">origin_header</span>);
<span class="kw">let</span> <span class="ident">response</span> <span class="op">=</span> <span class="ident">validate_and_build</span>(<span class="kw-2">&amp;</span><span class="ident">cors</span>, <span class="ident">request</span>.<span class="ident">inner</span>()).<span class="ident">expect</span>(<span class="string">&quot;to not fail&quot;</span>);
<span class="kw">let</span> <span class="ident">expected_response</span> <span class="op">=</span> <span class="ident">Response</span>::<span class="ident">new</span>()
.<span class="ident">origin</span>(<span class="string">&quot;https://www.acme.com&quot;</span>, <span class="bool-val">true</span>)
.<span class="ident">credentials</span>(<span class="ident">options</span>.<span class="ident">allow_credentials</span>)
.<span class="ident">exposed_headers</span>(<span class="kw-2">&amp;</span>[<span class="string">&quot;Content-Type&quot;</span>, <span class="string">&quot;X-Custom&quot;</span>]);
<span class="macro">assert_eq</span><span class="macro">!</span>(<span class="ident">expected_response</span>, <span class="ident">response</span>);
}
<span class="attribute">#[<span class="ident">test</span>]</span>
<span class="kw">fn</span> <span class="ident">actual_request_all_origins_with_wildcard</span>() {
<span class="kw">let</span> <span class="kw-2">mut</span> <span class="ident">options</span> <span class="op">=</span> <span class="ident">make_cors_options</span>();
<span class="ident">options</span>.<span class="ident">allowed_origins</span> <span class="op">=</span> <span class="ident">AllOrSome</span>::<span class="ident">All</span>;
<span class="ident">options</span>.<span class="ident">send_wildcard</span> <span class="op">=</span> <span class="bool-val">true</span>;
<span class="ident">options</span>.<span class="ident">allow_credentials</span> <span class="op">=</span> <span class="bool-val">false</span>;
<span class="kw">let</span> <span class="ident">cors</span> <span class="op">=</span> <span class="ident">options</span>.<span class="ident">to_cors</span>().<span class="ident">expect</span>(<span class="string">&quot;To not fail&quot;</span>);
<span class="kw">let</span> <span class="ident">client</span> <span class="op">=</span> <span class="ident">make_client</span>();
<span class="kw">let</span> <span class="ident">origin_header</span> <span class="op">=</span>
<span class="ident">Header</span>::<span class="ident">from</span>(<span class="ident">hyper</span>::<span class="ident">header</span>::<span class="ident">Origin</span>::<span class="ident">from_str</span>(<span class="string">&quot;https://www.acme.com&quot;</span>).<span class="ident">unwrap</span>());
<span class="kw">let</span> <span class="ident">request</span> <span class="op">=</span> <span class="ident">client</span>.<span class="ident">get</span>(<span class="string">&quot;/&quot;</span>).<span class="ident">header</span>(<span class="ident">origin_header</span>);
<span class="kw">let</span> <span class="ident">response</span> <span class="op">=</span> <span class="ident">validate_and_build</span>(<span class="kw-2">&amp;</span><span class="ident">cors</span>, <span class="ident">request</span>.<span class="ident">inner</span>()).<span class="ident">expect</span>(<span class="string">&quot;to not fail&quot;</span>);
<span class="kw">let</span> <span class="ident">expected_response</span> <span class="op">=</span> <span class="ident">Response</span>::<span class="ident">new</span>()
.<span class="ident">any</span>()
.<span class="ident">credentials</span>(<span class="ident">options</span>.<span class="ident">allow_credentials</span>)
.<span class="ident">exposed_headers</span>(<span class="kw-2">&amp;</span>[<span class="string">&quot;Content-Type&quot;</span>, <span class="string">&quot;X-Custom&quot;</span>]);
<span class="macro">assert_eq</span><span class="macro">!</span>(<span class="ident">expected_response</span>, <span class="ident">response</span>);
}
}
</pre></div>
</section><section id="search" class="content hidden"></section><section class="footer"></section><script>window.rootPath = "../../";window.currentCrate = "rocket_cors";</script><script src="../../aliases.js"></script><script src="../../main.js"></script><script src="../../source-script.js"></script><script src="../../source-files.js"></script><script defer src="../../search-index.js"></script></body></html>