Rama 101.1: HTTPS clients and layers of abstractionSkip to contentBack to blogNote<br>Follow our blog by subscribing to our newsletter or following our RSS Feed and do not miss when we release a new article in Rama 101, a series of blog articles to introduce you to Rama. In case you are new to network programming, you might learn a thing or two about its nifty protocols and how they "work together" as well.
In each article I will try to explain one or more concepts by means of a kind of example that I hope most of you are familiar with. For this first part we will use HTTPS clients as an example. But before that, and given that this is the start of the series, let us quickly answer another question first.<br>What is Rama<br>Rama is a modular service framework for the Rust language. That's how the Rama project README introduces it, and many of our other resources do so in a similar vein, be it perhaps more focused on proxies.<br>But if you boil it all down to its essentials, then it is this: Rama is meant to be the modular foundation that we can all share and build network services with. Meaning some kind of process that interacts with and within a computer network as a client, server, or a combination of both.<br>We call Rama a framework instead of a library to try to make it clear that it really provides you with an entire cohesive foundation. Rama consists of many crates (and modules), each focused on another feature or protocol. It is modular, as the framework is designed in such a way that it allows you to compose it all together in whatever way suits your business use case. You will see plenty of examples of that in this series.<br>Yet, because all these modules and crates are in fact part of a bigger framework (Rama), you do not need to worry about whether something is compatible (e.g. version-, API-, or protocol-wise). This important property is guaranteed not only by its design, but also by its many layers and different kinds of tests, right from the smallest unit test up to verifications of entire network services, their behavior and correctness. Not just today, but through its entire evolution, starting 5 years ago and hopefully continuing for many decades still to come.<br>And whenever any of us makes any kind of improvement, we all benefit from it. This is important as many pitfalls in network programming are not due to mistakes in any specific unit but are instead only made by means of composition. Those are the kind of hard lessons that the developers of projects made from duct-taped libraries have to learn the hard way, over and over again. But not you, as a Rama user.<br>An HTTPS Request<br>With the preface behind us, let us begin with something that I am hoping pretty much all of you are familiar with. Let's make an HTTPS request. The fact that you are reading this most likely means you used software that made an HTTPS request, be it via a web browser or via whatever application you use to read it through our RSS Feed.<br>Rustrama#d9272fc91let my_ip: Ipv4Addr = client2 .get("http://ipv4.ramaproxy.org")3 .typed_header(UserAgent::rama())4 .send_with_timeout(Duration::from_secs(30))5 .await6 .expect("send http(s) request")7 .try_into_string_with(8 CollectOptions::new()9 .with_timeout(Duration::from_secs(30))10 .with_max_size(3 + 3 * 4),11 )12 .await13 .expect("collect response payload")14 .parse()15 .expect("parse as IPv4 Address");1617println!("my ip: {my_ip}");In this example we make use of a constructed HTTPS client to "make" an HTTP request (that will in fact be redirected to an HTTPS request), wait (with limits) for it to be sent and for a response to come back, collect the body as a String, and parse it into an Ipv4Addr. That's a lot, yet at the same time hopefully familiar to most of you.<br>If not in code it might perhaps look more familiar to you as a CLI command:<br>bash1rama -L http://ipv4.ramaproxy.orgTip<br>You can learn more about the Rama CLI binary tool and how to install it in this Rama book chapter. The Rama CLI is not only a web client, but also a tool that allows you to run network servers of all kinds or help you interact with several protocols (probe).
Let's bring our focus back on the code, because usually when we refer to Rama, we mean the (Rust) framework instead. I will now zoom in on the type of client used in the example above. The easiest way to create an HTTPS client is by using the EasyHttpWebClient:<br>Rustrama#d9272fc91let client = EasyHttpWebClient::default();It is a prime example of the highest kind of abstraction provided in Rama and excellent for things that many people need for all kinds of reasons. Even within the most advanced proxy project you might need to interact with a remote server to sync information in one direction or the other.<br>However, even a convenient high-level abstraction like EasyHttpWebClient does not yet provide everything you would want within a production environment setting. This is because we do not want to make choices for you based on assumptions that we cannot...