diff options
author | Paul Woolcock <paul@woolcock.us> | 2020-10-07 05:47:39 -0400 |
---|---|---|
committer | Paul Woolcock <paul@woolcock.us> | 2020-10-07 09:06:13 -0400 |
commit | 02ca0a89515413ac9fb3b655de2f21f6a711e0f2 (patch) | |
tree | 004bcd9f88eca168e10e1ac85c5987fdd6769fcf /src/async/client.rs | |
parent | 04b5b54212629f058bdab1ba55c89a3d417e0454 (diff) |
Add basic async client
This adds a module, accessible by compiling with `--features async`,
that provides an `elefren::async::Client`. The client is
runtime-agnostic, and currently only provides unauthenticated access,
see the docs for the full list of methods that can be performed* with
this client.
* note that some API calls are publicly available by default, but can be
changed via instance settings to not be publicly accessible
Diffstat (limited to 'src/async/client.rs')
-rw-r--r-- | src/async/client.rs | 52 |
1 files changed, 52 insertions, 0 deletions
diff --git a/src/async/client.rs b/src/async/client.rs new file mode 100644 index 0000000..5081c6f --- /dev/null +++ b/src/async/client.rs @@ -0,0 +1,52 @@ +use crate::{ + entities::{account::Account, card::Card, context::Context, status::Status}, + errors::{Error, Result}, +}; +use http_types::{Method, Request, Response}; +use hyper_old_types::header::{parsing, Link, RelationType}; +use smol::{prelude::*, Async}; +use std::net::{TcpStream, ToSocketAddrs}; +use url::Url; + +// taken pretty much verbatim from `smol`s example + +/// Sends a request and fetches the response. +pub(super) async fn fetch(req: Request) -> Result<Response> { + // Figure out the host and the port. + let host = req + .url() + .host() + .ok_or_else(|| String::from("No host found"))? + .to_string(); + let port = req + .url() + .port_or_known_default() + .ok_or_else(|| Error::Other(String::from("No port found")))?; + + // Connect to the host. + let socket_addr = { + let host = host.clone(); + smol::unblock(move || (host.as_str(), port).to_socket_addrs()) + .await? + .next() + .ok_or_else(|| Error::Other(String::from("No socket addr")))? + }; + let stream = Async::<TcpStream>::connect(socket_addr).await?; + + // Send the request and wait for the response. + let resp = match req.url().scheme() { + "http" => async_h1::connect(stream, req).await?, + "https" => { + // In case of HTTPS, establish a secure TLS connection first. + let stream = async_native_tls::connect(&host, stream).await?; + async_h1::connect(stream, req).await? + }, + scheme => return Err(Error::Other(format!("unsupported scheme '{}'", scheme))), + }; + Ok(resp) +} + +pub(super) async fn get(url: Url) -> Result<Response> { + let req = Request::new(Method::Get, url); + Ok(fetch(req).await?) +} |