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 support for 'multipart/form-data' file upload #255

Open
jpaulgs opened this issue Mar 6, 2020 · 3 comments
Open

Add support for 'multipart/form-data' file upload #255

jpaulgs opened this issue Mar 6, 2020 · 3 comments
Labels

Comments

@jpaulgs
Copy link

jpaulgs commented Mar 6, 2020

I'm attempting to describe file upload, according to swagger docs for file-upload we should define the file as type string with the format of binary.

so my openapi for this request looks like:

      requestBody:
        content:
          multipart/form-data:
            schema:
              type: object
              properties:
                contractId:
                  type: string
                  example: 270A2087-6335-455E-B32D-350C00FFEEB7
                organisationId:
                  description: Your ID for this participant
                  example: AAA123
                  type: string
                resourceId:
                  type: string
                  example: 49E2797A-A62E-4042-9587-2CC0A1DBC679
                file:
                  type: string
                  format: binary

However by the time this gets to the committee middleware rack has exploded the file to a hash

file: {
  :filename=>"i_am_a_file.csv", 
  :type=>"text/plain", 
  :name=>"file", 
  :tempfile=>#<Tempfile:/tmp/RackMultipart20200306-13-1rx39tl.csv>, 
  :head=>"Content-Disposition: form-data; name=\"file\"; filename=\"i_am_a_file.csv\"\r\nContent-Type: text/plain\r\nContent-Length: 81\r\n"
}

so we end up with an error like:

#/paths/~1api~1v1~1telemetry_data_files/post/requestBody/content/multipart~1form-data/schema/properties/file expected string, but received Hash:

I was looking at test/request_unpacker_test.rb but I do not see how to handle this situation. What am I missing?

@masayuki14
Copy link

I faced to same problem too.
I solved problem as to use monky patch like follows.
This is not a sufficient change. But the test can pass.

module StringValidatorPatch
  def coerce_and_validate(value, schema, **_keyword_args)
    # change this
    # https://github.com/ota42y/openapi_parser/blob/61874f0190a86c09bdfb78de5f51cfb6ae16068b/lib/openapi_parser/schema_validators/string_validator.rb#L11
    unless value.is_a?(String)
      return OpenAPIParser::ValidateError.build_error_result(value, schema) if schema.format != 'binary'
    end
    # --- end

    value, err = check_enum_include(value, schema)
    return [nil, err] if err

    value, err = pattern_validate(value, schema)
    return [nil, err] if err

    unless @datetime_coerce_class.nil?
      value, err = coerce_date_time(value, schema)
      return [nil, err] if err
    end

    value, err = validate_max_min_length(value, schema)
    return [nil, err] if err

    value, err = validate_email_format(value, schema)
    return [nil, err] if err

    value, err = validate_uuid_format(value, schema)
    return [nil, err] if err

    [value, nil]
  end
end

class OpenAPIParser::SchemaValidator::StringValidator
  prepend StringValidatorPatch
end

@pechorin
Copy link

pechorin commented Mar 6, 2023

The actual version of patch (maybe, not sure, but works for my test suite):

module StringValidatorPatch
  def coerce_and_validate(value, schema, **_keyword_args)
    # Diff:
    # :- return OpenAPIParser::ValidateError.build_error_result(value, schema) unless value.kind_of?(String)
    #
    # :+
    if !value.is_a?(String)
      if schema.format == 'binary'
        # Fix: in tests rack uploaded file not converts automatically (committee bug)
        if value[:tempfile]
          return [ActionDispatch::Http::UploadedFile.new(value), nil]
        else
          return [value, nil]
        end
      else
        return OpenAPIParser::ValidateError.build_error_result(value, schema)
      end
    end
    # End of diff

    value, err = check_enum_include(value, schema)
    return [nil, err] if err

    value, err = pattern_validate(value, schema)
    return [nil, err] if err

    value, err = validate_max_min_length(value, schema)
    return [nil, err] if err

    value, err = validate_email_format(value, schema)
    return [nil, err] if err

    value, err = validate_uuid_format(value, schema)
    return [nil, err] if err

    value, err = validate_date_format(value, schema)
    return [nil, err] if err

    value, err = validate_datetime_format(value, schema)
    return [nil, err] if err

    [value, nil]
  end
end

class OpenAPIParser::SchemaValidator::StringValidator
  prepend StringValidatorPatch
end

@ota42y
Copy link
Member

ota42y commented Mar 12, 2023

We have no plans to fix it at this time (not that we don't want to, just that we don't have time to deal with it).
However, if there is an error, we would like to have some workaround (no verification, but no error either).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

4 participants