Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Enable prepared statements over http.client._MAXLINE limit #173

Closed

Conversation

mdesmet
Copy link
Contributor

@mdesmet mdesmet commented Apr 22, 2022

Fixes #148

Headers can become much longer then what is currently suported in Python's http.client. This code patches the header parsing from http.client to be able to parse the headers coming back from the Trino server.

Test is included. when removing the disable_header_limit() in client.py, the test will fail with requests.exceptions.ConnectionError: ('Connection aborted.', LineTooLong('got more than 65536 bytes when reading header line')).

@cla-bot cla-bot bot added the cla-signed label Apr 22, 2022
@@ -9,6 +9,7 @@
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
import http
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

from http.client import _MAXLINE

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That actually doesn't comply with the pre-commit check as it doesn't support private attributes.

tests/integration/test_dbapi_integration.py:15: error: Module "http.client" has no attribute "_MAXLINE"
Found 1 error in 1 file (checked 32 source files)

I think we don't want to import http.client at all in the module namespace as we only rely on some private property. I moved the import to the test itself.

trino/client.py Outdated
headers.append(line)
if line in (b'\r\n', b'\n', b''):
break
hstring = b''.join(headers).decode('iso-8859-1')
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: header_string

trino/client.py Outdated


# Disable header limit to avoid LineTooLong('got more than 65536 bytes when reading header line')
disable_header_limit()
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could this be moved into e.g ClientSession or TrinoRequest class?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It feels a lot less pythonic to me. it works of course and hides this override in TrinoRequest instead of the module's namespace.

class TrinoRequest: 
    @staticmethod
    def _disable_header_limit():
        import http.client
        import email.parser
        from http.client import HTTPMessage, _MAXLINE

        def parse_headers(fp, _class=HTTPMessage):
            headers = []
            while True:
                line = fp.readline(_MAXLINE + 1)
                headers.append(line)
                if line in (b'\r\n', b'\n', b''):
                    break
            header_string = b''.join(headers).decode('iso-8859-1')
            return email.parser.Parser(_class=_class).parsestr(header_string)

        http.client.parse_headers = parse_headers

    # Disable header limit to avoid LineTooLong('got more than 65536 bytes when reading header line')
    _disable_header_limit.__func__()

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I created a helper class for this override. Let me know WDYT.

@mdesmet mdesmet force-pushed the feature/fix_http_client_maxline branch 2 times, most recently from d08c906 to e3ecce6 Compare April 27, 2022 18:32
@mdesmet mdesmet force-pushed the feature/fix_http_client_maxline branch from e3ecce6 to 00dd234 Compare April 27, 2022 18:33
@mdesmet mdesmet closed this Nov 4, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Development

Successfully merging this pull request may close these issues.

Too large headers when inserting data
2 participants