From 1d1c5b47dcf0f4713e75f04a24c1173bae7a8d98 Mon Sep 17 00:00:00 2001 From: fdkevin Date: Wed, 15 Nov 2023 17:31:01 +0800 Subject: [PATCH 1/2] fix(kubo-rpc): block_put_post multipart with bytes --- kubo-rpc-server/src/client/mod.rs | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/kubo-rpc-server/src/client/mod.rs b/kubo-rpc-server/src/client/mod.rs index fc1f69489..185781ca6 100644 --- a/kubo-rpc-server/src/client/mod.rs +++ b/kubo-rpc-server/src/client/mod.rs @@ -555,7 +555,7 @@ where Err(e) => return Err(ApiError(format!("Unable to create request: {}", e))), }; - let (body_string, multipart_header) = { + let (body_bytes, multipart_header) = { let mut multipart = Multipart::new(); // For each parameter, encode as appropriate and add to the multipart body as a stream. @@ -577,9 +577,9 @@ where Err(err) => return Err(ApiError(format!("Unable to build request: {}", err))), }; - let mut body_string = String::new(); + let mut body_bytes = Vec::new(); - match fields.read_to_string(&mut body_string) { + match fields.read_to_end(&mut body_bytes) { Ok(_) => (), Err(err) => return Err(ApiError(format!("Unable to build body: {}", err))), } @@ -588,10 +588,10 @@ where let multipart_header = format!("multipart/form-data;boundary={}", boundary); - (body_string, multipart_header) + (body_bytes, multipart_header) }; - *request.body_mut() = Body::from(body_string); + *request.body_mut() = Body::from(body_bytes); request.headers_mut().insert( CONTENT_TYPE, From 96038a7a5b750aeeefcb12609e55e9f4a3196c7d Mon Sep 17 00:00:00 2001 From: fdkevin Date: Thu, 16 Nov 2023 11:57:20 +0800 Subject: [PATCH 2/2] feat(kubo-rpc): fix API schema --- kubo-rpc-server/README.md | 2 +- kubo-rpc-server/api/openapi.yaml | 10 ++++++++- kubo-rpc-server/examples/client/main.rs | 2 +- kubo-rpc-server/src/client/mod.rs | 29 +++++++++++++++---------- kubo-rpc-server/src/server/mod.rs | 16 +++++++++++--- kubo-rpc/kubo-rpc.yaml | 2 +- 6 files changed, 42 insertions(+), 19 deletions(-) diff --git a/kubo-rpc-server/README.md b/kubo-rpc-server/README.md index 38a1bf67a..c45811a22 100644 --- a/kubo-rpc-server/README.md +++ b/kubo-rpc-server/README.md @@ -15,7 +15,7 @@ To see how to make this your own, look here: [README]((https://openapi-generator.tech)) - API version: 0.9.0 -- Build date: 2023-11-13T20:39:18.296854378Z[Etc/UTC] +- Build date: 2023-11-15T16:13:27.108848Z[Etc/UTC] diff --git a/kubo-rpc-server/api/openapi.yaml b/kubo-rpc-server/api/openapi.yaml index b4e13d99f..fdceb3037 100644 --- a/kubo-rpc-server/api/openapi.yaml +++ b/kubo-rpc-server/api/openapi.yaml @@ -210,7 +210,7 @@ paths: content: multipart/form-data: schema: - $ref: '#/components/schemas/_dag_put_post_request' + $ref: '#/components/schemas/_block_put_post_request' responses: "200": content: @@ -558,6 +558,14 @@ components: - Cid - RemPath type: object + _block_put_post_request: + properties: + file: + format: binary + type: string + required: + - file + type: object _block_put_post_200_response: example: Size: 0.8008281904610115 diff --git a/kubo-rpc-server/examples/client/main.rs b/kubo-rpc-server/examples/client/main.rs index c10c28026..41bdbb590 100644 --- a/kubo-rpc-server/examples/client/main.rs +++ b/kubo-rpc-server/examples/client/main.rs @@ -121,7 +121,7 @@ fn main() { } Some("BlockPutPost") => { let result = rt.block_on(client.block_put_post( - swagger::ByteArray(Vec::from("BYTE_ARRAY_DATA_HERE")), + swagger::ByteArray(Vec::from("BINARY_DATA_HERE")), None, None, None, diff --git a/kubo-rpc-server/src/client/mod.rs b/kubo-rpc-server/src/client/mod.rs index 185781ca6..9719706d0 100644 --- a/kubo-rpc-server/src/client/mod.rs +++ b/kubo-rpc-server/src/client/mod.rs @@ -555,31 +555,36 @@ where Err(e) => return Err(ApiError(format!("Unable to create request: {}", e))), }; - let (body_bytes, multipart_header) = { + let (body_string, multipart_header) = { let mut multipart = Multipart::new(); // For each parameter, encode as appropriate and add to the multipart body as a stream. - let file_vec = param_file.to_vec(); - - let file_mime = match mime_0_2::Mime::from_str("application/octet-stream") { - Ok(mime) => mime, - Err(err) => return Err(ApiError(format!("Unable to get mime type: {:?}", err))), + let file_str = match serde_json::to_string(¶m_file) { + Ok(str) => str, + Err(e) => { + return Err(ApiError(format!( + "Unable to serialize file to string: {}", + e + ))) + } }; + let file_vec = file_str.as_bytes().to_vec(); + let file_mime = + mime_0_2::Mime::from_str("application/json").expect("impossible to fail to parse"); let file_cursor = Cursor::new(file_vec); - let filename = None as Option<&str>; - multipart.add_stream("file", file_cursor, filename, Some(file_mime)); + multipart.add_stream("file", file_cursor, None as Option<&str>, Some(file_mime)); let mut fields = match multipart.prepare() { Ok(fields) => fields, Err(err) => return Err(ApiError(format!("Unable to build request: {}", err))), }; - let mut body_bytes = Vec::new(); + let mut body_string = String::new(); - match fields.read_to_end(&mut body_bytes) { + match fields.read_to_string(&mut body_string) { Ok(_) => (), Err(err) => return Err(ApiError(format!("Unable to build body: {}", err))), } @@ -588,10 +593,10 @@ where let multipart_header = format!("multipart/form-data;boundary={}", boundary); - (body_bytes, multipart_header) + (body_string, multipart_header) }; - *request.body_mut() = Body::from(body_bytes); + *request.body_mut() = Body::from(body_string); request.headers_mut().insert( CONTENT_TYPE, diff --git a/kubo-rpc-server/src/server/mod.rs b/kubo-rpc-server/src/server/mod.rs index f4f7ac396..0ba4ca6ad 100644 --- a/kubo-rpc-server/src/server/mod.rs +++ b/kubo-rpc-server/src/server/mod.rs @@ -412,9 +412,19 @@ where let param_file = match field_file { Some(field) => { let mut reader = field[0].data.readable().expect("Unable to read field for file"); - let mut data = vec![]; - reader.read_to_end(&mut data).expect("Reading saved binary data should never fail"); - swagger::ByteArray(data) + let mut data = String::new(); + reader.read_to_string(&mut data).expect("Reading saved String should never fail"); + let file_model: swagger::ByteArray = match serde_json::from_str(&data) { + Ok(model) => model, + Err(e) => { + return Ok( + Response::builder() + .status(StatusCode::BAD_REQUEST) + .body(Body::from(format!("file data does not match API definition : {}", e))) + .expect("Unable to create Bad Request due to missing required form parameter file")) + } + }; + file_model }, None => { return Ok( diff --git a/kubo-rpc/kubo-rpc.yaml b/kubo-rpc/kubo-rpc.yaml index 9147613f1..34e9c1040 100644 --- a/kubo-rpc/kubo-rpc.yaml +++ b/kubo-rpc/kubo-rpc.yaml @@ -257,7 +257,7 @@ paths: properties: file: type: string - format: byte + format: binary responses: '200': description: success