1diff --git a/Cargo.lock b/Cargo.lock
2index 0b23a345018c789378ffbafcdf6c790f9869fec3..9b7111d7809c5d961d65d2d385b8f976d3d557f9 100644
3--- a/Cargo.lock
4+++ b/Cargo.lock
5@@ -3,6 +3,202 @@ # It is not intended for manual editing.
6 version = 3
7
8 [[package]]
9+name = "actix-codec"
10+version = "0.5.0"
11+source = "registry+https://github.com/rust-lang/crates.io-index"
12+checksum = "57a7559404a7f3573127aab53c08ce37a6c6a315c374a31070f3c91cd1b4a7fe"
13+dependencies = [
14+ "bitflags",
15+ "bytes",
16+ "futures-core",
17+ "futures-sink",
18+ "log",
19+ "memchr",
20+ "pin-project-lite",
21+ "tokio",
22+ "tokio-util",
23+]
24+
25+[[package]]
26+name = "actix-http"
27+version = "3.0.4"
28+source = "registry+https://github.com/rust-lang/crates.io-index"
29+checksum = "a5885cb81a0d4d0d322864bea1bb6c2a8144626b4fdc625d4c51eba197e7797a"
30+dependencies = [
31+ "actix-codec",
32+ "actix-rt",
33+ "actix-service",
34+ "actix-utils",
35+ "ahash",
36+ "base64",
37+ "bitflags",
38+ "brotli",
39+ "bytes",
40+ "bytestring",
41+ "derive_more",
42+ "encoding_rs",
43+ "flate2",
44+ "futures-core",
45+ "h2",
46+ "http",
47+ "httparse",
48+ "httpdate",
49+ "itoa",
50+ "language-tags",
51+ "local-channel",
52+ "log",
53+ "mime",
54+ "percent-encoding",
55+ "pin-project-lite",
56+ "rand",
57+ "sha-1",
58+ "smallvec",
59+ "zstd",
60+]
61+
62+[[package]]
63+name = "actix-macros"
64+version = "0.2.3"
65+source = "registry+https://github.com/rust-lang/crates.io-index"
66+checksum = "465a6172cf69b960917811022d8f29bc0b7fa1398bc4f78b3c466673db1213b6"
67+dependencies = [
68+ "quote",
69+ "syn",
70+]
71+
72+[[package]]
73+name = "actix-router"
74+version = "0.5.0"
75+source = "registry+https://github.com/rust-lang/crates.io-index"
76+checksum = "eb60846b52c118f2f04a56cc90880a274271c489b2498623d58176f8ca21fa80"
77+dependencies = [
78+ "bytestring",
79+ "firestorm",
80+ "http",
81+ "log",
82+ "regex",
83+ "serde",
84+]
85+
86+[[package]]
87+name = "actix-rt"
88+version = "2.7.0"
89+source = "registry+https://github.com/rust-lang/crates.io-index"
90+checksum = "7ea16c295198e958ef31930a6ef37d0fb64e9ca3b6116e6b93a8bdae96ee1000"
91+dependencies = [
92+ "futures-core",
93+ "tokio",
94+]
95+
96+[[package]]
97+name = "actix-server"
98+version = "2.1.1"
99+source = "registry+https://github.com/rust-lang/crates.io-index"
100+checksum = "0da34f8e659ea1b077bb4637948b815cd3768ad5a188fdcd74ff4d84240cd824"
101+dependencies = [
102+ "actix-rt",
103+ "actix-service",
104+ "actix-utils",
105+ "futures-core",
106+ "futures-util",
107+ "mio",
108+ "num_cpus",
109+ "socket2",
110+ "tokio",
111+ "tracing",
112+]
113+
114+[[package]]
115+name = "actix-service"
116+version = "2.0.2"
117+source = "registry+https://github.com/rust-lang/crates.io-index"
118+checksum = "3b894941f818cfdc7ccc4b9e60fa7e53b5042a2e8567270f9147d5591893373a"
119+dependencies = [
120+ "futures-core",
121+ "paste",
122+ "pin-project-lite",
123+]
124+
125+[[package]]
126+name = "actix-utils"
127+version = "3.0.0"
128+source = "registry+https://github.com/rust-lang/crates.io-index"
129+checksum = "e491cbaac2e7fc788dfff99ff48ef317e23b3cf63dbaf7aaab6418f40f92aa94"
130+dependencies = [
131+ "local-waker",
132+ "pin-project-lite",
133+]
134+
135+[[package]]
136+name = "actix-web"
137+version = "4.0.1"
138+source = "registry+https://github.com/rust-lang/crates.io-index"
139+checksum = "f4e5ebffd51d50df56a3ae0de0e59487340ca456f05dd0b90c0a7a6dd6a74d31"
140+dependencies = [
141+ "actix-codec",
142+ "actix-http",
143+ "actix-macros",
144+ "actix-router",
145+ "actix-rt",
146+ "actix-server",
147+ "actix-service",
148+ "actix-utils",
149+ "actix-web-codegen",
150+ "ahash",
151+ "bytes",
152+ "bytestring",
153+ "cfg-if",
154+ "cookie",
155+ "derive_more",
156+ "encoding_rs",
157+ "futures-core",
158+ "futures-util",
159+ "itoa",
160+ "language-tags",
161+ "log",
162+ "mime",
163+ "once_cell",
164+ "pin-project-lite",
165+ "regex",
166+ "serde",
167+ "serde_json",
168+ "serde_urlencoded",
169+ "smallvec",
170+ "socket2",
171+ "time 0.3.9",
172+ "url",
173+]
174+
175+[[package]]
176+name = "actix-web-codegen"
177+version = "4.0.0"
178+source = "registry+https://github.com/rust-lang/crates.io-index"
179+checksum = "7525bedf54704abb1d469e88d7e7e9226df73778798a69cea5022d53b2ae91bc"
180+dependencies = [
181+ "actix-router",
182+ "proc-macro2",
183+ "quote",
184+ "syn",
185+]
186+
187+[[package]]
188+name = "adler"
189+version = "1.0.2"
190+source = "registry+https://github.com/rust-lang/crates.io-index"
191+checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe"
192+
193+[[package]]
194+name = "ahash"
195+version = "0.7.6"
196+source = "registry+https://github.com/rust-lang/crates.io-index"
197+checksum = "fcb51a0695d8f838b1ee009b3fbf66bda078cd64590202a864a8f3e8c4315c47"
198+dependencies = [
199+ "getrandom",
200+ "once_cell",
201+ "version_check",
202+]
203+
204+[[package]]
205 name = "aho-corasick"
206 version = "0.7.18"
207 source = "registry+https://github.com/rust-lang/crates.io-index"
208@@ -12,10 +208,31 @@ "memchr",
209 ]
210
211 [[package]]
212+name = "alloc-no-stdlib"
213+version = "2.0.3"
214+source = "registry+https://github.com/rust-lang/crates.io-index"
215+checksum = "35ef4730490ad1c4eae5c4325b2a95f521d023e5c885853ff7aca0a6a1631db3"
216+
217+[[package]]
218+name = "alloc-stdlib"
219+version = "0.2.1"
220+source = "registry+https://github.com/rust-lang/crates.io-index"
221+checksum = "697ed7edc0f1711de49ce108c541623a0af97c6c60b2f6e2b65229847ac843c2"
222+dependencies = [
223+ "alloc-no-stdlib",
224+]
225+
226+[[package]]
227 name = "autocfg"
228 version = "1.1.0"
229 source = "registry+https://github.com/rust-lang/crates.io-index"
230 checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa"
231+
232+[[package]]
233+name = "base64"
234+version = "0.13.0"
235+source = "registry+https://github.com/rust-lang/crates.io-index"
236+checksum = "904dfeac50f3cdaba28fc6f57fdcddb75f49ed61346676a78c4ffe55877802fd"
237
238 [[package]]
239 name = "bitflags"
240@@ -33,12 +250,60 @@ "generic-array",
241 ]
242
243 [[package]]
244+name = "block-buffer"
245+version = "0.10.2"
246+source = "registry+https://github.com/rust-lang/crates.io-index"
247+checksum = "0bf7fe51849ea569fd452f37822f606a5cabb684dc918707a0193fd4664ff324"
248+dependencies = [
249+ "generic-array",
250+]
251+
252+[[package]]
253+name = "brotli"
254+version = "3.3.4"
255+source = "registry+https://github.com/rust-lang/crates.io-index"
256+checksum = "a1a0b1dbcc8ae29329621f8d4f0d835787c1c38bb1401979b49d13b0b305ff68"
257+dependencies = [
258+ "alloc-no-stdlib",
259+ "alloc-stdlib",
260+ "brotli-decompressor",
261+]
262+
263+[[package]]
264+name = "brotli-decompressor"
265+version = "2.3.2"
266+source = "registry+https://github.com/rust-lang/crates.io-index"
267+checksum = "59ad2d4653bf5ca36ae797b1f4bb4dbddb60ce49ca4aed8a2ce4829f60425b80"
268+dependencies = [
269+ "alloc-no-stdlib",
270+ "alloc-stdlib",
271+]
272+
273+[[package]]
274 name = "bytes"
275 version = "1.1.0"
276 source = "registry+https://github.com/rust-lang/crates.io-index"
277 checksum = "c4872d67bab6358e59559027aa3b9157c53d9358c51423c17554809a8858e0f8"
278
279 [[package]]
280+name = "bytestring"
281+version = "1.0.0"
282+source = "registry+https://github.com/rust-lang/crates.io-index"
283+checksum = "90706ba19e97b90786e19dc0d5e2abd80008d99d4c0c5d1ad0b5e72cec7c494d"
284+dependencies = [
285+ "bytes",
286+]
287+
288+[[package]]
289+name = "cc"
290+version = "1.0.73"
291+source = "registry+https://github.com/rust-lang/crates.io-index"
292+checksum = "2fff2a6927b3bb87f9595d67196a70493f627687a71d87a0d692242c33f58c11"
293+dependencies = [
294+ "jobserver",
295+]
296+
297+[[package]]
298 name = "cfg-if"
299 version = "1.0.0"
300 source = "registry+https://github.com/rust-lang/crates.io-index"
301@@ -53,11 +318,28 @@ dependencies = [
302 "libc",
303 "num-integer",
304 "num-traits",
305- "time",
306+ "time 0.1.44",
307 "winapi",
308 ]
309
310 [[package]]
311+name = "convert_case"
312+version = "0.4.0"
313+source = "registry+https://github.com/rust-lang/crates.io-index"
314+checksum = "6245d59a3e82a7fc217c5828a6692dbc6dfb63a0c8c90495621f7b9d79704a0e"
315+
316+[[package]]
317+name = "cookie"
318+version = "0.16.0"
319+source = "registry+https://github.com/rust-lang/crates.io-index"
320+checksum = "94d4706de1b0fa5b132270cddffa8585166037822e260a944fe161acd137ca05"
321+dependencies = [
322+ "percent-encoding",
323+ "time 0.3.9",
324+ "version_check",
325+]
326+
327+[[package]]
328 name = "cpufeatures"
329 version = "0.2.2"
330 source = "registry+https://github.com/rust-lang/crates.io-index"
331@@ -67,6 +349,38 @@ "libc",
332 ]
333
334 [[package]]
335+name = "crc32fast"
336+version = "1.3.2"
337+source = "registry+https://github.com/rust-lang/crates.io-index"
338+checksum = "b540bd8bc810d3885c6ea91e2018302f68baba2129ab3e88f32389ee9370880d"
339+dependencies = [
340+ "cfg-if",
341+]
342+
343+[[package]]
344+name = "crypto-common"
345+version = "0.1.3"
346+source = "registry+https://github.com/rust-lang/crates.io-index"
347+checksum = "57952ca27b5e3606ff4dd79b0020231aaf9d6aa76dc05fd30137538c50bd3ce8"
348+dependencies = [
349+ "generic-array",
350+ "typenum",
351+]
352+
353+[[package]]
354+name = "derive_more"
355+version = "0.99.17"
356+source = "registry+https://github.com/rust-lang/crates.io-index"
357+checksum = "4fb810d30a7c1953f91334de7244731fc3f3c10d7fe163338a35b9f640960321"
358+dependencies = [
359+ "convert_case",
360+ "proc-macro2",
361+ "quote",
362+ "rustc_version",
363+ "syn",
364+]
365+
366+[[package]]
367 name = "digest"
368 version = "0.9.0"
369 source = "registry+https://github.com/rust-lang/crates.io-index"
370@@ -76,6 +390,25 @@ "generic-array",
371 ]
372
373 [[package]]
374+name = "digest"
375+version = "0.10.3"
376+source = "registry+https://github.com/rust-lang/crates.io-index"
377+checksum = "f2fb860ca6fafa5552fb6d0e816a69c8e49f0908bf524e30a90d97c85892d506"
378+dependencies = [
379+ "block-buffer 0.10.2",
380+ "crypto-common",
381+]
382+
383+[[package]]
384+name = "encoding_rs"
385+version = "0.8.31"
386+source = "registry+https://github.com/rust-lang/crates.io-index"
387+checksum = "9852635589dc9f9ea1b6fe9f05b50ef208c85c834a562f0c6abb1c475736ec2b"
388+dependencies = [
389+ "cfg-if",
390+]
391+
392+[[package]]
393 name = "filetime"
394 version = "0.2.16"
395 source = "registry+https://github.com/rust-lang/crates.io-index"
396@@ -88,12 +421,40 @@ "winapi",
397 ]
398
399 [[package]]
400+name = "firestorm"
401+version = "0.5.0"
402+source = "registry+https://github.com/rust-lang/crates.io-index"
403+checksum = "4d3d6188b8804df28032815ea256b6955c9625c24da7525f387a7af02fbb8f01"
404+
405+[[package]]
406+name = "flate2"
407+version = "1.0.23"
408+source = "registry+https://github.com/rust-lang/crates.io-index"
409+checksum = "b39522e96686d38f4bc984b9198e3a0613264abaebaff2c5c918bfa6b6da09af"
410+dependencies = [
411+ "cfg-if",
412+ "crc32fast",
413+ "libc",
414+ "miniz_oxide",
415+]
416+
417+[[package]]
418 name = "fnv"
419 version = "1.0.7"
420 source = "registry+https://github.com/rust-lang/crates.io-index"
421 checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1"
422
423 [[package]]
424+name = "form_urlencoded"
425+version = "1.0.1"
426+source = "registry+https://github.com/rust-lang/crates.io-index"
427+checksum = "5fc25a87fa4fd2094bffb06925852034d90a17f0d1e05197d4956d3555752191"
428+dependencies = [
429+ "matches",
430+ "percent-encoding",
431+]
432+
433+[[package]]
434 name = "futures-channel"
435 version = "0.3.21"
436 source = "registry+https://github.com/rust-lang/crates.io-index"
437@@ -140,6 +501,17 @@ checksum = "fd48d33ec7f05fbfa152300fdad764757cbded343c1aa1cff2fbaf4134851803"
438 dependencies = [
439 "typenum",
440 "version_check",
441+]
442+
443+[[package]]
444+name = "getrandom"
445+version = "0.2.6"
446+source = "registry+https://github.com/rust-lang/crates.io-index"
447+checksum = "9be70c98951c83b8d2f8f60d7065fa6d5146873094452a1008da8c2f1e4205ad"
448+dependencies = [
449+ "cfg-if",
450+ "libc",
451+ "wasi 0.10.0+wasi-snapshot-preview1",
452 ]
453
454 [[package]]
455@@ -244,6 +616,17 @@ "want",
456 ]
457
458 [[package]]
459+name = "idna"
460+version = "0.2.3"
461+source = "registry+https://github.com/rust-lang/crates.io-index"
462+checksum = "418a0a6fab821475f634efe3ccc45c013f742efe03d853e8d3355d5cb850ecf8"
463+dependencies = [
464+ "matches",
465+ "unicode-bidi",
466+ "unicode-normalization",
467+]
468+
469+[[package]]
470 name = "indexmap"
471 version = "1.8.1"
472 source = "registry+https://github.com/rust-lang/crates.io-index"
473@@ -264,6 +647,21 @@ name = "itoap"
474 version = "1.0.1"
475 source = "registry+https://github.com/rust-lang/crates.io-index"
476 checksum = "9028f49264629065d057f340a86acb84867925865f73bbf8d47b4d149a7e88b8"
477+
478+[[package]]
479+name = "jobserver"
480+version = "0.1.24"
481+source = "registry+https://github.com/rust-lang/crates.io-index"
482+checksum = "af25a77299a7f711a01975c35a6a424eb6862092cc2d6c72c4ed6cbc56dfc1fa"
483+dependencies = [
484+ "libc",
485+]
486+
487+[[package]]
488+name = "language-tags"
489+version = "0.3.2"
490+source = "registry+https://github.com/rust-lang/crates.io-index"
491+checksum = "d4345964bb142484797b161f473a503a434de77149dd8c7427788c6e13379388"
492
493 [[package]]
494 name = "lazy_static"
495@@ -278,6 +676,24 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
496 checksum = "5916d2ae698f6de9bfb891ad7a8d65c09d232dc58cc4ac433c7da3b2fd84bc2b"
497
498 [[package]]
499+name = "local-channel"
500+version = "0.1.3"
501+source = "registry+https://github.com/rust-lang/crates.io-index"
502+checksum = "7f303ec0e94c6c54447f84f3b0ef7af769858a9c4ef56ef2a986d3dcd4c3fc9c"
503+dependencies = [
504+ "futures-core",
505+ "futures-sink",
506+ "futures-util",
507+ "local-waker",
508+]
509+
510+[[package]]
511+name = "local-waker"
512+version = "0.1.3"
513+source = "registry+https://github.com/rust-lang/crates.io-index"
514+checksum = "e34f76eb3611940e0e7d53a9aaa4e6a3151f69541a282fd0dad5571420c53ff1"
515+
516+[[package]]
517 name = "lock_api"
518 version = "0.4.7"
519 source = "registry+https://github.com/rust-lang/crates.io-index"
520@@ -300,6 +716,7 @@ [[package]]
521 name = "macroblog"
522 version = "0.1.0"
523 dependencies = [
524+ "actix-web",
525 "chrono",
526 "hyper",
527 "regex",
528@@ -309,10 +726,31 @@ "tokio",
529 ]
530
531 [[package]]
532+name = "matches"
533+version = "0.1.9"
534+source = "registry+https://github.com/rust-lang/crates.io-index"
535+checksum = "a3e378b66a060d48947b590737b30a1be76706c8dd7b8ba0f2fe3989c68a853f"
536+
537+[[package]]
538 name = "memchr"
539 version = "2.5.0"
540 source = "registry+https://github.com/rust-lang/crates.io-index"
541 checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d"
542+
543+[[package]]
544+name = "mime"
545+version = "0.3.16"
546+source = "registry+https://github.com/rust-lang/crates.io-index"
547+checksum = "2a60c7ce501c71e03a9c9c0d35b861413ae925bd979cc7a4e30d060069aaac8d"
548+
549+[[package]]
550+name = "miniz_oxide"
551+version = "0.5.1"
552+source = "registry+https://github.com/rust-lang/crates.io-index"
553+checksum = "d2b29bd4bc3f33391105ebee3589c19197c4271e3e5a9ec9bfe8127eeff8f082"
554+dependencies = [
555+ "adler",
556+]
557
558 [[package]]
559 name = "mio"
560@@ -376,6 +814,15 @@ "libc",
561 ]
562
563 [[package]]
564+name = "num_threads"
565+version = "0.1.6"
566+source = "registry+https://github.com/rust-lang/crates.io-index"
567+checksum = "2819ce041d2ee131036f4fc9d6ae7ae125a3a40e97ba64d04fe799ad9dabbb44"
568+dependencies = [
569+ "libc",
570+]
571+
572+[[package]]
573 name = "once_cell"
574 version = "1.10.0"
575 source = "registry+https://github.com/rust-lang/crates.io-index"
576@@ -411,6 +858,18 @@ "windows-sys",
577 ]
578
579 [[package]]
580+name = "paste"
581+version = "1.0.7"
582+source = "registry+https://github.com/rust-lang/crates.io-index"
583+checksum = "0c520e05135d6e763148b6426a837e239041653ba7becd2e538c076c738025fc"
584+
585+[[package]]
586+name = "percent-encoding"
587+version = "2.1.0"
588+source = "registry+https://github.com/rust-lang/crates.io-index"
589+checksum = "d4fd5641d01c8f18a23da7b6fe29298ff4b55afcccdf78973b24cf3175fee32e"
590+
591+[[package]]
592 name = "pin-project-lite"
593 version = "0.2.9"
594 source = "registry+https://github.com/rust-lang/crates.io-index"
595@@ -421,6 +880,12 @@ name = "pin-utils"
596 version = "0.1.0"
597 source = "registry+https://github.com/rust-lang/crates.io-index"
598 checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184"
599+
600+[[package]]
601+name = "ppv-lite86"
602+version = "0.2.16"
603+source = "registry+https://github.com/rust-lang/crates.io-index"
604+checksum = "eb9f9e6e233e5c4a35559a617bf40a4ec447db2e84c20b55a6f83167b7e57872"
605
606 [[package]]
607 name = "proc-macro2"
608@@ -441,6 +906,36 @@ "proc-macro2",
609 ]
610
611 [[package]]
612+name = "rand"
613+version = "0.8.5"
614+source = "registry+https://github.com/rust-lang/crates.io-index"
615+checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404"
616+dependencies = [
617+ "libc",
618+ "rand_chacha",
619+ "rand_core",
620+]
621+
622+[[package]]
623+name = "rand_chacha"
624+version = "0.3.1"
625+source = "registry+https://github.com/rust-lang/crates.io-index"
626+checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88"
627+dependencies = [
628+ "ppv-lite86",
629+ "rand_core",
630+]
631+
632+[[package]]
633+name = "rand_core"
634+version = "0.6.3"
635+source = "registry+https://github.com/rust-lang/crates.io-index"
636+checksum = "d34f1408f55294453790c48b2f1ebbb1c5b4b7563eb1f418bcfcfdbb06ebb4e7"
637+dependencies = [
638+ "getrandom",
639+]
640+
641+[[package]]
642 name = "redox_syscall"
643 version = "0.2.13"
644 source = "registry+https://github.com/rust-lang/crates.io-index"
645@@ -501,6 +996,15 @@ "walkdir",
646 ]
647
648 [[package]]
649+name = "rustc_version"
650+version = "0.4.0"
651+source = "registry+https://github.com/rust-lang/crates.io-index"
652+checksum = "bfa0f585226d2e68097d4f95d113b15b83a82e819ab25717ec0590d9584ef366"
653+dependencies = [
654+ "semver",
655+]
656+
657+[[package]]
658 name = "ryu"
659 version = "1.0.9"
660 source = "registry+https://github.com/rust-lang/crates.io-index"
661@@ -560,6 +1064,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
662 checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd"
663
664 [[package]]
665+name = "semver"
666+version = "1.0.9"
667+source = "registry+https://github.com/rust-lang/crates.io-index"
668+checksum = "8cb243bdfdb5936c8dc3c45762a19d12ab4550cdc753bc247637d4ec35a040fd"
669+
670+[[package]]
671 name = "serde"
672 version = "1.0.137"
673 source = "registry+https://github.com/rust-lang/crates.io-index"
674@@ -580,15 +1090,49 @@ "syn",
675 ]
676
677 [[package]]
678+name = "serde_json"
679+version = "1.0.81"
680+source = "registry+https://github.com/rust-lang/crates.io-index"
681+checksum = "9b7ce2b32a1aed03c558dc61a5cd328f15aff2dbc17daad8fb8af04d2100e15c"
682+dependencies = [
683+ "itoa",
684+ "ryu",
685+ "serde",
686+]
687+
688+[[package]]
689+name = "serde_urlencoded"
690+version = "0.7.1"
691+source = "registry+https://github.com/rust-lang/crates.io-index"
692+checksum = "d3491c14715ca2294c4d6a88f15e84739788c1d030eed8c110436aafdaa2f3fd"
693+dependencies = [
694+ "form_urlencoded",
695+ "itoa",
696+ "ryu",
697+ "serde",
698+]
699+
700+[[package]]
701+name = "sha-1"
702+version = "0.10.0"
703+source = "registry+https://github.com/rust-lang/crates.io-index"
704+checksum = "028f48d513f9678cda28f6e4064755b3fbb2af6acd672f2c209b62323f7aea0f"
705+dependencies = [
706+ "cfg-if",
707+ "cpufeatures",
708+ "digest 0.10.3",
709+]
710+
711+[[package]]
712 name = "sha2"
713 version = "0.9.9"
714 source = "registry+https://github.com/rust-lang/crates.io-index"
715 checksum = "4d58a1e1bf39749807d89cf2d98ac2dfa0ff1cb3faa38fbb64dd88ac8013d800"
716 dependencies = [
717- "block-buffer",
718+ "block-buffer 0.9.0",
719 "cfg-if",
720 "cpufeatures",
721- "digest",
722+ "digest 0.9.0",
723 "opaque-debug",
724 ]
725
726@@ -646,6 +1190,39 @@ "winapi",
727 ]
728
729 [[package]]
730+name = "time"
731+version = "0.3.9"
732+source = "registry+https://github.com/rust-lang/crates.io-index"
733+checksum = "c2702e08a7a860f005826c6815dcac101b19b5eb330c27fe4a5928fec1d20ddd"
734+dependencies = [
735+ "itoa",
736+ "libc",
737+ "num_threads",
738+ "time-macros",
739+]
740+
741+[[package]]
742+name = "time-macros"
743+version = "0.2.4"
744+source = "registry+https://github.com/rust-lang/crates.io-index"
745+checksum = "42657b1a6f4d817cda8e7a0ace261fe0cc946cf3a80314390b22cc61ae080792"
746+
747+[[package]]
748+name = "tinyvec"
749+version = "1.6.0"
750+source = "registry+https://github.com/rust-lang/crates.io-index"
751+checksum = "87cc5ceb3875bb20c2890005a4e226a4651264a5c75edb2421b52861a0a0cb50"
752+dependencies = [
753+ "tinyvec_macros",
754+]
755+
756+[[package]]
757+name = "tinyvec_macros"
758+version = "0.1.0"
759+source = "registry+https://github.com/rust-lang/crates.io-index"
760+checksum = "cda74da7e1a664f795bb1f8a87ec406fb89a02522cf6e50620d016add6dbbf5c"
761+
762+[[package]]
763 name = "tokio"
764 version = "1.18.1"
765 source = "registry+https://github.com/rust-lang/crates.io-index"
766@@ -712,6 +1289,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
767 checksum = "5d0ecdcb44a79f0fe9844f0c4f33a342cbcbb5117de8001e6ba0dc2351327d09"
768 dependencies = [
769 "cfg-if",
770+ "log",
771 "pin-project-lite",
772 "tracing-attributes",
773 "tracing-core",
774@@ -750,12 +1328,39 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
775 checksum = "dcf81ac59edc17cc8697ff311e8f5ef2d99fcbd9817b34cec66f90b6c3dfd987"
776
777 [[package]]
778+name = "unicode-bidi"
779+version = "0.3.8"
780+source = "registry+https://github.com/rust-lang/crates.io-index"
781+checksum = "099b7128301d285f79ddd55b9a83d5e6b9e97c92e0ea0daebee7263e932de992"
782+
783+[[package]]
784+name = "unicode-normalization"
785+version = "0.1.19"
786+source = "registry+https://github.com/rust-lang/crates.io-index"
787+checksum = "d54590932941a9e9266f0832deed84ebe1bf2e4c9e4a3554d393d18f5e854bf9"
788+dependencies = [
789+ "tinyvec",
790+]
791+
792+[[package]]
793 name = "unicode-xid"
794 version = "0.2.3"
795 source = "registry+https://github.com/rust-lang/crates.io-index"
796 checksum = "957e51f3646910546462e67d5f7599b9e4fb8acdd304b087a6494730f9eebf04"
797
798 [[package]]
799+name = "url"
800+version = "2.2.2"
801+source = "registry+https://github.com/rust-lang/crates.io-index"
802+checksum = "a507c383b2d33b5fc35d1861e77e6b383d158b2da5e14fe51b83dfedf6fd578c"
803+dependencies = [
804+ "form_urlencoded",
805+ "idna",
806+ "matches",
807+ "percent-encoding",
808+]
809+
810+[[package]]
811 name = "version_check"
812 version = "0.9.4"
813 source = "registry+https://github.com/rust-lang/crates.io-index"
814@@ -867,3 +1472,32 @@ name = "windows_x86_64_msvc"
815 version = "0.36.1"
816 source = "registry+https://github.com/rust-lang/crates.io-index"
817 checksum = "c811ca4a8c853ef420abd8592ba53ddbbac90410fab6903b3e79972a631f7680"
818+
819+[[package]]
820+name = "zstd"
821+version = "0.10.2+zstd.1.5.2"
822+source = "registry+https://github.com/rust-lang/crates.io-index"
823+checksum = "5f4a6bd64f22b5e3e94b4e238669ff9f10815c27a5180108b849d24174a83847"
824+dependencies = [
825+ "zstd-safe",
826+]
827+
828+[[package]]
829+name = "zstd-safe"
830+version = "4.1.6+zstd.1.5.2"
831+source = "registry+https://github.com/rust-lang/crates.io-index"
832+checksum = "94b61c51bb270702d6167b8ce67340d2754b088d0c091b06e593aa772c3ee9bb"
833+dependencies = [
834+ "libc",
835+ "zstd-sys",
836+]
837+
838+[[package]]
839+name = "zstd-sys"
840+version = "1.6.3+zstd.1.5.2"
841+source = "registry+https://github.com/rust-lang/crates.io-index"
842+checksum = "fc49afa5c8d634e75761feda8c592051e7eeb4683ba827211eb0d731d3402ea8"
843+dependencies = [
844+ "cc",
845+ "libc",
846+]
847diff --git a/Cargo.toml b/Cargo.toml
848index a241371df453dc2b6745ca43f8fc86ceecfd30a2..886081f508afde49126f89ec2a9bfe11d94e5f7b 100644
849--- a/Cargo.toml
850+++ b/Cargo.toml
851@@ -10,6 +10,7 @@ tokio = { version = "1", features = ["full"] }
852 regex = "1.5"
853 rust-embed = "6.4.0"
854 chrono = "0.4"
855+actix-web = "4"
856
857 [profile.release]
858 opt-level = 'z'
859@@ -21,3 +22,10 @@
860 [lib]
861 name="macroblog"
862 path="src/lib.rs"
863+
864+[[bin]]
865+name = "hyper"
866+
867+
868+[[bin]]
869+name = "actix"
870diff --git a/Procfile b/Procfile
871index 0c1f273d817fb263fc15d1b611c1214104bce5b6..d574f7a41b4b7eb49a7592690dc00ef26fd2bbc8 100644
872--- a/Procfile
873+++ b/Procfile
874@@ -1 +1 @@
875-web: ./target/release/macroblog
876\ No newline at end of file
877+web: ./target/release/hyper
878diff --git a/src/bin/actix.rs b/src/bin/actix.rs
879new file mode 100644
880index 0000000000000000000000000000000000000000..dd03ecea2991a37f05fa83202b0ca81f579a6ffb
881--- /dev/null
882+++ b/src/bin/actix.rs
883@@ -0,0 +1,34 @@
884+use actix_web::{get, web, App, HttpResponse, HttpServer, Responder, http::header::ContentType};
885+use macroblog::blog::{render_index_page, render_post_page};
886+
887+#[get("/")]
888+async fn index() -> impl Responder {
889+ let body = render_index_page();
890+
891+ HttpResponse::Ok()
892+ .content_type(ContentType::html())
893+ .body(body)
894+}
895+
896+
897+#[get("/posts/{name}")]
898+async fn posts(name: web::Path<String>) -> impl Responder {
899+ let body = render_post_page(&name);
900+
901+ HttpResponse::Ok()
902+ .content_type(ContentType::html())
903+ .body(body)
904+}
905+
906+
907+#[actix_web::main]
908+async fn main() -> std::io::Result<()> {
909+ HttpServer::new(|| {
910+ App::new()
911+ .service(index)
912+ .service(posts)
913+ })
914+ .bind(("0.0.0.0", 3000))?
915+ .run()
916+ .await
917+}
918diff --git a/src/main.rs b/src/bin/hyper.rs
919rename from src/main.rs
920rename to src/bin/hyper.rs
921index ed347135f021e81ec594c03a3b9266779fff82bd..3f23f18797072248065804ea49477ce5eac0d8bc 100644
922--- a/src/main.rs
923+++ b/src/bin/hyper.rs
924@@ -1,4 +1,3 @@
925-
926 use std::convert::Infallible;
927 use std::{env};
928 use std::net::SocketAddr;