♻️ Towards response headers and status code
							parent
							
								
									d286adadc9
								
							
						
					
					
						commit
						1e86e9735e
					
				|  | @ -9,9 +9,12 @@ edition = "2018" | |||
| 
 | ||||
| [dependencies] | ||||
| 
 | ||||
| base64 = "0.12" | ||||
| futures = "0.3" | ||||
| http = "0.2" | ||||
| hyper = "0.13" | ||||
| lazy_static = "1.4" | ||||
| regex = "1" | ||||
| reqwest = { version = "0.10.8", features = ["stream"] } | ||||
| rmp-serde = "0.14.4" | ||||
| serde = {version = "1.0", features = ["derive"]} | ||||
|  |  | |||
|  | @ -173,7 +173,12 @@ async fn handle_http_request ( | |||
| 	match r.await { | ||||
| 		Ok (Message::HttpResponseResponseStream (body)) => { | ||||
| 			println! ("Step 7"); | ||||
| 			status_reply (StatusCode::OK, body) | ||||
| 			
 | ||||
| 			Response::builder () | ||||
| 			.status (StatusCode::OK) | ||||
| 			.header ("Accept-Ranges", "bytes") | ||||
| 			.body (body) | ||||
| 			.unwrap () | ||||
| 		}, | ||||
| 		_ => status_reply (StatusCode::GATEWAY_TIMEOUT, "server didn't reply in time or somethin'"), | ||||
| 	} | ||||
|  |  | |||
|  | @ -1,6 +1,7 @@ | |||
| use std::{ | ||||
| 	convert::Infallible, | ||||
| 	error::Error, | ||||
| 	io::SeekFrom, | ||||
| 	path::PathBuf, | ||||
| 	sync::Arc, | ||||
| 	time::Duration, | ||||
|  | @ -10,6 +11,8 @@ use hyper::{ | |||
| 	StatusCode, | ||||
| 	Uri, | ||||
| }; | ||||
| use lazy_static::*; | ||||
| use regex::Regex; | ||||
| use reqwest::{ | ||||
| 	Body, | ||||
| 	Client, | ||||
|  | @ -25,6 +28,24 @@ use tokio::{ | |||
| 
 | ||||
| use ptth::http_serde::*; | ||||
| 
 | ||||
| fn parse_range_header (range_str: &str) -> (Option <u64>, Option <u64>) { | ||||
| 	lazy_static! { | ||||
| 		static ref RE: Regex = Regex::new (r"^(\d+)-(\d+)$").expect ("Couldn't compile regex for Range header"); | ||||
| 	} | ||||
| 	
 | ||||
| 	let caps = match RE.captures (range_str) { | ||||
| 		Some (x) => x, | ||||
| 		_ => return (None, None), | ||||
| 	}; | ||||
| 	let start = caps.get (1).map (|x| x.as_str ()); | ||||
| 	let end = caps.get (2).map (|x| x.as_str ()); | ||||
| 	
 | ||||
| 	let start = start.map (|x| u64::from_str_radix (x, 10).ok ()).flatten (); | ||||
| 	let end = end.map (|x| u64::from_str_radix (x, 10).ok ()).flatten (); | ||||
| 	
 | ||||
| 	(start, end) | ||||
| } | ||||
| 
 | ||||
| #[tokio::main] | ||||
| async fn main () -> Result <(), Box <dyn Error>> { | ||||
| 	let client = Arc::new (Client::new ()); | ||||
|  | @ -73,6 +94,19 @@ async fn main () -> Result <(), Box <dyn Error>> { | |||
| 		let (req_id, uri) = (parts.id, parts.uri); | ||||
| 		
 | ||||
| 		println! ("Client requested {}", uri); | ||||
| 		let mut range_start = None; | ||||
| 		let mut range_end = None; | ||||
| 		
 | ||||
| 		for (k, v) in parts.headers.iter () { | ||||
| 			let v = std::str::from_utf8 (v).unwrap (); | ||||
| 			println! ("{}: {}", k, v); | ||||
| 			
 | ||||
| 			if k == "range" { | ||||
| 				let (start, end) = parse_range_header (v); | ||||
| 				range_start = start; | ||||
| 				range_end = end; | ||||
| 			} | ||||
| 		} | ||||
| 		
 | ||||
| 		println! ("Step 4/5"); | ||||
| 		
 | ||||
|  | @ -80,22 +114,23 @@ async fn main () -> Result <(), Box <dyn Error>> { | |||
| 		let client = client.clone (); | ||||
| 		tokio::spawn (async move { | ||||
| 			let (tx, rx) = channel (2); | ||||
| 			//let rx: Receiver <Vec <u8>> = rx;
 | ||||
| 			
 | ||||
| 			tokio::spawn (async move { | ||||
| 				//let path = "/home/user/projects/2020/ptth/README.md";
 | ||||
| 			
 | ||||
| 			let mut path = PathBuf::from ("/home/user"); | ||||
| 				path.push (&uri [1..]); | ||||
| 				
 | ||||
| 				println! ("Opening file {:?}", path); | ||||
| 				
 | ||||
| 			let mut f = File::open (path).await.unwrap (); | ||||
| 			
 | ||||
| 			if let Some (start) = range_start { | ||||
| 				f.seek (SeekFrom::Start (start)).await.unwrap (); | ||||
| 			} | ||||
| 			
 | ||||
| 			tokio::spawn (async move { | ||||
| 				//println! ("Opening file {:?}", path);
 | ||||
| 				
 | ||||
| 				let mut tx = tx; | ||||
| 				let mut bytes_sent = 0; | ||||
| 				//let mut bytes_sent = 0;
 | ||||
| 				
 | ||||
| 				loop { | ||||
| 					let mut buffer = vec! [0u8; 4096]; | ||||
| 					let mut buffer = vec! [0u8; 65_536]; | ||||
| 					let bytes_read = f.read (&mut buffer).await.unwrap (); | ||||
| 					
 | ||||
| 					buffer.truncate (bytes_read); | ||||
|  | @ -104,10 +139,12 @@ async fn main () -> Result <(), Box <dyn Error>> { | |||
| 						break; | ||||
| 					} | ||||
| 					
 | ||||
| 					tx.send (Ok::<_, Infallible> (buffer)).await.unwrap (); | ||||
| 					bytes_sent += bytes_read; | ||||
| 					if tx.send (Ok::<_, Infallible> (buffer)).await.is_err () { | ||||
| 						break; | ||||
| 					} | ||||
| 					
 | ||||
| 					println! ("Sent {} bytes", bytes_sent); | ||||
| 					//bytes_sent += bytes_read;
 | ||||
| 					//println! ("Sent {} bytes", bytes_sent);
 | ||||
| 					
 | ||||
| 					delay_for (Duration::from_millis (50)).await; | ||||
| 				} | ||||
|  |  | |||
|  | @ -62,7 +62,7 @@ pub enum StatusCode { | |||
| 	Ok, | ||||
| 	NotFound, | ||||
| } | ||||
| 
 | ||||
| /* | ||||
| impl TryFrom <hyper::StatusCode> for StatusCode { | ||||
| 	type Error = Error; | ||||
| 	
 | ||||
|  | @ -74,7 +74,7 @@ impl TryFrom <hyper::StatusCode> for StatusCode { | |||
| 		} | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| */ | ||||
| impl From <StatusCode> for hyper::StatusCode { | ||||
| 	fn from (x: StatusCode) -> Self { | ||||
| 		match x { | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue
	
	 _
						_