@@ -66,6 +66,7 @@ pub(super) enum Event {
6666 Headers ( peer:: PollMessage ) ,
6767 Data ( Bytes ) ,
6868 Trailers ( HeaderMap ) ,
69+ InformationalHeaders ( peer:: PollMessage ) ,
6970}
7071
7172#[ derive( Debug ) ]
@@ -264,6 +265,21 @@ impl Recv {
264265 // corresponding headers frame pushed to `stream.pending_recv`.
265266 self . pending_accept . push ( stream) ;
266267 }
268+ } else {
269+ // This is an informational response (1xx status code)
270+ // Convert to response and store it for polling
271+ let message = counts
272+ . peer ( )
273+ . convert_poll_message ( pseudo, fields, stream_id) ?;
274+
275+ tracing:: trace!( "Received informational response: stream_id={:?}" , stream_id) ;
276+
277+ // Push the informational response onto the stream's recv buffer
278+ // with a special event type so it can be polled separately
279+ stream
280+ . pending_recv
281+ . push_back ( & mut self . buffer , Event :: InformationalHeaders ( message) ) ;
282+ stream. notify_recv ( ) ;
267283 }
268284
269285 Ok ( ( ) )
@@ -324,24 +340,63 @@ impl Recv {
324340 ) -> Poll < Result < Response < ( ) > , proto:: Error > > {
325341 use super :: peer:: PollMessage :: * ;
326342
327- // If the buffer is not empty, then the first frame must be a HEADERS
328- // frame or the user violated the contract.
329- match stream. pending_recv . pop_front ( & mut self . buffer ) {
330- Some ( Event :: Headers ( Client ( response) ) ) => Poll :: Ready ( Ok ( response) ) ,
331- Some ( _) => panic ! ( "poll_response called after response returned" ) ,
332- None => {
333- if !stream. state . ensure_recv_open ( ) ? {
334- proto_err ! ( stream: "poll_response: stream={:?} is not opened;" , stream. id) ;
335- return Poll :: Ready ( Err ( Error :: library_reset (
336- stream. id ,
337- Reason :: PROTOCOL_ERROR ,
338- ) ) ) ;
343+ // Skip over any interim informational headers to find the main response
344+ loop {
345+ match stream. pending_recv . pop_front ( & mut self . buffer ) {
346+ Some ( Event :: Headers ( Client ( response) ) ) => return Poll :: Ready ( Ok ( response) ) ,
347+ Some ( Event :: InformationalHeaders ( _) ) => {
348+ tracing:: trace!( "Skipping informational response in poll_response - should be consumed via poll_informational; stream_id={:?}" , stream. id) ;
349+ continue ;
339350 }
351+ Some ( _) => panic ! ( "poll_response called after response returned" ) ,
352+ None => {
353+ if !stream. state . ensure_recv_open ( ) ? {
354+ proto_err ! ( stream: "poll_response: stream={:?} is not opened;" , stream. id) ;
355+ return Poll :: Ready ( Err ( Error :: library_reset (
356+ stream. id ,
357+ Reason :: PROTOCOL_ERROR ,
358+ ) ) ) ;
359+ }
340360
341- stream. recv_task = Some ( cx. waker ( ) . clone ( ) ) ;
342- Poll :: Pending
361+ stream. recv_task = Some ( cx. waker ( ) . clone ( ) ) ;
362+ return Poll :: Pending ;
363+ }
364+ }
365+ }
366+ }
367+
368+ /// Called by the client to get informational responses (1xx status codes)
369+ pub fn poll_informational (
370+ & mut self ,
371+ cx : & Context ,
372+ stream : & mut store:: Ptr ,
373+ ) -> Poll < Option < Result < Response < ( ) > , proto:: Error > > > {
374+ use super :: peer:: PollMessage :: * ;
375+
376+ // Try to pop the front event and check if it's an informational response
377+ // If it's not, we put it back
378+ if let Some ( event) = stream. pending_recv . pop_front ( & mut self . buffer ) {
379+ match event {
380+ Event :: InformationalHeaders ( Client ( response) ) => {
381+ // Found an informational response, return it
382+ return Poll :: Ready ( Some ( Ok ( response) ) ) ;
383+ }
384+ other => {
385+ // Not an informational response, put it back at the front
386+ stream. pending_recv . push_front ( & mut self . buffer , other) ;
387+ }
343388 }
344389 }
390+
391+ // No informational response available at the front
392+ if stream. state . ensure_recv_open ( ) ? {
393+ // Request to get notified once more frames arrive
394+ stream. recv_task = Some ( cx. waker ( ) . clone ( ) ) ;
395+ Poll :: Pending
396+ } else {
397+ // No more frames will be received
398+ Poll :: Ready ( None )
399+ }
345400 }
346401
347402 /// Transition the stream based on receiving trailers
0 commit comments