-
Notifications
You must be signed in to change notification settings - Fork 37
Streamed read for binary HTTP #74
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
|
@martinthomson Hi Martin, I've been looking at this PR and have a few questions that I hope you don't mind me asking.
diff --git a/bhttp/src/lib.rs b/bhttp/src/lib.rs
index 2082b0f..9063e7e 100644
--- a/bhttp/src/lib.rs
+++ b/bhttp/src/lib.rs
@@ -188,7 +188,10 @@ impl FieldSection {
}
/// Gets all of the values of the named field.
- pub fn get_all<'a, 'b>(&'a self, n: &'b [u8]) -> impl Iterator<Item = &'a [u8]> + use<'a, 'b> {
+ pub fn get_all<'a, 'b>(&'a self, n: &'b [u8]) -> impl Iterator<Item = &'a [u8]> + 'b
+ where
+ 'a: 'b,
+ {
self.0.iter().filter_map(move |f| {
if &f.name[..] == n {
Some(&f.value[..])Thanks again for your work on this — it's really helpful! |
|
|
I've taken your suggested change, though I can't see a way to avoid the 1.82 change, even though it is in a dependency that you might not need. There doesn't seem to be a way to make the MSRV conditional on the feature set chosen. And until we get rust 2024 edition (1.85) we are stuck with a dependency resolver that consistently finds dependencies that can't be compiled. |
|
@martinthomson Thank you for your detailed explanation and the work you've done on this project. Regarding the first point about writing BHTTP messages: I'm working on a scenario where I need to receive HTTP messages (e.g. a server-sent event http response), convert them to BHTTP format on-the-fly, and stream them out. This led me to think about implementing an async conversion between bhttp encoded request/response binary stream and I'm happy to draft a PR for this if you think it aligns with the crate's goals. Looking forward to your thoughts! |
|
@martinthomson Hi, I have created an early implementation of http-compat #82. Looking forward to your valuable feedback. |
|
Oh, this is great. I'll take a look tomorrow. |
|
Found a panic when decapsulating a long request: #[test]
fn long_request() {
init();
// A long request.
const LONG_REQUEST: &[u8] = &[0u8; 1024];
let server_config = make_config();
let server = Server::new(server_config).unwrap();
let encoded_config = server.config().encode().unwrap();
trace!("Config: {}", hex::encode(&encoded_config));
// The client sends a request.
let client = ClientRequest::from_encoded_config(&encoded_config).unwrap();
let (mut request_read, request_write) = Pipe::new();
let mut client_request = client.encapsulate_stream(request_write).unwrap();
client_request
.write_all(LONG_REQUEST)
.sync_resolve()
.unwrap();
client_request.close().sync_resolve().unwrap();
trace!("Request: {}", hex::encode(LONG_REQUEST));
let enc_request = request_read.sync_read_to_end();
trace!("Encapsulated Request: {}", hex::encode(&enc_request));
// The server receives a request.
let mut server_request = server.decapsulate_stream(&enc_request[..]); // <---- panic here
assert_eq!(server_request.sync_read_to_end(), LONG_REQUEST);
}panic message The out of range access happens here: Line 490 in 8628e6c
|
|
Well, that embarrassing. That's a pretty big omission on my part. Thanks for finding it, and for the easy test case. The fix is non-trivial, but I'm on it. |
|
Hey @martinthomson, no worries at all. I'm glad we found the issue! |
The original code assumed that the output would always be large enough for an entire chunk. Thankfully, it didn't take much of a buffer for that assumption to be proven false.
|
I've put a fix in place. It should be a little more complete than yours (you lost the value of |
This is far from ready.
It also requires an MSRV update to 1.82, which is brand new, so I don't want to say that this is ready to land.
Missing:
Bodyimplementation), but this is still likely to be non-trivial.