Client Request body Empty

Background: I'm using a cloudflare tunnel. I'm writing an API. Problem: When I try to reach the API endpoints using my domain name as host, through the tunnel, I don't get the request body from client at all! This is present in neither the logs that the API backend generates, nor the logs stream on cloudflare tunnels log stream dashboard. The API backend receives and sends responses correctly when I access it on localhost directly. Example:
curl -X GET https://api.brightprogrammer.in/list_users \
-H "Content-Type: application/json" -H "Content-Length: 24" \
-d '{"user_type": "student"}'

{"error": "Bad Request."}
curl -X GET https://api.brightprogrammer.in/list_users \
-H "Content-Type: application/json" -H "Content-Length: 24" \
-d '{"user_type": "student"}'

{"error": "Bad Request."}
vs
curl -X GET http://localhost:1337/list_users \
-H "Content-Type: application/json" -H "Content-Length: 24" \
-d '{"user_type": "student"}'

{
"user_list": [
{
"user_name": "john_doe",
"user_type": "admin"
},
],
"has_more": false
}
curl -X GET http://localhost:1337/list_users \
-H "Content-Type: application/json" -H "Content-Length: 24" \
-d '{"user_type": "student"}'

{
"user_list": [
{
"user_name": "john_doe",
"user_type": "admin"
},
],
"has_more": false
}
Logs Generated:
[INFO] [2024-12-24 11:38:06] [main:352] REQUEST :GET /list_users HTTP/1.1
Host: api.brightprogrammer.in
User-Agent: curl/8.7.1
Content-Length: 24
Accept: */*
Accept-Encoding: gzip, br
Cdn-Loop: cloudflare; loops=1
Cf-Connecting-Ip: 2405:201:a408:e81b:fc94:99bc:bc8:604a
Cf-Ipcountry: IN
Cf-Ray: 8f6e6a37ce6b667a-AMS
Cf-Visitor: {"scheme":"https"}
Cf-Warp-Tag-Id: 2127ba3f-3f68-4f00-9b4e-ee67ef924542
Connection: keep-alive
Content-Type: application/json
X-Forwarded-For: 2405:201:a408:e81b:fc94:99bc:bc8:604a
X-Forwarded-Proto: https


[INFO] [2024-12-24 11:38:06] [HttpRequestParse:272] request ended while 24 bytes were left to read.
[INFO] [2024-12-24 11:38:06] [main:356] failed to parse http request
[INFO] [2024-12-24 11:38:06] [main:352] REQUEST :GET /list_users HTTP/1.1
Host: api.brightprogrammer.in
User-Agent: curl/8.7.1
Content-Length: 24
Accept: */*
Accept-Encoding: gzip, br
Cdn-Loop: cloudflare; loops=1
Cf-Connecting-Ip: 2405:201:a408:e81b:fc94:99bc:bc8:604a
Cf-Ipcountry: IN
Cf-Ray: 8f6e6a37ce6b667a-AMS
Cf-Visitor: {"scheme":"https"}
Cf-Warp-Tag-Id: 2127ba3f-3f68-4f00-9b4e-ee67ef924542
Connection: keep-alive
Content-Type: application/json
X-Forwarded-For: 2405:201:a408:e81b:fc94:99bc:bc8:604a
X-Forwarded-Proto: https


[INFO] [2024-12-24 11:38:06] [HttpRequestParse:272] request ended while 24 bytes were left to read.
[INFO] [2024-12-24 11:38:06] [main:356] failed to parse http request
vs
[INFO] [2024-12-24 11:39:02] [main:352] REQUEST :GET /list_users HTTP/1.1
Host: localhost:1337
User-Agent: curl/8.7.1
Accept: */*
Content-Type: application/json
Content-Length: 24

{"user_type": "student"}
[INFO] [2024-12-24 11:39:02] [main:352] REQUEST :GET /list_users HTTP/1.1
Host: localhost:1337
User-Agent: curl/8.7.1
Accept: */*
Content-Type: application/json
Content-Length: 24

{"user_type": "student"}
Expected: The backend through tunnel receives full request body, like it happens when not using the tunnel.
7 Replies
Tim Anthony
Tim Anthony2mo ago
Youre sending a Get request with a POST body. While this isn‘t explicitly diallowed in the Http spec, it‘s mostly not supported and you should use POST etc for that
brightprogrammer
brightprogrammerOP2mo ago
I tried all 4 combinations of JSON and FORM-BODY with GET and POST
Tim Anthony
Tim Anthony2mo ago
Should be Post, wouldn‘t try further with Get. Your server doesn‘t receive any Post body data?
Chaika
Chaika2mo ago
You don't need to specify the content-length either, it's auto-generated, manually specifying is likely just to cause you issues, ex:
curl -X POST https://127.0.0.1/list_users \ -H "Content-Type: application/json" \ -d '{"user_type": "student"}' -vvv
brightprogrammer
brightprogrammerOP2mo ago
Tried that as well I know it's auto generated, but just to be sure, I added that. I tried some online API testing tools as well Bump
Chaika
Chaika2mo ago
I'd get the logs both from Cloudflare tunnel and from your backend when you send it as POST request and don't manually specify the content-length
brightprogrammer
brightprogrammerOP2mo ago
Cloudflare logs don't show the form body or json, whichever one I set The server is up and always running if anyone wants to give it a shot
curl -X GET https://api.brightprogrammer.in/list_users \
-H "Content-Type: application/json" \
-d '{"user_type": "student"}'
curl -X GET https://api.brightprogrammer.in/list_users \
-H "Content-Type: application/json" \
-d '{"user_type": "student"}'
Curl request I'm using for testing. This is a big blocker for me. check https://api.brightprogrammer.in/docs for docs This is how it looks in cloudflare zero-trust tunnel logs
{
"connIndex": 3,
"originService": "http://localhost:1337",
"ingressRule": 0,
"host": "api.brightprogrammer.in",
"path": "/list_users",
"headers": {
"Accept": [
"*/*"
],
"Accept-Encoding": [
"gzip, br"
],
"Cf-Ray": [
"<redacted>"
],
"Cf-Warp-Tag-Id": [
"<redacted>"
],
"Content-Type": [
"application/json"
],
"X-Forwarded-Proto": [
"https"
],
"Cdn-Loop": [
"cloudflare; loops=1"
],
"Cf-Connecting-Ip": [
"<ip-redacted>"
],
"Cf-Ipcountry": [
"IN"
],
"Cf-Visitor": [
"{\"scheme\":\"https\"}"
],
"Content-Length": [
"24"
],
"User-Agent": [
"curl/8.7.1"
],
"X-Forwarded-For": [
"<ip-redacted>"
]
},
"content-length": 24
}
{
"connIndex": 3,
"originService": "http://localhost:1337",
"ingressRule": 0,
"host": "api.brightprogrammer.in",
"path": "/list_users",
"headers": {
"Accept": [
"*/*"
],
"Accept-Encoding": [
"gzip, br"
],
"Cf-Ray": [
"<redacted>"
],
"Cf-Warp-Tag-Id": [
"<redacted>"
],
"Content-Type": [
"application/json"
],
"X-Forwarded-Proto": [
"https"
],
"Cdn-Loop": [
"cloudflare; loops=1"
],
"Cf-Connecting-Ip": [
"<ip-redacted>"
],
"Cf-Ipcountry": [
"IN"
],
"Cf-Visitor": [
"{\"scheme\":\"https\"}"
],
"Content-Length": [
"24"
],
"User-Agent": [
"curl/8.7.1"
],
"X-Forwarded-For": [
"<ip-redacted>"
]
},
"content-length": 24
}
The problem seems to be in cloudflare itself. This is surely a bug. I checked with ngrok and it works flawlessly

Did you find this page helpful?