diff --git a/src/client.rs b/src/client.rs index 2e81c30..b479d15 100644 --- a/src/client.rs +++ b/src/client.rs @@ -230,11 +230,11 @@ where /// The response headers are stored in the provided rx_buf, which should be sized to contain at least the response headers. /// /// The response is returned. - pub async fn send<'buf, B: RequestBody>( - &'buf mut self, + pub async fn send<'req, 'buf, B: RequestBody>( + &'req mut self, request: Request<'conn, B>, rx_buf: &'buf mut [u8], - ) -> Result>, Error> { + ) -> Result>, Error> { request.write(self).await?; Response::read(self, request.method, rx_buf).await } @@ -326,10 +326,10 @@ where /// The response headers are stored in the provided rx_buf, which should be sized to contain at least the response headers. /// /// The response is returned. - pub async fn send<'buf>( - &'buf mut self, + pub async fn send<'req, 'buf>( + &'req mut self, rx_buf: &'buf mut [u8], - ) -> Result>, Error> { + ) -> Result>, Error> { let request = self.request.take().ok_or(Error::AlreadySent)?.build(); request.write(&mut self.conn).await?; Response::read(&mut self.conn, request.method, rx_buf).await @@ -454,11 +454,11 @@ where /// The response headers are stored in the provided rx_buf, which should be sized to contain at least the response headers. /// /// The response is returned. - pub async fn send<'req, B: RequestBody>( + pub async fn send<'req, 'buf, B: RequestBody>( &'req mut self, mut request: Request<'req, B>, - rx_buf: &'req mut [u8], - ) -> Result>, Error> { + rx_buf: &'buf mut [u8], + ) -> Result>, Error> { request.base_path = Some(self.base_path); request.write(&mut self.conn).await?; Response::read(&mut self.conn, request.method, rx_buf).await @@ -486,11 +486,10 @@ where /// The response headers are stored in the provided rx_buf, which should be sized to contain at least the response headers. /// /// The response is returned. - pub async fn send<'buf>(self, rx_buf: &'buf mut [u8]) -> Result>, Error> - where - 'conn: 'req + 'buf, - 'req: 'buf, - { + pub async fn send<'buf>( + self, + rx_buf: &'buf mut [u8], + ) -> Result>, Error> { let conn = self.conn; let mut request = self.request.build(); request.base_path = Some(self.base_path); diff --git a/src/reader.rs b/src/reader.rs index 62cfb83..be19719 100644 --- a/src/reader.rs +++ b/src/reader.rs @@ -42,19 +42,19 @@ impl ReadBuffer<'_> { } } -pub struct BufferingReader<'buf, B> +pub struct BufferingReader<'resp, 'buf, B> where B: Read, { buffer: ReadBuffer<'buf>, - stream: &'buf mut B, + stream: &'resp mut B, } -impl<'buf, 'conn, B> BufferingReader<'buf, B> +impl<'resp, 'buf, B> BufferingReader<'resp, 'buf, B> where B: Read, { - pub fn new(buffer: &'buf mut [u8], loaded: usize, stream: &'buf mut B) -> Self { + pub fn new(buffer: &'buf mut [u8], loaded: usize, stream: &'resp mut B) -> Self { Self { buffer: ReadBuffer::new(buffer, loaded), stream, @@ -62,14 +62,14 @@ where } } -impl ErrorType for BufferingReader<'_, C> +impl ErrorType for BufferingReader<'_, '_, C> where C: Read, { type Error = ErrorKind; } -impl Read for BufferingReader<'_, C> +impl Read for BufferingReader<'_, '_, C> where C: Read, { @@ -83,7 +83,7 @@ where } } -impl BufRead for BufferingReader<'_, HttpConnection<'_, C>> +impl BufRead for BufferingReader<'_, '_, HttpConnection<'_, C>> where C: Read + Write, { diff --git a/src/response.rs b/src/response.rs index 01e0c16..f56b3f8 100644 --- a/src/response.rs +++ b/src/response.rs @@ -10,7 +10,7 @@ use crate::Error; /// Type representing a parsed HTTP response. #[derive(Debug)] #[cfg_attr(feature = "defmt", derive(defmt::Format))] -pub struct Response<'resp, C> +pub struct Response<'resp, 'buf, C> where C: Read, { @@ -27,17 +27,17 @@ where pub transfer_encoding: heapless::Vec, /// The keep-alive parameters. pub keep_alive: Option, - header_buf: &'resp mut [u8], + header_buf: &'buf mut [u8], header_len: usize, raw_body_read: usize, } -impl<'resp, C> Response<'resp, C> +impl<'resp, 'buf, C> Response<'resp, 'buf, C> where C: Read, { // Read at least the headers from the connection. - pub async fn read(conn: &'resp mut C, method: Method, header_buf: &'resp mut [u8]) -> Result { + pub async fn read(conn: &'resp mut C, method: Method, header_buf: &'buf mut [u8]) -> Result { let mut header_len = 0; let mut pos = 0; while pos < header_buf.len() { @@ -135,7 +135,7 @@ where } /// Get the response body - pub fn body(self) -> ResponseBody<'resp, C> { + pub fn body(self) -> ResponseBody<'resp, 'buf, C> { let reader_hint = if self.method == Method::HEAD { // Head requests does not have a body so we return an empty reader ReaderHint::Empty @@ -179,7 +179,7 @@ impl<'a> Iterator for HeaderIterator<'a> { /// This type contains the original header buffer provided to `read_headers`, /// now renamed to `body_buf`, the number of read body bytes that are available /// in `body_buf`, and a reader to be used for reading the remaining body. -pub struct ResponseBody<'resp, C> +pub struct ResponseBody<'resp, 'buf, C> where C: Read, { @@ -188,7 +188,7 @@ where /// The number of raw bytes read from the body and available in the beginning of `body_buf`. raw_body_read: usize, /// The buffer initially provided to read the header. - pub body_buf: &'resp mut [u8], + pub body_buf: &'buf mut [u8], } enum ReaderHint { @@ -198,11 +198,11 @@ enum ReaderHint { ToEnd, // https://www.rfc-editor.org/rfc/rfc7230#section-3.3.3 pt. 7: Until end of connection } -impl<'resp, C> ResponseBody<'resp, C> +impl<'resp, 'buf, C> ResponseBody<'resp, 'buf, C> where C: Read, { - pub fn reader(self) -> BodyReader> { + pub fn reader(self) -> BodyReader> { let raw_body = BufferingReader::new(self.body_buf, self.raw_body_read, self.conn); match self.reader_hint { @@ -220,7 +220,7 @@ where } } -impl<'resp, C> ResponseBody<'resp, C> +impl<'resp, 'buf, C> ResponseBody<'resp, 'buf, C> where C: Read, { @@ -231,7 +231,7 @@ where /// while parsing the http response header would be available for the body reader. /// For this case, or if the original buffer is not large enough, use /// [`BodyReader::read_to_end()`] instead from the reader returned by [`ResponseBody::reader()`]. - pub async fn read_to_end(self) -> Result<&'resp mut [u8], Error> { + pub async fn read_to_end(self) -> Result<&'buf mut [u8], Error> { // We can only read responses with Content-Length header to end using the body_buf buffer, // as any other response would require the body reader to know the entire body. match self.reader_hint { diff --git a/tests/client.rs b/tests/client.rs index 77cf375..7447118 100644 --- a/tests/client.rs +++ b/tests/client.rs @@ -395,3 +395,15 @@ async fn echo(req: hyper::Request) -> Result, hyper: _ => Ok(hyper::Response::new(req.into_body())), } } + +#[test] +fn compile_tests() { + #[allow(dead_code)] + async fn rx_buffer_lifetime_is_propagated_to_output<'buf>(port: u16, rx_buf: &'buf mut [u8]) -> &'buf mut [u8] { + let mut http = HttpClient::new(&TCP, &LOOPBACK_DNS); + let url = format!("http://127.0.0.1:{}", port); + let mut request = http.request(Method::GET, &url).await.unwrap(); + let response = request.send(rx_buf).await.unwrap(); + response.body().read_to_end().await.unwrap() + } +}