Skip to content

Commit

Permalink
Moved fire module, linting, removed unused deps, added missing docs, …
Browse files Browse the repository at this point in the history
…added lint restrictions
  • Loading branch information
jacobtread committed Nov 25, 2023
1 parent a208f0f commit 7e893d9
Show file tree
Hide file tree
Showing 11 changed files with 141 additions and 88 deletions.
2 changes: 0 additions & 2 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@ repository = "https://github.com/PocketRelay/PocketRelayClientShared"
[dependencies]
# Logging
log = "0.4"
env_logger = "0.10"

# HTTP client (native-tls is required for client auth)
reqwest = { version = "0.11", default-features = false, features = [
Expand All @@ -22,7 +21,6 @@ reqwest = { version = "0.11", default-features = false, features = [

# Serialization
serde = { version = "1", features = ["derive"] }
serde_json = "1"

# SSLv3 implementation for the game communications
blaze-ssl-async = "^0.3"
Expand Down
39 changes: 26 additions & 13 deletions src/api.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
//! API logic for HTTP requests that are sent to the Pocket Relay server
use crate::{servers::HTTP_PORT, MIN_SERVER_VERSION};
use hyper::{
header::{self, HeaderName, HeaderValue},
Expand Down Expand Up @@ -41,7 +43,7 @@ mod headers {
/// if one is provided
///
/// ## Arguments
/// * identity - Optional identity for the client to use
/// * `identity` - Optional identity for the client to use
pub fn create_http_client(identity: Option<Identity>) -> Result<Client, reqwest::Error> {
let mut builder = Client::builder().user_agent(USER_AGENT);

Expand All @@ -52,10 +54,13 @@ pub fn create_http_client(identity: Option<Identity>) -> Result<Client, reqwest:
builder.build()
}

/// Errors that can occur when loading the client identity
#[derive(Debug, Error)]
pub enum ClientIdentityError {
/// Failed to read the identity file
#[error("Failed to read identity: {0}")]
Read(#[from] std::io::Error),
/// Failed to create the identity
#[error("Failed to create identity: {0}")]
Create(#[from] reqwest::Error),
}
Expand All @@ -65,7 +70,7 @@ pub enum ClientIdentityError {
/// certificate and private key with a blank password
///
/// ## Arguments
/// * path - The path to read the identity from
/// * `path` - The path to read the identity from
pub fn read_client_identity(path: &Path) -> Result<Identity, ClientIdentityError> {
// Read the identity file bytes
let bytes = std::fs::read(path).map_err(ClientIdentityError::Read)?;
Expand Down Expand Up @@ -121,20 +126,24 @@ pub enum LookupError {

/// Attempts to lookup a server at the provided url to see if
/// its a Pocket Relay server
///
/// ## Arguments
/// * `http_client` - The HTTP client to connect with
/// * `base_url` - The server base URL (Connection URL)
pub async fn lookup_server(
http_client: reqwest::Client,
host: String,
) -> Result<LookupData, LookupError> {
let mut url = String::new();

// Whether a scheme was inferred
let mut inserted_scheme = false;
let mut inferred_scheme = false;

// Fill in missing scheme portion
if !host.starts_with("http://") && !host.starts_with("https://") {
url.push_str("http://");

inserted_scheme = true;
inferred_scheme = true;
}

url.push_str(&host);
Expand All @@ -147,21 +156,23 @@ pub async fn lookup_server(
let mut url = Url::from_str(&url)?;

// Update scheme to be https if the 443 port was specified and the scheme was inferred as http://
if url.port().is_some_and(|port| port == 443) && inserted_scheme {
if url.port().is_some_and(|port| port == 443) && inferred_scheme {
let _ = url.set_scheme("https");
}

let info_url = url
.join(DETAILS_ENDPOINT)
.expect("Failed to create server details URL");

// Send the HTTP request and get its response
let response = http_client
.get(info_url)
.header(header::ACCEPT, "application/json")
.send()
.await
.map_err(LookupError::ConnectionFailed)?;

// Debug printing of response details for debug builds
#[cfg(debug_assertions)]
{
use log::debug;
Expand All @@ -172,10 +183,12 @@ pub async fn lookup_server(
debug!("HTTP Headers: {:?}", response.headers());
}

// Ensure the response wasn't a non 200 response
let response = response
.error_for_status()
.map_err(LookupError::ErrorResponse)?;

// Parse the JSON serialized server details
let details = response
.json::<ServerDetails>()
.await
Expand Down Expand Up @@ -218,8 +231,8 @@ pub enum ServerStreamError {
/// with the Pocket Relay server
///
/// ## Arguments
/// * http_client - The HTTP client to connect with
/// * base_url - The server base URL (Connection URL)
/// * `http_client` - The HTTP client to connect with
/// * `base_url` - The server base URL (Connection URL)
pub async fn create_server_stream(
http_client: reqwest::Client,
base_url: &Url,
Expand Down Expand Up @@ -284,15 +297,15 @@ pub struct TelemetryEvent {
/// Publishes a new telemetry event to the Pocket Relay server
///
/// ## Arguments
/// * http_client - The HTTP client to connect with
/// * base_url - The server base URL (Connection URL)
/// * event - The event to publish
/// * `http_client` - The HTTP client to connect with
/// * `base_url` - The server base URL (Connection URL)
/// * `event` - The event to publish
pub async fn publish_telemetry_event(
http_client: &reqwest::Client,
base_url: &Url,
event: TelemetryEvent,
) -> Result<(), reqwest::Error> {
// Create the upgrade endpoint URL
// Create the telemetry endpoint URL
let endpoint_url: Url = base_url
.join(TELEMETRY_ENDPOINT)
.expect("Failed to create telemetry endpoint");
Expand Down Expand Up @@ -321,8 +334,8 @@ pub enum ProxyError {
/// hyper response that can be served
///
/// ## Arguments
/// * http_client - The HTTP client to connect with
/// * url - The server URL to request
/// * `http_client` - The HTTP client to connect with
/// * `url` - The server URL to request
pub async fn proxy_http_request(
http_client: &reqwest::Client,
url: Url,
Expand Down
76 changes: 41 additions & 35 deletions src/blaze/mod.rs → src/fire.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
//! Minimal blaze packet parsing and creation implementation
//! Minimal fire packet parsing and creation implementation
//! this supports the very minimal required features
use bytes::{Buf, BufMut, Bytes};
Expand All @@ -23,7 +23,6 @@ pub enum FrameType {
impl From<u8> for FrameType {
fn from(value: u8) -> Self {
match value {
0x0 => FrameType::Request,
0x1 => FrameType::Response,
0x2 => FrameType::Notify,
0x3 => FrameType::Error,
Expand All @@ -32,8 +31,8 @@ impl From<u8> for FrameType {
}
}

/// Structure of the header for a frame
pub struct FireFrameHeader {
/// The header for a fire frame
pub struct FrameHeader {
/// The length of the frame contents
pub length: usize,
/// The component that should handle this frame
Expand All @@ -51,22 +50,23 @@ pub struct FireFrameHeader {
}

/// Packet framing structure
pub struct FireFrame {
pub struct Frame {
/// Header for the frame
pub header: FireFrameHeader,
pub header: FrameHeader,
/// The encoded byte contents of the packet
pub contents: Bytes,
}

impl FireFrame {
pub fn response<V>(header: &FireFrameHeader, value: V) -> FireFrame
where
V: TdfSerialize,
{
let contents = Bytes::from(serialize_vec(&value));

FireFrame {
header: FireFrameHeader {
impl Frame {
/// Creates a new response frame responding to the provided `header`
/// with the bytes contents of `value`
///
/// ## Arguments
/// * `header` - The header of the frame to respond to
/// * `contents` - The bytes of the frame
pub fn response_raw(header: &FrameHeader, contents: Bytes) -> Frame {
Frame {
header: FrameHeader {
length: contents.len(),
component: header.component,
command: header.command,
Expand All @@ -79,29 +79,35 @@ impl FireFrame {
}
}

pub fn response_empty(header: &FireFrameHeader) -> FireFrame {
let contents = Bytes::new();
/// Creates a new response frame responding to the provided `header`
/// with the encoded contents of the `value`
///
/// ## Arguments
/// * `header` - The header of the frame to respond to
/// * `value` - The value to encode as the frame bytes
#[inline]
pub fn response<V>(header: &FrameHeader, value: V) -> Frame
where
V: TdfSerialize,
{
Self::response_raw(header, Bytes::from(serialize_vec(&value)))
}

FireFrame {
header: FireFrameHeader {
length: contents.len(),
component: header.component,
command: header.command,
error: 0,
ty: FrameType::Response,
options: 0,
seq: header.seq,
},
contents,
}
/// Creates a new response frame responding to the provided `header`
/// with empty contents
///
/// ## Arguments
/// * `header` - The header of the frame to respond to
pub fn response_empty(header: &FrameHeader) -> Frame {
Self::response_raw(header, Bytes::new())
}
}

/// Codec for encoding and decoding fire frames
#[derive(Default)]
pub struct FireCodec {
/// Incomplete frame thats currently being read
current_frame: Option<FireFrameHeader>,
current_frame: Option<FrameHeader>,
}

impl FireCodec {
Expand All @@ -112,7 +118,7 @@ impl Decoder for FireCodec {
// The codec doesn't have any errors of its own so IO error is used
type Error = io::Error;
// The decoder provides fire frames
type Item = FireFrame;
type Item = Frame;

fn decode(&mut self, src: &mut bytes::BytesMut) -> Result<Option<Self::Item>, Self::Error> {
let current_frame = if let Some(current_frame) = self.current_frame.as_mut() {
Expand All @@ -133,7 +139,7 @@ impl Decoder for FireCodec {
let options: u8 = src.get_u8() >> 4;
let seq: u16 = src.get_u16();

let header = FireFrameHeader {
let header = FrameHeader {
length,
component,
command,
Expand All @@ -156,17 +162,17 @@ impl Decoder for FireCodec {
// Take all the frame bytes
let buffer = src.split_to(header.length);

Ok(Some(FireFrame {
Ok(Some(Frame {
header,
contents: buffer.freeze(),
}))
}
}

impl Encoder<FireFrame> for FireCodec {
impl Encoder<Frame> for FireCodec {
type Error = io::Error;

fn encode(&mut self, item: FireFrame, dst: &mut bytes::BytesMut) -> Result<(), Self::Error> {
fn encode(&mut self, item: Frame, dst: &mut bytes::BytesMut) -> Result<(), Self::Error> {
let header = item.header;
dst.put_u16(header.length as u16);
dst.put_u16(header.component);
Expand Down
15 changes: 14 additions & 1 deletion src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,22 @@
#![warn(missing_docs, unused_variables, unused_crate_dependencies)]

//! Shared core for Pocket Relay client
//!
//! This library handles creating and running the local servers required
//! for connecting to Pocket Relay servers.
//!
//! It provides shared backend for the different variants to make it easier
//! to keep feature parody across versions
//!
//! [`PocketRelay`]: https://pocket-relay.pages.dev/
// Re-exports for dependencies
pub use reqwest;
pub use semver::Version;
pub use url::Url;

pub mod api;
pub mod blaze;
pub mod fire;
pub mod servers;
pub mod update;

Expand Down
12 changes: 6 additions & 6 deletions src/servers/blaze.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,8 @@ use url::Url;
/// Starts the blaze server
///
/// ## Arguments
/// * http_client - The HTTP client passed around for connection upgrades
/// * base_url - The server base URL to connect clients to
/// * `http_client` - The HTTP client passed around for connection upgrades
/// * `base_url` - The server base URL to connect clients to
pub async fn start_blaze_server(
http_client: reqwest::Client,
base_url: Arc<Url>,
Expand All @@ -26,16 +26,16 @@ pub async fn start_blaze_server(
loop {
let (client_stream, _) = listener.accept().await?;

spawn_server_task(handle(client_stream, http_client.clone(), base_url.clone()))
spawn_server_task(handle(client_stream, http_client.clone(), base_url.clone()));
}
}

/// Handler for processing BlazeSDK client connections
///
/// ## Arguments
/// * client_stream - The client stream to read and write from
/// * http_client - The HTTP client passed around for connection upgrades
/// * base_url - The server base URL to connect clients to
/// * `client_stream` - The client stream to read and write from
/// * `http_client` - The HTTP client passed around for connection upgrades
/// * `base_url` - The server base URL to connect clients to
async fn handle(mut client_stream: TcpStream, http_client: reqwest::Client, base_url: Arc<Url>) {
debug!("Starting blaze connection");

Expand Down
Loading

0 comments on commit 7e893d9

Please sign in to comment.