Struct rhymuweb::Request[][src]

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,
    // some fields omitted
}

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

impl Request[src]

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

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.

#[must_use]pub fn new() -> Self[src]

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

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

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

impl Debug for Request[src]

impl Default for Request[src]

Auto Trait Implementations

impl RefUnwindSafe for Request

impl Send for Request

impl Sync for Request

impl Unpin for Request

impl UnwindSafe for Request

Blanket Implementations

impl<T> Any for T where
    T: 'static + ?Sized
[src]

impl<T> Borrow<T> for T where
    T: ?Sized
[src]

impl<T> BorrowMut<T> for T where
    T: ?Sized
[src]

impl<T> From<T> for T[src]

impl<T, U> Into<U> for T where
    U: From<T>, 
[src]

impl<T, U> TryFrom<U> for T where
    U: Into<T>, 
[src]

type Error = Infallible

The type returned in the event of a conversion error.

impl<T, U> TryInto<U> for T where
    U: TryFrom<T>, 
[src]

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

The type returned in the event of a conversion error.