Struct Request

Source
pub struct Request {
    pub body: Vec<u8>,
    pub headers: MessageHeaders,
    pub max_message_size: Option<usize>,
    pub method: Cow<'static, str>,
    pub request_line_limit: Option<usize>,
    pub target: Uri,
    /* private fields */
}
Expand description

This type is used to parse and generate HTTP 1.1 requests.

Fields§

§body: Vec<u8>

This holds the bytes which compose the body of the request.

§headers: MessageHeaders

This holds any headers for the request.

§max_message_size: Option<usize>

If not None, this sets a maximum size, in bytes, for the request as a whole. The parse function will return a Error::MessageTooLong error if the input exceeds this size.

§method: Cow<'static, str>

This is the method token in the request, which indicates the request method to be performed on the target resource, as defined in IETF RFC 7231 section 4.

§request_line_limit: Option<usize>

If not None, this sets a maximum size, in bytes, for the request line part of the request, which is defined in IETF RFC 7230 section 3.1.1. The parse function will return a Error::RequestLineTooLong(enum.Error.html#variant. RequestLineTooLong) error if the input going into the request line exceeds this size.

§target: Uri

This is the target Uniform Resource Identifier (URI) in the request. This is contained in the request line and identifies the resource upon which to apply the request, as defined in IETF RFC 7230 section 5.3.

Implementations§

Source§

impl Request

Source

pub fn generate(&self) -> Result<Vec<u8>, Error>

Produce the raw bytes form of the request, according to the rules of IETF RFC 7320 section 3:

  • The request line appears first, containing the request method, target URI, and protocol identifier.
  • The request header lines follow the request line.
  • An empty text line follows the header lines.
  • The body, if any, appears last. Its length is determined either by the “Content-Length” header, if present, or by the transfer coding technique(s) listed in the “Transfer-Encoding” header.
§Examples
use rhymuri::Uri;
use rhymuweb::Request;

let mut request = Request::new();
request.method = "GET".into();
request.target = Uri::parse("/foo").unwrap();
request.headers.set_header("Host", "www.example.com");
request.headers.set_header("Content-Type", "text/plain");
assert!(matches!(
    request.generate(),
    Ok(raw_request) if raw_request == concat!(
        "GET /foo HTTP/1.1\r\n",
        "Host: www.example.com\r\n",
        "Content-Type: text/plain\r\n",
        "\r\n",
    ).as_bytes()
));
§Errors
  • Error::Headers – the headers generator is configured with a line limit constraint and one or more headers are too long and cannot be folded to fit within the constraint.
  • Error::StringFormat – while technically it shouldn’t happen, logically this may be returned if one of the internal string formatting functions should fail (which they shouldn’t unless something used internally doesn’t implement Display properly.
Source

pub fn new() -> Self

Create a new request value with default method (GET), empty target URI, no headers or body, and default limit constraints.

Source

pub fn parse<T>(&mut self, raw_message: T) -> Result<ParseResults, Error>
where T: AsRef<[u8]>,

Feed more bytes into the parser, building the request internally, and detecting when the end of the request has been found.

This function may be called multiple times to parse input incrementally. Each call returns an indication of whether or not a message was parsed and how many input bytes were consumed.

§Examples
use rhymuri::Uri;
use rhymuweb::{Request, RequestParseResults, RequestParseStatus};

let raw_request_body = "say=Hi&to=Mom";
let raw_request_extra = "This is extra junk not part of the request!";
let raw_request_headers = format!(
    concat!(
        "POST / HTTP/1.1\r\n",
        "Host: foo.com\r\n",
        "Content-Type: application/x-www-form-urlencoded\r\n",
        "Content-Length: {}\r\n",
        "\r\n",
    ),
    raw_request_body.len()
);
let mut request = Request::new();
assert!(matches!(
    request.parse(
        raw_request_headers.clone()
        + raw_request_body
        + raw_request_extra
    ),
    Ok(RequestParseResults{
        status: RequestParseStatus::Complete,
        consumed
    }) if consumed == raw_request_headers.len() + raw_request_body.len()
));
assert_eq!("POST", request.method);
assert_eq!("/", request.target.to_string());
assert!(request.headers.has_header("Content-Type"));
assert_eq!(
    Some("application/x-www-form-urlencoded"),
    request.headers.header_value("Content-Type").as_deref()
);
assert!(request.headers.has_header("Host"));
assert_eq!(
    Some("foo.com"),
    request.headers.header_value("Host").as_deref()
);
assert!(request.headers.has_header("Content-Length"));
assert_eq!(
    Some(format!("{}", raw_request_body.len())),
    request.headers.header_value("Content-Length")
);
assert_eq!(
    raw_request_body.as_bytes(),
    request.body
);
§Errors

Trait Implementations§

Source§

impl Debug for Request

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl Default for Request

Source§

fn default() -> Self

Returns the “default value” for a type. Read more

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.