Skip to content

Commit 53bec8e

Browse files
committed
Verify spans generated for partial requests
1 parent 9079c3e commit 53bec8e

1 file changed

Lines changed: 126 additions & 1 deletion

File tree

src/models/partial_request.rs

Lines changed: 126 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,14 +34,61 @@ impl PartialHttpRequest {
3434
headers: Vec<Range<usize>>,
3535
body: Option<Range<usize>>,
3636
) -> Self {
37-
Self {
37+
let partial = Self {
3838
message: message.to_string(),
3939
method,
4040
uri,
4141
http_version,
4242
headers,
4343
body,
44+
};
45+
46+
partial.verify_spans();
47+
48+
partial
49+
}
50+
51+
/// Verify all the spans in the struct are valid
52+
///
53+
/// - Aren't out of bounds of the message
54+
/// - Parts aren't overlapping or out of order
55+
fn verify_spans(&self) {
56+
self.method.as_ref().inspect(|span| {
57+
assert!(span.start < span.end);
58+
assert_text_span(self.message(), span);
59+
});
60+
61+
self.uri.as_ref().inspect(|span| {
62+
assert!(span.start < span.end);
63+
assert_text_span(self.message(), span);
64+
65+
if let Some(method) = self.method_span() {
66+
if !(method.start < span.start && method.end < span.start) {
67+
panic!("uri {span:?} and method {method:?} spans conflict");
68+
}
69+
}
70+
});
71+
72+
self.http_version.as_ref().inspect(|span| {
73+
assert!(span.start < span.end);
74+
assert_text_span(self.message(), span);
75+
76+
if let Some(uri) = self.uri_span() {
77+
if !(uri.start < span.start && uri.end < span.start) {
78+
panic!("http version {span:?} and uri {uri:?} spans conflict");
79+
}
80+
}
81+
});
82+
83+
for span in self.header_spans().iter() {
84+
assert!(span.start < span.end);
85+
assert_text_span(self.message(), span);
4486
}
87+
88+
self.body.as_ref().inspect(|span| {
89+
assert!(span.start < span.end);
90+
assert_text_span(self.message(), span);
91+
});
4592
}
4693

4794
/// Get the original HTTP request message text
@@ -117,6 +164,11 @@ impl PartialHttpRequest {
117164
}
118165
}
119166

167+
fn assert_text_span(text: &str, span: &Range<usize>) {
168+
text.get(span.clone())
169+
.expect(&format!("span {:?} is outside of text bounds", span));
170+
}
171+
120172
impl Default for PartialHttpRequest {
121173
fn default() -> Self {
122174
Self::from_str("GET https://example.com HTTP/1.1").unwrap()
@@ -245,6 +297,79 @@ mod tests {
245297
models::{request::HttpRequest, uri::Uri},
246298
};
247299

300+
#[test]
301+
#[should_panic]
302+
fn verifies_out_of_bounds_method_span() {
303+
PartialHttpRequest::new("", Some(1..2), None, None, vec![], None);
304+
}
305+
306+
#[test]
307+
#[should_panic]
308+
fn verifies_inverted_method_span() {
309+
PartialHttpRequest::new("", Some(2..1), None, None, vec![], None);
310+
}
311+
312+
#[test]
313+
#[should_panic]
314+
fn verifies_out_of_bounds_uri_span() {
315+
PartialHttpRequest::new("", None, Some(1..2), None, vec![], None);
316+
}
317+
318+
#[test]
319+
#[should_panic]
320+
fn verifies_inverted_uri_span() {
321+
PartialHttpRequest::new("", None, Some(2..1), None, vec![], None);
322+
}
323+
324+
#[test]
325+
#[should_panic]
326+
fn verifies_method_span_overlaps_uri_span() {
327+
PartialHttpRequest::new(
328+
"GET https://example.com",
329+
Some(0..3),
330+
Some(2..10),
331+
None,
332+
vec![],
333+
None,
334+
);
335+
}
336+
337+
#[test]
338+
#[should_panic]
339+
fn verifies_out_of_bounds_http_version_span() {
340+
PartialHttpRequest::new("", None, None, Some(1..2), vec![], None);
341+
}
342+
343+
#[test]
344+
#[should_panic]
345+
fn verifies_inverted_http_version_span() {
346+
PartialHttpRequest::new("", None, None, Some(2..1), vec![], None);
347+
}
348+
349+
#[test]
350+
#[should_panic]
351+
fn verifies_out_of_bounds_header_span() {
352+
PartialHttpRequest::new("", None, None, None, vec![1..2], None);
353+
}
354+
355+
#[test]
356+
#[should_panic]
357+
fn verifies_inverted_header_span() {
358+
PartialHttpRequest::new("", None, None, None, vec![2..1], None);
359+
}
360+
361+
#[test]
362+
#[should_panic]
363+
fn verifies_out_of_bounds_body_span() {
364+
PartialHttpRequest::new("", None, None, None, vec![], Some(1..2));
365+
}
366+
367+
#[test]
368+
#[should_panic]
369+
fn verifies_inverted_body_span() {
370+
PartialHttpRequest::new("", None, None, None, vec![], Some(2..1));
371+
}
372+
248373
#[test]
249374
fn implements_default() {
250375
let partial = PartialHttpRequest::default();

0 commit comments

Comments
 (0)