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

Client: FormData._gen_form_data ignores filename, explodes #2201

Closed
patrick-jones opened this issue Aug 15, 2017 · 3 comments
Closed

Client: FormData._gen_form_data ignores filename, explodes #2201

patrick-jones opened this issue Aug 15, 2017 · 3 comments

Comments

@patrick-jones
Copy link
Contributor

I am using the client to upload a file using FormData, almost exactly the same code as shown in this example. The main difference is that I am passing a file created by tempfile.TemporaryFile as the second argument to add_field.

The result is: TypeError: Can not serialize value type: <class '_io.BufferedRandom'> headers: {'Content-Type': 'application/vnd.ms-excel'} value: <_io.BufferedRandom name=23>

The root exception is actually thrown from helpers.guess_filename: TypeError: 'int' object is not subscriptable

Expected behaviour

There should be no need to call guess_filename because I specified a filename:
form.add_field('file', data, filename=filename, content_type=content_type)

And even if I didn't provide a filename, guess_filename should not throw an exception if name is not a string (which is apparently the case for tempfiles; notice that my tempfile has the number 23 for a name).

Actual behaviour

FormData._gen_form_data is not passing the filename to payload.get_payload, even though the filename is available. It seems like the code could be changed to include filename=dispparams.get('filename') in the kwargs for get_payload.

guess_filename assumes that name will be a string. Oddly enough, sometimes it's a number.

Steps to reproduce

Here is my code that produces the error. data is a tempfile.TemporaryFile(). The exception is thrown from the post call. url, filename, and content_type are all valid strings.

    async def post_temp_file(self, url, filename, content_type, data):
        form = FormData()
        form.add_field('file', data, filename=filename, content_type=content_type)

        async with self.rest.post(url, data=form) as response:
            await self._raise_for_status(response)
            body = await response.text()

        return json.loads(body)

Workaround

        f = BytesIO(data.read())
        setattr(f, 'filename', filename)
        form.add_field('file', f, filename=filename, content_type=content_type)

Your environment

Python 3.6.1 on Ubuntu

@asvetlov asvetlov added the bug label Aug 15, 2017
@patrick-jones
Copy link
Contributor Author

Upon further inspection, it looks like it doesn't matter that FormData._gen_form_data doesn't pass the filename to get_payload. The filename is saved with a call to part.set_content_disposition a few lines later. As long as guess_filename doesn't blow up everything is fine.

I will PR.

@asvetlov
Copy link
Member

Fixed by #2207

@lock
Copy link

lock bot commented Oct 28, 2019

This thread has been automatically locked since there has not been any recent activity after it was closed. Please open a [new issue] for related bugs.
If you feel like there's important points made in this discussion, please include those exceprts into that [new issue].
[new issue]: https://github.com/aio-libs/aiohttp/issues/new

@lock lock bot added the outdated label Oct 28, 2019
@lock lock bot locked as resolved and limited conversation to collaborators Oct 28, 2019
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

2 participants