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

bpo-22708: Upgrade HTTP CONNECT to protocol HTTP/1.1 #8305

Open
wants to merge 15 commits into
base: main
Choose a base branch
from

Conversation

handlerbot
Copy link

@handlerbot handlerbot commented Jul 16, 2018

Use protocol HTTP/1.1 when sending HTTP CONNECT tunnelling requests; generate Host: headers if one is not already provided (required by HTTP/1.1), convert IDN domains to punycode in HTTP CONNECT requests.

This builds upon and obsoletes #742. cc @berkerpeksag who reviewed that PR.

(I have signed the CLA, but it was less than a day ago, so the human review may not yet be completed.)

https://bugs.python.org/issue22708

Use protocol HTTP/1.1 when sending HTTP CONNECT tunnelling requests;
generate Host: headers if one is not already provided (required by
HTTP/1.1), convert IDN domains to punycode in HTTP CONNECT requests.
@handlerbot
Copy link
Author

handlerbot commented Jul 16, 2018

Working on fix for BytesWarning now.

@berkerpeksag berkerpeksag self-requested a review Jul 17, 2018
@berkerpeksag
Copy link
Member

berkerpeksag commented Jul 17, 2018

Thanks for updating that PR, I've just added this to my TODO list, but it may take a while.

Doc/library/http.client.rst Outdated Show resolved Hide resolved
Lib/http/client.py Outdated Show resolved Hide resolved
@handlerbot
Copy link
Author

handlerbot commented Jan 27, 2019

Hi @berkerpeksag, circling back to this one, do you still have time and interest in the topic, or should we find another reviewer?

@akhayyat
Copy link

akhayyat commented Jul 2, 2019

Is this going to be merged any time soon?

@csabella csabella requested review from berkerpeksag and removed request for berkerpeksag Feb 6, 2020
@berkerpeksag
Copy link
Member

berkerpeksag commented Feb 7, 2020

Sorry, I will try to review this PR this weekend.

@keelson
Copy link

keelson commented Sep 2, 2020

any update?

this bug currently blocks any integretion with the linkerd2 proxy as this throws a 400 bad request for connections inititaded by python apps

https://github.com/linkerd/linkerd2/pull/1200/files

@merwok
Copy link
Member

merwok commented Sep 23, 2020

It crashes in _tunnel on response line:

Can you show the exact error for this?

«crash» usually describes a segfault of the interpreter, is that what happended or was it a regular Python exception?

@merwok
Copy link
Member

merwok commented Sep 23, 2020

Please answer: what exactly do you see when you say «it crashes»?

@handlerbot
Copy link
Author

handlerbot commented Mar 5, 2021

Hi folks -- would love to try again to get this merged. :-) cc @berkerpeksag who I solicited the original review from, and tagging in @orsenthil and @SethMichaelLarson (I think this is the same GitHub identity for the person who approved #20959, that's who I am looking for, sorry if I tagged the wrong person) who have also reviewed PRs for Lib/http/client.py in the past...

@handlerbot
Copy link
Author

handlerbot commented Mar 5, 2021

Sigh, I did mean @sethmlarson not @SethMichaelLarson, sorry about that, the GitHub autocompleter was determined to mislead me!

@orsenthil orsenthil self-assigned this Mar 5, 2021
@orsenthil
Copy link
Member

orsenthil commented Mar 5, 2021

Hi Michael, Thanks for following up. I will be able to review and bring it to a closure.

Lib/http/client.py Outdated Show resolved Hide resolved
@yilinjuang
Copy link

yilinjuang commented Nov 7, 2021

any updates on this? would love to see this merge as it prevents our services from using certain proxies. thanks

@SadPencil
Copy link

SadPencil commented Mar 4, 2022

Please merge this PR as HTTP/1.0 does not define CONNECT. It breaks the compatibility with some proxies and it is Python's fault. This PR fixes this bug but it has been delayed for more than a year.

@merwok
Copy link
Member

merwok commented Mar 4, 2022

This PR needs to have the fle conflicts resolved and get reviewed by an HTTP domain expert.

A note: I don’t think the module is intended to run on its own for production-grade applications. nginx, waitress, uwsgi are all full-featured capable servers that can run python apps and/or work as reverse proxy.

@SadPencil
Copy link

SadPencil commented Mar 4, 2022

This PR needs to have the fle conflicts resolved and get reviewed by an HTTP domain expert.

A note: I don’t think the module is intended to run on its own for production-grade applications. nginx, waitress, uwsgi are all full-featured capable servers that can run python apps and/or work as reverse proxy.

Reply to the note above: HTTP CONNECT is also widely used as a client instead of a production-ready server. For example, people who live in a country that blocks some websites needs an proxy client for their daily uses, including writing some Python scripts.

@merwok
Copy link
Member

merwok commented Mar 4, 2022

My bad, this PR is for http.client not http.server!

@MaxwellDupre
Copy link
Contributor

MaxwellDupre commented May 27, 2022

If you want this included the target (versionchanged) needs to be 3.12 now.

@roman-vynar
Copy link

roman-vynar commented Oct 7, 2022

It is weird this is still not merged.

Effectively this is a couple of lines change w/o comments and tests:

--- /usr/lib/python3.X/http/client.py
+++ client.py
@@ -855,10 +855,20 @@

         self._tunnel_host, self._tunnel_port = self._get_hostport(host, port)
         if headers:
-            self._tunnel_headers = headers
+            self._tunnel_headers = headers.copy()
         else:
             self._tunnel_headers.clear()

+        saw_host_header = False
+        for header in self._tunnel_headers.keys():
+            if header.lower() == "host":
+                saw_host_header = True
+                break
+        if not saw_host_header:
+            encoded_host = self._tunnel_host.encode("idna").decode("ascii")
+            self._tunnel_headers["Host"] = "%s:%d" % (
+                encoded_host, self._tunnel_port)
+
     def _get_hostport(self, host, port):
         if port is None:
             i = host.rfind(':')
@@ -883,8 +893,8 @@
         self.debuglevel = level

     def _tunnel(self):
-        connect = b"CONNECT %s:%d HTTP/1.0\r\n" % (
-            self._tunnel_host.encode("ascii"), self._tunnel_port)
+        connect = b"CONNECT %s:%d %s\r\n" % (
+            self._tunnel_host.encode("ascii"), self._tunnel_port, self._http_vsn_str.encode("ascii"))
         headers = [connect]
         for header, value in self._tunnel_headers.items():
             headers.append(f"{header}: {value}\r\n".encode("latin-1"))

merwok and others added 3 commits Oct 7, 2022
@roman-vynar
Copy link

roman-vynar commented Oct 8, 2022

Thanks for making a progress!

Lib/http/client.py Outdated Show resolved Hide resolved
@handlerbot
Copy link
Author

handlerbot commented Oct 10, 2022

@merwok @orsenthil @ammaraskar @berkerpeksag This PR has been refreshed to be mergeable into the current state of HEAD, and all checks are passing. As you folks are Python organizations members, can any of you help review or provide suggestions as next steps? Thank you for your time! 🙏🏻

Lib/http/client.py Outdated Show resolved Hide resolved
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet