Skip to content

Commit

Permalink
Fix multipart requests
Browse files Browse the repository at this point in the history
This patch fixes the implementation of multipart requests that were
previously just ignored.

Fixes: #20
  • Loading branch information
robin-nitrokey committed May 15, 2024
1 parent 2611871 commit 00e1329
Show file tree
Hide file tree
Showing 11 changed files with 2,831 additions and 6 deletions.
2 changes: 1 addition & 1 deletion .openapi-generator/VERSION
Original file line number Diff line number Diff line change
@@ -1 +1 @@
7.2.0-SNAPSHOT
7.6.0-SNAPSHOT
8 changes: 8 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,13 @@
# Changelog

## Unreleased

### Bugfixes

- Fix multipart requests, namely `system_restore_post` ([#20](https://github.com/Nitrokey/nethsm-sdk-rs/issues/20))

[All Changes](https://github.com/Nitrokey/nethsm-sdk-rs/compare/v1.0.1...HEAD)

## [v1.0.1](https://github.com/Nitrokey/nethsm-sdk-rs/releases/tag/v1.0.1) (2024-05-06)

### Bugfixes
Expand Down
3 changes: 3 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@ exclude = [
]

[dependencies]
mime = "0.3"
multipart = { version = "0.18", default-features = false, features = ["client"] }
serde = { default-features = false, version = "^1.0" }
serde_derive = "^1.0"
serde_json = { default-features = false, version = "^1.0" }
Expand All @@ -27,6 +29,7 @@ ureq = { version = "2", features = ["json", "tls"], default-features = false }
base64 = { version = "0.21", default-features = false, features = ["alloc"] }

[dev-dependencies]
chrono = "0.4.38"
env_logger = "0.11.3"
rustainers = "0.12.0"
rustls = { version = "0.22.4" }
Expand Down
3 changes: 3 additions & 0 deletions generator/src/main/resources/crust/Cargo.mustache
Original file line number Diff line number Diff line change
Expand Up @@ -41,8 +41,11 @@ serde_json = { default-features = false, version = "^1.0" }
url = "^2.2"
ureq = { version = "2", features = ["json", "tls"], default-features = false }
base64 = { version = "0.21", default-features = false, features = ["alloc"] }
mime = "0.3"
multipart = { version = "0.18", default-features = false, features = ["client"] }

[dev-dependencies]
chrono = "0.4.38"
env_logger = "0.11.3"
rustainers = "0.12.0"
rustls = { version = "0.22.4" }
Expand Down
40 changes: 40 additions & 0 deletions generator/src/main/resources/crust/reqwest/api.mustache
Original file line number Diff line number Diff line change
Expand Up @@ -285,6 +285,45 @@ pub fn {{{operationId}}}(configuration: &configuration::Configuration, {{#allPar
local_var_req_builder = local_var_req_builder.set("accept", accept_str);
{{/hasProduces}}

{{#isMultipart}}
let mut local_var_multipart = ::multipart::client::lazy::Multipart::new();

{{#hasFormParams}}
{{#formParams}}
{{#isFile}}
if let Some({{{paramName}}}) = {{{paramName}}} {
local_var_multipart.add_stream(
"{{{baseName}}}",
::std::io::Cursor::new({{{paramName}}}),
None::<&str>,
None,
);
}
{{/isFile}}
{{/formParams}}
{{#formParams}}
{{^isFile}}
if let Some({{{paramName}}}) = {{{paramName}}} {
let {{{paramName}}} = ::serde_json::to_vec(&{{{paramName}}})?;
local_var_multipart.add_stream(
"{{{baseName}}}",
::std::io::Cursor::new({{{paramName}}}),
None::<&str>,
None,
);
}
{{/isFile}}
{{/formParams}}
{{/hasFormParams}}

let local_var_multipart = local_var_multipart.prepare()?;
local_var_req_builder = local_var_req_builder.set(
"content-type",
&format!("multipart/form-data; boundary={}", local_var_multipart.boundary()),
);
let local_var_resp = local_var_req_builder.send(local_var_multipart)?;
{{/isMultipart}}
{{^isMultipart}}
{{#vendorExtensions.x-consumeMultipleMediaTypes}}
{{#hasBodyParam}}{{#bodyParams}}
let body_json = body.is_json();
Expand Down Expand Up @@ -328,6 +367,7 @@ pub fn {{{operationId}}}(configuration: &configuration::Configuration, {{#allPar
{{^hasBodyParam}}
let local_var_resp = local_var_req_builder.call()?;
{{/hasBodyParam}}
{{/isMultipart}}


let local_var_headers = super::get_header_map(&local_var_resp);
Expand Down
21 changes: 21 additions & 0 deletions generator/src/main/resources/crust/reqwest/api_mod.mustache
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,10 @@ pub struct ResponseContent<T> {

#[derive(Debug)]
pub enum Error<T> {
Multipart {
field: Option<String>,
error: std::io::Error,
},
Ureq(ureq::Error),
Serde(serde_json::Error),
Io(std::io::Error),
Expand All @@ -38,6 +42,13 @@ pub enum Error<T> {
impl <T> fmt::Display for Error<T> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
let (module, e) = match self {
Error::Multipart { field, error } => {
let error = match field {
Some(field) => format!("failed to encode {field}: {error}"),
None => error.to_string(),
};
("multipart", error)
}
Error::Ureq(e) => ("ureq", e.to_string()),
Error::Serde(e) => ("serde", e.to_string()),
Error::Io(e) => ("IO", e.to_string()),
Expand All @@ -51,6 +62,7 @@ impl <T> fmt::Display for Error<T> {
impl <T: fmt::Debug> error::Error for Error<T> {
fn source(&self) -> Option<&(dyn error::Error + 'static)> {
Some(match self {
Error::Multipart { error, .. } => error,
Error::Ureq(e) => e,
Error::Serde(e) => e,
Error::Io(e) => e,
Expand All @@ -60,6 +72,15 @@ impl <T: fmt::Debug> error::Error for Error<T> {
}
}

impl<T> From<multipart::client::lazy::LazyError<'_, std::io::Error>> for Error<T> {
fn from(e: multipart::client::lazy::LazyError<'_, std::io::Error>) -> Self {
Self::Multipart {
field: e.field_name.map(|s| s.into_owned()),
error: e.error,
}
}
}
impl <T> From<ureq::Error> for Error<T> {
fn from(e: ureq::Error) -> Self {
Error::Ureq(e)
Expand Down
Loading

0 comments on commit 00e1329

Please sign in to comment.