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

Add The Ability To Specify A Different Content Type #14

Open
wants to merge 1 commit into
base: main
Choose a base branch
from

Conversation

juna-nb
Copy link

@juna-nb juna-nb commented Oct 30, 2024

When trying to use faraday-multipart for Publishing Flows Tableau API's I was giving an error because Tableau's APIs multipart APIs only allow a Content-Type: multipart/mixed.

As noted in the comment below by @olleolleolle there are many different accepted mime types for multipart requests and this change provides the option to specify a different one.

The new option for this middleware provided in this PR:

client = Faraday.new(url:, headers:) do |builder|
  builder.request :multipart, content_type: 'multipart/mixed'
end

If a multipart mime type is not specified the middleware will default to multipart/form-data.

This change also changes the structure of the middleware a bit.

It changes the parent from UrlEncoded to inherit from Middleware directly instead. This is because we were overriding most of the UrlEncoded methods anyway so bringing last remaining methods over and removing that link in the dependency chain seemed to make sense.

Another structural code change was to move the methods that didn't need to be public under the private keyword. The intent of this was to help future developers know what they can change without worrying about breaking any external dependencies.

@olleolleolle
Copy link
Member

I think this idea is good! https://www.iana.org/assignments/media-types/media-types.xhtml#multipart here is the list of IANA multipart variants right now.

@juna-nb juna-nb changed the title Ability To Use a Different MIME Type Add The Ability To Specify A Different MIME Type Nov 1, 2024
@juna-nb juna-nb marked this pull request as ready for review November 1, 2024 23:09
@juna-nb juna-nb changed the title Add The Ability To Specify A Different MIME Type Add The Ability To Specify A Different Content Type Nov 1, 2024
class Middleware < Faraday::Request::UrlEncoded
DEFAULT_BOUNDARY_PREFIX = '-----------RubyMultipartPost'

self.mime_type = 'multipart/form-data'
Copy link
Author

Choose a reason for hiding this comment

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

This needed to be changed from a class variable to an instance variable otherwise it was causing race conditions in the RSpec tests (and presumably likely in people's code as well).

type = request_type(env)
env.body && (type.empty? || (type == mime_type))
end

Copy link
Author

Choose a reason for hiding this comment

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

And because we changed the mime_type from a class variable to an instance variable we also had to do so across this object, included in places where we once inherited from UrlEncoded. So this code is copied from that object but with the mime_type now being referenced from an instance variable instead.

type = type.split(';', 2).first if type.index(';')
type
end

Copy link
Author

Choose a reason for hiding this comment

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

Copied over from UrlEncoded to remove that class as a dependancy.

else
'multipart/form-data'
end
end
Copy link
Author

Choose a reason for hiding this comment

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

I figured as long as the Content-Type started with multipart that is mainly what we cared about and it keeps this middleware flexible.

@juna-nb
Copy link
Author

juna-nb commented Nov 12, 2024

@olleolleolle is there anything else you need me to do to expedite getting this change merged and released? Thanks!

Copy link
Member

@olleolleolle olleolleolle left a comment

Choose a reason for hiding this comment

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

Let's try using this!

# @return [String]
def request_type(env)
type = env.request_headers[CONTENT_TYPE].to_s
type = type.split(';', 2).first if type.index(';')
Copy link
Member

Choose a reason for hiding this comment

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

Unrelated to this PR: I'll try fixing the "using index to check if the string contains a character" minor issue. There are other methods, like String#include?. Let's keep this code "as copied over".

@olleolleolle
Copy link
Member

@juna-nb Ah, also, use Rubocop, some of the fixes can be -A -a auto-corrected. There seemed to be a duplicate method which perhaps needs more reading. Good luck!

@juna-nb
Copy link
Author

juna-nb commented Nov 14, 2024

Thanks @olleolleolle I'm hoping to get back to this today or tomorrow.

There are many different mime types for multipart
requests and this change provides the option to
specify a different one.

If a multipart mime type is not specified the
middleware will default to multipart/form-data.

This change also changes the structure of the
middleware a bit. It changes the parent from
UrlEncoded to inherit from Middleware directly
instead. This is because we were overriding most
of the UrlEncoded methods anyway so bringing last
remaining methods over and removing that link in
the dependency chain seemed to make sense.

Another structural code change was to move the
methods that didn't need to be public under the
private keyword. The intent of this was to help
future developers know what they can change
without worrying breaking any external
dependencies.
@juna-nb
Copy link
Author

juna-nb commented Nov 15, 2024

Thanks for the feedback @olleolleolle and for the catch on the fix for the older version of Ruby.

I've addressed them now, as well as the Rubocop linting issues, and some stray changes (due to my Markdown auto-formatters).

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.

2 participants