fix: allow multipart bodies without content-len in dag/put

This commit is contained in:
Joonas Koivunen 2020-07-08 19:25:43 +03:00
parent 4101383855
commit fef741c750

View File

@ -1,10 +1,12 @@
use crate::v0::support::{with_ipfs, InvalidMultipartFormData, StringError};
use futures::stream::StreamExt;
use crate::v0::support::{try_only_named_multipart, with_ipfs, NotImplemented, StringError};
use futures::stream::Stream;
use ipfs::{Ipfs, IpfsTypes};
use libipld::cid::{Cid, Codec};
use mime::Mime;
use serde::Deserialize;
use serde_json::json;
use warp::{multipart, path, query, reply, Buf, Filter, Rejection, Reply};
use warp::{path, query, reply, Buf, Filter, Rejection, Reply};
#[derive(Debug, Deserialize)]
pub struct PutQuery {
@ -15,7 +17,8 @@ pub struct PutQuery {
async fn put_query<T: IpfsTypes>(
ipfs: Ipfs<T>,
query: PutQuery,
mut form: multipart::FormData,
mime: Mime,
body: impl Stream<Item = Result<impl Buf, warp::Error>> + Unpin,
) -> Result<impl Reply, Rejection> {
use multihash::{Multihash, Sha2_256, Sha2_512, Sha3_512};
@ -26,22 +29,22 @@ async fn put_query<T: IpfsTypes>(
"raw" => (Codec::Raw, false),
_ => return Err(StringError::from("unknown codec").into()),
};
let (hasher, v0_hash) = match query.hash.as_deref().unwrap_or("sha2-256") {
"sha2-256" => (Sha2_256::digest as fn(&[u8]) -> Multihash, true),
"sha2-512" => (Sha2_512::digest as fn(&[u8]) -> Multihash, false),
"sha3-512" => (Sha3_512::digest as fn(&[u8]) -> Multihash, false),
_ => return Err(StringError::from("unknown hash").into()),
};
let buf = form
.next()
.await
.ok_or(InvalidMultipartFormData)?
.map_err(|_| InvalidMultipartFormData)?
.data()
.await
.ok_or(InvalidMultipartFormData)?
.map_err(|_| InvalidMultipartFormData)?;
let data = Box::from(buf.bytes());
let boundary = mime
.get_param("boundary")
.map(|v| v.to_string())
.ok_or_else(|| StringError::from("missing 'boundary' on content-type"))?;
let buf = try_only_named_multipart(&["data", "file"], 1024 * 1024, boundary, body).await?;
let data = buf.into_boxed_slice();
let digest = hasher(&data);
let cid = if v0_fmt && v0_hash {
// this is quite ugly way but apparently js-ipfs generates a v0 cid for this combination
@ -64,7 +67,8 @@ pub fn put<T: IpfsTypes>(
path!("dag" / "put")
.and(with_ipfs(ipfs))
.and(query::<PutQuery>())
.and(multipart::form())
.and(warp::header::<Mime>("content-type")) // TODO: rejects if missing
.and(warp::body::stream())
.and_then(put_query)
}