pub struct HttpClientBuilder { /* private fields */ }Implementations§
Source§impl HttpClientBuilder
impl HttpClientBuilder
pub fn new() -> Self
Sourcepub fn default_headers(self, headers: HashMap<String, String>) -> Self
pub fn default_headers(self, headers: HashMap<String, String>) -> Self
Examples found in repository?
examples/http_client.rs (line 41)
4fn main() -> Result<(), Box<dyn std::error::Error>> {
5 println!("====================================");
6 println!("HTTP v2 Client Demo");
7 println!("====================================");
8
9 println!("\n1. GET request:");
10 match get("https://httpbin.org/get").send() {
11 Ok(response) => {
12 println!("GET Status: {}", response.status());
13 println!("GET Success: {}", response.is_success());
14 }
15 Err(e) => println!("GET Error: {}", e),
16 }
17
18 println!("\n2. POST with JSON:");
19 let json_data = serde_json::json!({
20 "name": "Blockless SDK",
21 "version": "2.0",
22 "api_style": "reqwest-like"
23 });
24 match post("https://httpbin.org/post").json(&json_data)?.send() {
25 Ok(response) => {
26 println!("POST JSON Status: {}", response.status());
27 if let Ok(response_json) = response.json::<serde_json::Value>() {
28 if let Some(received_json) = response_json.get("json") {
29 println!("Received JSON: {}", received_json);
30 }
31 }
32 }
33 Err(e) => println!("POST JSON Error: {}", e),
34 }
35
36 println!("\n3. Client instance with default configuration:");
37 let mut default_headers = HashMap::new();
38 default_headers.insert("User-Agent".to_string(), "Blockless-SDK/2.0".to_string());
39 default_headers.insert("Accept".to_string(), "application/json".to_string());
40 let client = HttpClient::builder()
41 .default_headers(default_headers)
42 .timeout(10000)
43 .build();
44 match client
45 .get("https://httpbin.org/get")
46 .query("search", "blockless")
47 .query("limit", "10")
48 .query("format", "json")
49 .send()
50 {
51 Ok(response) => {
52 println!("Client GET Status: {}", response.status());
53 if let Ok(json_data) = response.json::<serde_json::Value>() {
54 if let Some(args) = json_data.get("args") {
55 println!("Query params: {}", args);
56 }
57 }
58 }
59 Err(e) => println!("Client GET Error: {}", e),
60 }
61
62 println!("\n4. Authentication examples:");
63 match client
64 .get("https://httpbin.org/basic-auth/user/pass")
65 .basic_auth("user", "pass")
66 .send()
67 {
68 Ok(response) => {
69 println!("Basic auth status: {}", response.status());
70 if let Ok(json_data) = response.json::<serde_json::Value>() {
71 println!("Authenticated: {:?}", json_data.get("authenticated"));
72 }
73 }
74 Err(e) => println!("Basic auth error: {}", e),
75 }
76
77 match client
78 .get("https://httpbin.org/bearer")
79 .bearer_auth("test-token-12345")
80 .send()
81 {
82 Ok(response) => {
83 println!("Bearer auth status: {}", response.status());
84 if let Ok(json_data) = response.json::<serde_json::Value>() {
85 println!("Token received: {:?}", json_data.get("token"));
86 }
87 }
88 Err(e) => println!("Bearer auth error: {}", e),
89 }
90
91 println!("\n5. Different request body types:");
92 let mut form_data = HashMap::new();
93 form_data.insert("name".to_string(), "Blockless".to_string());
94 form_data.insert("type".to_string(), "distributed computing".to_string());
95 match client
96 .post("https://httpbin.org/post")
97 .form(form_data)
98 .send()
99 {
100 Ok(response) => {
101 println!("Form POST Status: {}", response.status());
102 if let Ok(json_data) = response.json::<serde_json::Value>() {
103 if let Some(form) = json_data.get("form") {
104 println!("Form data received: {}", form);
105 }
106 }
107 }
108 Err(e) => println!("Form POST Error: {}", e),
109 }
110
111 println!("\n6. Multipart form with file upload:");
112 let multipart_fields = vec![
113 MultipartField::text("description", "SDK test file"),
114 MultipartField::file(
115 "upload",
116 b"Hello from Blockless SDK v2!".to_vec(),
117 "hello.txt",
118 Some("text/plain".to_string()),
119 ),
120 ];
121 match client
122 .post("https://httpbin.org/post")
123 .multipart(multipart_fields)
124 .send()
125 {
126 Ok(response) => {
127 println!("Multipart POST Status: {}", response.status());
128 if let Ok(json_data) = response.json::<serde_json::Value>() {
129 if let Some(files) = json_data.get("files") {
130 println!("Files uploaded: {}", files);
131 }
132 }
133 }
134 Err(e) => println!("Multipart POST Error: {}", e),
135 }
136
137 println!("\n7. Binary data:");
138 let binary_data = vec![0x48, 0x65, 0x6c, 0x6c, 0x6f]; // "Hello" in bytes
139 match client
140 .post("https://httpbin.org/post")
141 .header("Content-Type", "application/octet-stream")
142 .body_bytes(binary_data)
143 .send()
144 {
145 Ok(response) => {
146 println!("Binary POST Status: {}", response.status());
147 }
148 Err(e) => println!("Binary POST Error: {}", e),
149 }
150
151 println!("\n8. Advanced request building:");
152 match client
153 .put("https://httpbin.org/put")
154 .header("X-Custom-Header", "custom-value")
155 .header("X-API-Version", "2.0")
156 .query("action", "update")
157 .query("id", "12345")
158 .timeout(5000)
159 .body("Updated data")
160 .send()
161 {
162 Ok(response) => {
163 println!("PUT Status: {}", response.status());
164 if let Ok(json_data) = response.json::<serde_json::Value>() {
165 if let Some(headers) = json_data.get("headers") {
166 println!("Custom headers received: {}", headers);
167 }
168 }
169 }
170 Err(e) => println!("PUT Error: {}", e),
171 }
172
173 println!("\nDemo completed 🚀");
174 Ok(())
175}Sourcepub fn timeout(self, timeout: u32) -> Self
pub fn timeout(self, timeout: u32) -> Self
Examples found in repository?
examples/http_client.rs (line 42)
4fn main() -> Result<(), Box<dyn std::error::Error>> {
5 println!("====================================");
6 println!("HTTP v2 Client Demo");
7 println!("====================================");
8
9 println!("\n1. GET request:");
10 match get("https://httpbin.org/get").send() {
11 Ok(response) => {
12 println!("GET Status: {}", response.status());
13 println!("GET Success: {}", response.is_success());
14 }
15 Err(e) => println!("GET Error: {}", e),
16 }
17
18 println!("\n2. POST with JSON:");
19 let json_data = serde_json::json!({
20 "name": "Blockless SDK",
21 "version": "2.0",
22 "api_style": "reqwest-like"
23 });
24 match post("https://httpbin.org/post").json(&json_data)?.send() {
25 Ok(response) => {
26 println!("POST JSON Status: {}", response.status());
27 if let Ok(response_json) = response.json::<serde_json::Value>() {
28 if let Some(received_json) = response_json.get("json") {
29 println!("Received JSON: {}", received_json);
30 }
31 }
32 }
33 Err(e) => println!("POST JSON Error: {}", e),
34 }
35
36 println!("\n3. Client instance with default configuration:");
37 let mut default_headers = HashMap::new();
38 default_headers.insert("User-Agent".to_string(), "Blockless-SDK/2.0".to_string());
39 default_headers.insert("Accept".to_string(), "application/json".to_string());
40 let client = HttpClient::builder()
41 .default_headers(default_headers)
42 .timeout(10000)
43 .build();
44 match client
45 .get("https://httpbin.org/get")
46 .query("search", "blockless")
47 .query("limit", "10")
48 .query("format", "json")
49 .send()
50 {
51 Ok(response) => {
52 println!("Client GET Status: {}", response.status());
53 if let Ok(json_data) = response.json::<serde_json::Value>() {
54 if let Some(args) = json_data.get("args") {
55 println!("Query params: {}", args);
56 }
57 }
58 }
59 Err(e) => println!("Client GET Error: {}", e),
60 }
61
62 println!("\n4. Authentication examples:");
63 match client
64 .get("https://httpbin.org/basic-auth/user/pass")
65 .basic_auth("user", "pass")
66 .send()
67 {
68 Ok(response) => {
69 println!("Basic auth status: {}", response.status());
70 if let Ok(json_data) = response.json::<serde_json::Value>() {
71 println!("Authenticated: {:?}", json_data.get("authenticated"));
72 }
73 }
74 Err(e) => println!("Basic auth error: {}", e),
75 }
76
77 match client
78 .get("https://httpbin.org/bearer")
79 .bearer_auth("test-token-12345")
80 .send()
81 {
82 Ok(response) => {
83 println!("Bearer auth status: {}", response.status());
84 if let Ok(json_data) = response.json::<serde_json::Value>() {
85 println!("Token received: {:?}", json_data.get("token"));
86 }
87 }
88 Err(e) => println!("Bearer auth error: {}", e),
89 }
90
91 println!("\n5. Different request body types:");
92 let mut form_data = HashMap::new();
93 form_data.insert("name".to_string(), "Blockless".to_string());
94 form_data.insert("type".to_string(), "distributed computing".to_string());
95 match client
96 .post("https://httpbin.org/post")
97 .form(form_data)
98 .send()
99 {
100 Ok(response) => {
101 println!("Form POST Status: {}", response.status());
102 if let Ok(json_data) = response.json::<serde_json::Value>() {
103 if let Some(form) = json_data.get("form") {
104 println!("Form data received: {}", form);
105 }
106 }
107 }
108 Err(e) => println!("Form POST Error: {}", e),
109 }
110
111 println!("\n6. Multipart form with file upload:");
112 let multipart_fields = vec![
113 MultipartField::text("description", "SDK test file"),
114 MultipartField::file(
115 "upload",
116 b"Hello from Blockless SDK v2!".to_vec(),
117 "hello.txt",
118 Some("text/plain".to_string()),
119 ),
120 ];
121 match client
122 .post("https://httpbin.org/post")
123 .multipart(multipart_fields)
124 .send()
125 {
126 Ok(response) => {
127 println!("Multipart POST Status: {}", response.status());
128 if let Ok(json_data) = response.json::<serde_json::Value>() {
129 if let Some(files) = json_data.get("files") {
130 println!("Files uploaded: {}", files);
131 }
132 }
133 }
134 Err(e) => println!("Multipart POST Error: {}", e),
135 }
136
137 println!("\n7. Binary data:");
138 let binary_data = vec![0x48, 0x65, 0x6c, 0x6c, 0x6f]; // "Hello" in bytes
139 match client
140 .post("https://httpbin.org/post")
141 .header("Content-Type", "application/octet-stream")
142 .body_bytes(binary_data)
143 .send()
144 {
145 Ok(response) => {
146 println!("Binary POST Status: {}", response.status());
147 }
148 Err(e) => println!("Binary POST Error: {}", e),
149 }
150
151 println!("\n8. Advanced request building:");
152 match client
153 .put("https://httpbin.org/put")
154 .header("X-Custom-Header", "custom-value")
155 .header("X-API-Version", "2.0")
156 .query("action", "update")
157 .query("id", "12345")
158 .timeout(5000)
159 .body("Updated data")
160 .send()
161 {
162 Ok(response) => {
163 println!("PUT Status: {}", response.status());
164 if let Ok(json_data) = response.json::<serde_json::Value>() {
165 if let Some(headers) = json_data.get("headers") {
166 println!("Custom headers received: {}", headers);
167 }
168 }
169 }
170 Err(e) => println!("PUT Error: {}", e),
171 }
172
173 println!("\nDemo completed 🚀");
174 Ok(())
175}More examples
examples/ipfs_api.rs (line 15)
3fn main() -> Result<(), Box<dyn std::error::Error>> {
4 println!("IPFS RPC API Demo - HTTP v2 Client");
5 println!("=================================");
6 println!("Make sure your IPFS node is running on localhost:5001");
7 println!("Docker command: docker run --rm -it --name ipfs_host -p 4001:4001 -p 4001:4001/udp -p 8080:8080 -p 5001:5001 ipfs/kubo");
8 println!("Note: If you get CORS errors, configure CORS with:");
9 println!(" docker exec ipfs_host ipfs config --json API.HTTPHeaders.Access-Control-Allow-Origin '[\"*\"]'");
10 println!(" docker exec ipfs_host ipfs config --json API.HTTPHeaders.Access-Control-Allow-Methods '[\"GET\", \"POST\", \"PUT\", \"DELETE\", \"OPTIONS\"]'");
11 println!(" docker restart ipfs_host\n");
12
13 // Create HTTP client configured for IPFS RPC API
14 let client = HttpClient::builder()
15 .timeout(30000) // 30 seconds for file operations
16 .build();
17
18 let ipfs_api_base = "http://localhost:5001/api/v0";
19
20 // Example 1: Simple POST request - Get node version
21 println!("1. GET node version (POST with no body):");
22 match client.post(format!("{}/version", ipfs_api_base)).send() {
23 Ok(response) => {
24 println!(" Status: {}", response.status());
25 if response.is_success() {
26 if let Ok(version_info) = response.json::<serde_json::Value>() {
27 println!(
28 " IPFS Version: {}",
29 version_info
30 .get("Version")
31 .and_then(|v| v.as_str())
32 .unwrap_or("unknown")
33 );
34 println!(
35 " Commit: {}",
36 version_info
37 .get("Commit")
38 .and_then(|c| c.as_str())
39 .unwrap_or("unknown")
40 );
41 }
42 }
43 }
44 Err(e) => println!(" Error: {} (Is IPFS running?)", e),
45 }
46
47 // Example 2: POST with query parameters - Get node ID
48 println!("\n2. GET node ID (POST with query parameters):");
49 match client
50 .post(format!("{}/id", ipfs_api_base))
51 .query("format", "json")
52 .send()
53 {
54 Ok(response) => {
55 println!(" Status: {}", response.status());
56 if response.is_success() {
57 if let Ok(id_info) = response.json::<serde_json::Value>() {
58 println!(
59 " Node ID: {}",
60 id_info
61 .get("ID")
62 .and_then(|id| id.as_str())
63 .unwrap_or("unknown")
64 );
65 if let Some(addresses) = id_info.get("Addresses") {
66 if let Some(addr_array) = addresses.as_array() {
67 if !addr_array.is_empty() {
68 println!(" First Address: {}", addr_array[0]);
69 }
70 }
71 }
72 }
73 }
74 }
75 Err(e) => println!(" Error: {}", e),
76 }
77
78 // Example 3: POST with multipart file upload - Add file to IPFS
79 println!("\n3. ADD file to IPFS (POST with multipart upload):");
80 let file_content = b"Hello from Blockless SDK HTTP v2 client!\nThis file was uploaded to IPFS using multipart form data.";
81 let multipart_fields = vec![MultipartField::file(
82 "file", // IPFS expects 'file' as the field name
83 file_content.to_vec(),
84 "hello-blockless.txt",
85 Some("text/plain".to_string()),
86 )];
87
88 match client
89 .post(format!("{}/add", ipfs_api_base))
90 .query("pin", "true") // Pin the file after adding
91 .multipart(multipart_fields)
92 .send()
93 {
94 Ok(response) => {
95 println!(" Status: {}", response.status());
96 if response.is_success() {
97 if let Ok(add_result) = response.json::<serde_json::Value>() {
98 let hash = add_result
99 .get("Hash")
100 .and_then(|h| h.as_str())
101 .unwrap_or("unknown");
102 let name = add_result
103 .get("Name")
104 .and_then(|n| n.as_str())
105 .unwrap_or("unknown");
106 let size = add_result
107 .get("Size")
108 .and_then(|s| s.as_str())
109 .unwrap_or("0");
110 println!(" Added file: {}", name);
111 println!(" IPFS Hash: {}", hash);
112 println!(" Size: {} bytes", size);
113
114 // Store hash for later examples
115 if hash != "unknown" {
116 demonstrate_file_operations(&client, ipfs_api_base, hash)?;
117 }
118 }
119 }
120 }
121 Err(e) => println!(" Error: {}", e),
122 }
123
124 // Example 4: Repository stats (POST with query parameters)
125 println!("\n4. GET repository statistics (POST with boolean parameters):");
126 match client
127 .post(format!("{}/repo/stat", ipfs_api_base))
128 .query("human", "true")
129 .send()
130 {
131 Ok(response) => {
132 println!(" Status: {}", response.status());
133 if response.is_success() {
134 if let Ok(repo_stats) = response.json::<serde_json::Value>() {
135 println!(
136 " Repo Size: {}",
137 repo_stats
138 .get("RepoSize")
139 .unwrap_or(&serde_json::Value::Number(0.into()))
140 );
141 println!(
142 " Storage Max: {}",
143 repo_stats
144 .get("StorageMax")
145 .unwrap_or(&serde_json::Value::Number(0.into()))
146 );
147 println!(
148 " Num Objects: {}",
149 repo_stats
150 .get("NumObjects")
151 .unwrap_or(&serde_json::Value::Number(0.into()))
152 );
153 }
154 }
155 }
156 Err(e) => println!(" Error: {}", e),
157 }
158
159 // Example 5: Pin operations - List pinned objects
160 println!("\n5. LIST pinned objects (POST with type filter):");
161 match client
162 .post(format!("{}/pin/ls", ipfs_api_base))
163 .query("type", "recursive")
164 .query("stream", "true")
165 .send()
166 {
167 Ok(response) => {
168 println!(" Status: {}", response.status());
169 if response.is_success() {
170 if let Ok(pin_list) = response.json::<serde_json::Value>() {
171 if let Some(keys) = pin_list.get("Keys").and_then(|k| k.as_object()) {
172 println!(" Pinned objects count: {}", keys.len());
173 // Show first few pinned objects
174 for (hash, info) in keys.iter().take(3) {
175 if let Some(pin_type) = info.get("Type") {
176 println!(" - {} ({})", hash, pin_type);
177 }
178 }
179 if keys.len() > 3 {
180 println!(" ... and {} more", keys.len() - 3);
181 }
182 }
183 }
184 }
185 }
186 Err(e) => println!(" Error: {}", e),
187 }
188
189 // Example 6: Module-level convenience function
190 println!("\n6. GET swarm peers (using module-level function):");
191 match post(format!("{}/swarm/peers", ipfs_api_base))
192 .query("verbose", "false")
193 .send()
194 {
195 Ok(response) => {
196 println!(" Status: {}", response.status());
197 if response.is_success() {
198 if let Ok(peers_info) = response.json::<serde_json::Value>() {
199 if let Some(peers) = peers_info.get("Peers").and_then(|p| p.as_array()) {
200 println!(" Connected peers: {}", peers.len());
201 // Show first few peers
202 for peer in peers.iter().take(2) {
203 if let Some(peer_id) = peer.get("Peer") {
204 if let Some(addr) = peer.get("Addr") {
205 println!(
206 " - Peer: {}...{}",
207 &peer_id.as_str().unwrap_or("")[..8],
208 &peer_id.as_str().unwrap_or("")[peer_id
209 .as_str()
210 .unwrap_or("")
211 .len()
212 .saturating_sub(8)..]
213 );
214 println!(" Address: {}", addr);
215 }
216 }
217 }
218 if peers.len() > 2 {
219 println!(" ... and {} more peers", peers.len() - 2);
220 }
221 }
222 }
223 }
224 }
225 Err(e) => println!(" Error: {}", e),
226 }
227
228 println!("\n✅ IPFS API Demo completed!");
229 println!("This example demonstrated:");
230 println!(" • POST requests with no body (version, id)");
231 println!(" • POST with query parameters (repo/stat, pin/ls)");
232 println!(" • POST with multipart file upload (add)");
233 println!(" • POST with binary responses (cat - in demonstrate_file_operations)");
234 println!(" • Module-level convenience functions (swarm/peers)");
235 println!(" • Different response types (JSON, binary)");
236
237 Ok(())
238}Sourcepub fn build(self) -> HttpClient
pub fn build(self) -> HttpClient
Examples found in repository?
examples/http_client.rs (line 43)
4fn main() -> Result<(), Box<dyn std::error::Error>> {
5 println!("====================================");
6 println!("HTTP v2 Client Demo");
7 println!("====================================");
8
9 println!("\n1. GET request:");
10 match get("https://httpbin.org/get").send() {
11 Ok(response) => {
12 println!("GET Status: {}", response.status());
13 println!("GET Success: {}", response.is_success());
14 }
15 Err(e) => println!("GET Error: {}", e),
16 }
17
18 println!("\n2. POST with JSON:");
19 let json_data = serde_json::json!({
20 "name": "Blockless SDK",
21 "version": "2.0",
22 "api_style": "reqwest-like"
23 });
24 match post("https://httpbin.org/post").json(&json_data)?.send() {
25 Ok(response) => {
26 println!("POST JSON Status: {}", response.status());
27 if let Ok(response_json) = response.json::<serde_json::Value>() {
28 if let Some(received_json) = response_json.get("json") {
29 println!("Received JSON: {}", received_json);
30 }
31 }
32 }
33 Err(e) => println!("POST JSON Error: {}", e),
34 }
35
36 println!("\n3. Client instance with default configuration:");
37 let mut default_headers = HashMap::new();
38 default_headers.insert("User-Agent".to_string(), "Blockless-SDK/2.0".to_string());
39 default_headers.insert("Accept".to_string(), "application/json".to_string());
40 let client = HttpClient::builder()
41 .default_headers(default_headers)
42 .timeout(10000)
43 .build();
44 match client
45 .get("https://httpbin.org/get")
46 .query("search", "blockless")
47 .query("limit", "10")
48 .query("format", "json")
49 .send()
50 {
51 Ok(response) => {
52 println!("Client GET Status: {}", response.status());
53 if let Ok(json_data) = response.json::<serde_json::Value>() {
54 if let Some(args) = json_data.get("args") {
55 println!("Query params: {}", args);
56 }
57 }
58 }
59 Err(e) => println!("Client GET Error: {}", e),
60 }
61
62 println!("\n4. Authentication examples:");
63 match client
64 .get("https://httpbin.org/basic-auth/user/pass")
65 .basic_auth("user", "pass")
66 .send()
67 {
68 Ok(response) => {
69 println!("Basic auth status: {}", response.status());
70 if let Ok(json_data) = response.json::<serde_json::Value>() {
71 println!("Authenticated: {:?}", json_data.get("authenticated"));
72 }
73 }
74 Err(e) => println!("Basic auth error: {}", e),
75 }
76
77 match client
78 .get("https://httpbin.org/bearer")
79 .bearer_auth("test-token-12345")
80 .send()
81 {
82 Ok(response) => {
83 println!("Bearer auth status: {}", response.status());
84 if let Ok(json_data) = response.json::<serde_json::Value>() {
85 println!("Token received: {:?}", json_data.get("token"));
86 }
87 }
88 Err(e) => println!("Bearer auth error: {}", e),
89 }
90
91 println!("\n5. Different request body types:");
92 let mut form_data = HashMap::new();
93 form_data.insert("name".to_string(), "Blockless".to_string());
94 form_data.insert("type".to_string(), "distributed computing".to_string());
95 match client
96 .post("https://httpbin.org/post")
97 .form(form_data)
98 .send()
99 {
100 Ok(response) => {
101 println!("Form POST Status: {}", response.status());
102 if let Ok(json_data) = response.json::<serde_json::Value>() {
103 if let Some(form) = json_data.get("form") {
104 println!("Form data received: {}", form);
105 }
106 }
107 }
108 Err(e) => println!("Form POST Error: {}", e),
109 }
110
111 println!("\n6. Multipart form with file upload:");
112 let multipart_fields = vec![
113 MultipartField::text("description", "SDK test file"),
114 MultipartField::file(
115 "upload",
116 b"Hello from Blockless SDK v2!".to_vec(),
117 "hello.txt",
118 Some("text/plain".to_string()),
119 ),
120 ];
121 match client
122 .post("https://httpbin.org/post")
123 .multipart(multipart_fields)
124 .send()
125 {
126 Ok(response) => {
127 println!("Multipart POST Status: {}", response.status());
128 if let Ok(json_data) = response.json::<serde_json::Value>() {
129 if let Some(files) = json_data.get("files") {
130 println!("Files uploaded: {}", files);
131 }
132 }
133 }
134 Err(e) => println!("Multipart POST Error: {}", e),
135 }
136
137 println!("\n7. Binary data:");
138 let binary_data = vec![0x48, 0x65, 0x6c, 0x6c, 0x6f]; // "Hello" in bytes
139 match client
140 .post("https://httpbin.org/post")
141 .header("Content-Type", "application/octet-stream")
142 .body_bytes(binary_data)
143 .send()
144 {
145 Ok(response) => {
146 println!("Binary POST Status: {}", response.status());
147 }
148 Err(e) => println!("Binary POST Error: {}", e),
149 }
150
151 println!("\n8. Advanced request building:");
152 match client
153 .put("https://httpbin.org/put")
154 .header("X-Custom-Header", "custom-value")
155 .header("X-API-Version", "2.0")
156 .query("action", "update")
157 .query("id", "12345")
158 .timeout(5000)
159 .body("Updated data")
160 .send()
161 {
162 Ok(response) => {
163 println!("PUT Status: {}", response.status());
164 if let Ok(json_data) = response.json::<serde_json::Value>() {
165 if let Some(headers) = json_data.get("headers") {
166 println!("Custom headers received: {}", headers);
167 }
168 }
169 }
170 Err(e) => println!("PUT Error: {}", e),
171 }
172
173 println!("\nDemo completed 🚀");
174 Ok(())
175}More examples
examples/ipfs_api.rs (line 16)
3fn main() -> Result<(), Box<dyn std::error::Error>> {
4 println!("IPFS RPC API Demo - HTTP v2 Client");
5 println!("=================================");
6 println!("Make sure your IPFS node is running on localhost:5001");
7 println!("Docker command: docker run --rm -it --name ipfs_host -p 4001:4001 -p 4001:4001/udp -p 8080:8080 -p 5001:5001 ipfs/kubo");
8 println!("Note: If you get CORS errors, configure CORS with:");
9 println!(" docker exec ipfs_host ipfs config --json API.HTTPHeaders.Access-Control-Allow-Origin '[\"*\"]'");
10 println!(" docker exec ipfs_host ipfs config --json API.HTTPHeaders.Access-Control-Allow-Methods '[\"GET\", \"POST\", \"PUT\", \"DELETE\", \"OPTIONS\"]'");
11 println!(" docker restart ipfs_host\n");
12
13 // Create HTTP client configured for IPFS RPC API
14 let client = HttpClient::builder()
15 .timeout(30000) // 30 seconds for file operations
16 .build();
17
18 let ipfs_api_base = "http://localhost:5001/api/v0";
19
20 // Example 1: Simple POST request - Get node version
21 println!("1. GET node version (POST with no body):");
22 match client.post(format!("{}/version", ipfs_api_base)).send() {
23 Ok(response) => {
24 println!(" Status: {}", response.status());
25 if response.is_success() {
26 if let Ok(version_info) = response.json::<serde_json::Value>() {
27 println!(
28 " IPFS Version: {}",
29 version_info
30 .get("Version")
31 .and_then(|v| v.as_str())
32 .unwrap_or("unknown")
33 );
34 println!(
35 " Commit: {}",
36 version_info
37 .get("Commit")
38 .and_then(|c| c.as_str())
39 .unwrap_or("unknown")
40 );
41 }
42 }
43 }
44 Err(e) => println!(" Error: {} (Is IPFS running?)", e),
45 }
46
47 // Example 2: POST with query parameters - Get node ID
48 println!("\n2. GET node ID (POST with query parameters):");
49 match client
50 .post(format!("{}/id", ipfs_api_base))
51 .query("format", "json")
52 .send()
53 {
54 Ok(response) => {
55 println!(" Status: {}", response.status());
56 if response.is_success() {
57 if let Ok(id_info) = response.json::<serde_json::Value>() {
58 println!(
59 " Node ID: {}",
60 id_info
61 .get("ID")
62 .and_then(|id| id.as_str())
63 .unwrap_or("unknown")
64 );
65 if let Some(addresses) = id_info.get("Addresses") {
66 if let Some(addr_array) = addresses.as_array() {
67 if !addr_array.is_empty() {
68 println!(" First Address: {}", addr_array[0]);
69 }
70 }
71 }
72 }
73 }
74 }
75 Err(e) => println!(" Error: {}", e),
76 }
77
78 // Example 3: POST with multipart file upload - Add file to IPFS
79 println!("\n3. ADD file to IPFS (POST with multipart upload):");
80 let file_content = b"Hello from Blockless SDK HTTP v2 client!\nThis file was uploaded to IPFS using multipart form data.";
81 let multipart_fields = vec![MultipartField::file(
82 "file", // IPFS expects 'file' as the field name
83 file_content.to_vec(),
84 "hello-blockless.txt",
85 Some("text/plain".to_string()),
86 )];
87
88 match client
89 .post(format!("{}/add", ipfs_api_base))
90 .query("pin", "true") // Pin the file after adding
91 .multipart(multipart_fields)
92 .send()
93 {
94 Ok(response) => {
95 println!(" Status: {}", response.status());
96 if response.is_success() {
97 if let Ok(add_result) = response.json::<serde_json::Value>() {
98 let hash = add_result
99 .get("Hash")
100 .and_then(|h| h.as_str())
101 .unwrap_or("unknown");
102 let name = add_result
103 .get("Name")
104 .and_then(|n| n.as_str())
105 .unwrap_or("unknown");
106 let size = add_result
107 .get("Size")
108 .and_then(|s| s.as_str())
109 .unwrap_or("0");
110 println!(" Added file: {}", name);
111 println!(" IPFS Hash: {}", hash);
112 println!(" Size: {} bytes", size);
113
114 // Store hash for later examples
115 if hash != "unknown" {
116 demonstrate_file_operations(&client, ipfs_api_base, hash)?;
117 }
118 }
119 }
120 }
121 Err(e) => println!(" Error: {}", e),
122 }
123
124 // Example 4: Repository stats (POST with query parameters)
125 println!("\n4. GET repository statistics (POST with boolean parameters):");
126 match client
127 .post(format!("{}/repo/stat", ipfs_api_base))
128 .query("human", "true")
129 .send()
130 {
131 Ok(response) => {
132 println!(" Status: {}", response.status());
133 if response.is_success() {
134 if let Ok(repo_stats) = response.json::<serde_json::Value>() {
135 println!(
136 " Repo Size: {}",
137 repo_stats
138 .get("RepoSize")
139 .unwrap_or(&serde_json::Value::Number(0.into()))
140 );
141 println!(
142 " Storage Max: {}",
143 repo_stats
144 .get("StorageMax")
145 .unwrap_or(&serde_json::Value::Number(0.into()))
146 );
147 println!(
148 " Num Objects: {}",
149 repo_stats
150 .get("NumObjects")
151 .unwrap_or(&serde_json::Value::Number(0.into()))
152 );
153 }
154 }
155 }
156 Err(e) => println!(" Error: {}", e),
157 }
158
159 // Example 5: Pin operations - List pinned objects
160 println!("\n5. LIST pinned objects (POST with type filter):");
161 match client
162 .post(format!("{}/pin/ls", ipfs_api_base))
163 .query("type", "recursive")
164 .query("stream", "true")
165 .send()
166 {
167 Ok(response) => {
168 println!(" Status: {}", response.status());
169 if response.is_success() {
170 if let Ok(pin_list) = response.json::<serde_json::Value>() {
171 if let Some(keys) = pin_list.get("Keys").and_then(|k| k.as_object()) {
172 println!(" Pinned objects count: {}", keys.len());
173 // Show first few pinned objects
174 for (hash, info) in keys.iter().take(3) {
175 if let Some(pin_type) = info.get("Type") {
176 println!(" - {} ({})", hash, pin_type);
177 }
178 }
179 if keys.len() > 3 {
180 println!(" ... and {} more", keys.len() - 3);
181 }
182 }
183 }
184 }
185 }
186 Err(e) => println!(" Error: {}", e),
187 }
188
189 // Example 6: Module-level convenience function
190 println!("\n6. GET swarm peers (using module-level function):");
191 match post(format!("{}/swarm/peers", ipfs_api_base))
192 .query("verbose", "false")
193 .send()
194 {
195 Ok(response) => {
196 println!(" Status: {}", response.status());
197 if response.is_success() {
198 if let Ok(peers_info) = response.json::<serde_json::Value>() {
199 if let Some(peers) = peers_info.get("Peers").and_then(|p| p.as_array()) {
200 println!(" Connected peers: {}", peers.len());
201 // Show first few peers
202 for peer in peers.iter().take(2) {
203 if let Some(peer_id) = peer.get("Peer") {
204 if let Some(addr) = peer.get("Addr") {
205 println!(
206 " - Peer: {}...{}",
207 &peer_id.as_str().unwrap_or("")[..8],
208 &peer_id.as_str().unwrap_or("")[peer_id
209 .as_str()
210 .unwrap_or("")
211 .len()
212 .saturating_sub(8)..]
213 );
214 println!(" Address: {}", addr);
215 }
216 }
217 }
218 if peers.len() > 2 {
219 println!(" ... and {} more peers", peers.len() - 2);
220 }
221 }
222 }
223 }
224 }
225 Err(e) => println!(" Error: {}", e),
226 }
227
228 println!("\n✅ IPFS API Demo completed!");
229 println!("This example demonstrated:");
230 println!(" • POST requests with no body (version, id)");
231 println!(" • POST with query parameters (repo/stat, pin/ls)");
232 println!(" • POST with multipart file upload (add)");
233 println!(" • POST with binary responses (cat - in demonstrate_file_operations)");
234 println!(" • Module-level convenience functions (swarm/peers)");
235 println!(" • Different response types (JSON, binary)");
236
237 Ok(())
238}Trait Implementations§
Auto Trait Implementations§
impl Freeze for HttpClientBuilder
impl RefUnwindSafe for HttpClientBuilder
impl Send for HttpClientBuilder
impl Sync for HttpClientBuilder
impl Unpin for HttpClientBuilder
impl UnwindSafe for HttpClientBuilder
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Mutably borrows from an owned value. Read more