1
0
mirror of https://github.com/actix/actix-website synced 2025-07-01 09:05:10 +02:00

update actix-web api docs

This commit is contained in:
Nikolay Kim
2018-10-10 08:38:33 -07:00
parent 29977f4930
commit bf8faa455d
2298 changed files with 129471 additions and 17241 deletions

View File

@ -442,12 +442,32 @@
<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>
</pre><pre class="rust ">
<span class="kw">use</span> <span class="ident">std</span>::<span class="ident">collections</span>::<span class="ident">VecDeque</span>;
<span class="kw">use</span> <span class="ident">std</span>::<span class="ident">io</span>::{<span class="ident">Read</span>, <span class="ident">Write</span>};
<span class="kw">use</span> <span class="ident">std</span>::<span class="ident">net</span>::<span class="ident">SocketAddr</span>;
<span class="kw">use</span> <span class="ident">std</span>::<span class="ident">rc</span>::<span class="ident">Rc</span>;
<span class="kw">use</span> <span class="ident">std</span>::<span class="ident">time</span>::{<span class="ident">Duration</span>, <span class="ident">Instant</span>};
<span class="kw">use</span> <span class="ident">std</span>::<span class="ident">time</span>::<span class="ident">Instant</span>;
<span class="kw">use</span> <span class="ident">std</span>::{<span class="ident">cmp</span>, <span class="ident">io</span>, <span class="ident">mem</span>};
<span class="kw">use</span> <span class="ident">bytes</span>::{<span class="ident">Buf</span>, <span class="ident">Bytes</span>};
@ -459,19 +479,21 @@
<span class="kw">use</span> <span class="ident">tokio_timer</span>::<span class="ident">Delay</span>;
<span class="kw">use</span> <span class="ident">error</span>::{<span class="ident">Error</span>, <span class="ident">PayloadError</span>};
<span class="kw">use</span> <span class="ident">extensions</span>::<span class="ident">Extensions</span>;
<span class="kw">use</span> <span class="ident">http</span>::{<span class="ident">StatusCode</span>, <span class="ident">Version</span>};
<span class="kw">use</span> <span class="ident">payload</span>::{<span class="ident">Payload</span>, <span class="ident">PayloadStatus</span>, <span class="ident">PayloadWriter</span>};
<span class="kw">use</span> <span class="ident">uri</span>::<span class="ident">Url</span>;
<span class="kw">use</span> <span class="kw">super</span>::<span class="ident">error</span>::<span class="ident">ServerError</span>;
<span class="kw">use</span> <span class="kw">super</span>::<span class="ident">error</span>::{<span class="ident">HttpDispatchError</span>, <span class="ident">ServerError</span>};
<span class="kw">use</span> <span class="kw">super</span>::<span class="ident">h2writer</span>::<span class="ident">H2Writer</span>;
<span class="kw">use</span> <span class="kw">super</span>::<span class="ident">input</span>::<span class="ident">PayloadType</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="kw">super</span>::{<span class="ident">HttpHandler</span>, <span class="ident">HttpHandlerTask</span>, <span class="ident">Writer</span>};
<span class="kw">use</span> <span class="kw">super</span>::<span class="ident">settings</span>::<span class="ident">ServiceConfig</span>;
<span class="kw">use</span> <span class="kw">super</span>::{<span class="ident">HttpHandler</span>, <span class="ident">HttpHandlerTask</span>, <span class="ident">IoStream</span>, <span class="ident">Writer</span>};
<span class="macro">bitflags</span><span class="macro">!</span> {
<span class="kw">struct</span> <span class="ident">Flags</span>: <span class="ident">u8</span> {
<span class="kw">const</span> <span class="ident">DISCONNECTED</span> <span class="op">=</span> <span class="number">0b0000_0010</span>;
<span class="kw">const</span> <span class="ident">DISCONNECTED</span> <span class="op">=</span> <span class="number">0b0000_0001</span>;
<span class="kw">const</span> <span class="ident">SHUTDOWN</span> <span class="op">=</span> <span class="number">0b0000_0010</span>;
}
}
@ -482,11 +504,13 @@
<span class="ident">H</span>: <span class="ident">HttpHandler</span> <span class="op">+</span> <span class="lifetime">&#39;static</span>,
{
<span class="ident">flags</span>: <span class="ident">Flags</span>,
<span class="ident">settings</span>: <span class="ident">Rc</span><span class="op">&lt;</span><span class="ident">WorkerSettings</span><span class="op">&lt;</span><span class="ident">H</span><span class="op">&gt;&gt;</span>,
<span class="ident">settings</span>: <span class="ident">ServiceConfig</span><span class="op">&lt;</span><span class="ident">H</span><span class="op">&gt;</span>,
<span class="ident">addr</span>: <span class="prelude-ty">Option</span><span class="op">&lt;</span><span class="ident">SocketAddr</span><span class="op">&gt;</span>,
<span class="ident">state</span>: <span class="ident">State</span><span class="op">&lt;</span><span class="ident">IoWrapper</span><span class="op">&lt;</span><span class="ident">T</span><span class="op">&gt;&gt;</span>,
<span class="ident">tasks</span>: <span class="ident">VecDeque</span><span class="op">&lt;</span><span class="ident">Entry</span><span class="op">&lt;</span><span class="ident">H</span><span class="op">&gt;&gt;</span>,
<span class="ident">keepalive_timer</span>: <span class="prelude-ty">Option</span><span class="op">&lt;</span><span class="ident">Delay</span><span class="op">&gt;</span>,
<span class="ident">extensions</span>: <span class="prelude-ty">Option</span><span class="op">&lt;</span><span class="ident">Rc</span><span class="op">&lt;</span><span class="ident">Extensions</span><span class="op">&gt;&gt;</span>,
<span class="ident">ka_expire</span>: <span class="ident">Instant</span>,
<span class="ident">ka_timer</span>: <span class="prelude-ty">Option</span><span class="op">&lt;</span><span class="ident">Delay</span><span class="op">&gt;</span>,
}
<span class="kw">enum</span> <span class="ident">State</span><span class="op">&lt;</span><span class="ident">T</span>: <span class="ident">AsyncRead</span> <span class="op">+</span> <span class="ident">AsyncWrite</span><span class="op">&gt;</span> {
@ -497,12 +521,24 @@
<span class="kw">impl</span><span class="op">&lt;</span><span class="ident">T</span>, <span class="ident">H</span><span class="op">&gt;</span> <span class="ident">Http2</span><span class="op">&lt;</span><span class="ident">T</span>, <span class="ident">H</span><span class="op">&gt;</span>
<span class="kw">where</span>
<span class="ident">T</span>: <span class="ident">AsyncRead</span> <span class="op">+</span> <span class="ident">AsyncWrite</span> <span class="op">+</span> <span class="lifetime">&#39;static</span>,
<span class="ident">T</span>: <span class="ident">IoStream</span> <span class="op">+</span> <span class="lifetime">&#39;static</span>,
<span class="ident">H</span>: <span class="ident">HttpHandler</span> <span class="op">+</span> <span class="lifetime">&#39;static</span>,
{
<span class="kw">pub</span> <span class="kw">fn</span> <span class="ident">new</span>(
<span class="ident">settings</span>: <span class="ident">Rc</span><span class="op">&lt;</span><span class="ident">WorkerSettings</span><span class="op">&lt;</span><span class="ident">H</span><span class="op">&gt;&gt;</span>, <span class="ident">io</span>: <span class="ident">T</span>, <span class="ident">addr</span>: <span class="prelude-ty">Option</span><span class="op">&lt;</span><span class="ident">SocketAddr</span><span class="op">&gt;</span>, <span class="ident">buf</span>: <span class="ident">Bytes</span>,
<span class="ident">settings</span>: <span class="ident">ServiceConfig</span><span class="op">&lt;</span><span class="ident">H</span><span class="op">&gt;</span>, <span class="ident">io</span>: <span class="ident">T</span>, <span class="ident">buf</span>: <span class="ident">Bytes</span>, <span class="ident">keepalive_timer</span>: <span class="prelude-ty">Option</span><span class="op">&lt;</span><span class="ident">Delay</span><span class="op">&gt;</span>,
) <span class="op">-&gt;</span> <span class="self">Self</span> {
<span class="kw">let</span> <span class="ident">addr</span> <span class="op">=</span> <span class="ident">io</span>.<span class="ident">peer_addr</span>();
<span class="kw">let</span> <span class="ident">extensions</span> <span class="op">=</span> <span class="ident">io</span>.<span class="ident">extensions</span>();
<span class="comment">// keep-alive timeout</span>
<span class="kw">let</span> (<span class="ident">ka_expire</span>, <span class="ident">ka_timer</span>) <span class="op">=</span> <span class="kw">if</span> <span class="kw">let</span> <span class="prelude-val">Some</span>(<span class="ident">delay</span>) <span class="op">=</span> <span class="ident">keepalive_timer</span> {
(<span class="ident">delay</span>.<span class="ident">deadline</span>(), <span class="prelude-val">Some</span>(<span class="ident">delay</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">delay</span>) <span class="op">=</span> <span class="ident">settings</span>.<span class="ident">keep_alive_timer</span>() {
(<span class="ident">delay</span>.<span class="ident">deadline</span>(), <span class="prelude-val">Some</span>(<span class="ident">delay</span>))
} <span class="kw">else</span> {
(<span class="ident">settings</span>.<span class="ident">now</span>(), <span class="prelude-val">None</span>)
};
<span class="ident">Http2</span> {
<span class="ident">flags</span>: <span class="ident">Flags</span>::<span class="ident">empty</span>(),
<span class="ident">tasks</span>: <span class="ident">VecDeque</span>::<span class="ident">new</span>(),
@ -510,84 +546,84 @@
<span class="ident">unread</span>: <span class="kw">if</span> <span class="ident">buf</span>.<span class="ident">is_empty</span>() { <span class="prelude-val">None</span> } <span class="kw">else</span> { <span class="prelude-val">Some</span>(<span class="ident">buf</span>) },
<span class="ident">inner</span>: <span class="ident">io</span>,
})),
<span class="ident">keepalive_timer</span>: <span class="prelude-val">None</span>,
<span class="ident">addr</span>,
<span class="ident">settings</span>,
<span class="ident">extensions</span>,
<span class="ident">ka_expire</span>,
<span class="ident">ka_timer</span>,
}
}
<span class="kw">pub</span>(<span class="kw">crate</span>) <span class="kw">fn</span> <span class="ident">shutdown</span>(<span class="kw-2">&amp;</span><span class="kw-2">mut</span> <span class="self">self</span>) {
<span class="self">self</span>.<span class="ident">state</span> <span class="op">=</span> <span class="ident">State</span>::<span class="ident">Empty</span>;
<span class="self">self</span>.<span class="ident">tasks</span>.<span class="ident">clear</span>();
<span class="self">self</span>.<span class="ident">keepalive_timer</span>.<span class="ident">take</span>();
}
<span class="kw">pub</span> <span class="kw">fn</span> <span class="ident">poll</span>(<span class="kw-2">&amp;</span><span class="kw-2">mut</span> <span class="self">self</span>) <span class="op">-&gt;</span> <span class="ident">Poll</span><span class="op">&lt;</span>(), <span class="ident">HttpDispatchError</span><span class="op">&gt;</span> {
<span class="self">self</span>.<span class="ident">poll_keepalive</span>()<span class="question-mark">?</span>;
<span class="kw">pub</span> <span class="kw">fn</span> <span class="ident">settings</span>(<span class="kw-2">&amp;</span><span class="self">self</span>) <span class="op">-&gt;</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="self">self</span>.<span class="ident">settings</span>.<span class="ident">as_ref</span>()
}
<span class="kw">pub</span> <span class="kw">fn</span> <span class="ident">poll</span>(<span class="kw-2">&amp;</span><span class="kw-2">mut</span> <span class="self">self</span>) <span class="op">-&gt;</span> <span class="ident">Poll</span><span class="op">&lt;</span>(), ()<span class="op">&gt;</span> {
<span class="comment">// server</span>
<span class="kw">if</span> <span class="kw">let</span> <span class="ident">State</span>::<span class="ident">Connection</span>(<span class="kw-2">ref</span> <span class="kw-2">mut</span> <span class="ident">conn</span>) <span class="op">=</span> <span class="self">self</span>.<span class="ident">state</span> {
<span class="comment">// keep-alive timer</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="kw-2">mut</span> <span class="ident">timeout</span>) <span class="op">=</span> <span class="self">self</span>.<span class="ident">keepalive_timer</span> {
<span class="kw">match</span> <span class="ident">timeout</span>.<span class="ident">poll</span>() {
<span class="prelude-val">Ok</span>(<span class="ident">Async</span>::<span class="ident">Ready</span>(<span class="kw">_</span>)) <span class="op">=&gt;</span> {
<span class="macro">trace</span><span class="macro">!</span>(<span class="string">&quot;Keep-alive timeout, close connection&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">Ok</span>(<span class="ident">Async</span>::<span class="ident">NotReady</span>) <span class="op">=&gt;</span> (),
<span class="prelude-val">Err</span>(<span class="kw">_</span>) <span class="op">=&gt;</span> <span class="macro">unreachable</span><span class="macro">!</span>(),
}
}
<span class="kw">loop</span> {
<span class="comment">// shutdown connection</span>
<span class="kw">if</span> <span class="self">self</span>.<span class="ident">flags</span>.<span class="ident">contains</span>(<span class="ident">Flags</span>::<span class="ident">SHUTDOWN</span>) {
<span class="kw">return</span> <span class="ident">conn</span>.<span class="ident">poll_close</span>().<span class="ident">map_err</span>(<span class="op">|</span><span class="ident">e</span><span class="op">|</span> <span class="ident">e</span>.<span class="ident">into</span>());
}
<span class="kw">let</span> <span class="kw-2">mut</span> <span class="ident">not_ready</span> <span class="op">=</span> <span class="bool-val">true</span>;
<span class="kw">let</span> <span class="ident">disconnected</span> <span class="op">=</span> <span class="self">self</span>.<span class="ident">flags</span>.<span class="ident">contains</span>(<span class="ident">Flags</span>::<span class="ident">DISCONNECTED</span>);
<span class="comment">// check in-flight connections</span>
<span class="kw">for</span> <span class="ident">item</span> <span class="kw">in</span> <span class="kw-2">&amp;</span><span class="kw-2">mut</span> <span class="self">self</span>.<span class="ident">tasks</span> {
<span class="comment">// read payload</span>
<span class="ident">item</span>.<span class="ident">poll_payload</span>();
<span class="kw">if</span> <span class="op">!</span><span class="ident">disconnected</span> {
<span class="ident">item</span>.<span class="ident">poll_payload</span>();
}
<span class="kw">if</span> <span class="op">!</span><span class="ident">item</span>.<span class="ident">flags</span>.<span class="ident">contains</span>(<span class="ident">EntryFlags</span>::<span class="ident">EOF</span>) {
<span class="kw">let</span> <span class="ident">retry</span> <span class="op">=</span> <span class="ident">item</span>.<span class="ident">payload</span>.<span class="ident">need_read</span>() <span class="op">==</span> <span class="ident">PayloadStatus</span>::<span class="ident">Read</span>;
<span class="kw">loop</span> {
<span class="kw">match</span> <span class="ident">item</span>.<span class="ident">task</span>.<span class="ident">poll_io</span>(<span class="kw-2">&amp;</span><span class="kw-2">mut</span> <span class="ident">item</span>.<span class="ident">stream</span>) {
<span class="prelude-val">Ok</span>(<span class="ident">Async</span>::<span class="ident">Ready</span>(<span class="ident">ready</span>)) <span class="op">=&gt;</span> {
<span class="kw">if</span> <span class="ident">ready</span> {
<span class="kw">if</span> <span class="ident">disconnected</span> {
<span class="ident">item</span>.<span class="ident">flags</span>.<span class="ident">insert</span>(<span class="ident">EntryFlags</span>::<span class="ident">EOF</span>);
} <span class="kw">else</span> {
<span class="kw">let</span> <span class="ident">retry</span> <span class="op">=</span> <span class="ident">item</span>.<span class="ident">payload</span>.<span class="ident">need_read</span>() <span class="op">==</span> <span class="ident">PayloadStatus</span>::<span class="ident">Read</span>;
<span class="kw">loop</span> {
<span class="kw">match</span> <span class="ident">item</span>.<span class="ident">task</span>.<span class="ident">poll_io</span>(<span class="kw-2">&amp;</span><span class="kw-2">mut</span> <span class="ident">item</span>.<span class="ident">stream</span>) {
<span class="prelude-val">Ok</span>(<span class="ident">Async</span>::<span class="ident">Ready</span>(<span class="ident">ready</span>)) <span class="op">=&gt;</span> {
<span class="kw">if</span> <span class="ident">ready</span> {
<span class="ident">item</span>.<span class="ident">flags</span>.<span class="ident">insert</span>(
<span class="ident">EntryFlags</span>::<span class="ident">EOF</span> <span class="op">|</span> <span class="ident">EntryFlags</span>::<span class="ident">FINISHED</span>,
);
} <span class="kw">else</span> {
<span class="ident">item</span>.<span class="ident">flags</span>.<span class="ident">insert</span>(<span class="ident">EntryFlags</span>::<span class="ident">EOF</span>);
}
<span class="ident">not_ready</span> <span class="op">=</span> <span class="bool-val">false</span>;
}
<span class="prelude-val">Ok</span>(<span class="ident">Async</span>::<span class="ident">NotReady</span>) <span class="op">=&gt;</span> {
<span class="kw">if</span> <span class="ident">item</span>.<span class="ident">payload</span>.<span class="ident">need_read</span>()
<span class="op">==</span> <span class="ident">PayloadStatus</span>::<span class="ident">Read</span>
<span class="op">&amp;&amp;</span> <span class="op">!</span><span class="ident">retry</span>
{
<span class="kw">continue</span>;
}
}
<span class="prelude-val">Err</span>(<span class="ident">err</span>) <span class="op">=&gt;</span> {
<span class="macro">error</span><span class="macro">!</span>(<span class="string">&quot;Unhandled error: {}&quot;</span>, <span class="ident">err</span>);
<span class="ident">item</span>.<span class="ident">flags</span>.<span class="ident">insert</span>(
<span class="ident">EntryFlags</span>::<span class="ident">EOF</span> <span class="op">|</span> <span class="ident">EntryFlags</span>::<span class="ident">FINISHED</span>,
<span class="ident">EntryFlags</span>::<span class="ident">EOF</span>
<span class="op">|</span> <span class="ident">EntryFlags</span>::<span class="ident">ERROR</span>
<span class="op">|</span> <span class="ident">EntryFlags</span>::<span class="ident">WRITE_DONE</span>,
);
} <span class="kw">else</span> {
<span class="ident">item</span>.<span class="ident">flags</span>.<span class="ident">insert</span>(<span class="ident">EntryFlags</span>::<span class="ident">EOF</span>);
}
<span class="ident">not_ready</span> <span class="op">=</span> <span class="bool-val">false</span>;
}
<span class="prelude-val">Ok</span>(<span class="ident">Async</span>::<span class="ident">NotReady</span>) <span class="op">=&gt;</span> {
<span class="kw">if</span> <span class="ident">item</span>.<span class="ident">payload</span>.<span class="ident">need_read</span>() <span class="op">==</span> <span class="ident">PayloadStatus</span>::<span class="ident">Read</span>
<span class="op">&amp;&amp;</span> <span class="op">!</span><span class="ident">retry</span>
{
<span class="kw">continue</span>;
<span class="ident">item</span>.<span class="ident">stream</span>.<span class="ident">reset</span>(<span class="ident">Reason</span>::<span class="ident">INTERNAL_ERROR</span>);
}
}
<span class="prelude-val">Err</span>(<span class="ident">err</span>) <span class="op">=&gt;</span> {
<span class="macro">error</span><span class="macro">!</span>(<span class="string">&quot;Unhandled error: {}&quot;</span>, <span class="ident">err</span>);
<span class="ident">item</span>.<span class="ident">flags</span>.<span class="ident">insert</span>(
<span class="ident">EntryFlags</span>::<span class="ident">EOF</span>
<span class="op">|</span> <span class="ident">EntryFlags</span>::<span class="ident">ERROR</span>
<span class="op">|</span> <span class="ident">EntryFlags</span>::<span class="ident">WRITE_DONE</span>,
);
<span class="ident">item</span>.<span class="ident">stream</span>.<span class="ident">reset</span>(<span class="ident">Reason</span>::<span class="ident">INTERNAL_ERROR</span>);
}
<span class="kw">break</span>;
}
<span class="kw">break</span>;
}
} <span class="kw">else</span> <span class="kw">if</span> <span class="op">!</span><span class="ident">item</span>.<span class="ident">flags</span>.<span class="ident">contains</span>(<span class="ident">EntryFlags</span>::<span class="ident">FINISHED</span>) {
}
<span class="kw">if</span> <span class="ident">item</span>.<span class="ident">flags</span>.<span class="ident">contains</span>(<span class="ident">EntryFlags</span>::<span class="ident">EOF</span>)
<span class="op">&amp;&amp;</span> <span class="op">!</span><span class="ident">item</span>.<span class="ident">flags</span>.<span class="ident">contains</span>(<span class="ident">EntryFlags</span>::<span class="ident">FINISHED</span>)
{
<span class="kw">match</span> <span class="ident">item</span>.<span class="ident">task</span>.<span class="ident">poll_completed</span>() {
<span class="prelude-val">Ok</span>(<span class="ident">Async</span>::<span class="ident">NotReady</span>) <span class="op">=&gt;</span> (),
<span class="prelude-val">Ok</span>(<span class="ident">Async</span>::<span class="ident">Ready</span>(<span class="kw">_</span>)) <span class="op">=&gt;</span> {
<span class="ident">not_ready</span> <span class="op">=</span> <span class="bool-val">false</span>;
<span class="ident">item</span>.<span class="ident">flags</span>.<span class="ident">insert</span>(<span class="ident">EntryFlags</span>::<span class="ident">FINISHED</span>);
<span class="ident">item</span>.<span class="ident">flags</span>.<span class="ident">insert</span>(
<span class="ident">EntryFlags</span>::<span class="ident">FINISHED</span> <span class="op">|</span> <span class="ident">EntryFlags</span>::<span class="ident">WRITE_DONE</span>,
);
}
<span class="prelude-val">Err</span>(<span class="ident">err</span>) <span class="op">=&gt;</span> {
<span class="ident">item</span>.<span class="ident">flags</span>.<span class="ident">insert</span>(
@ -602,6 +638,7 @@
<span class="kw">if</span> <span class="ident">item</span>.<span class="ident">flags</span>.<span class="ident">contains</span>(<span class="ident">EntryFlags</span>::<span class="ident">FINISHED</span>)
<span class="op">&amp;&amp;</span> <span class="op">!</span><span class="ident">item</span>.<span class="ident">flags</span>.<span class="ident">contains</span>(<span class="ident">EntryFlags</span>::<span class="ident">WRITE_DONE</span>)
<span class="op">&amp;&amp;</span> <span class="op">!</span><span class="ident">disconnected</span>
{
<span class="kw">match</span> <span class="ident">item</span>.<span class="ident">stream</span>.<span class="ident">poll_completed</span>(<span class="bool-val">false</span>) {
<span class="prelude-val">Ok</span>(<span class="ident">Async</span>::<span class="ident">NotReady</span>) <span class="op">=&gt;</span> (),
@ -609,7 +646,7 @@
<span class="ident">not_ready</span> <span class="op">=</span> <span class="bool-val">false</span>;
<span class="ident">item</span>.<span class="ident">flags</span>.<span class="ident">insert</span>(<span class="ident">EntryFlags</span>::<span class="ident">WRITE_DONE</span>);
}
<span class="prelude-val">Err</span>(<span class="ident">_err</span>) <span class="op">=&gt;</span> {
<span class="prelude-val">Err</span>(<span class="kw">_</span>) <span class="op">=&gt;</span> {
<span class="ident">item</span>.<span class="ident">flags</span>.<span class="ident">insert</span>(<span class="ident">EntryFlags</span>::<span class="ident">ERROR</span>);
}
}
@ -618,7 +655,7 @@
<span class="comment">// cleanup finished tasks</span>
<span class="kw">while</span> <span class="op">!</span><span class="self">self</span>.<span class="ident">tasks</span>.<span class="ident">is_empty</span>() {
<span class="kw">if</span> <span class="self">self</span>.<span class="ident">tasks</span>[<span class="number">0</span>].<span class="ident">flags</span>.<span class="ident">contains</span>(<span class="ident">EntryFlags</span>::<span class="ident">EOF</span>)
<span class="kw">if</span> <span class="self">self</span>.<span class="ident">tasks</span>[<span class="number">0</span>].<span class="ident">flags</span>.<span class="ident">contains</span>(<span class="ident">EntryFlags</span>::<span class="ident">FINISHED</span>)
<span class="op">&amp;&amp;</span> <span class="self">self</span>.<span class="ident">tasks</span>[<span class="number">0</span>].<span class="ident">flags</span>.<span class="ident">contains</span>(<span class="ident">EntryFlags</span>::<span class="ident">WRITE_DONE</span>)
<span class="op">||</span> <span class="self">self</span>.<span class="ident">tasks</span>[<span class="number">0</span>].<span class="ident">flags</span>.<span class="ident">contains</span>(<span class="ident">EntryFlags</span>::<span class="ident">ERROR</span>)
{
@ -642,50 +679,30 @@
<span class="ident">not_ready</span> <span class="op">=</span> <span class="bool-val">false</span>;
<span class="kw">let</span> (<span class="ident">parts</span>, <span class="ident">body</span>) <span class="op">=</span> <span class="ident">req</span>.<span class="ident">into_parts</span>();
<span class="comment">// stop keepalive timer</span>
<span class="self">self</span>.<span class="ident">keepalive_timer</span>.<span class="ident">take</span>();
<span class="comment">// update keep-alive expire</span>
<span class="kw">if</span> <span class="self">self</span>.<span class="ident">ka_timer</span>.<span class="ident">is_some</span>() {
<span class="kw">if</span> <span class="kw">let</span> <span class="prelude-val">Some</span>(<span class="ident">expire</span>) <span class="op">=</span> <span class="self">self</span>.<span class="ident">settings</span>.<span class="ident">keep_alive_expire</span>() {
<span class="self">self</span>.<span class="ident">ka_expire</span> <span class="op">=</span> <span class="ident">expire</span>;
}
}
<span class="self">self</span>.<span class="ident">tasks</span>.<span class="ident">push_back</span>(<span class="ident">Entry</span>::<span class="ident">new</span>(
<span class="ident">parts</span>,
<span class="ident">body</span>,
<span class="ident">resp</span>,
<span class="self">self</span>.<span class="ident">addr</span>,
<span class="kw-2">&amp;</span><span class="self">self</span>.<span class="ident">settings</span>,
<span class="self">self</span>.<span class="ident">settings</span>.<span class="ident">clone</span>(),
<span class="self">self</span>.<span class="ident">extensions</span>.<span class="ident">clone</span>(),
));
}
<span class="prelude-val">Ok</span>(<span class="ident">Async</span>::<span class="ident">NotReady</span>) <span class="op">=&gt;</span> {
<span class="comment">// start keep-alive timer</span>
<span class="kw">if</span> <span class="self">self</span>.<span class="ident">tasks</span>.<span class="ident">is_empty</span>() {
<span class="kw">if</span> <span class="self">self</span>.<span class="ident">settings</span>.<span class="ident">keep_alive_enabled</span>() {
<span class="kw">let</span> <span class="ident">keep_alive</span> <span class="op">=</span> <span class="self">self</span>.<span class="ident">settings</span>.<span class="ident">keep_alive</span>();
<span class="kw">if</span> <span class="ident">keep_alive</span> <span class="op">&gt;</span> <span class="number">0</span> <span class="op">&amp;&amp;</span> <span class="self">self</span>.<span class="ident">keepalive_timer</span>.<span class="ident">is_none</span>() {
<span class="macro">trace</span><span class="macro">!</span>(<span class="string">&quot;Start keep-alive timer&quot;</span>);
<span class="kw">let</span> <span class="kw-2">mut</span> <span class="ident">timeout</span> <span class="op">=</span> <span class="ident">Delay</span>::<span class="ident">new</span>(
<span class="ident">Instant</span>::<span class="ident">now</span>()
<span class="op">+</span> <span class="ident">Duration</span>::<span class="ident">new</span>(<span class="ident">keep_alive</span>, <span class="number">0</span>),
);
<span class="comment">// register timeout</span>
<span class="kw">let</span> <span class="kw">_</span> <span class="op">=</span> <span class="ident">timeout</span>.<span class="ident">poll</span>();
<span class="self">self</span>.<span class="ident">keepalive_timer</span> <span class="op">=</span> <span class="prelude-val">Some</span>(<span class="ident">timeout</span>);
}
} <span class="kw">else</span> {
<span class="comment">// keep-alive disable, drop connection</span>
<span class="kw">return</span> <span class="ident">conn</span>.<span class="ident">poll_close</span>().<span class="ident">map_err</span>(<span class="op">|</span><span class="ident">e</span><span class="op">|</span> {
<span class="macro">error</span><span class="macro">!</span>(<span class="string">&quot;Error during connection close: {}&quot;</span>, <span class="ident">e</span>)
});
}
} <span class="kw">else</span> {
<span class="comment">// keep-alive unset, rely on operating system</span>
<span class="kw">return</span> <span class="prelude-val">Ok</span>(<span class="ident">Async</span>::<span class="ident">NotReady</span>);
}
}
<span class="prelude-val">Ok</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="ident">Async</span>::<span class="ident">NotReady</span>),
<span class="prelude-val">Err</span>(<span class="ident">err</span>) <span class="op">=&gt;</span> {
<span class="macro">trace</span><span class="macro">!</span>(<span class="string">&quot;Connection error: {}&quot;</span>, <span class="ident">err</span>);
<span class="self">self</span>.<span class="ident">flags</span>.<span class="ident">insert</span>(<span class="ident">Flags</span>::<span class="ident">DISCONNECTED</span>);
<span class="self">self</span>.<span class="ident">flags</span>.<span class="ident">insert</span>(<span class="ident">Flags</span>::<span class="ident">SHUTDOWN</span>);
<span class="kw">for</span> <span class="ident">entry</span> <span class="kw">in</span> <span class="kw-2">&amp;</span><span class="kw-2">mut</span> <span class="self">self</span>.<span class="ident">tasks</span> {
<span class="ident">entry</span>.<span class="ident">task</span>.<span class="ident">disconnected</span>()
}
<span class="self">self</span>.<span class="ident">keepalive_timer</span>.<span class="ident">take</span>();
<span class="kw">continue</span>;
}
}
}
@ -693,9 +710,7 @@
<span class="kw">if</span> <span class="ident">not_ready</span> {
<span class="kw">if</span> <span class="self">self</span>.<span class="ident">tasks</span>.<span class="ident">is_empty</span>() <span class="op">&amp;&amp;</span> <span class="self">self</span>.<span class="ident">flags</span>.<span class="ident">contains</span>(<span class="ident">Flags</span>::<span class="ident">DISCONNECTED</span>)
{
<span class="kw">return</span> <span class="ident">conn</span>
.<span class="ident">poll_close</span>()
.<span class="ident">map_err</span>(<span class="op">|</span><span class="ident">e</span><span class="op">|</span> <span class="macro">error</span><span class="macro">!</span>(<span class="string">&quot;Error during connection close: {}&quot;</span>, <span class="ident">e</span>));
<span class="kw">return</span> <span class="ident">conn</span>.<span class="ident">poll_close</span>().<span class="ident">map_err</span>(<span class="op">|</span><span class="ident">e</span><span class="op">|</span> <span class="ident">e</span>.<span class="ident">into</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>);
}
@ -710,7 +725,7 @@
<span class="prelude-val">Ok</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="ident">Async</span>::<span class="ident">NotReady</span>),
<span class="prelude-val">Err</span>(<span class="ident">err</span>) <span class="op">=&gt;</span> {
<span class="macro">trace</span><span class="macro">!</span>(<span class="string">&quot;Error handling connection: {}&quot;</span>, <span class="ident">err</span>);
<span class="kw">return</span> <span class="prelude-val">Err</span>(());
<span class="kw">return</span> <span class="prelude-val">Err</span>(<span class="ident">err</span>.<span class="ident">into</span>());
}
}
} <span class="kw">else</span> {
@ -719,6 +734,37 @@
<span class="self">self</span>.<span class="ident">poll</span>()
}
<span class="doccomment">/// keep-alive timer. returns `true` is keep-alive, otherwise drop</span>
<span class="kw">fn</span> <span class="ident">poll_keepalive</span>(<span class="kw-2">&amp;</span><span class="kw-2">mut</span> <span class="self">self</span>) <span class="op">-&gt;</span> <span class="prelude-ty">Result</span><span class="op">&lt;</span>(), <span class="ident">HttpDispatchError</span><span class="op">&gt;</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="kw-2">mut</span> <span class="ident">timer</span>) <span class="op">=</span> <span class="self">self</span>.<span class="ident">ka_timer</span> {
<span class="kw">match</span> <span class="ident">timer</span>.<span class="ident">poll</span>() {
<span class="prelude-val">Ok</span>(<span class="ident">Async</span>::<span class="ident">Ready</span>(<span class="kw">_</span>)) <span class="op">=&gt;</span> {
<span class="comment">// if we get timer during shutdown, just drop connection</span>
<span class="kw">if</span> <span class="self">self</span>.<span class="ident">flags</span>.<span class="ident">contains</span>(<span class="ident">Flags</span>::<span class="ident">SHUTDOWN</span>) {
<span class="kw">return</span> <span class="prelude-val">Err</span>(<span class="ident">HttpDispatchError</span>::<span class="ident">ShutdownTimeout</span>);
}
<span class="kw">if</span> <span class="ident">timer</span>.<span class="ident">deadline</span>() <span class="op">&gt;=</span> <span class="self">self</span>.<span class="ident">ka_expire</span> {
<span class="comment">// check for any outstanding request handling</span>
<span class="kw">if</span> <span class="self">self</span>.<span class="ident">tasks</span>.<span class="ident">is_empty</span>() {
<span class="kw">return</span> <span class="prelude-val">Err</span>(<span class="ident">HttpDispatchError</span>::<span class="ident">ShutdownTimeout</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">dl</span>) <span class="op">=</span> <span class="self">self</span>.<span class="ident">settings</span>.<span class="ident">keep_alive_expire</span>() {
<span class="ident">timer</span>.<span class="ident">reset</span>(<span class="ident">dl</span>)
}
} <span class="kw">else</span> {
<span class="ident">timer</span>.<span class="ident">reset</span>(<span class="self">self</span>.<span class="ident">ka_expire</span>)
}
}
<span class="prelude-val">Ok</span>(<span class="ident">Async</span>::<span class="ident">NotReady</span>) <span class="op">=&gt;</span> (),
<span class="prelude-val">Err</span>(<span class="ident">e</span>) <span class="op">=&gt;</span> {
<span class="macro">error</span><span class="macro">!</span>(<span class="string">&quot;Timer error {:?}&quot;</span>, <span class="ident">e</span>);
<span class="kw">return</span> <span class="prelude-val">Err</span>(<span class="ident">HttpDispatchError</span>::<span class="ident">Unknown</span>);
}
}
}
<span class="prelude-val">Ok</span>(())
}
}
<span class="macro">bitflags</span><span class="macro">!</span> {
@ -768,7 +814,8 @@
<span class="kw">impl</span><span class="op">&lt;</span><span class="ident">H</span>: <span class="ident">HttpHandler</span> <span class="op">+</span> <span class="lifetime">&#39;static</span><span class="op">&gt;</span> <span class="ident">Entry</span><span class="op">&lt;</span><span class="ident">H</span><span class="op">&gt;</span> {
<span class="kw">fn</span> <span class="ident">new</span>(
<span class="ident">parts</span>: <span class="ident">Parts</span>, <span class="ident">recv</span>: <span class="ident">RecvStream</span>, <span class="ident">resp</span>: <span class="ident">SendResponse</span><span class="op">&lt;</span><span class="ident">Bytes</span><span class="op">&gt;</span>,
<span class="ident">addr</span>: <span class="prelude-ty">Option</span><span class="op">&lt;</span><span class="ident">SocketAddr</span><span class="op">&gt;</span>, <span class="ident">settings</span>: <span class="kw-2">&amp;</span><span class="ident">Rc</span><span class="op">&lt;</span><span class="ident">WorkerSettings</span><span class="op">&lt;</span><span class="ident">H</span><span class="op">&gt;&gt;</span>,
<span class="ident">addr</span>: <span class="prelude-ty">Option</span><span class="op">&lt;</span><span class="ident">SocketAddr</span><span class="op">&gt;</span>, <span class="ident">settings</span>: <span class="ident">ServiceConfig</span><span class="op">&lt;</span><span class="ident">H</span><span class="op">&gt;</span>,
<span class="ident">extensions</span>: <span class="prelude-ty">Option</span><span class="op">&lt;</span><span class="ident">Rc</span><span class="op">&lt;</span><span class="ident">Extensions</span><span class="op">&gt;&gt;</span>,
) <span class="op">-&gt;</span> <span class="ident">Entry</span><span class="op">&lt;</span><span class="ident">H</span><span class="op">&gt;</span>
<span class="kw">where</span>
<span class="ident">H</span>: <span class="ident">HttpHandler</span> <span class="op">+</span> <span class="lifetime">&#39;static</span>,
@ -783,6 +830,7 @@
<span class="ident">inner</span>.<span class="ident">method</span> <span class="op">=</span> <span class="ident">parts</span>.<span class="ident">method</span>;
<span class="ident">inner</span>.<span class="ident">version</span> <span class="op">=</span> <span class="ident">parts</span>.<span class="ident">version</span>;
<span class="ident">inner</span>.<span class="ident">headers</span> <span class="op">=</span> <span class="ident">parts</span>.<span class="ident">headers</span>;
<span class="ident">inner</span>.<span class="ident">stream_extensions</span> <span class="op">=</span> <span class="ident">extensions</span>;
<span class="kw-2">*</span><span class="ident">inner</span>.<span class="ident">payload</span>.<span class="ident">borrow_mut</span>() <span class="op">=</span> <span class="prelude-val">Some</span>(<span class="ident">payload</span>);
<span class="ident">inner</span>.<span class="ident">addr</span> <span class="op">=</span> <span class="ident">addr</span>;
}
@ -791,28 +839,20 @@
<span class="kw">let</span> <span class="ident">psender</span> <span class="op">=</span> <span class="ident">PayloadType</span>::<span class="ident">new</span>(<span class="ident">msg</span>.<span class="ident">headers</span>(), <span class="ident">psender</span>);
<span class="comment">// start request processing</span>
<span class="kw">let</span> <span class="kw-2">mut</span> <span class="ident">task</span> <span class="op">=</span> <span class="prelude-val">None</span>;
<span class="kw">for</span> <span class="ident">h</span> <span class="kw">in</span> <span class="ident">settings</span>.<span class="ident">handlers</span>().<span class="ident">iter_mut</span>() {
<span class="ident">msg</span> <span class="op">=</span> <span class="kw">match</span> <span class="ident">h</span>.<span class="ident">handle</span>(<span class="ident">msg</span>) {
<span class="prelude-val">Ok</span>(<span class="ident">t</span>) <span class="op">=&gt;</span> {
<span class="ident">task</span> <span class="op">=</span> <span class="prelude-val">Some</span>(<span class="ident">t</span>);
<span class="kw">break</span>;
}
<span class="prelude-val">Err</span>(<span class="ident">msg</span>) <span class="op">=&gt;</span> <span class="ident">msg</span>,
}
}
<span class="kw">let</span> <span class="ident">task</span> <span class="op">=</span> <span class="kw">match</span> <span class="ident">settings</span>.<span class="ident">handler</span>().<span class="ident">handle</span>(<span class="ident">msg</span>) {
<span class="prelude-val">Ok</span>(<span class="ident">task</span>) <span class="op">=&gt;</span> <span class="ident">EntryPipe</span>::<span class="ident">Task</span>(<span class="ident">task</span>),
<span class="prelude-val">Err</span>(<span class="kw">_</span>) <span class="op">=&gt;</span> <span class="ident">EntryPipe</span>::<span class="ident">Error</span>(<span class="ident">ServerError</span>::<span class="ident">err</span>(
<span class="ident">Version</span>::<span class="ident">HTTP_2</span>,
<span class="ident">StatusCode</span>::<span class="ident">NOT_FOUND</span>,
)),
};
<span class="ident">Entry</span> {
<span class="ident">task</span>: <span class="ident">task</span>.<span class="ident">map</span>(<span class="ident">EntryPipe</span>::<span class="ident">Task</span>).<span class="ident">unwrap_or_else</span>(<span class="op">||</span> {
<span class="ident">EntryPipe</span>::<span class="ident">Error</span>(<span class="ident">ServerError</span>::<span class="ident">err</span>(
<span class="ident">Version</span>::<span class="ident">HTTP_2</span>,
<span class="ident">StatusCode</span>::<span class="ident">NOT_FOUND</span>,
))
}),
<span class="ident">payload</span>: <span class="ident">psender</span>,
<span class="ident">stream</span>: <span class="ident">H2Writer</span>::<span class="ident">new</span>(<span class="ident">resp</span>, <span class="ident">Rc</span>::<span class="ident">clone</span>(<span class="ident">settings</span>)),
<span class="ident">flags</span>: <span class="ident">EntryFlags</span>::<span class="ident">empty</span>(),
<span class="ident">task</span>,
<span class="ident">recv</span>,
<span class="ident">payload</span>: <span class="ident">psender</span>,
<span class="ident">stream</span>: <span class="ident">H2Writer</span>::<span class="ident">new</span>(<span class="ident">resp</span>, <span class="ident">settings</span>),
<span class="ident">flags</span>: <span class="ident">EntryFlags</span>::<span class="ident">empty</span>(),
}
}