rama/lib.rs
1//! 🦙 Rama (ラマ) is a modular service framework for the 🦀 Rust language to move and transform your network packets.
2//!
3//! > The reasons behind the creation of rama can be read in [the "Why Rama" chapter](https://ramaproxy.org/book/why_rama).
4//! >
5//! > It might however not be a framework for everyone. In particular, if you are building a typical simple web server
6//! > or just need an http client for making standard requests, you might be better served with other crates.
7//! > While we at [Plabayo](https://plabayo.tech) do use Rama for most of our web needs, be it clients, servers or proxies,
8//! > it is not the easiest framework to use, and does not yet have the big community backing that other crates have.
9//! >
10//! > - You might want to use [Axum](https://github.com/tokio-rs/axum) if you are building a typical http web server,
11//! > as it comes with a lot of extra community crates to help you with pretty much anything you can think of. Using
12//! > Axum does mean you give up full control over your web stack, meaning as soon as you need something which
13//! > is not typical or standard-enforced, you might get stuck.
14//! > - You might want to use [Reqwest](https://docs.rs/reqwest/latest/reqwest/) if all you need is to make typical
15//! > http requests with no need for fine-grained control over your http requests or responses,
16//! > and where TLS is a mere detail only noticeable because you are surfing to an `https` server, with the `s` for secure.
17//! >
18//! > If you are building proxies and you feel that Rama is not the right approach for you,
19//! > then you might also want to check out the alternatives mentioned in this project's README,
20//! > easily available at <https://github.com/plabayo/rama?tab=readme-ov-file#--alternatives>.
21//! >
22//! > Rama is all about empowerment and modularity. It is there to aid you in building your proxies, servers and clients,
23//! > without getting in your way and without stopping you in your mission where rama might fall short. A web stack
24//! > built with Rama can always be customized to your needs, even if that particular part or layer is custom to your purpose only.
25//! >
26//! > It goes without saying that Rama is built upon the shoulders of giants.
27//! > Please refer to the acknowledgements at <https://github.com/plabayo/rama?tab=readme-ov-file>
28//! > for more information about this.
29//! >
30//! > Where required we had to fork other crates due to an incompatibility in needs or scope.
31//! > While this is unfortunate as it leads to more work for us, we gladly do so in cases
32//! > where it fits our mission of empowering rama users, including ourselves.
33//! > You can find more information about these forks at <https://github.com/plabayo/rama/blob/main/docs/fork/README.md>.
34//! > As much as possible we preserve the code layout of forked code modules to be able
35//! > to keep in sync with upstream and push patches upstream where applicable.
36//!
37//! Rama is async-first using [Tokio](https://tokio.rs/) as its _only_ Async Runtime.
38//! Please refer to [the examples found in the `/examples` dir](https://github.com/plabayo/rama/tree/main/examples)
39//! to get inspired on how you can use it for your purposes.
40//!
41//! > 💡 If your organization relies on Rama (ラマ) for its operations,
42//! > we invite you to consider becoming a sponsor 💖. By supporting our project,
43//! > you'll help ensure its continued development and success.
44//! > To learn more about sponsorship opportunities, please refer to [the "Sponsors" chapter in rama's online book](https://ramaproxy.org/book/sponsor.html)
45//! > or contact us directly at [sponsor@ramaproxy.org](mailto:sponsor@ramaproxy.org).
46//!
47//! This framework comes with 🔋 batteries included, giving you the full freedome to build the middleware and services you want, without _having_ to repeat the "common":
48//!
49//! | category | support list |
50//! |-|-|
51//! | ✅ [transports](crate::net::stream) | ✅ [tcp] ⸱ ✅ [udp] ⸱ ✅ [middleware](crate::net::stream::layer) |
52//! | ✅ [http] | ✅ [auto](crate::http::server::service::HttpServer::auto) ⸱ ✅ [http/1.1](crate::http::server::service::HttpServer::http1) ⸱ ✅ [h2](crate::http::server::service::HttpServer::h2) ⸱ 🏗️ h3 <sup>(1)</sup> ⸱ ✅ [middleware](crate::http::layer) |
53//! | ✅ web server | ✅ [fs](crate::http::service::fs) ⸱ ✅ [redirect](crate::http::service::redirect::Redirect) ⸱ ✅ [router](crate::http::service::web::Router) ⸱ ✅ [dyn router](crate::http::service::web::WebService) ⸱ ✅ [static router](crate::http::service::web::match_service) ⸱ ✅ [handler extractors](crate::http::service::web::extract) ⸱ ✅ [k8s healthcheck](crate::http::service::web::k8s) |
54//! | ✅ [http client](crate::http::client) | ✅ [easy client](crate::http::client::EasyHttpWebClient) ⸱ ✅ [high level API](crate::http::service::client::HttpClientExt) ⸱ ✅ [Proxy Connect](crate::http::client::proxy::layer::HttpProxyConnector) ⸱ ❌ [Chromium Http](https://github.com/plabayo/rama/issues/189) <sup>(3)</sup> |
55//! | ✅ [tls] | ✅ [Rustls](crate::tls::rustls) ⸱ ✅ [BoringSSL](crate::tls::boring) ⸱ ❌ NSS <sup>(3)</sup> |
56//! | ✅ [dns] | ✅ [DNS Resolver][crate::dns::DnsResolver] |
57//! | ✅ [proxy] protocols | ✅ [PROXY protocol](crate::proxy::haproxy) ⸱ ✅ [http proxy](https://github.com/plabayo/rama/blob/main/examples/http_connect_proxy.rs) ⸱ ✅ [https proxy](https://github.com/plabayo/rama/blob/main/examples/https_connect_proxy.rs) ⸱ 🏗️ SOCKS5 <sup>(2)</sup> ⸱ 🏗️ SOCKS5H <sup>(2)</sup> |
58//! | 🏗️ web protocols | 🏗️ Web Sockets <sup>(1)</sup> ⸱ ❌ Web Transport <sup>(3)</sup> ⸱ ❌ gRPC <sup>(3)</sup> |
59//! | ✅ [async-method trait](https://blog.rust-lang.org/inside-rust/2023/05/03/stabilizing-async-fn-in-trait.html) services | ✅ [Service] ⸱ ✅ [Layer] ⸱ ✅ [context] ⸱ ✅ [dyn dispatch](crate::service::BoxService) ⸱ ✅ [middleware](crate::layer) |
60//! | ✅ [telemetry] | ✅ [tracing](https://tracing.rs/tracing/) ⸱ ✅ [opentelemetry][telemetry::opentelemetry] ⸱ ✅ [http metrics](crate::http::layer::opentelemetry) ⸱ ✅ [transport metrics](crate::net::stream::layer::opentelemetry) |
61//! | ✅ upstream [proxies](proxy) | ✅ [MemoryProxyDB](crate::proxy::MemoryProxyDB) ⸱ ✅ [Username Config] ⸱ ✅ [Proxy Filters](crate::proxy::ProxyFilter) |
62//! | ✅ [User Agent (UA)](https://ramaproxy.org/book/intro/user_agent) | ✅ [Http Emulation](crate::ua::profile::HttpProfile) ⸱ ✅ [Tls Emulation](crate::ua::profile::TlsProfile) ⸱ ✅ [UA Parsing](crate::ua::UserAgent) |
63//! | ✅ [Fingerprinting](crate::net::fingerprint) | ✅ [Ja3](crate::net::fingerprint::Ja3) ⸱ ✅ [Ja4](crate::net::fingerprint::Ja4) ⸱ ✅ [Ja4H](crate::net::fingerprint::Ja4H) ⸱ 🏗️ [Akamai passive h2](https://github.com/plabayo/rama/issues/517) <sup>(1)</sup> ⸱ 🏗️ [Peetprint (tls)](https://github.com/plabayo/rama/issues/518) <sup>(1)</sup> |
64//! | ✅ utilities | ✅ [error handling](crate::error) ⸱ ✅ [graceful shutdown](crate::graceful) ⸱ ✅ [Connection Pool](crate::net::client::Pool) ⸱ ✅ [Tower Adapter](crate::utils::tower) ⸱ 🏗️ IP2Loc <sup>(2)</sup> |
65//! | 🏗️ Graphical Interface | 🏗️ traffic logger <sup>(2)</sup> ⸱ 🏗️ curl export <sup>(2)</sup> ⸱ 🏗️ [TUI implementation](https://ratatui.rs/) <sup>(2)</sup> ⸱ ❌ traffic intercept <sup>(3)</sup> ⸱ ❌ traffic replay <sup>(3)</sup> |
66//! | ✅ binary | ✅ [prebuilt binaries](https://ramaproxy.org/book/deploy/rama-cli) ⸱ 🏗️ proxy config <sup>(2)</sup> ⸱ ✅ http client <sup>(1)</sup> ⸱ ❌ WASM Plugins <sup>(3)</sup> |
67//! | 🏗️ data scraping | 🏗️ Html Processor <sup>(2)</sup> ⸱ ❌ Json Processor <sup>(3)</sup> |
68//! | ❌ browser | ❌ JS Engine <sup>(3)</sup> ⸱ ❌ [Web API](https://developer.mozilla.org/en-US/docs/Web/API) Emulation <sup>(3)</sup> |
69//!
70//! [Username Config]: https://docs.rs/rama-core/latest/rama_core/username/index.html
71//!
72//! > 🗒️ _Footnotes_
73//! >
74//! > * <sup>(1)</sup> Part of [`v0.2.0` milestone (ETA: 2025 Q2)](https://github.com/plabayo/rama/milestone/1)
75//! > * <sup>(2)</sup> Part of [`v0.3.0` milestone (ETA: 2025 Q3)](https://github.com/plabayo/rama/milestone/2)
76//! > * <sup>(3)</sup> No immediate plans, but on our radar. Please [open an issue](https://github.com/plabayo/rama/issues) to request this feature if you have an immediate need for it. Please add sufficient motivation/reasoning and consider [becoming a sponsor](https://ramaproxy.org/book/sponsor.html) to help accelerate its priority.
77//!
78//! The primary focus of Rama is to aid you in your development of [proxies](https://ramaproxy.org/book/proxies/intro.html):
79//!
80//! - 🚦 [Reverse proxies](https://ramaproxy.org/book/proxies/reverse);
81//! - 🔓 [TLS Termination proxies](https://ramaproxy.org/book/proxies/tls);
82//! - 🌐 [HTTP(S) proxies](https://ramaproxy.org/book/proxies/http);
83//! - 🧦 [SOCKS5 proxies](https://ramaproxy.org/book/proxies/socks5) (will be implemented in `v0.3`);
84//! - 🔎 [MITM proxies](https://ramaproxy.org/book/proxies/mitm);
85//! - 🕵️♀️ [Distortion proxies](https://ramaproxy.org/book/proxies/distort).
86//!
87//! > 💡 Check out [the "Intro to Proxies" chapters in the Rama book](https://ramaproxy.org/book/proxies/intro.html)
88//! > to learn more about the different kind of proxies. It might help in case you are new to developing proxies.
89//!
90//! The [Distortion proxies](https://ramaproxy.org/book/proxies/distort) support
91//! comes with [User Agent (UA)](https://ramaproxy.org/book/intro/user_agent) emulation capabilities. The emulations are made possible by patterns
92//! and data extracted using [`rama-fp`](https://github.com/plabayo/rama/tree/main/rama-fp/). The service is publicly exposed at
93//! <https://fp.ramaproxy.org>, made possible by our sponsor host <https://fly.io/>.
94//!
95//! > 🔁 <https://echo.ramaproxy.org/> is another service publicly exposed.
96//! > In contrast to the Fingerprinting Service it is aimed at developers
97//! > and allows you to send any http request you wish in order to get an insight
98//! > on the Tls Info and Http Request Info the server receives
99//! > from you when making that request.
100//! >
101//! > ```bash
102//! > curl -XPOST 'https://echo.ramaproxy.org/foo?bar=baz' \
103//! > -H 'x-magic: 42' --data 'whatever forever'
104//! > ```
105//! >
106//! > Feel free to make use of while crafting distorted http requests,
107//! > but please do so with moderation. In case you have ideas on how to improve
108//! > the service, please let us know [by opening an issue](https://github.com/plabayo/rama/issues).
109//!
110//! [BrowserStack](https://browserstack.com) sponsors Rama by providing automated cross-platform browser testing
111//! on real devices, which [uses the public fingerprinting service](https://github.com/plabayo/rama/tree/main/rama-fp/browserstack/main.py) to aid in automated fingerprint collection
112//! on both the Http and Tls layers. By design we do not consider Tcp and Udp fingerprinting.
113//!
114//! Next to proxies, Rama can also be used to develop [Web Services](#--web-services) and [Http Clients](#--http-clients).
115//!
116//! - Learn more by reading the Rama book at <https://ramaproxy.org/book>;
117//! - or checkout the framework Rust docs at <https://docs.rs/rama>;
118//! - edge docs (for main branch) can be found at <https://ramaproxy.org/docs/rama>.
119//!
120//! 📖 Rama's full documentation, references and background material can be found in the form of the "rama book" at <https://ramaproxy.org/book>.
121//!
122//! 💬 Come join us at [Discord](https://discord.gg/29EetaSYCD) on the `#rama` public channel. To ask questions, discuss ideas and ask how rama may be useful for you.
123//!
124//! > Rama also has a public channel on the official Discord of the tokio project.
125//! > Feel free to join us there instead or as well: <https://discord.com/channels/500028886025895936/1349098858831024209>
126//!
127//! [](https://ramaproxy.org/)
128//!
129//! ## 🧪 | Experimental
130//!
131//! 🦙 Rama (ラマ) is to be considered experimental software for the foreseeable future. In the meanwhile it is already used
132//! in production by ourselves and others alike. This is great as it gives us new perspectives and data to further improve
133//! and grow the framework. It does mean however that there are still several non-backward compatible releases that will follow `0.2`.
134//!
135//! In the meanwhile the async ecosystem of Rust is also maturing, and edition 2024 is also to be expected as a 2024 end of year gift.
136//! It goes also without saying that we do not nilly-willy change designs or break on purpose. The core design is by now also well defined. But truth has to be said,
137//! there is still plenty to be improve and work out. Production use and feedback from you and other users helps a lot with that. As such,
138//! if you use Rama do let us know feedback over [Discord][discord-url], [email](mailto:glen@plabayo.tech) or a [GitHub issue](https://github.com/plabayo/rama/issues).
139//!
140//! 👉 If you are a company or enterprise that makes use of Rama, or even an individual user that makes use of Rama for commcercial purposes.
141//! Please consider becoming [a business/enterprise subscriber](https://github.com/sponsors/plabayo/sponsorships?tier_id=300734).
142//! It helps make the development cycle to remain sustainable, and is beneficial to you as well.
143//! As part of your benefits we are also available to assist you with migrations between breaking releases.
144//! For enterprise users we can even make time to develop those PR's in your integration codebases ourselves on your behalf.
145//! A win for everybody. 💪
146//!
147//! [discord-url]: https://discord.gg/29EetaSYCD
148//!
149//! ## 📣 | Rama Ecosystem
150//!
151//! For now there are only the rama crates found in this repository, also referred to as "official" rama crates.
152//!
153//! We welcome however community contributions not only in the form of contributions to this repository,
154//! but also have people write their own crates as extensions to the rama ecosystem.
155//! E.g. perhaps you wish to support an alternative http/tls backend.
156//!
157//! In case you have ideas for new features or stacks please let us know first.
158//! Perhaps there is room for these within an official rama crate.
159//! In case it is considered out of scope you are free to make your own community rama crate.
160//! Please prefix all rama community crates with "rama-x", this way the crates are easy to find,
161//! and are sufficiently different from "official" rama crates".
162//!
163//! Once you have such a crate published do let us know it, such that we can list them here.
164//!
165//! ### 📦 | Rama Crates
166//!
167//! The `rama` crate can be used as the one and only dependency.
168//! However, as you can also read in the "DIY" chapter of the book
169//! at <https://ramaproxy.org/book/diy.html#empowering>, you are able
170//! to pick and choose not only what specific parts of `rama` you wish to use,
171//! but also in fact what specific (sub) crates.
172//!
173//! Here is a list of all `rama` crates:
174//!
175//! - [`rama`][crate]: one crate to rule them all
176//! - [`rama-error`](https://crates.io/crates/rama-error): error utilities for rama and its users
177//! - [`rama-macros`](https://crates.io/crates/rama-macros): contains the procedural macros used by `rama`
178//! - [`rama-utils`](https://crates.io/crates/rama-utils): utilities crate for rama
179//! - [`rama-core`](https://crates.io/crates/rama-core): core crate containing the service, layer and
180//! context used by all other `rama` code, as well as some other _core_ utilities
181//! - [`rama-net`](https://crates.io/crates/rama-net): rama network types and utilities
182//! - [`rama-dns`](https://crates.io/crates/rama-dns): DNS support for rama
183//! - [`rama-tcp`](https://crates.io/crates/rama-tcp): TCP support for rama
184//! - [`rama-udp`](https://crates.io/crates/rama-udp): UDP support for rama
185//! - [`rama-tls-boring`](https://crates.io/crates/rama-tls-boring): [Boring](https://github.com/plabayo/rama-boring) tls support for rama
186//! - [`rama-tls-rustls`](https://crates.io/crates/rama-tls-rustls): [Rustls](https://github.com/rustls/rustls) support for rama
187//! - [`rama-proxy`](https://crates.io/crates/rama-proxy): proxy types and utilities for rama
188//! - [`rama-socks5`](https://crates.io/crates/rama-socks5): SOCKS5 support for rama
189//! - [`rama-haproxy`](https://crates.io/crates/rama-haproxy): rama HaProxy support
190//! - [`rama-ua`](https://crates.io/crates/rama-ua): User-Agent (UA) support for `rama`
191//! - [`rama-http-types`](https://crates.io/crates/rama-http-types): http types and utilities
192//! - [`rama-http`](https://crates.io/crates/rama-http): rama http services, layers and utilities
193//! - [`rama-http-backend`](https://crates.io/crates/rama-http-backend): default http backend for `rama`
194//! - [`rama-http-core`](https://crates.io/crates/rama-http-core): http protocol implementation driving `rama-http-backend`
195//! - [`rama-tower`](https://crates.io/crates/rama-tower): provide [tower](https://github.com/tower-rs/tower) compatibility for `rama`
196//!
197//! `rama` crates that live in <https://github.com/plabayo/rama-boring> (forks of `cloudflare/boring`):
198//!
199//! - [`rama-boring`](https://crates.io/crates/rama-boring): BoringSSL bindings for Rama
200//! - [`rama-boring-sys`](https://crates.io/crates/rama-boring-sys): FFI bindings to BoringSSL for Rama
201//! - [`rama-boring-tokio`](https://crates.io/crates/rama-boring-tokio): an implementation of SSL streams for Tokio backed by BoringSSL in function of Rama
202//!
203//! repositories in function of rama that aren't crates:
204//!
205//! - <https://github.com/plabayo/rama-boringssl>:
206//! Fork of [mirror of BoringSSL](https://github.com/plabayo/rama-boringssl)
207//! in function of [rama-boring](https://github.com/plabayo/rama-boring)
208//! - <https://github.com/plabayo/homebrew-rama>: Homebrew formula for the rama Cli tool
209//!
210//! ## 🏢 | Proxy Examples
211//!
212//! - [/examples/tls_rustls_termination.rs](https://github.com/plabayo/rama/tree/main/examples/tls_rustls_termination.rs):
213//! Spawns a mini handmade http server, as well as a TLS termination proxy (using rustls), forwarding the
214//! plain text stream to the first.
215//! - [/examples/tls_rustls_termination.rs](https://github.com/plabayo/rama/tree/main/examples/tls_boring_termination.rs):
216//! Spawns a mini handmade http server, as well as a TLS termination proxy (using boring), forwarding the
217//! plain text stream to the first.
218//! - [/examples/mtls_tunnel_and_service.rs](https://github.com/plabayo/rama/blob/main/examples/mtls_tunnel_and_service.rs):
219//! Example of how to do mTls (manual Tls, where the client also needs a certificate) using rama,
220//! as well as how one might use this concept to provide a tunnel service build with these concepts;
221//! - [/examples/http_connect_proxy.rs](https://github.com/plabayo/rama/tree/main/examples/http_connect_proxy.rs):
222//! Spawns a minimal http proxy which accepts http/1.1 and h2 connections alike,
223//! and proxies them to the target host.
224//!
225//! ## 🌐 | Web Services
226//!
227//! Developing proxies are the primary focus of Rama (ラマ). It can however also be used to develop web services to serve web pages, Http API's and static content. This comes with many of the same benefits that you get when developing proxies using Rama:
228//!
229//! * Use Async Method Traits;
230//! * Reuse modular [Tower](https://github.com/tower-rs/tower)-like middleware using extensions as well as strongly typed state;
231//! * Have the ability to be in full control of your web stack from Transport Layer (Tcp, Udp), through Tls and Http;
232//! * If all you care about is the Http layer then that is fine to.
233//! * Be able to trust that your incoming Application Http data has not been modified (e.g. Http header casing and order is preserved);
234//! * Easily develop your service at a Request layer and High level functions alike, choices are yours and can be combined.
235//!
236//! Examples of the kind of web services you might build with rama in function of your proxy service:
237//!
238//! - a k8s health service ([/examples/http_k8s_health.rs](https://github.com/plabayo/rama/tree/main/examples/http_k8s_health.rs));
239//! - a metric exposure service;
240//! - a minimal api service (e.g. to expose device profiles or certificates);
241//! - a graphical interface / control panel;
242//!
243//! > 📖 Learn more about developing web services in the Rama book: <https://ramaproxy.org/book/web_servers.html>.
244//!
245//! ## 🌐 | Web Service Examples
246//!
247//! Here are some low level web service examples without fancy features:
248//!
249//! - [/examples/http_listener_hello.rs](https://github.com/plabayo/rama/blob/main/examples/http_listener_hello.rs): is the most basic example on how to provide
250//! a root service with no needs for endpoints or anything else (e.g. good enough for some use cases related
251//! to health services or metrics exposures);
252//! - [/examples/http_health_check.rs](https://github.com/plabayo/rama/blob/main/examples/http_health_check.rs) is an even more minimal example
253//! of a health check service returning a _200 OK_ for any incoming request.
254//! - [/examples/http_service_hello.rs](https://github.com/plabayo/rama/blob/main/examples/http_service_hello.rs): is an example similar to the previous
255//! example but shows how you can also operate on the underlying transport (TCP) layer, prior to passing it to your
256//! http service;
257//!
258//! There's also a premade webservice that can be used as the health service for your proxy k8s workloads:
259//!
260//! - [/examples/http_k8s_health.rs](https://github.com/plabayo/rama/tree/main/examples/http_k8s_health.rs):
261//! built-in web service that can be used as a k8s health service for proxies deploying as a k8s deployment;
262//!
263//! The following are examples that use the high level concepts of Request/State extractors and IntoResponse converters,
264//! that you'll recognise from `axum`, just as available for `rama` services:
265//!
266//! - [/examples/http_key_value_store.rs](https://github.com/plabayo/rama/tree/main/examples/http_key_value_store.rs):
267//! a web service example showcasing how one might do a key value store web service using `Rama`;
268//! - [/examples/http_web_service_dir_and_api.rs](https://github.com/plabayo/rama/tree/main/examples/http_web_service_dir_and_api.rs):
269//! a web service example showcasing how one can make a web service to serve a website which includes an XHR API;
270//! - [/examples/http_web_router.rs](https://github.com/plabayo/rama/tree/main/examples/http_web_router.rs):
271//! a web service example showcasing demonstrating how to create a web router, which is excellent for the typical path-centric routing,
272//! and an approach you'll recognise from most other web frameworks out there.
273//!
274//! For a production-like example of a web service you can also read the [`rama-fp` source code](https://github.com/plabayo/rama/tree/main/rama-fp/src).
275//! This is the webservice behind the Rama fingerprinting service, which is used by the maintainers of 🦙 Rama (ラマ) to generate
276//! the UA emulation data for the Http and TLS layers. It is not meant to fingerprint humans or users. Instead it is meant to help
277//! automated processes look like a human.
278//!
279//! > 💡 This example showcases how you can make use of the [`match_service`](https://docs.rs/rama-http/latest/rama_http/service/web/macro.match_service.html)
280//! > macro to create a `Box`-free service router. Another example of this approach can be seen in the
281//! > [/examples/http_service_match.rs](https://github.com/plabayo/rama/tree/main/examples/http_service_match.rs) example.
282//!
283//! ### Datastar
284//!
285//! [](https://crates.io/crates/datastar)
286//! [](https://docs.rs/datastar/latest/datastar/index.html)
287//!
288//! Rama is also supported in the official Rust SDK of [🚀 data-\*](https://data-star.dev).
289//! Learn more about it at <https://ramaproxy.org/book/web_servers.html#datastar> or see it in
290//! action at [datastar > examples > rust > rama](https://github.com/starfederation/datastar/blob/develop/examples/rust/rama/hello-world/src/main.rs):
291//!
292//! ```plain
293//! async fn hello_world(ReadSignals(signals): ReadSignals<Signals>) -> impl IntoResponse {
294//! Sse(stream! {
295//! for i in 0..MESSAGE.len() {
296//! yield MergeFragments::new(format!("<div id='message'>{}</div>", &MESSAGE[0..i + 1])).into();
297//! tokio::time::sleep(Duration::from_millis(signals.delay)).await;
298//! }
299//! })
300//! }
301//! ```
302//!
303//! ## 🧑💻 | Http Clients
304//!
305//! In [The rama book](https://ramaproxy.org/book) you can read and learn that a big pillar of Rama's architecture is build on top of [the Service concept](https://ramaproxy.org/book/intro/services_all_the_way_down.html). A [`Service`][rama-service] takes as input a user-defined `State` (e.g. containing your database Pool) and a `Request`, and uses it to serve either a `Response` or `Error`. Such a [`Service`][rama-service] can produce the response "directly" (also called ☘️ Leaf services) or instead pass the request and state to an inner [`Service`][rama-service] which it wraps around (so called 🍔 Middlewares).
306//!
307//! [rama-service]: https://ramaproxy.org/docs/rama/service/trait.Service.html
308//!
309//! It's a powerful concept, originally introduced to Rust by [the Tower ecosystem](https://github.com/tower-rs/tower) and allows you build complex stacks specialised to your needs in a modular and easy manner. Even cooler is that this works for both clients and servers alike.
310//!
311//! Rama provides an [`EasyHttpWebClient`](https://ramaproxy.org/docs/rama/http/client/struct.EasyHttpWebClient.html) which sends your _Http_ `Request` over the network and returns the `Response` if it receives and read one or an `Error` otherwise. Combined with [the many Layers (middleware)](https://ramaproxy.org/docs/rama/http/layer/index.html) that `Rama` provides and perhaps also some developed by you it is possible to create a powerful _Http_ client suited to your needs.
312//!
313//! As a 🍒 cherry on the cake you can import the [`HttpClientExt`](https://ramaproxy.org/docs/rama/http/service/client/trait.HttpClientExt.html) trait in your Rust module to be able to use your _Http_ Client [`Service`][rama-service] stack using a high level API to build and send requests with ease.
314//!
315//! ### 🧑💻 | Http Client Example
316//!
317//! > 💡 The full "high level" example can be found at [/examples/http_high_level_client.rs](https://github.com/plabayo/rama/tree/main/examples/http_high_level_client.rs).
318//!
319//! ```rust,ignore
320//! # #[cfg(feature = "do-not-ever-run")]
321//! # {
322//! use rama::http::service::client::HttpClientExt;
323//!
324//! let client = (
325//! TraceLayer::new_for_http(),
326//! DecompressionLayer::new(),
327//! AddAuthorizationLayer::basic("john", "123")
328//! .as_sensitive(true)
329//! .if_not_present(),
330//! RetryLayer::new(
331//! ManagedPolicy::default().with_backoff(ExponentialBackoff::default()),
332//! ),
333//! ).into_layer(EasyHttpWebClient::default());
334//!
335//! #[derive(Debug, Deserialize)]
336//! struct Info {
337//! name: String,
338//! example: String,
339//! magic: u64,
340//! }
341//!
342//! let info: Info = client
343//! .get("http://example.com/info")
344//! .header("x-magic", "42")
345//! .typed_header(Accept::json())
346//! .send(Context::default())
347//! .await
348//! .unwrap()
349//! .try_into_json()
350//! .await
351//! .unwrap();
352//! # }
353//! ```
354
355#![doc(
356 html_favicon_url = "https://raw.githubusercontent.com/plabayo/rama/main/docs/img/old_logo.png"
357)]
358#![doc(html_logo_url = "https://raw.githubusercontent.com/plabayo/rama/main/docs/img/old_logo.png")]
359#![cfg_attr(docsrs, feature(doc_auto_cfg, doc_cfg))]
360#![cfg_attr(test, allow(clippy::float_cmp))]
361#![cfg_attr(not(test), warn(clippy::print_stdout, clippy::dbg_macro))]
362
363#[doc(inline)]
364pub use ::rama_core::{
365 Context, Layer, Service, combinators, context, error, graceful, inspect, layer, matcher, rt,
366 service, username,
367};
368
369#[cfg(feature = "tcp")]
370#[doc(inline)]
371pub use ::rama_tcp as tcp;
372
373#[cfg(feature = "udp")]
374#[doc(inline)]
375pub use ::rama_udp as udp;
376
377#[cfg(feature = "telemetry")]
378#[doc(inline)]
379pub use ::rama_core::telemetry;
380
381#[cfg(any(feature = "rustls", feature = "boring"))]
382pub mod tls {
383 #[cfg(feature = "boring")]
384 #[doc(inline)]
385 pub use ::rama_tls_boring as boring;
386
387 #[cfg(feature = "rustls")]
388 #[doc(inline)]
389 pub use ::rama_tls_rustls as rustls;
390}
391
392#[cfg(feature = "dns")]
393#[doc(inline)]
394pub use ::rama_dns as dns;
395
396#[cfg(feature = "net")]
397#[doc(inline)]
398pub use ::rama_net as net;
399
400#[cfg(feature = "http")]
401pub mod http;
402
403#[cfg(any(feature = "proxy", feature = "haproxy"))]
404pub mod proxy {
405 //! rama proxy support
406
407 #[cfg(feature = "proxy")]
408 #[doc(inline)]
409 pub use ::rama_proxy::*;
410
411 #[cfg(feature = "haproxy")]
412 #[doc(inline)]
413 pub use ::rama_haproxy as haproxy;
414}
415
416#[cfg(feature = "ua")]
417#[doc(inline)]
418pub use ::rama_ua as ua;
419
420#[cfg(feature = "cli")]
421pub mod cli;
422
423pub mod utils {
424 //! utilities for rama
425
426 #[doc(inline)]
427 pub use ::rama_utils::*;
428
429 #[cfg(feature = "tower")]
430 #[doc(inline)]
431 pub use ::rama_tower as tower;
432}