1
1
//! HTTP body types
2
2
3
+ use crate :: http:: fields:: header_map_from_wasi;
3
4
use crate :: io:: { AsyncInputStream , AsyncOutputStream , AsyncRead , AsyncWrite , Cursor , Empty } ;
5
+ use crate :: runtime:: AsyncPollable ;
4
6
use core:: fmt;
5
7
use http:: header:: { CONTENT_LENGTH , TRANSFER_ENCODING } ;
6
8
use wasi:: http:: types:: IncomingBody as WasiIncomingBody ;
@@ -116,9 +118,9 @@ impl Body for Empty {
116
118
pub struct IncomingBody {
117
119
kind : BodyKind ,
118
120
// IMPORTANT: the order of these fields here matters. `body_stream` must
119
- // be dropped before `_incoming_body `.
121
+ // be dropped before `incoming_body `.
120
122
body_stream : AsyncInputStream ,
121
- _incoming_body : WasiIncomingBody ,
123
+ incoming_body : WasiIncomingBody ,
122
124
}
123
125
124
126
impl IncomingBody {
@@ -130,9 +132,29 @@ impl IncomingBody {
130
132
Self {
131
133
kind,
132
134
body_stream,
133
- _incoming_body : incoming_body,
135
+ incoming_body,
134
136
}
135
137
}
138
+
139
+ /// Consume this `IncomingBody` and return the trailers, if present.
140
+ pub async fn finish ( self ) -> Result < Option < HeaderMap > , Error > {
141
+ // The stream is a child resource of the `IncomingBody`, so ensure that
142
+ // it's dropped first.
143
+ drop ( self . body_stream ) ;
144
+
145
+ let trailers = WasiIncomingBody :: finish ( self . incoming_body ) ;
146
+
147
+ AsyncPollable :: new ( trailers. subscribe ( ) ) . wait_for ( ) . await ;
148
+
149
+ let trailers = trailers. get ( ) . unwrap ( ) . unwrap ( ) ?;
150
+
151
+ let trailers = match trailers {
152
+ None => None ,
153
+ Some ( trailers) => Some ( header_map_from_wasi ( trailers) ?) ,
154
+ } ;
155
+
156
+ Ok ( trailers)
157
+ }
136
158
}
137
159
138
160
impl AsyncRead for IncomingBody {
0 commit comments