-
Notifications
You must be signed in to change notification settings - Fork 14
/
Copy pathindex.html
74 lines (74 loc) · 25.3 KB
/
index.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
<!doctype html><html lang=en><head><meta charset=utf-8><meta name=viewport content="width=device-width,initial-scale=1,shrink-to-fit=no"><meta http-equiv=x-ua-compatible content="ie=edge"><link rel=stylesheet href=https://actix.rs/css/bootstrap-reboot.css><link rel=stylesheet href=https://actix.rs/css/bootstrap.css><link rel=stylesheet href=https://actix.rs/css/font-awesome.min.css><link rel=stylesheet href=https://actix.rs/css/actix.css><link rel=stylesheet href=https://actix.rs/css/highlight.css><link rel=icon href=https://actix.rs/favicon.ico title=actix><title>Server</title></head><body><header class="navbar navbar-light navbar-toggleable-md bd-navbar"><nav class=actix-main-nav><div class="d-flex justify-content-between hidden-lg-up"><a href=https://actix.rs/ class=navbar-brand><img src=https://actix.rs/img/logo-nav.png class=align-middle alt></a>
<button class="navbar-toggle collapsed" type=button data-toggle=collapse data-target=#actix-main-nav aria-label="Toggle navigation" aria-controls=actix-main-nav aria-expanded=false>
<span class=navbar-toggler-icon></span></button></div><div class="navbar-collapse collapse" id=actix-main-nav><ul class="nav navbar-nav"><li class="nav-item hd-lg-down"><a class=navbar-brand href=https://actix.rs/><img src=https://actix.rs/img/logo-nav.png class=align-middle alt></a></li><li class=nav-item><a class=nav-link href=https://actix.rs/>Home</a></li><li class=nav-item><a class=nav-link href=https://actix.rs/docs/>Documentation</a></li><li class=nav-item><a class=nav-link href=https://actix.rs/community/>Community</a></li><li class=nav-item><a class=nav-link href=https://actix.rs/code/>Code</a></li></ul></div></nav></header><div class=actix-pageheader><div class=container><h1 class=display-4>Server</h1></div></div><div class="container actix-docs"><div class=row><div class=col-md-3><button class="btn doctoggle" type=button data-toggle=collapse data-target=#collapsing-docnav aria-expanded=false aria-controls=collapsing-docnav>
Toggle navigation</button><nav class="leftnav collapse show" id=collapsing-docnav><div><h5>Introduction</h5><div><ul class=nav><li><a href=https://actix.rs/docs/>Welcome</a></li><li><a href=https://actix.rs/docs/whatis/>What is Actix Web</a></li></ul></div><h5>Basics</h5><div><ul class=nav><li><a href=https://actix.rs/docs/getting-started/>Getting Started</a></li><li><a href=https://actix.rs/docs/application/>Application</a></li><li class=active><a href=https://actix.rs/docs/server/>Server</a></li><li><a href=https://actix.rs/docs/handlers/>Handlers</a></li><li><a href=https://actix.rs/docs/extractors/>Extractors</a></li></ul></div><h5>Advanced</h5><div><ul class=nav><li><a href=https://actix.rs/docs/errors/>Errors</a></li><li><a href=https://actix.rs/docs/url-dispatch/>URL Dispatch</a></li><li><a href=https://actix.rs/docs/request/>Requests</a></li><li><a href=https://actix.rs/docs/response/>Responses</a></li><li><a href=https://actix.rs/docs/testing/>Testing</a></li><li><a href=https://actix.rs/docs/middleware/>Middleware</a></li><li><a href=https://actix.rs/docs/static-files/>Static Files</a></li></ul></div><h5>Protocols</h5><div><ul class=nav><li><a href=https://actix.rs/docs/websockets/>Websockets</a></li><li><a href=https://actix.rs/docs/http2/>HTTP/2</a></li></ul></div><h5>Patterns</h5><div><ul class=nav><li><a href=https://actix.rs/docs/autoreload/>Auto-Reloading</a></li><li><a href=https://actix.rs/docs/databases/>Databases</a></li></ul></div><h5>Diagrams</h5><div><ul class=nav><li><a href=https://actix.rs/docs/http_server_init/>HTTP Server Initialization</a></li><li><a href=https://actix.rs/docs/conn_lifecycle/>Connection Lifecycle</a></li></ul></div><h5>API Documentation</h5><div><ul class=nav><li><a href=https://docs.rs/actix target=view_window>actix <span class="fa fa-external-link"></span></a></li><li><a href=https://docs.rs/actix-web/ target=view_window>actix-web <span class="fa fa-external-link"></span></a></li></ul></div></div></nav></div><div class=col-md-9><div class=actix-content><h1 id=the-http-server>The HTTP Server</h1><p>The <a href=https://docs.rs/actix-web/4/actix_web/struct.HttpServer.html><strong>HttpServer</strong></a> type is responsible for serving HTTP requests.</p><p><code>HttpServer</code> accepts an application factory as a parameter, and the application factory must have <code>Send</code> + <code>Sync</code> boundaries. More about that in the <em>multi-threading</em> section.</p><p>To start the web server it must first be bound to a network socket. Use <a href=https://docs.rs/actix-web/4/actix_web/struct.HttpServer.html#method.bind><code>HttpServer::bind()</code></a> with a socket address tuple or string such as <code>("127.0.0.1", 8080)</code> or <code>"0.0.0.0:8080"</code>. This will fail if the socket is being used by another application.</p><p>After the <code>bind</code> is successful, use <a href=https://docs.rs/actix-web/4/actix_web/struct.HttpServer.html#method.run><code>HttpServer::run()</code></a> to return a <a href=https://docs.rs/actix-web/4/actix_web/dev/struct.Server.html><code>Server</code></a> instance. The <code>Server</code> must be <code>await</code>ed or <code>spawn</code>ed to start processing requests and will run until it receives a shutdown signal (such as, by default, a <code>ctrl-c</code>; <a href=#graceful-shutdown>read more here</a>).</p><div class=highlight><pre class=chroma><code class=language-rust data-lang=rust><span class=k>use</span><span class=w> </span><span class=n>actix_web</span>::<span class=p>{</span><span class=n>web</span><span class=p>,</span><span class=w> </span><span class=n>App</span><span class=p>,</span><span class=w> </span><span class=n>HttpResponse</span><span class=p>,</span><span class=w> </span><span class=n>HttpServer</span><span class=p>};</span><span class=w>
</span><span class=w>
</span><span class=w></span><span class=cp>#[actix_web::main]</span><span class=w>
</span><span class=w></span><span class=k>async</span><span class=w> </span><span class=k>fn</span> <span class=nf>main</span><span class=p>()</span><span class=w> </span>-> <span class=nc>std</span>::<span class=n>io</span>::<span class=nb>Result</span><span class=o><</span><span class=p>()</span><span class=o>></span><span class=w> </span><span class=p>{</span><span class=w>
</span><span class=w> </span><span class=n>HttpServer</span>::<span class=n>new</span><span class=p>(</span><span class=o>||</span><span class=w> </span><span class=n>App</span>::<span class=n>new</span><span class=p>().</span><span class=n>route</span><span class=p>(</span><span class=s>"/"</span><span class=p>,</span><span class=w> </span><span class=n>web</span>::<span class=n>get</span><span class=p>().</span><span class=n>to</span><span class=p>(</span><span class=n>HttpResponse</span>::<span class=nb>Ok</span><span class=p>)))</span><span class=w>
</span><span class=w> </span><span class=p>.</span><span class=n>bind</span><span class=p>((</span><span class=s>"127.0.0.1"</span><span class=p>,</span><span class=w> </span><span class=mi>8080</span><span class=p>))</span><span class=o>?</span><span class=w>
</span><span class=w> </span><span class=p>.</span><span class=n>run</span><span class=p>()</span><span class=w>
</span><span class=w> </span><span class=p>.</span><span class=k>await</span><span class=w>
</span><span class=w></span><span class=p>}</span><span class=w>
</span></code></pre></div><h2 id=multi-threading>Multi-Threading</h2><p><code>HttpServer</code> automatically starts a number of HTTP <em>workers</em>, by default this number is equal to the number of logical CPUs in the system. This number can be overridden with the <a href=https://docs.rs/actix-web/4/actix_web/struct.HttpServer.html#method.workers><code>HttpServer::workers()</code></a> method.</p><div class=highlight><pre class=chroma><code class=language-rust data-lang=rust><span class=k>use</span><span class=w> </span><span class=n>actix_web</span>::<span class=p>{</span><span class=n>web</span><span class=p>,</span><span class=w> </span><span class=n>App</span><span class=p>,</span><span class=w> </span><span class=n>HttpResponse</span><span class=p>,</span><span class=w> </span><span class=n>HttpServer</span><span class=p>};</span><span class=w>
</span><span class=w>
</span><span class=w></span><span class=cp>#[actix_web::main]</span><span class=w>
</span><span class=w></span><span class=k>async</span><span class=w> </span><span class=k>fn</span> <span class=nf>main</span><span class=p>()</span><span class=w> </span><span class=p>{</span><span class=w>
</span><span class=w> </span><span class=n>HttpServer</span>::<span class=n>new</span><span class=p>(</span><span class=o>||</span><span class=w> </span><span class=n>App</span>::<span class=n>new</span><span class=p>().</span><span class=n>route</span><span class=p>(</span><span class=s>"/"</span><span class=p>,</span><span class=w> </span><span class=n>web</span>::<span class=n>get</span><span class=p>().</span><span class=n>to</span><span class=p>(</span><span class=n>HttpResponse</span>::<span class=nb>Ok</span><span class=p>))).</span><span class=n>workers</span><span class=p>(</span><span class=mi>4</span><span class=p>);</span><span class=w>
</span><span class=w> </span><span class=c1>// <- Start 4 workers
</span><span class=c1></span><span class=p>}</span><span class=w>
</span></code></pre></div><p>Once the workers are created, they each receive a separate <em>application</em> instance to handle requests. Application state is not shared between the threads, and handlers are free to manipulate their copy of the state with no concurrency concerns.</p><p>Application state does not need to be <code>Send</code> or <code>Sync</code>, but application factories must be <code>Send</code> + <code>Sync</code>.</p><p>To share state between worker threads, use an <code>Arc</code>/<code>Data</code>. Special care should be taken once sharing and synchronization are introduced. In many cases, performance costs are inadvertently introduced as a result of locking the shared state for modifications.</p><p>In some cases these costs can be alleviated using more efficient locking strategies, for example using <a href=https://doc.rust-lang.org/std/sync/struct.RwLock.html>read/write locks</a> instead of <a href=https://doc.rust-lang.org/std/sync/struct.Mutex.html>mutexes</a> to achieve non-exclusive locking, but the most performant implementations often tend to be ones in which no locking occurs at all.</p><p>Since each worker thread processes its requests sequentially, handlers which block the current thread will cause the current worker to stop processing new requests:</p><div class=highlight><pre class=chroma><code class=language-rust data-lang=rust><span class=k>fn</span> <span class=nf>my_handler</span><span class=p>()</span><span class=w> </span>-> <span class=nc>impl</span><span class=w> </span><span class=n>Responder</span><span class=w> </span><span class=p>{</span><span class=w>
</span><span class=w> </span><span class=n>std</span>::<span class=n>thread</span>::<span class=n>sleep</span><span class=p>(</span><span class=n>Duration</span>::<span class=n>from_secs</span><span class=p>(</span><span class=mi>5</span><span class=p>));</span><span class=w> </span><span class=c1>// <-- Bad practice! Will cause the current worker thread to hang!
</span><span class=c1></span><span class=w> </span><span class=s>"response"</span><span class=w>
</span><span class=w></span><span class=p>}</span><span class=w>
</span></code></pre></div><p>For this reason, any long, non-cpu-bound operation (e.g. I/O, database operations, etc.) should be expressed as futures or asynchronous functions. Async handlers get executed concurrently by worker threads and thus don’t block execution:</p><div class=highlight><pre class=chroma><code class=language-rust data-lang=rust><span class=k>async</span><span class=w> </span><span class=k>fn</span> <span class=nf>my_handler</span><span class=p>()</span><span class=w> </span>-> <span class=nc>impl</span><span class=w> </span><span class=n>Responder</span><span class=w> </span><span class=p>{</span><span class=w>
</span><span class=w> </span><span class=n>tokio</span>::<span class=n>time</span>::<span class=n>sleep</span><span class=p>(</span><span class=n>Duration</span>::<span class=n>from_secs</span><span class=p>(</span><span class=mi>5</span><span class=p>)).</span><span class=k>await</span><span class=p>;</span><span class=w> </span><span class=c1>// <-- Ok. Worker thread will handle other requests here
</span><span class=c1></span><span class=w> </span><span class=s>"response"</span><span class=w>
</span><span class=w></span><span class=p>}</span><span class=w>
</span></code></pre></div><p>The same limitation applies to extractors as well. When a handler function receives an argument which implements <code>FromRequest</code>, and that implementation blocks the current thread, the worker thread will block when running the handler. Special attention must be given when implementing extractors for this very reason, and they should also be implemented asynchronously where needed.</p><h2 id=tls--https>TLS / HTTPS</h2><p>Actix Web supports two TLS implementations out-of-the-box: <code>rustls</code> and <code>openssl</code>.</p><p>The <code>rustls</code> crate feature is for <code>rustls</code> integration and <code>openssl</code> is for <code>openssl</code> integration.</p><div class=highlight><pre class=chroma><code class=language-toml data-lang=toml><span class=p>[</span><span class=nx>dependencies</span><span class=p>]</span>
<span class=nx>actix</span><span class=err>-</span><span class=nx>web</span> <span class=p>=</span> <span class=p>{</span> <span class=nx>version</span> <span class=p>=</span> <span class=s2>"4"</span><span class=p>,</span> <span class=nx>features</span> <span class=p>=</span> <span class=p>[</span><span class=s2>"openssl"</span><span class=p>]</span> <span class=p>}</span>
<span class=nx>openssl</span> <span class=p>=</span> <span class=p>{</span> <span class=nx>version</span> <span class=p>=</span> <span class=s2>"0.10"</span> <span class=p>}</span>
</code></pre></div><div class=highlight><pre class=chroma><code class=language-rust data-lang=rust><span class=k>use</span><span class=w> </span><span class=n>actix_web</span>::<span class=p>{</span><span class=n>get</span><span class=p>,</span><span class=w> </span><span class=n>App</span><span class=p>,</span><span class=w> </span><span class=n>HttpRequest</span><span class=p>,</span><span class=w> </span><span class=n>HttpServer</span><span class=p>,</span><span class=w> </span><span class=n>Responder</span><span class=p>};</span><span class=w>
</span><span class=w></span><span class=k>use</span><span class=w> </span><span class=n>openssl</span>::<span class=n>ssl</span>::<span class=p>{</span><span class=n>SslAcceptor</span><span class=p>,</span><span class=w> </span><span class=n>SslFiletype</span><span class=p>,</span><span class=w> </span><span class=n>SslMethod</span><span class=p>};</span><span class=w>
</span><span class=w>
</span><span class=w></span><span class=cp>#[get(</span><span class=s>"/"</span><span class=cp>)]</span><span class=w>
</span><span class=w></span><span class=k>async</span><span class=w> </span><span class=k>fn</span> <span class=nf>index</span><span class=p>(</span><span class=n>_req</span>: <span class=nc>HttpRequest</span><span class=p>)</span><span class=w> </span>-> <span class=nc>impl</span><span class=w> </span><span class=n>Responder</span><span class=w> </span><span class=p>{</span><span class=w>
</span><span class=w> </span><span class=s>"Welcome!"</span><span class=w>
</span><span class=w></span><span class=p>}</span><span class=w>
</span><span class=w>
</span><span class=w></span><span class=cp>#[actix_web::main]</span><span class=w>
</span><span class=w></span><span class=k>async</span><span class=w> </span><span class=k>fn</span> <span class=nf>main</span><span class=p>()</span><span class=w> </span>-> <span class=nc>std</span>::<span class=n>io</span>::<span class=nb>Result</span><span class=o><</span><span class=p>()</span><span class=o>></span><span class=w> </span><span class=p>{</span><span class=w>
</span><span class=w> </span><span class=c1>// load TLS keys
</span><span class=c1></span><span class=w> </span><span class=c1>// to create a self-signed temporary cert for testing:
</span><span class=c1></span><span class=w> </span><span class=c1>// `openssl req -x509 -newkey rsa:4096 -nodes -keyout key.pem -out cert.pem -days 365 -subj '/CN=localhost'`
</span><span class=c1></span><span class=w> </span><span class=kd>let</span><span class=w> </span><span class=k>mut</span><span class=w> </span><span class=n>builder</span><span class=w> </span><span class=o>=</span><span class=w> </span><span class=n>SslAcceptor</span>::<span class=n>mozilla_intermediate</span><span class=p>(</span><span class=n>SslMethod</span>::<span class=n>tls</span><span class=p>()).</span><span class=n>unwrap</span><span class=p>();</span><span class=w>
</span><span class=w> </span><span class=n>builder</span><span class=w>
</span><span class=w> </span><span class=p>.</span><span class=n>set_private_key_file</span><span class=p>(</span><span class=s>"key.pem"</span><span class=p>,</span><span class=w> </span><span class=n>SslFiletype</span>::<span class=n>PEM</span><span class=p>)</span><span class=w>
</span><span class=w> </span><span class=p>.</span><span class=n>unwrap</span><span class=p>();</span><span class=w>
</span><span class=w> </span><span class=n>builder</span><span class=p>.</span><span class=n>set_certificate_chain_file</span><span class=p>(</span><span class=s>"cert.pem"</span><span class=p>).</span><span class=n>unwrap</span><span class=p>();</span><span class=w>
</span><span class=w>
</span><span class=w> </span><span class=n>HttpServer</span>::<span class=n>new</span><span class=p>(</span><span class=o>||</span><span class=w> </span><span class=n>App</span>::<span class=n>new</span><span class=p>().</span><span class=n>service</span><span class=p>(</span><span class=n>index</span><span class=p>))</span><span class=w>
</span><span class=w> </span><span class=p>.</span><span class=n>bind_openssl</span><span class=p>(</span><span class=s>"127.0.0.1:8080"</span><span class=p>,</span><span class=w> </span><span class=n>builder</span><span class=p>)</span><span class=o>?</span><span class=w>
</span><span class=w> </span><span class=p>.</span><span class=n>run</span><span class=p>()</span><span class=w>
</span><span class=w> </span><span class=p>.</span><span class=k>await</span><span class=w>
</span><span class=w></span><span class=p>}</span><span class=w>
</span></code></pre></div><p>To create the key.pem and cert.pem use the command. <strong>Fill in your own subject</strong></p><div class=highlight><pre class=chroma><code class=language-bash data-lang=bash>$ openssl req -x509 -newkey rsa:4096 -keyout key.pem -out cert.pem <span class=se>\
</span><span class=se></span> -days <span class=m>365</span> -sha256 -subj <span class=s2>"/C=CN/ST=Fujian/L=Xiamen/O=TVlinux/OU=Org/CN=muro.lxd"</span>
</code></pre></div><p>To remove the password, then copy nopass.pem to key.pem</p><div class=highlight><pre class=chroma><code class=language-bash data-lang=bash>$ openssl rsa -in key.pem -out nopass.pem
</code></pre></div><h2 id=keep-alive>Keep-Alive</h2><p>Actix Web keeps connections open to wait for subsequent requests.</p><blockquote><p><em>keep alive</em> connection behavior is defined by server settings.</p></blockquote><ul><li><code>Duration::from_secs(75)</code> or <code>KeepAlive::Timeout(75)</code>: enables 75 second keep-alive timer.</li><li><code>KeepAlive::Os</code>: uses OS keep-alive.</li><li><code>None</code> or <code>KeepAlive::Disabled</code>: disables keep-alive.</li></ul><div class=highlight><pre class=chroma><code class=language-rust data-lang=rust><span class=k>use</span><span class=w> </span><span class=n>actix_web</span>::<span class=p>{</span><span class=n>http</span>::<span class=n>KeepAlive</span><span class=p>,</span><span class=w> </span><span class=n>HttpServer</span><span class=p>};</span><span class=w>
</span><span class=w></span><span class=k>use</span><span class=w> </span><span class=n>std</span>::<span class=n>time</span>::<span class=n>Duration</span><span class=p>;</span><span class=w>
</span><span class=w>
</span><span class=w></span><span class=cp>#[actix_web::main]</span><span class=w>
</span><span class=w></span><span class=k>async</span><span class=w> </span><span class=k>fn</span> <span class=nf>main</span><span class=p>()</span><span class=w> </span>-> <span class=nc>std</span>::<span class=n>io</span>::<span class=nb>Result</span><span class=o><</span><span class=p>()</span><span class=o>></span><span class=w> </span><span class=p>{</span><span class=w>
</span><span class=w> </span><span class=c1>// Set keep-alive to 75 seconds
</span><span class=c1></span><span class=w> </span><span class=kd>let</span><span class=w> </span><span class=n>_one</span><span class=w> </span><span class=o>=</span><span class=w> </span><span class=n>HttpServer</span>::<span class=n>new</span><span class=p>(</span><span class=n>app</span><span class=p>).</span><span class=n>keep_alive</span><span class=p>(</span><span class=n>Duration</span>::<span class=n>from_secs</span><span class=p>(</span><span class=mi>75</span><span class=p>));</span><span class=w>
</span><span class=w>
</span><span class=w> </span><span class=c1>// Use OS's keep-alive (usually quite long)
</span><span class=c1></span><span class=w> </span><span class=kd>let</span><span class=w> </span><span class=n>_two</span><span class=w> </span><span class=o>=</span><span class=w> </span><span class=n>HttpServer</span>::<span class=n>new</span><span class=p>(</span><span class=n>app</span><span class=p>).</span><span class=n>keep_alive</span><span class=p>(</span><span class=n>KeepAlive</span>::<span class=n>Os</span><span class=p>);</span><span class=w>
</span><span class=w>
</span><span class=w> </span><span class=c1>// Disable keep-alive
</span><span class=c1></span><span class=w> </span><span class=kd>let</span><span class=w> </span><span class=n>_three</span><span class=w> </span><span class=o>=</span><span class=w> </span><span class=n>HttpServer</span>::<span class=n>new</span><span class=p>(</span><span class=n>app</span><span class=p>).</span><span class=n>keep_alive</span><span class=p>(</span><span class=nb>None</span><span class=p>);</span><span class=w>
</span><span class=w>
</span><span class=w> </span><span class=nb>Ok</span><span class=p>(())</span><span class=w>
</span><span class=w></span><span class=p>}</span><span class=w>
</span></code></pre></div><p>If the first option above is selected, then keep-alive is enabled for HTTP/1.1 requests if the response does not explicitly disallow it by, for example, setting the <a href=https://docs.rs/actix-web/4/actix_web/http/enum.ConnectionType.html>connection type</a> to <code>Close</code> or <code>Upgrade</code>. Force closing a connection can be done with <a href=https://docs.rs/actix-web/4/actix_web/dev/struct.HttpResponseBuilder.html#method.force_close>the <code>force_close()</code> method on <code>HttpResponseBuilder</code></a></p><blockquote><p>Keep-alive is <strong>off</strong> for HTTP/1.0 and is <strong>on</strong> for HTTP/1.1 and HTTP/2.0.</p></blockquote><h2 id=graceful-shutdown>Graceful shutdown</h2><p><code>HttpServer</code> supports graceful shutdown. After receiving a stop signal, workers have a specific amount of time to finish serving requests. Any workers still alive after the timeout are force-dropped. By default the shutdown timeout is set to 30 seconds. You can change this parameter with the <a href=https://docs.rs/actix-web/4/actix_web/struct.HttpServer.html#method.shutdown_timeout><code>HttpServer::shutdown_timeout()</code></a> method.</p><p><code>HttpServer</code> handles several OS signals. <em>CTRL-C</em> is available on all OSes, other signals are available on unix systems.</p><ul><li><em>SIGINT</em> - Force shutdown workers</li><li><em>SIGTERM</em> - Graceful shutdown workers</li><li><em>SIGQUIT</em> - Force shutdown workers</li></ul><blockquote><p>It is possible to disable signal handling with <a href=https://docs.rs/actix-web/4/actix_web/struct.HttpServer.html#method.disable_signals><code>HttpServer::disable_signals()</code></a> method.</p></blockquote><div class=github-edit><a class="fa fa-github" href=https://github.com/actix/actix-website/tree/master/content/docs/server.md>Edit on GitHub</a></div><div class=actix-next><b>Next up</b>: <a href=/docs/handlers/>Handlers</a></div></div></div></div></div><footer class=actix-footer><div class="text-muted actix-footer-gray d-flex justify-content-between"><div class=actix-footer-info>Copyright © 2022 The Actix Team</div><div class=actix-footer-social><a href=https://github.com/actix class=text-muted><i class="fa fa-github" aria-hidden=true></i></a></div></div></footer><script src=https://ajax.googleapis.com/ajax/libs/jquery/3.1.1/jquery.min.js integrity=sha384-3ceskX3iaEnIogmQchP8opvBy3Mi7Ce34nWjpBIwVTHfGYWQS9jwHDVRnpKKHJg7 crossorigin=anonymous></script><script src=https://cdnjs.cloudflare.com/ajax/libs/tether/1.3.7/js/tether.min.js integrity=sha384-XTs3FgkjiBgo8qjEjBk0tGmf3wPrWtA6coPfQDfFEY8AnYJwjalXCiosYRBIBZX8 crossorigin=anonymous></script><script src=https://actix.rs/js/bootstrap.min.js></script><script src=https://actix.rs/js/actix.js></script></body></html>