-
-
Notifications
You must be signed in to change notification settings - Fork 1.3k
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
HTTP2 #881
base: master
Are you sure you want to change the base?
HTTP2 #881
Conversation
- Refactored `hpack::Hpack` to an interchangeable interface class - Refactored `hpack::Table` to an interchangeable interface class - Implemented interfaces as `hpack::SimpleTable` and `hpack::SimpleHpack` - `hpack::SimpleHpack` Accepts an shared pointer to an hpack::Table implementation instead of creating its own - Rudimentarily implemented hpack inflating in `hpack::SimpleHpack`
Implemented rudimentary `h2c` handshake even if its not implemented by any mayor browser.
Still a memory management bug somewhere because `auto inflatedmap = inflated.getAll();` for the stream results in an segfault.
…ode size. However, its roughly 5x slower. Added a note for reference.
Removed async support for now, but should be implemented further down the road! Async+Http2 would be a perfect harmony.
…tion, priority and resetStream handlers in Http2StreamHandler.
…o RFC7540: Mainly added Flow-Control and refactored Http2Processor to be easier to read and to follow RFC7540 which frames should be applied to a connection and which are applied to streams
…code-pieces to run first h2spec checks. Warning: May contain ugly hacks that have to be cleaned before release!
…vailableToRead` and `commitReadOffset`
Still some places that are simple-api but we are getting there.
…ta/handleHeader/handleContinuation
…ectionHandler::handleConnection`
…eam::InputStream` instead of `data::stream::IOStream`. Output capabilities are not needed.
…ttpVersionSwitch`) Handling switching to HTTP2 with an upgrade-handler interceptor was not feasible anymore. Since we moved to async and an executor handles the rest, `HandleConnection` returns immediately. Thus, the HTTP connection handler always answered with some generic response to the peer and broke the HTTP2 stream. Now we have a designated `ConnectionHandler` for this which allows for more control. The `Http2ConnectionHandler` is implemented in a way which allows it to be chained behind the `HttpVersionSwitch` or directly be called from an `ConnectionProvider`. It carries its own PRI-Message evaluation in an async context.
…sionHandler`. Also fixed ping-data reading to correctly work in async.
…ctored error-handling and started fixing coroutine-flow.
…is observeable at http2/6.5.3 Somehow, no data is received anymore. Even in the HttpVersionSwitch. Without this fixed, there is no chance of proceeding.
# Conflicts: # src/oatpp/parser/json/mapping/Serializer.cpp # src/oatpp/web/protocol/http/incoming/Request.cpp # src/oatpp/web/protocol/http/incoming/Response.cpp # src/oatpp/web/protocol/http/outgoing/Request.cpp # src/oatpp/web/protocol/http/outgoing/Response.cpp
… in the HTTP/2 preflight message.
Hey Benedikt @bamkrs , Thank you so much for posting this! ❤️ I hope I'll be able to handle it from here. |
@lganzzzo I always hoped to find some time to pick up my work on this PR again since its so close to being finished and it would be a major benefit for OAT++. Well, we talked about pros and cons of HTTP2 in a REST backend, but since its such an heavily requested feature... |
HTTP2
This PR contains my long lost efforts to bring HTTP2 to OAT++ and its users. Development stopped in 2021 after OAT++ v1.3.0 was released since newer versions introduced some major changes in how OAT++ handles headers which basically made it impossible to integrate HTTP2 in OAT++ in such a way, that both HTTP1 and HTTP2 requests are indistinguishable for the user when writing his endpoints.
The Good
Most of HTTP2 works! The development was done in a test-driven approach using h2spec. Of 146 tests, 130 passed. HTTP2 implementation in most browsers is so sloppy that every major browser (Firefox, Chromium, Safari) I tested worked in perfect harmony with OAT++ HTTP2 (back then).
HTTP2 and HTTP1 work together nicely and the user does not need to care if a request is HTTP1 or HTTP2. Adding HTTP2 to a project is pretty easy for the user since the HTTP2 is implemented as a normal
network::ConnectionHandler
which gracefully handles checking for and upgrading to HTTP2 for each new request.The Bad
The changes aren't compatible with OAT++ newer than v1.3.0. This is mostly due to the major changes in OAT++'s streams implementation as well as the changes in HTTP header parsing and handling. In the end, I was stuck converting HTTP2 headers to the generic HTTP header container class in an efficient/performant way to pass it to the endpoint controllers.
The Ugly
Oh, there is a lot of ugly. Where do I start? This implementation of HTTP2 was never intended to be merged the way it is right now. I started it as a PoC to show @lganzzzo how HTTP2 could be integrated in OAT++ without breaking existing API's or major refactoring of OAT++'s ways. It should then be reimplemented as a joined effort since many details "under the hood" where misused and repurposed to speed up the development of the PoC. In 2021 I created some PR's that show these repurposing efforts (#463, #464, #465, #466, #474, #469, #482, #484, #494), especially these PR's around the streams and headers.
Next, there where 2 iterations of the implementation.
First, I implemented HTTP2 pretty straight forward in an "Simple-API" fashion. However, the Simple-API did not give me the right feature-set to implement some of HTTP2's specifications. Thus, I refactored the whole implementation to use the Async-API. This greatly improved the handling and performance of the HTTP2 implementation. Now, HTTP2 uses the framework of the Async-API under its hood while maintaining the users ability to use the Simple-API for their projects. The user does not see and does not need to care about this at all since its all hidden behind the well-known OAT++ workflow.
Whats Next?
I really don't known. I implemented the PoC as a small challenge while I was in lock-down due to covid. Now, post-covid, society returned back to normal (well, its not normal... look at Ukraine, Gaza or the military coups in Africa) and I'm pretty occupied with life in general.
Thus I invite everyone to contribute, rewrite or do whatever they want with this code. I won't be able to finish it.
Best would be if you create a PR in my fork to update this one. I try my best to look out for those PR's or any comments asking for guidance.
Appendix
Test-App
To test the implementation, just use the oatpp-starter repository and modify
AppComponent.hpp
andApp.cpp
like in this diff. This shows how simple it is to add HTTP2 to the users app.h2spec report
This is the h2spec report of the current state: