actix / examples

Community showcase and examples of Actix Web ecosystem usage.
Apache License 2.0
3.7k stars 807 forks source link

multipart example doesn't work #161

Closed mkpankov closed 5 years ago

mkpankov commented 5 years ago

Server:

[mkpankov@mkpankov-lenovo-x240]~/work/actix/examples/multipart% cargo run 
    Finished dev [unoptimized + debuginfo] target(s) in 0.62s
     Running `/home/mkpankov/work/actix/examples/target/debug/multipart`
[2019-08-10T14:18:52Z INFO  actix_server::builder] Starting 4 workers
[2019-08-10T14:18:52Z INFO  actix_server::builder] Starting server on 127.0.0.1:8080
1
[2019-08-10T14:18:56Z INFO  actix_web::middleware::logger] 127.0.0.1:36536 "POST / HTTP/1.1" 200 6 "-" "Python/3.7 aiohttp/3.5.4" 0.001850
1
failed: Multipart boundary is not found
[2019-08-10T14:18:56Z INFO  actix_web::middleware::logger] 127.0.0.1:36540 "POST / HTTP/1.1" 500 31 "-" "Python/3.7 aiohttp/3.5.4" 0.001922

Client:

[mkpankov@mkpankov-lenovo-x240]~/work/actix/examples/multipart% python3 client.py
Unclosed client session
client_session: <aiohttp.client.ClientSession object at 0x7fc9a4535cc0>
Unclosed connector
connections: ['[(<aiohttp.client_proto.ResponseHandler object at 0x7fc9a41f2588>, 1789.448346384)]']
connector: <aiohttp.connector.TCPConnector object at 0x7fc9a4535a58>
<ClientResponse(http://localhost:8080/) [200 OK]>
<CIMultiDictProxy('Content-Length': '6', 'Content-Type': 'application/json', 'Date': 'Sat, 10 Aug 2019 14:19:36 GMT')>

<ClientResponse(http://localhost:8080/) [500 Internal Server Error]>
<CIMultiDictProxy('Content-Length': '31', 'Content-Type': 'text/plain', 'Date': 'Sat, 10 Aug 2019 14:19:36 GMT')>

Unclosed client session
client_session: <aiohttp.client.ClientSession object at 0x7fc9a41d3160>
Unclosed connector
connections: ['[(<aiohttp.client_proto.ResponseHandler object at 0x7fc9a41f24c8>, 1789.46075974)]']
connector: <aiohttp.connector.TCPConnector object at 0x7fc9a41d3208>
Traceback (most recent call last):
  File "client.py", line 36, in <module>
    loop.run_until_complete(req2())
  File "/usr/lib64/python3.7/asyncio/base_events.py", line 584, in run_until_complete
    return future.result()
  File "client.py", line 31, in req2
    assert 200 == resp.status
AssertionError
mkpankov commented 5 years ago

Wireshark shows the request w/o problems: image

So it seems the server is at fault?

fafhrd91 commented 5 years ago

failed: Multipart boundary is not found

mkpankov commented 5 years ago

@fafhrd91 what are you trying to say?

fafhrd91 commented 5 years ago

That is from log output you posted

mkpankov commented 5 years ago

I've seen that, and I don't see how this explains why the example doesn't work. If you look at wireshark screenshot, there are boundaries, and all of them seem correct to me. If they aren't, please point out what's the problem, in your opinion.

fafhrd91 commented 5 years ago

Python client might be broken. Browsers work, I trust browser impl more

mattlockyer commented 5 years ago

I've successfully implemented multipart and built my formdata object using client side JavaScript. Perhaps you can try using the browser first then mimic in your own client code?

mkpankov commented 5 years ago

@mattlockyer that's nice, can you post minimal working example with your JavaScript client?

leizzer commented 5 years ago

Made a PR to remove python dependency I didn't like the lack of consistency, some times it fails and some times it passes.

Some reports of this issue on aiohttp https://github.com/aio-libs/aiohttp/issues/3544

mattlockyer commented 5 years ago

Pretty basic. data is ArrayBuffer. Not setting the type in the fetch body was a bit tricky, but I had to leave this out for another project involving a Go server as well. I'm guessing when the body is well encoded, servers determine the content type header themselves?

    const file = new File([data], 'upload')
    const formData = new FormData();
    formData.append(fileName, file);
    const upload = await fetch(SERVER + '/auth/upload', {
      body: formData
    }).then((res) => res.json())