Skip to content

💡Support h2c origin servers #1304

@ryao

Description

@ryao

Describe the feature you'd like
I would like origin pulls over cloudflare tunnels to be doable with h2c. Connections would be faster with origin pulls over h2c instead of h2 and the tunnel already provides encryption to make things secure.

Describe alternatives you've considered
Letting the origin pulls use http 1.1 instead of http/2 avoids the unnecessary extra encryption, but is counterproductive because it avoids the improvements of http/2. It might be possible to get similar performance to h2c using h2 with the NULL cipher, although this is unnecessarily complex and would force me to use TLSv1.2, if it works at all.

Additional context
Add any other context or screenshots about the feature request here.

This python script lets you open an HTTP/2 server on port 8000 on your present working directory:

from hypercorn.config import Config
from hypercorn.asyncio import serve
from quart import Quart, request, send_from_directory, jsonify
import asyncio

app = Quart(__name__)

@app.route('/<path:filename>')
async def serve_file(filename):
    # Print the detected HTTP version for debugging
    print(f"Detected HTTP version: {request.http_version}")
    if request.http_version != '2':
        return jsonify({"error": "HTTP version not supported"}), 426  # HTTP 426 Upgrade Required
    return await send_from_directory('.', filename)

async def main():
    config = Config()
    config.bind = ["0.0.0.0:8000"]
    config.h2c = True  # Enable HTTP/2 over cleartext
    await serve(app, config)

if __name__ == "__main__":
    asyncio.run(main())

I opened it on a git checkout of cloudflared.

Here is a quick test with curl to make sure it serves http/2 requests:

$ curl -sI --http2-prior-knowledge localhost:8000/CHANGES.md
HTTP/2 200 
content-type: text/markdown; charset=utf-8
content-length: 16725
last-modified: Sat, 03 Aug 2024 21:23:25 GMT
cache-control: public, max-age=43200
expires: Sun, 04 Aug 2024 09:52:04 GMT
etag: "1722720205.9618301-16725-259064569"
date: Sat, 03 Aug 2024 21:52:04 GMT
server: hypercorn-h2

And here is a quick test with curl to make sure that it does not serve http 1.1 requests:

$ curl -sI localhost:8000/CHANGES.md
HTTP/1.1 426 
content-type: application/json
content-length: 39
date: Sat, 03 Aug 2024 21:51:54 GMT
server: hypercorn-h11

Now that it is clear that this works, I run ./cloudflared-linux-amd64 tunnel --url localhost:8000 --http2-origin. I connect to the URL given with /CHANGES.md at the end. There is nothing there. The hostname has not been published. Also, the server shows no attempt to connect to it. That is presumably because the connection attempt was h2 instead of h2c and it was treated as as garbage by the python http/2 server.

Now, I kill that cloudflared-linux-amd64 process and try ./cloudflared-linux-amd64 tunnel --url localhost:8000. I again connect to the URL given with /CHANGES.md at the end. This time, I receive {"error":"HTTP version not supported"}. The server indicates that a http 1.1 connection had been made.

It seems that the http/2 support is restricted to h2. Please add h2c support. An --http2-cleartext-origin flag to enable it would be useful, as would a toggle under the "Additional application settings" in the cloudflare zero trust console.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Priority: NormalMinor issue impacting one or more usersType: Feature RequestA big idea that would be split into smaller pieces

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions