iris_core/protocols/stream/http/mod.rs
1//! HTTP transaction parsing.
2//!
3//! ## Remarks
4//! Iris currently only parses HTTP 1.x request and response headers, and does not attempt to
5//! parse or defragment HTTP bodies that may span multiple packets. This is enough for basic HTTP
6//! header analysis, but not for deep inspection of message body contents. Support for
7//! request/response continuations, chunked transfer encoding, and body content retrieval, are in
8//! progress.
9//!
10//! This module does support parsing pipelined requests and maintains state for linking requests and
11//! responses.
12//!
13/*
14NICE-TO-HAVE: support request/response continuations (body that spans multiple packets)
15NICE-TO-HAVE: support chunked transfer encoding
16NICE-TO-HAVE: provide request/response body
17NICE-TO-HAVE: HTTP/2 support
18*/
19
20pub mod parser;
21mod transaction;
22
23pub use self::transaction::{HttpRequest, HttpResponse};
24
25use serde::Serialize;
26
27/// Parsed HTTP transaction contents.
28#[derive(Debug, Serialize, Clone)]
29pub struct Http {
30 /// HTTP Request.
31 pub request: HttpRequest,
32 /// HTTP Response.
33 pub response: HttpResponse,
34 /// The pipelined depth into the connection of this transaction.
35 pub trans_depth: usize,
36}
37
38impl Http {
39 /// Returns the request URI, or `""` if it does not exist.
40 pub fn uri(&self) -> &str {
41 self.request.uri.as_deref().unwrap_or("")
42 }
43
44 /// Returns the HTTP method, or `""` if it does not exist.
45 pub fn method(&self) -> &str {
46 self.request.method.as_deref().unwrap_or("")
47 }
48
49 /// Returns the HTTP request version, or `""` if it does not exist.
50 pub fn request_version(&self) -> &str {
51 self.request.version.as_deref().unwrap_or("")
52 }
53
54 /// Returns the user agent string of the user agent, or `""` if it does not exist.
55 pub fn user_agent(&self) -> &str {
56 self.request.user_agent.as_deref().unwrap_or("")
57 }
58
59 /// Returns HTTP cookies sent by the client, or `""` if it does not exist.
60 pub fn cookie(&self) -> &str {
61 self.request.cookie.as_deref().unwrap_or("")
62 }
63
64 /// Returns the domain name of the server specified by the client, or `""` if it does not exist.
65 pub fn host(&self) -> &str {
66 self.request.host.as_deref().unwrap_or("")
67 }
68
69 /// Returns the size of the request body in bytes, or `0` if it does not exist.
70 pub fn request_content_length(&self) -> usize {
71 self.request.content_length.unwrap_or(0)
72 }
73
74 /// Returns the media type of the request resource, or `""` if it does not exist.
75 pub fn request_content_type(&self) -> &str {
76 self.request.content_type.as_deref().unwrap_or("")
77 }
78
79 /// Returns the form of encoding used to transfer the request body, or `""` if it does not
80 /// exist.
81 pub fn request_transfer_encoding(&self) -> &str {
82 self.request.transfer_encoding.as_deref().unwrap_or("")
83 }
84
85 /// Returns the HTTP response version, or `""` if it does not exist.
86 pub fn response_version(&self) -> &str {
87 self.response.version.as_deref().unwrap_or("")
88 }
89
90 /// Returns the HTTP status code, or `0` if it does not exist.
91 pub fn status_code(&self) -> u16 {
92 self.response.status_code.unwrap_or(0)
93 }
94
95 /// Returns the HTTP status tet, or `0` if it does not exist.
96 pub fn status_msg(&self) -> &str {
97 self.response.status_msg.as_deref().unwrap_or("")
98 }
99
100 /// Returns the size of the request body in bytes, or `0` if it does not exist.
101 pub fn response_content_length(&self) -> usize {
102 self.response.content_length.unwrap_or(0)
103 }
104
105 /// Returns the media type of the response resource, or `""` if it does not exist.
106 pub fn response_content_type(&self) -> &str {
107 self.response.content_type.as_deref().unwrap_or("")
108 }
109
110 /// Returns the form of encoding used to transfer the response body, or `""` if it does not
111 /// exist.
112 pub fn response_transfer_encoding(&self) -> &str {
113 self.response.transfer_encoding.as_deref().unwrap_or("")
114 }
115
116 // NICE-TO-HAVE: more methods...
117}