1
0
mirror of https://github.com/actix/actix-website synced 2024-11-28 18:32:39 +01:00
actix-website/static/api/actix-web/0.7.2/src/actix_web/server/h1decoder.rs.html
2018-07-26 10:53:41 -07:00

1019 lines
77 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/server/h1decoder.rs`."><meta name="keywords" content="rust, rustlang, rust-lang"><title>h1decoder.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></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></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"><input class="search-input" name="search" autocomplete="off" placeholder="Click or press S to search, ? for more options…" type="search"><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>
</pre><pre class="rust ">
<span class="kw">use</span> <span class="ident">std</span>::{<span class="ident">io</span>, <span class="ident">mem</span>};
<span class="kw">use</span> <span class="ident">bytes</span>::{<span class="ident">Bytes</span>, <span class="ident">BytesMut</span>};
<span class="kw">use</span> <span class="ident">futures</span>::{<span class="ident">Async</span>, <span class="ident">Poll</span>};
<span class="kw">use</span> <span class="ident">httparse</span>;
<span class="kw">use</span> <span class="kw">super</span>::<span class="ident">message</span>::{<span class="ident">MessageFlags</span>, <span class="ident">Request</span>};
<span class="kw">use</span> <span class="kw">super</span>::<span class="ident">settings</span>::<span class="ident">WorkerSettings</span>;
<span class="kw">use</span> <span class="ident">error</span>::<span class="ident">ParseError</span>;
<span class="kw">use</span> <span class="ident">http</span>::<span class="ident">header</span>::{<span class="ident">HeaderName</span>, <span class="ident">HeaderValue</span>};
<span class="kw">use</span> <span class="ident">http</span>::{<span class="ident">header</span>, <span class="ident">HttpTryFrom</span>, <span class="ident">Method</span>, <span class="ident">Uri</span>, <span class="ident">Version</span>};
<span class="kw">use</span> <span class="ident">uri</span>::<span class="ident">Url</span>;
<span class="kw">const</span> <span class="ident">MAX_BUFFER_SIZE</span>: <span class="ident">usize</span> <span class="op">=</span> <span class="number">131_072</span>;
<span class="kw">const</span> <span class="ident">MAX_HEADERS</span>: <span class="ident">usize</span> <span class="op">=</span> <span class="number">96</span>;
<span class="kw">pub</span>(<span class="kw">crate</span>) <span class="kw">struct</span> <span class="ident">H1Decoder</span> {
<span class="ident">decoder</span>: <span class="prelude-ty">Option</span><span class="op">&lt;</span><span class="ident">EncodingDecoder</span><span class="op">&gt;</span>,
}
<span class="kw">pub</span>(<span class="kw">crate</span>) <span class="kw">enum</span> <span class="ident">Message</span> {
<span class="ident">Message</span> { <span class="ident">msg</span>: <span class="ident">Request</span>, <span class="ident">payload</span>: <span class="ident">bool</span> },
<span class="ident">Chunk</span>(<span class="ident">Bytes</span>),
<span class="ident">Eof</span>,
}
<span class="attribute">#[<span class="ident">derive</span>(<span class="ident">Debug</span>)]</span>
<span class="kw">pub</span>(<span class="kw">crate</span>) <span class="kw">enum</span> <span class="ident">DecoderError</span> {
<span class="ident">Io</span>(<span class="ident">io</span>::<span class="ident">Error</span>),
<span class="ident">Error</span>(<span class="ident">ParseError</span>),
}
<span class="kw">impl</span> <span class="ident">From</span><span class="op">&lt;</span><span class="ident">io</span>::<span class="ident">Error</span><span class="op">&gt;</span> <span class="kw">for</span> <span class="ident">DecoderError</span> {
<span class="kw">fn</span> <span class="ident">from</span>(<span class="ident">err</span>: <span class="ident">io</span>::<span class="ident">Error</span>) <span class="op">-&gt;</span> <span class="ident">DecoderError</span> {
<span class="ident">DecoderError</span>::<span class="ident">Io</span>(<span class="ident">err</span>)
}
}
<span class="kw">impl</span> <span class="ident">H1Decoder</span> {
<span class="kw">pub</span> <span class="kw">fn</span> <span class="ident">new</span>() <span class="op">-&gt;</span> <span class="ident">H1Decoder</span> {
<span class="ident">H1Decoder</span> { <span class="ident">decoder</span>: <span class="prelude-val">None</span> }
}
<span class="kw">pub</span> <span class="kw">fn</span> <span class="ident">decode</span><span class="op">&lt;</span><span class="ident">H</span><span class="op">&gt;</span>(
<span class="kw-2">&amp;</span><span class="kw-2">mut</span> <span class="self">self</span>, <span class="ident">src</span>: <span class="kw-2">&amp;</span><span class="kw-2">mut</span> <span class="ident">BytesMut</span>, <span class="ident">settings</span>: <span class="kw-2">&amp;</span><span class="ident">WorkerSettings</span><span class="op">&lt;</span><span class="ident">H</span><span class="op">&gt;</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">Message</span><span class="op">&gt;</span>, <span class="ident">DecoderError</span><span class="op">&gt;</span> {
<span class="comment">// read payload</span>
<span class="kw">if</span> <span class="self">self</span>.<span class="ident">decoder</span>.<span class="ident">is_some</span>() {
<span class="kw">match</span> <span class="self">self</span>.<span class="ident">decoder</span>.<span class="ident">as_mut</span>().<span class="ident">unwrap</span>().<span class="ident">decode</span>(<span class="ident">src</span>)<span class="question-mark">?</span> {
<span class="ident">Async</span>::<span class="ident">Ready</span>(<span class="prelude-val">Some</span>(<span class="ident">bytes</span>)) <span class="op">=&gt;</span> <span class="kw">return</span> <span class="prelude-val">Ok</span>(<span class="prelude-val">Some</span>(<span class="ident">Message</span>::<span class="ident">Chunk</span>(<span class="ident">bytes</span>))),
<span class="ident">Async</span>::<span class="ident">Ready</span>(<span class="prelude-val">None</span>) <span class="op">=&gt;</span> {
<span class="self">self</span>.<span class="ident">decoder</span>.<span class="ident">take</span>();
<span class="kw">return</span> <span class="prelude-val">Ok</span>(<span class="prelude-val">Some</span>(<span class="ident">Message</span>::<span class="ident">Eof</span>));
}
<span class="ident">Async</span>::<span class="ident">NotReady</span> <span class="op">=&gt;</span> <span class="kw">return</span> <span class="prelude-val">Ok</span>(<span class="prelude-val">None</span>),
}
}
<span class="kw">match</span> <span class="self">self</span>
.<span class="ident">parse_message</span>(<span class="ident">src</span>, <span class="ident">settings</span>)
.<span class="ident">map_err</span>(<span class="ident">DecoderError</span>::<span class="ident">Error</span>)<span class="question-mark">?</span>
{
<span class="ident">Async</span>::<span class="ident">Ready</span>((<span class="ident">msg</span>, <span class="ident">decoder</span>)) <span class="op">=&gt;</span> {
<span class="self">self</span>.<span class="ident">decoder</span> <span class="op">=</span> <span class="ident">decoder</span>;
<span class="prelude-val">Ok</span>(<span class="prelude-val">Some</span>(<span class="ident">Message</span>::<span class="ident">Message</span> {
<span class="ident">msg</span>,
<span class="ident">payload</span>: <span class="self">self</span>.<span class="ident">decoder</span>.<span class="ident">is_some</span>(),
}))
}
<span class="ident">Async</span>::<span class="ident">NotReady</span> <span class="op">=&gt;</span> {
<span class="kw">if</span> <span class="ident">src</span>.<span class="ident">len</span>() <span class="op">&gt;=</span> <span class="ident">MAX_BUFFER_SIZE</span> {
<span class="macro">error</span><span class="macro">!</span>(<span class="string">&quot;MAX_BUFFER_SIZE unprocessed data reached, closing&quot;</span>);
<span class="prelude-val">Err</span>(<span class="ident">DecoderError</span>::<span class="ident">Error</span>(<span class="ident">ParseError</span>::<span class="ident">TooLarge</span>))
} <span class="kw">else</span> {
<span class="prelude-val">Ok</span>(<span class="prelude-val">None</span>)
}
}
}
}
<span class="kw">fn</span> <span class="ident">parse_message</span><span class="op">&lt;</span><span class="ident">H</span><span class="op">&gt;</span>(
<span class="kw-2">&amp;</span><span class="self">self</span>, <span class="ident">buf</span>: <span class="kw-2">&amp;</span><span class="kw-2">mut</span> <span class="ident">BytesMut</span>, <span class="ident">settings</span>: <span class="kw-2">&amp;</span><span class="ident">WorkerSettings</span><span class="op">&lt;</span><span class="ident">H</span><span class="op">&gt;</span>,
) <span class="op">-&gt;</span> <span class="ident">Poll</span><span class="op">&lt;</span>(<span class="ident">Request</span>, <span class="prelude-ty">Option</span><span class="op">&lt;</span><span class="ident">EncodingDecoder</span><span class="op">&gt;</span>), <span class="ident">ParseError</span><span class="op">&gt;</span> {
<span class="comment">// Parse http message</span>
<span class="kw">let</span> <span class="kw-2">mut</span> <span class="ident">has_upgrade</span> <span class="op">=</span> <span class="bool-val">false</span>;
<span class="kw">let</span> <span class="kw-2">mut</span> <span class="ident">chunked</span> <span class="op">=</span> <span class="bool-val">false</span>;
<span class="kw">let</span> <span class="kw-2">mut</span> <span class="ident">content_length</span> <span class="op">=</span> <span class="prelude-val">None</span>;
<span class="kw">let</span> <span class="ident">msg</span> <span class="op">=</span> {
<span class="comment">// Unsafe: we read only this data only after httparse parses headers into.</span>
<span class="comment">// performance bump for pipeline benchmarks.</span>
<span class="kw">let</span> <span class="kw-2">mut</span> <span class="ident">headers</span>: [<span class="ident">HeaderIndex</span>; <span class="ident">MAX_HEADERS</span>] <span class="op">=</span>
<span class="kw">unsafe</span> { <span class="ident">mem</span>::<span class="ident">uninitialized</span>() };
<span class="kw">let</span> (<span class="ident">len</span>, <span class="ident">method</span>, <span class="ident">path</span>, <span class="ident">version</span>, <span class="ident">headers_len</span>) <span class="op">=</span> {
<span class="kw">let</span> <span class="kw-2">mut</span> <span class="ident">parsed</span>: [<span class="ident">httparse</span>::<span class="ident">Header</span>; <span class="ident">MAX_HEADERS</span>] <span class="op">=</span>
<span class="kw">unsafe</span> { <span class="ident">mem</span>::<span class="ident">uninitialized</span>() };
<span class="kw">let</span> <span class="kw-2">mut</span> <span class="ident">req</span> <span class="op">=</span> <span class="ident">httparse</span>::<span class="ident">Request</span>::<span class="ident">new</span>(<span class="kw-2">&amp;</span><span class="kw-2">mut</span> <span class="ident">parsed</span>);
<span class="kw">match</span> <span class="ident">req</span>.<span class="ident">parse</span>(<span class="ident">buf</span>)<span class="question-mark">?</span> {
<span class="ident">httparse</span>::<span class="ident">Status</span>::<span class="ident">Complete</span>(<span class="ident">len</span>) <span class="op">=&gt;</span> {
<span class="kw">let</span> <span class="ident">method</span> <span class="op">=</span> <span class="ident">Method</span>::<span class="ident">from_bytes</span>(<span class="ident">req</span>.<span class="ident">method</span>.<span class="ident">unwrap</span>().<span class="ident">as_bytes</span>())
.<span class="ident">map_err</span>(<span class="op">|</span><span class="kw">_</span><span class="op">|</span> <span class="ident">ParseError</span>::<span class="ident">Method</span>)<span class="question-mark">?</span>;
<span class="kw">let</span> <span class="ident">path</span> <span class="op">=</span> <span class="ident">Url</span>::<span class="ident">new</span>(<span class="ident">Uri</span>::<span class="ident">try_from</span>(<span class="ident">req</span>.<span class="ident">path</span>.<span class="ident">unwrap</span>())<span class="question-mark">?</span>);
<span class="kw">let</span> <span class="ident">version</span> <span class="op">=</span> <span class="kw">if</span> <span class="ident">req</span>.<span class="ident">version</span>.<span class="ident">unwrap</span>() <span class="op">==</span> <span class="number">1</span> {
<span class="ident">Version</span>::<span class="ident">HTTP_11</span>
} <span class="kw">else</span> {
<span class="ident">Version</span>::<span class="ident">HTTP_10</span>
};
<span class="ident">HeaderIndex</span>::<span class="ident">record</span>(<span class="ident">buf</span>, <span class="ident">req</span>.<span class="ident">headers</span>, <span class="kw-2">&amp;</span><span class="kw-2">mut</span> <span class="ident">headers</span>);
(<span class="ident">len</span>, <span class="ident">method</span>, <span class="ident">path</span>, <span class="ident">version</span>, <span class="ident">req</span>.<span class="ident">headers</span>.<span class="ident">len</span>())
}
<span class="ident">httparse</span>::<span class="ident">Status</span>::<span class="ident">Partial</span> <span class="op">=&gt;</span> <span class="kw">return</span> <span class="prelude-val">Ok</span>(<span class="ident">Async</span>::<span class="ident">NotReady</span>),
}
};
<span class="kw">let</span> <span class="ident">slice</span> <span class="op">=</span> <span class="ident">buf</span>.<span class="ident">split_to</span>(<span class="ident">len</span>).<span class="ident">freeze</span>();
<span class="comment">// convert headers</span>
<span class="kw">let</span> <span class="kw-2">mut</span> <span class="ident">msg</span> <span class="op">=</span> <span class="ident">settings</span>.<span class="ident">get_request</span>();
{
<span class="kw">let</span> <span class="ident">inner</span> <span class="op">=</span> <span class="ident">msg</span>.<span class="ident">inner_mut</span>();
<span class="ident">inner</span>
.<span class="ident">flags</span>
.<span class="ident">get_mut</span>()
.<span class="ident">set</span>(<span class="ident">MessageFlags</span>::<span class="ident">KEEPALIVE</span>, <span class="ident">version</span> <span class="op">!=</span> <span class="ident">Version</span>::<span class="ident">HTTP_10</span>);
<span class="kw">for</span> <span class="ident">idx</span> <span class="kw">in</span> <span class="ident">headers</span>[..<span class="ident">headers_len</span>].<span class="ident">iter</span>() {
<span class="kw">if</span> <span class="kw">let</span> <span class="prelude-val">Ok</span>(<span class="ident">name</span>) <span class="op">=</span>
<span class="ident">HeaderName</span>::<span class="ident">from_bytes</span>(<span class="kw-2">&amp;</span><span class="ident">slice</span>[<span class="ident">idx</span>.<span class="ident">name</span>.<span class="number">0</span>..<span class="ident">idx</span>.<span class="ident">name</span>.<span class="number">1</span>])
{
<span class="comment">// Unsafe: httparse check header value for valid utf-8</span>
<span class="kw">let</span> <span class="ident">value</span> <span class="op">=</span> <span class="kw">unsafe</span> {
<span class="ident">HeaderValue</span>::<span class="ident">from_shared_unchecked</span>(
<span class="ident">slice</span>.<span class="ident">slice</span>(<span class="ident">idx</span>.<span class="ident">value</span>.<span class="number">0</span>, <span class="ident">idx</span>.<span class="ident">value</span>.<span class="number">1</span>),
)
};
<span class="kw">match</span> <span class="ident">name</span> {
<span class="ident">header</span>::<span class="ident">CONTENT_LENGTH</span> <span class="op">=&gt;</span> {
<span class="kw">if</span> <span class="kw">let</span> <span class="prelude-val">Ok</span>(<span class="ident">s</span>) <span class="op">=</span> <span class="ident">value</span>.<span class="ident">to_str</span>() {
<span class="kw">if</span> <span class="kw">let</span> <span class="prelude-val">Ok</span>(<span class="ident">len</span>) <span class="op">=</span> <span class="ident">s</span>.<span class="ident">parse</span>::<span class="op">&lt;</span><span class="ident">u64</span><span class="op">&gt;</span>() {
<span class="ident">content_length</span> <span class="op">=</span> <span class="prelude-val">Some</span>(<span class="ident">len</span>);
} <span class="kw">else</span> {
<span class="macro">debug</span><span class="macro">!</span>(<span class="string">&quot;illegal Content-Length: {:?}&quot;</span>, <span class="ident">len</span>);
<span class="kw">return</span> <span class="prelude-val">Err</span>(<span class="ident">ParseError</span>::<span class="ident">Header</span>);
}
} <span class="kw">else</span> {
<span class="macro">debug</span><span class="macro">!</span>(<span class="string">&quot;illegal Content-Length: {:?}&quot;</span>, <span class="ident">len</span>);
<span class="kw">return</span> <span class="prelude-val">Err</span>(<span class="ident">ParseError</span>::<span class="ident">Header</span>);
}
}
<span class="comment">// transfer-encoding</span>
<span class="ident">header</span>::<span class="ident">TRANSFER_ENCODING</span> <span class="op">=&gt;</span> {
<span class="kw">if</span> <span class="kw">let</span> <span class="prelude-val">Ok</span>(<span class="ident">s</span>) <span class="op">=</span> <span class="ident">value</span>.<span class="ident">to_str</span>() {
<span class="ident">chunked</span> <span class="op">=</span> <span class="ident">s</span>.<span class="ident">to_lowercase</span>().<span class="ident">contains</span>(<span class="string">&quot;chunked&quot;</span>);
} <span class="kw">else</span> {
<span class="kw">return</span> <span class="prelude-val">Err</span>(<span class="ident">ParseError</span>::<span class="ident">Header</span>);
}
}
<span class="comment">// connection keep-alive state</span>
<span class="ident">header</span>::<span class="ident">CONNECTION</span> <span class="op">=&gt;</span> {
<span class="kw">let</span> <span class="ident">ka</span> <span class="op">=</span> <span class="kw">if</span> <span class="kw">let</span> <span class="prelude-val">Ok</span>(<span class="ident">conn</span>) <span class="op">=</span> <span class="ident">value</span>.<span class="ident">to_str</span>() {
<span class="kw">if</span> <span class="ident">version</span> <span class="op">==</span> <span class="ident">Version</span>::<span class="ident">HTTP_10</span>
<span class="op">&amp;&amp;</span> <span class="ident">conn</span>.<span class="ident">contains</span>(<span class="string">&quot;keep-alive&quot;</span>)
{
<span class="bool-val">true</span>
} <span class="kw">else</span> {
<span class="ident">version</span> <span class="op">==</span> <span class="ident">Version</span>::<span class="ident">HTTP_11</span>
<span class="op">&amp;&amp;</span> <span class="op">!</span>(<span class="ident">conn</span>.<span class="ident">contains</span>(<span class="string">&quot;close&quot;</span>)
<span class="op">||</span> <span class="ident">conn</span>.<span class="ident">contains</span>(<span class="string">&quot;upgrade&quot;</span>))
}
} <span class="kw">else</span> {
<span class="bool-val">false</span>
};
<span class="ident">inner</span>.<span class="ident">flags</span>.<span class="ident">get_mut</span>().<span class="ident">set</span>(<span class="ident">MessageFlags</span>::<span class="ident">KEEPALIVE</span>, <span class="ident">ka</span>);
}
<span class="ident">header</span>::<span class="ident">UPGRADE</span> <span class="op">=&gt;</span> {
<span class="ident">has_upgrade</span> <span class="op">=</span> <span class="bool-val">true</span>;
}
<span class="kw">_</span> <span class="op">=&gt;</span> (),
}
<span class="ident">inner</span>.<span class="ident">headers</span>.<span class="ident">append</span>(<span class="ident">name</span>, <span class="ident">value</span>);
} <span class="kw">else</span> {
<span class="kw">return</span> <span class="prelude-val">Err</span>(<span class="ident">ParseError</span>::<span class="ident">Header</span>);
}
}
<span class="ident">inner</span>.<span class="ident">url</span> <span class="op">=</span> <span class="ident">path</span>;
<span class="ident">inner</span>.<span class="ident">method</span> <span class="op">=</span> <span class="ident">method</span>;
<span class="ident">inner</span>.<span class="ident">version</span> <span class="op">=</span> <span class="ident">version</span>;
}
<span class="ident">msg</span>
};
<span class="comment">// https://tools.ietf.org/html/rfc7230#section-3.3.3</span>
<span class="kw">let</span> <span class="ident">decoder</span> <span class="op">=</span> <span class="kw">if</span> <span class="ident">chunked</span> {
<span class="comment">// Chunked encoding</span>
<span class="prelude-val">Some</span>(<span class="ident">EncodingDecoder</span>::<span class="ident">chunked</span>())
} <span class="kw">else</span> <span class="kw">if</span> <span class="kw">let</span> <span class="prelude-val">Some</span>(<span class="ident">len</span>) <span class="op">=</span> <span class="ident">content_length</span> {
<span class="comment">// Content-Length</span>
<span class="prelude-val">Some</span>(<span class="ident">EncodingDecoder</span>::<span class="ident">length</span>(<span class="ident">len</span>))
} <span class="kw">else</span> <span class="kw">if</span> <span class="ident">has_upgrade</span> <span class="op">||</span> <span class="ident">msg</span>.<span class="ident">inner</span>.<span class="ident">method</span> <span class="op">==</span> <span class="ident">Method</span>::<span class="ident">CONNECT</span> {
<span class="comment">// upgrade(websocket) or connect</span>
<span class="prelude-val">Some</span>(<span class="ident">EncodingDecoder</span>::<span class="ident">eof</span>())
} <span class="kw">else</span> {
<span class="prelude-val">None</span>
};
<span class="prelude-val">Ok</span>(<span class="ident">Async</span>::<span class="ident">Ready</span>((<span class="ident">msg</span>, <span class="ident">decoder</span>)))
}
}
<span class="attribute">#[<span class="ident">derive</span>(<span class="ident">Clone</span>, <span class="ident">Copy</span>)]</span>
<span class="kw">pub</span>(<span class="kw">crate</span>) <span class="kw">struct</span> <span class="ident">HeaderIndex</span> {
<span class="kw">pub</span>(<span class="kw">crate</span>) <span class="ident">name</span>: (<span class="ident">usize</span>, <span class="ident">usize</span>),
<span class="kw">pub</span>(<span class="kw">crate</span>) <span class="ident">value</span>: (<span class="ident">usize</span>, <span class="ident">usize</span>),
}
<span class="kw">impl</span> <span class="ident">HeaderIndex</span> {
<span class="kw">pub</span>(<span class="kw">crate</span>) <span class="kw">fn</span> <span class="ident">record</span>(
<span class="ident">bytes</span>: <span class="kw-2">&amp;</span>[<span class="ident">u8</span>], <span class="ident">headers</span>: <span class="kw-2">&amp;</span>[<span class="ident">httparse</span>::<span class="ident">Header</span>], <span class="ident">indices</span>: <span class="kw-2">&amp;</span><span class="kw-2">mut</span> [<span class="ident">HeaderIndex</span>],
) {
<span class="kw">let</span> <span class="ident">bytes_ptr</span> <span class="op">=</span> <span class="ident">bytes</span>.<span class="ident">as_ptr</span>() <span class="kw">as</span> <span class="ident">usize</span>;
<span class="kw">for</span> (<span class="ident">header</span>, <span class="ident">indices</span>) <span class="kw">in</span> <span class="ident">headers</span>.<span class="ident">iter</span>().<span class="ident">zip</span>(<span class="ident">indices</span>.<span class="ident">iter_mut</span>()) {
<span class="kw">let</span> <span class="ident">name_start</span> <span class="op">=</span> <span class="ident">header</span>.<span class="ident">name</span>.<span class="ident">as_ptr</span>() <span class="kw">as</span> <span class="ident">usize</span> <span class="op">-</span> <span class="ident">bytes_ptr</span>;
<span class="kw">let</span> <span class="ident">name_end</span> <span class="op">=</span> <span class="ident">name_start</span> <span class="op">+</span> <span class="ident">header</span>.<span class="ident">name</span>.<span class="ident">len</span>();
<span class="ident">indices</span>.<span class="ident">name</span> <span class="op">=</span> (<span class="ident">name_start</span>, <span class="ident">name_end</span>);
<span class="kw">let</span> <span class="ident">value_start</span> <span class="op">=</span> <span class="ident">header</span>.<span class="ident">value</span>.<span class="ident">as_ptr</span>() <span class="kw">as</span> <span class="ident">usize</span> <span class="op">-</span> <span class="ident">bytes_ptr</span>;
<span class="kw">let</span> <span class="ident">value_end</span> <span class="op">=</span> <span class="ident">value_start</span> <span class="op">+</span> <span class="ident">header</span>.<span class="ident">value</span>.<span class="ident">len</span>();
<span class="ident">indices</span>.<span class="ident">value</span> <span class="op">=</span> (<span class="ident">value_start</span>, <span class="ident">value_end</span>);
}
}
}
<span class="doccomment">/// Decoders to handle different Transfer-Encodings.</span>
<span class="doccomment">///</span>
<span class="doccomment">/// If a message body does not include a Transfer-Encoding, it *should*</span>
<span class="doccomment">/// include a Content-Length header.</span>
<span class="attribute">#[<span class="ident">derive</span>(<span class="ident">Debug</span>, <span class="ident">Clone</span>, <span class="ident">PartialEq</span>)]</span>
<span class="kw">pub</span> <span class="kw">struct</span> <span class="ident">EncodingDecoder</span> {
<span class="ident">kind</span>: <span class="ident">Kind</span>,
}
<span class="kw">impl</span> <span class="ident">EncodingDecoder</span> {
<span class="kw">pub</span> <span class="kw">fn</span> <span class="ident">length</span>(<span class="ident">x</span>: <span class="ident">u64</span>) <span class="op">-&gt;</span> <span class="ident">EncodingDecoder</span> {
<span class="ident">EncodingDecoder</span> {
<span class="ident">kind</span>: <span class="ident">Kind</span>::<span class="ident">Length</span>(<span class="ident">x</span>),
}
}
<span class="kw">pub</span> <span class="kw">fn</span> <span class="ident">chunked</span>() <span class="op">-&gt;</span> <span class="ident">EncodingDecoder</span> {
<span class="ident">EncodingDecoder</span> {
<span class="ident">kind</span>: <span class="ident">Kind</span>::<span class="ident">Chunked</span>(<span class="ident">ChunkedState</span>::<span class="ident">Size</span>, <span class="number">0</span>),
}
}
<span class="kw">pub</span> <span class="kw">fn</span> <span class="ident">eof</span>() <span class="op">-&gt;</span> <span class="ident">EncodingDecoder</span> {
<span class="ident">EncodingDecoder</span> {
<span class="ident">kind</span>: <span class="ident">Kind</span>::<span class="ident">Eof</span>(<span class="bool-val">false</span>),
}
}
}
<span class="attribute">#[<span class="ident">derive</span>(<span class="ident">Debug</span>, <span class="ident">Clone</span>, <span class="ident">PartialEq</span>)]</span>
<span class="kw">enum</span> <span class="ident">Kind</span> {
<span class="doccomment">/// A Reader used when a Content-Length header is passed with a positive</span>
<span class="doccomment">/// integer.</span>
<span class="ident">Length</span>(<span class="ident">u64</span>),
<span class="doccomment">/// A Reader used when Transfer-Encoding is `chunked`.</span>
<span class="ident">Chunked</span>(<span class="ident">ChunkedState</span>, <span class="ident">u64</span>),
<span class="doccomment">/// A Reader used for responses that don&#39;t indicate a length or chunked.</span>
<span class="doccomment">///</span>
<span class="doccomment">/// Note: This should only used for `Response`s. It is illegal for a</span>
<span class="doccomment">/// `Request` to be made with both `Content-Length` and</span>
<span class="doccomment">/// `Transfer-Encoding: chunked` missing, as explained from the spec:</span>
<span class="doccomment">///</span>
<span class="doccomment">/// &gt; If a Transfer-Encoding header field is present in a response and</span>
<span class="doccomment">/// &gt; the chunked transfer coding is not the final encoding, the</span>
<span class="doccomment">/// &gt; message body length is determined by reading the connection until</span>
<span class="doccomment">/// &gt; it is closed by the server. If a Transfer-Encoding header field</span>
<span class="doccomment">/// &gt; is present in a request and the chunked transfer coding is not</span>
<span class="doccomment">/// &gt; the final encoding, the message body length cannot be determined</span>
<span class="doccomment">/// &gt; reliably; the server MUST respond with the 400 (Bad Request)</span>
<span class="doccomment">/// &gt; status code and then close the connection.</span>
<span class="ident">Eof</span>(<span class="ident">bool</span>),
}
<span class="attribute">#[<span class="ident">derive</span>(<span class="ident">Debug</span>, <span class="ident">PartialEq</span>, <span class="ident">Clone</span>)]</span>
<span class="kw">enum</span> <span class="ident">ChunkedState</span> {
<span class="ident">Size</span>,
<span class="ident">SizeLws</span>,
<span class="ident">Extension</span>,
<span class="ident">SizeLf</span>,
<span class="ident">Body</span>,
<span class="ident">BodyCr</span>,
<span class="ident">BodyLf</span>,
<span class="ident">EndCr</span>,
<span class="ident">EndLf</span>,
<span class="ident">End</span>,
}
<span class="kw">impl</span> <span class="ident">EncodingDecoder</span> {
<span class="kw">pub</span> <span class="kw">fn</span> <span class="ident">decode</span>(<span class="kw-2">&amp;</span><span class="kw-2">mut</span> <span class="self">self</span>, <span class="ident">body</span>: <span class="kw-2">&amp;</span><span class="kw-2">mut</span> <span class="ident">BytesMut</span>) <span class="op">-&gt;</span> <span class="ident">Poll</span><span class="op">&lt;</span><span class="prelude-ty">Option</span><span class="op">&lt;</span><span class="ident">Bytes</span><span class="op">&gt;</span>, <span class="ident">io</span>::<span class="ident">Error</span><span class="op">&gt;</span> {
<span class="kw">match</span> <span class="self">self</span>.<span class="ident">kind</span> {
<span class="ident">Kind</span>::<span class="ident">Length</span>(<span class="kw-2">ref</span> <span class="kw-2">mut</span> <span class="ident">remaining</span>) <span class="op">=&gt;</span> {
<span class="kw">if</span> <span class="kw-2">*</span><span class="ident">remaining</span> <span class="op">==</span> <span class="number">0</span> {
<span class="prelude-val">Ok</span>(<span class="ident">Async</span>::<span class="ident">Ready</span>(<span class="prelude-val">None</span>))
} <span class="kw">else</span> {
<span class="kw">if</span> <span class="ident">body</span>.<span class="ident">is_empty</span>() {
<span class="kw">return</span> <span class="prelude-val">Ok</span>(<span class="ident">Async</span>::<span class="ident">NotReady</span>);
}
<span class="kw">let</span> <span class="ident">len</span> <span class="op">=</span> <span class="ident">body</span>.<span class="ident">len</span>() <span class="kw">as</span> <span class="ident">u64</span>;
<span class="kw">let</span> <span class="ident">buf</span>;
<span class="kw">if</span> <span class="kw-2">*</span><span class="ident">remaining</span> <span class="op">&gt;</span> <span class="ident">len</span> {
<span class="ident">buf</span> <span class="op">=</span> <span class="ident">body</span>.<span class="ident">take</span>().<span class="ident">freeze</span>();
<span class="kw-2">*</span><span class="ident">remaining</span> <span class="op">-=</span> <span class="ident">len</span>;
} <span class="kw">else</span> {
<span class="ident">buf</span> <span class="op">=</span> <span class="ident">body</span>.<span class="ident">split_to</span>(<span class="kw-2">*</span><span class="ident">remaining</span> <span class="kw">as</span> <span class="ident">usize</span>).<span class="ident">freeze</span>();
<span class="kw-2">*</span><span class="ident">remaining</span> <span class="op">=</span> <span class="number">0</span>;
}
<span class="macro">trace</span><span class="macro">!</span>(<span class="string">&quot;Length read: {}&quot;</span>, <span class="ident">buf</span>.<span class="ident">len</span>());
<span class="prelude-val">Ok</span>(<span class="ident">Async</span>::<span class="ident">Ready</span>(<span class="prelude-val">Some</span>(<span class="ident">buf</span>)))
}
}
<span class="ident">Kind</span>::<span class="ident">Chunked</span>(<span class="kw-2">ref</span> <span class="kw-2">mut</span> <span class="ident">state</span>, <span class="kw-2">ref</span> <span class="kw-2">mut</span> <span class="ident">size</span>) <span class="op">=&gt;</span> {
<span class="kw">loop</span> {
<span class="kw">let</span> <span class="kw-2">mut</span> <span class="ident">buf</span> <span class="op">=</span> <span class="prelude-val">None</span>;
<span class="comment">// advances the chunked state</span>
<span class="kw-2">*</span><span class="ident">state</span> <span class="op">=</span> <span class="macro">try_ready</span><span class="macro">!</span>(<span class="ident">state</span>.<span class="ident">step</span>(<span class="ident">body</span>, <span class="ident">size</span>, <span class="kw-2">&amp;</span><span class="kw-2">mut</span> <span class="ident">buf</span>));
<span class="kw">if</span> <span class="kw-2">*</span><span class="ident">state</span> <span class="op">==</span> <span class="ident">ChunkedState</span>::<span class="ident">End</span> {
<span class="macro">trace</span><span class="macro">!</span>(<span class="string">&quot;End of chunked stream&quot;</span>);
<span class="kw">return</span> <span class="prelude-val">Ok</span>(<span class="ident">Async</span>::<span class="ident">Ready</span>(<span class="prelude-val">None</span>));
}
<span class="kw">if</span> <span class="kw">let</span> <span class="prelude-val">Some</span>(<span class="ident">buf</span>) <span class="op">=</span> <span class="ident">buf</span> {
<span class="kw">return</span> <span class="prelude-val">Ok</span>(<span class="ident">Async</span>::<span class="ident">Ready</span>(<span class="prelude-val">Some</span>(<span class="ident">buf</span>)));
}
<span class="kw">if</span> <span class="ident">body</span>.<span class="ident">is_empty</span>() {
<span class="kw">return</span> <span class="prelude-val">Ok</span>(<span class="ident">Async</span>::<span class="ident">NotReady</span>);
}
}
}
<span class="ident">Kind</span>::<span class="ident">Eof</span>(<span class="kw-2">ref</span> <span class="kw-2">mut</span> <span class="ident">is_eof</span>) <span class="op">=&gt;</span> {
<span class="kw">if</span> <span class="kw-2">*</span><span class="ident">is_eof</span> {
<span class="prelude-val">Ok</span>(<span class="ident">Async</span>::<span class="ident">Ready</span>(<span class="prelude-val">None</span>))
} <span class="kw">else</span> <span class="kw">if</span> <span class="op">!</span><span class="ident">body</span>.<span class="ident">is_empty</span>() {
<span class="prelude-val">Ok</span>(<span class="ident">Async</span>::<span class="ident">Ready</span>(<span class="prelude-val">Some</span>(<span class="ident">body</span>.<span class="ident">take</span>().<span class="ident">freeze</span>())))
} <span class="kw">else</span> {
<span class="prelude-val">Ok</span>(<span class="ident">Async</span>::<span class="ident">NotReady</span>)
}
}
}
}
}
<span class="macro">macro_rules</span><span class="macro">!</span> <span class="ident">byte</span> (
(<span class="macro-nonterminal">$</span><span class="macro-nonterminal">rdr</span>:<span class="ident">ident</span>) <span class="op">=&gt;</span> ({
<span class="kw">if</span> <span class="macro-nonterminal">$</span><span class="macro-nonterminal">rdr</span>.<span class="ident">len</span>() <span class="op">&gt;</span> <span class="number">0</span> {
<span class="kw">let</span> <span class="ident">b</span> <span class="op">=</span> <span class="macro-nonterminal">$</span><span class="macro-nonterminal">rdr</span>[<span class="number">0</span>];
<span class="macro-nonterminal">$</span><span class="macro-nonterminal">rdr</span>.<span class="ident">split_to</span>(<span class="number">1</span>);
<span class="ident">b</span>
} <span class="kw">else</span> {
<span class="kw">return</span> <span class="prelude-val">Ok</span>(<span class="ident">Async</span>::<span class="ident">NotReady</span>)
}
})
);
<span class="kw">impl</span> <span class="ident">ChunkedState</span> {
<span class="kw">fn</span> <span class="ident">step</span>(
<span class="kw-2">&amp;</span><span class="self">self</span>, <span class="ident">body</span>: <span class="kw-2">&amp;</span><span class="kw-2">mut</span> <span class="ident">BytesMut</span>, <span class="ident">size</span>: <span class="kw-2">&amp;</span><span class="kw-2">mut</span> <span class="ident">u64</span>, <span class="ident">buf</span>: <span class="kw-2">&amp;</span><span class="kw-2">mut</span> <span class="prelude-ty">Option</span><span class="op">&lt;</span><span class="ident">Bytes</span><span class="op">&gt;</span>,
) <span class="op">-&gt;</span> <span class="ident">Poll</span><span class="op">&lt;</span><span class="ident">ChunkedState</span>, <span class="ident">io</span>::<span class="ident">Error</span><span class="op">&gt;</span> {
<span class="kw">use</span> <span class="self">self</span>::<span class="ident">ChunkedState</span>::<span class="kw-2">*</span>;
<span class="kw">match</span> <span class="kw-2">*</span><span class="self">self</span> {
<span class="ident">Size</span> <span class="op">=&gt;</span> <span class="ident">ChunkedState</span>::<span class="ident">read_size</span>(<span class="ident">body</span>, <span class="ident">size</span>),
<span class="ident">SizeLws</span> <span class="op">=&gt;</span> <span class="ident">ChunkedState</span>::<span class="ident">read_size_lws</span>(<span class="ident">body</span>),
<span class="ident">Extension</span> <span class="op">=&gt;</span> <span class="ident">ChunkedState</span>::<span class="ident">read_extension</span>(<span class="ident">body</span>),
<span class="ident">SizeLf</span> <span class="op">=&gt;</span> <span class="ident">ChunkedState</span>::<span class="ident">read_size_lf</span>(<span class="ident">body</span>, <span class="ident">size</span>),
<span class="ident">Body</span> <span class="op">=&gt;</span> <span class="ident">ChunkedState</span>::<span class="ident">read_body</span>(<span class="ident">body</span>, <span class="ident">size</span>, <span class="ident">buf</span>),
<span class="ident">BodyCr</span> <span class="op">=&gt;</span> <span class="ident">ChunkedState</span>::<span class="ident">read_body_cr</span>(<span class="ident">body</span>),
<span class="ident">BodyLf</span> <span class="op">=&gt;</span> <span class="ident">ChunkedState</span>::<span class="ident">read_body_lf</span>(<span class="ident">body</span>),
<span class="ident">EndCr</span> <span class="op">=&gt;</span> <span class="ident">ChunkedState</span>::<span class="ident">read_end_cr</span>(<span class="ident">body</span>),
<span class="ident">EndLf</span> <span class="op">=&gt;</span> <span class="ident">ChunkedState</span>::<span class="ident">read_end_lf</span>(<span class="ident">body</span>),
<span class="ident">End</span> <span class="op">=&gt;</span> <span class="prelude-val">Ok</span>(<span class="ident">Async</span>::<span class="ident">Ready</span>(<span class="ident">ChunkedState</span>::<span class="ident">End</span>)),
}
}
<span class="kw">fn</span> <span class="ident">read_size</span>(<span class="ident">rdr</span>: <span class="kw-2">&amp;</span><span class="kw-2">mut</span> <span class="ident">BytesMut</span>, <span class="ident">size</span>: <span class="kw-2">&amp;</span><span class="kw-2">mut</span> <span class="ident">u64</span>) <span class="op">-&gt;</span> <span class="ident">Poll</span><span class="op">&lt;</span><span class="ident">ChunkedState</span>, <span class="ident">io</span>::<span class="ident">Error</span><span class="op">&gt;</span> {
<span class="kw">let</span> <span class="ident">radix</span> <span class="op">=</span> <span class="number">16</span>;
<span class="kw">match</span> <span class="macro">byte</span><span class="macro">!</span>(<span class="ident">rdr</span>) {
<span class="ident">b</span> @ <span class="string">b&#39;0&#39;</span>...<span class="string">b&#39;9&#39;</span> <span class="op">=&gt;</span> {
<span class="kw-2">*</span><span class="ident">size</span> <span class="op">*=</span> <span class="ident">radix</span>;
<span class="kw-2">*</span><span class="ident">size</span> <span class="op">+=</span> <span class="ident">u64</span>::<span class="ident">from</span>(<span class="ident">b</span> <span class="op">-</span> <span class="string">b&#39;0&#39;</span>);
}
<span class="ident">b</span> @ <span class="string">b&#39;a&#39;</span>...<span class="string">b&#39;f&#39;</span> <span class="op">=&gt;</span> {
<span class="kw-2">*</span><span class="ident">size</span> <span class="op">*=</span> <span class="ident">radix</span>;
<span class="kw-2">*</span><span class="ident">size</span> <span class="op">+=</span> <span class="ident">u64</span>::<span class="ident">from</span>(<span class="ident">b</span> <span class="op">+</span> <span class="number">10</span> <span class="op">-</span> <span class="string">b&#39;a&#39;</span>);
}
<span class="ident">b</span> @ <span class="string">b&#39;A&#39;</span>...<span class="string">b&#39;F&#39;</span> <span class="op">=&gt;</span> {
<span class="kw-2">*</span><span class="ident">size</span> <span class="op">*=</span> <span class="ident">radix</span>;
<span class="kw-2">*</span><span class="ident">size</span> <span class="op">+=</span> <span class="ident">u64</span>::<span class="ident">from</span>(<span class="ident">b</span> <span class="op">+</span> <span class="number">10</span> <span class="op">-</span> <span class="string">b&#39;A&#39;</span>);
}
<span class="string">b&#39;\t&#39;</span> <span class="op">|</span> <span class="string">b&#39; &#39;</span> <span class="op">=&gt;</span> <span class="kw">return</span> <span class="prelude-val">Ok</span>(<span class="ident">Async</span>::<span class="ident">Ready</span>(<span class="ident">ChunkedState</span>::<span class="ident">SizeLws</span>)),
<span class="string">b&#39;;&#39;</span> <span class="op">=&gt;</span> <span class="kw">return</span> <span class="prelude-val">Ok</span>(<span class="ident">Async</span>::<span class="ident">Ready</span>(<span class="ident">ChunkedState</span>::<span class="ident">Extension</span>)),
<span class="string">b&#39;\r&#39;</span> <span class="op">=&gt;</span> <span class="kw">return</span> <span class="prelude-val">Ok</span>(<span class="ident">Async</span>::<span class="ident">Ready</span>(<span class="ident">ChunkedState</span>::<span class="ident">SizeLf</span>)),
<span class="kw">_</span> <span class="op">=&gt;</span> {
<span class="kw">return</span> <span class="prelude-val">Err</span>(<span class="ident">io</span>::<span class="ident">Error</span>::<span class="ident">new</span>(
<span class="ident">io</span>::<span class="ident">ErrorKind</span>::<span class="ident">InvalidInput</span>,
<span class="string">&quot;Invalid chunk size line: Invalid Size&quot;</span>,
));
}
}
<span class="prelude-val">Ok</span>(<span class="ident">Async</span>::<span class="ident">Ready</span>(<span class="ident">ChunkedState</span>::<span class="ident">Size</span>))
}
<span class="kw">fn</span> <span class="ident">read_size_lws</span>(<span class="ident">rdr</span>: <span class="kw-2">&amp;</span><span class="kw-2">mut</span> <span class="ident">BytesMut</span>) <span class="op">-&gt;</span> <span class="ident">Poll</span><span class="op">&lt;</span><span class="ident">ChunkedState</span>, <span class="ident">io</span>::<span class="ident">Error</span><span class="op">&gt;</span> {
<span class="macro">trace</span><span class="macro">!</span>(<span class="string">&quot;read_size_lws&quot;</span>);
<span class="kw">match</span> <span class="macro">byte</span><span class="macro">!</span>(<span class="ident">rdr</span>) {
<span class="comment">// LWS can follow the chunk size, but no more digits can come</span>
<span class="string">b&#39;\t&#39;</span> <span class="op">|</span> <span class="string">b&#39; &#39;</span> <span class="op">=&gt;</span> <span class="prelude-val">Ok</span>(<span class="ident">Async</span>::<span class="ident">Ready</span>(<span class="ident">ChunkedState</span>::<span class="ident">SizeLws</span>)),
<span class="string">b&#39;;&#39;</span> <span class="op">=&gt;</span> <span class="prelude-val">Ok</span>(<span class="ident">Async</span>::<span class="ident">Ready</span>(<span class="ident">ChunkedState</span>::<span class="ident">Extension</span>)),
<span class="string">b&#39;\r&#39;</span> <span class="op">=&gt;</span> <span class="prelude-val">Ok</span>(<span class="ident">Async</span>::<span class="ident">Ready</span>(<span class="ident">ChunkedState</span>::<span class="ident">SizeLf</span>)),
<span class="kw">_</span> <span class="op">=&gt;</span> <span class="prelude-val">Err</span>(<span class="ident">io</span>::<span class="ident">Error</span>::<span class="ident">new</span>(
<span class="ident">io</span>::<span class="ident">ErrorKind</span>::<span class="ident">InvalidInput</span>,
<span class="string">&quot;Invalid chunk size linear white space&quot;</span>,
)),
}
}
<span class="kw">fn</span> <span class="ident">read_extension</span>(<span class="ident">rdr</span>: <span class="kw-2">&amp;</span><span class="kw-2">mut</span> <span class="ident">BytesMut</span>) <span class="op">-&gt;</span> <span class="ident">Poll</span><span class="op">&lt;</span><span class="ident">ChunkedState</span>, <span class="ident">io</span>::<span class="ident">Error</span><span class="op">&gt;</span> {
<span class="kw">match</span> <span class="macro">byte</span><span class="macro">!</span>(<span class="ident">rdr</span>) {
<span class="string">b&#39;\r&#39;</span> <span class="op">=&gt;</span> <span class="prelude-val">Ok</span>(<span class="ident">Async</span>::<span class="ident">Ready</span>(<span class="ident">ChunkedState</span>::<span class="ident">SizeLf</span>)),
<span class="kw">_</span> <span class="op">=&gt;</span> <span class="prelude-val">Ok</span>(<span class="ident">Async</span>::<span class="ident">Ready</span>(<span class="ident">ChunkedState</span>::<span class="ident">Extension</span>)), <span class="comment">// no supported extensions</span>
}
}
<span class="kw">fn</span> <span class="ident">read_size_lf</span>(
<span class="ident">rdr</span>: <span class="kw-2">&amp;</span><span class="kw-2">mut</span> <span class="ident">BytesMut</span>, <span class="ident">size</span>: <span class="kw-2">&amp;</span><span class="kw-2">mut</span> <span class="ident">u64</span>,
) <span class="op">-&gt;</span> <span class="ident">Poll</span><span class="op">&lt;</span><span class="ident">ChunkedState</span>, <span class="ident">io</span>::<span class="ident">Error</span><span class="op">&gt;</span> {
<span class="kw">match</span> <span class="macro">byte</span><span class="macro">!</span>(<span class="ident">rdr</span>) {
<span class="string">b&#39;\n&#39;</span> <span class="kw">if</span> <span class="kw-2">*</span><span class="ident">size</span> <span class="op">&gt;</span> <span class="number">0</span> <span class="op">=&gt;</span> <span class="prelude-val">Ok</span>(<span class="ident">Async</span>::<span class="ident">Ready</span>(<span class="ident">ChunkedState</span>::<span class="ident">Body</span>)),
<span class="string">b&#39;\n&#39;</span> <span class="kw">if</span> <span class="kw-2">*</span><span class="ident">size</span> <span class="op">==</span> <span class="number">0</span> <span class="op">=&gt;</span> <span class="prelude-val">Ok</span>(<span class="ident">Async</span>::<span class="ident">Ready</span>(<span class="ident">ChunkedState</span>::<span class="ident">EndCr</span>)),
<span class="kw">_</span> <span class="op">=&gt;</span> <span class="prelude-val">Err</span>(<span class="ident">io</span>::<span class="ident">Error</span>::<span class="ident">new</span>(
<span class="ident">io</span>::<span class="ident">ErrorKind</span>::<span class="ident">InvalidInput</span>,
<span class="string">&quot;Invalid chunk size LF&quot;</span>,
)),
}
}
<span class="kw">fn</span> <span class="ident">read_body</span>(
<span class="ident">rdr</span>: <span class="kw-2">&amp;</span><span class="kw-2">mut</span> <span class="ident">BytesMut</span>, <span class="ident">rem</span>: <span class="kw-2">&amp;</span><span class="kw-2">mut</span> <span class="ident">u64</span>, <span class="ident">buf</span>: <span class="kw-2">&amp;</span><span class="kw-2">mut</span> <span class="prelude-ty">Option</span><span class="op">&lt;</span><span class="ident">Bytes</span><span class="op">&gt;</span>,
) <span class="op">-&gt;</span> <span class="ident">Poll</span><span class="op">&lt;</span><span class="ident">ChunkedState</span>, <span class="ident">io</span>::<span class="ident">Error</span><span class="op">&gt;</span> {
<span class="macro">trace</span><span class="macro">!</span>(<span class="string">&quot;Chunked read, remaining={:?}&quot;</span>, <span class="ident">rem</span>);
<span class="kw">let</span> <span class="ident">len</span> <span class="op">=</span> <span class="ident">rdr</span>.<span class="ident">len</span>() <span class="kw">as</span> <span class="ident">u64</span>;
<span class="kw">if</span> <span class="ident">len</span> <span class="op">==</span> <span class="number">0</span> {
<span class="prelude-val">Ok</span>(<span class="ident">Async</span>::<span class="ident">Ready</span>(<span class="ident">ChunkedState</span>::<span class="ident">Body</span>))
} <span class="kw">else</span> {
<span class="kw">let</span> <span class="ident">slice</span>;
<span class="kw">if</span> <span class="kw-2">*</span><span class="ident">rem</span> <span class="op">&gt;</span> <span class="ident">len</span> {
<span class="ident">slice</span> <span class="op">=</span> <span class="ident">rdr</span>.<span class="ident">take</span>().<span class="ident">freeze</span>();
<span class="kw-2">*</span><span class="ident">rem</span> <span class="op">-=</span> <span class="ident">len</span>;
} <span class="kw">else</span> {
<span class="ident">slice</span> <span class="op">=</span> <span class="ident">rdr</span>.<span class="ident">split_to</span>(<span class="kw-2">*</span><span class="ident">rem</span> <span class="kw">as</span> <span class="ident">usize</span>).<span class="ident">freeze</span>();
<span class="kw-2">*</span><span class="ident">rem</span> <span class="op">=</span> <span class="number">0</span>;
}
<span class="kw-2">*</span><span class="ident">buf</span> <span class="op">=</span> <span class="prelude-val">Some</span>(<span class="ident">slice</span>);
<span class="kw">if</span> <span class="kw-2">*</span><span class="ident">rem</span> <span class="op">&gt;</span> <span class="number">0</span> {
<span class="prelude-val">Ok</span>(<span class="ident">Async</span>::<span class="ident">Ready</span>(<span class="ident">ChunkedState</span>::<span class="ident">Body</span>))
} <span class="kw">else</span> {
<span class="prelude-val">Ok</span>(<span class="ident">Async</span>::<span class="ident">Ready</span>(<span class="ident">ChunkedState</span>::<span class="ident">BodyCr</span>))
}
}
}
<span class="kw">fn</span> <span class="ident">read_body_cr</span>(<span class="ident">rdr</span>: <span class="kw-2">&amp;</span><span class="kw-2">mut</span> <span class="ident">BytesMut</span>) <span class="op">-&gt;</span> <span class="ident">Poll</span><span class="op">&lt;</span><span class="ident">ChunkedState</span>, <span class="ident">io</span>::<span class="ident">Error</span><span class="op">&gt;</span> {
<span class="kw">match</span> <span class="macro">byte</span><span class="macro">!</span>(<span class="ident">rdr</span>) {
<span class="string">b&#39;\r&#39;</span> <span class="op">=&gt;</span> <span class="prelude-val">Ok</span>(<span class="ident">Async</span>::<span class="ident">Ready</span>(<span class="ident">ChunkedState</span>::<span class="ident">BodyLf</span>)),
<span class="kw">_</span> <span class="op">=&gt;</span> <span class="prelude-val">Err</span>(<span class="ident">io</span>::<span class="ident">Error</span>::<span class="ident">new</span>(
<span class="ident">io</span>::<span class="ident">ErrorKind</span>::<span class="ident">InvalidInput</span>,
<span class="string">&quot;Invalid chunk body CR&quot;</span>,
)),
}
}
<span class="kw">fn</span> <span class="ident">read_body_lf</span>(<span class="ident">rdr</span>: <span class="kw-2">&amp;</span><span class="kw-2">mut</span> <span class="ident">BytesMut</span>) <span class="op">-&gt;</span> <span class="ident">Poll</span><span class="op">&lt;</span><span class="ident">ChunkedState</span>, <span class="ident">io</span>::<span class="ident">Error</span><span class="op">&gt;</span> {
<span class="kw">match</span> <span class="macro">byte</span><span class="macro">!</span>(<span class="ident">rdr</span>) {
<span class="string">b&#39;\n&#39;</span> <span class="op">=&gt;</span> <span class="prelude-val">Ok</span>(<span class="ident">Async</span>::<span class="ident">Ready</span>(<span class="ident">ChunkedState</span>::<span class="ident">Size</span>)),
<span class="kw">_</span> <span class="op">=&gt;</span> <span class="prelude-val">Err</span>(<span class="ident">io</span>::<span class="ident">Error</span>::<span class="ident">new</span>(
<span class="ident">io</span>::<span class="ident">ErrorKind</span>::<span class="ident">InvalidInput</span>,
<span class="string">&quot;Invalid chunk body LF&quot;</span>,
)),
}
}
<span class="kw">fn</span> <span class="ident">read_end_cr</span>(<span class="ident">rdr</span>: <span class="kw-2">&amp;</span><span class="kw-2">mut</span> <span class="ident">BytesMut</span>) <span class="op">-&gt;</span> <span class="ident">Poll</span><span class="op">&lt;</span><span class="ident">ChunkedState</span>, <span class="ident">io</span>::<span class="ident">Error</span><span class="op">&gt;</span> {
<span class="kw">match</span> <span class="macro">byte</span><span class="macro">!</span>(<span class="ident">rdr</span>) {
<span class="string">b&#39;\r&#39;</span> <span class="op">=&gt;</span> <span class="prelude-val">Ok</span>(<span class="ident">Async</span>::<span class="ident">Ready</span>(<span class="ident">ChunkedState</span>::<span class="ident">EndLf</span>)),
<span class="kw">_</span> <span class="op">=&gt;</span> <span class="prelude-val">Err</span>(<span class="ident">io</span>::<span class="ident">Error</span>::<span class="ident">new</span>(
<span class="ident">io</span>::<span class="ident">ErrorKind</span>::<span class="ident">InvalidInput</span>,
<span class="string">&quot;Invalid chunk end CR&quot;</span>,
)),
}
}
<span class="kw">fn</span> <span class="ident">read_end_lf</span>(<span class="ident">rdr</span>: <span class="kw-2">&amp;</span><span class="kw-2">mut</span> <span class="ident">BytesMut</span>) <span class="op">-&gt;</span> <span class="ident">Poll</span><span class="op">&lt;</span><span class="ident">ChunkedState</span>, <span class="ident">io</span>::<span class="ident">Error</span><span class="op">&gt;</span> {
<span class="kw">match</span> <span class="macro">byte</span><span class="macro">!</span>(<span class="ident">rdr</span>) {
<span class="string">b&#39;\n&#39;</span> <span class="op">=&gt;</span> <span class="prelude-val">Ok</span>(<span class="ident">Async</span>::<span class="ident">Ready</span>(<span class="ident">ChunkedState</span>::<span class="ident">End</span>)),
<span class="kw">_</span> <span class="op">=&gt;</span> <span class="prelude-val">Err</span>(<span class="ident">io</span>::<span class="ident">Error</span>::<span class="ident">new</span>(
<span class="ident">io</span>::<span class="ident">ErrorKind</span>::<span class="ident">InvalidInput</span>,
<span class="string">&quot;Invalid chunk end LF&quot;</span>,
)),
}
}
}
</pre>
</section><section id="search" class="content hidden"></section><section class="footer"></section><aside id="help" class="hidden"><div><h1 class="hidden">Help</h1><div class="shortcuts"><h2>Keyboard Shortcuts</h2><dl><dt><kbd>?</kbd></dt><dd>Show this help dialog</dd><dt><kbd>S</kbd></dt><dd>Focus the search field</dd><dt><kbd></kbd></dt><dd>Move up in search results</dd><dt><kbd></kbd></dt><dd>Move down in search results</dd><dt><kbd></kbd></dt><dd>Switch tab</dd><dt><kbd>&#9166;</kbd></dt><dd>Go to active search result</dd><dt><kbd>+</kbd></dt><dd>Expand all sections</dd><dt><kbd>-</kbd></dt><dd>Collapse all sections</dd></dl></div><div class="infos"><h2>Search Tricks</h2><p>Prefix searches with a type followed by a colon (e.g. <code>fn:</code>) to restrict the search to a given type.</p><p>Accepted types are: <code>fn</code>, <code>mod</code>, <code>struct</code>, <code>enum</code>, <code>trait</code>, <code>type</code>, <code>macro</code>, and <code>const</code>.</p><p>Search functions by type signature (e.g. <code>vec -> usize</code> or <code>* -> vec</code>)</p><p>Search multiple things at once by splitting your query with comma (e.g. <code>str,u8</code> or <code>String,struct:Vec,test</code>)</p></div></div></aside><script>window.rootPath = "../../../";window.currentCrate = "actix_web";</script><script src="../../../aliases.js"></script><script src="../../../main.js"></script><script defer src="../../../search-index.js"></script></body></html>