(doc) Documented the internal design of Hyper.
This includes a rationale and description of the overall design of Hyper as well as providing a guide to understanding and navigating the source.
This commit is contained in:
		
							
								
								
									
										106
									
								
								README.md
									
									
									
									
									
								
							
							
						
						
									
										106
									
								
								README.md
									
									
									
									
									
								
							| @@ -56,7 +56,113 @@ test result: ok. 0 passed; 0 failed; 0 ignored; 3 measured | |||||||
|  |  | ||||||
| \* No science was harmed in the making of this benchmark. | \* No science was harmed in the making of this benchmark. | ||||||
|  |  | ||||||
|  | ## Internal Design | ||||||
|  |  | ||||||
|  | Hyper is designed as a relatively low-level wrapped over raw HTTP. It should | ||||||
|  | allow the implementation of higher-level abstractions with as little pain as | ||||||
|  | possible, and should not irrevocably hide any information from its users. | ||||||
|  |  | ||||||
|  | ### Common Functionality | ||||||
|  |  | ||||||
|  | Functionality and code shared between the Server and Client implementations can | ||||||
|  | be found in `src` directly - this includes `NetworkStream`s, `Method`s, | ||||||
|  | `StatusCode`, and so on. | ||||||
|  |  | ||||||
|  | #### Methods | ||||||
|  |  | ||||||
|  | Methods are represented as a single `enum` to remain as simple as possible. | ||||||
|  | Extension Methods are represented as raw `String`s. A method's safety and | ||||||
|  | idempotence can be accessed using the `safe` and `idempotent` methods. | ||||||
|  |  | ||||||
|  | #### StatusCode | ||||||
|  |  | ||||||
|  | Status codes are also represented as a single, exhaustive, `enum`. This | ||||||
|  | representation is efficient, typesafe, and ergonomic as it allows the use of | ||||||
|  | `match` to disambiguate known status codes. | ||||||
|  |  | ||||||
|  | #### Headers | ||||||
|  |  | ||||||
|  | Hyper's header representation is likely the most complex API exposed by Hyper. | ||||||
|  |  | ||||||
|  | Hyper's headers are an abstraction over an internal `HashMap` and provides a | ||||||
|  | typesafe API for interacting with headers that does not rely on the use of | ||||||
|  | "string-typing." | ||||||
|  |  | ||||||
|  | Each HTTP header in Hyper has an associated type and implementation of the | ||||||
|  | `Header` trait, which defines an HTTP headers name as a string, how to parse | ||||||
|  | that header, and how to format that header. | ||||||
|  |  | ||||||
|  | Headers are then parsed from the string representation lazily when the typed | ||||||
|  | representation of a header is requested and formatted back into their string | ||||||
|  | representation when headers are written back to the client. | ||||||
|  |  | ||||||
|  | #### NetworkStream and NetworkAcceptor | ||||||
|  |  | ||||||
|  | These are found in `src/net.rs` and define the interface that acceptors and | ||||||
|  | streams must fulfill for them to be used within Hyper. They are by and large | ||||||
|  | internal tools and you should only need to mess around with them if you want to | ||||||
|  | mock or replace `TcpStream` and `TcpAcceptor`. | ||||||
|  |  | ||||||
|  | ### Server | ||||||
|  |  | ||||||
|  | Server-specific functionality, such as `Request` and `Response` | ||||||
|  | representations, are found in in `src/server`. | ||||||
|  |  | ||||||
|  | #### Request | ||||||
|  |  | ||||||
|  | An incoming HTTP Request is represented as a struct containing | ||||||
|  | a `Reader` over a `NetworkStream`, which represents the body, headers, a remote | ||||||
|  | address, an HTTP version, and a `Method` - relatively standard stuff. | ||||||
|  |  | ||||||
|  | `Request` implements `Reader` itself, meaning that you can ergonomically get | ||||||
|  | the body out of a `Request` using standard `Reader` methods and helpers. | ||||||
|  |  | ||||||
|  | #### Response | ||||||
|  |  | ||||||
|  | An outgoing HTTP Response is also represented as a struct containing a `Writer` | ||||||
|  | over a `NetworkStream` which represents the Response body in addition to | ||||||
|  | standard items such as the `StatusCode` and HTTP version. `Response`'s `Writer` | ||||||
|  | implementation provides a streaming interface for sending data over to the | ||||||
|  | client. | ||||||
|  |  | ||||||
|  | One of the traditional problems with representing outgoing HTTP Responses is | ||||||
|  | tracking the write-status of the Response - have we written the status-line, | ||||||
|  | the headers, the body, etc.? Hyper tracks this information statically using the | ||||||
|  | type system and prevents you, using the type system, from writing headers after | ||||||
|  | you have started writing to the body or vice versa. | ||||||
|  |  | ||||||
|  | Hyper does this through a phantom type parameter in the definition of Response, | ||||||
|  | which tracks whether you are allowed to write to the headers or the body. This | ||||||
|  | phantom type can have two values `Fresh` or `Streaming`, with `Fresh` | ||||||
|  | indicating that you can write the headers and `Streaming` indicating that you | ||||||
|  | may write to the body, but not the headers. | ||||||
|  |  | ||||||
|  | ### Client | ||||||
|  |  | ||||||
|  | Client-specific functionality, such as `Request` and `Response` | ||||||
|  | representations, are found in `src/client`. | ||||||
|  |  | ||||||
|  | #### Request | ||||||
|  |  | ||||||
|  | An outgoing HTTP Request is represented as a struct containing a `Writer` over | ||||||
|  | a `NetworkStream` which represents the Request body in addition to the standard | ||||||
|  | information such as headers and the request method. | ||||||
|  |  | ||||||
|  | Outgoing Requests track their write-status in almost exactly the same way as | ||||||
|  | outgoing HTTP Responses do on the Server, so we will defer to the explanation | ||||||
|  | in the documentation for sever Response. | ||||||
|  |  | ||||||
|  | Requests expose an efficient streaming interface instead of a builder pattern, | ||||||
|  | but they also provide the needed interface for creating a builder pattern over | ||||||
|  | the API exposed by core Hyper. | ||||||
|  |  | ||||||
|  | #### Response | ||||||
|  |  | ||||||
|  | Incoming HTTP Responses are represented as a struct containing a `Reader` over | ||||||
|  | a `NetworkStream` and contain headers, a status, and an http version. They | ||||||
|  | implement `Reader` and can be read to get the data out of a `Response`. | ||||||
|  |  | ||||||
| ## License | ## License | ||||||
|  |  | ||||||
| [MIT](./LICENSE) | [MIT](./LICENSE) | ||||||
|  |  | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user