Compare commits
No commits in common. "8ce3acde5e932e0f5a6e3036d4179c11103a6fe5" and "6dd7e3c08e3c9ed243274678a3281b3a51708a7d" have entirely different histories.
8ce3acde5e
...
6dd7e3c08e
4 changed files with 40 additions and 112 deletions
16
src/main.rs
16
src/main.rs
|
|
@ -1,6 +1,6 @@
|
||||||
mod sharry;
|
mod sharry;
|
||||||
|
|
||||||
use log::{error, info};
|
use log::info;
|
||||||
use sharry::{Alias, File, NewShareRequest, Share};
|
use sharry::{Alias, File, NewShareRequest, Share};
|
||||||
use std::time::Duration;
|
use std::time::Duration;
|
||||||
use ureq::Agent;
|
use ureq::Agent;
|
||||||
|
|
@ -22,15 +22,13 @@ fn main() {
|
||||||
let share = Share::create(&agent, &alias, share).unwrap();
|
let share = Share::create(&agent, &alias, share).unwrap();
|
||||||
info!("share: {:?}", share);
|
info!("share: {:?}", share);
|
||||||
|
|
||||||
let file = File::create(&agent, &share, "/lib/x86_64-linux-gnu/liblldb-14.so.1").unwrap();
|
let file = File::create(
|
||||||
|
&agent,
|
||||||
|
&share,
|
||||||
|
"/lib/x86_64-linux-gnu/liblldb-14.so.1".into(),
|
||||||
|
)
|
||||||
|
.unwrap();
|
||||||
info!("file: {:?}", file);
|
info!("file: {:?}", file);
|
||||||
|
|
||||||
for chunk in file.chunked(10 * 1024 * 1024) {
|
|
||||||
println!("chunk len: {}", chunk.bytes.len());
|
|
||||||
file.upload_chunk(&agent, chunk)
|
|
||||||
.inspect_err(|e| error!("error: {}", e))
|
|
||||||
.unwrap();
|
|
||||||
}
|
|
||||||
|
|
||||||
share.notify(&agent).unwrap();
|
share.notify(&agent).unwrap();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,60 +0,0 @@
|
||||||
use std::{
|
|
||||||
fs,
|
|
||||||
io::{self, Read, Seek},
|
|
||||||
mem,
|
|
||||||
path::PathBuf,
|
|
||||||
};
|
|
||||||
|
|
||||||
use log::error;
|
|
||||||
|
|
||||||
pub struct ChunkedFile<'t> {
|
|
||||||
path: &'t PathBuf,
|
|
||||||
cnum: u64,
|
|
||||||
csize: usize,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'t> ChunkedFile<'t> {
|
|
||||||
pub(super) fn new(path: &'t PathBuf, chunk_size: usize) -> Self {
|
|
||||||
Self {
|
|
||||||
path,
|
|
||||||
cnum: 0,
|
|
||||||
csize: chunk_size,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'t> Iterator for ChunkedFile<'t> {
|
|
||||||
type Item = Chunk;
|
|
||||||
|
|
||||||
fn next(&mut self) -> Option<Self::Item> {
|
|
||||||
let offset = {
|
|
||||||
let csize: u64 = self.csize.try_into().unwrap();
|
|
||||||
self.cnum * csize
|
|
||||||
};
|
|
||||||
|
|
||||||
let mut f = fs::File::open(&self.path)
|
|
||||||
.inspect_err(|e| error!("Error opening file: {}", e))
|
|
||||||
.ok()?;
|
|
||||||
f.seek(io::SeekFrom::Start(offset)).ok()?;
|
|
||||||
|
|
||||||
let mut buffer = vec![0; self.csize];
|
|
||||||
let read_len = f
|
|
||||||
.read(&mut buffer)
|
|
||||||
.inspect_err(|e| error!("Error reading file: {}", e))
|
|
||||||
.ok()?;
|
|
||||||
buffer.truncate(read_len);
|
|
||||||
|
|
||||||
self.cnum += 1;
|
|
||||||
|
|
||||||
Some(Self::Item {
|
|
||||||
offset: offset.try_into().unwrap(),
|
|
||||||
bytes: buffer,
|
|
||||||
})
|
|
||||||
.filter(|c| c.bytes.len() > 0)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub struct Chunk {
|
|
||||||
pub offset: usize,
|
|
||||||
pub bytes: Vec<u8>,
|
|
||||||
}
|
|
||||||
|
|
@ -1,18 +1,15 @@
|
||||||
use std::{
|
use std::{
|
||||||
ffi::OsStr,
|
ffi::OsStr,
|
||||||
fs,
|
fs,
|
||||||
io::{self, Read, Seek},
|
io::{self, Read},
|
||||||
os::unix::fs::FileExt,
|
|
||||||
path::{Path, PathBuf},
|
path::{Path, PathBuf},
|
||||||
str::FromStr,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
use log::{debug, error};
|
use log::debug;
|
||||||
use ureq::http::StatusCode;
|
use ureq::http::StatusCode;
|
||||||
|
|
||||||
use super::{
|
use super::{
|
||||||
alias::{Alias, SharryAlias},
|
alias::{Alias, SharryAlias},
|
||||||
chunkedfile::{Chunk, ChunkedFile},
|
|
||||||
share::Share,
|
share::Share,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -27,18 +24,17 @@ impl<'t> File<'t> {
|
||||||
pub fn create(
|
pub fn create(
|
||||||
http: &ureq::Agent,
|
http: &ureq::Agent,
|
||||||
share: &'t Share,
|
share: &'t Share,
|
||||||
file_path: impl Into<PathBuf>,
|
file_path: PathBuf,
|
||||||
) -> Result<Self, ureq::Error> {
|
) -> Result<Self, ureq::Error> {
|
||||||
let file_path: PathBuf = file_path.into();
|
let endpoint = share
|
||||||
|
.alias
|
||||||
|
.get_endpoint(format!("alias/upload/{}/files/tus", share.id));
|
||||||
|
|
||||||
let filename = file_path
|
let filename = file_path
|
||||||
.file_name()
|
.file_name()
|
||||||
.and_then(OsStr::to_str)
|
.and_then(OsStr::to_str)
|
||||||
.unwrap_or("file.bin");
|
.unwrap_or("file.bin");
|
||||||
|
|
||||||
let endpoint = share
|
|
||||||
.alias
|
|
||||||
.get_endpoint(format!("alias/upload/{}/files/tus", share.id));
|
|
||||||
|
|
||||||
let res = http
|
let res = http
|
||||||
.post(endpoint)
|
.post(endpoint)
|
||||||
.sharry_header(share.alias)
|
.sharry_header(share.alias)
|
||||||
|
|
@ -59,6 +55,14 @@ impl<'t> File<'t> {
|
||||||
|
|
||||||
debug!("location: {}", location);
|
debug!("location: {}", location);
|
||||||
|
|
||||||
|
// let start = 10;
|
||||||
|
// let count = 10;
|
||||||
|
|
||||||
|
// let mut f = File::open(path)?;
|
||||||
|
// f.seek(SeekFrom::Start(0));
|
||||||
|
// let mut buf = vec![0; count];
|
||||||
|
// f.read_exact(&mut buf)?;
|
||||||
|
|
||||||
Ok(Self {
|
Ok(Self {
|
||||||
alias: share.alias,
|
alias: share.alias,
|
||||||
file_path,
|
file_path,
|
||||||
|
|
@ -66,36 +70,23 @@ impl<'t> File<'t> {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn chunked(&self, chunk_size: usize) -> ChunkedFile {
|
pub fn upload(&self, chunk_size: usize) -> UploadChunk {
|
||||||
ChunkedFile::new(&self.file_path, chunk_size)
|
UploadChunk::new(&self.file_path, chunk_size).unwrap()
|
||||||
}
|
}
|
||||||
|
}
|
||||||
pub fn upload_chunk(&self, http: &ureq::Agent, chunk: Chunk) -> Result<(), ureq::Error> {
|
|
||||||
debug!("upload uri: {:?}", self.patch_uri);
|
pub struct UploadChunk {
|
||||||
|
num: u64,
|
||||||
let res = http
|
f: fs::File,
|
||||||
.patch(&self.patch_uri)
|
buffer: Vec<u8>,
|
||||||
.sharry_header(self.alias)
|
}
|
||||||
.header("Upload-Offset", chunk.offset)
|
|
||||||
.send(&chunk.bytes)?;
|
impl UploadChunk {
|
||||||
|
fn new(path: impl AsRef<Path>, chunk_size: usize) -> io::Result<Self> {
|
||||||
if res.status() != StatusCode::NO_CONTENT {
|
Ok(Self {
|
||||||
return Err(ureq::Error::Other("unexpected response status".into()));
|
num: 0,
|
||||||
}
|
f: fs::File::open(path)?,
|
||||||
|
buffer: vec![0; chunk_size],
|
||||||
let offset = res
|
})
|
||||||
.headers()
|
|
||||||
.get("Upload-Offset")
|
|
||||||
.ok_or_else(|| ureq::Error::Other("Upload-Offset header not found".into()))?
|
|
||||||
.to_str()
|
|
||||||
.map_err(|_| ureq::Error::Other("Upload-Offset header invalid".into()))?
|
|
||||||
.parse::<usize>()
|
|
||||||
.map_err(|_| ureq::Error::Other("Upload-Offset header not an integer".into()))?;
|
|
||||||
|
|
||||||
if chunk.offset + chunk.bytes.len() != offset {
|
|
||||||
return Err(ureq::Error::Other("unexpected offset response".into()));
|
|
||||||
}
|
|
||||||
|
|
||||||
Ok(())
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,6 @@
|
||||||
|
|
||||||
mod alias;
|
mod alias;
|
||||||
mod api;
|
mod api;
|
||||||
mod chunkedfile;
|
|
||||||
mod file;
|
mod file;
|
||||||
mod share;
|
mod share;
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue