bump proxmox to 0.3, cleanup http_err macro usage
Also swap the order of a couple of `.map_err().await` to `.await.map_err()` since that's generally more efficient. Signed-off-by: Wolfgang Bumiller <w.bumiller@proxmox.com>
This commit is contained in:
parent
3865e27e96
commit
8aa67ee758
|
@ -39,7 +39,7 @@ pam-sys = "0.5"
|
||||||
percent-encoding = "2.1"
|
percent-encoding = "2.1"
|
||||||
pin-utils = "0.1.0"
|
pin-utils = "0.1.0"
|
||||||
pathpatterns = "0.1.2"
|
pathpatterns = "0.1.2"
|
||||||
proxmox = { version = "0.2.1", features = [ "sortable-macro", "api-macro", "websocket" ] }
|
proxmox = { version = "0.3.0", features = [ "sortable-macro", "api-macro", "websocket" ] }
|
||||||
#proxmox = { git = "ssh://gitolite3@proxdev.maurer-it.com/rust/proxmox", version = "0.1.2", features = [ "sortable-macro", "api-macro" ] }
|
#proxmox = { git = "ssh://gitolite3@proxdev.maurer-it.com/rust/proxmox", version = "0.1.2", features = [ "sortable-macro", "api-macro" ] }
|
||||||
#proxmox = { path = "../proxmox/proxmox", features = [ "sortable-macro", "api-macro", "websocket" ] }
|
#proxmox = { path = "../proxmox/proxmox", features = [ "sortable-macro", "api-macro", "websocket" ] }
|
||||||
proxmox-fuse = "0.1.0"
|
proxmox-fuse = "0.1.0"
|
||||||
|
|
|
@ -156,7 +156,7 @@ fn create_ticket(
|
||||||
Err(err) => {
|
Err(err) => {
|
||||||
let client_ip = "unknown"; // $rpcenv->get_client_ip() || '';
|
let client_ip = "unknown"; // $rpcenv->get_client_ip() || '';
|
||||||
log::error!("authentication failure; rhost={} user={} msg={}", client_ip, username, err.to_string());
|
log::error!("authentication failure; rhost={} user={} msg={}", client_ip, username, err.to_string());
|
||||||
Err(http_err!(UNAUTHORIZED, "permission check failed.".into()))
|
Err(http_err!(UNAUTHORIZED, "permission check failed."))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -846,8 +846,8 @@ fn download_file(
|
||||||
path.push(&file_name);
|
path.push(&file_name);
|
||||||
|
|
||||||
let file = tokio::fs::File::open(&path)
|
let file = tokio::fs::File::open(&path)
|
||||||
.map_err(|err| http_err!(BAD_REQUEST, format!("File open failed: {}", err)))
|
.await
|
||||||
.await?;
|
.map_err(|err| http_err!(BAD_REQUEST, "File open failed: {}", err))?;
|
||||||
|
|
||||||
let payload = tokio_util::codec::FramedRead::new(file, tokio_util::codec::BytesCodec::new())
|
let payload = tokio_util::codec::FramedRead::new(file, tokio_util::codec::BytesCodec::new())
|
||||||
.map_ok(|bytes| hyper::body::Bytes::from(bytes.freeze()))
|
.map_ok(|bytes| hyper::body::Bytes::from(bytes.freeze()))
|
||||||
|
@ -954,7 +954,7 @@ fn download_file_decoded(
|
||||||
},
|
},
|
||||||
"blob" => {
|
"blob" => {
|
||||||
let file = std::fs::File::open(&path)
|
let file = std::fs::File::open(&path)
|
||||||
.map_err(|err| http_err!(BAD_REQUEST, format!("File open failed: {}", err)))?;
|
.map_err(|err| http_err!(BAD_REQUEST, "File open failed: {}", err))?;
|
||||||
|
|
||||||
Body::wrap_stream(
|
Body::wrap_stream(
|
||||||
WrappedReaderStream::new(DataBlobReader::new(file, None)?)
|
WrappedReaderStream::new(DataBlobReader::new(file, None)?)
|
||||||
|
|
|
@ -1,18 +1,19 @@
|
||||||
use std::path::PathBuf;
|
use std::path::PathBuf;
|
||||||
|
|
||||||
use anyhow::Error;
|
use anyhow::Error;
|
||||||
use futures::*;
|
use futures::stream::TryStreamExt;
|
||||||
use hyper::{Body, Response, StatusCode, header};
|
use hyper::{Body, Response, StatusCode, header};
|
||||||
use proxmox::http_err;
|
|
||||||
|
use proxmox::http_bail;
|
||||||
|
|
||||||
pub async fn create_download_response(path: PathBuf) -> Result<Response<Body>, Error> {
|
pub async fn create_download_response(path: PathBuf) -> Result<Response<Body>, Error> {
|
||||||
let file = tokio::fs::File::open(path.clone())
|
let file = match tokio::fs::File::open(path.clone()).await {
|
||||||
.map_err(move |err| {
|
Ok(file) => file,
|
||||||
match err.kind() {
|
Err(ref err) if err.kind() == std::io::ErrorKind::NotFound => {
|
||||||
std::io::ErrorKind::NotFound => http_err!(NOT_FOUND, format!("open file {:?} failed - not found", path.clone())),
|
http_bail!(NOT_FOUND, "open file {:?} failed - not found", path);
|
||||||
_ => http_err!(BAD_REQUEST, format!("open file {:?} failed: {}", path.clone(), err)),
|
|
||||||
}
|
}
|
||||||
})
|
Err(err) => http_bail!(BAD_REQUEST, "open file {:?} failed: {}", path, err),
|
||||||
.await?;
|
};
|
||||||
|
|
||||||
let payload = tokio_util::codec::FramedRead::new(file, tokio_util::codec::BytesCodec::new())
|
let payload = tokio_util::codec::FramedRead::new(file, tokio_util::codec::BytesCodec::new())
|
||||||
.map_ok(|bytes| hyper::body::Bytes::from(bytes.freeze()));
|
.map_ok(|bytes| hyper::body::Bytes::from(bytes.freeze()));
|
||||||
|
|
|
@ -225,8 +225,8 @@ fn download_chunk(
|
||||||
env.debug(format!("download chunk {:?}", path));
|
env.debug(format!("download chunk {:?}", path));
|
||||||
|
|
||||||
let data = tokio::fs::read(path)
|
let data = tokio::fs::read(path)
|
||||||
.map_err(move |err| http_err!(BAD_REQUEST, format!("reading file {:?} failed: {}", path2, err)))
|
.await
|
||||||
.await?;
|
.map_err(move |err| http_err!(BAD_REQUEST, "reading file {:?} failed: {}", path2, err))?;
|
||||||
|
|
||||||
let body = Body::from(data);
|
let body = Body::from(data);
|
||||||
|
|
||||||
|
@ -260,7 +260,7 @@ fn download_chunk_old(
|
||||||
let path3 = path.clone();
|
let path3 = path.clone();
|
||||||
|
|
||||||
let response_future = tokio::fs::File::open(path)
|
let response_future = tokio::fs::File::open(path)
|
||||||
.map_err(move |err| http_err!(BAD_REQUEST, format!("open file {:?} failed: {}", path2, err)))
|
.map_err(move |err| http_err!(BAD_REQUEST, "open file {:?} failed: {}", path2, err))
|
||||||
.and_then(move |file| {
|
.and_then(move |file| {
|
||||||
env2.debug(format!("download chunk {:?}", path3));
|
env2.debug(format!("download chunk {:?}", path3));
|
||||||
let payload = tokio_util::codec::FramedRead::new(file, tokio_util::codec::BytesCodec::new())
|
let payload = tokio_util::codec::FramedRead::new(file, tokio_util::codec::BytesCodec::new())
|
||||||
|
|
|
@ -44,7 +44,7 @@ impl <E: RpcEnvironment + Clone> H2Service<E> {
|
||||||
|
|
||||||
let (path, components) = match tools::normalize_uri_path(parts.uri.path()) {
|
let (path, components) = match tools::normalize_uri_path(parts.uri.path()) {
|
||||||
Ok((p,c)) => (p, c),
|
Ok((p,c)) => (p, c),
|
||||||
Err(err) => return future::err(http_err!(BAD_REQUEST, err.to_string())).boxed(),
|
Err(err) => return future::err(http_err!(BAD_REQUEST, "{}", err)).boxed(),
|
||||||
};
|
};
|
||||||
|
|
||||||
self.debug(format!("{} {}", method, path));
|
self.debug(format!("{} {}", method, path));
|
||||||
|
@ -55,7 +55,7 @@ impl <E: RpcEnvironment + Clone> H2Service<E> {
|
||||||
|
|
||||||
match self.router.find_method(&components, method, &mut uri_param) {
|
match self.router.find_method(&components, method, &mut uri_param) {
|
||||||
None => {
|
None => {
|
||||||
let err = http_err!(NOT_FOUND, format!("Path '{}' not found.", path).to_string());
|
let err = http_err!(NOT_FOUND, "Path '{}' not found.", path);
|
||||||
future::ok((formatter.format_error)(err)).boxed()
|
future::ok((formatter.format_error)(err)).boxed()
|
||||||
}
|
}
|
||||||
Some(api_method) => {
|
Some(api_method) => {
|
||||||
|
|
|
@ -204,13 +204,13 @@ async fn get_request_parameters<S: 'static + BuildHasher + Send>(
|
||||||
}
|
}
|
||||||
|
|
||||||
let body = req_body
|
let body = req_body
|
||||||
.map_err(|err| http_err!(BAD_REQUEST, format!("Promlems reading request body: {}", err)))
|
.map_err(|err| http_err!(BAD_REQUEST, "Promlems reading request body: {}", err))
|
||||||
.try_fold(Vec::new(), |mut acc, chunk| async move {
|
.try_fold(Vec::new(), |mut acc, chunk| async move {
|
||||||
if acc.len() + chunk.len() < 64*1024 { //fimxe: max request body size?
|
if acc.len() + chunk.len() < 64*1024 { //fimxe: max request body size?
|
||||||
acc.extend_from_slice(&*chunk);
|
acc.extend_from_slice(&*chunk);
|
||||||
Ok(acc)
|
Ok(acc)
|
||||||
} else {
|
} else {
|
||||||
Err(http_err!(BAD_REQUEST, "Request body too large".to_string()))
|
Err(http_err!(BAD_REQUEST, "Request body too large"))
|
||||||
}
|
}
|
||||||
}).await?;
|
}).await?;
|
||||||
|
|
||||||
|
@ -392,12 +392,12 @@ async fn simple_static_file_download(filename: PathBuf) -> Result<Response<Body>
|
||||||
|
|
||||||
let mut file = File::open(filename)
|
let mut file = File::open(filename)
|
||||||
.await
|
.await
|
||||||
.map_err(|err| http_err!(BAD_REQUEST, format!("File open failed: {}", err)))?;
|
.map_err(|err| http_err!(BAD_REQUEST, "File open failed: {}", err))?;
|
||||||
|
|
||||||
let mut data: Vec<u8> = Vec::new();
|
let mut data: Vec<u8> = Vec::new();
|
||||||
file.read_to_end(&mut data)
|
file.read_to_end(&mut data)
|
||||||
.await
|
.await
|
||||||
.map_err(|err| http_err!(BAD_REQUEST, format!("File read failed: {}", err)))?;
|
.map_err(|err| http_err!(BAD_REQUEST, "File read failed: {}", err))?;
|
||||||
|
|
||||||
let mut response = Response::new(data.into());
|
let mut response = Response::new(data.into());
|
||||||
response.headers_mut().insert(
|
response.headers_mut().insert(
|
||||||
|
@ -411,7 +411,7 @@ async fn chuncked_static_file_download(filename: PathBuf) -> Result<Response<Bod
|
||||||
|
|
||||||
let file = File::open(filename)
|
let file = File::open(filename)
|
||||||
.await
|
.await
|
||||||
.map_err(|err| http_err!(BAD_REQUEST, format!("File open failed: {}", err)))?;
|
.map_err(|err| http_err!(BAD_REQUEST, "File open failed: {}", err))?;
|
||||||
|
|
||||||
let payload = tokio_util::codec::FramedRead::new(file, tokio_util::codec::BytesCodec::new())
|
let payload = tokio_util::codec::FramedRead::new(file, tokio_util::codec::BytesCodec::new())
|
||||||
.map_ok(|bytes| hyper::body::Bytes::from(bytes.freeze()));
|
.map_ok(|bytes| hyper::body::Bytes::from(bytes.freeze()));
|
||||||
|
@ -429,7 +429,7 @@ async fn chuncked_static_file_download(filename: PathBuf) -> Result<Response<Bod
|
||||||
async fn handle_static_file_download(filename: PathBuf) -> Result<Response<Body>, Error> {
|
async fn handle_static_file_download(filename: PathBuf) -> Result<Response<Body>, Error> {
|
||||||
|
|
||||||
let metadata = tokio::fs::metadata(filename.clone())
|
let metadata = tokio::fs::metadata(filename.clone())
|
||||||
.map_err(|err| http_err!(BAD_REQUEST, format!("File access problems: {}", err)))
|
.map_err(|err| http_err!(BAD_REQUEST, "File access problems: {}", err))
|
||||||
.await?;
|
.await?;
|
||||||
|
|
||||||
if metadata.len() < 1024*32 {
|
if metadata.len() < 1024*32 {
|
||||||
|
@ -535,7 +535,7 @@ pub async fn handle_request(api: Arc<ApiConfig>, req: Request<Body>) -> Result<R
|
||||||
Ok(username) => rpcenv.set_user(Some(username)),
|
Ok(username) => rpcenv.set_user(Some(username)),
|
||||||
Err(err) => {
|
Err(err) => {
|
||||||
// always delay unauthorized calls by 3 seconds (from start of request)
|
// always delay unauthorized calls by 3 seconds (from start of request)
|
||||||
let err = http_err!(UNAUTHORIZED, format!("authentication failed - {}", err));
|
let err = http_err!(UNAUTHORIZED, "authentication failed - {}", err);
|
||||||
tokio::time::delay_until(Instant::from_std(delay_unauth_time)).await;
|
tokio::time::delay_until(Instant::from_std(delay_unauth_time)).await;
|
||||||
return Ok((formatter.format_error)(err));
|
return Ok((formatter.format_error)(err));
|
||||||
}
|
}
|
||||||
|
@ -544,13 +544,13 @@ pub async fn handle_request(api: Arc<ApiConfig>, req: Request<Body>) -> Result<R
|
||||||
|
|
||||||
match api.find_method(&components[2..], method, &mut uri_param) {
|
match api.find_method(&components[2..], method, &mut uri_param) {
|
||||||
None => {
|
None => {
|
||||||
let err = http_err!(NOT_FOUND, format!("Path '{}' not found.", path).to_string());
|
let err = http_err!(NOT_FOUND, "Path '{}' not found.", path);
|
||||||
return Ok((formatter.format_error)(err));
|
return Ok((formatter.format_error)(err));
|
||||||
}
|
}
|
||||||
Some(api_method) => {
|
Some(api_method) => {
|
||||||
let user = rpcenv.get_user();
|
let user = rpcenv.get_user();
|
||||||
if !check_api_permission(api_method.access.permission, user.as_deref(), &uri_param, user_info.as_ref()) {
|
if !check_api_permission(api_method.access.permission, user.as_deref(), &uri_param, user_info.as_ref()) {
|
||||||
let err = http_err!(FORBIDDEN, format!("permission check failed"));
|
let err = http_err!(FORBIDDEN, "permission check failed");
|
||||||
tokio::time::delay_until(Instant::from_std(access_forbidden_time)).await;
|
tokio::time::delay_until(Instant::from_std(access_forbidden_time)).await;
|
||||||
return Ok((formatter.format_error)(err));
|
return Ok((formatter.format_error)(err));
|
||||||
}
|
}
|
||||||
|
@ -598,5 +598,5 @@ pub async fn handle_request(api: Arc<ApiConfig>, req: Request<Body>) -> Result<R
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Err(http_err!(NOT_FOUND, format!("Path '{}' not found.", path).to_string()))
|
Err(http_err!(NOT_FOUND, "Path '{}' not found.", path))
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue