diff options
author | Ferris Tseng <ferristseng@fastmail.fm> | 2017-11-24 13:47:16 -0500 |
---|---|---|
committer | Ferris Tseng <ferristseng@fastmail.fm> | 2017-11-24 13:47:16 -0500 |
commit | 5d08948eb496e7e98add3845b0d9e9c529334421 (patch) | |
tree | c96243e54bd4da0aa657fdcdd1a38eeae64d8354 | |
parent | e231cbbf2c131e8ac912c20864dce4ec259d1867 (diff) |
finish implementing config replace call
-rw-r--r-- | ipfs-api/examples/default_config.json | 121 | ||||
-rw-r--r-- | ipfs-api/examples/replace_config.rs | 30 | ||||
-rw-r--r-- | ipfs-api/src/client.rs | 211 | ||||
-rw-r--r-- | ipfs-api/src/multipart.rs | 12 | ||||
-rw-r--r-- | ipfs-api/src/request/config.rs | 28 |
5 files changed, 290 insertions, 112 deletions
diff --git a/ipfs-api/examples/default_config.json b/ipfs-api/examples/default_config.json new file mode 100644 index 0000000..89a87f4 --- /dev/null +++ b/ipfs-api/examples/default_config.json @@ -0,0 +1,121 @@ +{ + "Identity": { + "PeerID": "QmVRF8ZnT1ootg5vSrzS4ws8W8NwzF5q5MUCzfNK6ZmYeH" + }, + "Datastore": { + "StorageMax": "10GB", + "StorageGCWatermark": 90, + "GCPeriod": "1h", + "Spec": { + "mounts": [ + { + "child": { + "path": "blocks", + "shardFunc": "/repo/flatfs/shard/v1/next-to-last/2", + "sync": true, + "type": "flatfs" + }, + "mountpoint": "/blocks", + "prefix": "flatfs.datastore", + "type": "measure" + }, + { + "child": { + "compression": "none", + "path": "datastore", + "type": "levelds" + }, + "mountpoint": "/", + "prefix": "leveldb.datastore", + "type": "measure" + } + ], + "type": "mount" + }, + "HashOnRead": false, + "BloomFilterSize": 0 + }, + "Addresses": { + "Swarm": [ + "/ip4/0.0.0.0/tcp/4001", + "/ip6/::/tcp/4001" + ], + "Announce": [], + "NoAnnounce": [], + "API": "/ip4/127.0.0.1/tcp/5001", + "Gateway": "/ip4/127.0.0.1/tcp/8080" + }, + "Mounts": { + "IPFS": "/ipfs", + "IPNS": "/ipns", + "FuseAllowOther": false + }, + "Discovery": { + "MDNS": { + "Enabled": true, + "Interval": 10 + } + }, + "Ipns": { + "RepublishPeriod": "", + "RecordLifetime": "", + "ResolveCacheSize": 128 + }, + "Bootstrap": [ + "/dnsaddr/bootstrap.libp2p.io/ipfs/QmNnooDu7bfjPFoTZYxMNLWUQJyrVwtbZg5gBMjTezGAJN", + "/dnsaddr/bootstrap.libp2p.io/ipfs/QmQCU2EcMqAqQPR2i9bChDtGNJchTbq5TbXJJ16u19uLTa", + "/dnsaddr/bootstrap.libp2p.io/ipfs/QmbLHAnMoJPWSCR5Zhtx6BHJX9KiKNN6tpvbUcqanj75Nb", + "/dnsaddr/bootstrap.libp2p.io/ipfs/QmcZf59bWwK5XFi76CZX8cbJ4BhTzzA3gU1ZjYZcYW3dwt", + "/ip4/104.131.131.82/tcp/4001/ipfs/QmaCpDMGvV2BGHeYERUEnRQAwe3N8SzbUtfsmvsqQLuvuJ", + "/ip4/104.236.179.241/tcp/4001/ipfs/QmSoLPppuBtQSGwKDZT2M73ULpjvfd3aZ6ha4oFGL1KrGM", + "/ip4/128.199.219.111/tcp/4001/ipfs/QmSoLSafTMBsPKadTEgaXctDQVcqN88CNLHXMkTNwMKPnu", + "/ip4/104.236.76.40/tcp/4001/ipfs/QmSoLV4Bbm51jM9C4gDYZQ9Cy3U6aXMJDAbzgu2fzaDs64", + "/ip4/178.62.158.247/tcp/4001/ipfs/QmSoLer265NRgSp2LA3dPaeykiS1J6DifTC88f5uVQKNAd", + "/ip6/2604:a880:1:20::203:d001/tcp/4001/ipfs/QmSoLPppuBtQSGwKDZT2M73ULpjvfd3aZ6ha4oFGL1KrGM", + "/ip6/2400:6180:0:d0::151:6001/tcp/4001/ipfs/QmSoLSafTMBsPKadTEgaXctDQVcqN88CNLHXMkTNwMKPnu", + "/ip6/2604:a880:800:10::4a:5001/tcp/4001/ipfs/QmSoLV4Bbm51jM9C4gDYZQ9Cy3U6aXMJDAbzgu2fzaDs64", + "/ip6/2a03:b0c0:0:1010::23:1001/tcp/4001/ipfs/QmSoLer265NRgSp2LA3dPaeykiS1J6DifTC88f5uVQKNAd" + ], + "Gateway": { + "HTTPHeaders": { + "Access-Control-Allow-Headers": [ + "X-Requested-With", + "Range" + ], + "Access-Control-Allow-Methods": [ + "GET" + ], + "Access-Control-Allow-Origin": [ + "*" + ] + }, + "RootRedirect": "", + "Writable": false, + "PathPrefixes": [] + }, + "API": { + "HTTPHeaders": null + }, + "Swarm": { + "AddrFilters": null, + "DisableBandwidthMetrics": false, + "DisableNatPortMap": false, + "DisableRelay": false, + "EnableRelayHop": false, + "ConnMgr": { + "Type": "basic", + "LowWater": 600, + "HighWater": 900, + "GracePeriod": "20s" + } + }, + "Reprovider": { + "Interval": "12h", + "Strategy": "all" + }, + "Experimental": { + "FilestoreEnabled": false, + "ShardingEnabled": false, + "Libp2pStreamMounting": false + } +} diff --git a/ipfs-api/examples/replace_config.rs b/ipfs-api/examples/replace_config.rs new file mode 100644 index 0000000..e66c920 --- /dev/null +++ b/ipfs-api/examples/replace_config.rs @@ -0,0 +1,30 @@ +// Copyright 2017 rust-ipfs-api Developers +// +// Licensed under the Apache License, Version 2.0, <LICENSE-APACHE or +// http://apache.org/licenses/LICENSE-2.0> or the MIT license <LICENSE-MIT or +// http://opensource.org/licenses/MIT>, at your option. This file may not be +// copied, modified, or distributed except according to those terms. +// + +extern crate ipfs_api; +extern crate tokio_core; + +use ipfs_api::IpfsClient; +use std::io::Cursor; +use tokio_core::reactor::Core; + +// Creates an Ipfs client, and replaces the config file with the default one. +// +fn main() { + println!("note: this must be run in the root of the project repository"); + println!("connecting to localhost:5001..."); + + let mut core = Core::new().expect("expected event loop"); + let client = IpfsClient::default(&core.handle()); + let default_config = include_str!("default_config.json"); + let req = client.config_replace(Cursor::new(default_config)); + + core.run(req).expect("expected a valid response"); + + println!("replaced file"); +} diff --git a/ipfs-api/src/client.rs b/ipfs-api/src/client.rs index 53c2663..a0c8ec1 100644 --- a/ipfs-api/src/client.rs +++ b/ipfs-api/src/client.rs @@ -73,7 +73,11 @@ impl IpfsClient { /// Builds the url for an api call. /// - fn build_base_request<Req>(&self, req: &Req) -> Result<Request<multipart::Body>, Error> + fn build_base_request<Req>( + &self, + req: &Req, + form: Option<multipart::Form>, + ) -> Result<Request<multipart::Body>, Error> where Req: ApiRequest + Serialize, { @@ -85,7 +89,15 @@ impl IpfsClient { ); url.parse::<Uri>() - .map(|url| Request::new(Method::Get, url)) + .map(|url| { + let mut req = Request::new(Method::Get, url); + + if let Some(mut form) = form { + form.set_body(&mut req); + } + + req + }) .map_err(From::from) } @@ -190,11 +202,15 @@ impl IpfsClient { /// Generates a request, and returns the unprocessed response future. /// - fn request_raw<Req>(&self, req: &Req) -> AsyncResponse<(StatusCode, Chunk)> + fn request_raw<Req>( + &self, + req: &Req, + form: Option<multipart::Form>, + ) -> AsyncResponse<(StatusCode, Chunk)> where Req: ApiRequest + Serialize, { - let res = self.build_base_request(req) + let res = self.build_base_request(req, form) .map(|req| self.send_request(req)) .into_future() .flatten(); @@ -205,12 +221,12 @@ impl IpfsClient { /// Generic method for making a request to the Ipfs server, and getting /// a deserializable response. /// - fn request<Req, Res>(&self, req: &Req) -> AsyncResponse<Res> + fn request<Req, Res>(&self, req: &Req, form: Option<multipart::Form>) -> AsyncResponse<Res> where Req: ApiRequest + Serialize, for<'de> Res: 'static + Deserialize<'de>, { - let res = self.build_base_request(req) + let res = self.build_base_request(req, form) .map(|req| self.send_request_json(req)) .into_future() .flatten(); @@ -219,32 +235,13 @@ impl IpfsClient { } /// Generic method for making a request to the Ipfs server, and getting - /// a deserializable response. - /// - fn request_with_body<Req, Res>(&self, form: multipart::Form, req: &Req) -> AsyncResponse<Res> - where - Req: ApiRequest + Serialize, - for<'de> Res: 'static + Deserialize<'de>, - { - let res = self.build_base_request(req) - .map(move |mut req| { - form.set_body(&mut req); - self.send_request_json(req) - }) - .into_future() - .flatten(); - - Box::new(res) - } - - /// Generic method for making a request to the Ipfs server, and getting /// back a response with no body. /// - fn request_empty<Req>(&self, req: &Req) -> AsyncResponse<()> + fn request_empty<Req>(&self, req: &Req, form: Option<multipart::Form>) -> AsyncResponse<()> where Req: ApiRequest + Serialize, { - let res = self.request_raw(req).and_then( + let res = self.request_raw(req, form).and_then( |(status, chunk)| match status { StatusCode::Ok => Ok(()), _ => Err(Self::build_error_from_body(chunk)), @@ -257,11 +254,11 @@ impl IpfsClient { /// Generic method for making a request to the Ipfs server, and getting /// back raw bytes. /// - fn request_bytes<Req>(&self, req: &Req) -> AsyncResponse<Vec<u8>> + fn request_bytes<Req>(&self, req: &Req, form: Option<multipart::Form>) -> AsyncResponse<Vec<u8>> where Req: ApiRequest + Serialize, { - let res = self.request_raw(req).and_then( + let res = self.request_raw(req, form).and_then( |(status, chunk)| match status { StatusCode::Ok => Ok(chunk.to_vec()), _ => Err(Self::build_error_from_body(chunk)), @@ -274,11 +271,11 @@ impl IpfsClient { /// Generic method for making a request to the Ipfs server, and getting /// back a raw String response. /// - fn request_string<Req>(&self, req: &Req) -> AsyncResponse<String> + fn request_string<Req>(&self, req: &Req, form: Option<multipart::Form>) -> AsyncResponse<String> where Req: ApiRequest + Serialize, { - let res = self.request_raw(req).and_then( + let res = self.request_raw(req, form).and_then( |(status, chunk)| match status { StatusCode::Ok => String::from_utf8(chunk.to_vec()).map_err(From::from), _ => Err(Self::build_error_from_body(chunk)), @@ -291,12 +288,16 @@ impl IpfsClient { /// Generic method to return a streaming response of deserialized json /// objects delineated by new line separators. /// - fn request_stream<Req, Res>(&self, req: &Req) -> AsyncStreamResponse<Res> + fn request_stream<Req, Res>( + &self, + req: &Req, + form: Option<multipart::Form>, + ) -> AsyncStreamResponse<Res> where Req: ApiRequest + Serialize, for<'de> Res: 'static + Deserialize<'de>, { - let res = self.build_base_request(req) + let res = self.build_base_request(req, form) .map(|req| self.client.request(req).from_err()) .into_future() .flatten() @@ -321,28 +322,28 @@ impl IpfsClient { form.add_reader("path", data); - self.request_with_body(form, &request::Add) + self.request(&request::Add, Some(form)) } /// Returns the current ledger for a peer. /// #[inline] pub fn bitswap_ledger(&self, peer: &str) -> AsyncResponse<response::BitswapLedgerResponse> { - self.request(&request::BitswapLedger { peer }) + self.request(&request::BitswapLedger { peer }, None) } /// Returns some stats about the bitswap agent. /// #[inline] pub fn bitswap_stat(&self) -> AsyncResponse<response::BitswapStatResponse> { - self.request(&request::BitswapStat) + self.request(&request::BitswapStat, None) } /// Remove a given block from your wantlist. /// #[inline] pub fn bitswap_unwant(&self, key: &str) -> AsyncResponse<response::BitswapUnwantResponse> { - self.request_empty(&request::BitswapUnwant { key }) + self.request_empty(&request::BitswapUnwant { key }, None) } /// Shows blocks on the wantlist for you or the specified peer. @@ -352,14 +353,14 @@ impl IpfsClient { &self, peer: Option<&str>, ) -> AsyncResponse<response::BitswapWantlistResponse> { - self.request(&request::BitswapWantlist { peer }) + self.request(&request::BitswapWantlist { peer }, None) } /// Gets a raw IPFS block. /// #[inline] pub fn block_get(&self, hash: &str) -> AsyncResponse<response::BlockGetResponse> { - self.request_bytes(&request::BlockGet { hash }) + self.request_bytes(&request::BlockGet { hash }, None) } // TODO @@ -370,61 +371,71 @@ impl IpfsClient { /// #[inline] pub fn block_rm(&self, hash: &str) -> AsyncResponse<response::BlockRmResponse> { - self.request(&request::BlockRm { hash }) + self.request(&request::BlockRm { hash }, None) } /// Prints information about a raw IPFS block. /// #[inline] pub fn block_stat(&self, hash: &str) -> AsyncResponse<response::BlockStatResponse> { - self.request(&request::BlockStat { hash }) + self.request(&request::BlockStat { hash }, None) } /// Add default peers to the bootstrap list. /// #[inline] pub fn bootstrap_add_default(&self) -> AsyncResponse<response::BootstrapAddDefaultResponse> { - self.request(&request::BootstrapAddDefault) + self.request(&request::BootstrapAddDefault, None) } /// Lists peers in bootstrap list. /// #[inline] pub fn bootstrap_list(&self) -> AsyncResponse<response::BootstrapListResponse> { - self.request(&request::BootstrapList) + self.request(&request::BootstrapList, None) } /// Removes all peers in bootstrap list. /// #[inline] pub fn bootstrap_rm_all(&self) -> AsyncResponse<response::BootstrapRmAllResponse> { - self.request(&request::BootstrapRmAll) + self.request(&request::BootstrapRmAll, None) } /// Returns the contents of an Ipfs object. /// #[inline] pub fn cat(&self, path: &str) -> AsyncResponse<response::CatResponse> { - self.request_bytes(&request::Cat { path }) + self.request_bytes(&request::Cat { path }, None) } /// List available commands that the server accepts. /// #[inline] pub fn commands(&self) -> AsyncResponse<response::CommandsResponse> { - self.request(&request::Commands) + self.request(&request::Commands, None) } /// Opens the config file for editing (on the server). /// #[inline] pub fn config_edit(&self) -> AsyncResponse<response::ConfigEditResponse> { - self.request(&request::ConfigEdit) + self.request(&request::ConfigEdit, None) } - // TODO - // pub fn config_replace(&self, ...) -> AsyncResponse<response::ConfigReplaceResponse> { - // } + /// Replace the config file. + /// + #[inline] + pub fn config_replace<R>(&self, data: R) -> AsyncResponse<response::ConfigReplaceResponse> + where + R: 'static + Read + Send, + { + let mut form = multipart::Form::default(); + + form.add_reader("file", data); + + self.request_empty(&request::ConfigReplace, Some(form)) + } /// Show the current config of the server. /// @@ -432,14 +443,14 @@ impl IpfsClient { /// #[inline] pub fn config_show(&self) -> AsyncResponse<response::ConfigShowResponse> { - self.request_string(&request::ConfigShow) + self.request_string(&request::ConfigShow, None) } /// Returns information about a dag node in Ipfs. /// #[inline] pub fn dag_get(&self, path: &str) -> AsyncResponse<response::DagGetResponse> { - self.request(&request::DagGet { path }) + self.request(&request::DagGet { path }, None) } // TODO @@ -450,49 +461,49 @@ impl IpfsClient { /// #[inline] pub fn dht_findpeer(&self, peer: &str) -> AsyncStreamResponse<response::DhtFindPeerResponse> { - self.request_stream(&request::DhtFindPeer { peer }) + self.request_stream(&request::DhtFindPeer { peer }, None) } /// Find peers in the DHT that can provide a specific value given a key. /// #[inline] pub fn dht_findprovs(&self, key: &str) -> AsyncStreamResponse<response::DhtFindProvsResponse> { - self.request_stream(&request::DhtFindProvs { key }) + self.request_stream(&request::DhtFindProvs { key }, None) } /// Query the DHT for a given key. /// #[inline] pub fn dht_get(&self, key: &str) -> AsyncStreamResponse<response::DhtGetResponse> { - self.request_stream(&request::DhtGet { key }) + self.request_stream(&request::DhtGet { key }, None) } /// Announce to the network that you are providing a given value. /// #[inline] pub fn dht_provide(&self, key: &str) -> AsyncResponse<response::DhtProvideResponse> { - self.request(&request::DhtProvide { key }) + self.request(&request::DhtProvide { key }, None) } /// Write a key/value pair to the DHT. /// #[inline] pub fn dht_put(&self, key: &str, value: &str) -> AsyncStreamResponse<response::DhtPutResponse> { - self.request_stream(&request::DhtPut { key, value }) + self.request_stream(&request::DhtPut { key, value }, None) } /// Find the closest peer given the peer ID by querying the DHT. /// #[inline] pub fn dht_query(&self, peer: &str) -> AsyncStreamResponse<response::DhtQueryResponse> { - self.request_stream(&request::DhtQuery { peer }) + self.request_stream(&request::DhtQuery { peer }, None) } /// Clear inactive requests from the log. /// #[inline] pub fn diag_cmds_clear(&self) -> AsyncResponse<response::DiagCmdsClearResponse> { - self.request_empty(&request::DiagCmdsClear) + self.request_empty(&request::DiagCmdsClear, None) } /// Set how long to keep inactive requests in the log. @@ -502,7 +513,7 @@ impl IpfsClient { &self, time: &str, ) -> AsyncResponse<response::DiagCmdsSetTimeResponse> { - self.request_empty(&request::DiagCmdsSetTime { time }) + self.request_empty(&request::DiagCmdsSetTime { time }, None) } /// Print system diagnostic information. @@ -513,42 +524,42 @@ impl IpfsClient { /// #[inline] pub fn diag_sys(&self) -> AsyncResponse<response::DiagSysResponse> { - self.request_string(&request::DiagSys) + self.request_string(&request::DiagSys, None) } /// Resolve DNS link. /// #[inline] pub fn dns(&self, link: &str, recursive: bool) -> AsyncResponse<response::DnsResponse> { - self.request(&request::Dns { link, recursive }) + self.request(&request::Dns { link, recursive }, None) } /// List directory for Unix filesystem objects. /// #[inline] pub fn file_ls(&self, path: &str) -> AsyncResponse<response::FileLsResponse> { - self.request(&request::FileLs { path }) + self.request(&request::FileLs { path }, None) } /// Copy files into MFS. /// #[inline] pub fn files_cp(&self, path: &str, dest: &str) -> AsyncResponse<response::FilesCpResponse> { - self.request_empty(&request::FilesCp { path, dest }) + self.request_empty(&request::FilesCp { path, dest }, None) } /// Flush a path's data to disk. /// #[inline] pub fn files_flush(&self, path: Option<&str>) -> AsyncResponse<response::FilesFlushResponse> { - self.request_empty(&request::FilesFlush { path }) + self.request_empty(&request::FilesFlush { path }, None) } /// List directories in MFS. /// #[inline] pub fn files_ls(&self, path: Option<&str>) -> AsyncResponse<response::FilesLsResponse> { - self.request(&request::FilesLs { path }) + self.request(&request::FilesLs { path }, None) } /// Make directories in MFS. @@ -559,21 +570,21 @@ impl IpfsClient { path: &str, parents: bool, ) -> AsyncResponse<response::FilesMkdirResponse> { - self.request_empty(&request::FilesMkdir { path, parents }) + self.request_empty(&request::FilesMkdir { path, parents }, None) } /// Copy files into MFS. /// #[inline] pub fn files_mv(&self, path: &str, dest: &str) -> AsyncResponse<response::FilesMvResponse> { - self.request_empty(&request::FilesMv { path, dest }) + self.request_empty(&request::FilesMv { path, dest }, None) } /// Read a file in MFS. /// #[inline] pub fn files_read(&self, path: &str) -> AsyncResponse<response::FilesReadResponse> { - self.request_bytes(&request::FilesRead { path }) + self.request_bytes(&request::FilesRead { path }, None) } /// Remove a file in MFS. @@ -584,14 +595,14 @@ impl IpfsClient { path: &str, recursive: bool, ) -> AsyncResponse<response::FilesRmResponse> { - self.request_empty(&request::FilesRm { path, recursive }) + self.request_empty(&request::FilesRm { path, recursive }, None) } /// Display a file's status in MDFS. /// #[inline] pub fn files_stat(&self, path: &str) -> AsyncResponse<response::FilesStatResponse> { - self.request(&request::FilesStat { path }) + self.request(&request::FilesStat { path }, None) } // TODO @@ -602,28 +613,28 @@ impl IpfsClient { /// #[inline] pub fn filestore_dups(&self) -> AsyncStreamResponse<response::FilestoreDupsResponse> { - self.request_stream(&request::FilestoreDups) + self.request_stream(&request::FilestoreDups, None) } /// List objects in filestore. /// #[inline] pub fn filestore_ls(&self) -> AsyncStreamResponse<response::FilestoreLsResponse> { - self.request_stream(&request::FilestoreLs) + self.request_stream(&request::FilestoreLs, None) } /// Verify objects in filestore. /// #[inline] pub fn filestore_verify(&self) -> AsyncStreamResponse<response::FilestoreVerifyResponse> { - self.request_stream(&request::FilestoreVerify) + self.request_stream(&request::FilestoreVerify, None) } /// Download Ipfs object. /// #[inline] pub fn get(&self, path: &str) -> AsyncResponse<response::GetResponse> { - self.request_bytes(&request::Get { path }) + self.request_bytes(&request::Get { path }, None) } /// Returns information about a peer. @@ -632,7 +643,7 @@ impl IpfsClient { /// #[inline] pub fn id(&self, peer: Option<&str>) -> AsyncResponse<response::IdResponse> { - self.request(&request::Id { peer }) + self.request(&request::Id { peer }, None) } /// Create a new keypair. @@ -644,14 +655,14 @@ impl IpfsClient { kind: request::KeyType, size: Option<i32>, ) -> AsyncResponse<response::KeyGenResponse> { - self.request(&request::KeyGen { name, kind, size }) + self.request(&request::KeyGen { name, kind, size }, None) } /// List all local keypairs. /// #[inline] pub fn key_list(&self) -> AsyncResponse<response::KeyListResponse> { - self.request(&request::KeyList) + self.request(&request::KeyList, None) } /// Change the logging level for a logger. @@ -662,20 +673,20 @@ impl IpfsClient { logger: request::Logger, level: request::LoggingLevel, ) -> AsyncResponse<response::LogLevelResponse> { - self.request(&request::LogLevel { logger, level }) + self.request(&request::LogLevel { logger, level }, None) } /// List all logging subsystems. /// #[inline] pub fn log_ls(&self) -> AsyncResponse<response::LogLsResponse> { - self.request(&request::LogLs) + self.request(&request::LogLs, None) } /// Read the event log. /// pub fn log_tail(&self) -> AsyncStreamResponse<String> { - let res = self.build_base_request(&request::LogTail) + let res = self.build_base_request(&request::LogTail, None) .map(|req| self.client.request(req).from_err()) .into_future() .flatten() @@ -689,7 +700,7 @@ impl IpfsClient { /// #[inline] pub fn ls(&self, path: Option<&str>) -> AsyncResponse<response::LsResponse> { - self.request(&request::Ls { path }) + self.request(&request::Ls { path }, None) } /// Returns the diff of two Ipfs objects. @@ -700,28 +711,28 @@ impl IpfsClient { key0: &str, key1: &str, ) -> AsyncResponse<response::ObjectDiffResponse> { - self.request(&request::ObjectDiff { key0, key1 }) + self.request(&request::ObjectDiff { key0, key1 }, None) } /// Returns the data in an object. /// #[inline] pub fn object_get(&self, key: &str) -> AsyncResponse<response::ObjectGetResponse> { - self.request(&request::ObjectGet { key }) + self.request(&request::ObjectGet { key }, None) } /// Returns the links that an object points to. /// #[inline] pub fn object_links(&self, key: &str) -> AsyncResponse<response::ObjectLinksResponse> { - self.request(&request::ObjectLinks { key }) + self.request(&request::ObjectLinks { key }, None) } /// Returns the stats for an object. /// #[inline] pub fn object_stat(&self, key: &str) -> AsyncResponse<response::ObjectStatResponse> { - self.request(&request::ObjectStat { key }) + self.request(&request::ObjectStat { key }, None) } /// Returns a list of pinned objects in local storage. @@ -732,7 +743,7 @@ impl IpfsClient { key: Option<&str>, typ: Option<&str>, ) -> AsyncResponse<response::PinLsResponse> { - self.request(&request::PinLs { key, typ }) + self.request(&request::PinLs { key, typ }, None) } /// Removes a pinned object from local storage. @@ -743,7 +754,7 @@ impl IpfsClient { key: &str, recursive: Option<bool>, ) -> AsyncResponse<response::PinRmResponse> { - self.request(&request::PinRm { key, recursive }) + self.request(&request::PinRm { key, recursive }, None) } /// Pings a peer. @@ -754,14 +765,14 @@ impl IpfsClient { peer: &str, count: Option<usize>, ) -> AsyncStreamResponse<response::PingResponse> { - self.request_stream(&request::Ping { peer, count }) + self.request_stream(&request::Ping { peer, count }, None) } /// List subscribed pubsub topics. /// #[inline] pub fn pubsub_ls(&self) -> AsyncResponse<response::PubsubLsResponse> { - self.request(&request::PubsubLs) + self.request(&request::PubsubLs, None) } /// List peers that are being published to. @@ -771,7 +782,7 @@ impl IpfsClient { &self, topic: Option<&str>, ) -> AsyncResponse<response::PubsubPeersResponse> { - self.request(&request::PubsubPeers { topic }) + self.request(&request::PubsubPeers { topic }, None) } /// Publish a message to a topic. @@ -782,7 +793,7 @@ impl IpfsClient { topic: &str, payload: &str, ) -> AsyncResponse<response::PubsubPubResponse> { - self.request_empty(&request::PubsubPub { topic, payload }) + self.request_empty(&request::PubsubPub { topic, payload }, None) } /// Subscribes to a pubsub topic. @@ -793,55 +804,55 @@ impl IpfsClient { topic: &str, discover: Option<bool>, ) -> AsyncStreamResponse<response::PubsubSubResponse> { - self.request_stream(&request::PubsubSub { topic, discover }) + self.request_stream(&request::PubsubSub { topic, discover }, None) } /// Gets a list of local references. /// #[inline] pub fn refs_local(&self) -> AsyncStreamResponse<response::RefsLocalResponse> { - self.request_stream(&request::RefsLocal) + self.request_stream(&request::RefsLocal, None) } /// Returns bitswap stats. /// #[inline] pub fn stats_bitswap(&self) -> AsyncResponse<response::StatsBitswapResponse> { - self.request(&request::StatsBitswap) + self.request(&request::StatsBitswap, None) } /// Returns bandwidth stats. /// #[inline] pub fn stats_bw(&self) -> AsyncResponse<response::StatsBwResponse> { - self.request(&request::StatsBw) + self.request(&request::StatsBw, None) } /// Returns repo stats. /// #[inline] pub fn stats_repo(&self) -> AsyncResponse<response::StatsRepoResponse> { - self.request(&request::StatsRepo) + self.request(&request::StatsRepo, None) } /// Return a list of local addresses. /// #[inline] pub fn swarm_addrs_local(&self) -> AsyncResponse<response::SwarmAddrsLocalResponse> { - self.request(&request::SwarmAddrsLocal) + self.request(&request::SwarmAddrsLocal, None) } /// Return a list of peers with open connections. /// #[inline] pub fn swarm_peers(&self) -> AsyncResponse<response::SwarmPeersResponse> { - self.request(&request::SwarmPeers) + self.request(&request::SwarmPeers, None) } /// Returns information about the Ipfs server version. /// #[inline] pub fn version(&self) -> AsyncResponse<response::VersionResponse> { - self.request(&request::Version) + self.request(&request::Version, None) } } diff --git a/ipfs-api/src/multipart.rs b/ipfs-api/src/multipart.rs index 1ffac62..36b0c5a 100644 --- a/ipfs-api/src/multipart.rs +++ b/ipfs-api/src/multipart.rs @@ -134,10 +134,14 @@ impl Stream for Body { } let num = if let Some(ref mut read) = self.current { - // TODO: This should not write more bytes that are remaining in - // the buffer. - // - io::copy(read, &mut writer)? + let mut buf = writer.get_mut(); + unsafe { + let num = read.read(&mut buf.bytes_mut())?; + + buf.advance_mut(num); + + num + } } else { 0 }; diff --git a/ipfs-api/src/request/config.rs b/ipfs-api/src/request/config.rs index cdbd835..d018056 100644 --- a/ipfs-api/src/request/config.rs +++ b/ipfs-api/src/request/config.rs @@ -9,25 +9,37 @@ use request::ApiRequest; -pub struct ConfigShow; +pub struct ConfigEdit; -impl_skip_serialize!(ConfigShow); +impl_skip_serialize!(ConfigEdit); -impl ApiRequest for ConfigShow { +impl ApiRequest for ConfigEdit { #[inline] fn path() -> &'static str { - "/config/show" + "/config/edit" } } -pub struct ConfigEdit; +pub struct ConfigReplace; -impl_skip_serialize!(ConfigEdit); +impl_skip_serialize!(ConfigReplace); -impl ApiRequest for ConfigEdit { +impl ApiRequest for ConfigReplace { #[inline] fn path() -> &'static str { - "/config/edit" + "/config/replace" + } +} + + +pub struct ConfigShow; + +impl_skip_serialize!(ConfigShow); + +impl ApiRequest for ConfigShow { + #[inline] + fn path() -> &'static str { + "/config/show" } } |