├── .gitignore ├── src ├── tests.rs ├── lib.rs ├── seekstream.rs └── multipart.rs ├── examples ├── download-videos.sh └── server.rs ├── Cargo.toml ├── LICENSE.md ├── README.md └── Cargo.lock /.gitignore: -------------------------------------------------------------------------------- 1 | /target 2 | **/*.rs.bk 3 | *.webm 4 | -------------------------------------------------------------------------------- /src/tests.rs: -------------------------------------------------------------------------------- 1 | #[cfg(test)] 2 | mod tests {} 3 | -------------------------------------------------------------------------------- /examples/download-videos.sh: -------------------------------------------------------------------------------- 1 | # Get some videos for the example 2 | # Depends on youtube-dl for retrieving the videos. 3 | 4 | dl() { 5 | yt-dlp --flat-playlist $1 -o $2 6 | } 7 | 8 | dl "https://youtu.be/iRkTT54L83o" "tari_tari.webm" 9 | dl "https://youtu.be/A4OL4s3TWj4" "fly_me_to_the_moon.webm" 10 | dl "https://youtu.be/k8ozVkIkr-g" "cruel_angels_thesis.webm" 11 | dl "https://youtu.be/HaMP1tWFo9Y" "ison.webm" -------------------------------------------------------------------------------- /src/lib.rs: -------------------------------------------------------------------------------- 1 | //! This crate provides a seekable stream responder for rocket that will satisfy range requests. 2 | //! 3 | //! # Examples 4 | //! see the examples directory for more. 5 | //! 6 | //! ```no_run 7 | //! use rocket::{get, launch, routes}; 8 | //! use rocket_seek_stream::SeekStream; 9 | //! 10 | //! #[get("/")] 11 | //! fn home<'a>() -> std::io::Result> { 12 | //! SeekStream::from_path("kosmodrom.webm") 13 | //! } 14 | //! 15 | //! #[launch] 16 | //! fn rocket() -> _ { 17 | //! rocket::Rocket::build() 18 | //! .mount("/", routes![home]) 19 | //! } 20 | //! 21 | //! ``` 22 | 23 | mod multipart; 24 | mod seekstream; 25 | 26 | pub use seekstream::{ReadSeek, SeekStream}; 27 | -------------------------------------------------------------------------------- /Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "rocket_seek_stream" 3 | version = "0.2.6" 4 | description="Rocket-rs 0.5.0-rc.3 responder to range requests using types that implement AsyncRead + AsyncSeek" 5 | authors = ["Ryan Dzengelewski ", "Samuel Rembisz "] 6 | edition = "2021" 7 | license="MIT" 8 | repository="https://github.com/rydz/rocket_seek_stream" 9 | readme="README.md" 10 | keywords=["rocket", "rocket-rs", "partial-content", "range-request", "206"] 11 | 12 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 13 | 14 | [dependencies] 15 | rocket = "0.5.0-rc.3" 16 | tree_magic_mini = "3.0.3" 17 | range_header = "0.2" 18 | rand = "0.8.5" 19 | futures = "0.3.21" 20 | -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2019 Ryan Dzengelewski 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. -------------------------------------------------------------------------------- /examples/server.rs: -------------------------------------------------------------------------------- 1 | #![feature(proc_macro_hygiene, decl_macro)] 2 | 3 | /// Run download-videos.sh to download the videos required to run this example 4 | /// It depends on yt-dlp. 5 | /// 6 | /// Use `cargo run --example server` then navigate to [localhost:8000](http://localhost:8000) 7 | /// in your browser. 8 | /// 9 | /// Change the path between "/"", "from_path", and "long" to see the different examples in action. 10 | 11 | #[macro_use] 12 | extern crate rocket; 13 | use rocket_seek_stream::SeekStream; 14 | 15 | // stream from an in memory buffer 16 | #[get("/memory")] 17 | fn hello<'a>() -> SeekStream<'a> { 18 | let bytes = &include_bytes!("./cruel_angels_thesis.webm")[..]; 19 | let len = bytes.len(); 20 | let stream = std::io::Cursor::new(bytes); 21 | 22 | SeekStream::with_opts(stream, len as u64, "video/webm") 23 | } 24 | 25 | // stream from a given filepath 26 | #[get("/from_path")] 27 | fn from_path<'a>() -> std::io::Result> { 28 | SeekStream::from_path("fly_me_to_the_moon.webm") 29 | } 30 | 31 | // some long media 32 | #[get("/long")] 33 | fn long<'a>() -> std::io::Result> { 34 | SeekStream::from_path("tari_tari.webm") 35 | } 36 | 37 | // some longer media 38 | #[get("/")] 39 | fn longer<'a>() -> std::io::Result> { 40 | SeekStream::from_path("ison.webm") 41 | } 42 | 43 | #[launch] 44 | fn rocket() -> _ { 45 | let config = { 46 | let mut config = rocket::Config::default(); 47 | config.port = 8000; 48 | config 49 | }; 50 | 51 | rocket::Rocket::custom(config) 52 | .mount("/", routes![hello, from_path, long, longer]) 53 | } 54 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # rocket_seek_stream 2 | 3 | [crates.io](https://crates.io/crates/rocket_seek_stream) 4 | 5 | A [Rocket](https://github.com/SergioBenitez/Rocket) responder for types implementing the `AsyncRead + AsyncSeek` traits, such as files and `rocket::futures::io::Cursor`, that will respond to range requests with a 206 Partial Content response. The `Content-Type` can optionally be inferred by taking a sample of bytes from the beginning of the stream, or given manually. An `Accept-Ranges: bytes` header will be sent in all responses to notify browsers that range requests are supported for the resource. 6 | 7 | This supports both single and multipart/byterange requests. 8 | [https://tools.ietf.org/html/rfc7233](https://tools.ietf.org/html/rfc7233) 9 | 10 | ## Cargo.toml 11 | 12 | Add this to your dependencies. 13 | 14 | ``` 15 | rocket_seek_stream = {git="https://github.com/rydz/rocket_seek_stream"} 16 | ``` 17 | 18 | ## Examples 19 | 20 | Serving a file from the disk 21 | 22 | ```rust 23 | #![feature(proc_macro_hygiene, decl_macro)] 24 | #[macro_use] 25 | extern crate rocket; 26 | use rocket_seek_stream::SeekStream; 27 | 28 | #[get("/")] 29 | fn home<'a>() -> std::io::Result> { 30 | SeekStream::from_path("kosmodrom.webm") 31 | } 32 | 33 | #[rocket::main] 34 | async fn main() { 35 | match rocket::build().mount("/", routes![home]).launch().await { 36 | Ok(_) => (), 37 | Err(e) => { 38 | eprintln!("Rocket stopped unexpectedly. (Error {})", e); 39 | } 40 | }; 41 | } 42 | ``` 43 | 44 | Serving an in memory buffer 45 | 46 | ```rust 47 | #[get("/")] 48 | fn cursor<'a>() -> SeekStream<'a> { 49 | let bytes = &include_bytes!("./fly_me_to_the_moon.webm")[..]; 50 | let len = bytes.len(); 51 | let stream = std::io::Cursor::new(bytes); 52 | 53 | SeekStream::with_opts(stream, len as u64, "video/webm") 54 | } 55 | ``` 56 | 57 | Use `cargo run --example server` to run the example. run `examples/download.sh` to download the media it depends on using [yt-dlp](https://github.com/yt-dlp/yt-dlp). 58 | 59 | ## TODO 60 | 61 | - Write some tests 62 | 63 | I've compared the output of the Golang stdlib http router's multipart response to what I output here and it looks about the same except for a small difference in whitespace. 64 | -------------------------------------------------------------------------------- /src/seekstream.rs: -------------------------------------------------------------------------------- 1 | #![allow(unused_must_use)] 2 | 3 | use crate::multipart::MultipartReader; 4 | use futures::executor::block_on; 5 | use rocket::futures; 6 | use rocket::response::{self, Responder, Response}; 7 | use rocket::tokio::io::{AsyncRead, AsyncReadExt, AsyncSeek, AsyncSeekExt}; 8 | use rocket::tokio::runtime::Handle; 9 | use std::cell::RefCell; 10 | use std::path::Path; 11 | use std::pin::Pin; 12 | use tree_magic_mini; 13 | 14 | /// Alias trait for AsyncRead + AsyncSeek + Send 15 | pub trait ReadSeek: AsyncRead + AsyncSeek + Send {} 16 | impl ReadSeek for T {} 17 | 18 | /// Infer the mime type of a stream of bytes using an excerpt from the beginning of the stream 19 | fn infer_mime_type(prelude: &[u8]) -> &'static str { 20 | return tree_magic_mini::from_u8(prelude); 21 | } 22 | 23 | /// Serves a readable and seekable stream, 24 | /// The mime type can optionally be inferred by taking a sample of 25 | /// bytes from the beginning of the stream. 26 | /// 27 | /// The Accept Ranges header will always be set. 28 | /// If a range request is received, it will respond with the requested offset. 29 | /// Multipart range requests are also supported. 30 | pub struct SeekStream<'a> { 31 | stream: RefCell>>, 32 | length: Option, 33 | content_type: Option<&'a str>, 34 | } 35 | 36 | impl<'a> SeekStream<'a> { 37 | pub fn new(s: T) -> SeekStream<'a> 38 | where 39 | T: AsyncRead + AsyncSeek + Send + 'static, 40 | { 41 | Self::with_opts(s, None, None) 42 | } 43 | 44 | pub fn with_opts( 45 | stream: T, 46 | stream_len: impl Into>, 47 | content_type: impl Into>, 48 | ) -> SeekStream<'a> 49 | where 50 | T: AsyncRead + AsyncSeek + Send + 'static, 51 | { 52 | SeekStream { 53 | stream: RefCell::new(Box::pin(stream)), 54 | length: stream_len.into(), 55 | content_type: content_type.into(), 56 | } 57 | } 58 | 59 | /// Serve content from a file path. The mime type will be inferred by taking a sample from 60 | /// The beginning of the stream. 61 | pub fn from_path>(p: T) -> std::io::Result { 62 | let handle = Handle::current(); 63 | handle.enter(); 64 | let file = match block_on(rocket::tokio::fs::File::open(p.as_ref())) { 65 | Ok(f) => f, 66 | Err(e) => return Err(e), 67 | }; 68 | let len = block_on(file.metadata()).unwrap().len(); 69 | 70 | Ok(Self::with_opts(file, len, None)) 71 | } 72 | } 73 | 74 | // Convert a range to a satisfiable range 75 | fn to_satisfiable_range( 76 | from: Option, 77 | to: Option, 78 | length: u64, 79 | ) -> Result<(u64, u64), &'static str> { 80 | let (start, mut end) = match (from, to) { 81 | (Some(x), Some(z)) => (x, z), // FromToAll 82 | (Some(x), None) => (x, length - 1), // FromTo 83 | (None, Some(z)) => (length - z, length - 1), // FromEnd 84 | (None, None) => return Err("You need at least one value to satisfy a range request"), 85 | }; 86 | 87 | if end < start { 88 | return Err("A byte-range-spec is invalid if the last-byte-pos value is present and less than the first-byte-pos."); 89 | } 90 | if end > length { 91 | end = length 92 | } 93 | 94 | Ok((start, end)) 95 | } 96 | 97 | fn range_header_parts(header: &range_header::ByteRange) -> (Option, Option) { 98 | use range_header::ByteRange::{FromTo, FromToAll, Last}; 99 | match *header { 100 | FromTo(x) => (Some(x), None), 101 | FromToAll(x, y) => (Some(x), Some(y)), 102 | Last(x) => (None, Some(x)), 103 | } 104 | } 105 | 106 | #[rocket::async_trait] 107 | impl<'r> Responder<'r, 'static> for SeekStream<'r> { 108 | fn respond_to(self, req: &'r rocket::Request) -> response::Result<'static> { 109 | use rocket::http::Status; 110 | use std::io::SeekFrom; 111 | let handle = Handle::current(); 112 | handle.enter(); 113 | 114 | const SERVER_ERROR: Status = Status::InternalServerError; 115 | const RANGE_ERROR: Status = Status::RangeNotSatisfiable; 116 | 117 | // Get the total length of the stream if not already specified 118 | let stream_len = match self.length { 119 | Some(x) => x, 120 | _ => { 121 | let mut borrowed = self.stream.borrow_mut(); 122 | let old_pos = match block_on(borrowed.seek(SeekFrom::Current(0))) { 123 | Ok(x) => x, 124 | Err(_) => return Err(SERVER_ERROR), 125 | }; 126 | let len = match block_on(borrowed.seek(SeekFrom::End(0))) { 127 | Ok(x) => x, 128 | Err(_) => return Err(SERVER_ERROR), 129 | }; 130 | match block_on(borrowed.seek(SeekFrom::Start(old_pos))) { 131 | Ok(_) => len, 132 | Err(_) => return Err(SERVER_ERROR), 133 | } 134 | } 135 | }; 136 | 137 | // Get the mime type, either by inferring it from the stream 138 | // Or the optional value set in the struct 139 | let mime_type = match self.content_type { 140 | Some(x) => String::from(x), 141 | None => { 142 | // Infer the mime type of the stream by taking at most a 256 byte sample from the beginning 143 | // And passing it to the infer_mime_type function 144 | let mut prelude: [u8; 256] = [0; 256]; 145 | 146 | let c = block_on(self.stream.borrow_mut().read(&mut prelude)) 147 | .map_err(|_| SERVER_ERROR)?; 148 | 149 | // Seek to the beginning of the stream to reset the data we took for the sample 150 | block_on(self.stream.borrow_mut().seek(std::io::SeekFrom::Start(0))) 151 | .map_err(|_| SERVER_ERROR)?; 152 | 153 | infer_mime_type(&prelude[..c]).to_owned() 154 | } 155 | }; 156 | 157 | // Set the response headers 158 | let mut resp = Response::new(); 159 | resp.set_raw_header("Accept-Ranges", "bytes"); 160 | resp.set_raw_header("Content-Type", mime_type.clone()); 161 | 162 | // If the range header exists, set the response status code to 163 | // 206 partial content and seek the stream to the requested position 164 | if let Some(x) = req.headers().get_one("Range") { 165 | let (ranges, errors) = range_header::ByteRange::parse(x) 166 | .iter() 167 | .map(|x| range_header_parts(&x)) 168 | .map(|(start, end)| to_satisfiable_range(start, end, stream_len)) 169 | .partition::, _>(|x| x.is_ok()); 170 | 171 | // If any of the ranges produce an incorrect value, 172 | // Or the list of ranges is empty. 173 | // Return a range error. 174 | if errors.len() > 0 || ranges.len() == 0 { 175 | for e in errors { 176 | println!("{:?}", e.unwrap_err()); 177 | } 178 | return Err(RANGE_ERROR); 179 | } 180 | 181 | // Unwrap all the results 182 | let mut ranges: Vec<(u64, u64)> = ranges.iter().map(|x| x.unwrap()).collect(); 183 | 184 | // de-duplicate the list of ranges 185 | ranges.sort(); 186 | ranges.dedup_by(|&mut (a, b), &mut (c, d)| a == c && b == d); 187 | 188 | // Stream multipart/bytes if multiple ranges have been requested 189 | if ranges.len() > 1 { 190 | let rd = MultipartReader::new( 191 | self.stream.into_inner(), 192 | stream_len, 193 | mime_type, 194 | ranges, 195 | ); 196 | 197 | resp.set_raw_header( 198 | "Content-Type", 199 | format!("multipart/byterange; boundary={}", rd.boundary.clone()), 200 | ); 201 | resp.set_streamed_body(rd); 202 | } else { 203 | // Stream a single range request if only one was present in the byte ranges 204 | let &(start, end) = ranges.get(0).unwrap(); 205 | 206 | // Seek the stream to the desired position 207 | match block_on(self.stream.borrow_mut().seek(SeekFrom::Start(start))) 208 | .map_err(|_| SERVER_ERROR) 209 | { 210 | Ok(_) => (), 211 | Err(_) => return Err(SERVER_ERROR), 212 | }; 213 | 214 | let mut stream: Pin> = Box::pin(self.stream.into_inner()); 215 | if end + 1 < stream_len { 216 | stream = Box::pin(stream.take(end + 1 - start)); 217 | } 218 | 219 | resp.set_raw_header( 220 | "Content-Range", 221 | format!("bytes {}-{}/{}", start, end, stream_len), 222 | ); 223 | 224 | // Set the content length to be the length of the partial stream 225 | resp.set_raw_header("Content-Length", format!("{}", end + 1 - start)); 226 | resp.set_status(rocket::http::Status::PartialContent); 227 | 228 | resp.set_streamed_body(stream) 229 | } 230 | } else { 231 | // No range request; Response with the entire stream 232 | resp.set_raw_header("Content-Length", format!("{}", stream_len)); 233 | resp.set_streamed_body(self.stream.into_inner()); 234 | } 235 | 236 | Ok(resp) 237 | } 238 | } 239 | -------------------------------------------------------------------------------- /src/multipart.rs: -------------------------------------------------------------------------------- 1 | #![allow(dead_code)] 2 | #![allow(unused_must_use)] 3 | 4 | use crate::ReadSeek; 5 | use rand; 6 | use rocket::futures::io::Cursor; 7 | use rocket::futures::AsyncWriteExt; 8 | use rocket::tokio::io::ReadBuf; 9 | use rocket::tokio::runtime::Handle; 10 | use rocket::{ 11 | futures::executor::block_on, 12 | tokio::io::{AsyncRead, AsyncSeek, AsyncSeekExt}, 13 | }; 14 | use std::io::SeekFrom; 15 | use std::pin::Pin; 16 | use std::task::{Context, Poll}; 17 | 18 | pub type Ranges = Vec<(u64, u64)>; 19 | 20 | /// [https://golang.org/src/mime/multipart/writer.go?s=478:513#L84](https://golang.org/src/mime/multipart/writer.go?s=478:513#L84) 21 | /// Boundaries can be no more than 70 characters long. 22 | fn random_boundary() -> String { 23 | use rand::RngCore; 24 | 25 | let mut x = [0 as u8; 30]; 26 | rand::thread_rng().fill_bytes(&mut x); 27 | (&x[..]) 28 | .iter() 29 | .map(|&x| format!("{:x}", x)) 30 | .fold(String::new(), |mut a, x| { 31 | a.push_str(x.as_str()); 32 | a 33 | }) 34 | } 35 | 36 | /// An adapter for a ReadSeek that will stream the provided byteranges 37 | /// with multipart/byteranges headers and boundaries. 38 | pub struct MultipartReader<'a> { 39 | stream_len: u64, 40 | stream: Pin>, 41 | ranges: Ranges, 42 | 43 | // Current index in the ranges vector being served 44 | idx: usize, 45 | pub boundary: String, 46 | 47 | // the content type to be sent along with each range boundary 48 | content_type: String, 49 | 50 | // Buffer to write boundaries into. 51 | buffer: Cursor>, 52 | 53 | // if a boundary header has already been written this will be true 54 | wrote_boundary_header: bool, 55 | } 56 | 57 | impl<'a> MultipartReader<'a> { 58 | pub fn new( 59 | stream: T, 60 | stream_len: u64, 61 | content_type: impl Into, 62 | ranges: Vec<(u64, u64)>, 63 | ) -> MultipartReader<'a> 64 | where 65 | T: AsyncRead + AsyncSeek + Send + 'a, 66 | { 67 | let stream = Box::pin(stream); 68 | 69 | return MultipartReader { 70 | stream_len, 71 | stream, 72 | ranges, 73 | idx: 0, 74 | boundary: random_boundary(), 75 | content_type: content_type.into(), 76 | buffer: Cursor::new(Vec::new()), 77 | wrote_boundary_header: false, 78 | }; 79 | } 80 | 81 | /// write the boundary into the buffer 82 | fn write_boundary(&mut self) -> std::io::Result<()> { 83 | let handle = Handle::current(); 84 | handle.enter(); 85 | let boundary = format!("\r\n--{}\r\n", self.boundary); 86 | block_on(self.buffer.write_all(boundary.as_bytes())) 87 | } 88 | 89 | /// Write a header to buffer 90 | fn write_boundary_header( 91 | &mut self, 92 | header: impl AsRef, 93 | value: impl AsRef, 94 | ) -> std::io::Result<()> { 95 | let handle = Handle::current(); 96 | handle.enter(); 97 | let header = format!("{}: {}\r\n", header.as_ref(), value.as_ref()); 98 | block_on(self.buffer.write_all(header.as_bytes())) 99 | } 100 | 101 | /// Write CRLF to buffer 102 | fn write_boundary_end(&mut self) -> std::io::Result<()> { 103 | let handle = Handle::current(); 104 | handle.enter(); 105 | block_on(self.buffer.write_all("\r\n".as_bytes())) 106 | } 107 | 108 | // Close the multipart form by sending the boundary closer field. 109 | fn write_boundary_closer(&mut self) -> std::io::Result<()> { 110 | let handle = Handle::current(); 111 | handle.enter(); 112 | block_on( 113 | self.buffer 114 | .write_all(format!("\r\n--{}--\r\n\r\n", &self.boundary).as_bytes()), 115 | ) 116 | } 117 | 118 | /// Empty the buffer by truncating the underlying vector 119 | fn clear_buffer(&mut self) { 120 | let handle = Handle::current(); 121 | handle.enter(); 122 | block_on(rocket::futures::AsyncSeekExt::seek( 123 | &mut self.buffer, 124 | SeekFrom::Start(0), 125 | )) 126 | .unwrap(); 127 | self.buffer.get_mut().truncate(0); 128 | } 129 | } 130 | 131 | impl<'a> AsyncRead for MultipartReader<'a> { 132 | fn poll_read( 133 | mut self: Pin<&mut MultipartReader<'a>>, 134 | _cs: &mut Context, 135 | buf: &mut ReadBuf<'_>, 136 | ) -> Poll> { 137 | let handle = Handle::current(); 138 | handle.enter(); 139 | // The number of bytes read into the buffer so far. 140 | let mut c = 0; 141 | 142 | // Find the length of the header buffer to see if it's not empty. 143 | // If so, send the remaining contents in the buffer. 144 | let bufsize = self.buffer.get_ref().len() as u64; 145 | if bufsize > 0 { 146 | // If the buffer isn't empty send the content within it 147 | if self.buffer.position() < bufsize - 1 { 148 | // read operations on the buffer cannot fail. 149 | c = block_on(rocket::futures::AsyncReadExt::read( 150 | &mut self.buffer, 151 | buf.initialized_mut(), 152 | )) 153 | .unwrap(); 154 | } 155 | 156 | // Clear the buffer if all of it has already been read 157 | if self.buffer.position() >= bufsize - 1 { 158 | self.clear_buffer(); 159 | } 160 | } 161 | 162 | // If we cannot fill the buffer anymore, so return with the number of bytes read. 163 | if c >= buf.initialized().len() { 164 | return Poll::Ready(Ok(())); 165 | } 166 | 167 | // All the ranges have completed being read. 168 | // Finalize by sending the closing boundary and 169 | // Returning 0 for all future calls. 170 | if self.idx >= self.ranges.len() { 171 | if self.idx == self.ranges.len() { 172 | self.write_boundary_closer()?; 173 | block_on(rocket::futures::AsyncSeekExt::seek( 174 | &mut self.buffer, 175 | SeekFrom::Start(0), 176 | )) 177 | .unwrap(); 178 | 179 | // Because this is one greater than the length 180 | // The function will return Ok(0) from now on 181 | self.idx = self.idx + 1; 182 | return match block_on(rocket::tokio::io::AsyncReadExt::read( 183 | &mut self, 184 | &mut buf.initialized_mut()[c..], 185 | )) { 186 | Ok(_) => Poll::Ready(Ok(())), 187 | Err(e) => Poll::Ready(Err(e)), 188 | }; 189 | } 190 | return Poll::Ready(Ok(())); 191 | } 192 | 193 | // Write the range data into the remaining space in the buffer 194 | let (start, end) = self.ranges[self.idx]; 195 | let current_position = match block_on(self.stream.stream_position()) { 196 | Ok(pos) => pos, 197 | Err(e) => return Poll::Ready(Err(e)), 198 | }; 199 | 200 | // If we have not written a boundary header yet, we are at the beginning of a new stream 201 | // Write a boundary header and prepare the stream 202 | if !self.wrote_boundary_header { 203 | match block_on(self.stream.seek(SeekFrom::Start(start))) { 204 | Ok(_) => (), 205 | Err(e) => return Poll::Ready(Err(e)), 206 | }; 207 | self.write_boundary()?; 208 | let stream_len = self.stream_len; 209 | self.write_boundary_header( 210 | "Content-Range", 211 | format!("bytes {}-{}/{}", start, end, stream_len).as_str(), 212 | )?; 213 | let content_type = self.content_type.clone(); 214 | self.write_boundary_header("Content-Type", content_type)?; 215 | self.write_boundary_end()?; 216 | 217 | self.wrote_boundary_header = true; 218 | 219 | // Seek the buffer back to the start to prepare for being read 220 | // In the next call. 221 | block_on(rocket::futures::AsyncSeekExt::seek( 222 | &mut self.buffer, 223 | SeekFrom::Start(0), 224 | )) 225 | .unwrap(); 226 | 227 | // Read until the boundary_header is done being sent 228 | return match block_on(rocket::tokio::io::AsyncReadExt::read( 229 | &mut self, 230 | &mut buf.initialized_mut()[c..], 231 | )) { 232 | Ok(_) => Poll::Ready(Ok(())), 233 | Err(e) => Poll::Ready(Err(e)), 234 | }; 235 | } 236 | 237 | // Number of bytes remaining until the end 238 | let remaining = (end + 1 - current_position) as usize; 239 | 240 | // If the number of remaining bytes in this range is less than what we can fit in the buffer, 241 | // then we have reached the end of this range, send the final piece 242 | // And increment the range idx by one to move onto the next 243 | // Set "wrote_boundary_header" to false, allowing the next header to be created 244 | if buf.initialized().len() - c >= remaining { 245 | match block_on(rocket::tokio::io::AsyncReadExt::read_exact( 246 | &mut self.stream, 247 | &mut buf.initialized_mut()[c..remaining + c], 248 | )) { 249 | Ok(_) => (), 250 | Err(e) => return Poll::Ready(Err(e)), 251 | }; 252 | self.idx = self.idx + 1; 253 | self.wrote_boundary_header = false; 254 | return Poll::Ready(Ok(())); 255 | } 256 | 257 | // Read the next chunk of the range 258 | match block_on(rocket::tokio::io::AsyncReadExt::read( 259 | &mut self.stream, 260 | &mut buf.initialized_mut()[c..], 261 | )) { 262 | Ok(_) => Poll::Ready(Ok(())), 263 | Err(e) => Poll::Ready(Err(e)), 264 | } 265 | } 266 | } 267 | -------------------------------------------------------------------------------- /Cargo.lock: -------------------------------------------------------------------------------- 1 | # This file is automatically @generated by Cargo. 2 | # It is not intended for manual editing. 3 | version = 3 4 | 5 | [[package]] 6 | name = "async-stream" 7 | version = "0.3.5" 8 | source = "registry+https://github.com/rust-lang/crates.io-index" 9 | checksum = "cd56dd203fef61ac097dd65721a419ddccb106b2d2b70ba60a6b529f03961a51" 10 | dependencies = [ 11 | "async-stream-impl", 12 | "futures-core", 13 | "pin-project-lite", 14 | ] 15 | 16 | [[package]] 17 | name = "async-stream-impl" 18 | version = "0.3.5" 19 | source = "registry+https://github.com/rust-lang/crates.io-index" 20 | checksum = "16e62a023e7c117e27523144c5d2459f4397fcc3cab0085af8e2224f643a0193" 21 | dependencies = [ 22 | "proc-macro2", 23 | "quote", 24 | "syn", 25 | ] 26 | 27 | [[package]] 28 | name = "async-trait" 29 | version = "0.1.68" 30 | source = "registry+https://github.com/rust-lang/crates.io-index" 31 | checksum = "b9ccdd8f2a161be9bd5c023df56f1b2a0bd1d83872ae53b71a84a12c9bf6e842" 32 | dependencies = [ 33 | "proc-macro2", 34 | "quote", 35 | "syn", 36 | ] 37 | 38 | [[package]] 39 | name = "atomic" 40 | version = "0.5.1" 41 | source = "registry+https://github.com/rust-lang/crates.io-index" 42 | checksum = "b88d82667eca772c4aa12f0f1348b3ae643424c8876448f3f7bd5787032e234c" 43 | dependencies = [ 44 | "autocfg", 45 | ] 46 | 47 | [[package]] 48 | name = "autocfg" 49 | version = "1.1.0" 50 | source = "registry+https://github.com/rust-lang/crates.io-index" 51 | checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" 52 | 53 | [[package]] 54 | name = "binascii" 55 | version = "0.1.4" 56 | source = "registry+https://github.com/rust-lang/crates.io-index" 57 | checksum = "383d29d513d8764dcdc42ea295d979eb99c3c9f00607b3692cf68a431f7dca72" 58 | 59 | [[package]] 60 | name = "bitflags" 61 | version = "1.3.2" 62 | source = "registry+https://github.com/rust-lang/crates.io-index" 63 | checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" 64 | 65 | [[package]] 66 | name = "bitflags" 67 | version = "2.2.1" 68 | source = "registry+https://github.com/rust-lang/crates.io-index" 69 | checksum = "24a6904aef64d73cf10ab17ebace7befb918b82164785cb89907993be7f83813" 70 | 71 | [[package]] 72 | name = "block-buffer" 73 | version = "0.10.4" 74 | source = "registry+https://github.com/rust-lang/crates.io-index" 75 | checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71" 76 | dependencies = [ 77 | "generic-array", 78 | ] 79 | 80 | [[package]] 81 | name = "bytecount" 82 | version = "0.6.3" 83 | source = "registry+https://github.com/rust-lang/crates.io-index" 84 | checksum = "2c676a478f63e9fa2dd5368a42f28bba0d6c560b775f38583c8bbaa7fcd67c9c" 85 | 86 | [[package]] 87 | name = "bytes" 88 | version = "1.4.0" 89 | source = "registry+https://github.com/rust-lang/crates.io-index" 90 | checksum = "89b2fd2a0dcf38d7971e2194b6b6eebab45ae01067456a7fd93d5547a61b70be" 91 | 92 | [[package]] 93 | name = "cc" 94 | version = "1.0.79" 95 | source = "registry+https://github.com/rust-lang/crates.io-index" 96 | checksum = "50d30906286121d95be3d479533b458f87493b30a4b5f79a607db8f5d11aa91f" 97 | 98 | [[package]] 99 | name = "cfg-if" 100 | version = "1.0.0" 101 | source = "registry+https://github.com/rust-lang/crates.io-index" 102 | checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" 103 | 104 | [[package]] 105 | name = "cookie" 106 | version = "0.17.0" 107 | source = "registry+https://github.com/rust-lang/crates.io-index" 108 | checksum = "7efb37c3e1ccb1ff97164ad95ac1606e8ccd35b3fa0a7d99a304c7f4a428cc24" 109 | dependencies = [ 110 | "percent-encoding", 111 | "time", 112 | "version_check", 113 | ] 114 | 115 | [[package]] 116 | name = "cpufeatures" 117 | version = "0.2.7" 118 | source = "registry+https://github.com/rust-lang/crates.io-index" 119 | checksum = "3e4c1eaa2012c47becbbad2ab175484c2a84d1185b566fb2cc5b8707343dfe58" 120 | dependencies = [ 121 | "libc", 122 | ] 123 | 124 | [[package]] 125 | name = "crypto-common" 126 | version = "0.1.6" 127 | source = "registry+https://github.com/rust-lang/crates.io-index" 128 | checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3" 129 | dependencies = [ 130 | "generic-array", 131 | "typenum", 132 | ] 133 | 134 | [[package]] 135 | name = "devise" 136 | version = "0.4.1" 137 | source = "registry+https://github.com/rust-lang/crates.io-index" 138 | checksum = "d6eacefd3f541c66fc61433d65e54e0e46e0a029a819a7dbbc7a7b489e8a85f8" 139 | dependencies = [ 140 | "devise_codegen", 141 | "devise_core", 142 | ] 143 | 144 | [[package]] 145 | name = "devise_codegen" 146 | version = "0.4.1" 147 | source = "registry+https://github.com/rust-lang/crates.io-index" 148 | checksum = "9c8cf4b8dd484ede80fd5c547592c46c3745a617c8af278e2b72bea86b2dfed6" 149 | dependencies = [ 150 | "devise_core", 151 | "quote", 152 | ] 153 | 154 | [[package]] 155 | name = "devise_core" 156 | version = "0.4.1" 157 | source = "registry+https://github.com/rust-lang/crates.io-index" 158 | checksum = "35b50dba0afdca80b187392b24f2499a88c336d5a8493e4b4ccfb608708be56a" 159 | dependencies = [ 160 | "bitflags 2.2.1", 161 | "proc-macro2", 162 | "proc-macro2-diagnostics", 163 | "quote", 164 | "syn", 165 | ] 166 | 167 | [[package]] 168 | name = "digest" 169 | version = "0.10.6" 170 | source = "registry+https://github.com/rust-lang/crates.io-index" 171 | checksum = "8168378f4e5023e7218c89c891c0fd8ecdb5e5e4f18cb78f38cf245dd021e76f" 172 | dependencies = [ 173 | "block-buffer", 174 | "crypto-common", 175 | ] 176 | 177 | [[package]] 178 | name = "either" 179 | version = "1.8.1" 180 | source = "registry+https://github.com/rust-lang/crates.io-index" 181 | checksum = "7fcaabb2fef8c910e7f4c7ce9f67a1283a1715879a7c230ca9d6d1ae31f16d91" 182 | 183 | [[package]] 184 | name = "encoding_rs" 185 | version = "0.8.32" 186 | source = "registry+https://github.com/rust-lang/crates.io-index" 187 | checksum = "071a31f4ee85403370b58aca746f01041ede6f0da2730960ad001edc2b71b394" 188 | dependencies = [ 189 | "cfg-if", 190 | ] 191 | 192 | [[package]] 193 | name = "errno" 194 | version = "0.3.1" 195 | source = "registry+https://github.com/rust-lang/crates.io-index" 196 | checksum = "4bcfec3a70f97c962c307b2d2c56e358cf1d00b558d74262b5f929ee8cc7e73a" 197 | dependencies = [ 198 | "errno-dragonfly", 199 | "libc", 200 | "windows-sys 0.48.0", 201 | ] 202 | 203 | [[package]] 204 | name = "errno-dragonfly" 205 | version = "0.1.2" 206 | source = "registry+https://github.com/rust-lang/crates.io-index" 207 | checksum = "aa68f1b12764fab894d2755d2518754e71b4fd80ecfb822714a1206c2aab39bf" 208 | dependencies = [ 209 | "cc", 210 | "libc", 211 | ] 212 | 213 | [[package]] 214 | name = "fastrand" 215 | version = "1.9.0" 216 | source = "registry+https://github.com/rust-lang/crates.io-index" 217 | checksum = "e51093e27b0797c359783294ca4f0a911c270184cb10f85783b118614a1501be" 218 | dependencies = [ 219 | "instant", 220 | ] 221 | 222 | [[package]] 223 | name = "figment" 224 | version = "0.10.8" 225 | source = "registry+https://github.com/rust-lang/crates.io-index" 226 | checksum = "4e56602b469b2201400dec66a66aec5a9b8761ee97cd1b8c96ab2483fcc16cc9" 227 | dependencies = [ 228 | "atomic", 229 | "pear", 230 | "serde", 231 | "toml", 232 | "uncased", 233 | "version_check", 234 | ] 235 | 236 | [[package]] 237 | name = "fixedbitset" 238 | version = "0.4.2" 239 | source = "registry+https://github.com/rust-lang/crates.io-index" 240 | checksum = "0ce7134b9999ecaf8bcd65542e436736ef32ddca1b3e06094cb6ec5755203b80" 241 | 242 | [[package]] 243 | name = "fnv" 244 | version = "1.0.7" 245 | source = "registry+https://github.com/rust-lang/crates.io-index" 246 | checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" 247 | 248 | [[package]] 249 | name = "futures" 250 | version = "0.3.28" 251 | source = "registry+https://github.com/rust-lang/crates.io-index" 252 | checksum = "23342abe12aba583913b2e62f22225ff9c950774065e4bfb61a19cd9770fec40" 253 | dependencies = [ 254 | "futures-channel", 255 | "futures-core", 256 | "futures-executor", 257 | "futures-io", 258 | "futures-sink", 259 | "futures-task", 260 | "futures-util", 261 | ] 262 | 263 | [[package]] 264 | name = "futures-channel" 265 | version = "0.3.28" 266 | source = "registry+https://github.com/rust-lang/crates.io-index" 267 | checksum = "955518d47e09b25bbebc7a18df10b81f0c766eaf4c4f1cccef2fca5f2a4fb5f2" 268 | dependencies = [ 269 | "futures-core", 270 | "futures-sink", 271 | ] 272 | 273 | [[package]] 274 | name = "futures-core" 275 | version = "0.3.28" 276 | source = "registry+https://github.com/rust-lang/crates.io-index" 277 | checksum = "4bca583b7e26f571124fe5b7561d49cb2868d79116cfa0eefce955557c6fee8c" 278 | 279 | [[package]] 280 | name = "futures-executor" 281 | version = "0.3.28" 282 | source = "registry+https://github.com/rust-lang/crates.io-index" 283 | checksum = "ccecee823288125bd88b4d7f565c9e58e41858e47ab72e8ea2d64e93624386e0" 284 | dependencies = [ 285 | "futures-core", 286 | "futures-task", 287 | "futures-util", 288 | ] 289 | 290 | [[package]] 291 | name = "futures-io" 292 | version = "0.3.28" 293 | source = "registry+https://github.com/rust-lang/crates.io-index" 294 | checksum = "4fff74096e71ed47f8e023204cfd0aa1289cd54ae5430a9523be060cdb849964" 295 | 296 | [[package]] 297 | name = "futures-macro" 298 | version = "0.3.28" 299 | source = "registry+https://github.com/rust-lang/crates.io-index" 300 | checksum = "89ca545a94061b6365f2c7355b4b32bd20df3ff95f02da9329b34ccc3bd6ee72" 301 | dependencies = [ 302 | "proc-macro2", 303 | "quote", 304 | "syn", 305 | ] 306 | 307 | [[package]] 308 | name = "futures-sink" 309 | version = "0.3.28" 310 | source = "registry+https://github.com/rust-lang/crates.io-index" 311 | checksum = "f43be4fe21a13b9781a69afa4985b0f6ee0e1afab2c6f454a8cf30e2b2237b6e" 312 | 313 | [[package]] 314 | name = "futures-task" 315 | version = "0.3.28" 316 | source = "registry+https://github.com/rust-lang/crates.io-index" 317 | checksum = "76d3d132be6c0e6aa1534069c705a74a5997a356c0dc2f86a47765e5617c5b65" 318 | 319 | [[package]] 320 | name = "futures-util" 321 | version = "0.3.28" 322 | source = "registry+https://github.com/rust-lang/crates.io-index" 323 | checksum = "26b01e40b772d54cf6c6d721c1d1abd0647a0106a12ecaa1c186273392a69533" 324 | dependencies = [ 325 | "futures-channel", 326 | "futures-core", 327 | "futures-io", 328 | "futures-macro", 329 | "futures-sink", 330 | "futures-task", 331 | "memchr", 332 | "pin-project-lite", 333 | "pin-utils", 334 | "slab", 335 | ] 336 | 337 | [[package]] 338 | name = "generator" 339 | version = "0.7.4" 340 | source = "registry+https://github.com/rust-lang/crates.io-index" 341 | checksum = "f3e123d9ae7c02966b4d892e550bdc32164f05853cd40ab570650ad600596a8a" 342 | dependencies = [ 343 | "cc", 344 | "libc", 345 | "log", 346 | "rustversion", 347 | "windows", 348 | ] 349 | 350 | [[package]] 351 | name = "generic-array" 352 | version = "0.14.7" 353 | source = "registry+https://github.com/rust-lang/crates.io-index" 354 | checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a" 355 | dependencies = [ 356 | "typenum", 357 | "version_check", 358 | ] 359 | 360 | [[package]] 361 | name = "getrandom" 362 | version = "0.2.9" 363 | source = "registry+https://github.com/rust-lang/crates.io-index" 364 | checksum = "c85e1d9ab2eadba7e5040d4e09cbd6d072b76a557ad64e797c2cb9d4da21d7e4" 365 | dependencies = [ 366 | "cfg-if", 367 | "libc", 368 | "wasi", 369 | ] 370 | 371 | [[package]] 372 | name = "glob" 373 | version = "0.3.1" 374 | source = "registry+https://github.com/rust-lang/crates.io-index" 375 | checksum = "d2fabcfbdc87f4758337ca535fb41a6d701b65693ce38287d856d1674551ec9b" 376 | 377 | [[package]] 378 | name = "h2" 379 | version = "0.3.18" 380 | source = "registry+https://github.com/rust-lang/crates.io-index" 381 | checksum = "17f8a914c2987b688368b5138aa05321db91f4090cf26118185672ad588bce21" 382 | dependencies = [ 383 | "bytes", 384 | "fnv", 385 | "futures-core", 386 | "futures-sink", 387 | "futures-util", 388 | "http", 389 | "indexmap", 390 | "slab", 391 | "tokio", 392 | "tokio-util", 393 | "tracing", 394 | ] 395 | 396 | [[package]] 397 | name = "hashbrown" 398 | version = "0.12.3" 399 | source = "registry+https://github.com/rust-lang/crates.io-index" 400 | checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" 401 | 402 | [[package]] 403 | name = "hermit-abi" 404 | version = "0.2.6" 405 | source = "registry+https://github.com/rust-lang/crates.io-index" 406 | checksum = "ee512640fe35acbfb4bb779db6f0d80704c2cacfa2e39b601ef3e3f47d1ae4c7" 407 | dependencies = [ 408 | "libc", 409 | ] 410 | 411 | [[package]] 412 | name = "hermit-abi" 413 | version = "0.3.1" 414 | source = "registry+https://github.com/rust-lang/crates.io-index" 415 | checksum = "fed44880c466736ef9a5c5b5facefb5ed0785676d0c02d612db14e54f0d84286" 416 | 417 | [[package]] 418 | name = "http" 419 | version = "0.2.9" 420 | source = "registry+https://github.com/rust-lang/crates.io-index" 421 | checksum = "bd6effc99afb63425aff9b05836f029929e345a6148a14b7ecd5ab67af944482" 422 | dependencies = [ 423 | "bytes", 424 | "fnv", 425 | "itoa", 426 | ] 427 | 428 | [[package]] 429 | name = "http-body" 430 | version = "0.4.5" 431 | source = "registry+https://github.com/rust-lang/crates.io-index" 432 | checksum = "d5f38f16d184e36f2408a55281cd658ecbd3ca05cce6d6510a176eca393e26d1" 433 | dependencies = [ 434 | "bytes", 435 | "http", 436 | "pin-project-lite", 437 | ] 438 | 439 | [[package]] 440 | name = "httparse" 441 | version = "1.8.0" 442 | source = "registry+https://github.com/rust-lang/crates.io-index" 443 | checksum = "d897f394bad6a705d5f4104762e116a75639e470d80901eed05a860a95cb1904" 444 | 445 | [[package]] 446 | name = "httpdate" 447 | version = "1.0.2" 448 | source = "registry+https://github.com/rust-lang/crates.io-index" 449 | checksum = "c4a1e36c821dbe04574f602848a19f742f4fb3c98d40449f11bcad18d6b17421" 450 | 451 | [[package]] 452 | name = "hyper" 453 | version = "0.14.26" 454 | source = "registry+https://github.com/rust-lang/crates.io-index" 455 | checksum = "ab302d72a6f11a3b910431ff93aae7e773078c769f0a3ef15fb9ec692ed147d4" 456 | dependencies = [ 457 | "bytes", 458 | "futures-channel", 459 | "futures-core", 460 | "futures-util", 461 | "h2", 462 | "http", 463 | "http-body", 464 | "httparse", 465 | "httpdate", 466 | "itoa", 467 | "pin-project-lite", 468 | "socket2", 469 | "tokio", 470 | "tower-service", 471 | "tracing", 472 | "want", 473 | ] 474 | 475 | [[package]] 476 | name = "indexmap" 477 | version = "1.9.3" 478 | source = "registry+https://github.com/rust-lang/crates.io-index" 479 | checksum = "bd070e393353796e801d209ad339e89596eb4c8d430d18ede6a1cced8fafbd99" 480 | dependencies = [ 481 | "autocfg", 482 | "hashbrown", 483 | "serde", 484 | ] 485 | 486 | [[package]] 487 | name = "inlinable_string" 488 | version = "0.1.15" 489 | source = "registry+https://github.com/rust-lang/crates.io-index" 490 | checksum = "c8fae54786f62fb2918dcfae3d568594e50eb9b5c25bf04371af6fe7516452fb" 491 | 492 | [[package]] 493 | name = "instant" 494 | version = "0.1.12" 495 | source = "registry+https://github.com/rust-lang/crates.io-index" 496 | checksum = "7a5bbe824c507c5da5956355e86a746d82e0e1464f65d862cc5e71da70e94b2c" 497 | dependencies = [ 498 | "cfg-if", 499 | ] 500 | 501 | [[package]] 502 | name = "io-lifetimes" 503 | version = "1.0.10" 504 | source = "registry+https://github.com/rust-lang/crates.io-index" 505 | checksum = "9c66c74d2ae7e79a5a8f7ac924adbe38ee42a859c6539ad869eb51f0b52dc220" 506 | dependencies = [ 507 | "hermit-abi 0.3.1", 508 | "libc", 509 | "windows-sys 0.48.0", 510 | ] 511 | 512 | [[package]] 513 | name = "is-terminal" 514 | version = "0.4.7" 515 | source = "registry+https://github.com/rust-lang/crates.io-index" 516 | checksum = "adcf93614601c8129ddf72e2d5633df827ba6551541c6d8c59520a371475be1f" 517 | dependencies = [ 518 | "hermit-abi 0.3.1", 519 | "io-lifetimes", 520 | "rustix", 521 | "windows-sys 0.48.0", 522 | ] 523 | 524 | [[package]] 525 | name = "itoa" 526 | version = "1.0.6" 527 | source = "registry+https://github.com/rust-lang/crates.io-index" 528 | checksum = "453ad9f582a441959e5f0d088b02ce04cfe8d51a8eaf077f12ac6d3e94164ca6" 529 | 530 | [[package]] 531 | name = "lazy_static" 532 | version = "1.4.0" 533 | source = "registry+https://github.com/rust-lang/crates.io-index" 534 | checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" 535 | 536 | [[package]] 537 | name = "libc" 538 | version = "0.2.142" 539 | source = "registry+https://github.com/rust-lang/crates.io-index" 540 | checksum = "6a987beff54b60ffa6d51982e1aa1146bc42f19bd26be28b0586f252fccf5317" 541 | 542 | [[package]] 543 | name = "linux-raw-sys" 544 | version = "0.3.4" 545 | source = "registry+https://github.com/rust-lang/crates.io-index" 546 | checksum = "36eb31c1778188ae1e64398743890d0877fef36d11521ac60406b42016e8c2cf" 547 | 548 | [[package]] 549 | name = "lock_api" 550 | version = "0.4.9" 551 | source = "registry+https://github.com/rust-lang/crates.io-index" 552 | checksum = "435011366fe56583b16cf956f9df0095b405b82d76425bc8981c0e22e60ec4df" 553 | dependencies = [ 554 | "autocfg", 555 | "scopeguard", 556 | ] 557 | 558 | [[package]] 559 | name = "log" 560 | version = "0.4.17" 561 | source = "registry+https://github.com/rust-lang/crates.io-index" 562 | checksum = "abb12e687cfb44aa40f41fc3978ef76448f9b6038cad6aef4259d3c095a2382e" 563 | dependencies = [ 564 | "cfg-if", 565 | ] 566 | 567 | [[package]] 568 | name = "loom" 569 | version = "0.5.6" 570 | source = "registry+https://github.com/rust-lang/crates.io-index" 571 | checksum = "ff50ecb28bb86013e935fb6683ab1f6d3a20016f123c76fd4c27470076ac30f5" 572 | dependencies = [ 573 | "cfg-if", 574 | "generator", 575 | "scoped-tls", 576 | "serde", 577 | "serde_json", 578 | "tracing", 579 | "tracing-subscriber", 580 | ] 581 | 582 | [[package]] 583 | name = "matchers" 584 | version = "0.1.0" 585 | source = "registry+https://github.com/rust-lang/crates.io-index" 586 | checksum = "8263075bb86c5a1b1427b5ae862e8889656f126e9f77c484496e8b47cf5c5558" 587 | dependencies = [ 588 | "regex-automata", 589 | ] 590 | 591 | [[package]] 592 | name = "memchr" 593 | version = "2.5.0" 594 | source = "registry+https://github.com/rust-lang/crates.io-index" 595 | checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d" 596 | 597 | [[package]] 598 | name = "mime" 599 | version = "0.3.17" 600 | source = "registry+https://github.com/rust-lang/crates.io-index" 601 | checksum = "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a" 602 | 603 | [[package]] 604 | name = "minimal-lexical" 605 | version = "0.2.1" 606 | source = "registry+https://github.com/rust-lang/crates.io-index" 607 | checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a" 608 | 609 | [[package]] 610 | name = "mio" 611 | version = "0.8.6" 612 | source = "registry+https://github.com/rust-lang/crates.io-index" 613 | checksum = "5b9d9a46eff5b4ff64b45a9e316a6d1e0bc719ef429cbec4dc630684212bfdf9" 614 | dependencies = [ 615 | "libc", 616 | "log", 617 | "wasi", 618 | "windows-sys 0.45.0", 619 | ] 620 | 621 | [[package]] 622 | name = "multer" 623 | version = "2.1.0" 624 | source = "registry+https://github.com/rust-lang/crates.io-index" 625 | checksum = "01acbdc23469fd8fe07ab135923371d5f5a422fbf9c522158677c8eb15bc51c2" 626 | dependencies = [ 627 | "bytes", 628 | "encoding_rs", 629 | "futures-util", 630 | "http", 631 | "httparse", 632 | "log", 633 | "memchr", 634 | "mime", 635 | "spin", 636 | "tokio", 637 | "tokio-util", 638 | "version_check", 639 | ] 640 | 641 | [[package]] 642 | name = "nom" 643 | version = "7.1.3" 644 | source = "registry+https://github.com/rust-lang/crates.io-index" 645 | checksum = "d273983c5a657a70a3e8f2a01329822f3b8c8172b73826411a55751e404a0a4a" 646 | dependencies = [ 647 | "memchr", 648 | "minimal-lexical", 649 | ] 650 | 651 | [[package]] 652 | name = "nu-ansi-term" 653 | version = "0.46.0" 654 | source = "registry+https://github.com/rust-lang/crates.io-index" 655 | checksum = "77a8165726e8236064dbb45459242600304b42a5ea24ee2948e18e023bf7ba84" 656 | dependencies = [ 657 | "overload", 658 | "winapi", 659 | ] 660 | 661 | [[package]] 662 | name = "num_cpus" 663 | version = "1.15.0" 664 | source = "registry+https://github.com/rust-lang/crates.io-index" 665 | checksum = "0fac9e2da13b5eb447a6ce3d392f23a29d8694bff781bf03a16cd9ac8697593b" 666 | dependencies = [ 667 | "hermit-abi 0.2.6", 668 | "libc", 669 | ] 670 | 671 | [[package]] 672 | name = "once_cell" 673 | version = "1.17.1" 674 | source = "registry+https://github.com/rust-lang/crates.io-index" 675 | checksum = "b7e5500299e16ebb147ae15a00a942af264cf3688f47923b8fc2cd5858f23ad3" 676 | 677 | [[package]] 678 | name = "overload" 679 | version = "0.1.1" 680 | source = "registry+https://github.com/rust-lang/crates.io-index" 681 | checksum = "b15813163c1d831bf4a13c3610c05c0d03b39feb07f7e09fa234dac9b15aaf39" 682 | 683 | [[package]] 684 | name = "parking_lot" 685 | version = "0.12.1" 686 | source = "registry+https://github.com/rust-lang/crates.io-index" 687 | checksum = "3742b2c103b9f06bc9fff0a37ff4912935851bee6d36f3c02bcc755bcfec228f" 688 | dependencies = [ 689 | "lock_api", 690 | "parking_lot_core", 691 | ] 692 | 693 | [[package]] 694 | name = "parking_lot_core" 695 | version = "0.9.7" 696 | source = "registry+https://github.com/rust-lang/crates.io-index" 697 | checksum = "9069cbb9f99e3a5083476ccb29ceb1de18b9118cafa53e90c9551235de2b9521" 698 | dependencies = [ 699 | "cfg-if", 700 | "libc", 701 | "redox_syscall 0.2.16", 702 | "smallvec", 703 | "windows-sys 0.45.0", 704 | ] 705 | 706 | [[package]] 707 | name = "pear" 708 | version = "0.2.4" 709 | source = "registry+https://github.com/rust-lang/crates.io-index" 710 | checksum = "0ec95680a7087503575284e5063e14b694b7a9c0b065e5dceec661e0497127e8" 711 | dependencies = [ 712 | "inlinable_string", 713 | "pear_codegen", 714 | "yansi", 715 | ] 716 | 717 | [[package]] 718 | name = "pear_codegen" 719 | version = "0.2.4" 720 | source = "registry+https://github.com/rust-lang/crates.io-index" 721 | checksum = "9661a3a53f93f09f2ea882018e4d7c88f6ff2956d809a276060476fd8c879d3c" 722 | dependencies = [ 723 | "proc-macro2", 724 | "proc-macro2-diagnostics", 725 | "quote", 726 | "syn", 727 | ] 728 | 729 | [[package]] 730 | name = "percent-encoding" 731 | version = "2.2.0" 732 | source = "registry+https://github.com/rust-lang/crates.io-index" 733 | checksum = "478c572c3d73181ff3c2539045f6eb99e5491218eae919370993b890cdbdd98e" 734 | 735 | [[package]] 736 | name = "pest" 737 | version = "2.6.0" 738 | source = "registry+https://github.com/rust-lang/crates.io-index" 739 | checksum = "e68e84bfb01f0507134eac1e9b410a12ba379d064eab48c50ba4ce329a527b70" 740 | dependencies = [ 741 | "thiserror", 742 | "ucd-trie", 743 | ] 744 | 745 | [[package]] 746 | name = "pest_derive" 747 | version = "2.6.0" 748 | source = "registry+https://github.com/rust-lang/crates.io-index" 749 | checksum = "6b79d4c71c865a25a4322296122e3924d30bc8ee0834c8bfc8b95f7f054afbfb" 750 | dependencies = [ 751 | "pest", 752 | "pest_generator", 753 | ] 754 | 755 | [[package]] 756 | name = "pest_generator" 757 | version = "2.6.0" 758 | source = "registry+https://github.com/rust-lang/crates.io-index" 759 | checksum = "6c435bf1076437b851ebc8edc3a18442796b30f1728ffea6262d59bbe28b077e" 760 | dependencies = [ 761 | "pest", 762 | "pest_meta", 763 | "proc-macro2", 764 | "quote", 765 | "syn", 766 | ] 767 | 768 | [[package]] 769 | name = "pest_meta" 770 | version = "2.6.0" 771 | source = "registry+https://github.com/rust-lang/crates.io-index" 772 | checksum = "745a452f8eb71e39ffd8ee32b3c5f51d03845f99786fa9b68db6ff509c505411" 773 | dependencies = [ 774 | "once_cell", 775 | "pest", 776 | "sha2", 777 | ] 778 | 779 | [[package]] 780 | name = "petgraph" 781 | version = "0.6.3" 782 | source = "registry+https://github.com/rust-lang/crates.io-index" 783 | checksum = "4dd7d28ee937e54fe3080c91faa1c3a46c06de6252988a7f4592ba2310ef22a4" 784 | dependencies = [ 785 | "fixedbitset", 786 | "indexmap", 787 | ] 788 | 789 | [[package]] 790 | name = "pin-project-lite" 791 | version = "0.2.9" 792 | source = "registry+https://github.com/rust-lang/crates.io-index" 793 | checksum = "e0a7ae3ac2f1173085d398531c705756c94a4c56843785df85a60c1a0afac116" 794 | 795 | [[package]] 796 | name = "pin-utils" 797 | version = "0.1.0" 798 | source = "registry+https://github.com/rust-lang/crates.io-index" 799 | checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" 800 | 801 | [[package]] 802 | name = "ppv-lite86" 803 | version = "0.2.17" 804 | source = "registry+https://github.com/rust-lang/crates.io-index" 805 | checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de" 806 | 807 | [[package]] 808 | name = "proc-macro2" 809 | version = "1.0.56" 810 | source = "registry+https://github.com/rust-lang/crates.io-index" 811 | checksum = "2b63bdb0cd06f1f4dedf69b254734f9b45af66e4a031e42a7480257d9898b435" 812 | dependencies = [ 813 | "unicode-ident", 814 | ] 815 | 816 | [[package]] 817 | name = "proc-macro2-diagnostics" 818 | version = "0.10.0" 819 | source = "registry+https://github.com/rust-lang/crates.io-index" 820 | checksum = "606c4ba35817e2922a308af55ad51bab3645b59eae5c570d4a6cf07e36bd493b" 821 | dependencies = [ 822 | "proc-macro2", 823 | "quote", 824 | "syn", 825 | "version_check", 826 | "yansi", 827 | ] 828 | 829 | [[package]] 830 | name = "quote" 831 | version = "1.0.26" 832 | source = "registry+https://github.com/rust-lang/crates.io-index" 833 | checksum = "4424af4bf778aae2051a77b60283332f386554255d722233d09fbfc7e30da2fc" 834 | dependencies = [ 835 | "proc-macro2", 836 | ] 837 | 838 | [[package]] 839 | name = "rand" 840 | version = "0.8.5" 841 | source = "registry+https://github.com/rust-lang/crates.io-index" 842 | checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" 843 | dependencies = [ 844 | "libc", 845 | "rand_chacha", 846 | "rand_core", 847 | ] 848 | 849 | [[package]] 850 | name = "rand_chacha" 851 | version = "0.3.1" 852 | source = "registry+https://github.com/rust-lang/crates.io-index" 853 | checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" 854 | dependencies = [ 855 | "ppv-lite86", 856 | "rand_core", 857 | ] 858 | 859 | [[package]] 860 | name = "rand_core" 861 | version = "0.6.4" 862 | source = "registry+https://github.com/rust-lang/crates.io-index" 863 | checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" 864 | dependencies = [ 865 | "getrandom", 866 | ] 867 | 868 | [[package]] 869 | name = "range_header" 870 | version = "0.2.0" 871 | source = "registry+https://github.com/rust-lang/crates.io-index" 872 | checksum = "f91066bbbc00d9eb5cf42cf9ea0abdf40097d20065e48b6c0cc14a2154d44934" 873 | dependencies = [ 874 | "pest", 875 | "pest_derive", 876 | ] 877 | 878 | [[package]] 879 | name = "redox_syscall" 880 | version = "0.2.16" 881 | source = "registry+https://github.com/rust-lang/crates.io-index" 882 | checksum = "fb5a58c1855b4b6819d59012155603f0b22ad30cad752600aadfcb695265519a" 883 | dependencies = [ 884 | "bitflags 1.3.2", 885 | ] 886 | 887 | [[package]] 888 | name = "redox_syscall" 889 | version = "0.3.5" 890 | source = "registry+https://github.com/rust-lang/crates.io-index" 891 | checksum = "567664f262709473930a4bf9e51bf2ebf3348f2e748ccc50dea20646858f8f29" 892 | dependencies = [ 893 | "bitflags 1.3.2", 894 | ] 895 | 896 | [[package]] 897 | name = "ref-cast" 898 | version = "1.0.16" 899 | source = "registry+https://github.com/rust-lang/crates.io-index" 900 | checksum = "f43faa91b1c8b36841ee70e97188a869d37ae21759da6846d4be66de5bf7b12c" 901 | dependencies = [ 902 | "ref-cast-impl", 903 | ] 904 | 905 | [[package]] 906 | name = "ref-cast-impl" 907 | version = "1.0.16" 908 | source = "registry+https://github.com/rust-lang/crates.io-index" 909 | checksum = "8d2275aab483050ab2a7364c1a46604865ee7d6906684e08db0f090acf74f9e7" 910 | dependencies = [ 911 | "proc-macro2", 912 | "quote", 913 | "syn", 914 | ] 915 | 916 | [[package]] 917 | name = "regex" 918 | version = "1.8.1" 919 | source = "registry+https://github.com/rust-lang/crates.io-index" 920 | checksum = "af83e617f331cc6ae2da5443c602dfa5af81e517212d9d611a5b3ba1777b5370" 921 | dependencies = [ 922 | "regex-syntax 0.7.1", 923 | ] 924 | 925 | [[package]] 926 | name = "regex-automata" 927 | version = "0.1.10" 928 | source = "registry+https://github.com/rust-lang/crates.io-index" 929 | checksum = "6c230d73fb8d8c1b9c0b3135c5142a8acee3a0558fb8db5cf1cb65f8d7862132" 930 | dependencies = [ 931 | "regex-syntax 0.6.29", 932 | ] 933 | 934 | [[package]] 935 | name = "regex-syntax" 936 | version = "0.6.29" 937 | source = "registry+https://github.com/rust-lang/crates.io-index" 938 | checksum = "f162c6dd7b008981e4d40210aca20b4bd0f9b60ca9271061b07f78537722f2e1" 939 | 940 | [[package]] 941 | name = "regex-syntax" 942 | version = "0.7.1" 943 | source = "registry+https://github.com/rust-lang/crates.io-index" 944 | checksum = "a5996294f19bd3aae0453a862ad728f60e6600695733dd5df01da90c54363a3c" 945 | 946 | [[package]] 947 | name = "rocket" 948 | version = "0.5.0-rc.3" 949 | source = "registry+https://github.com/rust-lang/crates.io-index" 950 | checksum = "58734f7401ae5cfd129685b48f61182331745b357b96f2367f01aebaf1cc9cc9" 951 | dependencies = [ 952 | "async-stream", 953 | "async-trait", 954 | "atomic", 955 | "binascii", 956 | "bytes", 957 | "either", 958 | "figment", 959 | "futures", 960 | "indexmap", 961 | "is-terminal", 962 | "log", 963 | "memchr", 964 | "multer", 965 | "num_cpus", 966 | "parking_lot", 967 | "pin-project-lite", 968 | "rand", 969 | "ref-cast", 970 | "rocket_codegen", 971 | "rocket_http", 972 | "serde", 973 | "state", 974 | "tempfile", 975 | "time", 976 | "tokio", 977 | "tokio-stream", 978 | "tokio-util", 979 | "ubyte", 980 | "version_check", 981 | "yansi", 982 | ] 983 | 984 | [[package]] 985 | name = "rocket_codegen" 986 | version = "0.5.0-rc.3" 987 | source = "registry+https://github.com/rust-lang/crates.io-index" 988 | checksum = "7093353f14228c744982e409259fb54878ba9563d08214f2d880d59ff2fc508b" 989 | dependencies = [ 990 | "devise", 991 | "glob", 992 | "indexmap", 993 | "proc-macro2", 994 | "quote", 995 | "rocket_http", 996 | "syn", 997 | "unicode-xid", 998 | ] 999 | 1000 | [[package]] 1001 | name = "rocket_http" 1002 | version = "0.5.0-rc.3" 1003 | source = "registry+https://github.com/rust-lang/crates.io-index" 1004 | checksum = "936012c99162a03a67f37f9836d5f938f662e26f2717809761a9ac46432090f4" 1005 | dependencies = [ 1006 | "cookie", 1007 | "either", 1008 | "futures", 1009 | "http", 1010 | "hyper", 1011 | "indexmap", 1012 | "log", 1013 | "memchr", 1014 | "pear", 1015 | "percent-encoding", 1016 | "pin-project-lite", 1017 | "ref-cast", 1018 | "serde", 1019 | "smallvec", 1020 | "stable-pattern", 1021 | "state", 1022 | "time", 1023 | "tokio", 1024 | "uncased", 1025 | ] 1026 | 1027 | [[package]] 1028 | name = "rocket_seek_stream" 1029 | version = "0.2.5" 1030 | dependencies = [ 1031 | "futures", 1032 | "rand", 1033 | "range_header", 1034 | "rocket", 1035 | "tree_magic_mini", 1036 | ] 1037 | 1038 | [[package]] 1039 | name = "rustix" 1040 | version = "0.37.15" 1041 | source = "registry+https://github.com/rust-lang/crates.io-index" 1042 | checksum = "a0661814f891c57c930a610266415528da53c4933e6dea5fb350cbfe048a9ece" 1043 | dependencies = [ 1044 | "bitflags 1.3.2", 1045 | "errno", 1046 | "io-lifetimes", 1047 | "libc", 1048 | "linux-raw-sys", 1049 | "windows-sys 0.48.0", 1050 | ] 1051 | 1052 | [[package]] 1053 | name = "rustversion" 1054 | version = "1.0.12" 1055 | source = "registry+https://github.com/rust-lang/crates.io-index" 1056 | checksum = "4f3208ce4d8448b3f3e7d168a73f5e0c43a61e32930de3bceeccedb388b6bf06" 1057 | 1058 | [[package]] 1059 | name = "ryu" 1060 | version = "1.0.13" 1061 | source = "registry+https://github.com/rust-lang/crates.io-index" 1062 | checksum = "f91339c0467de62360649f8d3e185ca8de4224ff281f66000de5eb2a77a79041" 1063 | 1064 | [[package]] 1065 | name = "scoped-tls" 1066 | version = "1.0.1" 1067 | source = "registry+https://github.com/rust-lang/crates.io-index" 1068 | checksum = "e1cf6437eb19a8f4a6cc0f7dca544973b0b78843adbfeb3683d1a94a0024a294" 1069 | 1070 | [[package]] 1071 | name = "scopeguard" 1072 | version = "1.1.0" 1073 | source = "registry+https://github.com/rust-lang/crates.io-index" 1074 | checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd" 1075 | 1076 | [[package]] 1077 | name = "serde" 1078 | version = "1.0.160" 1079 | source = "registry+https://github.com/rust-lang/crates.io-index" 1080 | checksum = "bb2f3770c8bce3bcda7e149193a069a0f4365bda1fa5cd88e03bca26afc1216c" 1081 | dependencies = [ 1082 | "serde_derive", 1083 | ] 1084 | 1085 | [[package]] 1086 | name = "serde_derive" 1087 | version = "1.0.160" 1088 | source = "registry+https://github.com/rust-lang/crates.io-index" 1089 | checksum = "291a097c63d8497e00160b166a967a4a79c64f3facdd01cbd7502231688d77df" 1090 | dependencies = [ 1091 | "proc-macro2", 1092 | "quote", 1093 | "syn", 1094 | ] 1095 | 1096 | [[package]] 1097 | name = "serde_json" 1098 | version = "1.0.96" 1099 | source = "registry+https://github.com/rust-lang/crates.io-index" 1100 | checksum = "057d394a50403bcac12672b2b18fb387ab6d289d957dab67dd201875391e52f1" 1101 | dependencies = [ 1102 | "itoa", 1103 | "ryu", 1104 | "serde", 1105 | ] 1106 | 1107 | [[package]] 1108 | name = "sha2" 1109 | version = "0.10.6" 1110 | source = "registry+https://github.com/rust-lang/crates.io-index" 1111 | checksum = "82e6b795fe2e3b1e845bafcb27aa35405c4d47cdfc92af5fc8d3002f76cebdc0" 1112 | dependencies = [ 1113 | "cfg-if", 1114 | "cpufeatures", 1115 | "digest", 1116 | ] 1117 | 1118 | [[package]] 1119 | name = "sharded-slab" 1120 | version = "0.1.4" 1121 | source = "registry+https://github.com/rust-lang/crates.io-index" 1122 | checksum = "900fba806f70c630b0a382d0d825e17a0f19fcd059a2ade1ff237bcddf446b31" 1123 | dependencies = [ 1124 | "lazy_static", 1125 | ] 1126 | 1127 | [[package]] 1128 | name = "signal-hook-registry" 1129 | version = "1.4.1" 1130 | source = "registry+https://github.com/rust-lang/crates.io-index" 1131 | checksum = "d8229b473baa5980ac72ef434c4415e70c4b5e71b423043adb4ba059f89c99a1" 1132 | dependencies = [ 1133 | "libc", 1134 | ] 1135 | 1136 | [[package]] 1137 | name = "slab" 1138 | version = "0.4.8" 1139 | source = "registry+https://github.com/rust-lang/crates.io-index" 1140 | checksum = "6528351c9bc8ab22353f9d776db39a20288e8d6c37ef8cfe3317cf875eecfc2d" 1141 | dependencies = [ 1142 | "autocfg", 1143 | ] 1144 | 1145 | [[package]] 1146 | name = "smallvec" 1147 | version = "1.10.0" 1148 | source = "registry+https://github.com/rust-lang/crates.io-index" 1149 | checksum = "a507befe795404456341dfab10cef66ead4c041f62b8b11bbb92bffe5d0953e0" 1150 | 1151 | [[package]] 1152 | name = "socket2" 1153 | version = "0.4.9" 1154 | source = "registry+https://github.com/rust-lang/crates.io-index" 1155 | checksum = "64a4a911eed85daf18834cfaa86a79b7d266ff93ff5ba14005426219480ed662" 1156 | dependencies = [ 1157 | "libc", 1158 | "winapi", 1159 | ] 1160 | 1161 | [[package]] 1162 | name = "spin" 1163 | version = "0.9.8" 1164 | source = "registry+https://github.com/rust-lang/crates.io-index" 1165 | checksum = "6980e8d7511241f8acf4aebddbb1ff938df5eebe98691418c4468d0b72a96a67" 1166 | 1167 | [[package]] 1168 | name = "stable-pattern" 1169 | version = "0.1.0" 1170 | source = "registry+https://github.com/rust-lang/crates.io-index" 1171 | checksum = "4564168c00635f88eaed410d5efa8131afa8d8699a612c80c455a0ba05c21045" 1172 | dependencies = [ 1173 | "memchr", 1174 | ] 1175 | 1176 | [[package]] 1177 | name = "state" 1178 | version = "0.5.3" 1179 | source = "registry+https://github.com/rust-lang/crates.io-index" 1180 | checksum = "dbe866e1e51e8260c9eed836a042a5e7f6726bb2b411dffeaa712e19c388f23b" 1181 | dependencies = [ 1182 | "loom", 1183 | ] 1184 | 1185 | [[package]] 1186 | name = "syn" 1187 | version = "2.0.15" 1188 | source = "registry+https://github.com/rust-lang/crates.io-index" 1189 | checksum = "a34fcf3e8b60f57e6a14301a2e916d323af98b0ea63c599441eec8558660c822" 1190 | dependencies = [ 1191 | "proc-macro2", 1192 | "quote", 1193 | "unicode-ident", 1194 | ] 1195 | 1196 | [[package]] 1197 | name = "tempfile" 1198 | version = "3.5.0" 1199 | source = "registry+https://github.com/rust-lang/crates.io-index" 1200 | checksum = "b9fbec84f381d5795b08656e4912bec604d162bff9291d6189a78f4c8ab87998" 1201 | dependencies = [ 1202 | "cfg-if", 1203 | "fastrand", 1204 | "redox_syscall 0.3.5", 1205 | "rustix", 1206 | "windows-sys 0.45.0", 1207 | ] 1208 | 1209 | [[package]] 1210 | name = "thiserror" 1211 | version = "1.0.40" 1212 | source = "registry+https://github.com/rust-lang/crates.io-index" 1213 | checksum = "978c9a314bd8dc99be594bc3c175faaa9794be04a5a5e153caba6915336cebac" 1214 | dependencies = [ 1215 | "thiserror-impl", 1216 | ] 1217 | 1218 | [[package]] 1219 | name = "thiserror-impl" 1220 | version = "1.0.40" 1221 | source = "registry+https://github.com/rust-lang/crates.io-index" 1222 | checksum = "f9456a42c5b0d803c8cd86e73dd7cc9edd429499f37a3550d286d5e86720569f" 1223 | dependencies = [ 1224 | "proc-macro2", 1225 | "quote", 1226 | "syn", 1227 | ] 1228 | 1229 | [[package]] 1230 | name = "thread_local" 1231 | version = "1.1.7" 1232 | source = "registry+https://github.com/rust-lang/crates.io-index" 1233 | checksum = "3fdd6f064ccff2d6567adcb3873ca630700f00b5ad3f060c25b5dcfd9a4ce152" 1234 | dependencies = [ 1235 | "cfg-if", 1236 | "once_cell", 1237 | ] 1238 | 1239 | [[package]] 1240 | name = "time" 1241 | version = "0.3.20" 1242 | source = "registry+https://github.com/rust-lang/crates.io-index" 1243 | checksum = "cd0cbfecb4d19b5ea75bb31ad904eb5b9fa13f21079c3b92017ebdf4999a5890" 1244 | dependencies = [ 1245 | "itoa", 1246 | "serde", 1247 | "time-core", 1248 | "time-macros", 1249 | ] 1250 | 1251 | [[package]] 1252 | name = "time-core" 1253 | version = "0.1.0" 1254 | source = "registry+https://github.com/rust-lang/crates.io-index" 1255 | checksum = "2e153e1f1acaef8acc537e68b44906d2db6436e2b35ac2c6b42640fff91f00fd" 1256 | 1257 | [[package]] 1258 | name = "time-macros" 1259 | version = "0.2.8" 1260 | source = "registry+https://github.com/rust-lang/crates.io-index" 1261 | checksum = "fd80a657e71da814b8e5d60d3374fc6d35045062245d80224748ae522dd76f36" 1262 | dependencies = [ 1263 | "time-core", 1264 | ] 1265 | 1266 | [[package]] 1267 | name = "tokio" 1268 | version = "1.28.0" 1269 | source = "registry+https://github.com/rust-lang/crates.io-index" 1270 | checksum = "c3c786bf8134e5a3a166db9b29ab8f48134739014a3eca7bc6bfa95d673b136f" 1271 | dependencies = [ 1272 | "autocfg", 1273 | "bytes", 1274 | "libc", 1275 | "mio", 1276 | "num_cpus", 1277 | "pin-project-lite", 1278 | "signal-hook-registry", 1279 | "socket2", 1280 | "tokio-macros", 1281 | "windows-sys 0.48.0", 1282 | ] 1283 | 1284 | [[package]] 1285 | name = "tokio-macros" 1286 | version = "2.1.0" 1287 | source = "registry+https://github.com/rust-lang/crates.io-index" 1288 | checksum = "630bdcf245f78637c13ec01ffae6187cca34625e8c63150d424b59e55af2675e" 1289 | dependencies = [ 1290 | "proc-macro2", 1291 | "quote", 1292 | "syn", 1293 | ] 1294 | 1295 | [[package]] 1296 | name = "tokio-stream" 1297 | version = "0.1.14" 1298 | source = "registry+https://github.com/rust-lang/crates.io-index" 1299 | checksum = "397c988d37662c7dda6d2208364a706264bf3d6138b11d436cbac0ad38832842" 1300 | dependencies = [ 1301 | "futures-core", 1302 | "pin-project-lite", 1303 | "tokio", 1304 | ] 1305 | 1306 | [[package]] 1307 | name = "tokio-util" 1308 | version = "0.7.8" 1309 | source = "registry+https://github.com/rust-lang/crates.io-index" 1310 | checksum = "806fe8c2c87eccc8b3267cbae29ed3ab2d0bd37fca70ab622e46aaa9375ddb7d" 1311 | dependencies = [ 1312 | "bytes", 1313 | "futures-core", 1314 | "futures-sink", 1315 | "pin-project-lite", 1316 | "tokio", 1317 | "tracing", 1318 | ] 1319 | 1320 | [[package]] 1321 | name = "toml" 1322 | version = "0.5.11" 1323 | source = "registry+https://github.com/rust-lang/crates.io-index" 1324 | checksum = "f4f7f0dd8d50a853a531c426359045b1998f04219d88799810762cd4ad314234" 1325 | dependencies = [ 1326 | "serde", 1327 | ] 1328 | 1329 | [[package]] 1330 | name = "tower-service" 1331 | version = "0.3.2" 1332 | source = "registry+https://github.com/rust-lang/crates.io-index" 1333 | checksum = "b6bc1c9ce2b5135ac7f93c72918fc37feb872bdc6a5533a8b85eb4b86bfdae52" 1334 | 1335 | [[package]] 1336 | name = "tracing" 1337 | version = "0.1.38" 1338 | source = "registry+https://github.com/rust-lang/crates.io-index" 1339 | checksum = "cf9cf6a813d3f40c88b0b6b6f29a5c95c6cdbf97c1f9cc53fb820200f5ad814d" 1340 | dependencies = [ 1341 | "pin-project-lite", 1342 | "tracing-attributes", 1343 | "tracing-core", 1344 | ] 1345 | 1346 | [[package]] 1347 | name = "tracing-attributes" 1348 | version = "0.1.24" 1349 | source = "registry+https://github.com/rust-lang/crates.io-index" 1350 | checksum = "0f57e3ca2a01450b1a921183a9c9cbfda207fd822cef4ccb00a65402cbba7a74" 1351 | dependencies = [ 1352 | "proc-macro2", 1353 | "quote", 1354 | "syn", 1355 | ] 1356 | 1357 | [[package]] 1358 | name = "tracing-core" 1359 | version = "0.1.30" 1360 | source = "registry+https://github.com/rust-lang/crates.io-index" 1361 | checksum = "24eb03ba0eab1fd845050058ce5e616558e8f8d8fca633e6b163fe25c797213a" 1362 | dependencies = [ 1363 | "once_cell", 1364 | "valuable", 1365 | ] 1366 | 1367 | [[package]] 1368 | name = "tracing-log" 1369 | version = "0.1.3" 1370 | source = "registry+https://github.com/rust-lang/crates.io-index" 1371 | checksum = "78ddad33d2d10b1ed7eb9d1f518a5674713876e97e5bb9b7345a7984fbb4f922" 1372 | dependencies = [ 1373 | "lazy_static", 1374 | "log", 1375 | "tracing-core", 1376 | ] 1377 | 1378 | [[package]] 1379 | name = "tracing-subscriber" 1380 | version = "0.3.17" 1381 | source = "registry+https://github.com/rust-lang/crates.io-index" 1382 | checksum = "30a651bc37f915e81f087d86e62a18eec5f79550c7faff886f7090b4ea757c77" 1383 | dependencies = [ 1384 | "matchers", 1385 | "nu-ansi-term", 1386 | "once_cell", 1387 | "regex", 1388 | "sharded-slab", 1389 | "smallvec", 1390 | "thread_local", 1391 | "tracing", 1392 | "tracing-core", 1393 | "tracing-log", 1394 | ] 1395 | 1396 | [[package]] 1397 | name = "tree_magic_mini" 1398 | version = "3.0.3" 1399 | source = "registry+https://github.com/rust-lang/crates.io-index" 1400 | checksum = "91adfd0607cacf6e4babdb870e9bec4037c1c4b151cfd279ccefc5e0c7feaa6d" 1401 | dependencies = [ 1402 | "bytecount", 1403 | "fnv", 1404 | "lazy_static", 1405 | "nom", 1406 | "once_cell", 1407 | "petgraph", 1408 | ] 1409 | 1410 | [[package]] 1411 | name = "try-lock" 1412 | version = "0.2.4" 1413 | source = "registry+https://github.com/rust-lang/crates.io-index" 1414 | checksum = "3528ecfd12c466c6f163363caf2d02a71161dd5e1cc6ae7b34207ea2d42d81ed" 1415 | 1416 | [[package]] 1417 | name = "typenum" 1418 | version = "1.16.0" 1419 | source = "registry+https://github.com/rust-lang/crates.io-index" 1420 | checksum = "497961ef93d974e23eb6f433eb5fe1b7930b659f06d12dec6fc44a8f554c0bba" 1421 | 1422 | [[package]] 1423 | name = "ubyte" 1424 | version = "0.10.3" 1425 | source = "registry+https://github.com/rust-lang/crates.io-index" 1426 | checksum = "c81f0dae7d286ad0d9366d7679a77934cfc3cf3a8d67e82669794412b2368fe6" 1427 | dependencies = [ 1428 | "serde", 1429 | ] 1430 | 1431 | [[package]] 1432 | name = "ucd-trie" 1433 | version = "0.1.5" 1434 | source = "registry+https://github.com/rust-lang/crates.io-index" 1435 | checksum = "9e79c4d996edb816c91e4308506774452e55e95c3c9de07b6729e17e15a5ef81" 1436 | 1437 | [[package]] 1438 | name = "uncased" 1439 | version = "0.9.7" 1440 | source = "registry+https://github.com/rust-lang/crates.io-index" 1441 | checksum = "09b01702b0fd0b3fadcf98e098780badda8742d4f4a7676615cad90e8ac73622" 1442 | dependencies = [ 1443 | "serde", 1444 | "version_check", 1445 | ] 1446 | 1447 | [[package]] 1448 | name = "unicode-ident" 1449 | version = "1.0.8" 1450 | source = "registry+https://github.com/rust-lang/crates.io-index" 1451 | checksum = "e5464a87b239f13a63a501f2701565754bae92d243d4bb7eb12f6d57d2269bf4" 1452 | 1453 | [[package]] 1454 | name = "unicode-xid" 1455 | version = "0.2.4" 1456 | source = "registry+https://github.com/rust-lang/crates.io-index" 1457 | checksum = "f962df74c8c05a667b5ee8bcf162993134c104e96440b663c8daa176dc772d8c" 1458 | 1459 | [[package]] 1460 | name = "valuable" 1461 | version = "0.1.0" 1462 | source = "registry+https://github.com/rust-lang/crates.io-index" 1463 | checksum = "830b7e5d4d90034032940e4ace0d9a9a057e7a45cd94e6c007832e39edb82f6d" 1464 | 1465 | [[package]] 1466 | name = "version_check" 1467 | version = "0.9.4" 1468 | source = "registry+https://github.com/rust-lang/crates.io-index" 1469 | checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" 1470 | 1471 | [[package]] 1472 | name = "want" 1473 | version = "0.3.0" 1474 | source = "registry+https://github.com/rust-lang/crates.io-index" 1475 | checksum = "1ce8a968cb1cd110d136ff8b819a556d6fb6d919363c61534f6860c7eb172ba0" 1476 | dependencies = [ 1477 | "log", 1478 | "try-lock", 1479 | ] 1480 | 1481 | [[package]] 1482 | name = "wasi" 1483 | version = "0.11.0+wasi-snapshot-preview1" 1484 | source = "registry+https://github.com/rust-lang/crates.io-index" 1485 | checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" 1486 | 1487 | [[package]] 1488 | name = "winapi" 1489 | version = "0.3.9" 1490 | source = "registry+https://github.com/rust-lang/crates.io-index" 1491 | checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" 1492 | dependencies = [ 1493 | "winapi-i686-pc-windows-gnu", 1494 | "winapi-x86_64-pc-windows-gnu", 1495 | ] 1496 | 1497 | [[package]] 1498 | name = "winapi-i686-pc-windows-gnu" 1499 | version = "0.4.0" 1500 | source = "registry+https://github.com/rust-lang/crates.io-index" 1501 | checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" 1502 | 1503 | [[package]] 1504 | name = "winapi-x86_64-pc-windows-gnu" 1505 | version = "0.4.0" 1506 | source = "registry+https://github.com/rust-lang/crates.io-index" 1507 | checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" 1508 | 1509 | [[package]] 1510 | name = "windows" 1511 | version = "0.48.0" 1512 | source = "registry+https://github.com/rust-lang/crates.io-index" 1513 | checksum = "e686886bc078bc1b0b600cac0147aadb815089b6e4da64016cbd754b6342700f" 1514 | dependencies = [ 1515 | "windows-targets 0.48.0", 1516 | ] 1517 | 1518 | [[package]] 1519 | name = "windows-sys" 1520 | version = "0.45.0" 1521 | source = "registry+https://github.com/rust-lang/crates.io-index" 1522 | checksum = "75283be5efb2831d37ea142365f009c02ec203cd29a3ebecbc093d52315b66d0" 1523 | dependencies = [ 1524 | "windows-targets 0.42.2", 1525 | ] 1526 | 1527 | [[package]] 1528 | name = "windows-sys" 1529 | version = "0.48.0" 1530 | source = "registry+https://github.com/rust-lang/crates.io-index" 1531 | checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9" 1532 | dependencies = [ 1533 | "windows-targets 0.48.0", 1534 | ] 1535 | 1536 | [[package]] 1537 | name = "windows-targets" 1538 | version = "0.42.2" 1539 | source = "registry+https://github.com/rust-lang/crates.io-index" 1540 | checksum = "8e5180c00cd44c9b1c88adb3693291f1cd93605ded80c250a75d472756b4d071" 1541 | dependencies = [ 1542 | "windows_aarch64_gnullvm 0.42.2", 1543 | "windows_aarch64_msvc 0.42.2", 1544 | "windows_i686_gnu 0.42.2", 1545 | "windows_i686_msvc 0.42.2", 1546 | "windows_x86_64_gnu 0.42.2", 1547 | "windows_x86_64_gnullvm 0.42.2", 1548 | "windows_x86_64_msvc 0.42.2", 1549 | ] 1550 | 1551 | [[package]] 1552 | name = "windows-targets" 1553 | version = "0.48.0" 1554 | source = "registry+https://github.com/rust-lang/crates.io-index" 1555 | checksum = "7b1eb6f0cd7c80c79759c929114ef071b87354ce476d9d94271031c0497adfd5" 1556 | dependencies = [ 1557 | "windows_aarch64_gnullvm 0.48.0", 1558 | "windows_aarch64_msvc 0.48.0", 1559 | "windows_i686_gnu 0.48.0", 1560 | "windows_i686_msvc 0.48.0", 1561 | "windows_x86_64_gnu 0.48.0", 1562 | "windows_x86_64_gnullvm 0.48.0", 1563 | "windows_x86_64_msvc 0.48.0", 1564 | ] 1565 | 1566 | [[package]] 1567 | name = "windows_aarch64_gnullvm" 1568 | version = "0.42.2" 1569 | source = "registry+https://github.com/rust-lang/crates.io-index" 1570 | checksum = "597a5118570b68bc08d8d59125332c54f1ba9d9adeedeef5b99b02ba2b0698f8" 1571 | 1572 | [[package]] 1573 | name = "windows_aarch64_gnullvm" 1574 | version = "0.48.0" 1575 | source = "registry+https://github.com/rust-lang/crates.io-index" 1576 | checksum = "91ae572e1b79dba883e0d315474df7305d12f569b400fcf90581b06062f7e1bc" 1577 | 1578 | [[package]] 1579 | name = "windows_aarch64_msvc" 1580 | version = "0.42.2" 1581 | source = "registry+https://github.com/rust-lang/crates.io-index" 1582 | checksum = "e08e8864a60f06ef0d0ff4ba04124db8b0fb3be5776a5cd47641e942e58c4d43" 1583 | 1584 | [[package]] 1585 | name = "windows_aarch64_msvc" 1586 | version = "0.48.0" 1587 | source = "registry+https://github.com/rust-lang/crates.io-index" 1588 | checksum = "b2ef27e0d7bdfcfc7b868b317c1d32c641a6fe4629c171b8928c7b08d98d7cf3" 1589 | 1590 | [[package]] 1591 | name = "windows_i686_gnu" 1592 | version = "0.42.2" 1593 | source = "registry+https://github.com/rust-lang/crates.io-index" 1594 | checksum = "c61d927d8da41da96a81f029489353e68739737d3beca43145c8afec9a31a84f" 1595 | 1596 | [[package]] 1597 | name = "windows_i686_gnu" 1598 | version = "0.48.0" 1599 | source = "registry+https://github.com/rust-lang/crates.io-index" 1600 | checksum = "622a1962a7db830d6fd0a69683c80a18fda201879f0f447f065a3b7467daa241" 1601 | 1602 | [[package]] 1603 | name = "windows_i686_msvc" 1604 | version = "0.42.2" 1605 | source = "registry+https://github.com/rust-lang/crates.io-index" 1606 | checksum = "44d840b6ec649f480a41c8d80f9c65108b92d89345dd94027bfe06ac444d1060" 1607 | 1608 | [[package]] 1609 | name = "windows_i686_msvc" 1610 | version = "0.48.0" 1611 | source = "registry+https://github.com/rust-lang/crates.io-index" 1612 | checksum = "4542c6e364ce21bf45d69fdd2a8e455fa38d316158cfd43b3ac1c5b1b19f8e00" 1613 | 1614 | [[package]] 1615 | name = "windows_x86_64_gnu" 1616 | version = "0.42.2" 1617 | source = "registry+https://github.com/rust-lang/crates.io-index" 1618 | checksum = "8de912b8b8feb55c064867cf047dda097f92d51efad5b491dfb98f6bbb70cb36" 1619 | 1620 | [[package]] 1621 | name = "windows_x86_64_gnu" 1622 | version = "0.48.0" 1623 | source = "registry+https://github.com/rust-lang/crates.io-index" 1624 | checksum = "ca2b8a661f7628cbd23440e50b05d705db3686f894fc9580820623656af974b1" 1625 | 1626 | [[package]] 1627 | name = "windows_x86_64_gnullvm" 1628 | version = "0.42.2" 1629 | source = "registry+https://github.com/rust-lang/crates.io-index" 1630 | checksum = "26d41b46a36d453748aedef1486d5c7a85db22e56aff34643984ea85514e94a3" 1631 | 1632 | [[package]] 1633 | name = "windows_x86_64_gnullvm" 1634 | version = "0.48.0" 1635 | source = "registry+https://github.com/rust-lang/crates.io-index" 1636 | checksum = "7896dbc1f41e08872e9d5e8f8baa8fdd2677f29468c4e156210174edc7f7b953" 1637 | 1638 | [[package]] 1639 | name = "windows_x86_64_msvc" 1640 | version = "0.42.2" 1641 | source = "registry+https://github.com/rust-lang/crates.io-index" 1642 | checksum = "9aec5da331524158c6d1a4ac0ab1541149c0b9505fde06423b02f5ef0106b9f0" 1643 | 1644 | [[package]] 1645 | name = "windows_x86_64_msvc" 1646 | version = "0.48.0" 1647 | source = "registry+https://github.com/rust-lang/crates.io-index" 1648 | checksum = "1a515f5799fe4961cb532f983ce2b23082366b898e52ffbce459c86f67c8378a" 1649 | 1650 | [[package]] 1651 | name = "yansi" 1652 | version = "0.5.1" 1653 | source = "registry+https://github.com/rust-lang/crates.io-index" 1654 | checksum = "09041cd90cf85f7f8b2df60c646f853b7f535ce68f85244eb6731cf89fa498ec" 1655 | --------------------------------------------------------------------------------