1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
use crate::http::header::HTTPRequestHeaders;
use crate::http::request::HTTPRequest;
use std::io::Read;
/// A dinamically sized buffer used within `rsweb` to read requests
pub struct DBuffer {
buffer: Vec<u8>,
}
impl DBuffer {
/// create a new DBuffer
pub fn new() -> DBuffer {
DBuffer { buffer: Vec::new() }
}
/// create a new DBuffer with `cap` as its capacity
pub fn with_capacity(cap: usize) -> DBuffer {
DBuffer {
buffer: Vec::with_capacity(cap),
}
}
/// read from `r` until it hits a null byte (`\0`)
///
/// # Returns
/// This function returns a result that if Ok holds the amount of bytes read
pub fn read_until_zero<T: Read>(&mut self, r: &mut T) -> std::io::Result<usize> {
let mut tmp_buf = [0u8];
let mut counter: usize = 0;
loop {
match r.read(&mut tmp_buf) {
Ok(n) => {
if n != 1 {
break;
}
if tmp_buf[0] == 0 {
break;
}
self.buffer.push(tmp_buf[0]);
counter += 1;
}
Err(e) => {
return Err(e);
}
}
}
Ok(counter)
}
/// read a HTTP request from `r`
///
/// # Returns
/// This function returns a result that if Ok holds the amount of bytes read
pub fn read_http_request<T: Read>(&mut self, r: &mut T) -> std::io::Result<usize> {
let mut tmp_buf = [0u8];
let mut header_size: usize = 0;
let mut crlf_counter: u8 = 0;
let mut cr: bool = false;
loop {
match r.read(&mut tmp_buf) {
Ok(n) => {
if n != 1 {
break;
}
if tmp_buf[0] == 0xD {
cr = true;
} else if cr && tmp_buf[0] == 0xA {
crlf_counter += 1;
} else {
crlf_counter = 0;
cr = false;
}
self.buffer.push(tmp_buf[0]);
header_size += 1;
if crlf_counter == 2 {
break;
}
}
Err(e) => {
return Err(e);
}
}
}
let string = match self.to_string() {
Ok(n) => n,
Err(_) => {
return Err(std::io::Error::new(
std::io::ErrorKind::Other,
"failed to convert bytes to string",
));
}
};
let request = match HTTPRequest::from_string(string) {
Ok(n) => n,
Err(_) => {
return Err(std::io::Error::new(
std::io::ErrorKind::Other,
"failed to parse header of HTTP request",
));
}
};
let header: Vec<HTTPRequestHeaders> = request.get_header().to_vec();
let mut length: usize = 0;
for head in header {
if let HTTPRequestHeaders::ContentLength(n) = head {
length = n;
break;
}
}
if length == 0 {
return Ok(header_size);
} else {
let mut bytes_read: usize = 0;
let mut buf = [0u8];
while bytes_read < length {
match r.read(&mut buf) {
Ok(n) => {
if n != 1 {
break;
}
self.buffer.push(buf[0]);
bytes_read += 1;
}
Err(_) => {
break;
}
}
}
return Ok(header_size + bytes_read);
}
}
/// try to convert the internal buffer to a string
pub fn to_string(&self) -> Result<String, std::string::FromUtf8Error> {
String::from_utf8(self.buffer.clone())
}
}