|
| 1 | +# hyper Vision |
| 2 | + |
| 3 | +## Purpose |
| 4 | + |
| 5 | +This is an overview of what the shape of hyper looks like, but also somewhat |
| 6 | +zoomed out, so that the _vision_ can survive while the exact minute details |
| 7 | +might shift and change over time. |
| 8 | + |
| 9 | +### Charter |
| 10 | + |
| 11 | +> hyper is a protective and efficient HTTP library for all. |
| 12 | +
|
| 13 | +### Tenets |
| 14 | + |
| 15 | +Tenets are guiding principles. They guide how decisions are made for the whole |
| 16 | +project. Ideally, we do all of them all the time. In some cases, though, we may |
| 17 | +be forced to decide between slightly penalizing one goal or another. In that |
| 18 | +case, we tend to support those goals that come earlier in the list over those |
| 19 | +that come later (but every case is different). |
| 20 | + |
| 21 | +0. Open |
| 22 | +1. Correct |
| 23 | +2. Fast |
| 24 | +3. HTTP/\* |
| 25 | +4. Flexible |
| 26 | +5. Understandable |
| 27 | + |
| 28 | +There's a lot more detail about each in [TENETS](./TENETS.md). |
| 29 | + |
| 30 | +## Use Cases |
| 31 | + |
| 32 | +Who are the *users* of hyper? How would they use hyper? |
| 33 | + |
| 34 | +### Low-Level Client Library (curl, reqwest, aws-sdk) |
| 35 | + |
| 36 | +These client libraries care that hyper is **Flexible**, since they are |
| 37 | +expressing their own opinion on how a more-featured HTTP client should act. |
| 38 | +This includes opinions on connection establishment, management, pooling, HTTP |
| 39 | +version options, and even runtimes. |
| 40 | + |
| 41 | +curl's main reason for using hyper is that it is **Safe**. |
| 42 | + |
| 43 | +### Web Server Frameworks (deno, axum) |
| 44 | + |
| 45 | +These are using hyper's server feature to expose a different, higher-level API |
| 46 | +to users. Besides the obvious requirements, these require that hyper is |
| 47 | +**Fast**. Servers are costly, handling more requests faster is important to |
| 48 | +them. |
| 49 | + |
| 50 | +That hyper is **Flexible** is also important, in that it needs to be flexible |
| 51 | +enough for them to build a server framework, and allow them to express their |
| 52 | +own opinions about API to their users. |
| 53 | + |
| 54 | +### Services and Proxies (linkerd, cloudflare, fastly) |
| 55 | + |
| 56 | +These are using hyper directly, likely both the client and server, in order to |
| 57 | +build efficient and powerful services, applications, and tools for their end |
| 58 | +users. They care greatly that hyper is **Correct**, since web traffic can |
| 59 | +stretch the limits of what is valid HTTP, and exercise less-common parts of the |
| 60 | +specifications. |
| 61 | + |
| 62 | +They also require hyper to be **Fast**, for similar reasons that the web server |
| 63 | +frameworks do. |
| 64 | + |
| 65 | +### New Rust Web Developers |
| 66 | + |
| 67 | +These are developers who are either new to Rust, or new to web servers, and |
| 68 | +have reached for hyper to start with. |
| 69 | + |
| 70 | +It's likely that these users don't have strong opinions about how an HTTP |
| 71 | +server or client should work, just that it _should_ handle all the things they |
| 72 | +normally assume it would. For these users, it would be best to quickly help |
| 73 | +them compare their own expectations with hyper's capabitilities, and may |
| 74 | +suggest reaching for higher-level, _easier_ libraries instead. |
| 75 | + |
| 76 | +Those that stick around after that recommendation are users that wish both to |
| 77 | +learn at a lower level, and to pick and choose what batteries they plug in to |
| 78 | +hyper as they move along. While they do care about the other tenets, that hyper |
| 79 | +is **Understandable** is of extra importance to them. |
| 80 | + |
| 81 | +## The Library |
| 82 | + |
| 83 | +So with all that context in mind, what does hyper, the library, actually look |
| 84 | +like? This doesn't highlight what _is_ and _isn't_ present. What currently |
| 85 | +needs to change to reach this vision is left to individual version roadmaps. |
| 86 | + |
| 87 | +### Layers |
| 88 | + |
| 89 | +In all cases, a user brings their own runtime and IO to work with hyper. The IO |
| 90 | +is provided to hyper, and hyper acts on top of it. hyper returns `Future`s that |
| 91 | +the user then decides how to poll, likely involving their runtime options. |
| 92 | + |
| 93 | + |
| 94 | + |
| 95 | + |
| 96 | +#### Protocol Codecs |
| 97 | + |
| 98 | +hyper has dedicated codecs for the major HTTP versions. Each is internally |
| 99 | +designed to be **Correct** and **Fast** when it comes to encoding and decoding. |
| 100 | + |
| 101 | +The individual codecs may be implemented as sub-crates, with a less-stable |
| 102 | +promise, to support the **Flexible** needs of some users who wish to build |
| 103 | +their own connection management, or customize encoding and decoding beyond what |
| 104 | +is officially supported. |
| 105 | + |
| 106 | +#### Connection State Management |
| 107 | + |
| 108 | +A **Correct** implementation includes more than just enforcing certain |
| 109 | +characters when encoding and decoding. Order of frames, and flags in certain |
| 110 | +frames can affect the state of the connection. Some examples of things enforced |
| 111 | +at this layer: |
| 112 | + |
| 113 | +- If a message has a `content-length`, enforce only that many bytes are read or |
| 114 | + written. |
| 115 | +- Reading a `Response` before a `Request` is even written implies a mismatched |
| 116 | + reply that should be interpreted as an error. |
| 117 | +- The presence of some headers, such as `Connection: close`, or the absence of |
| 118 | + others, such as `content-length` and `transfer-encoding`, can mean that the |
| 119 | + connection should terminate after the current message. |
| 120 | +- HTTP/2 and HTTP/3 may send connection-level frames that don't pertain to any |
| 121 | + specific transaction, and must be read and handled regardless of if a user is |
| 122 | + currently checking for a message. |
| 123 | + |
| 124 | +#### HTTP Role and Version Abstraction |
| 125 | + |
| 126 | +This is the public API layer. Methods exposed are around sending and receiving |
| 127 | +`http::Request`s and `http::Response`s, not around framing specifics of the |
| 128 | +different versions. These are built around a client or server `Connection` |
| 129 | +interface. |
| 130 | + |
| 131 | +By exposing this layer publicly, we take care of the **Correct** tenet, by not |
| 132 | +forcing the user to send the specific frames themselves. The API should be |
| 133 | +designed in a way that a user cannot easily (if at all) create an _incorrect_ |
| 134 | +HTTP connection. |
| 135 | + |
| 136 | +Motivated by the **Flexible** tenet, there _are_ version-specific options that |
| 137 | +can be configured at this level, and version-specific functionality can usually |
| 138 | +be handled via `http::Extensions`. |
| 139 | + |
| 140 | +### Not quite stable, but utile (useful) |
| 141 | + |
| 142 | +Beyond what is directly in the hyper crate, there are useful (utile) parts that |
| 143 | +may not meet hyper's stability promise. Developing, experimenting, and exposing |
| 144 | +those parts is the purpose of the `hyper-util` crate. That crate does not have |
| 145 | +the same stability level as hyper. However, the goal is that things that other |
| 146 | +libraries might want to expose as a public dependency do not live in |
| 147 | +`hyper-util` forever, but rather stabilize and get promoted into `hyper`. |
| 148 | + |
| 149 | +Exactly what gets put into `hyper-util` presently is kept in the roadmap |
| 150 | +documents. |
| 151 | + |
| 152 | +### Stability Promise |
| 153 | + |
| 154 | +What even is hyper's stability promise? Does it mean we are "done"? No. Will we |
| 155 | +ever make breaking changes again? Probably. We'll still follow the [semantic |
| 156 | +versioning](https://semver.org). |
| 157 | + |
| 158 | +Prior to 1.0, hyper has already only done breaking changes once a year. So 1 |
| 159 | +year isn't much of a promise. We'll have significant more use and understanding |
| 160 | +after a few years, and that could prompt some redesign. |
| 161 | + |
| 162 | +As of this writing, we'll promise that _major_ versions of hyper are stable for |
| 163 | +3 years. New features will come out in _minor_ versions frequently. If it is |
| 164 | +determined necessary to make breaking changes to the API, we'll save them for |
| 165 | +after the 3 years. |
| 166 | + |
| 167 | +hyper also establishes a Minimum Supported Rust Version (MSRV). hyper will |
| 168 | +support Rust versions at least 6 months old. If a new Rust version is released |
| 169 | +with a feature hyper wishes to use, we won't do so until at least 6 months |
| 170 | +afterwards. hyper will only ever require a new Rust version as a _minor_ |
| 171 | +release (1.x), not as a patch (1.x.y). |
| 172 | + |
| 173 | +## Security |
| 174 | + |
| 175 | +The security of hyper is a large part of what makes hyper _protective_. We make |
| 176 | +hyper secure via the combined efforts of being **Correct**, focusing on |
| 177 | +**HTTP/\***, and making it all **Understandable**. |
| 178 | + |
| 179 | +### Memory Safety |
| 180 | + |
| 181 | +Being **Correct** requires that hyper be memory-safe. Using the Rust language |
| 182 | +gets us most of the way there. But there is the ability to write `unsafe` |
| 183 | +Rust. Does being **Correct** mean that we can _never_ write `unsafe` code |
| 184 | +anywhere? Even if it helps make hyper **Fast**? We can, carefully. |
| 185 | + |
| 186 | +How do we balance the two, so that hyper is secure? |
| 187 | + |
| 188 | +hyper prefers not to have large modules of intertwined `unsafe` code. hyper |
| 189 | +does allow small `unsafe` blocks, no more than a few lines, where it's easier |
| 190 | +to verify that the `unsafe` code was written **Correctly**. |
| 191 | + |
| 192 | +### Meticulous Testing |
| 193 | + |
| 194 | +hyper's test suite grows and grows. There's a lot that needs to be right. |
| 195 | +Parsers, encoders, state machines. When easily isolated, those pieces have |
| 196 | +internal unit tests. But hyper also keeps a large list of growing integration |
| 197 | +tests that make sure all the parts are **Correct**. |
| 198 | + |
| 199 | +Making writing new tests easy is a high priority. Investing in the testing |
| 200 | +infrastructure is a proven way to make sure hyper stays **Correct** and secure. |
| 201 | + |
| 202 | +### Constant Fuzzing |
| 203 | + |
| 204 | +One thing is to know specific cases to test for. But we can't know all the |
| 205 | +inputs or states that *might* cause a bug. That's why hyper has rounds of |
| 206 | +fuzzing built into its CI. It's also why hyper signs up for and uses resources |
| 207 | +to provide *constant*, around-the-clock fuzzing, always looking for something |
| 208 | +that hyper should be hardened against. |
| 209 | + |
| 210 | +### Security Process |
| 211 | + |
| 212 | +hyper has an outlined |
| 213 | +[SECURITY](https://github.com/hyperium/hyper/blob/master/SECURITY.md) process, |
| 214 | +so we can safely report and fix issues. |
| 215 | + |
| 216 | +## Non-goals |
| 217 | + |
| 218 | +After writing this up, it is easier to articulate what sorts of things many |
| 219 | +might associate with an HTTP library, but which are explicitly *not* for hyper. |
| 220 | +These are all things that definitely **out of scope**. |
| 221 | + |
| 222 | +- TLS: We learned early that bundling TLS directly in hyper [has |
| 223 | + problems](https://github.com/hyperium/hyper/issues/985). People also have |
| 224 | + very strong opinions about which TLS implementation to use. The design of |
| 225 | + hyper allows users to bring their own TLS. |
| 226 | +- Routing |
| 227 | +- Cookies |
| 228 | +- Not-HTTP: WebSockets, or other protocols that are built next to HTTP. It |
| 229 | + should be possible to _use_ hyper to upgrade, but the actual next-protocol |
| 230 | + should be handled by a different library. |
0 commit comments