Skip to content

Generate better server code for response content */* (dynamic Content-Type) #859

@brandonbloom

Description

@brandonbloom

Description

When an OpenAPI response uses content: {'*/*': ...} to indicate the response media type is intentionally unconstrained / dynamic / extensible, the generated server serializer currently emits code that:

  1. calls converter.validateAcceptIfPresent("*/*", in: request.headerFields), and
  2. sets the outgoing Content-Type to "*/*" (e.g. via setResponseBodyAsBinary(..., contentType: "*/*")).

This causes two practical problems:

  • Client compatibility: it effectively forces clients to include Accept: */* just to pass validation (a client sending Accept: application/json can be rejected even though the operation is intentionally “any content”).
  • Bad response header: it emits Content-Type: */*, which is not a useful concrete media type to put on the wire.

We’d like wildcard */* to mean “no static content negotiation; content type is chosen dynamically at runtime”, not “alias for application/octet-stream”.

Commit hash: ecf21fdf08d4cf30ca506bb822f5fe580e090efb

Reproduction

Minimal spec:

# openapi.yaml
openapi: 3.0.3
info:
  title: t
  version: 1.0.0
paths:
  /download:
    get:
      operationId: download
      responses:
        "200":
          description: ok
          content:
            "*/*":
              schema:
                type: string
                format: binary

Minimal generator config:

# openapi-generator-config.yaml
mode:
  - types
  - server

In the generated server serializer, the */* response path includes validateAcceptIfPresent("*/*") and emits Content-Type: */*.

Package version(s)

  • swift-openapi-generator: commit ecf21fdf08d4cf30ca506bb822f5fe580e090efb
  • (also involves generated code’s usage of swift-openapi-runtime Converter.validateAcceptIfPresent / setResponseBodyAsBinary)

Expected behavior

For response content type exactly */* (server serializers):

  1. Skip validateAcceptIfPresent entirely.
  2. Do not emit Content-Type: */*.

However, simply omitting Content-Type is not ideal; what we really want is dynamic Content-Type.

Feature request: plumb dynamic headers/media type through the generated output model for the */* case, so the handler can provide a real Content-Type at runtime.

One concrete approach would be to model the */* body case as something that carries header fields too, for example:

  • case any(OpenAPIRuntime.UndocumentedPayload) (reusing an existing runtime type that carries headerFields + body), or
  • a dedicated “wildcard response payload” type (e.g. { headerFields: HTTPFields, body: HTTPBody } or { contentType: String, body: HTTPBody }).

Then generated server serialization for this case would:

  • not validate Accept,
  • merge the payload’s header fields into response.headerFields (including a real Content-Type when provided),
  • return the payload body.

Environment

$ swift --version
swift-driver version: 1.127.14.1 Apple Swift version 6.2 (swiftlang-6.2.0.19.9 clang-1700.3.19.1)
Target: arm64-apple-macosx26.0

$ uname -a
Darwin Brandons-MacBook-Pro.local 25.2.0 Darwin Kernel Version 25.2.0: Tue Nov 18 21:09:56 PST 2025; root:xnu-12377.61.12~1/RELEASE_ARM64_T6041 arm64

Additional information

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions