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

How to state parameter requirements in HTTP headers? #2458

Open
lmmarsano opened this issue Feb 12, 2021 · 9 comments
Open

How to state parameter requirements in HTTP headers? #2458

lmmarsano opened this issue Feb 12, 2021 · 9 comments
Labels
headers media and encoding Issues regarding media type support and how to encode data (outside of query/path params)
Milestone

Comments

@lmmarsano
Copy link

lmmarsano commented Feb 12, 2021

For example, as described in the guide, in a request such as

POST /upload HTTP/1.1
Content-Length: 428
Content-Type: multipart/form-data; boundary=abcde12345
--abcde12345
Content-Disposition: form-data; name="profileImage"; filename="image1.png"
Content-Type: application/octet-stream
{…file content…}
--abcde12345--

how would a spec state that the filename parameter in header Content-Disposition is required and explain special usage in a description?
RFCs state that the filename parameter is optional.
It's not clear how to express parameters for a header object.

@spacether
Copy link

spacether commented Feb 21, 2021

If the Content-Disposition will be manually passed in by devs, how about setting it as type string in parameter.schema.type and set required to true in parameter.required. You could also add a regex pattern in parameter.schema.pattern that must pass for the value of Content-Disposition that describes the filename value as a string with length > 0.

Don't forget to include the body description like so.
In openapi-generator in the python client. We have a spec like this:

  /fake/uploadDownloadFile:
    post:
      tags:
        - fake
      summary: uploads a file and downloads a file using application/octet-stream
      description: ''
      operationId: uploadDownloadFile
      responses:
        '200':
          description: successful operation
          content:
            application/octet-stream:
              schema:
                type: string
                format: binary
                description: file to download
      requestBody:
        required: true
        content:
          application/octet-stream:
            schema:
              type: string
              format: binary
              description: file to upload

@lmmarsano
Copy link
Author

This doesn't match the request, however.
It's multipart/form-data.
I'm trying to follow the discussion on specifying headers for those.
The header, Content-Disposition, is standard.
However, the spec needs to say the parameter, filename, is required.
I'm thinking the parameter object for the header would need some combination of style matrix and schema type object.

requestBody:
  required: true
  content:
    multipart/form-data:
      schema:
        type: object
        properties:
          profileImage:
            type: string
            format: binary
      encoding:
        profileImage: # Property name
          contentType: application/octet-stream
          headers: # Custom headers
            Content-Disposition:
              description: part's filename
              style: matrix
              explode: true
              schema:
                type: object
                required:
                - form-data
                - name
                - filename
                properties:
                  form-data:
                    const: ''
                  name:
                    description: part name
                    type: string
                  filename:
                    description: name of file to be created
                    type: string

RFC 6570 says

If there is an explode modifier, expansion consists of appending each pair that has a defined value as either "name=value" or, if the value is the empty string and the expression type does not indicate form-style parameters (i.e., not a "?" or "&" type), simply "name".

However, this will put a ; before form-data, which is incorrect.
Is there something like path templating for headers?

@handrews
Copy link
Member

@lmmarsano unfortunately, there's no clear mapping from schemas or parameter styles into HTTP headers, in part because the syntax is pretty inconsistent across different headers. I think the best you could do would be to treat it as a string and use a regex 😕

@handrews handrews added Needs author feedback media and encoding Issues regarding media type support and how to encode data (outside of query/path params) labels Jan 28, 2024
Copy link
Contributor

github-actions bot commented Feb 4, 2024

This issue has been labeled with No recent activity because there has been no recent activity. It will be closed if no further activity occurs within 28 days. Please re-open this issue or open a new one after this delay if you need to.

@github-actions github-actions bot added the No recent activity The issue has not been updated in 7 days. label Feb 4, 2024
@lmmarsano
Copy link
Author

@handrews While I agree it's a challenge, it's not entirely inconsistent.
The http specification defines a set of rules for the bulk of cases.

Regex complexity to account for these rules can be considerable.
A regex-only solution may often force us to choose between

  • simple & overly constrained (clearer, more maintainable spec that rejects some valid header values)
  • complicated & correct (less readable, maintainable spec that accepts all valid header values).

For clearer, more maintainable specs, I wonder about interest in making the language more aware of the http spec on headers.

  • A choice to validate according to the common rules of the http spec.
  • Specify whether a header field is a list/repeatable or single-valued/non-repeatable.
  • Specify valid values and whether they are required.
  • Specify valid parameters and which are required.

While I understand OpenAPI specs largely serve http APIs with JSON payloads, the introduction states it's for http APIs generally, and this seems the logical place for rules in the http spec.

If the interest exists, I also wonder how we might best approach that

  • Schema dialect
  • OpenAPI specification revision
  • Specification extension
  • Something else?

@github-actions github-actions bot added Needs attention The author has replied and people with triage rights should take action. and removed Needs author feedback No recent activity The issue has not been updated in 7 days. labels Feb 5, 2024
@handrews
Copy link
Member

handrews commented Feb 5, 2024

@lmmarsano I had actually been thinking about leveraging the rules for the common cases (RFCs 8941 and 9110) and having an extension registry for mechanisms to support more unusual cases.

We can keep discussing headers here to see if there is something that might fit in OAS 3.2 (possibly leveraging the registries).

For the bigger-picture questions of modularity and extension, I would recommend looking at the Moonwalk discussions, where we are discussing breaking changes for the next major OAS release.

@lmmarsano
Copy link
Author

Cool, I didn't know about moonwalk.
I'm seeing approaches suggested here overlapping with the inclusion principle, reuse of internet standards, and parameterSchema.

Based on the participation guidelines, a draft feature in the registry you suggested makes sense.

RFC 8941 is stricter and more structured, so it might be preferable.

  • http dates are used by headers such as retry-after, so I imagine API authors wanting to represent such fields. While the http core production for http dates appears to be absent from the structured fields spec, the core spec states that members containing , ought to be delimited (probably by ): the stricter specification identifies such values as strings. Would defining a JSON schema format for http date be appropriate here?
  • The distinction between token and (quoted) string raises questions about representing that in a schema. The core spec treats quotes strictly as syntax, whereas the structured fields spec makes a semantic distinction (quotes identify strings). Maybe the specification language needs to draw a similar distinction?

@handrews handrews removed the Needs attention The author has replied and people with triage rights should take action. label Apr 28, 2024
@handrews
Copy link
Member

For HTTP dates, yeah we'd need to add a format value to the registry, probably.

I think that RFC 8941 would be handled one way (with one set of format values as needed), and the "common rules" in RFC 9110 would be handled another. They're similar, but we'd want to make a distinction because of various subtleties. That might include not worrying about the distinction between quoted strings and tokens for 9110, but making that distinction for 8941.

This would be for 3.2 (at the earliest), so there's some time to think about this while we focus on getting 3.0.4 and 3.1.1 out the door.

@kevinswiber
Copy link
Contributor

FYI: RFC 9651 has obsoleted RFC 8941.

Appendix D.  Changes from RFC 8941

   This revision of the "Structured Field Values for HTTP" specification
   has made the following changes:

   *  Added the Date Structured Type.  (Section 3.3.7)

   *  Stopped encouraging use of ABNF in definitions of new Structured
      Fields.  (Section 2)

   *  Moved ABNF to an informative appendix.  (Appendix C)

   *  Added a "Structured Type" column to the "Hypertext Transfer
      Protocol (HTTP) Field Name Registry".  (Section 5)

   *  Refined parse failure handling.  (Section 4.2)

   *  Added the Display String Structured Type.  (Section 3.3.8)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
headers media and encoding Issues regarding media type support and how to encode data (outside of query/path params)
Projects
None yet
Development

No branches or pull requests

4 participants