MasoniteFramework / masonite

The Modern And Developer Centric Python Web Framework. Be sure to read the documentation and join the Discord channel for questions: https://discord.gg/TwKeFahmPZ
http://docs.masoniteproject.com
MIT License
2.21k stars 126 forks source link

Access raw input values from environ["wsgi.input"] #838

Open ReS4 opened 2 weeks ago

ReS4 commented 2 weeks ago

Is your feature request related to a problem?

Sometimes, the InputBag class doesn't parse the inputs correctly. for example, datatable generates this query string for server-side processing:

get_data?draw=1&columns[0][data]=id&columns[0][name]=id&columns[0][searchable]=true&columns[0][orderable]=false&columns[0][search][value]=&columns[0][search][regex]=false&columns[1][data]=first_name&columns[1][name]=first_name&columns[1][searchable]=true&columns[1][orderable]=false&columns[1][search][value]=&columns[1][search][regex]=false&columns[2][data]=last_name&columns[2][name]=last_name&columns[2][searchable]=true&columns[2][orderable]=false&columns[2][search][value]=&columns[2][search][regex]=false&columns[3][data]=email&columns[3][name]=email&columns[3][searchable]=true&columns[3][orderable]=false&columns[3][search][value]=&columns[3][search][regex]=false&columns[4][data]=&columns[4][name]=action&columns[4][searchable]=false&columns[4][orderable]=false&columns[4][search][value]=&columns[4][search][regex]=false&start=0&length=25&search[value]=&search[regex]=false&_=1731034705534

masonite parses this query string into something like this:

{'draw': '1', 'columns': {'0': 'false', '1': 'false', '2': 'false', '3': 'false', '4': 'false'}, 'start': '0', 'length': '25', 'search': {'regex': 'false'}, '_': '1731034845908'}

obviously, this is not the desired result.

What do we currently have to do now?

There is no way to access the original environ["wsgi.input"] value. Because it's an ioBuffer object, reading environ["wsgi.input"] value for the second time is impossible. (cannot use seek(0) method for this variable in some wsgi servers)

Describe the solution you'd like

In the InputBag class, introduce a new variable and store the environ["wsgi.input"] raw value for further access.

InputBag.py


    def parse(self, environ):
            ...
            elif "application/x-www-form-urlencoded" in environ.get("CONTENT_TYPE", ""):
                try:
                    request_body_size = int(environ.get("CONTENT_LENGTH", 0))
                except (ValueError):
                    request_body_size = 0

                request_body = environ["wsgi.input"].read(request_body_size)
                parsed_request_body = parse_qs(bytes(request_body).decode("utf-8"))

                self.raw_parsed_request_body = parsed_request_body  # < This line should do the job

                self.post_data = self.parse_dict(parsed_request_body)

...

Describe alternatives you've considered

No response

Would this be a breaking change ?

Anything else ?

No response