Skip to content

Commit

Permalink
feat:6.0.0
Browse files Browse the repository at this point in the history
  • Loading branch information
ltpp-universe committed Dec 2, 2024
1 parent 52713fb commit 745a052
Show file tree
Hide file tree
Showing 9 changed files with 159 additions and 48 deletions.
2 changes: 1 addition & 1 deletion Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "http-request"
version = "5.3.0"
version = "6.0.0"
edition = "2021"
authors = ["ltpp-universe <[email protected]>"]
license = "MIT"
Expand Down
22 changes: 11 additions & 11 deletions src/request/http_request/impl.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,10 @@ use crate::{
request::{
config::r#type::Config, error::Error, request_url::r#type::RequestUrl, tmp::r#type::Tmp,
},
response::{http_response_binary::r#type::HttpResponseBinary, r#trait::HttpResponse},
response::{
http_response_binary::r#type::HttpResponseBinary, r#trait::HttpResponse,
r#type::BoxHttpResponse,
},
utils::vec::case_insensitive_match,
};
use crate::{
Expand Down Expand Up @@ -225,7 +228,7 @@ impl HttpRequest {
fn send_get_request(
&mut self,
stream: &mut Box<dyn ReadWrite>,
) -> Result<HttpResponseBinary, Error> {
) -> Result<BoxHttpResponse, Error> {
let mut request: Vec<u8> = Vec::new();
let path: String = self.get_path();
let request_line_string: String =
Expand Down Expand Up @@ -256,7 +259,7 @@ impl HttpRequest {
fn send_post_request(
&mut self,
stream: &mut Box<dyn ReadWrite>,
) -> Result<HttpResponseBinary, Error> {
) -> Result<BoxHttpResponse, Error> {
let mut request: Vec<u8> = Vec::new();
let path: String = self.get_path();
let request_line_string: String =
Expand Down Expand Up @@ -287,10 +290,7 @@ impl HttpRequest {
/// Returns a `Result<HttpResponseBinary, Error>`, where:
/// - `Ok(HttpResponseBinary)` contains the complete HTTP response after processing headers and body.
/// - `Err(Error)` indicates that an error occurred while reading the response.
fn read_response(
&mut self,
stream: &mut Box<dyn ReadWrite>,
) -> Result<HttpResponseBinary, Error> {
fn read_response(&mut self, stream: &mut Box<dyn ReadWrite>) -> Result<BoxHttpResponse, Error> {
let buffer_size: usize = self.config.buffer;
let mut buffer: Vec<u8> = vec![0; buffer_size];
let mut response_bytes: Vec<u8> = Vec::new();
Expand Down Expand Up @@ -344,7 +344,7 @@ impl HttpRequest {
}
self.response = <HttpResponseBinary as HttpResponse>::from(&response_bytes);
if !self.config.redirect || redirect_url.is_none() {
return Ok(self.response.clone());
return Ok(Box::new(self.response.clone()));
}
let url: String =
String::from_utf8(redirect_url.unwrap()).map_err(|_| Error::InvalidUrl)?;
Expand Down Expand Up @@ -438,7 +438,7 @@ impl HttpRequest {
/// - `url`: The redirection URL to follow.
///
/// Returns `Ok(HttpResponseBinary)` if the redirection is successful, or `Err(Error)` otherwise.
fn handle_redirect(&mut self, url: String) -> Result<HttpResponseBinary, Error> {
fn handle_redirect(&mut self, url: String) -> Result<BoxHttpResponse, Error> {
if self.tmp.visit_url.contains(&url) {
return Err(Error::RedirectUrlDeadLoop);
}
Expand Down Expand Up @@ -529,15 +529,15 @@ impl HttpRequest {
/// Determines the HTTP method and constructs the appropriate request (GET or POST).
///
/// Returns `Ok(HttpResponseBinary)` if the request is successful, or `Err(Error)` otherwise.
pub fn send(&mut self) -> Result<HttpResponseBinary, Error> {
pub fn send(&mut self) -> Result<BoxHttpResponse, Error> {
self.config.url_obj = self.parse_url().map_err(|_| Error::InvalidUrl)?;
let methods: Methods = self.get_methods();
let host: String = self.config.url_obj.host.clone().unwrap_or_default();
let port: u16 = self.get_port(self.config.url_obj.port.clone().unwrap_or_default());
let mut stream: Box<dyn ReadWrite> = self
.get_connection_stream(host, port)
.map_err(|_| Error::TcpStreamConnectError)?;
let res: Result<HttpResponseBinary, Error> = match methods {
let res: Result<BoxHttpResponse, Error> = match methods {
m if m.is_get() => self.send_get_request(&mut stream),
m if m.is_post() => self.send_post_request(&mut stream),
_ => Err(Error::RequestError),
Expand Down
69 changes: 41 additions & 28 deletions src/response/http_response_binary/impl.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,35 +11,37 @@ use crate::{
};
use std::{collections::HashMap, vec::IntoIter};

/// Provides functionality for parsing and working with HTTP responses.
/// Implements the `HttpResponse` trait for `HttpResponseBinary`.
///
/// This implementation contains methods for extracting specific information from HTTP response
/// strings, such as content length, and parsing the entire response into an `HttpResponseBinary` object.
/// This implementation specifies the associated types for binary and text representations
/// of HTTP responses, enabling seamless conversion and handling of HTTP response data.
///
/// # Methods
/// - `get_content_length`: Extracts the `Content-Length` value from the HTTP response string.
/// - `from`: Parses a raw HTTP response string into an `HttpResponseBinary` struct, including the
/// status line, headers, and body.
/// # Associated Types
/// - `OutputText`: Specifies the text representation of an HTTP response (`HttpResponseText`).
/// - `OutputBinary`: Specifies the binary representation of an HTTP response (`HttpResponseBinary`).
impl HttpResponse for HttpResponseBinary {
type OutputText = HttpResponseText;
type OutputBinary = HttpResponseBinary;
/// Parses an HTTP response from a byte slice and returns an `HttpResponseBinary` object.

/// Parses a raw HTTP response from a byte slice and constructs an `HttpResponseBinary` instance.
///
/// This function processes the raw HTTP response in byte form. It splits the response into
/// the status line, headers, and body, parsing each part accordingly. The status line is parsed
/// to extract the HTTP version, status code, and status text. Headers are split and stored in
/// a `HashMap`. The body is collected into a byte vector.
/// This method processes the raw HTTP response into its constituent parts: status line, headers, and body.
/// Each part is parsed and stored in the resulting `HttpResponseBinary` object.
///
/// # Parameters
/// - `response`: A byte slice representing the raw HTTP response.
///
/// # Returns
/// Returns an `HttpResponseBinary` object containing the parsed HTTP version, status code, status text,
/// headers, and body. If parsing any part fails, defaults are used (e.g., `HTTP/1.1`, status code `200`).
/// - `HttpResponseBinary`: A structured representation of the parsed HTTP response, including
/// the HTTP version, status code, status text, headers, and body.
///
/// # Panics
/// This method will panic if the HTTP response is malformed in ways that the unwrap operations cannot handle.
fn from(response: &[u8]) -> Self {
/// - This method will panic if the HTTP response format is malformed and required components
/// such as the status line cannot be parsed.
fn from(response: &[u8]) -> Self
where
Self: Sized,
{
let split_lines: Vec<&[u8]> = split_multi_byte(response, HTTP_BR_BYTES);
let mut lines: IntoIter<&[u8]> = split_lines.into_iter();
let status_line: &[u8] = lines.next().unwrap_or(&[]);
Expand Down Expand Up @@ -82,23 +84,34 @@ impl HttpResponse for HttpResponseBinary {
}
}

/// Converts the response body to text format.
/// Returns a clone of the binary representation of the HTTP response.
///
/// This function takes the current response and creates a new `HttpResponseBinary`
/// instance with the body converted to a text representation. The `body` is
/// extracted as text from the original response body and stored in the new
/// response as a `ResponseBody::Text` variant.
/// This method is part of the `HttpResponse` trait implementation, allowing for retrieval
/// of the current binary HTTP response without modification.
///
/// # Returns
/// - `Self::OutputBinary`: A binary representation of the HTTP response, cloned from the current instance.
fn binary(&self) -> Self::OutputBinary {
self.clone()
}

/// Converts the binary HTTP response to its text representation.
///
/// - `Self` - A new `HttpResponseBinary` instance with the body converted to text.
fn text(self) -> HttpResponseText {
let body: String = String::from_utf8_lossy(&self.body).to_string();
/// This method processes the current instance of `HttpResponseBinary` by interpreting the
/// response body as UTF-8 encoded text, preserving other components such as HTTP version,
/// status code, status text, and headers unchanged.
///
/// # Returns
/// - `HttpResponseText`: A structured representation of the HTTP response with the body
/// converted to text.
fn text(&self) -> HttpResponseText {
let http_response: HttpResponseBinary = self.clone();
let body: String = String::from_utf8_lossy(&http_response.body).to_string();
HttpResponseText {
http_version: self.http_version,
status_code: self.status_code,
status_text: self.status_text,
headers: self.headers,
http_version: http_response.http_version,
status_code: http_response.status_code,
status_text: http_response.status_text,
headers: http_response.headers,
body,
}
}
Expand Down
64 changes: 64 additions & 0 deletions src/response/http_response_text/impl.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
use super::r#type::HttpResponseText;
use crate::response::{http_response_binary::r#type::HttpResponseBinary, r#trait::HttpResponse};

/// Implements the `HttpResponse` trait for `HttpResponseText`.
///
/// This implementation allows `HttpResponseText` to convert between text and binary
/// representations of HTTP responses. It provides methods for parsing raw responses, as well
/// as accessing text and binary formats.
///
/// # Associated Types
/// - `OutputText`: Specifies the text representation of an HTTP response (`HttpResponseText`).
/// - `OutputBinary`: Specifies the binary representation of an HTTP response (`HttpResponseBinary`).
impl HttpResponse for HttpResponseText {
type OutputText = HttpResponseText;
type OutputBinary = HttpResponseBinary;

/// Parses a raw HTTP response from a byte slice and converts it to a `HttpResponseText` instance.
///
/// This method utilizes the `from` implementation of `HttpResponseBinary` to parse the binary
/// response and then converts it to a text representation.
///
/// # Parameters
/// - `response`: A byte slice representing the raw HTTP response.
///
/// # Returns
/// - `Self::OutputText`: A `HttpResponseText` instance with the parsed response.
///
/// # Panics
/// - This method will panic if the binary parsing or text conversion fails unexpectedly.
fn from(response: &[u8]) -> Self::OutputText
where
Self: Sized,
{
<HttpResponseBinary as HttpResponse>::from(response).text()
}

/// Returns a clone of the current text representation of the HTTP response.
///
/// This method allows for retrieving the current instance as the text representation without
/// modification.
///
/// # Returns
/// - `Self::OutputText`: A clone of the current instance.
fn text(&self) -> Self::OutputText {
self.clone()
}

/// Converts the text representation to a binary representation of the HTTP response.
///
/// This method constructs a new `HttpResponseBinary` instance, copying all fields and
/// converting the body from a string to a byte vector.
///
/// # Returns
/// - `HttpResponseBinary`: The binary representation of the HTTP response.
fn binary(&self) -> HttpResponseBinary {
HttpResponseBinary {
http_version: self.http_version.clone(),
status_code: self.status_code,
status_text: self.status_text.clone(),
headers: self.headers.clone(),
body: self.body.clone().into_bytes(),
}
}
}
1 change: 1 addition & 0 deletions src/response/http_response_text/mod.rs
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
pub mod r#impl;
pub mod r#type;
1 change: 1 addition & 0 deletions src/response/mod.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
pub mod http_response_binary;
pub mod http_response_text;
pub mod r#trait;
pub mod r#type;
33 changes: 26 additions & 7 deletions src/response/trait.rs
Original file line number Diff line number Diff line change
@@ -1,26 +1,45 @@
/// A trait representing common behaviors for HTTP response types.
///
/// This trait provides a generic `text` method and a `from` method for
/// parsing and transforming HTTP responses.
/// This trait provides methods for transforming an HTTP response into
/// different formats (text and binary) and parsing raw HTTP response data.
/// Implementing types should define how to convert the response into text
/// and binary formats, as well as how to parse raw response data into a
/// structured representation.
///
/// # Associated Types
/// - `Output`: The type returned by the `from` method.
/// - `OutputText`: The type returned by the `text` method, typically a text-based HTTP response.
/// - `OutputBinary`: The type returned by the `binary` method, typically a binary-based HTTP response.
pub trait HttpResponse {
type OutputText;
type OutputBinary;

/// Transforms the HTTP response into a text representation.
///
/// This method converts the body of the HTTP response into a string format.
///
/// # Returns
/// - `Self::OutputText`: The text representation of the HTTP response, typically a string.
fn text(&self) -> Self::OutputText;

/// Transforms the HTTP response into a binary representation.
///
/// This method converts the body of the HTTP response into a byte-based format.
///
/// # Returns
/// Returns the body of the HTTP response as a string.
fn text(self) -> Self::OutputText;
/// - `Self::OutputBinary`: The binary representation of the HTTP response, typically a byte vector.
fn binary(&self) -> Self::OutputBinary;

/// Parses a raw HTTP response into the associated type `Output`.
///
/// This method is responsible for parsing a byte slice representing a raw HTTP response
/// and transforming it into a structured HTTP response object.
///
/// # Parameters
/// - `response`: A byte slice representing the raw HTTP response.
///
/// # Returns
/// Returns an instance of the implementing type.
fn from(response: &[u8]) -> Self::OutputBinary;
/// - `Self`: An instance of the implementing type, populated with parsed data.
fn from(response: &[u8]) -> Self
where
Self: Sized;
}
13 changes: 13 additions & 0 deletions src/response/type.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
use super::{
http_response_binary::r#type::HttpResponseBinary, http_response_text::r#type::HttpResponseText,
};
use crate::HttpResponse;

/// A type alias for a boxed dynamic trait object implementing the `HttpResponse` trait.
///
/// This alias defines a `Response` as a `Box` containing any type that implements the
/// `HttpResponse` trait, with associated types `OutputText` set to `HttpResponseText`
/// and `OutputBinary` set to `HttpResponseBinary`. It allows for flexible handling of
/// HTTP responses that can be either in text or binary format.
pub type BoxHttpResponse =
Box<dyn HttpResponse<OutputText = HttpResponseText, OutputBinary = HttpResponseBinary>>;

0 comments on commit 745a052

Please sign in to comment.