aiohttp icon indicating copy to clipboard operation
aiohttp copied to clipboard

Providing a better abstract layer for Client/Server for implementing future current and future http protocols

Open Vizonex opened this issue 2 months ago • 3 comments

Is your feature request related to a problem?

Recently I've been attempting to implement http/2 and http/3 into this library but I've been having a bit of difficulty on figuring out how aiohttp should handle these and future protocols. What I have determined is that we need to provide a smarter abstract layer or try an approach similar to httpx.

I think it should be done in this order and I'll start with the client's end.

Client -> Abstract Layer for Http/1.1 Http/2 and Http/3 -> Server

Server end is more or less the same where we can replace the Server and median if we wish...

Low Level Server Layer (example: aioquic, h2, or the current aiohttp http 1.1 ) -> Abstract Layer -> Aiohttp Application

When accepting TCP Connections there are flags for accepting these protocols on connections. We can use it to determine which protocol we end up going with on both the client and server's end as we wish...

Code is from h2 documentation and I've snipped out the unimportant details

    # we can check to see what alpn protocols are in use on connection to determine which protocol gets set...
    ctx.set_alpn_protocols(["h2", "http/1.1"])

While each protocol is vastly different from each over. A rewrite into this format In a future release would benefit more people and make aiohttp a more desirable library later down the road.

Describe the solution you'd like

In here I'll lay out an abstract class object that handles this sending of requests and responses for both clients and servers.

from abc import ABC, abstractmethod

from aiohttp import ClientRequest, ClientResponse
from aiohttp.web import Request, Response



class AbstractClientProtocol(ABC):
    # My main goal was visualizing an abstract layering system 
    # for future protocols so __init__ did not feel important

    @abstractmethod
    async def send_request(req:ClientRequest) -> None:...

    @abstractmethod
    async def get_response(self) -> ClientResponse:...

    # Otherwise I was thinking we try
    @abstractmethod
    def on_response(self, resp:ClientResponse):...

# From there we can build on top of it and pass whatever is needed...
class Http11ClientProtocol(AbstractClientProtocol):
    pass

class Http2ClientProtocol(AbstractClientProtocol):
    pass

class Http3ClientProtocol(AbstractClientProtocol):
    pass


class AbstractServerProtocol(ABC):

    # I did however understand that each protocol is vastly different
    # from each other however if we can just provide handlers for
    # request and responses that will be enough to prove my point and idea.
    @abstractmethod
    async def on_request(self, req:Request) -> None:...

    @abstractmethod
    async def on_response(self, resp:Response) -> None:...


class Http11ServerProtocol(AbstractServerProtocol):
    pass

class Http2ServerProtocol(AbstractServerProtocol):
    pass

class Http3ServerProtocol(AbstractServerProtocol):
    pass

Describe alternatives you've considered

The alternative http clients that implement http2 or http3 or both vs aiohttp are currently

  • curl-cffi (looks to be aimed towards webscrapers)
  • cycurl (I've contributed here but it's been a long time)
  • httpx (it's a little sluggish due to only being pure python)

Server backend implementations

  • hypercorn (http/2 and http/3 supported)
  • aioquic (hypercorn works off this library)

Related component

Client, Server

Additional context

No response

Code of Conduct

  • [x] I agree to follow the aio-libs Code of Conduct

Vizonex avatar Nov 04 '25 17:11 Vizonex

I'm not clear how that abstract class would fit in anywhere. It'd atleast need to abstract the behaviour we already have. HTTP responses are streamed at that level, so a get_response() method wouldn't make any sense.

Dreamsorcerer avatar Nov 06 '25 20:11 Dreamsorcerer

We already have the HttpParser class, I assume any HTTP/2 implementation would be another class replacing that one, with the same public interface (maybe we'll need to tweak the interface, and we can use an abstract class for that).

Dreamsorcerer avatar Nov 06 '25 20:11 Dreamsorcerer

We already have the HttpParser class, I assume any HTTP/2 implementation would be another class replacing that one, with the same public interface (maybe we'll need to tweak the interface, and we can use an abstract class for that).

I agree since my goal is not just http/2 it's also getting http/3 in there too since many python libraries have http/2 already and we need to catch up with them.

Vizonex avatar Nov 07 '25 16:11 Vizonex