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:
@ -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">'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"><</span><span class="ident">WorkerSettings</span><span class="op"><</span><span class="ident">H</span><span class="op">>></span>,
|
||||
<span class="ident">settings</span>: <span class="ident">ServiceConfig</span><span class="op"><</span><span class="ident">H</span><span class="op">></span>,
|
||||
<span class="ident">addr</span>: <span class="prelude-ty">Option</span><span class="op"><</span><span class="ident">SocketAddr</span><span class="op">></span>,
|
||||
<span class="ident">state</span>: <span class="ident">State</span><span class="op"><</span><span class="ident">IoWrapper</span><span class="op"><</span><span class="ident">T</span><span class="op">>></span>,
|
||||
<span class="ident">tasks</span>: <span class="ident">VecDeque</span><span class="op"><</span><span class="ident">Entry</span><span class="op"><</span><span class="ident">H</span><span class="op">>></span>,
|
||||
<span class="ident">keepalive_timer</span>: <span class="prelude-ty">Option</span><span class="op"><</span><span class="ident">Delay</span><span class="op">></span>,
|
||||
<span class="ident">extensions</span>: <span class="prelude-ty">Option</span><span class="op"><</span><span class="ident">Rc</span><span class="op"><</span><span class="ident">Extensions</span><span class="op">>></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"><</span><span class="ident">Delay</span><span class="op">></span>,
|
||||
}
|
||||
|
||||
<span class="kw">enum</span> <span class="ident">State</span><span class="op"><</span><span class="ident">T</span>: <span class="ident">AsyncRead</span> <span class="op">+</span> <span class="ident">AsyncWrite</span><span class="op">></span> {
|
||||
@ -497,12 +521,24 @@
|
||||
|
||||
<span class="kw">impl</span><span class="op"><</span><span class="ident">T</span>, <span class="ident">H</span><span class="op">></span> <span class="ident">Http2</span><span class="op"><</span><span class="ident">T</span>, <span class="ident">H</span><span class="op">></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">'static</span>,
|
||||
<span class="ident">T</span>: <span class="ident">IoStream</span> <span class="op">+</span> <span class="lifetime">'static</span>,
|
||||
<span class="ident">H</span>: <span class="ident">HttpHandler</span> <span class="op">+</span> <span class="lifetime">'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"><</span><span class="ident">WorkerSettings</span><span class="op"><</span><span class="ident">H</span><span class="op">>></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"><</span><span class="ident">SocketAddr</span><span class="op">></span>, <span class="ident">buf</span>: <span class="ident">Bytes</span>,
|
||||
<span class="ident">settings</span>: <span class="ident">ServiceConfig</span><span class="op"><</span><span class="ident">H</span><span class="op">></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"><</span><span class="ident">Delay</span><span class="op">></span>,
|
||||
) <span class="op">-></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">&</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">&</span><span class="kw-2">mut</span> <span class="self">self</span>) <span class="op">-></span> <span class="ident">Poll</span><span class="op"><</span>(), <span class="ident">HttpDispatchError</span><span class="op">></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">&</span><span class="self">self</span>) <span class="op">-></span> <span class="kw-2">&</span><span class="ident">WorkerSettings</span><span class="op"><</span><span class="ident">H</span><span class="op">></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">&</span><span class="kw-2">mut</span> <span class="self">self</span>) <span class="op">-></span> <span class="ident">Poll</span><span class="op"><</span>(), ()<span class="op">></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">=></span> {
|
||||
<span class="macro">trace</span><span class="macro">!</span>(<span class="string">"Keep-alive timeout, close connection"</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">=></span> (),
|
||||
<span class="prelude-val">Err</span>(<span class="kw">_</span>) <span class="op">=></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">&</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">&</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">=></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">&</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">=></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">=></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">&&</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">=></span> {
|
||||
<span class="macro">error</span><span class="macro">!</span>(<span class="string">"Unhandled error: {}"</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">=></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">&&</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">=></span> {
|
||||
<span class="macro">error</span><span class="macro">!</span>(<span class="string">"Unhandled error: {}"</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">&&</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">=></span> (),
|
||||
<span class="prelude-val">Ok</span>(<span class="ident">Async</span>::<span class="ident">Ready</span>(<span class="kw">_</span>)) <span class="op">=></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">=></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">&&</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">&&</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">=></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">=></span> {
|
||||
<span class="prelude-val">Err</span>(<span class="kw">_</span>) <span class="op">=></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">&&</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">&</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">=></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">></span> <span class="number">0</span> <span class="op">&&</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">"Start keep-alive timer"</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">"Error during connection close: {}"</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">=></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">=></span> {
|
||||
<span class="macro">trace</span><span class="macro">!</span>(<span class="string">"Connection error: {}"</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">&</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">&&</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">"Error during connection close: {}"</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">=></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">=></span> {
|
||||
<span class="macro">trace</span><span class="macro">!</span>(<span class="string">"Error handling connection: {}"</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">&</span><span class="kw-2">mut</span> <span class="self">self</span>) <span class="op">-></span> <span class="prelude-ty">Result</span><span class="op"><</span>(), <span class="ident">HttpDispatchError</span><span class="op">></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">=></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">>=</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">=></span> (),
|
||||
<span class="prelude-val">Err</span>(<span class="ident">e</span>) <span class="op">=></span> {
|
||||
<span class="macro">error</span><span class="macro">!</span>(<span class="string">"Timer error {:?}"</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"><</span><span class="ident">H</span>: <span class="ident">HttpHandler</span> <span class="op">+</span> <span class="lifetime">'static</span><span class="op">></span> <span class="ident">Entry</span><span class="op"><</span><span class="ident">H</span><span class="op">></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"><</span><span class="ident">Bytes</span><span class="op">></span>,
|
||||
<span class="ident">addr</span>: <span class="prelude-ty">Option</span><span class="op"><</span><span class="ident">SocketAddr</span><span class="op">></span>, <span class="ident">settings</span>: <span class="kw-2">&</span><span class="ident">Rc</span><span class="op"><</span><span class="ident">WorkerSettings</span><span class="op"><</span><span class="ident">H</span><span class="op">>></span>,
|
||||
<span class="ident">addr</span>: <span class="prelude-ty">Option</span><span class="op"><</span><span class="ident">SocketAddr</span><span class="op">></span>, <span class="ident">settings</span>: <span class="ident">ServiceConfig</span><span class="op"><</span><span class="ident">H</span><span class="op">></span>,
|
||||
<span class="ident">extensions</span>: <span class="prelude-ty">Option</span><span class="op"><</span><span class="ident">Rc</span><span class="op"><</span><span class="ident">Extensions</span><span class="op">>></span>,
|
||||
) <span class="op">-></span> <span class="ident">Entry</span><span class="op"><</span><span class="ident">H</span><span class="op">></span>
|
||||
<span class="kw">where</span>
|
||||
<span class="ident">H</span>: <span class="ident">HttpHandler</span> <span class="op">+</span> <span class="lifetime">'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">=></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">=></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">=></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">=></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>(),
|
||||
}
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user