♻️ 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;
|
||||
|
||||
let mut path = PathBuf::from ("/home/user");
|
||||
path.push (&uri [1..]);
|
||||
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 {
|
||||
//let path = "/home/user/projects/2020/ptth/README.md";
|
||||
//println! ("Opening file {:?}", path);
|
||||
|
||||
let mut path = PathBuf::from ("/home/user");
|
||||
path.push (&uri [1..]);
|
||||
|
||||
println! ("Opening file {:?}", path);
|
||||
|
||||
let mut f = File::open (path).await.unwrap ();
|
||||
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