Skip to content

Commit e1fe8cf

Browse files
committed
Updates!
1 parent 1c53d19 commit e1fe8cf

File tree

9 files changed

+557
-70
lines changed

9 files changed

+557
-70
lines changed

README.md

Lines changed: 37 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,13 @@
11
# http_message
22

3+
Parse partial/non spec compliant HTTP messages.
4+
5+
## Partial HTTP Message
6+
7+
A partial HTTP message contains the potential spans for `method`, `uri`, `http_version`, `headers`, and `body`. The HTTP message does not need to be spec compliant so things like `http_version` are optional.
8+
39
```rust
4-
use http_message::PartialHttpRequest;
10+
use http_message::{PartialHttpRequest, error::Error, models::request::HttpRequest};
511

612
fn main() {
713
let partial = PartialHttpRequest::from_str("GET https://example.com\nx-key: 123").unwrap();
@@ -18,7 +24,36 @@ fn main() {
1824
assert_eq!(Some(&(24..34)), partial.header_span("x-key"));
1925
assert_eq!(Some("x-key: 123"), partial.header_str("x-key"));
2026

21-
let request: HttpRequest = partial.into();
27+
let request: Result<HttpRequest, Error> = partial.try_into();
28+
29+
assert_eq!(Err(Error::missing_required("http_version")), request);
30+
}
31+
```
32+
33+
## Parsed HTTP Message
34+
35+
A parsed HTTP message contains the spans for `method`, `uri`, `http_version`, `headers`, and `body`. The HTTP message does need to be spec compliant so things like `http_version` are required.
36+
37+
```rust
38+
use http_message::models::{parsed_request::ParsedHttpRequest, request::HttpRequest, uri::Uri};
39+
40+
fn main() {
41+
let parsed =
42+
ParsedHttpRequest::from_str("GET https://example.com HTTP/1.1\nx-key: 123\n\n").unwrap();
43+
44+
assert_eq!(&(0..3), parsed.method_span());
45+
assert_eq!("GET", parsed.method_str());
46+
47+
assert_eq!(&(4..23), parsed.uri_span());
48+
assert_eq!("https://example.com", parsed.uri_str());
49+
50+
assert_eq!(&(24..32), parsed.http_version_span());
51+
assert_eq!("HTTP/1.1", parsed.http_version_str());
52+
53+
assert_eq!(Some(&(33..44)), parsed.header_span("x-key"));
54+
assert_eq!(Some("x-key: 123\n"), parsed.header_str("x-key"));
55+
56+
let request: HttpRequest = parsed.into();
2257

2358
assert_eq!(
2459
HttpRequest {

examples/parsed.rs

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
use http_message::models::{parsed_request::ParsedHttpRequest, request::HttpRequest, uri::Uri};
2+
3+
fn main() {
4+
let parsed =
5+
ParsedHttpRequest::from_str("GET https://example.com HTTP/1.1\nx-key: 123\n\n").unwrap();
6+
7+
assert_eq!(&(0..3), parsed.method_span());
8+
assert_eq!("GET", parsed.method_str());
9+
10+
assert_eq!(&(4..23), parsed.uri_span());
11+
assert_eq!("https://example.com", parsed.uri_str());
12+
13+
assert_eq!(&(24..32), parsed.http_version_span());
14+
assert_eq!("HTTP/1.1", parsed.http_version_str());
15+
16+
assert_eq!(Some(&(33..44)), parsed.header_span("x-key"));
17+
assert_eq!(Some("x-key: 123\n"), parsed.header_str("x-key"));
18+
19+
let request: HttpRequest = parsed.into();
20+
21+
assert_eq!(
22+
HttpRequest {
23+
uri: Uri::new("https://example.com"),
24+
method: "GET".into(),
25+
http_version: "HTTP/1.1".into(),
26+
headers: vec![("x-key", "123").into()],
27+
body: None
28+
},
29+
request
30+
);
31+
}
Lines changed: 3 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,4 @@
1-
use http_message::{
2-
PartialHttpRequest,
3-
models::{request::HttpRequest, uri::Uri},
4-
};
1+
use http_message::{PartialHttpRequest, error::Error, models::request::HttpRequest};
52

63
fn main() {
74
let partial = PartialHttpRequest::from_str("GET https://example.com\nx-key: 123").unwrap();
@@ -18,16 +15,7 @@ fn main() {
1815
assert_eq!(Some(&(24..34)), partial.header_span("x-key"));
1916
assert_eq!(Some("x-key: 123"), partial.header_str("x-key"));
2017

21-
let request: HttpRequest = partial.into();
18+
let request: Result<HttpRequest, Error> = partial.try_into();
2219

23-
assert_eq!(
24-
HttpRequest {
25-
uri: Uri::new("https://example.com"),
26-
method: "GET".into(),
27-
http_version: "HTTP/1.1".into(),
28-
headers: vec![("x-key", "123").into()],
29-
body: None
30-
},
31-
request
32-
);
20+
assert_eq!(Err(Error::missing_required("http_version")), request);
3321
}

src/error.rs

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,17 @@
11
use snafu::prelude::*;
22

3-
#[derive(Debug, Snafu)]
3+
#[derive(Debug, Snafu, PartialEq)]
44
pub enum Error {
5-
#[snafu(display("ID may not be less than 10, but it was {id}"))]
6-
InvalidId { id: u16 },
5+
#[snafu(display("HTTP Message strings can't be empty"))]
6+
EmptyHttpMessage,
7+
#[snafu(display("Required but not found: {key}"))]
8+
MissingRequired { key: String },
9+
}
10+
11+
impl Error {
12+
pub fn missing_required(key: &str) -> Self {
13+
Self::MissingRequired {
14+
key: key.to_string(),
15+
}
16+
}
717
}

src/models/mod.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
pub mod body;
22
pub mod headers;
3+
pub mod parsed_request;
34
pub mod partial_request;
45
pub mod request;
56
pub mod response;

0 commit comments

Comments
 (0)