When I run my first sample (the first official tutorial) using FastAPI, I notice something weird when testing with curl.
I launch the server with:
fastapi dev main.py
To test the endpoint, I execute:
curl http://127.0.0.1:8000
I logically receive the output:
{"Hello":"World"}
But if I execute the same request using localhost instead of 127.0.0.1, I get:
curl: (52) Empty reply from server
If I use wget:
wget -qO - http://localhost:8000
It returns the proper Hello World JSON body (it works).
I saw many post regarding the uvicorn configuration, but since wget works correctly, I guess the issue is more on the curl side.
I used to have proxy configuration, but I unset the environment variables http_proxy and https_proxy to make sure everything works locally.
I checked similar issues on StackOverflow, but most of the time, if localhost is not working, 127.0.0.1 is also not working.
As I was writing this question, I found a potential reason, hence I write this answer.
When increasing the verbosity with the -vvv option in curl, I noticed this:
10:46:07.594948 [0-0] == Info: Host localhost:8000 was resolved.
10:46:07.595282 [0-0] == Info: IPv6: ::1
10:46:07.595449 [0-0] == Info: IPv4: 127.0.0.1
10:46:07.595633 [0-0] == Info: [SETUP] added
10:46:07.595957 [0-0] == Info: Trying [::1]:8000...
10:46:07.596717 [0-0] == Info: [SETUP] Curl_conn_connect(block=0) -> 0, done=0
10:46:07.597169 [0-0] == Info: [SETUP] Curl_conn_connect(block=0) -> 0, done=1
10:46:07.597591 [0-0] == Info: Established connection to localhost (::1 port 8000) from ::1 port 53406
... meaning it tries first the IPv6 address before the IPv4: [::1]:8000
Now, If I force curl to use IPv4:
curl -4 http://localhost:8000
it works!
My observations:
uvicorn default configuration only manages the IPv4 and not IPv6.curl is using first IPv6 as default loopback address and not IPv4wget is using first IPv4 as default loopback address and not IPv6