Skip to content

Commit 9517a30

Browse files
Sebastien Boeufgeorgepisaltu
authored andcommitted
Retrieve the optional file associated with a Request
The sever is now able to get any optional file descriptor that might have been sent over with the bytes related to a request. This patch leverages this ability by extending the Request structure with an optional File, which might have been received from the byte stream. With the Request containing an optional File, we give the consumers of this crate the possibility to receive a file descriptor associated with the HTTP request. Signed-off-by: Sebastien Boeuf <[email protected]>
1 parent 3c4cc3a commit 9517a30

File tree

3 files changed

+34
-4
lines changed

3 files changed

+34
-4
lines changed

coverage_config.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
{"coverage_score": 93.1, "exclude_path": "", "crate_features": ""}
1+
{"coverage_score": 92.8, "exclude_path": "", "crate_features": ""}

src/connection.rs

Lines changed: 27 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
// SPDX-License-Identifier: Apache-2.0
33

44
use std::collections::VecDeque;
5+
use std::fs::File;
56
use std::io::{Read, Write};
67

78
use crate::common::ascii::{CR, CRLF_LEN, LF};
@@ -50,6 +51,9 @@ pub struct HttpConnection<T> {
5051
/// A buffer containing the bytes of a response that is currently
5152
/// being sent.
5253
response_buffer: Option<Vec<u8>>,
54+
/// The latest file that has been received and which must be associated
55+
/// with the pending request.
56+
file: Option<File>,
5357
}
5458

5559
impl<T: Read + Write + ScmSocket> HttpConnection<T> {
@@ -66,6 +70,7 @@ impl<T: Read + Write + ScmSocket> HttpConnection<T> {
6670
parsed_requests: VecDeque::new(),
6771
response_queue: VecDeque::new(),
6872
response_buffer: None,
73+
file: None,
6974
}
7075
}
7176

@@ -107,8 +112,9 @@ impl<T: Read + Write + ScmSocket> HttpConnection<T> {
107112
// the `parsed_requests` queue.
108113
self.state = ConnectionState::WaitingForRequestLine;
109114
self.body_bytes_to_be_read = 0;
110-
self.parsed_requests
111-
.push_back(self.pending_request.take().unwrap());
115+
let mut pending_request = self.pending_request.take().unwrap();
116+
pending_request.file = self.file.take();
117+
self.parsed_requests.push_back(pending_request);
112118
}
113119
};
114120
}
@@ -127,11 +133,16 @@ impl<T: Read + Write + ScmSocket> HttpConnection<T> {
127133
}
128134
// Append new bytes to what we already have in the buffer.
129135
// The slice access is safe, the index is checked above.
130-
let (bytes_read, _) = self
136+
let (bytes_read, file) = self
131137
.stream
132138
.recv_with_fd(&mut self.buffer[self.read_cursor..])
133139
.map_err(ConnectionError::StreamReadError)?;
134140

141+
// Update the internal file that must be associated with the request.
142+
if file.is_some() {
143+
self.file = file;
144+
}
145+
135146
// If the read returned 0 then the client has closed the connection.
136147
if bytes_read == 0 {
137148
return Err(ConnectionError::ConnectionClosed);
@@ -176,6 +187,7 @@ impl<T: Read + Write + ScmSocket> HttpConnection<T> {
176187
.map_err(ConnectionError::ParseError)?,
177188
headers: Headers::default(),
178189
body: None,
190+
file: None,
179191
});
180192
self.state = ConnectionState::WaitingForHeaders;
181193
Ok(true)
@@ -517,6 +529,7 @@ mod tests {
517529
request_line: RequestLine::new(Method::Patch, "http://localhost/home", Version::Http11),
518530
headers: Headers::new(26, true, true),
519531
body: Some(Body::new(b"this is not\n\r\na json \nbody".to_vec())),
532+
file: None,
520533
};
521534

522535
assert_eq!(request, expected_request);
@@ -553,6 +566,7 @@ mod tests {
553566
request_line: RequestLine::new(Method::Patch, "http://localhost/home", Version::Http11),
554567
headers: Headers::new(26, true, true),
555568
body: Some(Body::new(b"this is not\n\r\na json \nbody".to_vec())),
569+
file: None,
556570
};
557571
assert_eq!(request, expected_request);
558572
}
@@ -586,6 +600,7 @@ mod tests {
586600
request_line: RequestLine::new(Method::Patch, "http://localhost/home", Version::Http11),
587601
headers: Headers::new(26, true, true),
588602
body: Some(Body::new(b"this is not\n\r\na json \nbody".to_vec())),
603+
file: None,
589604
};
590605
assert_eq!(request, expected_request);
591606
}
@@ -650,6 +665,7 @@ mod tests {
650665
request_line: RequestLine::new(Method::Patch, "http://localhost/home", Version::Http11),
651666
headers: Headers::new(1400, true, true),
652667
body: Some(Body::new(request_body)),
668+
file: None,
653669
};
654670

655671
assert_eq!(request, expected_request);
@@ -720,6 +736,7 @@ mod tests {
720736
request_line: RequestLine::new(Method::Patch, "http://localhost/home", Version::Http11),
721737
headers: Headers::new(0, true, true),
722738
body: None,
739+
file: None,
723740
};
724741
assert_eq!(request, expected_request);
725742
}
@@ -741,6 +758,7 @@ mod tests {
741758
request_line: RequestLine::new(Method::Patch, "http://localhost/home", Version::Http11),
742759
headers: Headers::new(0, false, false),
743760
body: None,
761+
file: None,
744762
};
745763
assert_eq!(request, expected_request);
746764
}
@@ -769,6 +787,7 @@ mod tests {
769787
request_line: RequestLine::new(Method::Patch, "http://localhost/home", Version::Http11),
770788
headers: Headers::new(0, false, false),
771789
body: None,
790+
file: None,
772791
};
773792
assert_eq!(request, expected_request);
774793

@@ -787,6 +806,7 @@ mod tests {
787806
),
788807
headers: Headers::new(0, false, false),
789808
body: None,
809+
file: None,
790810
};
791811
assert_eq!(request, expected_request);
792812
}
@@ -814,6 +834,7 @@ mod tests {
814834
request_line: RequestLine::new(Method::Patch, "http://localhost/home", Version::Http11),
815835
headers: Headers::new(26, false, true),
816836
body: Some(Body::new(b"this is not\n\r\na json \nbody".to_vec())),
837+
file: None,
817838
};
818839

819840
conn.try_read().unwrap();
@@ -824,6 +845,7 @@ mod tests {
824845
request_line: RequestLine::new(Method::Put, "http://farhost/away", Version::Http11),
825846
headers: Headers::new(23, false, false),
826847
body: Some(Body::new(b"this is another request".to_vec())),
848+
file: None,
827849
};
828850
assert_eq!(request_first, expected_request_first);
829851
assert_eq!(request_second, expected_request_second);
@@ -1036,6 +1058,7 @@ mod tests {
10361058
request_line: RequestLine::new(Method::Get, "http://foo/bar", Version::Http11),
10371059
headers: Headers::new(0, true, true),
10381060
body: None,
1061+
file: None,
10391062
});
10401063
assert_eq!(
10411064
conn.parse_headers(&mut 0, BUFFER_SIZE).unwrap_err(),
@@ -1093,6 +1116,7 @@ mod tests {
10931116
request_line: RequestLine::new(Method::Get, "http://foo/bar", Version::Http11),
10941117
headers: Headers::new(0, true, true),
10951118
body: None,
1119+
file: None,
10961120
});
10971121
conn.body_vec = vec![0xde, 0xad, 0xbe, 0xef];
10981122
assert_eq!(

src/request.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
// Copyright 2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
22
// SPDX-License-Identifier: Apache-2.0
33

4+
use std::fs::File;
45
use std::str::from_utf8;
56

67
use crate::common::ascii::{CR, CRLF_LEN, LF, SP};
@@ -158,6 +159,8 @@ pub struct Request {
158159
pub headers: Headers,
159160
/// The body of the request.
160161
pub body: Option<Body>,
162+
/// The optional file associated with the request.
163+
pub file: Option<File>,
161164
}
162165

163166
impl Request {
@@ -217,6 +220,7 @@ impl Request {
217220
request_line,
218221
headers: Headers::default(),
219222
body: None,
223+
file: None,
220224
}),
221225
Some(headers_end) => {
222226
// Parse the request headers.
@@ -276,6 +280,7 @@ impl Request {
276280
request_line,
277281
headers,
278282
body,
283+
file: None,
279284
})
280285
}
281286
// If we can't find a CR LF CR LF even though the request should have headers
@@ -444,6 +449,7 @@ mod tests {
444449
uri: Uri::new("http://localhost/home"),
445450
},
446451
body: None,
452+
file: None,
447453
headers: Headers::default(),
448454
};
449455
let request_bytes = b"GET http://localhost/home HTTP/1.0\r\n\

0 commit comments

Comments
 (0)