Skip to content

feat(oas31): add support for file upload #10335

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

Closed
wants to merge 3 commits into from
Closed

Conversation

char0n
Copy link
Member

@char0n char0n commented Mar 3, 2025

Related to OpenAPI 3.1.x.

We should now display file input when:

  • contentEncoding is base64
  • contentMediaType is application/octet-stream, image/*, video/* or audio/*
  • Media Type Object is empty

Does not add support for file upload if schema has union type or if type and contentEncoding/contentMediaType are defined in oneOf/anyOf.


base64 vs byte

Refs #9278

Attribution: @glowcloud

@char0n
Copy link
Member Author

char0n commented Apr 9, 2025

Related to OpenAPI 3.1.x.

We should now display file input when:

  • contentEncoding is base64

Conclusion is a bit falsy. We don't care about the value of contentEncoding unless is different then "identity". We only care if it's defined and different than "identity".

  • contentMediaType is application/octet-stream, image/*, video/* or audio/*

Conclusion is a bit falsy. Here we don't create about the value for sure. contentMediaType by itself is an indication that raw or anyother data will be attached, and for SwaggerUI it indicates we should render file input.

  • Media Type Object is empty

This depends on the pattern matching of media type of media range under which the Media Type Object is attached. We currently do recognize application/octet-stream, image/, video/ or audio/* as raw data.

Does not add support for file upload if schema has union type or if type and contentEncoding/contentMediaType are defined in oneOf/anyOf.

That's fine.

base64 vs byte

Yeah this is an obvious bug.

Refs #9278

Attribution: @glowcloud

@char0n
Copy link
Member Author

char0n commented Apr 9, 2025

Execution plan

We'll introduce proper support for OpenAPI upload in 3 layers.

Layer 1

Fix the current code so that type & format combos are aligned with the spec. The combo works both in OpenAPI 3.1.x and OpenAPI 3.0.x.

format=base64 is invalid and not existing. We should assert format=byte.


We should compare the media-type and media-range non-terminals differently, than we currently do. The reason is that both non-terminals can contain parameters.

application/octet-stream; param=1 - valid media-type/media-range

So instead of doing:

 if(
    contentType === "application/octet-stream"
    || contentType.indexOf("image/") === 0
    || contentType.indexOf("audio/") === 0
    || contentType.indexOf("video/") === 0
    ...
  ) {

We should be doing:

 if(
    contentType.startsWith("application/octet-stream")
    || contentType.startsWith("image/")
    || contentType.startsWith("audio/") 
    || contentType.startsWith("video/") 
    ...
  ) {

We should access the JSON Schema type keyword depending on OpenAPI version. In OpenAPI 3.0.x type==="string" assertion is fine, but in OpenAPI 3.1.x we have to do assertion as following expression: type==="string" || (Array.isArray(type) && type.includes("string"))

Layer 2

This layer is OpenAPI 3.1.x specific and modifies getType function form json-schema-2020-12 plugin, specifically inference of the type from the contentMediaType and contentEncoding keywords. When either one of those keywords is there, we can infer type="string".

Layer 3

Handling of new contentMediaType and contentEncoding keywords in OpenAPI 3.1.x.

Rules (assuming type="string" and format: * have not been defined):

  1. presence of specific contentType (key of attached Media Type Object) like "application/octet-stream", "image/", etc.. make below rules inconsequential and always indicate file input
  2. contentMediaType or contentEncoding has precedence/priority over type=string && format: byte | binary combo
  3. presence of contentMediaType containing any value indicates file input
  4. presence of contentEncoding when contentMediaType present, is inconsequential
  5. presence of contentEncoding when contentMediaType is not present indicates file input
  6. presence of combo type=string && format: byte | binary is asserted as the last option

There is an ambiguous case for rule 5. contentEncoding SHOULD be associated with type="string". But if type is omitted, JSON Schema treats the schema as applying to any type (open-ended). Therefore, in spec terms: it's valid, but ambiguous — it should be assumed to apply to strings. It will be addressed (to certain level) by Layer 2.

@glowcloud
Copy link
Contributor

Superseded by #10409 and #10412

@glowcloud glowcloud closed this Apr 11, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants