Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(ios)!: solve FormData boundary issues #7306

Merged
merged 4 commits into from
Mar 14, 2024
Merged

fix(ios)!: solve FormData boundary issues #7306

merged 4 commits into from
Mar 14, 2024

Conversation

jcesarmobile
Copy link
Member

@jcesarmobile jcesarmobile commented Mar 1, 2024

Marking it as breaking since it adds a contentType param to getRequestDataAsMultipartFormData, which is a public function.

Removes the custom boundary native-bridge.ts is adding and uses the browser one.
Read the browser boundary from native and uses that one instead of a custom one (android already does that).
Removes some new lines added that break on some servers.
Makes getRequestDataFromFormData public since all other methods are public.

closes #6748
closes #7242
closes #6832

if dataType == "file" {
guard let stringData = body as? String else {
throw CapacitorUrlRequestError.serializationError("[ data ] argument could not be parsed as string")
}
return Data(base64Encoded: stringData)
} else if dataType == "formData" {
return try getRequestDataFromFormData(body)
return try getRequestDataFromFormData(body, boundary!)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We sure this will always be non-nil?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

When using the patched fetch/XHR yeah, it will be there.
For direct API calls not so sure, but on Android there are no checks, so in any case it would crash on both platforms.

Copy link
Member

@Steven0351 Steven0351 Mar 5, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could easily turn this into:

} else if dataType == "formData", let boundary {

to avoid the force unwrapping

Copy link
Member

@Steven0351 Steven0351 Mar 5, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

another solution could be to collapse the "multipart/form-data" check below into one if like:

} else if dataType == "formData" || contentType.contains("multipart/form-data"), let boundary = contentType.components(separatedBy: "=").last {

It's a bit verbose but it keeps the one form-data case in a single branch. It also won't do the string processing of the boundary until the content type itself has been verified.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"formData" and "multipart/form-data" call different functions, so doing this would require a second if to call one or the other.

Copy link
Contributor

@markemer markemer left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is looking good, but we should ditch those force unwraps.

@jcesarmobile
Copy link
Member Author

Since you didn't like the force unwrap, I've restored the old code that creates a new boundary if none is present.

Note that on Android there is no similar code, if there is no boundary it will throw there, but this change is for iOS only, so I'm not changing anything there.

@giralte-ionic giralte-ionic merged commit 11817a0 into main Mar 14, 2024
6 checks passed
@giralte-ionic giralte-ionic deleted the RDMR-53 branch March 14, 2024 17:34
michaelwolz added a commit to michaelwolz/capacitor that referenced this pull request Jun 18, 2024
The changes introduced in ionic-team#7306 fixed several bugs with multipart/form-data requests on iOS.
However, the extraction of the actual boundary value might fail due to the value
being surrounded by double quotes, which is allowed and happens occasionally.
Additionally, the `Content-Type` header might include other keys such as `charset`.
This change extracts the boundary value regardless of the order of the individual keys within
the `Content-Type` header.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

bug: multipart/form-data encoding error in CapacitorUrlRequest.swift
4 participants