@@ -191,7 +191,9 @@ where
191
191
// This is because Service only allows returning a single Response, and
192
192
// so if you try to reply with a e.g. 100 Continue, you have no way of
193
193
// replying with the latter status code response.
194
- let ( ret, mut is_last) = if StatusCode :: SWITCHING_PROTOCOLS == msg. head . subject {
194
+ let is_upgrade = msg. head . subject == StatusCode :: SWITCHING_PROTOCOLS
195
+ || ( msg. req_method == & Some ( Method :: CONNECT ) && msg. head . subject . is_success ( ) ) ;
196
+ let ( ret, mut is_last) = if is_upgrade {
195
197
( T :: on_encode_upgrade ( & mut msg) , true )
196
198
} else if msg. head . subject . is_informational ( ) {
197
199
error ! ( "response with 1xx status code not supported" ) ;
@@ -851,12 +853,20 @@ impl OnUpgrade for YesUpgrades {
851
853
852
854
impl OnUpgrade for NoUpgrades {
853
855
fn on_encode_upgrade ( msg : & mut Encode < StatusCode > ) -> :: Result < ( ) > {
854
- error ! ( "response with 101 status code not supported" ) ;
855
856
* msg. head = MessageHead :: default ( ) ;
856
857
msg. head . subject = :: StatusCode :: INTERNAL_SERVER_ERROR ;
857
858
msg. body = None ;
858
- //TODO: replace with more descriptive error
859
- Err ( :: Error :: new_status ( ) )
859
+
860
+ if msg. head . subject == StatusCode :: SWITCHING_PROTOCOLS {
861
+ error ! ( "response with 101 status code not supported" ) ;
862
+ Err ( Parse :: UpgradeNotSupported . into ( ) )
863
+ } else if msg. req_method == & Some ( Method :: CONNECT ) {
864
+ error ! ( "200 response to CONNECT request not supported" ) ;
865
+ Err ( :: Error :: new_user_unsupported_request_method ( ) )
866
+ } else {
867
+ debug_assert ! ( false , "upgrade incorrectly detected" ) ;
868
+ Err ( :: Error :: new_status ( ) )
869
+ }
860
870
}
861
871
862
872
fn on_decode_upgrade ( ) -> Result < Decoder , Parse > {
@@ -1309,6 +1319,39 @@ mod tests {
1309
1319
assert_eq ! ( vec, b"GET / HTTP/1.1\r \n Content-Length: 10\r \n Content-Type: application/json\r \n \r \n " . to_vec( ) ) ;
1310
1320
}
1311
1321
1322
+ #[ test]
1323
+ fn test_server_no_upgrades_connect_method ( ) {
1324
+ let mut head = MessageHead :: default ( ) ;
1325
+
1326
+ let mut vec = Vec :: new ( ) ;
1327
+ let err = Server :: encode ( Encode {
1328
+ head : & mut head,
1329
+ body : None ,
1330
+ keep_alive : true ,
1331
+ req_method : & mut Some ( Method :: CONNECT ) ,
1332
+ title_case_headers : false ,
1333
+ } , & mut vec) . unwrap_err ( ) ;
1334
+
1335
+ assert ! ( err. is_user( ) ) ;
1336
+ assert_eq ! ( err. kind( ) , & :: error:: Kind :: UnsupportedRequestMethod ) ;
1337
+ }
1338
+
1339
+ #[ test]
1340
+ fn test_server_yes_upgrades_connect_method ( ) {
1341
+ let mut head = MessageHead :: default ( ) ;
1342
+
1343
+ let mut vec = Vec :: new ( ) ;
1344
+ let encoder = S :: < YesUpgrades > :: encode ( Encode {
1345
+ head : & mut head,
1346
+ body : None ,
1347
+ keep_alive : true ,
1348
+ req_method : & mut Some ( Method :: CONNECT ) ,
1349
+ title_case_headers : false ,
1350
+ } , & mut vec) . unwrap ( ) ;
1351
+
1352
+ assert ! ( encoder. is_last( ) ) ;
1353
+ }
1354
+
1312
1355
#[ cfg( feature = "nightly" ) ]
1313
1356
use test:: Bencher ;
1314
1357
0 commit comments