Giter VIP home page Giter VIP logo

jawah / urllib3.future Goto Github PK

View Code? Open in Web Editor NEW

This project forked from urllib3/urllib3

20.0 2.0 1.0 7.53 MB

urllib3.future is the supercharged low level http client we dreamed of. Support HTTP/1.1, HTTP/2, and HTTP/3 with multiplexed connections! With DNS over QUIC, TLS, HTTPS and UDP. DNSSEC Protected & Async!

Home Page: https://urllib3future.readthedocs.io/en/latest/

License: MIT License

Shell 0.04% Python 99.89% Dockerfile 0.07%
http2 http3 multiplexed quic streams urllib3 dns dns-over-https dns-over-quic dns-over-tls dns-over-udp dnssec doh doq dot async asyncio

urllib3.future's Introduction

urllib3.future logo

PyPI Version Python Versions
urllib3.future is as BoringSSL is to OpenSSL but to urllib3 (except support is available!)
✨🍰 Enjoy HTTP like its 2024 🍰✨
💰 Promotional offer, get everything and more for 40k 0$!
Wondering why and how this fork exist? Why urllib3 does not merge this, even partially? Take a peek at this article!

⚡ urllib3.future is a powerful, user-friendly HTTP client for Python.
⚡ urllib3.future goes beyond supported features while remaining compatible.
⚡ urllib3.future brings many critical features that are missing from both the Python standard libraries and urllib3:

  • Async.
  • Task safety.
  • Thread safety.
  • Happy Eyeballs.
  • Connection pooling.
  • Unopinionated about OpenSSL.
  • Client-side SSL/TLS verification.
  • Highly customizable DNS resolution.
  • File uploads with multipart encoding.
  • DNS over UDP, TLS, QUIC, or HTTPS. DNSSEC protected.
  • Helpers for retrying requests and dealing with HTTP redirects.
  • Support for gzip, deflate, brotli, and zstd encoding.
  • Support for Python/PyPy 3.7+, no compromise.
  • HTTP/1.1, HTTP/2 and HTTP/3 support.
  • Proxy support for HTTP and SOCKS.
  • Detailed connection inspection.
  • HTTP/2 with prior knowledge.
  • Multiplexed connection.
  • Mirrored Sync & Async.
  • Amazingly Fast.

urllib3.future is powerful and easy to use:

>>> import urllib3
>>> pm = urllib3.PoolManager()
>>> resp = pm.request("GET", "https://httpbin.org/robots.txt")
>>> resp.status
200
>>> resp.data
b"User-agent: *\nDisallow: /deny\n"
>>> resp.version
20

or using asyncio!

import asyncio
import urllib3

async def main() -> None:
    async with urllib3.AsyncPoolManager() as pm:
        resp = await pm.request("GET", "https://httpbin.org/robots.txt")
        print(resp.status)  # 200
        body = await resp.data
        print(body)  # # b"User-agent: *\nDisallow: /deny\n"
        print(resp.version)  # 20

asyncio.run(main())

Installing

urllib3.future can be installed with pip:

$ python -m pip install urllib3.future

You either do

import urllib3

Or...

import urllib3_future

Or... upgrade any of your containers with...

FROM python:3.12

# ... your installation ...
RUN pip install .
# then! (after every other pip call)
RUN pip install urllib3-future

Doing import urllib3_future is the safest option if you start a project from scratch for you as there is a significant number of projects that require urllib3.

Notes / Frequently Asked Questions

  • It's a fork

⚠️ Installing urllib3.future shadows the actual urllib3 package (depending on installation order). The semver will always be like MAJOR.MINOR.9PP like 2.0.941, the patch node is always greater or equal to 900.

Support for bugs or improvements is served in this repository. We regularly sync this fork with the main branch of urllib3/urllib3 against bugfixes and security patches if applicable.

  • Why replacing urllib3 when it is maintained?

Progress does not necessarily mean to be a revisionist, first we need to embrace what was graciously made by our predecessors. So much knowledge has been poured into this that we must just extend it.

We attempted to participate in urllib3 development only to find that we were in disagreement on how to proceed. It happens all the time, even on the biggest projects out there (e.g. OpenSSL vs BoringSSL or NSS or LibreSSL...))

  • OK, but I got there because I saw that urllib3 was replaced in my environment!

Since Forks are allowed (fortunately for us); It how package manager do things.

We know how sensible this matter is, this is why we are obligated to ensure the highest level of compatibility and a fast support in case anything happen. We are probably going to be less forgiven in case of bugs than the original urllib3. For good~ish reasons, we know.

The matter is taken with utmost seriousness and everyone can inspect this package at will.

We regularly test this fork against the most used packages (that depend on urllib3, especially those who plunged deep into urllib3 internals).

Finally, rare is someone "fully aware" of their transitive dependencies. And "urllib3" is forced into your environments regardless of your preferences.

  • Wasn't there any other solution than having an in-place fork?

We assessed many solutions but none were completely satisfying. We agree that this solution isn't perfect and actually put a lot of pressure on us (urllib3-future).

Here are some of the reasons (not exhaustive) we choose to work this way:

A) Some major companies may not be able to touch the production code but can "change/swap" dependencies.

B) urllib3-future main purpose is to fuel Niquests, which is itself a drop-in replacement of Requests. And there's more than 100 packages commonly used that plug into Requests, but the code (of the packages) invoke urllib3 So... We cannot fork those 100+ projects to patch urllib3 usage, it is impossible at the moment, given our means. Requests trapped us, and there should be a way to escape the nonsense "migrate" to another http client that reinvent basic things and interactions.

C) We don't have to reinvent the wheel.

D) Some of our partners started noticing that HTTP/1 started to be disabled by some webservices in favor of HTTP/2+ So, this fork can unblock them at (almost) zero cost.

  • OK... then what do I gain from this?
  1. It is faster than its counterpart, we measured gain up to 2X faster in a multithreaded environment using a http2 endpoint.
  2. It works well with gevent / does not conflict. We do not use the standard queue class from stdlib as it does not fit http2+ constraints.
  3. Leveraging recent protocols like http2 and http3 transparently. Code and behaviors does not change one bit.
  4. You do not depend on the standard library to emit http/1 requests, and that is actually a good news. http.client has numerous known flaws but cannot be fixed as we speak. (e.g. urllib3 is based on http.client)
  5. There a ton of other improvement you may leverage, but for that you will need to migrate to Niquests or update your code to enable specific capabilities, like but not limited to: "DNS over QUIC, HTTP" / "Happy Eyeballs" / "Native Asyncio" / "Advanced Multiplexing".
  6. Non-blocking IO with concurrent streams/requests. And yes, transparently.
  7. It relaxes some constraints established by upstream in their version 2, thus making it easier to upgrade from version 1.
  • Is this funded?

Yes! We have some funds coming in regularly to ensure its sustainability.

  • How can I restore urllib3 to the "legacy" version?

You can easily do so:

# remove both
python -m pip uninstall -y urllib3 urllib3-future
# reinstate legacy urllib3
python -m pip install urllib3

OK! How to let them both?

# remove both
python -m pip uninstall -y urllib3 urllib3-future
# install urllib3-future
python -m pip install urllib3-future
# reinstate legacy urllib3
python -m pip install urllib3

The order is (actually) important.

  • Can you guarantee us that everything will go smooth?

Guarantee is a strong word with a lot of (legal) implication. We cannot offer a "guarantee". But, we answer and solve issues in a timely manner as you may have seen in our tracker.

We take a lot of precaution with this fork, and we welcome any contribution at the sole condition that you don't break the compatibility between the projects. Namely, urllib3 and urllib3-future.

Every software is subject to bugs no matter what we do.

This being said, rest assured, we kept all the tests from urllib3 to ensure that what was guaranteed by upstream is also carefully watched down there. See the CI/pipeline for yourself.

In addition to that, we enforced key integration tests to watch how urllib3-future act with some critical projects.

  • OS Package Managers

Fellow OS package maintainers, you cannot just build and ship this package to your package registry. As it override urllib3 and due to its current criticality, you'll have to set:

URLLIB3_NO_OVERRIDE=true python -m build. Set URLLIB3_NO_OVERRIDE variable with "true" in it.

It will prevent the override.

Compatibility with downstream

You should always install the downstream project prior to this fork. It is compatible with any program that use urllib3 directly or indirectly.

e.g. I want requests to be use this package.

python -m pip install requests
python -m pip install urllib3.future

Nowadays, we suggest using the package Niquests as a drop-in replacement for Requests. It leverages urllib3.future capabilities appropriately.

Testing

To ensure that we serve HTTP/1.1, HTTP/2 and HTTP/3 correctly we use containers that simulate a real-world server that is not made with Python.

Although it is not made mandatory to run the test suite, it is strongly recommended.

You should have docker installed and the compose plugin available. The rest will be handled automatically.

python -m pip install nox
nox -s test-3.11

The nox script will attempt to start a Traefik server along with a httpbin instance. Both Traefik and httpbin are written in golang.

You may prevent the containers from starting by passing the following environment variable:

TRAEFIK_HTTPBIN_ENABLE=false nox -s test-3.11

Documentation

urllib3.future has usage and reference documentation at urllib3future.readthedocs.io.

Contributing

urllib3.future happily accepts contributions.

Security Disclosures

To report a security vulnerability, please use the GitHub advisory disclosure form.

Sponsorship

If your company benefits from this library, please consider sponsoring its development.

urllib3.future's People

Contributors

shazow avatar lukasa avatar sethmlarson avatar pquentin avatar t-8ch avatar hramezani avatar sigmavirus24 avatar ousret avatar sethmichaellarson avatar dependabot[bot] avatar haikuginger avatar alexwlchan avatar kevinburke avatar schlamar avatar hodbn avatar jschneier avatar stanvit avatar palaviv avatar jdufresne avatar takluyver avatar graingert avatar eteq avatar mattbillenstein avatar nateprewitt avatar bluetech avatar jeremycline avatar wbond avatar bui avatar scop avatar venthur avatar

Stargazers

Dr. Juan Miguel Cejuela avatar ButenkoMS avatar  avatar  avatar Poruri Sai Rahul avatar Paul Willot avatar  avatar  avatar  avatar Andrew avatar Markus Geiger avatar MtkN1 avatar Colin Coe avatar ning_donald avatar ShellWen | 颉文 avatar GreenYoshi (Wang Han) avatar  avatar Andreas Motl avatar George Xexakis avatar  avatar

Watchers

 avatar  avatar

Forkers

padraic-padraic

urllib3.future's Issues

Rebrand to urllib3000

Thanks for the reply. If you plan to advertise this project beyond your own use we would appreciate not using the "urllib3.future" name and our logo so as not to cause confusion about association with the urllib3 project.

Originally posted by @sethmlarson in #46 (comment)

I must say i was a bit confused with the project name, looked like directly related to the original urllib3

Possible names

  • urllib3000
  • urllib300
  • urllib4
  • httpxlib
  • n...

yt-dlp warnings like `[youtube] TLS over QUIC did not succeed. Chain certificate verification failed or client cert validation failed.`

Subject

When I use yt-dlp with urllib3.future (or urllib3-future - is there a difference?) and without setting --no-check-certificates I get a lot of these warnings.

With --extractor-args "youtube:formats=dashy" videos still download but the warnings show up while downloading as [download] Got error: TLS over QUIC did not succeed. Chain certificate verification failed or client cert validation failed. It seems like the first try always fails and then the 2nd try succeeds, though I'm not 100% sure of that.

Without the extractor-args, it seems to just retry 10 times and then fail.

Environment

OS Windows-11-10.0.22631-SP0
Python 3.12.3
OpenSSL 3.0.13 30 Jan 2024
urllib3 2.7.906

Steps to Reproduce

  1. Install the latest version of yt-dlp
  2. Download any video from YouTube, e.g. https://www.youtube.com/watch?v=1f6uVIK7Uko

Expected Behavior

No warnings / errors.

Actual Behavior

  1. Warnings like [youtube] TLS over QUIC did not succeed. Chain certificate verification failed or client cert validation failed. before the download starts.
  2. Errors like [download] Got error: TLS over QUIC did not succeed. Chain certificate verification failed or client cert validation failed. during the download.
  3. Without --extractor-args "youtube:formats=dashy" the errors pile up until the download fails. With that argument, the download seems to work after 1 retry, but the errors keep occurring.

Why overshadowing?!! This does not help debugging

There is a bug in the connection.py from urllib3.future but my traceback points to lib/python3.12/site-packages/urllib3/connection.py

I spent like hours confused before seeing urllib3_future folder and figuring out that it OVERWROTE THE URLLIB3 PACKAGE because some other package in the chain used niquests. The package was for some not-super-usefull feature but blocking the main program because boto3 and botocore rely on STABLE URLLIB3.

It is malware-like behaviour that took me hours to debu.

One line fix later and my program works again but it would if you didn't overwrote working library.

I am not telling you where the bug is until you stop this practice and I am officially making request to PYPA to remove it from pypi,

[FYI] `urllib3-future` is now available from ArchLinux User Repository as `python-urllib3-future-git`

[ This is an informational message only. No action is required on your part, and the issue can be closed at your discretion. ]

I thought you'd like to know that ArchLinux users can now install urllib3-future directly from ArchLinux User Repository (AUR) as python-urllib3-future-git:

The package can be installed using an AUR helper, e.g. yay:

» yay -S python-urllib3-future-git

This will build the python module from the latest commit, and install it along with the README and the LICENSE.

🙏

This library breaks botocore.AWSConnection

Subject

I gave a try to niquests ( found it on Hacker News ), but it seems urllib3.future is incompatible with boto3 / botocore for AWS, which is a major usecase nowadays.
I will need to set this experiment aside until this can be fixed.

Environment

Windows
python 3.11

Steps to Reproduce

Most AWS call will trigger an error, for example s3.put_object()

Expected Behavior

boto call going through smoothly.

Actual Behavior

Traceback (most recent call last):
  File ".venv\Lib\site-packages\botocore\httpsession.py", line 464, in send
    urllib_response = conn.urlopen(
                      ^^^^^^^^^^^^^
  File ".venv\Lib\site-packages\urllib3\connectionpool.py", line 1184, in urlopen
    response = self._make_request(  # type: ignore[call-overload,misc]
               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File ".venv\Lib\site-packages\urllib3\connectionpool.py", line 810, in _make_request
    rp = conn.request(
         ^^^^^^^^^^^^^
  File ".venv\Lib\site-packages\botocore\awsrequest.py", line 96, in request
    rval = super().request(method, url, body, headers, *args, **kwargs)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File ".venv\Lib\site-packages\urllib3\connection.py", line 489, in request
    rp = self.send(b"", eot=True)
         ^^^^^^^^^^^^^^^^^^^^^^^^
TypeError: AWSConnection.send() got an unexpected keyword argument 'eot'

urllib3 compatibility: signature change of HTTPConnectionPool._new_conn breaks other subclasses

urllib3 compatibility: signature change of HTTPConnectionPool._new_conn breaks other subclasses

urllib3.connectionpool.HTTPConnectionPool method _new_conn had it's signature changed from def _new_conn(self) -> HTTPConnection to def _new_conn(self, *, heb_timeout: Timeout | None = None) -> HTTPConnection. Importantly, this adds the kwarg-only heb_timeout.
This causes a problem with subclasses of HTTPConnectionPool, such as the "docker" package's UnixHTTPConnectionPool (source code for UnixHTTPConnectionPool). Since this kwarg doesn't exist on that function, we get "TypeError: _new_conn() got an unexpected keyword argument 'heb_timeout'".

I think the easiest thing to do is to try to get the "docker" or upstream "urllib3" package to modify the signature to def _new_conn(self, **kwargs) -> HTTPConnection.

Environment

I've tested with 'docker==7.1.0' and 'docker==7.0.0', but I believe it affects most of them

>>> import platform
>>> import ssl
>>> import urllib3
>>> 
>>> print("OS", platform.platform())
OS Linux-6.5.0-35-generic-x86_64-with-glibc2.35
>>> print("Python", platform.python_version())
Python 3.10.12
>>> print(ssl.OPENSSL_VERSION)
OpenSSL 3.0.2 15 Mar 2022
>>> print("urllib3", urllib3.__version__)
urllib3 2.7.912

Steps to Reproduce

python3 -m venv /tmp/venv && source /tmp/venv/bin/activate
# note that urllib3 will be pulled in as a dependency of "docker"
pip3 install 'docker==7.1.0' 'urllib3==2.2.1' 'urllib3-future==2.7.912'

# force docker to use unix socket
export DOCKER_HOST="unix:///run/user/1000/docker.sock"
python3 -c 'import docker; docker.from_env()'

Expected Behavior

"urllib3-future" should be a drop-in replacement for "urllib3"

Actual Behavior

traceback ``` python3 -c 'import docker; docker.from_env()' Traceback (most recent call last): File "/tmp/venv/lib/python3.10/site-packages/docker/api/client.py", line 223, in _retrieve_server_version return self.version(api_version=False)["ApiVersion"] File "/tmp/venv/lib/python3.10/site-packages/docker/api/daemon.py", line 181, in version return self._result(self._get(url), json=True) File "/tmp/venv/lib/python3.10/site-packages/docker/utils/decorators.py", line 44, in inner return f(self, *args, **kwargs) File "/tmp/venv/lib/python3.10/site-packages/docker/api/client.py", line 246, in _get return self.get(url, **self._set_request_timeout(kwargs)) File "/tmp/venv/lib/python3.10/site-packages/requests/sessions.py", line 602, in get return self.request("GET", url, **kwargs) File "/tmp/venv/lib/python3.10/site-packages/requests/sessions.py", line 589, in request resp = self.send(prep, **send_kwargs) File "/tmp/venv/lib/python3.10/site-packages/requests/sessions.py", line 703, in send r = adapter.send(request, **kwargs) File "/tmp/venv/lib/python3.10/site-packages/requests/adapters.py", line 589, in send resp = conn.urlopen( File "/tmp/venv/lib/python3.10/site-packages/urllib3/connectionpool.py", line 1366, in urlopen conn = self._get_conn(timeout=pool_timeout, heb_timeout=timeout_obj) File "/tmp/venv/lib/python3.10/site-packages/urllib3/connectionpool.py", line 530, in _get_conn return conn or self._new_conn(heb_timeout=heb_timeout) TypeError: UnixHTTPConnectionPool._new_conn() got an unexpected keyword argument 'heb_timeout'

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
File "", line 1, in
File "/tmp/venv/lib/python3.10/site-packages/docker/client.py", line 94, in from_env
return cls(
File "/tmp/venv/lib/python3.10/site-packages/docker/client.py", line 45, in init
self.api = APIClient(*args, **kwargs)
File "/tmp/venv/lib/python3.10/site-packages/docker/api/client.py", line 207, in init
self._version = self._retrieve_server_version()
File "/tmp/venv/lib/python3.10/site-packages/docker/api/client.py", line 230, in _retrieve_server_version
raise DockerException(
docker.errors.DockerException: Error while fetching server API version: UnixHTTPConnectionPool._new_conn() got an unexpected keyword argument 'heb_timeout'

</details>

Please reconsider name-shadowing `urllib3`

From the README:

Installing urllib3.future shadows the actual urllib3 package (depending on installation order). The semver will always be like MAJOR.MINOR.9PP like 2.0.941, the patch node is always greater or equal to 900.

The problem is that this practice really hurts reproducible builds, causing bugs that are difficult to reproduce and narrow down. urllib3.future can still be a drop-in replacement to anyone using it by just renaming the import: import urllib3_future as urllib3 - which would avoid the name clashes during the virtual environment creation by not shadowing the name urllib3 for anyone using it.

As an example, I currently have the same poetry environment with the same versions on two different machines, and they behave differently because when urllib3 is imported, it's not obvious which one will take precedence.

This precedence uncertainty is capable of changing a program's behavior even if urllib3 and urllib3_future were identical: think isinstance(retry, urllib3.utils.retry.Retry) vs isinstance(retry, urllib3_future.utils.retry.Retry) - which is analogous to a line present in niquests.

I don't know if this is standardized somewhere in the Python landscape, but I don't think the installation order of packages should change a program's behavior. And please, let me know if I missed something here, or if my understanding of this matter is incomplete.

AttributeError: 'Settings' object has no attribute 'has_update'

[ Re: commit 37e0c96 ]

Subject

I am packaging urllib3.future (as part of niquests and all its dependencies) for ArchLinux User Repository (AUR) and am therefore using the URLLIB3_NO_OVERRIDE=true python -m build … stanza as described in the README. As of the latest urllib3.future commit (see above) even a simple niquests.get() fails (see below).

Environment

Describe your environment.
At least, paste here the output of:

>>> print("OS", platform.platform())
OS Linux-6.8.8-arch1-1-x86_64-with-glibc2.39
>>> print("Python", platform.python_version())
Python 3.12.3
>>> print(ssl.OPENSSL_VERSION)
OpenSSL 3.3.0 9 Apr 2024
>>> print("urllib3", urllib3.__version__)
urllib3 1.26.18

Additionally, the newest versions of wassima, qh3, jh2, and niquests are installed.

Steps to Reproduce

>>> import niquests
req = niquests.get('https://github.com/jawah/urllib3.future')

Expected Behavior

niquests would fetch the requested page and return the request.

Actual Behavior

Python 3.12.3 (main, Apr 23 2024, 09:16:07) [GCC 13.2.1 20240417] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import niquests
>>> niquests.get('https://github.com/jawah/urllib3.future')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/usr/lib/python3.12/site-packages/niquests/api.py", line 170, in get
    return request(
           ^^^^^^^^
  File "/usr/lib/python3.12/site-packages/niquests/api.py", line 107, in request
    return session.request(
           ^^^^^^^^^^^^^^^^
  File "/usr/lib/python3.12/site-packages/niquests/sessions.py", line 539, in request
    resp = self.send(prep, **send_kwargs)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/lib/python3.12/site-packages/niquests/sessions.py", line 1174, in send
    r = adapter.send(request, **kwargs)
        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/lib/python3.12/site-packages/niquests/adapters.py", line 896, in send
    resp_or_promise = conn.urlopen(  # type: ignore[call-overload]
                      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/lib/python3.12/site-packages/urllib3_future/connectionpool.py", line 1383, in urlopen
    response = self._make_request(  # type: ignore[call-overload,misc]
               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/lib/python3.12/site-packages/urllib3_future/connectionpool.py", line 962, in _make_request
    self._validate_conn(conn)
  File "/usr/lib/python3.12/site-packages/urllib3_future/connectionpool.py", line 1922, in _validate_conn
    super()._validate_conn(conn)
  File "/usr/lib/python3.12/site-packages/urllib3_future/connectionpool.py", line 595, in _validate_conn
    conn.connect()
  File "/usr/lib/python3.12/site-packages/urllib3_future/connection.py", line 745, in connect
    self._post_conn()
  File "/usr/lib/python3.12/site-packages/urllib3_future/backend/hface.py", line 438, in _post_conn
    self.__exchange_until(
  File "/usr/lib/python3.12/site-packages/urllib3_future/backend/hface.py", line 628, in __exchange_until
    self._protocol.bytes_received(data_in)
  File "/usr/lib/python3.12/site-packages/urllib3_future/contrib/hface/protocols/http2/_h2.py", line 199, in bytes_received
    if self._connection.remote_settings.has_update:
       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
AttributeError: 'Settings' object has no attribute 'has_update'
>>> 

Little bit of history - docs

I feel like I can't really find reasons why HTTP/2.0 is not supported by now in urllib3. So, I am asking here. Would you explain why this fork exists and whether there is possibility of implementing the changes directly in urllib3?

Consider upstreaming support for HTTP/2

Hello!

It's great to see excitement around HTTP/2 and HTTP/3 with urllib3. We've actually unblocked working on HTTP/2 upstream now by adding a Quart and Hypercorn test server and enabling us to start working on HTTP/2 support in earnest. Previously we were hung up on being able to migrate our test suite to be able to use both HTTP/1.1, HTTP/2 and more since there's a lot of value in our test suite. We're tracking that work in this GitHub issue and sub-issues.

I haven't given this a read completely yet, but if I had to guess it's likely based on the work done in this PR by @Ousret. My main question is whether you'd consider collaborating with our team so that more users are able to take advantage of these improvements being made. If not that is okay, but want to be explicit that upstream is open to accepting PRs for HTTP/2 support at this time (and more able to now compared to when that original PR was made).

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.