juniper/hyper/server/index.html
Juniper Documentation Builder 95d942c9d4 Update documentation for Juniper
2016-09-11 18:41:24 +00:00

257 lines
No EOL
16 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="API documentation for the Rust `server` mod in crate `hyper`.">
<meta name="keywords" content="rust, rustlang, rust-lang, server">
<title>hyper::server - Rust</title>
<link rel="stylesheet" type="text/css" href="../../rustdoc.css">
<link rel="stylesheet" type="text/css" href="../../main.css">
</head>
<body class="rustdoc">
<!--[if lte IE 8]>
<div class="warning">
This old browser is unsupported and will most likely display funky
things.
</div>
<![endif]-->
<nav class="sidebar">
<p class='location'><a href='../index.html'>hyper</a></p><script>window.sidebarCurrent = {name: 'server', ty: 'mod', relpath: '../'};</script><script defer src="../sidebar-items.js"></script>
</nav>
<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">
</div>
</form>
</nav>
<section id='main' class="content mod">
<h1 class='fqn'><span class='in-band'>Module <a href='../index.html'>hyper</a>::<wbr><a class='mod' href=''>server</a></span><span class='out-of-band'><span id='render-detail'>
<a id="toggle-all-docs" href="javascript:void(0)" title="collapse all docs">
[<span class='inner'>&#x2212;</span>]
</a>
</span><a id='src-7213' class='srclink' href='../../src/hyper/server/mod.rs.html#1-510' title='goto source code'>[src]</a></span></h1>
<div class='docblock'><p>HTTP Server</p>
<h1 id='server' class='section-header'><a href='#server'>Server</a></h1>
<p>A <code>Server</code> is created to listen on port, parse HTTP requests, and hand
them off to a <code>Handler</code>. By default, the Server will listen across multiple
threads, but that can be configured to a single thread if preferred.</p>
<h1 id='handling-requests' class='section-header'><a href='#handling-requests'>Handling requests</a></h1>
<p>You must pass a <code>Handler</code> to the Server that will handle requests. There is
a default implementation for <code>fn</code>s and closures, allowing you pass one of
those easily.</p>
<pre class='rust rust-example-rendered'>
<span class='kw'>use</span> <span class='ident'>hyper</span>::<span class='ident'>server</span>::{<span class='ident'>Server</span>, <span class='ident'>Request</span>, <span class='ident'>Response</span>};
<span class='kw'>fn</span> <span class='ident'>hello</span>(<span class='ident'>req</span>: <span class='ident'>Request</span>, <span class='ident'>res</span>: <span class='ident'>Response</span>) {
<span class='comment'>// handle things here</span>
}
<span class='ident'>Server</span>::<span class='ident'>http</span>(<span class='string'>&quot;0.0.0.0:0&quot;</span>).<span class='ident'>unwrap</span>().<span class='ident'>handle</span>(<span class='ident'>hello</span>).<span class='ident'>unwrap</span>();</pre>
<p>As with any trait, you can also define a struct and implement <code>Handler</code>
directly on your own type, and pass that to the <code>Server</code> instead.</p>
<pre class='rust rust-example-rendered'>
<span class='kw'>use</span> <span class='ident'>std</span>::<span class='ident'>sync</span>::<span class='ident'>Mutex</span>;
<span class='kw'>use</span> <span class='ident'>std</span>::<span class='ident'>sync</span>::<span class='ident'>mpsc</span>::{<span class='ident'>channel</span>, <span class='ident'>Sender</span>};
<span class='kw'>use</span> <span class='ident'>hyper</span>::<span class='ident'>server</span>::{<span class='ident'>Handler</span>, <span class='ident'>Server</span>, <span class='ident'>Request</span>, <span class='ident'>Response</span>};
<span class='kw'>struct</span> <span class='ident'>SenderHandler</span> {
<span class='ident'>sender</span>: <span class='ident'>Mutex</span><span class='op'>&lt;</span><span class='ident'>Sender</span><span class='op'>&lt;</span><span class='kw-2'>&amp;</span><span class='lifetime'>&#39;static</span> <span class='ident'>str</span><span class='op'>&gt;&gt;</span>
}
<span class='kw'>impl</span> <span class='ident'>Handler</span> <span class='kw'>for</span> <span class='ident'>SenderHandler</span> {
<span class='kw'>fn</span> <span class='ident'>handle</span>(<span class='kw-2'>&amp;</span><span class='self'>self</span>, <span class='ident'>req</span>: <span class='ident'>Request</span>, <span class='ident'>res</span>: <span class='ident'>Response</span>) {
<span class='self'>self</span>.<span class='ident'>sender</span>.<span class='ident'>lock</span>().<span class='ident'>unwrap</span>().<span class='ident'>send</span>(<span class='string'>&quot;start&quot;</span>).<span class='ident'>unwrap</span>();
}
}
<span class='kw'>let</span> (<span class='ident'>tx</span>, <span class='ident'>rx</span>) <span class='op'>=</span> <span class='ident'>channel</span>();
<span class='ident'>Server</span>::<span class='ident'>http</span>(<span class='string'>&quot;0.0.0.0:0&quot;</span>).<span class='ident'>unwrap</span>().<span class='ident'>handle</span>(<span class='ident'>SenderHandler</span> {
<span class='ident'>sender</span>: <span class='ident'>Mutex</span>::<span class='ident'>new</span>(<span class='ident'>tx</span>)
}).<span class='ident'>unwrap</span>();</pre>
<p>Since the <code>Server</code> will be listening on multiple threads, the <code>Handler</code>
must implement <code>Sync</code>: any mutable state must be synchronized.</p>
<pre class='rust rust-example-rendered'>
<span class='kw'>use</span> <span class='ident'>std</span>::<span class='ident'>sync</span>::<span class='ident'>atomic</span>::{<span class='ident'>AtomicUsize</span>, <span class='ident'>Ordering</span>};
<span class='kw'>use</span> <span class='ident'>hyper</span>::<span class='ident'>server</span>::{<span class='ident'>Server</span>, <span class='ident'>Request</span>, <span class='ident'>Response</span>};
<span class='kw'>let</span> <span class='ident'>counter</span> <span class='op'>=</span> <span class='ident'>AtomicUsize</span>::<span class='ident'>new</span>(<span class='number'>0</span>);
<span class='ident'>Server</span>::<span class='ident'>http</span>(<span class='string'>&quot;0.0.0.0:0&quot;</span>).<span class='ident'>unwrap</span>().<span class='ident'>handle</span>(<span class='kw'>move</span> <span class='op'>|</span><span class='ident'>req</span>: <span class='ident'>Request</span>, <span class='ident'>res</span>: <span class='ident'>Response</span><span class='op'>|</span> {
<span class='ident'>counter</span>.<span class='ident'>fetch_add</span>(<span class='number'>1</span>, <span class='ident'>Ordering</span>::<span class='ident'>Relaxed</span>);
}).<span class='ident'>unwrap</span>();</pre>
<h1 id='the-request-and-response-pair' class='section-header'><a href='#the-request-and-response-pair'>The <code>Request</code> and <code>Response</code> pair</a></h1>
<p>A <code>Handler</code> receives a pair of arguments, a <code>Request</code> and a <code>Response</code>. The
<code>Request</code> includes access to the <code>method</code>, <code>uri</code>, and <code>headers</code> of the
incoming HTTP request. It also implements <code>std::io::Read</code>, in order to
read any body, such as with <code>POST</code> or <code>PUT</code> messages.</p>
<p>Likewise, the <code>Response</code> includes ways to set the <code>status</code> and <code>headers</code>,
and implements <code>std::io::Write</code> to allow writing the response body.</p>
<pre class='rust rust-example-rendered'>
<span class='kw'>use</span> <span class='ident'>std</span>::<span class='ident'>io</span>;
<span class='kw'>use</span> <span class='ident'>hyper</span>::<span class='ident'>server</span>::{<span class='ident'>Server</span>, <span class='ident'>Request</span>, <span class='ident'>Response</span>};
<span class='kw'>use</span> <span class='ident'>hyper</span>::<span class='ident'>status</span>::<span class='ident'>StatusCode</span>;
<span class='ident'>Server</span>::<span class='ident'>http</span>(<span class='string'>&quot;0.0.0.0:0&quot;</span>).<span class='ident'>unwrap</span>().<span class='ident'>handle</span>(<span class='op'>|</span><span class='kw-2'>mut</span> <span class='ident'>req</span>: <span class='ident'>Request</span>, <span class='kw-2'>mut</span> <span class='ident'>res</span>: <span class='ident'>Response</span><span class='op'>|</span> {
<span class='kw'>match</span> <span class='ident'>req</span>.<span class='ident'>method</span> {
<span class='ident'>hyper</span>::<span class='ident'>Post</span> <span class='op'>=&gt;</span> {
<span class='ident'>io</span>::<span class='ident'>copy</span>(<span class='kw-2'>&amp;</span><span class='kw-2'>mut</span> <span class='ident'>req</span>, <span class='kw-2'>&amp;</span><span class='kw-2'>mut</span> <span class='ident'>res</span>.<span class='ident'>start</span>().<span class='ident'>unwrap</span>()).<span class='ident'>unwrap</span>();
},
_ <span class='op'>=&gt;</span> <span class='op'>*</span><span class='ident'>res</span>.<span class='ident'>status_mut</span>() <span class='op'>=</span> <span class='ident'>StatusCode</span>::<span class='ident'>MethodNotAllowed</span>
}
}).<span class='ident'>unwrap</span>();</pre>
<h2 id='an-aside-write-status' class='section-header'><a href='#an-aside-write-status'>An aside: Write Status</a></h2>
<p>The <code>Response</code> uses a phantom type parameter to determine its write status.
What does that mean? In short, it ensures you never write a body before
adding all headers, and never add a header after writing some of the body.</p>
<p>This is often done in most implementations by include a boolean property
on the response, such as <code>headers_written</code>, checking that each time the
body has something to write, so as to make sure the headers are sent once,
and only once. But this has 2 downsides:</p>
<ol>
<li>You are typically never notified that your late header is doing nothing.</li>
<li>There&#39;s a runtime cost to checking on every write.</li>
</ol>
<p>Instead, hyper handles this statically, or at compile-time. A
<code>Response&lt;Fresh&gt;</code> includes a <code>headers_mut()</code> method, allowing you add more
headers. It also does not implement <code>Write</code>, so you can&#39;t accidentally
write early. Once the &quot;head&quot; of the response is correct, you can &quot;send&quot; it
out by calling <code>start</code> on the <code>Response&lt;Fresh&gt;</code>. This will return a new
<code>Response&lt;Streaming&gt;</code> object, that no longer has <code>headers_mut()</code>, but does
implement <code>Write</code>.</p>
</div><h2 id='reexports' class='section-header'><a href="#reexports">Reexports</a></h2>
<table><tr><td><code>pub use self::<a class='mod'
href='./request/index.html'>request</a>::<a class='struct' href='../../hyper/server/request/struct.Request.html' title='hyper::server::request::Request'>Request</a>;</code></td></tr><tr><td><code>pub use self::<a class='mod'
href='./response/index.html'>response</a>::<a class='struct' href='../../hyper/server/response/struct.Response.html' title='hyper::server::response::Response'>Response</a>;</code></td></tr><tr><td><code>pub use net::{<a class='enum' href='../../hyper/net/enum.Fresh.html' title='hyper::net::Fresh'>Fresh</a>, <a class='enum' href='../../hyper/net/enum.Streaming.html' title='hyper::net::Streaming'>Streaming</a>};</code></td></tr></table><h2 id='modules' class='section-header'><a href="#modules">Modules</a></h2>
<table>
<tr class=' module-item'>
<td><a class='mod' href='request/index.html'
title='hyper::server::request'>request</a></td>
<td class='docblock short'>
<p>Server Requests</p>
</td>
</tr>
<tr class=' module-item'>
<td><a class='mod' href='response/index.html'
title='hyper::server::response'>response</a></td>
<td class='docblock short'>
<p>Server Responses</p>
</td>
</tr></table><h2 id='structs' class='section-header'><a href="#structs">Structs</a></h2>
<table>
<tr class=' module-item'>
<td><a class='struct' href='struct.Listening.html'
title='hyper::server::Listening'>Listening</a></td>
<td class='docblock short'>
<p>A listening server, which can later be closed.</p>
</td>
</tr>
<tr class=' module-item'>
<td><a class='struct' href='struct.Server.html'
title='hyper::server::Server'>Server</a></td>
<td class='docblock short'>
<p>A server can listen on a TCP socket.</p>
</td>
</tr></table><h2 id='traits' class='section-header'><a href="#traits">Traits</a></h2>
<table>
<tr class=' module-item'>
<td><a class='trait' href='trait.Handler.html'
title='hyper::server::Handler'>Handler</a></td>
<td class='docblock short'>
<p>A handler that can handle incoming requests for a server.</p>
</td>
</tr></table></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>?</dt>
<dd>Show this help dialog</dd>
<dt>S</dt>
<dd>Focus the search field</dd>
<dt>&larrb;</dt>
<dd>Move up in search results</dd>
<dt>&rarrb;</dt>
<dd>Move down in search results</dd>
<dt>&#9166;</dt>
<dd>Go to active search result</dd>
<dt>+</dt>
<dd>Collapse/expand 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>
</div>
</div>
</aside>
<script>
window.rootPath = "../../";
window.currentCrate = "hyper";
window.playgroundUrl = "";
</script>
<script src="../../jquery.js"></script>
<script src="../../main.js"></script>
<script defer src="../../search-index.js"></script>
</body>
</html>