locustio / locust

Write scalable load tests in plain Python 🚗💨
MIT License
24.61k stars 2.96k forks source link

locust.contrib.fasthttp.FastHttpLocust does not support multipart/form-data #1252

Closed pcdinh closed 3 years ago

pcdinh commented 4 years ago

Describe the bug

I tried to upload a file using FastHttpLocust and got an exception

  File "c:\python37\lib\site-packages\locust\contrib\fasthttp.py", line 236, in post
    return self.request("POST", path, data=data, **kwargs)
  File "c:\python37\lib\site-packages\locust\contrib\fasthttp.py", line 178, in request
    response = self._send_request_safe_mode(method, url, payload=data, headers=headers, **kwargs)
  File "c:\python37\lib\site-packages\locust\contrib\fasthttp.py", line 124, in _send_request_safe_mode
    return self.client.urlopen(url, method=method, **kwargs)
  File "c:\python37\lib\site-packages\geventhttpclient\useragent.py", line 333, in urlopen
    req = self._make_request(url, method=method, headers=headers, payload=payload)
  File "c:\python37\lib\site-packages\geventhttpclient\useragent.py", line 285, in _make_request
    raise NotImplementedError
NotImplementedError

The geventhttpclient code confirms that this feature is not supported

    def _make_request(self, url, method='GET', headers=None, payload=None):
        req_headers = self.default_headers.copy()
        if headers:
            req_headers.update(headers)
        if payload:
            # Adjust headers depending on payload content
            content_type = req_headers.get('content-type', None)
            if not content_type and isinstance(payload, dict):
                req_headers['content-type'] = "application/x-www-form-urlencoded; charset=utf-8"
                payload = urlencode(payload)
            elif not content_type and isinstance(payload, text_type):
                req_headers['content-type'] = 'text/plain; charset=utf-8'
            elif not content_type:
                req_headers['content-type'] = 'application/octet-stream'
            elif content_type.startswith("multipart/form-data"):
                # See restkit for some example implementation
                # TODO: Implement it
                raise NotImplementedError
        return CompatRequest(url, method=method, headers=req_headers, payload=payload)

I expect that feature is supported. If it is not available for the moment, the document should mention it.

cyberw commented 4 years ago

Hi! Unfortunately this is in the geventhttpclient code base so it is hard for us to fix. I would suggest falling back to HttpLocust for now.

MiltiadisKoutsokeras commented 9 months ago

What about this PR: https://github.com/geventhttpclient/geventhttpclient/pull/159