Skip to content

request.form empty for certain form POST request payloads #2734

@dividebysandwich

Description

@dividebysandwich

I have a weird one, and I admit I am not entirely sure if it's a problem in Werkzeug or maybe somewhere deeper:

I have an ecowitt weather station and am happily getting data pushed to a python script that works great. Recently someone else wanted to do the same, installed my script but... it just didn't work. We found that the only difference was that I was still on python 3.6.9 and Werkzeug 2.0.3, whereas he was on Python 3.9.2 and Werkzeug 2.3.6

What happens is that in the route handler, request.form is empty depending on how the form request looks in detail.

Here's the code snippet:

@app.route('/weather/report', methods=['POST'])
def receiveEcoWitt():
    print("Data size: " + str(len(request.form)))
    data = request.form
    for key in data:
        print(f"{key}: {data[key]}\n")

So far so easy, right? Now sending a POST request using a simple html form works fine as long as it looks like this:

POST /weather/report HTTP/1.1
Host: 192.168.178.208:8100
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:109.0) Gecko/20100101 Firefox/114.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
Content-Type: application/x-www-form-urlencoded
Content-Length: 20
Origin: null
Connection: keep-alive
Upgrade-Insecure-Requests: 1

fname=John&lname=Doe

With that request, request.form is filled and the data can be parsed normally.
However, the Ecowitt station sends requests that have a different set of header fields, which looks like this:

POST /weather/report HTTP/1.1
HOST: 192.168.178.208
Connection: Close
Content-Type: application/x-www-form-urlencoded
Content-Length:502

PASSKEY=78D8DCE861B2164BAD38A473167ACFD2&stationtype=GW2000A_V2.2.4&runtime=1247&dateutc=2023-06-17+10:34:52&tempinf=87.98&humidityin=43&baromrelin=29.158&baromabsin=29.158&tempf=71.60&humidity=57&winddir=44&windspeedmph=0.00&windgustmph=0.00&maxdailygust=1.12&solarradiation=5.52&uv=0&rrain_piezo=0.000&erain_piezo=0.000&hrain_piezo=0.000&drain_piezo=0.000&wrain_piezo=0.000&mrain_piezo=0.000&yrain_piezo=0.000&ws90cap_volt=2.2&ws90_ver=132&wh26batt=0&wh90batt=2.98&freq=868M&model=GW2000A&interval=16

Sending that request results in an empty request.form. It's also no use to try and use request.get_data() or stuff like that. The method in both requests is POST.

What should happen: Both requests should work and request.form should be filled in both cases.

This works fine in Python 3.6.9 and Werkzeug 2.0.3

Environment:

Python v3.9.2
Werkzeug v2.3.6

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions