swagger-api / swagger-api/swagger-ui

request.body missing with multipart/form-data

Open
#9,365 3 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
JavaScript
Stars
29k
Forks
9.3k
Avg merge
2d 23h
Merged PRs (30d)
25

Description

I'm in charge of modifying code that I did not write myself. The original coder did not keep the license file for Swagger-UI packaged up, so I pulled the version mentioned above for some clarity.

The code uses the requestInterceptor to add a request signature to the header before sending. The signature relies on content in request.body. This works fine except when the content type is set to multipart/form-data. In this case request.body is empty, causing the custom signing function to fail. Should the request.body be empty in this scenario? If so, how would one go about retrieving the form fields for the specific path as there are several?

  • Swagger-UI version: 5.9.2
  • Swagger/OpenAPI version: OpenAPI 3.0

Swagger/OpenAPI definition:
{ "openapi": "3.0.0", "info": { "title": "API Docs", "description": "Documentation for APIs.<br/><a href=\"api_to_pdf.php\" target=\"_blank\">Download PDF</a>", "version": "1.0.0" }, "servers": [ { "url": "https://<your_site>/api/actions", "description": "Server" } ], "paths": { "/upload/file/to/source": { "summary": "Upload File to Folder", "description": "Upload a file to a location within a source and create a new asset for it.", "parameters": [ { "$ref": "#/components/parameters/auth-user-header" }, { "$ref": "#/components/parameters/auth-sign-header" } ], "post": { "summary": "Upload File to Folder", "requestBody": { "required": false, "content": { "multipart/form-data": { "schema": { "$ref": "#/components/schemas/upload-file-to-source-request" } } } }, "responses": { "200": { "description": "ok", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/boolean-response" } } } } }, "tags": [ "Sources", "Upload" ] } } }, "components": { "parameters": { "auth-user-header": { "in": "header", "name": "X-User", "required": true, "schema": { "type": "string" }, "description": "Username of the user who's calling the API." }, "auth-sign-header": { "in": "header", "name": "X-Sign", "required": true, "schema": { "type": "string" }, "description": "Sha256 hash generated by concatenating user's session key with the payload submitted in the API request. When using 'Try it out' mode of API docs, just provide the session key and it will automatically generate the correct SHA-256 signature of the request payload." } }, "schemas": { "upload-file-to-source-request": { "type": "object", "properties": { "source": { "type": "integer", "description": "ID of the source the file should be uploaded to." }, "structure": { "type": "integer", "description": "ID of structure (folder) within the source we want to upload the file to. If left blank the file will be uploaded to the root of the source.<br/>Default: ''.", "default": "" }, "url": { "type": "string", "description": "The URL of a file to upload.<br/>Default: ''.", "default": "" }, "file": { "type": "string", "format": "binary", "description": "File to upload." } }, "encoding": { "profile": { "contentType": "application/json" } }, "required": [ "source" ] }, "boolean-response": { "type": "boolean", "description": "TRUE on success. FALSE otherwise." } } } }

Swagger UI:

window.onload = () => {
    window.ui = SwaggerUIBundle({
        spec: <?php echo json_encode($openapiJson)?>,
        dom_id: '#swagger-ui',
        requestInterceptor: async (request) => {
            console.log('Request', request);
            if(!request.headers['X-Sign']){
                return request;
            } 
            const hash = await generateSignature(request.headers['X-Sign'], (typeof request.body!='undefined' ? request.body : ''));
            request.headers['X-Sign'] = hash;
            return request;
        },
        presets: [
            SwaggerUIBundle.presets.apis,
            //SwaggerUIStandalonePreset
        ]
    });
};

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start with the requestInterceptor and SwaggerUIBundle configuration shown in the issue, then reproduce the supplied multipart/form-data OpenAPI operation in Swagger UI 5.9.2. Trace how the generated request represents form fields and files before the interceptor runs. Done means the expected request body behavior is established and the issue is resolved with a verified change or clear documented limitation.

Written by the indexing model from the issue text.

Assessment

Tech stack
javascript
Domain
frontend
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Needs clarification
Newbie friendliness
25/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.