connexion icon indicating copy to clipboard operation
connexion copied to clipboard

Crash when calling file upload endpoint with other content

Open Kulu-M opened this issue 4 years ago • 7 comments

Description

When using a file upload endpoint but POSTing anything else than a file, for example JSON, the application crashes on this line.

Expected behaviour

API should not crash.

Actual behaviour

API crashes.

Steps to reproduce

  1. Have an endpoint which accepts file upload.
paths:
  /upload:
    post:
      tags:
        - Upload
      operationId: mis.api.upload.upload.post
      description: This endpoint can be used to upload.
      requestBody:
        content:
          multipart/form-data:
            schema:
              type: object
              properties:
                filename:
                  type: array
                  items:
                    type: string
                    format: binary
      responses:
        "200":
          description: Success
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/uploadResult'
  1. Call this endpoint, with a JSON body request.
  2. Sadly, API crashes:
File "C:\...\virtualenvs\mis-KdSfneRH-py3.8\Lib\site-packages\connexion\decorators\validation.py", line 161, in wrapper data.update(dict.fromkeys(request.files, ''))  # validator expects string..
AttributeError: 'bytes' object has no attribute 'update'

Additional info:

Output of the commands:

  • python --version Python 3.8.2

  • pip show connexion | grep "^Version\:" Name: connexion Version: 2.7.0

Kulu-M avatar Jul 22 '20 12:07 Kulu-M

You need to include the suggested headers mentioned on Swagger doc for multipart

While calling the API endpoint, include the following headers:

Content-Type: multipart/form-data;
Content-Disposition: form-data;

Let me know if this solves your issue.

piyusharma95 avatar Dec 07 '20 06:12 piyusharma95

This does not resolve the issue. If you call the mentioned endpoint with a application/json body it results in 500 and the above mentioned error.

This means if you have an upload endpoint, the application can be crashed by consumers - and there is nothing you can do. Except I missed something...

Kulu-M avatar Dec 07 '20 12:12 Kulu-M

@Kulu-M I agree, this is a (minor) bug. Supplying a wrong request like this should result in an HTTP 400 BAD REQUEST error instead of a HTTP 500 error. It would be great if this could be addressed. I ran into similar additional errors with uploading files, specifically with supplying an incorrect body in combination with a multipart message, most of which we found workarounds for. Ideally bad requests should be handled gracefully by connexion since that way everyone else saves a lot of effort with individual debugging and workarounds.

joe42 avatar Aug 25 '21 11:08 joe42

Actually an HTTP 415 (unsupported media type) might be more appropriate here since it gives more detail on what exactly is wrong with the request.

joe42 avatar Aug 25 '21 13:08 joe42

As a workaround it is possible to catch the error by implementing a custom request body validator and returning the correct error message. A suggested fix would be to precede the line where the error occurs (see the first post): data.update(dict.fromkeys(request.files, '')) # validator expects string.. with a check for the current headers:

    content_type = connexion.request.headers.get('content-type')
    if content_type not in ('application/x-www-form-urlencoded', 'multipart/form-data'):
        # return an HTTP 415 error

joe42 avatar Aug 26 '21 12:08 joe42

We're having a similar issue, when trying to define an end-point with two different possible bodies: whenever we're not sending the "multipart/form-data" body, the application crashes, because it still tries to validate the body as multipart/form-data.

Is there any plan to eventually fix this issue? It's now 3 years old...

paniccia-taurob avatar Sep 13 '23 09:09 paniccia-taurob

Can reproduce, although with a different error message.

RobbeSneyders avatar Nov 01 '23 17:11 RobbeSneyders