Browse Source

Fix no response on invalid range handling

main
Georg Hopp 11 months ago
parent
commit
0c640725a2
Signed by: ghopp GPG Key ID: 4C5D226768784538
  1. 55
      src/client.rs

55
src/client.rs

@ -2,7 +2,7 @@ use std::{io::ErrorKind, path::Path, time::Duration};
use anyhow::anyhow;
use futures_util::StreamExt as _;
use http::{header::{CONTENT_TYPE, RANGE}, request::Builder as RequestBuilder, uri::{Authority, Scheme}, Request, Response, StatusCode, Uri};
use http::{header::{CONTENT_LENGTH, CONTENT_TYPE, RANGE}, request::Builder as RequestBuilder, uri::{Authority, Scheme}, HeaderValue, Request, Response, StatusCode, Uri};
use http_body_util::BodyDataStream;
use m3u8_rs::{MediaPlaylist, MediaSegment, Playlist};
use reqwest::{redirect::Policy, Body};
@ -114,10 +114,20 @@ impl State {
. await
. map_err(|e| DownloadError::new(uri.clone(), Some(e)))?;
// We always need the content-type to be able to decide
let content_type = response.headers()[CONTENT_TYPE].to_str()
. expect("No content-type header found in response");
match response.headers().get("x-finished") {
None => (),
Some(v) => if let Ok(v) = v.to_str() {
if v == "true" {
return Ok(())
}
},
}
// We always need the content-type to be able to decide
let content_type = response.headers().get(CONTENT_TYPE)
. expect("No content-type header found in response")
. to_str()
. expect("Can't create &str from content-type header") ;
if content_type != "video/MP2T" {
let message = format!("unexpected content-type: {}", content_type);
log!(Level::Debug, "{}", message);
@ -208,6 +218,43 @@ impl State {
async fn request(&mut self, uri: &Uri, from: u64) -> anyhow::Result<Response<Body>>
{
let request = RequestBuilder::new()
. method("HEAD")
. uri(uri)
. body(Body::default())?;
log!(Level::Debug, "{:?}", request);
// Send get request with timeout.
// let send_fut = self.client.get(uri).send()?;
let send_fut = self.client.execute(request);
let response = timeout(self.timeout, send_fut).await??;
anyhow::ensure!( response.status().is_success()
, "resonse status failed: {}"
, response.status() );
log!(Level::Debug, "{:?}", response);
let content_length: u64 = response.headers().get(CONTENT_LENGTH)
. or(Some(&HeaderValue::from(0)))
. expect("No CONTENT-LENGTH in response")
. to_str()
. expect("unable to get CONTENT-LENGTH value")
. parse()
. expect("unable to parse CONTENT-LENGTH value");
if from != 0 && content_length - 1 <= from {
let response = Response::builder()
. header("x-finished", "true")
. body(Body::default())
. expect("Unable to create default response");
log!(Level::Debug, "content_length: {}, from: {}", content_length, from);
return Ok(response);
}
let request = RequestBuilder::new()
. uri(uri)
. header(RANGE, format!("bytes={}-", from))

Loading…
Cancel
Save