prism icon indicating copy to clipboard operation
prism copied to clipboard

'multipart/form-data' will always return a validation error

Open SeMuell opened this issue 2 years ago • 6 comments

Describe the bug

The validation always fails whenever a multipart/form-data content type is used in the requestBody. This prevents the normal usage of prism without any other proxy server (like nginx) on which such requests can be filtered out.

To Reproduce

  1. Given this OpenAPI document (stored as testapi.yaml)
openapi: '3.1.0'
paths:
  /path:
    post:
      responses:
        200:
          content:
            text/plain:
              example: ok
      requestBody:
        content:
          multipart/form-data:
            schema:
              type: object
              properties:
                testData:
                  type: string
              required:
                - "testData"
  1. Run this CLI command .\prism-cli-win.exe mock -h 127.0.0.1 .\testapi.yaml
  2. Write a non-empty post request to http://127.0.0.1/path with included form-data in the request body
  3. See response error
 {
    "type": "https://stoplight.io/prism/errors#UNPROCESSABLE_ENTITY",
    "title": "Invalid request",
    "status": 422,
    "detail": "Your request is not valid and no HTTP validation response was found in the spec, so Prism is generating this error for you.",
    "validation": [
        {
            "location": [
                "body"
            ],
            "severity": "Error",
            "code": "type",
            "message": "must be object"
        }
    ]
}

Expected behavior

It is expected that the response defined in the example is returned.

Additional context

As one of the last PR #1990 the validation is skipped when an empty request is send. As a simple workaround this could also be implemented for the case multipart/form-data is used.

gz#8297

(related to Zendesk ticket #8297)

SeMuell avatar Mar 11 '22 09:03 SeMuell

thanks @SeMuell. i'm looking into this - i notice we have several feature requests closed #432 #1012 - i'll leave this open as we discuss internally.

daniel-white avatar Mar 16 '22 12:03 daniel-white

Our project also needs multipart/form-data support because we use multipart/form-data to upload files. How about responding in the following ways?

packages/http-server/src/server.ts
//~~~

import * as formidable from 'formidable';

//~~~

function parseRequestBody(request: IncomingMessage) {
  // if no body provided then return null instead of empty string
  if (
    // If the body size is null, it means the body itself is null so the promise can resolve with a null value
    request.headers['content-length'] === '0' ||
    (request.headers['content-type'] === undefined &&
      request.headers['transfer-encoding'] === undefined &&
      request.headers['content-length'] === undefined)
  ) {
    return Promise.resolve(null);
  }

  if (typeIs(request, ['application/json', 'application/*+json'])) {
    return json(request, { limit: '10mb' });
  }

  if (typeIs(request, ['multipart/form-data'])) {
    const form = formidable({ multiples: true });
    return new Promise((resolve, reject) => {
      form.parse(request, (error, fields, files) => {
        if (error) {
          reject(error);
          return;
        }
        resolve({ ...fields, ...files });
      });
    });
  }

  return text(request, { limit: '10mb' });
}

yuki0410-dev avatar Feb 07 '23 07:02 yuki0410-dev

I want to make sure it works, but I dont know how to make sure @stoplight/prism-http-server` works....

yuki0410-dev avatar Feb 07 '23 07:02 yuki0410-dev

Sorry. I'm using @stoplight/[email protected] and I also have the above problem. Is there any solution for the above problem?

NguyenPhuongNam-lab avatar May 16 '23 03:05 NguyenPhuongNam-lab

It would be nice if we can disable validatior when using multipart/form-data content by a parameter of @stoplight/prism-cli.

loclv avatar May 16 '23 09:05 loclv

I discovered this issue when I was using Prism in proxy mode. The real backend was rejecting my uploads complaining that the file I was trying to upload was not valid. The upload worked when I decided to skip the Prism proxy.

My workaround, for now, is to use the --validate-request false option only when I need to upload this file.

dzegarra avatar Jun 14 '23 14:06 dzegarra