@@ -6,7 +6,7 @@ use async_std::io;
6
6
use async_std:: io:: prelude:: * ;
7
7
use async_std:: task:: { Context , Poll } ;
8
8
use http_types:: headers:: { CONTENT_LENGTH , DATE , TRANSFER_ENCODING } ;
9
- use http_types:: Response ;
9
+ use http_types:: { Method , Response } ;
10
10
11
11
use crate :: chunked:: ChunkedEncoder ;
12
12
use crate :: date:: fmt_http_date;
@@ -36,6 +36,8 @@ pub(crate) struct Encoder {
36
36
body_bytes_written : usize ,
37
37
/// An encoder for chunked encoding.
38
38
chunked : ChunkedEncoder ,
39
+ /// the http method that this response is in reply to
40
+ method : Method ,
39
41
}
40
42
41
43
#[ derive( Debug ) ]
@@ -69,7 +71,7 @@ impl Read for Encoder {
69
71
70
72
impl Encoder {
71
73
/// Create a new instance of Encoder.
72
- pub ( crate ) fn new ( res : Response ) -> Self {
74
+ pub ( crate ) fn new ( res : Response , method : Method ) -> Self {
73
75
Self {
74
76
res,
75
77
depth : 0 ,
@@ -80,6 +82,7 @@ impl Encoder {
80
82
body_len : 0 ,
81
83
body_bytes_written : 0 ,
82
84
chunked : ChunkedEncoder :: new ( ) ,
85
+ method,
83
86
}
84
87
}
85
88
@@ -97,7 +100,7 @@ impl Encoder {
97
100
match self . state {
98
101
Start => assert ! ( matches!( state, ComputeHead ) ) ,
99
102
ComputeHead => assert ! ( matches!( state, EncodeHead ) ) ,
100
- EncodeHead => assert ! ( matches!( state, EncodeChunkedBody | EncodeFixedBody ) ) ,
103
+ EncodeHead => assert ! ( matches!( state, EncodeChunkedBody | EncodeFixedBody | End ) ) ,
101
104
EncodeFixedBody => assert ! ( matches!( state, End ) ) ,
102
105
EncodeChunkedBody => assert ! ( matches!( state, End ) ) ,
103
106
End => panic ! ( "No state transitions allowed after the ServerEncoder has ended" ) ,
@@ -176,14 +179,20 @@ impl Encoder {
176
179
// If we've read the total length of the head we're done
177
180
// reading the head and can transition to reading the body
178
181
if self . head_bytes_written == head_len {
179
- // The response length lets us know if we are encoding
180
- // our body in chunks or not
181
- match self . res . len ( ) {
182
- Some ( body_len) => {
183
- self . body_len = body_len;
184
- self . dispatch ( State :: EncodeFixedBody , cx, buf)
182
+ if self . method == Method :: Head {
183
+ // If we are responding to a HEAD request, we MUST NOT send
184
+ // body content
185
+ self . dispatch ( State :: End , cx, buf)
186
+ } else {
187
+ // The response length lets us know if we are encoding
188
+ // our body in chunks or not
189
+ match self . res . len ( ) {
190
+ Some ( body_len) => {
191
+ self . body_len = body_len;
192
+ self . dispatch ( State :: EncodeFixedBody , cx, buf)
193
+ }
194
+ None => self . dispatch ( State :: EncodeChunkedBody , cx, buf) ,
185
195
}
186
- None => self . dispatch ( State :: EncodeChunkedBody , cx, buf) ,
187
196
}
188
197
} else {
189
198
// If we haven't read the entire header it means `buf` isn't
0 commit comments