A decentralized music tracking and discovery platform built on AT Protocol 🎵

[storage] add storage service (Cloudflare R2)

+514 -40
+308 -40
Cargo.lock
··· 30 30 "actix-service", 31 31 "actix-utils", 32 32 "ahash 0.8.11", 33 - "base64", 33 + "base64 0.22.1", 34 34 "bitflags 2.8.0", 35 35 "brotli", 36 36 "bytes", ··· 455 455 "arrow-schema", 456 456 "arrow-select", 457 457 "atoi", 458 - "base64", 458 + "base64 0.22.1", 459 459 "chrono", 460 460 "comfy-table", 461 461 "half", ··· 548 548 source = "registry+https://github.com/rust-lang/crates.io-index" 549 549 checksum = "a798aab0c0203b31d67d501e5ed1f3ac6c36a329899ce47fc93c3bea53f3ae89" 550 550 dependencies = [ 551 - "base64", 551 + "base64 0.22.1", 552 552 "bytes", 553 553 "futures", 554 554 "memchr", ··· 560 560 "rand 0.8.5", 561 561 "regex", 562 562 "ring", 563 - "rustls-native-certs", 564 - "rustls-pemfile", 565 - "rustls-webpki", 563 + "rustls-native-certs 0.7.3", 564 + "rustls-pemfile 2.2.0", 565 + "rustls-webpki 0.102.8", 566 566 "serde", 567 567 "serde_json", 568 568 "serde_nanos", ··· 570 570 "thiserror 1.0.69", 571 571 "time", 572 572 "tokio", 573 - "tokio-rustls", 573 + "tokio-rustls 0.26.1", 574 574 "tokio-util", 575 575 "tokio-websockets", 576 576 "tracing", ··· 633 633 checksum = "1505bd5d3d116872e7271a6d4e16d81d0c8570876c8de68093a09ac269d8aac0" 634 634 635 635 [[package]] 636 + name = "attohttpc" 637 + version = "0.28.5" 638 + source = "registry+https://github.com/rust-lang/crates.io-index" 639 + checksum = "07a9b245ba0739fc90935094c29adbaee3f977218b5fb95e822e261cda7f56a3" 640 + dependencies = [ 641 + "http 1.2.0", 642 + "log", 643 + "rustls 0.23.23", 644 + "serde", 645 + "serde_json", 646 + "url", 647 + "webpki-roots", 648 + ] 649 + 650 + [[package]] 636 651 name = "autocfg" 637 652 version = "1.4.0" 638 653 source = "registry+https://github.com/rust-lang/crates.io-index" 639 654 checksum = "ace50bade8e6234aa140d9a2f552bbee1db4d353f69b8217bc503490fc1a9f26" 640 655 641 656 [[package]] 657 + name = "aws-creds" 658 + version = "0.37.0" 659 + source = "registry+https://github.com/rust-lang/crates.io-index" 660 + checksum = "7f84143206b9c72b3c5cb65415de60c7539c79cd1559290fddec657939131be0" 661 + dependencies = [ 662 + "attohttpc", 663 + "home", 664 + "log", 665 + "quick-xml 0.32.0", 666 + "rust-ini", 667 + "serde", 668 + "thiserror 1.0.69", 669 + "time", 670 + "url", 671 + ] 672 + 673 + [[package]] 674 + name = "aws-region" 675 + version = "0.25.5" 676 + source = "registry+https://github.com/rust-lang/crates.io-index" 677 + checksum = "e9aed3f9c7eac9be28662fdb3b0f4d1951e812f7c64fed4f0327ba702f459b3b" 678 + dependencies = [ 679 + "thiserror 1.0.69", 680 + ] 681 + 682 + [[package]] 642 683 name = "backtrace" 643 684 version = "0.3.74" 644 685 source = "registry+https://github.com/rust-lang/crates.io-index" ··· 652 693 "rustc-demangle", 653 694 "windows-targets 0.52.6", 654 695 ] 696 + 697 + [[package]] 698 + name = "base64" 699 + version = "0.21.7" 700 + source = "registry+https://github.com/rust-lang/crates.io-index" 701 + checksum = "9d297deb1925b89f2ccc13d7635fa0714f12c87adce1c75356b39ca9b7178567" 655 702 656 703 [[package]] 657 704 name = "base64" ··· 1251 1298 ] 1252 1299 1253 1300 [[package]] 1301 + name = "dlv-list" 1302 + version = "0.5.2" 1303 + source = "registry+https://github.com/rust-lang/crates.io-index" 1304 + checksum = "442039f5147480ba31067cb00ada1adae6892028e40e45fc5de7b7df6dcc1b5f" 1305 + dependencies = [ 1306 + "const-random", 1307 + ] 1308 + 1309 + [[package]] 1254 1310 name = "dotenv" 1255 1311 version = "0.15.0" 1256 1312 source = "registry+https://github.com/rust-lang/crates.io-index" ··· 1839 1895 1840 1896 [[package]] 1841 1897 name = "http-body" 1898 + version = "0.4.6" 1899 + source = "registry+https://github.com/rust-lang/crates.io-index" 1900 + checksum = "7ceab25649e9960c0311ea418d17bee82c0dcec1bd053b5f9a66e265a693bed2" 1901 + dependencies = [ 1902 + "bytes", 1903 + "http 0.2.12", 1904 + "pin-project-lite", 1905 + ] 1906 + 1907 + [[package]] 1908 + name = "http-body" 1842 1909 version = "1.0.1" 1843 1910 source = "registry+https://github.com/rust-lang/crates.io-index" 1844 1911 checksum = "1efedce1fb8e6913f23e0c92de8e62cd5b772a67e7b3946df930a62566c93184" ··· 1856 1923 "bytes", 1857 1924 "futures-util", 1858 1925 "http 1.2.0", 1859 - "http-body", 1926 + "http-body 1.0.1", 1860 1927 "pin-project-lite", 1861 1928 ] 1862 1929 ··· 1874 1941 1875 1942 [[package]] 1876 1943 name = "hyper" 1944 + version = "0.14.32" 1945 + source = "registry+https://github.com/rust-lang/crates.io-index" 1946 + checksum = "41dfc780fdec9373c01bae43289ea34c972e40ee3c9f6b3c8801a35f35586ce7" 1947 + dependencies = [ 1948 + "bytes", 1949 + "futures-channel", 1950 + "futures-core", 1951 + "futures-util", 1952 + "http 0.2.12", 1953 + "http-body 0.4.6", 1954 + "httparse", 1955 + "httpdate", 1956 + "itoa", 1957 + "pin-project-lite", 1958 + "socket2", 1959 + "tokio", 1960 + "tower-service", 1961 + "tracing", 1962 + "want", 1963 + ] 1964 + 1965 + [[package]] 1966 + name = "hyper" 1877 1967 version = "1.6.0" 1878 1968 source = "registry+https://github.com/rust-lang/crates.io-index" 1879 1969 checksum = "cc2b571658e38e0c01b1fdca3bbbe93c00d3d71693ff2770043f8c29bc7d6f80" ··· 1882 1972 "futures-channel", 1883 1973 "futures-util", 1884 1974 "http 1.2.0", 1885 - "http-body", 1975 + "http-body 1.0.1", 1886 1976 "httparse", 1887 1977 "itoa", 1888 1978 "pin-project-lite", ··· 1893 1983 1894 1984 [[package]] 1895 1985 name = "hyper-rustls" 1986 + version = "0.24.2" 1987 + source = "registry+https://github.com/rust-lang/crates.io-index" 1988 + checksum = "ec3efd23720e2049821a693cbc7e65ea87c72f1c58ff2f9522ff332b1491e590" 1989 + dependencies = [ 1990 + "futures-util", 1991 + "http 0.2.12", 1992 + "hyper 0.14.32", 1993 + "rustls 0.21.12", 1994 + "tokio", 1995 + "tokio-rustls 0.24.1", 1996 + ] 1997 + 1998 + [[package]] 1999 + name = "hyper-rustls" 1896 2000 version = "0.27.5" 1897 2001 source = "registry+https://github.com/rust-lang/crates.io-index" 1898 2002 checksum = "2d191583f3da1305256f22463b9bb0471acad48a4e534a5218b9963e9c1f59b2" 1899 2003 dependencies = [ 1900 2004 "futures-util", 1901 2005 "http 1.2.0", 1902 - "hyper", 2006 + "hyper 1.6.0", 1903 2007 "hyper-util", 1904 - "rustls", 2008 + "rustls 0.23.23", 1905 2009 "rustls-pki-types", 1906 2010 "tokio", 1907 - "tokio-rustls", 2011 + "tokio-rustls 0.26.1", 1908 2012 "tower-service", 1909 2013 "webpki-roots", 1910 2014 ] ··· 1919 2023 "futures-channel", 1920 2024 "futures-util", 1921 2025 "http 1.2.0", 1922 - "http-body", 1923 - "hyper", 2026 + "http-body 1.0.1", 2027 + "hyper 1.6.0", 1924 2028 "pin-project-lite", 1925 2029 "socket2", 1926 2030 "tokio", ··· 2181 2285 source = "registry+https://github.com/rust-lang/crates.io-index" 2182 2286 checksum = "5a87cc7a48537badeae96744432de36f4be2b4a34a05a5ef32e9dd8a1c169dde" 2183 2287 dependencies = [ 2184 - "base64", 2288 + "base64 0.22.1", 2185 2289 "js-sys", 2186 2290 "pem", 2187 2291 "ring", ··· 2414 2518 ] 2415 2519 2416 2520 [[package]] 2521 + name = "maybe-async" 2522 + version = "0.2.10" 2523 + source = "registry+https://github.com/rust-lang/crates.io-index" 2524 + checksum = "5cf92c10c7e361d6b99666ec1c6f9805b0bea2c3bd8c78dc6fe98ac5bd78db11" 2525 + dependencies = [ 2526 + "proc-macro2", 2527 + "quote", 2528 + "syn 2.0.98", 2529 + ] 2530 + 2531 + [[package]] 2417 2532 name = "md-5" 2418 2533 version = "0.10.6" 2419 2534 source = "registry+https://github.com/rust-lang/crates.io-index" ··· 2651 2766 checksum = "d05e27ee213611ffe7d6348b942e8f942b37114c00cc03cec254295a4a17852e" 2652 2767 2653 2768 [[package]] 2769 + name = "ordered-multimap" 2770 + version = "0.7.3" 2771 + source = "registry+https://github.com/rust-lang/crates.io-index" 2772 + checksum = "49203cdcae0030493bad186b28da2fa25645fa276a51b6fec8010d281e02ef79" 2773 + dependencies = [ 2774 + "dlv-list", 2775 + "hashbrown 0.14.5", 2776 + ] 2777 + 2778 + [[package]] 2654 2779 name = "owo-colors" 2655 2780 version = "4.1.0" 2656 2781 source = "registry+https://github.com/rust-lang/crates.io-index" ··· 2706 2831 source = "registry+https://github.com/rust-lang/crates.io-index" 2707 2832 checksum = "8e459365e590736a54c3fa561947c84837534b8e9af6fc5bf781307e82658fae" 2708 2833 dependencies = [ 2709 - "base64", 2834 + "base64 0.22.1", 2710 2835 "serde", 2711 2836 ] 2712 2837 ··· 3100 3225 dependencies = [ 3101 3226 "ahash 0.8.11", 3102 3227 "argminmax", 3103 - "base64", 3228 + "base64 0.22.1", 3104 3229 "bytemuck", 3105 3230 "chrono", 3106 3231 "chrono-tz", ··· 3134 3259 dependencies = [ 3135 3260 "ahash 0.8.11", 3136 3261 "async-stream", 3137 - "base64", 3262 + "base64 0.22.1", 3138 3263 "bytemuck", 3139 3264 "ethnum", 3140 3265 "futures", ··· 3412 3537 3413 3538 [[package]] 3414 3539 name = "quick-xml" 3540 + version = "0.32.0" 3541 + source = "registry+https://github.com/rust-lang/crates.io-index" 3542 + checksum = "1d3a6e5838b60e0e8fa7a43f22ade549a37d61f8bdbe636d0d7816191de969c2" 3543 + dependencies = [ 3544 + "memchr", 3545 + "serde", 3546 + ] 3547 + 3548 + [[package]] 3549 + name = "quick-xml" 3415 3550 version = "0.37.4" 3416 3551 source = "registry+https://github.com/rust-lang/crates.io-index" 3417 3552 checksum = "a4ce8c88de324ff838700f36fb6ab86c96df0e3c4ab6ef3a9b2044465cce1369" ··· 3431 3566 "quinn-proto", 3432 3567 "quinn-udp", 3433 3568 "rustc-hash", 3434 - "rustls", 3569 + "rustls 0.23.23", 3435 3570 "socket2", 3436 3571 "thiserror 2.0.11", 3437 3572 "tokio", ··· 3449 3584 "rand 0.8.5", 3450 3585 "ring", 3451 3586 "rustc-hash", 3452 - "rustls", 3587 + "rustls 0.23.23", 3453 3588 "rustls-pki-types", 3454 3589 "slab", 3455 3590 "thiserror 2.0.11", ··· 3682 3817 source = "registry+https://github.com/rust-lang/crates.io-index" 3683 3818 checksum = "43e734407157c3c2034e0258f5e4473ddb361b1e85f95a66690d67264d7cd1da" 3684 3819 dependencies = [ 3685 - "base64", 3820 + "base64 0.22.1", 3686 3821 "bytes", 3687 3822 "futures-core", 3688 3823 "futures-util", 3689 3824 "http 1.2.0", 3690 - "http-body", 3825 + "http-body 1.0.1", 3691 3826 "http-body-util", 3692 - "hyper", 3693 - "hyper-rustls", 3827 + "hyper 1.6.0", 3828 + "hyper-rustls 0.27.5", 3694 3829 "hyper-util", 3695 3830 "ipnet", 3696 3831 "js-sys", ··· 3701 3836 "percent-encoding", 3702 3837 "pin-project-lite", 3703 3838 "quinn", 3704 - "rustls", 3705 - "rustls-pemfile", 3839 + "rustls 0.23.23", 3840 + "rustls-pemfile 2.2.0", 3706 3841 "rustls-pki-types", 3707 3842 "serde", 3708 3843 "serde_json", 3709 3844 "serde_urlencoded", 3710 3845 "sync_wrapper", 3711 3846 "tokio", 3712 - "tokio-rustls", 3847 + "tokio-rustls 0.26.1", 3713 3848 "tokio-util", 3714 3849 "tower", 3715 3850 "tower-service", ··· 3786 3921 ] 3787 3922 3788 3923 [[package]] 3924 + name = "rust-ini" 3925 + version = "0.21.1" 3926 + source = "registry+https://github.com/rust-lang/crates.io-index" 3927 + checksum = "4e310ef0e1b6eeb79169a1171daf9abcb87a2e17c03bee2c4bb100b55c75409f" 3928 + dependencies = [ 3929 + "cfg-if", 3930 + "ordered-multimap", 3931 + "trim-in-place", 3932 + ] 3933 + 3934 + [[package]] 3935 + name = "rust-s3" 3936 + version = "0.35.1" 3937 + source = "registry+https://github.com/rust-lang/crates.io-index" 3938 + checksum = "c3df3f353b1f4209dcf437d777cda90279c397ab15a0cd6fd06bd32c88591533" 3939 + dependencies = [ 3940 + "async-trait", 3941 + "aws-creds", 3942 + "aws-region", 3943 + "base64 0.22.1", 3944 + "bytes", 3945 + "cfg-if", 3946 + "futures", 3947 + "hex", 3948 + "hmac", 3949 + "http 0.2.12", 3950 + "hyper 0.14.32", 3951 + "hyper-rustls 0.24.2", 3952 + "log", 3953 + "maybe-async", 3954 + "md5", 3955 + "percent-encoding", 3956 + "quick-xml 0.32.0", 3957 + "rustls 0.21.12", 3958 + "rustls-native-certs 0.6.3", 3959 + "serde", 3960 + "serde_derive", 3961 + "serde_json", 3962 + "sha2", 3963 + "thiserror 1.0.69", 3964 + "time", 3965 + "tokio", 3966 + "tokio-rustls 0.24.1", 3967 + "tokio-stream", 3968 + "url", 3969 + ] 3970 + 3971 + [[package]] 3789 3972 name = "rust_decimal" 3790 3973 version = "1.36.0" 3791 3974 source = "registry+https://github.com/rust-lang/crates.io-index" ··· 3850 4033 3851 4034 [[package]] 3852 4035 name = "rustls" 4036 + version = "0.21.12" 4037 + source = "registry+https://github.com/rust-lang/crates.io-index" 4038 + checksum = "3f56a14d1f48b391359b22f731fd4bd7e43c97f3c50eee276f3aa09c94784d3e" 4039 + dependencies = [ 4040 + "log", 4041 + "ring", 4042 + "rustls-webpki 0.101.7", 4043 + "sct", 4044 + ] 4045 + 4046 + [[package]] 4047 + name = "rustls" 3853 4048 version = "0.23.23" 3854 4049 source = "registry+https://github.com/rust-lang/crates.io-index" 3855 4050 checksum = "47796c98c480fce5406ef69d1c76378375492c3b0a0de587be0c1d9feb12f395" ··· 3857 4052 "once_cell", 3858 4053 "ring", 3859 4054 "rustls-pki-types", 3860 - "rustls-webpki", 4055 + "rustls-webpki 0.102.8", 3861 4056 "subtle", 3862 4057 "zeroize", 3863 4058 ] 3864 4059 3865 4060 [[package]] 3866 4061 name = "rustls-native-certs" 4062 + version = "0.6.3" 4063 + source = "registry+https://github.com/rust-lang/crates.io-index" 4064 + checksum = "a9aace74cb666635c918e9c12bc0d348266037aa8eb599b5cba565709a8dff00" 4065 + dependencies = [ 4066 + "openssl-probe", 4067 + "rustls-pemfile 1.0.4", 4068 + "schannel", 4069 + "security-framework", 4070 + ] 4071 + 4072 + [[package]] 4073 + name = "rustls-native-certs" 3867 4074 version = "0.7.3" 3868 4075 source = "registry+https://github.com/rust-lang/crates.io-index" 3869 4076 checksum = "e5bfb394eeed242e909609f56089eecfe5fda225042e8b171791b9c95f5931e5" 3870 4077 dependencies = [ 3871 4078 "openssl-probe", 3872 - "rustls-pemfile", 4079 + "rustls-pemfile 2.2.0", 3873 4080 "rustls-pki-types", 3874 4081 "schannel", 3875 4082 "security-framework", ··· 3877 4084 3878 4085 [[package]] 3879 4086 name = "rustls-pemfile" 4087 + version = "1.0.4" 4088 + source = "registry+https://github.com/rust-lang/crates.io-index" 4089 + checksum = "1c74cae0a4cf6ccbbf5f359f08efdf8ee7e1dc532573bf0db71968cb56b1448c" 4090 + dependencies = [ 4091 + "base64 0.21.7", 4092 + ] 4093 + 4094 + [[package]] 4095 + name = "rustls-pemfile" 3880 4096 version = "2.2.0" 3881 4097 source = "registry+https://github.com/rust-lang/crates.io-index" 3882 4098 checksum = "dce314e5fee3f39953d46bb63bb8a46d40c2f8fb7cc5a3b6cab2bde9721d6e50" ··· 3895 4111 3896 4112 [[package]] 3897 4113 name = "rustls-webpki" 4114 + version = "0.101.7" 4115 + source = "registry+https://github.com/rust-lang/crates.io-index" 4116 + checksum = "8b6275d1ee7a1cd780b64aca7726599a1dbc893b1e64144529e55c3c2f745765" 4117 + dependencies = [ 4118 + "ring", 4119 + "untrusted", 4120 + ] 4121 + 4122 + [[package]] 4123 + name = "rustls-webpki" 3898 4124 version = "0.102.8" 3899 4125 source = "registry+https://github.com/rust-lang/crates.io-index" 3900 4126 checksum = "64ca1bc8749bd4cf37b5ce386cc146580777b4e8572c7b97baf22c83f444bee9" ··· 3945 4171 "jsonwebtoken", 3946 4172 "md5", 3947 4173 "owo-colors", 3948 - "quick-xml", 4174 + "quick-xml 0.37.4", 3949 4175 "rand 0.9.0", 3950 4176 "redis", 3951 4177 "reqwest", ··· 3953 4179 "serde_json", 3954 4180 "sqlx", 3955 4181 "tokio", 4182 + ] 4183 + 4184 + [[package]] 4185 + name = "sct" 4186 + version = "0.7.1" 4187 + source = "registry+https://github.com/rust-lang/crates.io-index" 4188 + checksum = "da046153aa2352493d6cb7da4b6e5c0c057d8a1d0a9aa8560baffdd945acd414" 4189 + dependencies = [ 4190 + "ring", 4191 + "untrusted", 3956 4192 ] 3957 4193 3958 4194 [[package]] ··· 4279 4515 "memchr", 4280 4516 "once_cell", 4281 4517 "percent-encoding", 4282 - "rustls", 4283 - "rustls-pemfile", 4518 + "rustls 0.23.23", 4519 + "rustls-pemfile 2.2.0", 4284 4520 "serde", 4285 4521 "serde_json", 4286 4522 "sha2", ··· 4339 4575 checksum = "4560278f0e00ce64938540546f59f590d60beee33fffbd3b9cd47851e5fff233" 4340 4576 dependencies = [ 4341 4577 "atoi", 4342 - "base64", 4578 + "base64 0.22.1", 4343 4579 "bitflags 2.8.0", 4344 4580 "byteorder", 4345 4581 "bytes", ··· 4382 4618 checksum = "c5b98a57f363ed6764d5b3a12bfedf62f07aa16e1856a7ddc2a0bb190a959613" 4383 4619 dependencies = [ 4384 4620 "atoi", 4385 - "base64", 4621 + "base64 0.22.1", 4386 4622 "bitflags 2.8.0", 4387 4623 "byteorder", 4388 4624 "chrono", ··· 4463 4699 checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" 4464 4700 4465 4701 [[package]] 4702 + name = "storage" 4703 + version = "0.1.0" 4704 + dependencies = [ 4705 + "actix-web", 4706 + "anyhow", 4707 + "dotenv", 4708 + "owo-colors", 4709 + "rust-s3", 4710 + "serde", 4711 + "serde_json", 4712 + "sqlx", 4713 + "tokio", 4714 + "tokio-stream", 4715 + ] 4716 + 4717 + [[package]] 4466 4718 name = "streaming-decompression" 4467 4719 version = "0.1.2" 4468 4720 source = "registry+https://github.com/rust-lang/crates.io-index" ··· 4957 5209 4958 5210 [[package]] 4959 5211 name = "tokio-rustls" 5212 + version = "0.24.1" 5213 + source = "registry+https://github.com/rust-lang/crates.io-index" 5214 + checksum = "c28327cf380ac148141087fbfb9de9d7bd4e84ab5d2c28fbc911d753de8a7081" 5215 + dependencies = [ 5216 + "rustls 0.21.12", 5217 + "tokio", 5218 + ] 5219 + 5220 + [[package]] 5221 + name = "tokio-rustls" 4960 5222 version = "0.26.1" 4961 5223 source = "registry+https://github.com/rust-lang/crates.io-index" 4962 5224 checksum = "5f6d0975eaace0cf0fcadee4e4aaa5da15b5c079146f2cffb67c113be122bf37" 4963 5225 dependencies = [ 4964 - "rustls", 5226 + "rustls 0.23.23", 4965 5227 "tokio", 4966 5228 ] 4967 5229 ··· 4985 5247 dependencies = [ 4986 5248 "futures-util", 4987 5249 "log", 4988 - "rustls", 5250 + "rustls 0.23.23", 4989 5251 "rustls-pki-types", 4990 5252 "tokio", 4991 - "tokio-rustls", 5253 + "tokio-rustls 0.26.1", 4992 5254 "tungstenite", 4993 5255 "webpki-roots", 4994 5256 ] ··· 5012 5274 source = "registry+https://github.com/rust-lang/crates.io-index" 5013 5275 checksum = "f591660438b3038dd04d16c938271c79e7e06260ad2ea2885a4861bfb238605d" 5014 5276 dependencies = [ 5015 - "base64", 5277 + "base64 0.22.1", 5016 5278 "bytes", 5017 5279 "futures-core", 5018 5280 "futures-sink", ··· 5022 5284 "ring", 5023 5285 "rustls-pki-types", 5024 5286 "tokio", 5025 - "tokio-rustls", 5287 + "tokio-rustls 0.26.1", 5026 5288 "tokio-util", 5027 5289 "webpki-roots", 5028 5290 ] ··· 5104 5366 ] 5105 5367 5106 5368 [[package]] 5369 + name = "trim-in-place" 5370 + version = "0.1.7" 5371 + source = "registry+https://github.com/rust-lang/crates.io-index" 5372 + checksum = "343e926fc669bc8cde4fa3129ab681c63671bae288b1f1081ceee6d9d37904fc" 5373 + 5374 + [[package]] 5107 5375 name = "try-lock" 5108 5376 version = "0.2.5" 5109 5377 source = "registry+https://github.com/rust-lang/crates.io-index" ··· 5132 5400 "httparse", 5133 5401 "log", 5134 5402 "rand 0.9.0", 5135 - "rustls", 5403 + "rustls 0.23.23", 5136 5404 "rustls-pki-types", 5137 5405 "sha1", 5138 5406 "thiserror 2.0.11",
+1
crates/storage/.gitignore
··· 1 + .env
+28
crates/storage/Cargo.toml
··· 1 + [package] 2 + name = "storage" 3 + version = "0.1.0" 4 + authors.workspace = true 5 + edition.workspace = true 6 + license.workspace = true 7 + repository.workspace = true 8 + 9 + [dependencies] 10 + rust-s3 = { version = "0.35.1", features = [ 11 + "tokio-rustls-tls", 12 + ], default-features = false } 13 + tokio = { version = "1.43.0", features = ["full"] } 14 + owo-colors = "4.1.0" 15 + dotenv = "0.15.0" 16 + anyhow = "1.0.96" 17 + serde = { version = "1.0.217", features = ["derive"] } 18 + serde_json = "1.0.139" 19 + sqlx = { version = "0.8.3", features = [ 20 + "runtime-tokio", 21 + "tls-rustls", 22 + "postgres", 23 + "chrono", 24 + "derive", 25 + "macros", 26 + ] } 27 + actix-web = "4.9.0" 28 + tokio-stream = { version = "0.1.17", features = ["full"] }
+6
crates/storage/src/handlers/files.rs
··· 1 + use actix_web::{web, HttpRequest, HttpResponse}; 2 + use anyhow::Error; 3 + 4 + pub async fn presign_get(payload: &mut web::Payload, _req: &HttpRequest,) -> Result<HttpResponse, Error> { 5 + todo!() 6 + }
+51
crates/storage/src/handlers/folders.rs
··· 1 + use actix_web::{web, HttpRequest, HttpResponse}; 2 + use anyhow::Error; 3 + use s3::{creds::Credentials, Bucket, Region}; 4 + use serde_json::json; 5 + use tokio_stream::StreamExt; 6 + 7 + use crate::{read_payload, types::params::ListParams}; 8 + 9 + pub async fn list(payload: &mut web::Payload, _req: &HttpRequest,) -> Result<HttpResponse, Error> { 10 + let body = read_payload!(payload); 11 + let params = serde_json::from_slice::<ListParams>(&body)?; 12 + let access_key = std::env::var("ACCESS_KEY").expect("ACCESS_KEY not set"); 13 + let secret_key = std::env::var("SECRET_KEY").expect("SECRET_KEY not set"); 14 + let bucket_name = std::env::var("BUCKET_NAME").expect("BUCKET_NAME not set"); 15 + let account_id = std::env::var("ACCOUNT_ID").expect("ACCOUNT_ID not set"); 16 + 17 + let bucket = Bucket::new( 18 + &bucket_name, 19 + Region::R2 { account_id }, 20 + Credentials::new( 21 + Some(access_key.as_str()), 22 + Some(secret_key.as_str()), 23 + None, 24 + None, 25 + None 26 + )?, 27 + )? 28 + .with_path_style(); 29 + 30 + let (res, _) = bucket.list_page(params.prefix, params.delimiter, params.continuation_token, params.start_after, params.max_keys).await?; 31 + 32 + 33 + Ok(HttpResponse::Ok().json(json!({ 34 + "max_keys": res.max_keys, 35 + "prefix": res.prefix, 36 + "continuation_token": res.continuation_token, 37 + "encoding_type": res.encoding_type, 38 + "is_truncated": res.is_truncated, 39 + "next_continuation_token": res.next_continuation_token, 40 + "contents": res.contents.iter().map(|content| { 41 + json!({ 42 + "key": content.key, 43 + "last_modified": content.last_modified, 44 + "etag": content.e_tag, 45 + "size": content.size, 46 + "storage_class": content.storage_class, 47 + }) 48 + }).collect::<Vec<_>>() 49 + }))) 50 + 51 + }
+28
crates/storage/src/handlers/mod.rs
··· 1 + use actix_web::{web, HttpRequest, HttpResponse}; 2 + use anyhow::Error; 3 + use files::presign_get; 4 + use folders::list; 5 + 6 + pub mod files; 7 + pub mod folders; 8 + 9 + #[macro_export] 10 + macro_rules! read_payload { 11 + ($payload:expr) => {{ 12 + let mut body = Vec::new(); 13 + while let Some(chunk) = $payload.next().await { 14 + match chunk { 15 + Ok(bytes) => body.extend_from_slice(&bytes), 16 + Err(err) => return Err(err.into()), 17 + } 18 + } 19 + body 20 + }}; 21 + } 22 + 23 + pub async fn handle(method: &str, payload: &mut web::Payload, req: &HttpRequest) -> Result<HttpResponse, Error> { 24 + match method { 25 + "storage.list" => list(payload, req).await, 26 + "storage.presignGet" => presign_get(payload, req).await, _ => return Err(anyhow::anyhow!("Method not found")), 27 + } 28 + }
+13
crates/storage/src/main.rs
··· 1 + use dotenv::dotenv; 2 + use server::serve; 3 + 4 + pub mod handlers; 5 + pub mod server; 6 + pub mod types; 7 + 8 + #[tokio::main] 9 + async fn main() -> Result<(), Box<dyn std::error::Error>> { 10 + dotenv().ok(); 11 + serve().await?; 12 + Ok(()) 13 + }
+51
crates/storage/src/server.rs
··· 1 + use std::env; 2 + 3 + use actix_web::{get, post, web, App, HttpRequest, HttpResponse, HttpServer, Responder}; 4 + use owo_colors::OwoColorize; 5 + use serde_json::json; 6 + use anyhow::Error; 7 + 8 + use crate::handlers::handle; 9 + 10 + 11 + #[get("/")] 12 + async fn index(_req: HttpRequest) -> HttpResponse { 13 + HttpResponse::Ok().json(json!({ 14 + "server": "Rocksky Storage Server", 15 + "version": "0.1.0", 16 + })) 17 + } 18 + 19 + #[post("/{method}")] 20 + async fn call_method( 21 + mut payload: web::Payload, 22 + req: HttpRequest) -> Result<impl Responder, actix_web::Error> { 23 + let method = req.match_info().get("method").unwrap_or("unknown"); 24 + println!("Method: {}", method.bright_green()); 25 + 26 + handle(method, &mut payload, &req).await 27 + .map_err(actix_web::error::ErrorInternalServerError) 28 + } 29 + 30 + 31 + pub async fn serve() -> Result<(), Error> { 32 + 33 + let host = env::var("STORAGE_HOST").unwrap_or_else(|_| "127.0.0.1".to_string()); 34 + let port = env::var("STORAGE_PORT").unwrap_or_else(|_| "7883".to_string()); 35 + let addr = format!("{}:{}", host, port); 36 + 37 + let url = format!("http://{}", addr); 38 + println!("Listening on {}", url.bright_green()); 39 + 40 + HttpServer::new(move || { 41 + App::new() 42 + .service(index) 43 + .service(call_method) 44 + }) 45 + .bind(&addr)? 46 + .run() 47 + .await 48 + .map_err(Error::new)?; 49 + 50 + Ok(()) 51 + }
+16
crates/storage/src/types/file.rs
··· 1 + use serde::{Deserialize, Serialize}; 2 + 3 + #[derive(Serialize, Deserialize, Debug, Clone)] 4 + pub struct File { 5 + pub last_modified: String, 6 + 7 + #[serde(skip_serializing_if = "Option::is_none")] 8 + e_tag: Option<String>, 9 + 10 + #[serde(skip_serializing_if = "Option::is_none")] 11 + pub storage_class: Option<String>, 12 + 13 + pub key: String, 14 + pub owner: String, 15 + pub size: u64, 16 + }
+2
crates/storage/src/types/mod.rs
··· 1 + pub mod file; 2 + pub mod params;
+10
crates/storage/src/types/params.rs
··· 1 + use serde::{Deserialize, Serialize}; 2 + 3 + #[derive(Serialize, Deserialize, Debug, Clone)] 4 + pub struct ListParams { 5 + pub prefix: String, 6 + pub continuation_token: Option<String>, 7 + pub delimiter: Option<String>, 8 + pub start_after: Option<String>, 9 + pub max_keys: Option<usize>, 10 + }