Browse Source

Implement pooled connections

pull/86/head
Toromino 5 months ago
parent
commit
5dd167e427

+ 121
- 85
Cargo.lock View File

15
 
15
 
16
 [[package]]
16
 [[package]]
17
 name = "arrayvec"
17
 name = "arrayvec"
18
-version = "0.4.10"
18
+version = "0.4.11"
19
 source = "registry+https://github.com/rust-lang/crates.io-index"
19
 source = "registry+https://github.com/rust-lang/crates.io-index"
20
 dependencies = [
20
 dependencies = [
21
  "nodrop 0.1.13 (registry+https://github.com/rust-lang/crates.io-index)",
21
  "nodrop 0.1.13 (registry+https://github.com/rust-lang/crates.io-index)",
23
 
23
 
24
 [[package]]
24
 [[package]]
25
 name = "atty"
25
 name = "atty"
26
-version = "0.2.11"
26
+version = "0.2.12"
27
 source = "registry+https://github.com/rust-lang/crates.io-index"
27
 source = "registry+https://github.com/rust-lang/crates.io-index"
28
 dependencies = [
28
 dependencies = [
29
  "libc 0.2.59 (registry+https://github.com/rust-lang/crates.io-index)",
29
  "libc 0.2.59 (registry+https://github.com/rust-lang/crates.io-index)",
30
- "termion 1.5.3 (registry+https://github.com/rust-lang/crates.io-index)",
31
  "winapi 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)",
30
  "winapi 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)",
32
 ]
31
 ]
33
 
32
 
157
 ]
156
 ]
158
 
157
 
159
 [[package]]
158
 [[package]]
160
-name = "cached"
161
-version = "0.9.0"
162
-source = "registry+https://github.com/rust-lang/crates.io-index"
163
-dependencies = [
164
- "once_cell 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)",
165
-]
166
-
167
-[[package]]
168
 name = "cc"
159
 name = "cc"
169
 version = "1.0.37"
160
 version = "1.0.37"
170
 source = "registry+https://github.com/rust-lang/crates.io-index"
161
 source = "registry+https://github.com/rust-lang/crates.io-index"
236
  "cookie 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)",
227
  "cookie 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)",
237
  "failure 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
228
  "failure 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
238
  "idna 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
229
  "idna 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
239
- "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
230
+ "log 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)",
240
  "publicsuffix 1.5.2 (registry+https://github.com/rust-lang/crates.io-index)",
231
  "publicsuffix 1.5.2 (registry+https://github.com/rust-lang/crates.io-index)",
241
  "serde 1.0.94 (registry+https://github.com/rust-lang/crates.io-index)",
232
  "serde 1.0.94 (registry+https://github.com/rust-lang/crates.io-index)",
242
  "serde_json 1.0.40 (registry+https://github.com/rust-lang/crates.io-index)",
233
  "serde_json 1.0.40 (registry+https://github.com/rust-lang/crates.io-index)",
281
 version = "0.7.1"
272
 version = "0.7.1"
282
 source = "registry+https://github.com/rust-lang/crates.io-index"
273
 source = "registry+https://github.com/rust-lang/crates.io-index"
283
 dependencies = [
274
 dependencies = [
284
- "arrayvec 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)",
275
+ "arrayvec 0.4.11 (registry+https://github.com/rust-lang/crates.io-index)",
285
  "cfg-if 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)",
276
  "cfg-if 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)",
286
  "crossbeam-utils 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)",
277
  "crossbeam-utils 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)",
287
  "lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
278
  "lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
326
 source = "registry+https://github.com/rust-lang/crates.io-index"
317
 source = "registry+https://github.com/rust-lang/crates.io-index"
327
 dependencies = [
318
 dependencies = [
328
  "devise_core 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
319
  "devise_core 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
329
- "quote 0.6.12 (registry+https://github.com/rust-lang/crates.io-index)",
320
+ "quote 0.6.13 (registry+https://github.com/rust-lang/crates.io-index)",
330
 ]
321
 ]
331
 
322
 
332
 [[package]]
323
 [[package]]
336
 dependencies = [
327
 dependencies = [
337
  "bitflags 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
328
  "bitflags 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
338
  "proc-macro2 0.4.30 (registry+https://github.com/rust-lang/crates.io-index)",
329
  "proc-macro2 0.4.30 (registry+https://github.com/rust-lang/crates.io-index)",
339
- "quote 0.6.12 (registry+https://github.com/rust-lang/crates.io-index)",
330
+ "quote 0.6.13 (registry+https://github.com/rust-lang/crates.io-index)",
340
  "syn 0.15.39 (registry+https://github.com/rust-lang/crates.io-index)",
331
  "syn 0.15.39 (registry+https://github.com/rust-lang/crates.io-index)",
341
 ]
332
 ]
342
 
333
 
350
  "chrono 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)",
341
  "chrono 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)",
351
  "diesel_derives 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
342
  "diesel_derives 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
352
  "pq-sys 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
343
  "pq-sys 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
344
+ "r2d2 0.8.5 (registry+https://github.com/rust-lang/crates.io-index)",
353
  "serde_json 1.0.40 (registry+https://github.com/rust-lang/crates.io-index)",
345
  "serde_json 1.0.40 (registry+https://github.com/rust-lang/crates.io-index)",
354
 ]
346
 ]
355
 
347
 
359
 source = "registry+https://github.com/rust-lang/crates.io-index"
351
 source = "registry+https://github.com/rust-lang/crates.io-index"
360
 dependencies = [
352
 dependencies = [
361
  "proc-macro2 0.4.30 (registry+https://github.com/rust-lang/crates.io-index)",
353
  "proc-macro2 0.4.30 (registry+https://github.com/rust-lang/crates.io-index)",
362
- "quote 0.6.12 (registry+https://github.com/rust-lang/crates.io-index)",
354
+ "quote 0.6.13 (registry+https://github.com/rust-lang/crates.io-index)",
363
  "syn 0.15.39 (registry+https://github.com/rust-lang/crates.io-index)",
355
  "syn 0.15.39 (registry+https://github.com/rust-lang/crates.io-index)",
364
 ]
356
 ]
365
 
357
 
413
 source = "registry+https://github.com/rust-lang/crates.io-index"
405
 source = "registry+https://github.com/rust-lang/crates.io-index"
414
 dependencies = [
406
 dependencies = [
415
  "proc-macro2 0.4.30 (registry+https://github.com/rust-lang/crates.io-index)",
407
  "proc-macro2 0.4.30 (registry+https://github.com/rust-lang/crates.io-index)",
416
- "quote 0.6.12 (registry+https://github.com/rust-lang/crates.io-index)",
408
+ "quote 0.6.13 (registry+https://github.com/rust-lang/crates.io-index)",
417
  "syn 0.15.39 (registry+https://github.com/rust-lang/crates.io-index)",
409
  "syn 0.15.39 (registry+https://github.com/rust-lang/crates.io-index)",
418
  "synstructure 0.10.2 (registry+https://github.com/rust-lang/crates.io-index)",
410
  "synstructure 0.10.2 (registry+https://github.com/rust-lang/crates.io-index)",
419
 ]
411
 ]
557
  "futures 0.1.28 (registry+https://github.com/rust-lang/crates.io-index)",
549
  "futures 0.1.28 (registry+https://github.com/rust-lang/crates.io-index)",
558
  "http 0.1.17 (registry+https://github.com/rust-lang/crates.io-index)",
550
  "http 0.1.17 (registry+https://github.com/rust-lang/crates.io-index)",
559
  "indexmap 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
551
  "indexmap 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
560
- "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
552
+ "log 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)",
561
  "slab 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
553
  "slab 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
562
  "string 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
554
  "string 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
563
  "tokio-io 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)",
555
  "tokio-io 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)",
564
 ]
556
 ]
565
 
557
 
566
 [[package]]
558
 [[package]]
559
+name = "hashbrown"
560
+version = "0.1.8"
561
+source = "registry+https://github.com/rust-lang/crates.io-index"
562
+dependencies = [
563
+ "byteorder 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
564
+ "scopeguard 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
565
+]
566
+
567
+[[package]]
567
 name = "http"
568
 name = "http"
568
 version = "0.1.17"
569
 version = "0.1.17"
569
 source = "registry+https://github.com/rust-lang/crates.io-index"
570
 source = "registry+https://github.com/rust-lang/crates.io-index"
614
 
615
 
615
 [[package]]
616
 [[package]]
616
 name = "hyper"
617
 name = "hyper"
617
-version = "0.12.31"
618
+version = "0.12.32"
618
 source = "registry+https://github.com/rust-lang/crates.io-index"
619
 source = "registry+https://github.com/rust-lang/crates.io-index"
619
 dependencies = [
620
 dependencies = [
620
  "bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)",
621
  "bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)",
626
  "httparse 1.3.4 (registry+https://github.com/rust-lang/crates.io-index)",
627
  "httparse 1.3.4 (registry+https://github.com/rust-lang/crates.io-index)",
627
  "iovec 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
628
  "iovec 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
628
  "itoa 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)",
629
  "itoa 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)",
629
- "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
630
+ "log 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)",
630
  "net2 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)",
631
  "net2 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)",
631
  "rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
632
  "rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
632
  "time 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)",
633
  "time 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)",
648
 dependencies = [
649
 dependencies = [
649
  "bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)",
650
  "bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)",
650
  "futures 0.1.28 (registry+https://github.com/rust-lang/crates.io-index)",
651
  "futures 0.1.28 (registry+https://github.com/rust-lang/crates.io-index)",
651
- "hyper 0.12.31 (registry+https://github.com/rust-lang/crates.io-index)",
652
+ "hyper 0.12.32 (registry+https://github.com/rust-lang/crates.io-index)",
652
  "native-tls 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
653
  "native-tls 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
653
  "tokio-io 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)",
654
  "tokio-io 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)",
654
 ]
655
 ]
715
 dependencies = [
716
 dependencies = [
716
  "base64 0.10.1 (registry+https://github.com/rust-lang/crates.io-index)",
717
  "base64 0.10.1 (registry+https://github.com/rust-lang/crates.io-index)",
717
  "bcrypt 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)",
718
  "bcrypt 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)",
718
- "cached 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)",
719
  "chrono 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)",
719
  "chrono 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)",
720
  "config 0.9.3 (registry+https://github.com/rust-lang/crates.io-index)",
720
  "config 0.9.3 (registry+https://github.com/rust-lang/crates.io-index)",
721
  "diesel 1.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
721
  "diesel 1.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
722
  "getopts 0.2.19 (registry+https://github.com/rust-lang/crates.io-index)",
722
  "getopts 0.2.19 (registry+https://github.com/rust-lang/crates.io-index)",
723
  "lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
723
  "lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
724
+ "lru 0.1.15 (registry+https://github.com/rust-lang/crates.io-index)",
724
  "openssl 0.10.23 (registry+https://github.com/rust-lang/crates.io-index)",
725
  "openssl 0.10.23 (registry+https://github.com/rust-lang/crates.io-index)",
725
  "openssl-sys 0.9.47 (registry+https://github.com/rust-lang/crates.io-index)",
726
  "openssl-sys 0.9.47 (registry+https://github.com/rust-lang/crates.io-index)",
726
  "pem 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
727
  "pem 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
786
 ]
787
 ]
787
 
788
 
788
 [[package]]
789
 [[package]]
790
+name = "lock_api"
791
+version = "0.2.0"
792
+source = "registry+https://github.com/rust-lang/crates.io-index"
793
+dependencies = [
794
+ "scopeguard 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
795
+]
796
+
797
+[[package]]
789
 name = "log"
798
 name = "log"
790
 version = "0.3.9"
799
 version = "0.3.9"
791
 source = "registry+https://github.com/rust-lang/crates.io-index"
800
 source = "registry+https://github.com/rust-lang/crates.io-index"
792
 dependencies = [
801
 dependencies = [
793
- "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
802
+ "log 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)",
794
 ]
803
 ]
795
 
804
 
796
 [[package]]
805
 [[package]]
797
 name = "log"
806
 name = "log"
798
-version = "0.4.6"
807
+version = "0.4.7"
799
 source = "registry+https://github.com/rust-lang/crates.io-index"
808
 source = "registry+https://github.com/rust-lang/crates.io-index"
800
 dependencies = [
809
 dependencies = [
801
  "cfg-if 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)",
810
  "cfg-if 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)",
802
 ]
811
 ]
803
 
812
 
804
 [[package]]
813
 [[package]]
814
+name = "lru"
815
+version = "0.1.15"
816
+source = "registry+https://github.com/rust-lang/crates.io-index"
817
+dependencies = [
818
+ "hashbrown 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)",
819
+]
820
+
821
+[[package]]
805
 name = "maplit"
822
 name = "maplit"
806
 version = "1.0.1"
823
 version = "1.0.1"
807
 source = "registry+https://github.com/rust-lang/crates.io-index"
824
 source = "registry+https://github.com/rust-lang/crates.io-index"
877
  "iovec 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
894
  "iovec 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
878
  "kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
895
  "kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
879
  "libc 0.2.59 (registry+https://github.com/rust-lang/crates.io-index)",
896
  "libc 0.2.59 (registry+https://github.com/rust-lang/crates.io-index)",
880
- "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
897
+ "log 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)",
881
  "miow 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
898
  "miow 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
882
  "net2 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)",
899
  "net2 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)",
883
  "slab 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
900
  "slab 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
890
 source = "registry+https://github.com/rust-lang/crates.io-index"
907
 source = "registry+https://github.com/rust-lang/crates.io-index"
891
 dependencies = [
908
 dependencies = [
892
  "lazycell 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
909
  "lazycell 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
893
- "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
910
+ "log 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)",
894
  "mio 0.6.19 (registry+https://github.com/rust-lang/crates.io-index)",
911
  "mio 0.6.19 (registry+https://github.com/rust-lang/crates.io-index)",
895
  "slab 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
912
  "slab 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
896
 ]
913
 ]
913
 dependencies = [
930
 dependencies = [
914
  "lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
931
  "lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
915
  "libc 0.2.59 (registry+https://github.com/rust-lang/crates.io-index)",
932
  "libc 0.2.59 (registry+https://github.com/rust-lang/crates.io-index)",
916
- "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
933
+ "log 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)",
917
  "openssl 0.10.23 (registry+https://github.com/rust-lang/crates.io-index)",
934
  "openssl 0.10.23 (registry+https://github.com/rust-lang/crates.io-index)",
918
  "openssl-probe 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
935
  "openssl-probe 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
919
  "openssl-sys 0.9.47 (registry+https://github.com/rust-lang/crates.io-index)",
936
  "openssl-sys 0.9.47 (registry+https://github.com/rust-lang/crates.io-index)",
999
 ]
1016
 ]
1000
 
1017
 
1001
 [[package]]
1018
 [[package]]
1002
-name = "numtoa"
1003
-version = "0.1.0"
1004
-source = "registry+https://github.com/rust-lang/crates.io-index"
1005
-
1006
-[[package]]
1007
-name = "once_cell"
1008
-version = "0.1.8"
1009
-source = "registry+https://github.com/rust-lang/crates.io-index"
1010
-dependencies = [
1011
- "parking_lot 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)",
1012
-]
1013
-
1014
-[[package]]
1015
 name = "opaque-debug"
1019
 name = "opaque-debug"
1016
 version = "0.2.2"
1020
 version = "0.2.2"
1017
 source = "registry+https://github.com/rust-lang/crates.io-index"
1021
 source = "registry+https://github.com/rust-lang/crates.io-index"
1064
 ]
1068
 ]
1065
 
1069
 
1066
 [[package]]
1070
 [[package]]
1071
+name = "parking_lot"
1072
+version = "0.8.0"
1073
+source = "registry+https://github.com/rust-lang/crates.io-index"
1074
+dependencies = [
1075
+ "lock_api 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
1076
+ "parking_lot_core 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)",
1077
+ "rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
1078
+]
1079
+
1080
+[[package]]
1067
 name = "parking_lot_core"
1081
 name = "parking_lot_core"
1068
 version = "0.4.0"
1082
 version = "0.4.0"
1069
 source = "registry+https://github.com/rust-lang/crates.io-index"
1083
 source = "registry+https://github.com/rust-lang/crates.io-index"
1076
 ]
1090
 ]
1077
 
1091
 
1078
 [[package]]
1092
 [[package]]
1093
+name = "parking_lot_core"
1094
+version = "0.5.0"
1095
+source = "registry+https://github.com/rust-lang/crates.io-index"
1096
+dependencies = [
1097
+ "cfg-if 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)",
1098
+ "cloudabi 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)",
1099
+ "libc 0.2.59 (registry+https://github.com/rust-lang/crates.io-index)",
1100
+ "rand 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)",
1101
+ "redox_syscall 0.1.56 (registry+https://github.com/rust-lang/crates.io-index)",
1102
+ "rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
1103
+ "smallvec 0.6.10 (registry+https://github.com/rust-lang/crates.io-index)",
1104
+ "winapi 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)",
1105
+]
1106
+
1107
+[[package]]
1079
 name = "pear"
1108
 name = "pear"
1080
 version = "0.1.2"
1109
 version = "0.1.2"
1081
 source = "registry+https://github.com/rust-lang/crates.io-index"
1110
 source = "registry+https://github.com/rust-lang/crates.io-index"
1089
 source = "registry+https://github.com/rust-lang/crates.io-index"
1118
 source = "registry+https://github.com/rust-lang/crates.io-index"
1090
 dependencies = [
1119
 dependencies = [
1091
  "proc-macro2 0.4.30 (registry+https://github.com/rust-lang/crates.io-index)",
1120
  "proc-macro2 0.4.30 (registry+https://github.com/rust-lang/crates.io-index)",
1092
- "quote 0.6.12 (registry+https://github.com/rust-lang/crates.io-index)",
1121
+ "quote 0.6.13 (registry+https://github.com/rust-lang/crates.io-index)",
1093
  "syn 0.15.39 (registry+https://github.com/rust-lang/crates.io-index)",
1122
  "syn 0.15.39 (registry+https://github.com/rust-lang/crates.io-index)",
1094
  "version_check 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
1123
  "version_check 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
1095
  "yansi 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
1124
  "yansi 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
1136
  "pest 2.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
1165
  "pest 2.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
1137
  "pest_meta 2.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
1166
  "pest_meta 2.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
1138
  "proc-macro2 0.4.30 (registry+https://github.com/rust-lang/crates.io-index)",
1167
  "proc-macro2 0.4.30 (registry+https://github.com/rust-lang/crates.io-index)",
1139
- "quote 0.6.12 (registry+https://github.com/rust-lang/crates.io-index)",
1168
+ "quote 0.6.13 (registry+https://github.com/rust-lang/crates.io-index)",
1140
  "syn 0.15.39 (registry+https://github.com/rust-lang/crates.io-index)",
1169
  "syn 0.15.39 (registry+https://github.com/rust-lang/crates.io-index)",
1141
 ]
1170
 ]
1142
 
1171
 
1225
 
1254
 
1226
 [[package]]
1255
 [[package]]
1227
 name = "quote"
1256
 name = "quote"
1228
-version = "0.6.12"
1257
+version = "0.6.13"
1229
 source = "registry+https://github.com/rust-lang/crates.io-index"
1258
 source = "registry+https://github.com/rust-lang/crates.io-index"
1230
 dependencies = [
1259
 dependencies = [
1231
  "proc-macro2 0.4.30 (registry+https://github.com/rust-lang/crates.io-index)",
1260
  "proc-macro2 0.4.30 (registry+https://github.com/rust-lang/crates.io-index)",
1232
 ]
1261
 ]
1233
 
1262
 
1234
 [[package]]
1263
 [[package]]
1264
+name = "r2d2"
1265
+version = "0.8.5"
1266
+source = "registry+https://github.com/rust-lang/crates.io-index"
1267
+dependencies = [
1268
+ "log 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)",
1269
+ "parking_lot 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
1270
+ "scheduled-thread-pool 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
1271
+]
1272
+
1273
+[[package]]
1235
 name = "rand"
1274
 name = "rand"
1236
 version = "0.6.5"
1275
 version = "0.6.5"
1237
 source = "registry+https://github.com/rust-lang/crates.io-index"
1276
 source = "registry+https://github.com/rust-lang/crates.io-index"
1379
 source = "registry+https://github.com/rust-lang/crates.io-index"
1418
 source = "registry+https://github.com/rust-lang/crates.io-index"
1380
 
1419
 
1381
 [[package]]
1420
 [[package]]
1382
-name = "redox_termios"
1383
-version = "0.1.1"
1384
-source = "registry+https://github.com/rust-lang/crates.io-index"
1385
-dependencies = [
1386
- "redox_syscall 0.1.56 (registry+https://github.com/rust-lang/crates.io-index)",
1387
-]
1388
-
1389
-[[package]]
1390
 name = "regex"
1421
 name = "regex"
1391
 version = "1.1.9"
1422
 version = "1.1.9"
1392
 source = "registry+https://github.com/rust-lang/crates.io-index"
1423
 source = "registry+https://github.com/rust-lang/crates.io-index"
1427
  "flate2 1.0.9 (registry+https://github.com/rust-lang/crates.io-index)",
1458
  "flate2 1.0.9 (registry+https://github.com/rust-lang/crates.io-index)",
1428
  "futures 0.1.28 (registry+https://github.com/rust-lang/crates.io-index)",
1459
  "futures 0.1.28 (registry+https://github.com/rust-lang/crates.io-index)",
1429
  "http 0.1.17 (registry+https://github.com/rust-lang/crates.io-index)",
1460
  "http 0.1.17 (registry+https://github.com/rust-lang/crates.io-index)",
1430
- "hyper 0.12.31 (registry+https://github.com/rust-lang/crates.io-index)",
1461
+ "hyper 0.12.32 (registry+https://github.com/rust-lang/crates.io-index)",
1431
  "hyper-tls 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
1462
  "hyper-tls 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
1432
- "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
1463
+ "log 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)",
1433
  "mime 0.3.13 (registry+https://github.com/rust-lang/crates.io-index)",
1464
  "mime 0.3.13 (registry+https://github.com/rust-lang/crates.io-index)",
1434
  "mime_guess 2.0.0-alpha.6 (registry+https://github.com/rust-lang/crates.io-index)",
1465
  "mime_guess 2.0.0-alpha.6 (registry+https://github.com/rust-lang/crates.io-index)",
1435
  "native-tls 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
1466
  "native-tls 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
1462
 version = "0.4.2"
1493
 version = "0.4.2"
1463
 source = "registry+https://github.com/rust-lang/crates.io-index"
1494
 source = "registry+https://github.com/rust-lang/crates.io-index"
1464
 dependencies = [
1495
 dependencies = [
1465
- "atty 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)",
1496
+ "atty 0.2.12 (registry+https://github.com/rust-lang/crates.io-index)",
1466
  "base64 0.10.1 (registry+https://github.com/rust-lang/crates.io-index)",
1497
  "base64 0.10.1 (registry+https://github.com/rust-lang/crates.io-index)",
1467
- "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
1498
+ "log 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)",
1468
  "memchr 2.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
1499
  "memchr 2.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
1469
  "num_cpus 1.10.1 (registry+https://github.com/rust-lang/crates.io-index)",
1500
  "num_cpus 1.10.1 (registry+https://github.com/rust-lang/crates.io-index)",
1470
  "pear 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
1501
  "pear 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
1484
 dependencies = [
1515
 dependencies = [
1485
  "devise 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
1516
  "devise 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
1486
  "indexmap 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
1517
  "indexmap 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
1487
- "quote 0.6.12 (registry+https://github.com/rust-lang/crates.io-index)",
1518
+ "quote 0.6.13 (registry+https://github.com/rust-lang/crates.io-index)",
1488
  "rocket_http 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
1519
  "rocket_http 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
1489
  "version_check 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)",
1520
  "version_check 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)",
1490
  "yansi 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)",
1521
  "yansi 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)",
1496
 source = "registry+https://github.com/rust-lang/crates.io-index"
1527
 source = "registry+https://github.com/rust-lang/crates.io-index"
1497
 dependencies = [
1528
 dependencies = [
1498
  "glob 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
1529
  "glob 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
1499
- "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
1530
+ "log 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)",
1500
  "notify 4.0.12 (registry+https://github.com/rust-lang/crates.io-index)",
1531
  "notify 4.0.12 (registry+https://github.com/rust-lang/crates.io-index)",
1501
  "rocket 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
1532
  "rocket 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
1502
  "serde 1.0.94 (registry+https://github.com/rust-lang/crates.io-index)",
1533
  "serde 1.0.94 (registry+https://github.com/rust-lang/crates.io-index)",
1566
 ]
1597
 ]
1567
 
1598
 
1568
 [[package]]
1599
 [[package]]
1600
+name = "scheduled-thread-pool"
1601
+version = "0.2.1"
1602
+source = "registry+https://github.com/rust-lang/crates.io-index"
1603
+dependencies = [
1604
+ "parking_lot 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
1605
+]
1606
+
1607
+[[package]]
1569
 name = "scopeguard"
1608
 name = "scopeguard"
1570
 version = "0.3.3"
1609
 version = "0.3.3"
1571
 source = "registry+https://github.com/rust-lang/crates.io-index"
1610
 source = "registry+https://github.com/rust-lang/crates.io-index"
1572
 
1611
 
1573
 [[package]]
1612
 [[package]]
1613
+name = "scopeguard"
1614
+version = "1.0.0"
1615
+source = "registry+https://github.com/rust-lang/crates.io-index"
1616
+
1617
+[[package]]
1574
 name = "security-framework"
1618
 name = "security-framework"
1575
 version = "0.3.1"
1619
 version = "0.3.1"
1576
 source = "registry+https://github.com/rust-lang/crates.io-index"
1620
 source = "registry+https://github.com/rust-lang/crates.io-index"
1633
 source = "registry+https://github.com/rust-lang/crates.io-index"
1677
 source = "registry+https://github.com/rust-lang/crates.io-index"
1634
 dependencies = [
1678
 dependencies = [
1635
  "proc-macro2 0.4.30 (registry+https://github.com/rust-lang/crates.io-index)",
1679
  "proc-macro2 0.4.30 (registry+https://github.com/rust-lang/crates.io-index)",
1636
- "quote 0.6.12 (registry+https://github.com/rust-lang/crates.io-index)",
1680
+ "quote 0.6.13 (registry+https://github.com/rust-lang/crates.io-index)",
1637
  "syn 0.15.39 (registry+https://github.com/rust-lang/crates.io-index)",
1681
  "syn 0.15.39 (registry+https://github.com/rust-lang/crates.io-index)",
1638
 ]
1682
 ]
1639
 
1683
 
1729
 source = "registry+https://github.com/rust-lang/crates.io-index"
1773
 source = "registry+https://github.com/rust-lang/crates.io-index"
1730
 dependencies = [
1774
 dependencies = [
1731
  "proc-macro2 0.4.30 (registry+https://github.com/rust-lang/crates.io-index)",
1775
  "proc-macro2 0.4.30 (registry+https://github.com/rust-lang/crates.io-index)",
1732
- "quote 0.6.12 (registry+https://github.com/rust-lang/crates.io-index)",
1776
+ "quote 0.6.13 (registry+https://github.com/rust-lang/crates.io-index)",
1733
  "unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
1777
  "unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
1734
 ]
1778
 ]
1735
 
1779
 
1739
 source = "registry+https://github.com/rust-lang/crates.io-index"
1783
 source = "registry+https://github.com/rust-lang/crates.io-index"
1740
 dependencies = [
1784
 dependencies = [
1741
  "proc-macro2 0.4.30 (registry+https://github.com/rust-lang/crates.io-index)",
1785
  "proc-macro2 0.4.30 (registry+https://github.com/rust-lang/crates.io-index)",
1742
- "quote 0.6.12 (registry+https://github.com/rust-lang/crates.io-index)",
1786
+ "quote 0.6.13 (registry+https://github.com/rust-lang/crates.io-index)",
1743
  "syn 0.15.39 (registry+https://github.com/rust-lang/crates.io-index)",
1787
  "syn 0.15.39 (registry+https://github.com/rust-lang/crates.io-index)",
1744
  "unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
1788
  "unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
1745
 ]
1789
 ]
1778
 ]
1822
 ]
1779
 
1823
 
1780
 [[package]]
1824
 [[package]]
1781
-name = "termion"
1782
-version = "1.5.3"
1783
-source = "registry+https://github.com/rust-lang/crates.io-index"
1784
-dependencies = [
1785
- "libc 0.2.59 (registry+https://github.com/rust-lang/crates.io-index)",
1786
- "numtoa 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
1787
- "redox_syscall 0.1.56 (registry+https://github.com/rust-lang/crates.io-index)",
1788
- "redox_termios 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
1789
-]
1790
-
1791
-[[package]]
1792
 name = "thread_local"
1825
 name = "thread_local"
1793
 version = "0.3.6"
1826
 version = "0.3.6"
1794
 source = "registry+https://github.com/rust-lang/crates.io-index"
1827
 source = "registry+https://github.com/rust-lang/crates.io-index"
1859
 dependencies = [
1892
 dependencies = [
1860
  "bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)",
1893
  "bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)",
1861
  "futures 0.1.28 (registry+https://github.com/rust-lang/crates.io-index)",
1894
  "futures 0.1.28 (registry+https://github.com/rust-lang/crates.io-index)",
1862
- "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
1895
+ "log 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)",
1863
 ]
1896
 ]
1864
 
1897
 
1865
 [[package]]
1898
 [[package]]
1870
  "crossbeam-utils 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)",
1903
  "crossbeam-utils 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)",
1871
  "futures 0.1.28 (registry+https://github.com/rust-lang/crates.io-index)",
1904
  "futures 0.1.28 (registry+https://github.com/rust-lang/crates.io-index)",
1872
  "lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
1905
  "lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
1873
- "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
1906
+ "log 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)",
1874
  "mio 0.6.19 (registry+https://github.com/rust-lang/crates.io-index)",
1907
  "mio 0.6.19 (registry+https://github.com/rust-lang/crates.io-index)",
1875
  "num_cpus 1.10.1 (registry+https://github.com/rust-lang/crates.io-index)",
1908
  "num_cpus 1.10.1 (registry+https://github.com/rust-lang/crates.io-index)",
1876
  "parking_lot 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)",
1909
  "parking_lot 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)",
1911
  "crossbeam-queue 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
1944
  "crossbeam-queue 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
1912
  "crossbeam-utils 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)",
1945
  "crossbeam-utils 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)",
1913
  "futures 0.1.28 (registry+https://github.com/rust-lang/crates.io-index)",
1946
  "futures 0.1.28 (registry+https://github.com/rust-lang/crates.io-index)",
1914
- "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
1947
+ "log 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)",
1915
  "num_cpus 1.10.1 (registry+https://github.com/rust-lang/crates.io-index)",
1948
  "num_cpus 1.10.1 (registry+https://github.com/rust-lang/crates.io-index)",
1916
  "rand 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)",
1949
  "rand 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)",
1917
  "slab 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
1950
  "slab 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
2121
 source = "registry+https://github.com/rust-lang/crates.io-index"
2154
 source = "registry+https://github.com/rust-lang/crates.io-index"
2122
 dependencies = [
2155
 dependencies = [
2123
  "futures 0.1.28 (registry+https://github.com/rust-lang/crates.io-index)",
2156
  "futures 0.1.28 (registry+https://github.com/rust-lang/crates.io-index)",
2124
- "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
2157
+ "log 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)",
2125
  "try-lock 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
2158
  "try-lock 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
2126
 ]
2159
 ]
2127
 
2160
 
2192
 [metadata]
2225
 [metadata]
2193
 "checksum adler32 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "7e522997b529f05601e05166c07ed17789691f562762c7f3b987263d2dedee5c"
2226
 "checksum adler32 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "7e522997b529f05601e05166c07ed17789691f562762c7f3b987263d2dedee5c"
2194
 "checksum aho-corasick 0.7.4 (registry+https://github.com/rust-lang/crates.io-index)" = "36b7aa1ccb7d7ea3f437cf025a2ab1c47cc6c1bc9fc84918ff449def12f5e282"
2227
 "checksum aho-corasick 0.7.4 (registry+https://github.com/rust-lang/crates.io-index)" = "36b7aa1ccb7d7ea3f437cf025a2ab1c47cc6c1bc9fc84918ff449def12f5e282"
2195
-"checksum arrayvec 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)" = "92c7fb76bc8826a8b33b4ee5bb07a247a81e76764ab4d55e8f73e3a4d8808c71"
2196
-"checksum atty 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)" = "9a7d5b8723950951411ee34d271d99dddcc2035a16ab25310ea2c8cfd4369652"
2228
+"checksum arrayvec 0.4.11 (registry+https://github.com/rust-lang/crates.io-index)" = "b8d73f9beda665eaa98ab9e4f7442bd4e7de6652587de55b2525e52e29c1b0ba"
2229
+"checksum atty 0.2.12 (registry+https://github.com/rust-lang/crates.io-index)" = "ecaaea69f52b3b18633611ec0007d188517d0366f47ff703d400fa6879d6f8d5"
2197
 "checksum autocfg 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "0e49efa51329a5fd37e7c79db4621af617cd4e3e5bc224939808d076077077bf"
2230
 "checksum autocfg 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "0e49efa51329a5fd37e7c79db4621af617cd4e3e5bc224939808d076077077bf"
2198
 "checksum backtrace 0.3.32 (registry+https://github.com/rust-lang/crates.io-index)" = "18b50f5258d1a9ad8396d2d345827875de4261b158124d4c819d9b351454fae5"
2231
 "checksum backtrace 0.3.32 (registry+https://github.com/rust-lang/crates.io-index)" = "18b50f5258d1a9ad8396d2d345827875de4261b158124d4c819d9b351454fae5"
2199
 "checksum backtrace-sys 0.1.30 (registry+https://github.com/rust-lang/crates.io-index)" = "5b3a000b9c543553af61bc01cbfc403b04b5caa9e421033866f2e98061eb3e61"
2232
 "checksum backtrace-sys 0.1.30 (registry+https://github.com/rust-lang/crates.io-index)" = "5b3a000b9c543553af61bc01cbfc403b04b5caa9e421033866f2e98061eb3e61"
2209
 "checksum byteorder 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "a7c3dd8985a7111efc5c80b44e23ecdd8c007de8ade3b96595387e812b957cf5"
2242
 "checksum byteorder 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "a7c3dd8985a7111efc5c80b44e23ecdd8c007de8ade3b96595387e812b957cf5"
2210
 "checksum bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)" = "206fdffcfa2df7cbe15601ef46c813fce0965eb3286db6b56c583b814b51c81c"
2243
 "checksum bytes 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)" = "206fdffcfa2df7cbe15601ef46c813fce0965eb3286db6b56c583b814b51c81c"
2211
 "checksum c2-chacha 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7d64d04786e0f528460fc884753cf8dddcc466be308f6026f8e355c41a0e4101"
2244
 "checksum c2-chacha 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7d64d04786e0f528460fc884753cf8dddcc466be308f6026f8e355c41a0e4101"
2212
-"checksum cached 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "24f3f5ca5651b8360fb859d6fd1b80fb4c25bc3cbf3ffc3a74d3d6a79fba328e"
2213
 "checksum cc 1.0.37 (registry+https://github.com/rust-lang/crates.io-index)" = "39f75544d7bbaf57560d2168f28fd649ff9c76153874db88bdbdfd839b1a7e7d"
2245
 "checksum cc 1.0.37 (registry+https://github.com/rust-lang/crates.io-index)" = "39f75544d7bbaf57560d2168f28fd649ff9c76153874db88bdbdfd839b1a7e7d"
2214
 "checksum cfg-if 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)" = "b486ce3ccf7ffd79fdeb678eac06a9e6c09fc88d33836340becb8fffe87c5e33"
2246
 "checksum cfg-if 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)" = "b486ce3ccf7ffd79fdeb678eac06a9e6c09fc88d33836340becb8fffe87c5e33"
2215
 "checksum chrono 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)" = "77d81f58b7301084de3b958691458a53c3f7e0b1d702f77e550b6a88e3a88abe"
2247
 "checksum chrono 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)" = "77d81f58b7301084de3b958691458a53c3f7e0b1d702f77e550b6a88e3a88abe"
2257
 "checksum glob 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)" = "8be18de09a56b60ed0edf84bc9df007e30040691af7acd1c41874faac5895bfb"
2289
 "checksum glob 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)" = "8be18de09a56b60ed0edf84bc9df007e30040691af7acd1c41874faac5895bfb"
2258
 "checksum glob 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "9b919933a397b79c37e33b77bb2aa3dc8eb6e165ad809e58ff75bc7db2e34574"
2290
 "checksum glob 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "9b919933a397b79c37e33b77bb2aa3dc8eb6e165ad809e58ff75bc7db2e34574"
2259
 "checksum h2 0.1.25 (registry+https://github.com/rust-lang/crates.io-index)" = "a539b63339fbbb00e081e84b6e11bd1d9634a82d91da2984a18ac74a8823f392"
2291
 "checksum h2 0.1.25 (registry+https://github.com/rust-lang/crates.io-index)" = "a539b63339fbbb00e081e84b6e11bd1d9634a82d91da2984a18ac74a8823f392"
2292
+"checksum hashbrown 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)" = "3bae29b6653b3412c2e71e9d486db9f9df5d701941d86683005efb9f2d28e3da"
2260
 "checksum http 0.1.17 (registry+https://github.com/rust-lang/crates.io-index)" = "eed324f0f0daf6ec10c474f150505af2c143f251722bf9dbd1261bd1f2ee2c1a"
2293
 "checksum http 0.1.17 (registry+https://github.com/rust-lang/crates.io-index)" = "eed324f0f0daf6ec10c474f150505af2c143f251722bf9dbd1261bd1f2ee2c1a"
2261
 "checksum http-body 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "6741c859c1b2463a423a1dbce98d418e6c3c3fc720fb0d45528657320920292d"
2294
 "checksum http-body 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "6741c859c1b2463a423a1dbce98d418e6c3c3fc720fb0d45528657320920292d"
2262
 "checksum httparse 1.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "cd179ae861f0c2e53da70d892f5f3029f9594be0c41dc5269cd371691b1dc2f9"
2295
 "checksum httparse 1.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "cd179ae861f0c2e53da70d892f5f3029f9594be0c41dc5269cd371691b1dc2f9"
2263
 "checksum humansize 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b6cab2627acfc432780848602f3f558f7e9dd427352224b0d9324025796d2a5e"
2296
 "checksum humansize 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b6cab2627acfc432780848602f3f558f7e9dd427352224b0d9324025796d2a5e"
2264
 "checksum hyper 0.10.16 (registry+https://github.com/rust-lang/crates.io-index)" = "0a0652d9a2609a968c14be1a9ea00bf4b1d64e2e1f53a1b51b6fff3a6e829273"
2297
 "checksum hyper 0.10.16 (registry+https://github.com/rust-lang/crates.io-index)" = "0a0652d9a2609a968c14be1a9ea00bf4b1d64e2e1f53a1b51b6fff3a6e829273"
2265
-"checksum hyper 0.12.31 (registry+https://github.com/rust-lang/crates.io-index)" = "6481fff8269772d4463253ca83c788104a7305cb3fb9136bc651a6211e46e03f"
2298
+"checksum hyper 0.12.32 (registry+https://github.com/rust-lang/crates.io-index)" = "a64d71c1e77d39da024f06f5821ee00ad9c38febb90370bad1f07a94e0bc8793"
2266
 "checksum hyper-tls 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "3a800d6aa50af4b5850b2b0f659625ce9504df908e9733b635720483be26174f"
2299
 "checksum hyper-tls 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "3a800d6aa50af4b5850b2b0f659625ce9504df908e9733b635720483be26174f"
2267
 "checksum idna 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "38f09e0f0b1fb55fdee1f17470ad800da77af5186a1a76c026b679358b7e844e"
2300
 "checksum idna 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "38f09e0f0b1fb55fdee1f17470ad800da77af5186a1a76c026b679358b7e844e"
2268
 "checksum indexmap 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7e81a7c05f79578dbc15793d8b619db9ba32b4577003ef3af1a91c416798c58d"
2301
 "checksum indexmap 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7e81a7c05f79578dbc15793d8b619db9ba32b4577003ef3af1a91c416798c58d"
2279
 "checksum linked-hash-map 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "6d262045c5b87c0861b3f004610afd0e2c851e2908d08b6c870cbb9d5f494ecd"
2312
 "checksum linked-hash-map 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "6d262045c5b87c0861b3f004610afd0e2c851e2908d08b6c870cbb9d5f494ecd"
2280
 "checksum linked-hash-map 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)" = "ae91b68aebc4ddb91978b11a1b02ddd8602a05ec19002801c5666000e05e0f83"
2313
 "checksum linked-hash-map 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)" = "ae91b68aebc4ddb91978b11a1b02ddd8602a05ec19002801c5666000e05e0f83"
2281
 "checksum lock_api 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "62ebf1391f6acad60e5c8b43706dde4582df75c06698ab44511d15016bc2442c"
2314
 "checksum lock_api 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "62ebf1391f6acad60e5c8b43706dde4582df75c06698ab44511d15016bc2442c"
2315
+"checksum lock_api 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ed946d4529956a20f2d63ebe1b69996d5a2137c91913fe3ebbeff957f5bca7ff"
2282
 "checksum log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)" = "e19e8d5c34a3e0e2223db8e060f9e8264aeeb5c5fc64a4ee9965c062211c024b"
2316
 "checksum log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)" = "e19e8d5c34a3e0e2223db8e060f9e8264aeeb5c5fc64a4ee9965c062211c024b"
2283
-"checksum log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)" = "c84ec4b527950aa83a329754b01dbe3f58361d1c5efacd1f6d68c494d08a17c6"
2317
+"checksum log 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)" = "c275b6ad54070ac2d665eef9197db647b32239c9d244bfb6f041a766d00da5b3"
2318
+"checksum lru 0.1.15 (registry+https://github.com/rust-lang/crates.io-index)" = "276235bb6b60773280b44b65e93815de82da5b6279ef175004fca03f4d06770a"
2284
 "checksum maplit 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "08cbb6b4fef96b6d77bfc40ec491b1690c779e77b05cd9f07f787ed376fd4c43"
2319
 "checksum maplit 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "08cbb6b4fef96b6d77bfc40ec491b1690c779e77b05cd9f07f787ed376fd4c43"
2285
 "checksum matches 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)" = "7ffc5c5338469d4d3ea17d269fa8ea3512ad247247c30bd2df69e68309ed0a08"
2320
 "checksum matches 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)" = "7ffc5c5338469d4d3ea17d269fa8ea3512ad247247c30bd2df69e68309ed0a08"
2286
 "checksum memchr 2.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "88579771288728879b57485cc7d6b07d648c9f0141eb955f8ab7f9d45394468e"
2321
 "checksum memchr 2.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "88579771288728879b57485cc7d6b07d648c9f0141eb955f8ab7f9d45394468e"
2302
 "checksum num-traits 0.1.43 (registry+https://github.com/rust-lang/crates.io-index)" = "92e5113e9fd4cc14ded8e499429f396a20f98c772a47cc8622a736e1ec843c31"
2337
 "checksum num-traits 0.1.43 (registry+https://github.com/rust-lang/crates.io-index)" = "92e5113e9fd4cc14ded8e499429f396a20f98c772a47cc8622a736e1ec843c31"
2303
 "checksum num-traits 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)" = "6ba9a427cfca2be13aa6f6403b0b7e7368fe982bfa16fccc450ce74c46cd9b32"
2338
 "checksum num-traits 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)" = "6ba9a427cfca2be13aa6f6403b0b7e7368fe982bfa16fccc450ce74c46cd9b32"
2304
 "checksum num_cpus 1.10.1 (registry+https://github.com/rust-lang/crates.io-index)" = "bcef43580c035376c0705c42792c294b66974abbfd2789b511784023f71f3273"
2339
 "checksum num_cpus 1.10.1 (registry+https://github.com/rust-lang/crates.io-index)" = "bcef43580c035376c0705c42792c294b66974abbfd2789b511784023f71f3273"
2305
-"checksum numtoa 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b8f8bdf33df195859076e54ab11ee78a1b208382d3a26ec40d142ffc1ecc49ef"
2306
-"checksum once_cell 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)" = "532c29a261168a45ce28948f9537ddd7a5dd272cc513b3017b1e82a88f962c37"
2307
 "checksum opaque-debug 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "93f5bb2e8e8dec81642920ccff6b61f1eb94fa3020c5a325c9851ff604152409"
2340
 "checksum opaque-debug 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "93f5bb2e8e8dec81642920ccff6b61f1eb94fa3020c5a325c9851ff604152409"
2308
 "checksum openssl 0.10.23 (registry+https://github.com/rust-lang/crates.io-index)" = "97c140cbb82f3b3468193dd14c1b88def39f341f68257f8a7fe8ed9ed3f628a5"
2341
 "checksum openssl 0.10.23 (registry+https://github.com/rust-lang/crates.io-index)" = "97c140cbb82f3b3468193dd14c1b88def39f341f68257f8a7fe8ed9ed3f628a5"
2309
 "checksum openssl-probe 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "77af24da69f9d9341038eba93a073b1fdaaa1b788221b00a69bce9e762cb32de"
2342
 "checksum openssl-probe 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "77af24da69f9d9341038eba93a073b1fdaaa1b788221b00a69bce9e762cb32de"
2310
 "checksum openssl-sys 0.9.47 (registry+https://github.com/rust-lang/crates.io-index)" = "75bdd6dbbb4958d38e47a1d2348847ad1eb4dc205dc5d37473ae504391865acc"
2343
 "checksum openssl-sys 0.9.47 (registry+https://github.com/rust-lang/crates.io-index)" = "75bdd6dbbb4958d38e47a1d2348847ad1eb4dc205dc5d37473ae504391865acc"
2311
 "checksum owning_ref 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "49a4b8ea2179e6a2e27411d3bca09ca6dd630821cf6894c6c7c8467a8ee7ef13"
2344
 "checksum owning_ref 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "49a4b8ea2179e6a2e27411d3bca09ca6dd630821cf6894c6c7c8467a8ee7ef13"
2312
 "checksum parking_lot 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)" = "ab41b4aed082705d1056416ae4468b6ea99d52599ecf3169b00088d43113e337"
2345
 "checksum parking_lot 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)" = "ab41b4aed082705d1056416ae4468b6ea99d52599ecf3169b00088d43113e337"
2346
+"checksum parking_lot 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "fa7767817701cce701d5585b9c4db3cdd02086398322c1d7e8bf5094a96a2ce7"
2313
 "checksum parking_lot_core 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "94c8c7923936b28d546dfd14d4472eaf34c99b14e1c973a32b3e6d4eb04298c9"
2347
 "checksum parking_lot_core 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "94c8c7923936b28d546dfd14d4472eaf34c99b14e1c973a32b3e6d4eb04298c9"
2348
+"checksum parking_lot_core 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "cb88cb1cb3790baa6776844f968fea3be44956cf184fa1be5a03341f5491278c"
2314
 "checksum pear 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "c26d2b92e47063ffce70d3e3b1bd097af121a9e0db07ca38a6cc1cf0cc85ff25"
2349
 "checksum pear 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "c26d2b92e47063ffce70d3e3b1bd097af121a9e0db07ca38a6cc1cf0cc85ff25"
2315
 "checksum pear_codegen 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "336db4a192cc7f54efeb0c4e11a9245394824cc3bcbd37ba3ff51240c35d7a6e"
2350
 "checksum pear_codegen 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "336db4a192cc7f54efeb0c4e11a9245394824cc3bcbd37ba3ff51240c35d7a6e"
2316
 "checksum pem 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "fd2ae096568d61688cd1d419ca9815c94475d7b4622b1834d6e068e5bb2eb3d2"
2351
 "checksum pem 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "fd2ae096568d61688cd1d419ca9815c94475d7b4622b1834d6e068e5bb2eb3d2"
2328
 "checksum pq-sys 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)" = "6ac25eee5a0582f45a67e837e350d784e7003bd29a5f460796772061ca49ffda"
2363
 "checksum pq-sys 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)" = "6ac25eee5a0582f45a67e837e350d784e7003bd29a5f460796772061ca49ffda"
2329
 "checksum proc-macro2 0.4.30 (registry+https://github.com/rust-lang/crates.io-index)" = "cf3d2011ab5c909338f7887f4fc896d35932e29146c12c8d01da6b22a80ba759"
2364
 "checksum proc-macro2 0.4.30 (registry+https://github.com/rust-lang/crates.io-index)" = "cf3d2011ab5c909338f7887f4fc896d35932e29146c12c8d01da6b22a80ba759"
2330
 "checksum publicsuffix 1.5.2 (registry+https://github.com/rust-lang/crates.io-index)" = "5afecba86dcf1e4fd610246f89899d1924fe12e1e89f555eb7c7f710f3c5ad1d"
2365
 "checksum publicsuffix 1.5.2 (registry+https://github.com/rust-lang/crates.io-index)" = "5afecba86dcf1e4fd610246f89899d1924fe12e1e89f555eb7c7f710f3c5ad1d"
2331
-"checksum quote 0.6.12 (registry+https://github.com/rust-lang/crates.io-index)" = "faf4799c5d274f3868a4aae320a0a182cbd2baee377b378f080e16a23e9d80db"
2366
+"checksum quote 0.6.13 (registry+https://github.com/rust-lang/crates.io-index)" = "6ce23b6b870e8f94f81fb0a363d65d86675884b34a09043c81e5562f11c1f8e1"
2367
+"checksum r2d2 0.8.5 (registry+https://github.com/rust-lang/crates.io-index)" = "bc42ce75d9f4447fb2a04bbe1ed5d18dd949104572850ec19b164e274919f81b"
2332
 "checksum rand 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)" = "6d71dacdc3c88c1fde3885a3be3fbab9f35724e6ce99467f7d9c5026132184ca"
2368
 "checksum rand 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)" = "6d71dacdc3c88c1fde3885a3be3fbab9f35724e6ce99467f7d9c5026132184ca"
2333
 "checksum rand 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d47eab0e83d9693d40f825f86948aa16eff6750ead4bdffc4ab95b8b3a7f052c"
2369
 "checksum rand 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d47eab0e83d9693d40f825f86948aa16eff6750ead4bdffc4ab95b8b3a7f052c"
2334
 "checksum rand_chacha 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "556d3a1ca6600bfcbab7c7c91ccb085ac7fbbcd70e008a98742e7847f4f7bcef"
2370
 "checksum rand_chacha 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "556d3a1ca6600bfcbab7c7c91ccb085ac7fbbcd70e008a98742e7847f4f7bcef"
2345
 "checksum rand_xorshift 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "cbf7e9e623549b0e21f6e97cf8ecf247c1a8fd2e8a992ae265314300b2455d5c"
2381
 "checksum rand_xorshift 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "cbf7e9e623549b0e21f6e97cf8ecf247c1a8fd2e8a992ae265314300b2455d5c"
2346
 "checksum rdrand 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "678054eb77286b51581ba43620cc911abf02758c91f93f479767aed0f90458b2"
2382
 "checksum rdrand 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "678054eb77286b51581ba43620cc911abf02758c91f93f479767aed0f90458b2"
2347
 "checksum redox_syscall 0.1.56 (registry+https://github.com/rust-lang/crates.io-index)" = "2439c63f3f6139d1b57529d16bc3b8bb855230c8efcc5d3a896c8bea7c3b1e84"
2383
 "checksum redox_syscall 0.1.56 (registry+https://github.com/rust-lang/crates.io-index)" = "2439c63f3f6139d1b57529d16bc3b8bb855230c8efcc5d3a896c8bea7c3b1e84"
2348
-"checksum redox_termios 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "7e891cfe48e9100a70a3b6eb652fef28920c117d366339687bd5576160db0f76"
2349
 "checksum regex 1.1.9 (registry+https://github.com/rust-lang/crates.io-index)" = "d9d8297cc20bbb6184f8b45ff61c8ee6a9ac56c156cec8e38c3e5084773c44ad"
2384
 "checksum regex 1.1.9 (registry+https://github.com/rust-lang/crates.io-index)" = "d9d8297cc20bbb6184f8b45ff61c8ee6a9ac56c156cec8e38c3e5084773c44ad"
2350
 "checksum regex-syntax 0.6.8 (registry+https://github.com/rust-lang/crates.io-index)" = "9b01330cce219c1c6b2e209e5ed64ccd587ae5c67bed91c0b49eecf02ae40e21"
2385
 "checksum regex-syntax 0.6.8 (registry+https://github.com/rust-lang/crates.io-index)" = "9b01330cce219c1c6b2e209e5ed64ccd587ae5c67bed91c0b49eecf02ae40e21"
2351
 "checksum remove_dir_all 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)" = "4a83fa3702a688b9359eccba92d153ac33fd2e8462f9e0e3fdf155239ea7792e"
2386
 "checksum remove_dir_all 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)" = "4a83fa3702a688b9359eccba92d153ac33fd2e8462f9e0e3fdf155239ea7792e"
2362
 "checksum safemem 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "8dca453248a96cb0749e36ccdfe2b0b4e54a61bfef89fb97ec621eb8e0a93dd9"
2397
 "checksum safemem 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "8dca453248a96cb0749e36ccdfe2b0b4e54a61bfef89fb97ec621eb8e0a93dd9"
2363
 "checksum same-file 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "8f20c4be53a8a1ff4c1f1b2bd14570d2f634628709752f0702ecdd2b3f9a5267"
2398
 "checksum same-file 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "8f20c4be53a8a1ff4c1f1b2bd14570d2f634628709752f0702ecdd2b3f9a5267"
2364
 "checksum schannel 0.1.15 (registry+https://github.com/rust-lang/crates.io-index)" = "f2f6abf258d99c3c1c5c2131d99d064e94b7b3dd5f416483057f308fea253339"
2399
 "checksum schannel 0.1.15 (registry+https://github.com/rust-lang/crates.io-index)" = "f2f6abf258d99c3c1c5c2131d99d064e94b7b3dd5f416483057f308fea253339"
2400
+"checksum scheduled-thread-pool 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "bbecfcb36d47e0d6a4aefb198d475b13aa06e326770c1271171d44893766ae1c"
2365
 "checksum scopeguard 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "94258f53601af11e6a49f722422f6e3425c52b06245a5cf9bc09908b174f5e27"
2401
 "checksum scopeguard 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "94258f53601af11e6a49f722422f6e3425c52b06245a5cf9bc09908b174f5e27"
2402
+"checksum scopeguard 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b42e15e59b18a828bbf5c58ea01debb36b9b096346de35d941dcb89009f24a0d"
2366
 "checksum security-framework 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "eee63d0f4a9ec776eeb30e220f0bc1e092c3ad744b2a379e3993070364d3adc2"
2403
 "checksum security-framework 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "eee63d0f4a9ec776eeb30e220f0bc1e092c3ad744b2a379e3993070364d3adc2"
2367
 "checksum security-framework-sys 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "9636f8989cbf61385ae4824b98c1aaa54c994d7d8b41f11c601ed799f0549a56"
2404
 "checksum security-framework-sys 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "9636f8989cbf61385ae4824b98c1aaa54c994d7d8b41f11c601ed799f0549a56"
2368
 "checksum semver 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1d7eb9ef2c18661902cc47e535f9bc51b78acd254da71d375c2f6720d9a40403"
2405
 "checksum semver 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1d7eb9ef2c18661902cc47e535f9bc51b78acd254da71d375c2f6720d9a40403"
2387
 "checksum synstructure 0.10.2 (registry+https://github.com/rust-lang/crates.io-index)" = "02353edf96d6e4dc81aea2d8490a7e9db177bf8acb0e951c24940bf866cb313f"
2424
 "checksum synstructure 0.10.2 (registry+https://github.com/rust-lang/crates.io-index)" = "02353edf96d6e4dc81aea2d8490a7e9db177bf8acb0e951c24940bf866cb313f"
2388
 "checksum tempfile 3.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7a6e24d9338a0a5be79593e2fa15a648add6138caa803e2d5bc782c371732ca9"
2425
 "checksum tempfile 3.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7a6e24d9338a0a5be79593e2fa15a648add6138caa803e2d5bc782c371732ca9"
2389
 "checksum tera 0.11.20 (registry+https://github.com/rust-lang/crates.io-index)" = "4b505279e19d8f7d24b1a9dc58327c9c36174b1a2c7ebdeac70792d017cb64f3"
2426
 "checksum tera 0.11.20 (registry+https://github.com/rust-lang/crates.io-index)" = "4b505279e19d8f7d24b1a9dc58327c9c36174b1a2c7ebdeac70792d017cb64f3"
2390
-"checksum termion 1.5.3 (registry+https://github.com/rust-lang/crates.io-index)" = "6a8fb22f7cde82c8220e5aeacb3258ed7ce996142c77cba193f203515e26c330"
2391
 "checksum thread_local 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)" = "c6b53e329000edc2b34dbe8545fd20e55a333362d0a321909685a19bd28c3f1b"
2427
 "checksum thread_local 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)" = "c6b53e329000edc2b34dbe8545fd20e55a333362d0a321909685a19bd28c3f1b"
2392
 "checksum time 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)" = "db8dcfca086c1143c9270ac42a2bbd8a7ee477b78ac8e45b19abfb0cbede4b6f"
2428
 "checksum time 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)" = "db8dcfca086c1143c9270ac42a2bbd8a7ee477b78ac8e45b19abfb0cbede4b6f"
2393
 "checksum tokio 0.1.22 (registry+https://github.com/rust-lang/crates.io-index)" = "5a09c0b5bb588872ab2f09afa13ee6e9dac11e10a0ec9e8e3ba39a5a5d530af6"
2429
 "checksum tokio 0.1.22 (registry+https://github.com/rust-lang/crates.io-index)" = "5a09c0b5bb588872ab2f09afa13ee6e9dac11e10a0ec9e8e3ba39a5a5d530af6"

+ 2
- 4
Cargo.toml View File

1
-cargo-features = ["default-run"]
2
-
3
 [package]
1
 [package]
4
 name = "kibou"
2
 name = "kibou"
5
 version = "0.1.0"
3
 version = "0.1.0"
9
 [dependencies]
7
 [dependencies]
10
 base64 = "0.10.1"
8
 base64 = "0.10.1"
11
 bcrypt = "0.5.0"
9
 bcrypt = "0.5.0"
12
-cached = "0.9.0"
13
 chrono = "0.4.7"
10
 chrono = "0.4.7"
14
 config = "0.9.3"
11
 config = "0.9.3"
15
-diesel = { version = "1.4.2", features = ["chrono", "postgres", "serde_json"] }
12
+diesel = { version = "1.4.2", features = ["chrono", "postgres", "r2d2", "serde_json"] }
16
 getopts = "0.2.19"
13
 getopts = "0.2.19"
17
 lazy_static = "1.3.0"
14
 lazy_static = "1.3.0"
15
+lru = "0.1.15"
18
 openssl-sys = "0.9.47"
16
 openssl-sys = "0.9.47"
19
 openssl = "0.10.23"
17
 openssl = "0.10.23"
20
 pem = "0.6.0"
18
 pem = "0.6.0"

+ 7
- 1
contrib/kibou.service View File

7
 ; paths according to your Kibou installation
7
 ; paths according to your Kibou installation
8
 ; ------------------------------------------------
8
 ; ------------------------------------------------
9
 WorkingDirectory=/srv/kibou
9
 WorkingDirectory=/srv/kibou
10
-ExecStart=/srv/kibou/target/debug/kibou_server
10
+ExecStart=/srv/kibou/target/release/kibou_server
11
+; ------------------------------------------------
12
+
13
+; Change the the environment
14
+; -> Enum {production, development, staging}
15
+; ------------------------------------------------
16
+Environment="ROCKET_ENV=production"
11
 ; ------------------------------------------------
17
 ; ------------------------------------------------
12
 
18
 
13
 ExecReload=/bin/kill $MAINPID
19
 ExecReload=/bin/kill $MAINPID

+ 4
- 0
env.toml.sample View File

17
 host = "localhost"
17
 host = "localhost"
18
 port = 8000
18
 port = 8000
19
 
19
 
20
+# Adjust the workers value 
21
+# -> Number of CPU cores * 2
22
+workers = 2
23
+
20
 [node]
24
 [node]
21
 name = "Kibou"
25
 name = "Kibou"
22
 description = "A Kibou instance"
26
 description = "A Kibou instance"

+ 2
- 2
migrations/2019-06-23-131810_notifications/up.sql View File

1
 CREATE TABLE notifications (
1
 CREATE TABLE notifications (
2
 	id BIGSERIAL PRIMARY KEY,
2
 	id BIGSERIAL PRIMARY KEY,
3
-	activity_id BIGSERIAL REFERENCES activities(id),
4
-	actor_id BIGSERIAL REFERENCES actors(id),
3
+	activity_id BIGSERIAL REFERENCES activities(id) ON DELETE CASCADE,
4
+	actor_id BIGSERIAL REFERENCES actors(id) ON DELETE CASCADE,
5
 	created TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
5
 	created TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
6
 	modified TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP
6
 	modified TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP
7
 );
7
 );

+ 43
- 21
src/activity.rs View File

1
-use database::models::{InsertActivity, QueryActivity};
1
+use database::models::{InsertActivity, QueryActivity, QueryActivityId};
2
 use database::runtime_escape;
2
 use database::runtime_escape;
3
 use database::schema::activities;
3
 use database::schema::activities;
4
 use database::schema::activities::dsl::*;
4
 use database::schema::activities::dsl::*;
16
     pub actor: String,
16
     pub actor: String,
17
 }
17
 }
18
 
18
 
19
+// Beware: This module depends on a lot of raw queries, which we should deprecate in the future. The
20
+// only reason they're being used is because Diesel.rs does not support JSONB operators that are
21
+// needed:
22
+// {->, ->>, @>, ?}
23
+//
24
+// Related issue: https://git.cybre.club/kibouproject/kibou/issues/32
25
+// Diesel.rs issue: https://github.com/diesel-rs/diesel/issues/44
26
+
19
 pub fn count_ap_object_replies_by_id(
27
 pub fn count_ap_object_replies_by_id(
20
     db_connection: &PgConnection,
28
     db_connection: &PgConnection,
21
     object_id: &str,
29
     object_id: &str,
22
 ) -> Result<usize, diesel::result::Error> {
30
 ) -> Result<usize, diesel::result::Error> {
23
     match sql_query(format!(
31
     match sql_query(format!(
24
-        "SELECT * FROM activities WHERE data @> '{{\"object\": {{\"inReplyTo\": \"{}\"}}}}';",
32
+        "SELECT id FROM activities WHERE data @> '{{\"object\": {{\"inReplyTo\": \"{}\"}}}}';",
25
         runtime_escape(object_id)
33
         runtime_escape(object_id)
26
     ))
34
     ))
27
-    .load::<QueryActivity>(db_connection)
35
+    .load::<QueryActivityId>(db_connection)
28
     {
36
     {
29
         Ok(activity_arr) => Ok(activity_arr.len()),
37
         Ok(activity_arr) => Ok(activity_arr.len()),
30
         Err(e) => Err(e),
38
         Err(e) => Err(e),
37
     reaction: &str,
45
     reaction: &str,
38
 ) -> Result<usize, diesel::result::Error> {
46
 ) -> Result<usize, diesel::result::Error> {
39
     match sql_query(format!(
47
     match sql_query(format!(
40
-        "SELECT * FROM activities WHERE data @> '{{\"type\": \"{reaction_type}\"}}' \
48
+        "SELECT id FROM activities WHERE data @> '{{\"type\": \"{reaction_type}\"}}' \
41
          AND data @> '{{\"object\": \"{id}\"}}';",
49
          AND data @> '{{\"object\": \"{id}\"}}';",
42
         reaction_type = runtime_escape(reaction),
50
         reaction_type = runtime_escape(reaction),
43
         id = runtime_escape(object_id)
51
         id = runtime_escape(object_id)
44
     ))
52
     ))
45
-    .load::<QueryActivity>(db_connection)
53
+    .load::<QueryActivityId>(db_connection)
46
     {
54
     {
47
         Ok(activity_arr) => Ok(activity_arr.len()),
55
         Ok(activity_arr) => Ok(activity_arr.len()),
48
         Err(e) => Err(e),
56
         Err(e) => Err(e),
54
     actor: &str,
62
     actor: &str,
55
 ) -> Result<usize, diesel::result::Error> {
63
 ) -> Result<usize, diesel::result::Error> {
56
     match sql_query(format!(
64
     match sql_query(format!(
57
-        "SELECT * \
65
+        "SELECT id \
58
          FROM activities \
66
          FROM activities \
59
-         WHERE data->>'type' = 'Create' \
60
-         AND data->'object'->>'type' = 'Note' \
61
-         AND data->>'actor' = '{actor}' \
67
+         WHERE data @> '{{\"actor\": \"{actor}\", \
68
+         \"type\": \"Create\", \
69
+         \"object\": {{\"type\": \"Note\"}}}}' \
62
          AND ((data->>'to')::jsonb ? 'https://www.w3.org/ns/activitystreams#Public' \
70
          AND ((data->>'to')::jsonb ? 'https://www.w3.org/ns/activitystreams#Public' \
63
          OR (data->>'cc')::jsonb ? 'https://www.w3.org/ns/activitystreams#Public');",
71
          OR (data->>'cc')::jsonb ? 'https://www.w3.org/ns/activitystreams#Public');",
64
         actor = runtime_escape(actor)
72
         actor = runtime_escape(actor)
65
     ))
73
     ))
66
-    .load::<QueryActivity>(db_connection)
74
+    .load::<QueryActivityId>(db_connection)
67
     {
75
     {
68
         Ok(activity_arr) => Ok(activity_arr.len()),
76
         Ok(activity_arr) => Ok(activity_arr.len()),
69
         Err(e) => Err(e),
77
         Err(e) => Err(e),
72
 
80
 
73
 pub fn count_local_ap_notes(db_connection: &PgConnection) -> Result<usize, diesel::result::Error> {
81
 pub fn count_local_ap_notes(db_connection: &PgConnection) -> Result<usize, diesel::result::Error> {
74
     match sql_query(format!(
82
     match sql_query(format!(
75
-        "SELECT * \
83
+        "SELECT id \
76
          FROM activities \
84
          FROM activities \
77
          WHERE data->>'type' = 'Create' \
85
          WHERE data->>'type' = 'Create' \
78
          AND data->'object'->>'type' = 'Note' \
86
          AND data->'object'->>'type' = 'Note' \
83
         base_domain = env::get_value(String::from("endpoint.base_domain"))
91
         base_domain = env::get_value(String::from("endpoint.base_domain"))
84
     ))
92
     ))
85
     .clone()
93
     .clone()
86
-    .load::<QueryActivity>(db_connection)
94
+    .load::<QueryActivityId>(db_connection)
87
     {
95
     {
88
         Ok(activity_arr) => Ok(activity_arr.len()),
96
         Ok(activity_arr) => Ok(activity_arr.len()),
89
         Err(e) => Err(e),
97
         Err(e) => Err(e),
90
     }
98
     }
91
 }
99
 }
92
 
100
 
101
+pub fn get_activities_by_id(
102
+    db_connection: &PgConnection,
103
+    ids: Vec<i64>,
104
+) -> Result<Vec<Activity>, diesel::result::Error> {
105
+    let parsed_ids: Vec<String> = ids.iter().map(|num| num.to_string()).collect();
106
+    match sql_query(format!(
107
+        "SELECT * FROM activities WHERE id = ANY(ARRAY[{}]);",
108
+        parsed_ids.join(", ")
109
+    ))
110
+    .load::<QueryActivity>(db_connection)
111
+    {
112
+        Ok(activity_arr) => Ok(activity_arr
113
+            .iter()
114
+            .map(|activity| serialize_activity(activity.clone()))
115
+            .collect()),
116
+        Err(e) => Err(e),
117
+    }
118
+}
119
+
93
 pub fn get_activity_by_id(
120
 pub fn get_activity_by_id(
94
     db_connection: &PgConnection,
121
     db_connection: &PgConnection,
95
     activity_id: i64,
122
     activity_id: i64,
159
     ))
186
     ))
160
     .load::<QueryActivity>(db_connection)
187
     .load::<QueryActivity>(db_connection)
161
     {
188
     {
162
-        Ok(activity) => {
163
-            let mut serialized_activites: Vec<Activity> = vec![];
164
-
165
-            for object in activity {
166
-                serialized_activites.push(serialize_activity(object));
167
-            }
168
-
169
-            Ok(serialized_activites)
170
-        }
189
+        Ok(activity_arr) => Ok(activity_arr
190
+            .iter()
191
+            .map(|activity| serialize_activity(activity.clone()))
192
+            .collect()),
171
         Err(e) => Err(e),
193
         Err(e) => Err(e),
172
     }
194
     }
173
 }
195
 }

+ 24
- 1
src/activitypub/mod.rs View File

5
 pub mod validator;
5
 pub mod validator;
6
 
6
 
7
 use base64;
7
 use base64;
8
+use rocket::data::{self, Data, FromDataSimple};
8
 use rocket::http::ContentType;
9
 use rocket::http::ContentType;
9
 use rocket::http::MediaType;
10
 use rocket::http::MediaType;
10
 use rocket::http::Status;
11
 use rocket::http::Status;
13
 use rocket::Outcome;
14
 use rocket::Outcome;
14
 use serde::{Deserialize, Serialize};
15
 use serde::{Deserialize, Serialize};
15
 use std::collections::HashMap;
16
 use std::collections::HashMap;
16
-use std::io::Cursor;
17
+use std::io::{Cursor, Read};
17
 use web::http_signatures::Signature;
18
 use web::http_signatures::Signature;
18
 
19
 
19
 pub struct ActivitypubMediatype(bool);
20
 pub struct ActivitypubMediatype(bool);
31
     pub mediaType: Option<String>,
32
     pub mediaType: Option<String>,
32
 }
33
 }
33
 
34
 
35
+pub struct Payload(serde_json::Value);
36
+
37
+impl FromDataSimple for Payload {
38
+    type Error = String;
39
+
40
+    fn from_data(req: &Request, data: Data) -> data::Outcome<Self, String> {
41
+        let mut data_stream = String::new();
42
+
43
+        // Read at most a 1MB payload
44
+        //
45
+        // TODO: This value should be adjustable in the config
46
+        if let Err(e) = data.open().take(1048576).read_to_string(&mut data_stream) {
47
+            return Outcome::Failure((Status::InternalServerError, format!("{:?}", e)));
48
+        }
49
+
50
+        match serde_json::from_str(&data_stream) {
51
+            Ok(value) => return Outcome::Success(Payload(value)),
52
+            Err(e) => return Outcome::Failure((Status::UnprocessableEntity, format!("{:?}", e))),
53
+        }
54
+    }
55
+}
56
+
34
 impl<'a, 'r> FromRequest<'a, 'r> for ActivitypubMediatype {
57
 impl<'a, 'r> FromRequest<'a, 'r> for ActivitypubMediatype {
35
     type Error = ();
58
     type Error = ();
36
 
59
 

+ 5
- 16
src/activitypub/routes.rs View File

3
 use activitypub::controller;
3
 use activitypub::controller;
4
 use activitypub::ActivitypubMediatype;
4
 use activitypub::ActivitypubMediatype;
5
 use activitypub::ActivitystreamsResponse;
5
 use activitypub::ActivitystreamsResponse;
6
+use activitypub::Payload;
6
 use activitypub::Signature;
7
 use activitypub::Signature;
7
 use rocket::http::Status;
8
 use rocket::http::Status;
8
 use serde_json;
9
 use serde_json;
18
 }
19
 }
19
 
20
 
20
 #[post("/actors/<id>/inbox", data = "<activity>")]
21
 #[post("/actors/<id>/inbox", data = "<activity>")]
21
-pub fn actor_inbox(id: String, activity: String, _signature: Signature) -> Status {
22
-    match serde_json::from_str(&activity) {
23
-        Ok(serialized_activity) => {
24
-            controller::prepare_incoming(serialized_activity, _signature);
25
-            return rocket::http::Status::Ok;
26
-        }
27
-        Err(_) => return rocket::http::Status::BadRequest,
28
-    }
22
+pub fn actor_inbox(id: String, activity: Payload, _signature: Signature) {
23
+    controller::prepare_incoming(activity.0, _signature);
29
 }
24
 }
30
 
25
 
31
 #[post("/inbox", data = "<activity>")]
26
 #[post("/inbox", data = "<activity>")]
32
-pub fn inbox(activity: String, _signature: Signature) -> Status {
33
-    match serde_json::from_str(&activity) {
34
-        Ok(serialized_activity) => {
35
-            controller::prepare_incoming(serialized_activity, _signature);
36
-            return rocket::http::Status::Ok;
37
-        }
38
-        Err(_) => return rocket::http::Status::BadRequest,
39
-    }
27
+pub fn inbox(activity: Payload, _signature: Signature) {
28
+    controller::prepare_incoming(activity.0, _signature);
40
 }
29
 }
41
 
30
 
42
 #[get("/objects/<id>")]
31
 #[get("/objects/<id>")]

+ 5
- 5
src/bin/kibou_server.rs View File

4
 use kibou::rocket_app;
4
 use kibou::rocket_app;
5
 
5
 
6
 fn main() {
6
 fn main() {
7
-    // TODO: Determine the environment Rocket is running in (ROCKET_ENV)
8
-    // We are currently just assuming a development enviroment
9
-
10
-    let rocket_config = rocket::config::Config::build(rocket::config::Environment::Development)
7
+    let rocket_config = rocket::config::Config::build(rocket::config::Environment::active().expect("Unknown ROCKET_ENV value! (enum: {Development, Staging, Production})"))
11
         .address(env::get_value("endpoint.host".to_string()))
8
         .address(env::get_value("endpoint.host".to_string()))
12
         .port(
9
         .port(
13
             env::get_value("endpoint.port".to_string())
10
             env::get_value("endpoint.port".to_string())
14
                 .parse::<u16>()
11
                 .parse::<u16>()
15
                 .unwrap(),
12
                 .unwrap(),
16
-        );
13
+        )
14
+        .workers(env::get_value("endpoint.workers".to_string())
15
+                .parse::<u16>()
16
+                .unwrap_or_else(|_| 2));
17
 
17
 
18
     unsafe {
18
     unsafe {
19
         kibou::raito_fe::BYPASS_API = &true;
19
         kibou::raito_fe::BYPASS_API = &true;

+ 52
- 10
src/database/mod.rs View File

1
 pub mod models;
1
 pub mod models;
2
 pub mod schema;
2
 pub mod schema;
3
-
4
 use diesel::pg::PgConnection;
3
 use diesel::pg::PgConnection;
5
 use diesel::prelude::*;
4
 use diesel::prelude::*;
5
+use diesel::r2d2;
6
+use diesel::r2d2::ConnectionManager;
6
 use env;
7
 use env;
7
 use regex::Regex;
8
 use regex::Regex;
9
+use rocket::http::Status;
10
+use rocket::request::{self, FromRequest};
11
+use rocket::{Outcome, Request, State};
12
+
13
+pub type Pool = r2d2::Pool<ConnectionManager<PgConnection>>;
14
+pub struct PooledConnection(pub r2d2::PooledConnection<ConnectionManager<PgConnection>>);
15
+
16
+lazy_static! {
17
+    pub static ref POOL: Pool = initialize_pool();
18
+}
19
+
20
+impl<'a, 'r> FromRequest<'a, 'r> for PooledConnection {
21
+    type Error = ();
22
+    fn from_request(request: &'a Request<'r>) -> request::Outcome<PooledConnection, Self::Error> {
23
+        match POOL.get() {
24
+            Ok(db_connection) => Outcome::Success(PooledConnection(db_connection)),
25
+            Err(_) => Outcome::Failure((Status::ServiceUnavailable, ())),
26
+        }
27
+    }
28
+}
8
 
29
 
30
+impl std::ops::Deref for PooledConnection {
31
+    type Target = PgConnection;
32
+    fn deref(&self) -> &Self::Target {
33
+        return &self.0;
34
+    }
35
+}
36
+
37
+#[deprecated]
9
 pub fn establish_connection() -> PgConnection {
38
 pub fn establish_connection() -> PgConnection {
10
-    let database_url = format!(
11
-        "postgres://{username}:{password}@{host}/{database}",
12
-        username = env::get_value("database.username".to_string()),
13
-        password = env::get_value("database.password".to_string()),
14
-        host = env::get_value("database.hostname".to_string()),
15
-        database = env::get_value("database.database".to_string())
16
-    );
39
+    PgConnection::establish(&prepare_postgres_url()).unwrap_or_else(|_| {
40
+        panic!(format!(
41
+            "Could not connect to {url}",
42
+            url = &prepare_postgres_url()
43
+        ))
44
+    })
45
+}
17
 
46
 
18
-    PgConnection::establish(&database_url)
19
-        .unwrap_or_else(|_| panic!(format!("Could not connect to {url}", url = &database_url)))
47
+pub fn initialize_pool() -> Pool {
48
+    let connection_manager = ConnectionManager::<PgConnection>::new(prepare_postgres_url());
49
+
50
+    // TODO: Eventually replace this with r2d2::Pool::builder()
51
+    return Pool::new(connection_manager).expect("Could not initialize database pool!");
20
 }
52
 }
21
 
53
 
22
 pub fn runtime_escape(value: &str) -> String {
54
 pub fn runtime_escape(value: &str) -> String {
26
         .filter(|&c| escape_regex.is_match(&c.to_string()))
58
         .filter(|&c| escape_regex.is_match(&c.to_string()))
27
         .collect()
59
         .collect()
28
 }
60
 }
61
+
62
+fn prepare_postgres_url() -> String {
63
+    return format!(
64
+        "postgres://{username}:{password}@{host}/{database}",
65
+        username = env::get_value("database.username".to_string()),
66
+        password = env::get_value("database.password".to_string()),
67
+        host = env::get_value("database.hostname".to_string()),
68
+        database = env::get_value("database.database".to_string())
69
+    );
70
+}

+ 14
- 8
src/env.rs View File

1
-extern crate config;
1
+use rocket::config::Environment;
2
 
2
 
3
 pub fn get_value(key: String) -> String {
3
 pub fn get_value(key: String) -> String {
4
     let mut config = config::Config::default();
4
     let mut config = config::Config::default();
5
+    let environment = match Environment::active() {
6
+        Ok(Environment::Development) => "development",
7
+        Ok(Environment::Staging) => "staging",
8
+        Ok(Environment::Production) => "production",
9
+        Err(_) => "development"
10
+    };
5
 
11
 
6
     set_default_config_values(&mut config);
12
     set_default_config_values(&mut config);
7
 
13
 
8
-    // TODO: Find config file based on ROCKET_ENV
9
     config
14
     config
10
-        .merge(config::File::with_name("env.development.toml"))
15
+        .merge(config::File::with_name(&format!("env.{}.toml", environment)))
11
         .expect("Environment config not found!");
16
         .expect("Environment config not found!");
12
 
17
 
13
-    if config.get_str(&key).is_ok() {
14
-        config.get_str(&key).ok().unwrap()
15
-    } else {
16
-        eprintln!("Key '{}' in environment config not found", &key);
17
-        String::from("")
18
+    match config.get_str(&key) {
19
+        Ok(value) => value,
20
+        Err(_) => {
21
+            eprintln!("Key '{}' not found in config", &key);
22
+            return String::from("");
23
+        }
18
     }
24
     }
19
 }
25
 }
20
 
26
 

+ 6
- 0
src/html.rs View File

1
 use regex::Regex;
1
 use regex::Regex;
2
 
2
 
3
+pub fn to_plain_text(input: &str) -> String {
4
+    let output = str::replace(&input, "\n", "<br>");
5
+
6
+    return strip_tags(&output);
7
+}
8
+
3
 pub fn strip_tags(input: &str) -> String {
9
 pub fn strip_tags(input: &str) -> String {
4
     let allowed_tags = vec!["a", "b", "br", "em", "img", "strong", "u"];
10
     let allowed_tags = vec!["a", "b", "br", "em", "img", "strong", "u"];
5
     let forbidden_attributes = vec![
11
     let forbidden_attributes = vec![

+ 7
- 16
src/kibou_api/mod.rs View File

12
 use activitypub::activity::{serialize_from_internal_activity, Tag};
12
 use activitypub::activity::{serialize_from_internal_activity, Tag};
13
 use activitypub::actor::{add_follow, remove_follow};
13
 use activitypub::actor::{add_follow, remove_follow};
14
 use activitypub::controller as ap_controller;
14
 use activitypub::controller as ap_controller;
15
-
16
 use actor::{get_actor_by_acct, get_actor_by_id, get_actor_by_uri, is_actor_followed_by, Actor};
15
 use actor::{get_actor_by_acct, get_actor_by_id, get_actor_by_uri, is_actor_followed_by, Actor};
17
 use database;
16
 use database;
17
+use database::PooledConnection;
18
 use diesel::PgConnection;
18
 use diesel::PgConnection;
19
 use html;
19
 use html;
20
 use mastodon_api;
20
 use mastodon_api;
121
     }
121
     }
122
 }
122
 }
123
 
123
 
124
-pub fn route_activities() -> JsonValue {
125
-    return json!(public_activities());
124
+pub fn public_activities(pooled_connection: &PooledConnection) -> JsonValue {
125
+    match timeline::public_activities(pooled_connection) {
126
+        Ok(activities) => mastodon_api::controller::cached_statuses(pooled_connection, activities),
127
+        Err(_) => json!({"error": "An error occured while querying public activities"}),
128
+    }
126
 }
129
 }
127
 
130
 
128
 pub fn status_build(
131
 pub fn status_build(
140
     let mut tags: Vec<serde_json::Value> = Vec::new();
143
     let mut tags: Vec<serde_json::Value> = Vec::new();
141
     let mut in_reply_to_id: Option<String>;
144
     let mut in_reply_to_id: Option<String>;
142
 
145
 
143
-    let parsed_mentions = parse_mentions(html::strip_tags(&content));
146
+    let parsed_mentions = parse_mentions(html::to_plain_text(&content));
144
     direct_receipients.extend(parsed_mentions.0);
147
     direct_receipients.extend(parsed_mentions.0);
145
     inboxes.extend(parsed_mentions.1);
148
     inboxes.extend(parsed_mentions.1);
146
     tags.extend(parsed_mentions.2);
149
     tags.extend(parsed_mentions.2);
335
     }
338
     }
336
     (receipients, inboxes, tags, new_content)
339
     (receipients, inboxes, tags, new_content)
337
 }
340
 }
338
-
339
-fn public_activities() -> Vec<mastodon_api::Status> {
340
-    let database = database::establish_connection();
341
-
342
-    match timeline::public_activities(&database) {
343
-        Ok(activities) => activities
344
-            .iter()
345
-            .map(|activity| mastodon_api::controller::status_cached_by_id(*activity).unwrap())
346
-            .collect(),
347
-        Err(_) => Vec::new(),
348
-    }
349
-}

+ 3
- 2
src/kibou_api/routes.rs View File

1
+use database::PooledConnection;
1
 use kibou_api;
2
 use kibou_api;
2
 use rocket_contrib::json::JsonValue;
3
 use rocket_contrib::json::JsonValue;
3
 
4
 
4
 #[get("/api/kibou/activities")]
5
 #[get("/api/kibou/activities")]
5
-pub fn activities() -> JsonValue {
6
-    return kibou_api::route_activities();
6
+pub fn activities(pooled_connection: PooledConnection) -> JsonValue {
7
+    return kibou_api::public_activities(&pooled_connection);
7
 }
8
 }

+ 4
- 2
src/lib.rs View File

3
 
3
 
4
 extern crate base64;
4
 extern crate base64;
5
 extern crate bcrypt;
5
 extern crate bcrypt;
6
-#[macro_use]
7
-extern crate cached;
8
 extern crate chrono;
6
 extern crate chrono;
9
 #[macro_use]
7
 #[macro_use]
10
 extern crate diesel;
8
 extern crate diesel;
9
+#[macro_use]
10
+extern crate lazy_static;
11
+extern crate lru;
11
 extern crate openssl;
12
 extern crate openssl;
12
 extern crate pem;
13
 extern crate pem;
13
 extern crate regex;
14
 extern crate regex;
14
 extern crate reqwest;
15
 extern crate reqwest;
15
 #[macro_use]
16
 #[macro_use]
16
 extern crate rocket;
17
 extern crate rocket;
18
+extern crate core;
17
 extern crate rocket_contrib;
19
 extern crate rocket_contrib;
18
 extern crate serde;
20
 extern crate serde;
19
 extern crate serde_json;
21
 extern crate serde_json;

+ 251
- 532
src/mastodon_api/controller.rs View File

1
 use activity;
1
 use activity;
2
-use activity::{get_ap_object_by_id, get_ap_object_replies_by_id, type_exists_for_object_id};
2
+use activity::{
3
+    get_activities_by_id, get_ap_object_by_id, get_ap_object_replies_by_id,
4
+    type_exists_for_object_id,
5
+};
3
 use activitypub;
6
 use activitypub;
4
 use actor;
7
 use actor;
5
 use actor::get_actor_by_id;
8
 use actor::get_actor_by_id;
6
 use actor::get_actor_by_uri;
9
 use actor::get_actor_by_uri;
7
-use cached::TimedCache;
8
 use chrono;
10
 use chrono;
9
 use chrono::Utc;
11
 use chrono::Utc;
12
+use core::borrow::Borrow;
10
 use database;
13
 use database;
14
+use database::PooledConnection;
11
 use diesel::PgConnection;
15
 use diesel::PgConnection;
12
 use env;
16
 use env;
13
 use kibou_api;
17
 use kibou_api;
18
+use lru::LruCache;
19
+use mastodon_api::routes::status;
14
 use mastodon_api::{
20
 use mastodon_api::{
15
     Account, Attachment, HomeTimeline, Instance, Notification, PublicTimeline, RegistrationForm,
21
     Account, Attachment, HomeTimeline, Instance, Notification, PublicTimeline, RegistrationForm,
16
-    Relationship, Source, Status, StatusForm,
22
+    Relationship, Source, Status, StatusForm, MASTODON_API_ACCOUNT_CACHE,
23
+    MASTODON_API_NOTIFICATION_CACHE, MASTODON_API_STATUS_CACHE,
17
 };
24
 };
18
 use notification::notifications_for_actor;
25
 use notification::notifications_for_actor;
19
 use oauth;
26
 use oauth;
25
 use timeline;
32
 use timeline;
26
 use timeline::{home_timeline as get_home_timeline, public_timeline as get_public_timeline};
33
 use timeline::{home_timeline as get_home_timeline, public_timeline as get_public_timeline};
27
 
34
 
28
-pub fn account(id: i64) -> JsonValue {
29
-    let database = database::establish_connection();
30
-
31
-    match actor::get_actor_by_id(&database, &id) {
32
-        Ok(actor) => json!(serialize_account(actor, false)),
35
+pub fn account(pooled_connection: &PooledConnection, id: i64) -> JsonValue {
36
+    match actor::get_actor_by_id(pooled_connection, &id) {
37
+        Ok(actor) => json!(Account::from_actor(pooled_connection, actor, false)),
33
         Err(_) => json!({"error": "User not found."}),
38
         Err(_) => json!({"error": "User not found."}),
34
     }
39
     }
35
 }
40
 }
36
 
41
 
37
-pub fn account_by_oauth_token(token: String) -> Result<Account, diesel::result::Error> {
38
-    let database = database::establish_connection();
39
-
40
-    match verify_token(&database, token) {
41
-        Ok(token) => match actor::get_local_actor_by_preferred_username(&database, &token.actor) {
42
-            Ok(actor) => Ok(serialize_account(actor, true)),
43
-            Err(e) => Err(e),
44
-        },
45
-        Err(e) => Err(e),
46
-    }
47
-}
48
-
49
-pub fn account_json_by_oauth_token(token: String) -> JsonValue {
50
-    let database = database::establish_connection();
51
-
52
-    match verify_token(&database, token) {
53
-        Ok(token) => match actor::get_local_actor_by_preferred_username(&database, &token.actor) {
54
-            Ok(actor) => json!(serialize_account(actor, true)),
55
-            Err(_) => json!({"error": "No user is associated to this token!"}),
56
-        },
42
+pub fn account_by_oauth_token(pooled_connection: &PooledConnection, token: String) -> JsonValue {
43
+    match verify_token(pooled_connection, token) {
44
+        Ok(token) => {
45
+            match actor::get_local_actor_by_preferred_username(pooled_connection, &token.actor) {
46
+                Ok(actor) => json!(Account::from_actor(pooled_connection, actor, true)),
47
+                Err(_) => json!({"error": "No user is associated to this token!"}),
48
+            }
49
+        }
57
         Err(_) => json!({"error": "Token invalid!"}),
50
         Err(_) => json!({"error": "Token invalid!"}),
58
     }
51
     }
59
 }
52
 }
60
 
53
 
61
-pub fn account_create_json(form: &RegistrationForm) -> JsonValue {
62
-    match account_create(form) {
63
-        Some(token) => serde_json::to_value(token).unwrap().into(),
64
-        None => json!({"error": "Account could not be created!"}),
65
-    }
66
-}
67
-
68
-pub fn account_create(form: &RegistrationForm) -> Option<Token> {
54
+pub fn account_create(form: &RegistrationForm) -> JsonValue {
69
     let email_regex = Regex::new(r"^[a-zA-Z0-9_.+-]+@[a-zA-Z0-9-]+\.[a-zA-Z0-9-.]+$").unwrap();
55
     let email_regex = Regex::new(r"^[a-zA-Z0-9_.+-]+@[a-zA-Z0-9-]+\.[a-zA-Z0-9-.]+$").unwrap();
70
     let username_regex = Regex::new(r"^[A-Za-z0-9_]{1,32}$").unwrap();
56
     let username_regex = Regex::new(r"^[A-Za-z0-9_]{1,32}$").unwrap();
71
 
57
 
96
         actor::create_actor(&database, &mut new_actor);
82
         actor::create_actor(&database, &mut new_actor);
97
 
83
 
98
         match actor::get_local_actor_by_preferred_username(&database, &form.username) {
84
         match actor::get_local_actor_by_preferred_username(&database, &form.username) {
99
-            Ok(_actor) => Some(oauth::token::create(&form.username)),
100
-            Err(_) => None,
85
+            Ok(_actor) => json!(oauth::token::create(&form.username)),
86
+            Err(_) => json!({"error": "Account could not be created"}),
101
         }
87
         }
102
     } else {
88
     } else {
103
-        return None;
89
+        return json!({"error": "Username or E-mail contains unsupported characters"});
104
     }
90
     }
105
 }
91
 }
106
 
92
 
107
-pub fn account_statuses_json_by_id(
93
+pub fn account_statuses_by_id(
94
+    pooled_connection: &PooledConnection,
108
     id: i64,
95
     id: i64,
109
     max_id: Option<i64>,
96
     max_id: Option<i64>,
110
     since_id: Option<i64>,
97
     since_id: Option<i64>,
111
     min_id: Option<i64>,
98
     min_id: Option<i64>,
112
     limit: Option<i64>,
99
     limit: Option<i64>,
113
 ) -> JsonValue {
100
 ) -> JsonValue {
114
-    let database = database::establish_connection();
115
-
116
-    match actor::get_actor_by_id(&database, &id) {
101
+    match actor::get_actor_by_id(pooled_connection, &id) {
117
         Ok(actor) => {
102
         Ok(actor) => {
118
-            match timeline::user_timeline(&database, actor, max_id, since_id, min_id, limit) {
119
-                Ok(statuses) => {
120
-                    let status_vec: Vec<Status> = statuses
121
-                        .iter()
122
-                        .filter(|&id| status_cached_by_id(*id).is_ok())
123
-                        .map(|id| status_cached_by_id(*id).unwrap())
124
-                        .collect();
125
-                    return json!(status_vec);
126
-                }
103
+            match timeline::user_timeline(pooled_connection, actor, max_id, since_id, min_id, limit)
104
+            {
105
+                Ok(statuses) => cached_statuses(pooled_connection, statuses),
127
                 Err(_) => json!({"error": "Error generating user timeline."}),
106
                 Err(_) => json!({"error": "Error generating user timeline."}),
128
             }
107
             }
129
         }
108
         }
131
     }
110
     }
132
 }
111
 }
133
 
112
 
134
-pub fn application_create(application: OAuthApplication) -> rocket_contrib::json::JsonValue {
135
-    let database = database::establish_connection();
136
-    let oauth_app: OAuthApplication = oauth::application::create(&database, application);
113
+pub fn application_create(
114
+    pooled_connection: &PooledConnection,
115
+    application: OAuthApplication,
116
+) -> JsonValue {
117
+    let oauth_app: OAuthApplication = oauth::application::create(pooled_connection, application);
137
     rocket_contrib::json!({
118
     rocket_contrib::json!({
138
         "name": oauth_app.client_name.unwrap_or_default(),
119
         "name": oauth_app.client_name.unwrap_or_default(),
139
         "website": oauth_app.website,
120
         "website": oauth_app.website,
144
     })
125
     })
145
 }
126
 }
146
 
127
 
147
-pub fn context_json_for_id(id: i64) -> JsonValue {
148
-    let database = database::establish_connection();
128
+pub fn cached_account(pooled_connection: &PooledConnection, uri: &str) -> JsonValue {
129
+    let mut account_cache = MASTODON_API_ACCOUNT_CACHE.lock().unwrap();
130
+
131
+    if account_cache.contains(&uri.to_string()) {
132
+        return json!(account_cache.get(&uri.to_string()));
133
+    } else {
134
+        match actor::get_actor_by_uri(pooled_connection, uri) {
135
+            Ok(actor) => {
136
+                let result =
137
+                    serde_json::json!(Account::from_actor(pooled_connection, actor, false));
138
+                account_cache.put(uri.to_string(), result.clone());
139
+                return json!(result);
140
+            }
141
+            Err(_) => json!({ "error": format!("Account not found: {}", uri) }),
142
+        }
143
+    }
144
+}
149
 
145
 
150
-    match activity::get_activity_by_id(&database, id) {
146
+pub fn cached_notifications(pooled_connection: &PooledConnection, ids: Vec<i64>) -> JsonValue {
147
+    let mut notification_cache = MASTODON_API_NOTIFICATION_CACHE.lock().unwrap();
148
+    let mut notifications: Vec<Notification> = Vec::new();
149
+    let mut uncached_notifications: Vec<i64> = Vec::new();
150
+    for id in ids {