Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit effee5a

Browse files
leoyvensJannis Pohlmann
authored andcommitted
graph: Limit max ipfs file size through env var
1 parent f015989 commit effee5a

File tree

1 file changed

+44
-11
lines changed

1 file changed

+44
-11
lines changed
Lines changed: 44 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,12 @@
11
use data::subgraph::Link;
22
use failure;
33
use ipfs_api;
4+
use std::env;
5+
use std::str::FromStr;
6+
use std::time::Duration;
47
use tokio::prelude::*;
58

6-
use std::time::Duration;
9+
const MAX_IPFS_FILE_BYTES_ENV_VAR: &str = "GRAPH_MAX_IPFS_FILE_BYTES";
710

811
/// Resolves links to subgraph manifests and resources referenced by them.
912
pub trait LinkResolver: Send + Sync + 'static {
@@ -12,18 +15,48 @@ pub trait LinkResolver: Send + Sync + 'static {
1215
}
1316

1417
impl LinkResolver for ipfs_api::IpfsClient {
15-
/// Currently supports only links of the form `/ipfs/ipfs_hash`
18+
/// Supports links of the form `/ipfs/ipfs_hash` or just `ipfs_hash`.
1619
fn cat(&self, link: &Link) -> Box<Future<Item = Vec<u8>, Error = failure::Error> + Send> {
1720
// Discard the `/ipfs/` prefix (if present) to get the hash.
18-
let path = link.link.trim_left_matches("/ipfs/");
21+
let path = link.link.trim_left_matches("/ipfs/").to_owned();
22+
let max_file_bytes = env::var(MAX_IPFS_FILE_BYTES_ENV_VAR)
23+
.ok()
24+
.and_then(|s| u64::from_str(&s).ok());
25+
26+
let cat = self
27+
.cat(&path)
28+
.concat2()
29+
// Guard against IPFS unresponsiveness.
30+
.timeout(Duration::from_secs(10))
31+
.map(|x| x.to_vec())
32+
.map_err(|e| failure::err_msg(e.to_string()));
1933

20-
Box::new(
21-
self.cat(path)
22-
.concat2()
23-
// Guard against IPFS unresponsiveness.
24-
.timeout(Duration::from_secs(10))
25-
.map(|x| x.to_vec())
26-
.map_err(|e| failure::err_msg(e.to_string())),
27-
)
34+
match max_file_bytes {
35+
Some(max_bytes) => Box::new(
36+
self.object_stat(&path)
37+
.map_err(|e| failure::err_msg(e.to_string()))
38+
.and_then(move |stat| match stat.cumulative_size > max_bytes {
39+
false => Ok(()),
40+
true => Err(format_err!("Ipfs file {} is too large", path)),
41+
})
42+
.and_then(|()| cat),
43+
),
44+
None => Box::new(cat),
45+
}
2846
}
2947
}
48+
49+
#[test]
50+
fn max_file_size() {
51+
env::set_var(MAX_IPFS_FILE_BYTES_ENV_VAR, "200");
52+
let file: &[u8] = &[0u8; 201];
53+
let client = ipfs_api::IpfsClient::default();
54+
55+
let mut runtime = tokio::runtime::Runtime::new().unwrap();
56+
let link = runtime.block_on(client.add(file)).unwrap().hash;
57+
let err = runtime
58+
.block_on(LinkResolver::cat(&client, &Link { link: link.clone() }))
59+
.unwrap_err();
60+
env::remove_var(MAX_IPFS_FILE_BYTES_ENV_VAR);
61+
assert_eq!(err.to_string(), format!("Ipfs file {} is too large", link));
62+
}

0 commit comments

Comments
 (0)